1<sj-lesson-type-icon
2 type="PDF"
3 style="--icon-color: var(--color-blue)"
4></sj-lesson-type-icon>
1const elem = document.createElement('sj-example');
2elem.setAttribute('example-attribute', 'example value');
3elem.addEventListener('example-event', () => console.log('An example event occurred'));
4document.body.appendChild(elem);
1:root {
2 --icon-color: var(--color-geysergrey);
3}
4
5sj-lesson-icon {
6 --icon-active-color: var(--color-blue);
7}
1export default class Example extends HTMLElement {
2 static get observedAttributes() { return [] }
3
4 constructor() {}
5
6 connectedCallback() {}
7 attributeChangedCallback(name, oldValue, newValue) {}
8 disconnectedCallback() {}
9 adoptedCallback() {}
10}
1export default class Example extends HTMLElement {
2 #example;
3
4 static get observedAttributes() {
5 return ['example'];
6 }
7
8 constructor() {
9 super();
10 // Per the spec: don't access the attribute here
11 }
12
13 connectedCallback() {
14 this.updateAttribute(this.getAttribute('example'));
15 this.appendChild(this.#rootElement);
16 }
17
18 attributeChangedCallback(name, oldValue, newValue) {
19 if (name === 'example') {
20 this.updateAttribute(newValue);
21 }
22 }
23
24 updateAttribute(newValue) {
25 this.#example = newValue;
26 }
27}
1export default class Example extends HTMLElement {
2 #rootElement;
3
4 constructor() {
5 super();
6 this.#rootElement = document.createElement('sj-icon');
7 }
8
9 connectedCallback() {
10 this.#rootElement.addEventListener('click', this.#onExample);
11 }
12
13 disconnectedCallback() {
14 this.#rootElement.removeEventListener('click', this.#onExample);
15 }
16
17 #onExample() {
18 this.#rootElement.dispatchEvent(new CustomEvent('example'));
19 }
20}
1class Example extends HTMLElement {
2 constructor() {
3 super();
4
5 const shadow = this.attachShadow({ mode: "open" }); // also, mode: "closed"
6
7 const wrapper = document.createElement("span");
8 wrapper.innerText = 'Hello World!';
9
10 const style = document.createElement("style");
11 style.textContent += `.wrapper { color: rebeccapurple }`;
12
13 shadow.appendChild(style);
14 shadow.appendChild(wrapper);
15 }
16}
17
18customElements.define("example", Example);
1class Example extends HTMLElement {
2 constructor() {
3 super();
4
5 const template = document.createElement(`
6 <template>
7 <span>Slotted content:</span>
8 <slot name="example-slot">DEFAULT VALUE</slot>
9 </template>
10 `).content;
11
12 const shadowRoot = this.attachShadow({ mode: "open" });
13 shadowRoot.appendChild(template.cloneNode(true));
14 }
15}
16
17customElements.define("example-element", Example);
1<example-element>
2 <span slot="example-slot">slot</span>
3</example-element>
1:root {
2 --example-color: rebeccapurple;
3}
4
5sj-example {
6 color: var(--example-color);
7}
1import { mount } from '@test-utils/web-component-rendering';
2
3test('emits click event when the icon is clicked', async () => {
4 // Arrange
5 const myProp = 'example';
6 const clickMock = jest.fn();
7
8 // Act
9 const elem = await mount({ tag: 'sj-example', attributes: { myProp } });
10 elem.addEventListener('click', clickMock);
11 elem.click();
12
13
14 expect(clickMock).toHaveBeenCalled();
15 expect(elem.firstChild.classList).toContain(myProp);
16});