Skip to content
729G87 - Interaction Programming
GitLab

Assignment 4

This assignment is not final. Changes to the assignment are still possible.

The fourth 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.

There are prepared files for this assignment in the respective subdirs.

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 two optional task.

Hints

Have a look into your repository, in examples/web-components/cats you will find the cats drawer from assignment 2 implemented as web-components.

Exercise 1 - Your first Web Component

Required task

Create a website that uses the Web Component (<info-message>). It should display 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.

A lot of template-code is already written. Your task is to read, understand and extend the current codebase.

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 Template for the web component

Use the following HTML as template for the web component, i.e. use is when you define your template. 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>

Hints

  • The exercise requires you to add this code snipped at the appropriate place.
  • The code can be used as a general template and best practices how to implement web-components.

In this exercise you will encounter this code-snippet:

this.shadowRoot.innerHTML = /*html*/`
 <!-- html code here -->
`

The comment /*html*/ is a utility to enable html-syntax highlighting in your vs-code editor, using this addon: https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html

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:

  • index.html, the page that uses four <toggle-button> elements
  • a4e2.css, the CSS for a4e2/index.html
  • a4e2.js, javascript that listens for input events from the <toggle-button> elements and displays their values
  • toggle-button.js, a file where you are supposed to define the <toggle-button> web component

Visuals

a4e1/index.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/index.html)

In a4e2/index.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:

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/index.html and name it a4e2/index-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/index-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

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:

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 the button’s aria-expanded attribute should be true. When its content div is not visible, the button’s aria-expanded value should be set to false.
  • 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 the id of the content div it controls the visibility of
    • aria-labelledby: this attribute is set on a content div and its value is the id of the button 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, the hidden attribute is often used when creating accessible UI components rather than just setting display: none. Just setting display: none will hide it from seeing users, but it may still be read by some assistive tools.

HTML (a4e3/index.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’s aria-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’s aria-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 css-animations