Assignment 4
The fourth and final assignment in this course consists of three exercises where you will be creating web components.
Submit your completed assignment before the deadline. Submission instructions can be found on the main assignment page.
Learning outcomes
After this lab assignment, you should have gained knowledge about the following:
- How to create Web Components
- How to dispatch synthetic events
- How ARIA attributes are used
Assignment points
Exercises 1 and 2 have optional tasks.
- 1 point: Complete all required tasks.
- 2 points: Complete all required tasks and one optional task.
General requirements
Create a folder the assignment and a sub-folder for each exercise.
Exercise 1 - Your first Web Component
Required task
Create a Web Component (<info-message>
that displays an informational message using slots for the title and message. In this exercise you will also be using the open source icon library Fork Awesome.
There are prepared files for this assignment: a4e1.zip
These zip-file contains
a4e1.html
, the web page that uses two<info-message>
web componentsa4e1.css
, the CSS file fora4e1.html
andinfomessage.js
, an empty file where you are supposed to define the web component
Visuals
Below is an image of how your web component should look like. It uses an icon from the Fork Awesome library (see below for information on how to use Fork Awesome icons).
HTML (a4e1.html)
Keep the original contents of the a4e1.html
file. You only need to add the link to the Fork Awesome css (see below). The HTML uses the <info-message>
web component that you need to define.
HTML Template for the web component
Use the following HTML as template for the web component, i.e. use is when you define your template in infomessage.js
. Refer to the lecture slides for an outline for defining a custom element/web component.
<div class="infobox">
<div class="heading">
<div class="icon center">
<i class="fa fa-info-circle fa-lg fa-inverse fa-fw" aria-hidden="true"></i>
</div>
<div class="title">
<p><slot name="title">TITLE GOES HERE</slot></p>
</div>
</div>
<div class="message">
<slot name="message">MESSAGE</slot>
</div>
</div>
Using Fork Awesome
You can either link to the Fork Awesome stylesheet via their CDN (Content Delivery Network), or download the library and link to the local file (fork-awesome.min.css
).
If you use the CDN version use the code below. You will need to link to if both from your HTML Template and the main page (a4e1.html
) for the icons to work.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css" integrity="sha256-XoaMnoYC5TH6/+ihMEnospgm0J1PM/nioxbOUdnM8HY=" crossorigin="anonymous">
If you download and use a local version, you must keep the folder structure intact (the css file refers to the folder ../fonts
for the fonts).
The template HTML code above uses the fa-info-circle
icon. You can read more about how to use Fork Awesome icons on their web site: Fork Awesome Examples.
Exercise 2 - Toggle button
Required task
Create a <toggle-button>
Web Component that toggles on/off when clicked. The <toggle-button>
should also fire an input
event when its value changes. The current value should be accessible via its .value
property.
There are prepared files for this assignment: a4e2.zip
The zip-file contains
a4e2.html
, the page that uses four<toggle-button>
elementsa4e2.css
, the CSS fora4e2.html
a4e2.js
, javascript that listens forinput
events from the<toggle-button>
elements and displays their valuestoggle-button.js
, an empty file where you are supposed to define the<toggle-button>
web component
Visuals
a4e1.html
should look something like this when you have created the CSS for the toggle widget.
Below is an image of what it should look like after you have toggled widget 2 and 4.
ARIA attributes
The two relevant ARIA attributes for the <toggle-button>
are the role
and the aria-pressed
attributes. The clickable web component HTML should have role="button"
as it functions as a two state button. The attribute aria-pressed
should be set as "false"
if the button is in its “off”-state, and set to “true” when the button is in its “on”-state.
HTML (a4e2.html)
In a4e2.html
you can see the toggle-button
elements which are the custom elements you have to implement, e.g.
<toggle-button label="Toggle 1"></toggle-button>
HTML Template for the web component
Use the following as the template for your web component:
<div class="wrapper">
<p>label text</p>
<div class="toggle" aria-pressed="false"></div>
</div>
The label text
should be replaced by the text in the label
attribute of the custom element when the custom element is created. The value of the ARIA attribute aria-pressed
should reflect the state of the <toggle-button>
(see Behavior below).
Behavior
Implement the ability for toggling the color of the widget between white and green. When the widget is white, its value should be 0
. I.e. console.log((toggleButton.value)
should print out 0
. The value when showing green should be 1
.
This means your class should have an instance variable with the name value
that stores the value of the button (0
or 1
).
Also change the value of the attribute aria-pressed
accordingly (more info: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role).
Fire input events
The web component should also fire input
events when the user clicks it that bubble. See the lecture slides, and the following two pages for more info:
- https://developer.mozilla.org/en-US/docs/Web/Events/Creating_and_triggering_events
- https://developer.mozilla.org/en-US/docs/Web/API/Event/Event
Optional task 1
Note: If you complete Optional task 1 you need to submit both the required and optional task. Make a copy of a4e2.html
and name it a4e2-optional.html
and copy toggle-button.js
to toggle-button-optional.js
and use that for the optional task.
For Optional task 1 allow the user to specify two images that are used to show the state of the <toggle-button>
:
<toggle-button label="Toggle 1" pressed="green.png" not-pressed="red.png"></toggle-button>
Change the use of the custom elements in a4e2-optional.html
to reflect the code above.
If you implement the optional task, red.png
should be shown initially. When the user clicks on the widget, green.png
should be shown. Clicking again switches the images.
You can use these image URL:s if you do not want to use your own images:
Exercise 3 - Accordion
Required task
Create an <accortion-component>
web component that contains headings with expandable content.
There are prepared files for this assignment: a4e3.zip
The zip-file contains
a4e3.html
, web page that uses the<accordion-component>
web componenta4e3.css
, the CSS fora4e3.html
accordion.js
, an empty file where you are supposed to define the<accordion-component>
web component
Visuals
a4e2.html
should look something like this when you have created the CSS for the accordion widget.
Tip: You can use the CSS below to add different triangles when the accordian is opened and closed.
.accordion button::before {
content: "▶︎ ";
}
.accordion button[aria-expanded="true"]::before {
content: "▼︎ ";
}
ARIA attributes
- Role The element containing the content of an accordion panel has
role="region"
- State When a button’s content
div
is visible, the value of thebutton
’saria-expanded
attribute should betrue
. When its contentdiv
is not visible, the button’saria-expanded
value should be set tofalse
. - Relationship You are not required to apply these attributes for the assignment.
aria-controls
: this attribute is set on a button and and its value is theid
of the contentdiv
it controls the visibility ofaria-labelledby
: this attribute is set on a contentdiv
and its value is theid
of thebutton
it belongs to.
- Misc An element with the
hidden
attribute will not be visible in the browser, nor will it be read by any assistive technologies. Because of this, thehidden
attribute is often used when creating accessible UI components rather than just settingdisplay: none
. Just settingdisplay: none
will hide it from seeing users, but it may still be read by some assistive tools.
HTML (a4e3.html)
The idea here, is to let the user write only what is necessary from a content author’s perspective. Here is the HTML that is the user is required to write.
<accordion-component>
<h2>Accordion 1 title</h2>
<div><p>Content for Accordion 1<p></div>
<h2>Accordion 2 title</h2>
<div><p>Content for Accordion 2<p></div>
<h2>Accordion 3 title</h2>
<div><p>Content for Accordion 3<p></div>
</accordion-component>
HTML Template for the web component
Use the following HTML as the template for your web component:
<div class="accordion">
<ul>
</ul>
</div>
You will need to create elements using JavaScript to put the content of the web component into the appropriate elements in the shadow DOM. This is what the final shadow DOM should look like for the <accordion-component>
example above.
<div class="accordion">
<ul>
<li>
<button aria-expanded="false">Accordion 1 title</button>
<div role="region" hidden=""><p>Content for Accordion 1</p></div>
</li>
<li>
<button aria-expanded="false">Accordion 2 title</button>
<div role="region" hidden=""><p>Content for Accordion 2</p></div>
</li>
<li>
<button aria-expanded="false">Accordion 3 title</button>
<div role="region" hidden=""><p>Content for Accordion 3</p></div>
</li>
</ul>
</div>
Important: Some methods and properties, e.g. element.children
and document.getElementsByClassName()
return a live HTMLCollection
. “Live” means that any changes to the DOM will be immediately reflected in the HTMLCollection
. If you intend to move any elements in the HTMLCollection
to a new place in the DOM, do NOT do this from inside of a e.g. a for
-loop where you are using indexes. Instead, copy the elements to an array and loop through the array: let myElements = Array.from(myHTMLCollection)
and loop over the array.
If you try to loop over a live HTMLCollection of e.g. the children of a node and move any of the children to another place in the DOM, the HTMLCollection will shrink and you will have a smaller HTMLCollection than you initially had.
Note: You cannot change the tagName
of a DOM node, e.g. you cannot change a h2
to a button
. Instead you have to create a new button
element, then copy the .innerHTML
and optionally destroy the h2
element (use element.remove()
).
Behavior
- If an unexpanded accordion title is clicked, its content is revealed (remove the
hidden
attribute) and the value of the title’saria-expanded
attribute is set to"true"
. - If a expanded accordion title is clicked, its content is hidden (add the
hidden
attribute) and the value of the title’saria-expanded
attribute is set to"false"
. - There are no dependencies between accordions, i.e. any number of accordions may be opened or closed at the same time.
Optional Task 2
- Animate the accordions opening and closing using anime.js
Page contact: Johan Falkenjack
Last update: 2022-12-02