MDN Web Components Examples

repository·main·Indexed 25 days ago

https://github.com/mdn/web-components-examples

A collection of practical Web Component examples used to illustrate concepts in MDN Web Components documentation. The repository demonstrates autonomous custom elements, customized built-in elements, Shadow DOM usage, slots, lifecycle callbacks, and CSS pseudo-classes. Featured examples include <editable-list>, <edit-word>, <expanding-list>, and <custom-square>.

Tokens
4.4K
Snippets
7
Records
24
Agent score
85%

What's inside mdn-web-components-examples

  1. Overview of web-components-examples

    main
    This repository contains a collection of Web Component examples designed to complement the MDN Web Components documentation. These examples demonstrate various concepts including autonomous custom elements, customized built-in elements, Shadow DOM usage, slots, and lifecycle callbacks.
  2. Explore Web Component examples

    main

    The following examples are available in this repository to demonstrate specific Web Component features:

    • Event Properties: composed-composed-path demonstrates the Event.composed and Event.composedPath() properties.
    • CSS Pseudo-classes: defined-pseudo-class shows the usage of the :defined pseudo-class; slotted-pseudo-element demonstrates the ::slotted pseudo-element.
    • Custom Elements (Autonomous):
      • <editable-list>: A list with addable/removable items via list-item attributes or UI interaction.
      • <edit-word>: An element that reveals a text input for editing text when focused.
      • <element-details>: Uses a <template> and <slot> to display element names and descriptions.
      • <popup-info img="" text="">: An info icon that displays a popup via Shadow DOM based on attributes.
      • <simple-template>: A basic demonstration of <template> and <slot> elements.
    • Custom Elements (Customized Built-in):
      • <ul is="expanding-list">: An unordered list with expandable/collapsible children (inherits from HTMLUListElement).
      • <word-count>: Counts words inside an element and updates via an interval (inherits from HTMLParagraphElement).
    • Lifecycle and Slots:
      • life-cycle-callbacks: Uses <custom-square l="" c=""> to demonstrate lifecycle callbacks through element creation, destruction, and attribute changes.
      • slotchange: Uses <summary-display> to demonstrate the slotchange event and HTMLSlotElement interface by dynamically assigning slot attributes to paragraphs.
  3. Inspect slotted elements in 'my-paragraph'

    main

    When using <my-paragraph> with slotted content (e.g., <span> elements), you can access the slot relationship via the assignedSlot and slot properties on the slotted elements.

    const slottedSpan = document.querySelector('my-paragraph span');
    
    console.log(slottedSpan.assignedSlot);
    console.log(slottedSpan.slot);
  4. Demonstrate Event.composed and Event.composedPath() with Shadow DOM

    main

    This example demonstrates how Event.composed and Event.composedPath() behave when interacting with Shadow DOM boundaries. It defines two custom elements: open-shadow (using an open shadow root) and closed-shadow (using a closed shadow root). An event listener is attached to the html element to log the event's composition status and its propagation path.

    // Define an element with an open shadow root
    customElements.define('open-shadow',
      class extends HTMLElement {
        constructor() {
          super();
          const pElem = document.createElement('p');
          pElem.textContent = this.getAttribute('text');
          const shadowRoot = this.attachShadow({mode: 'open'});
          shadowRoot.appendChild(pElem);
        }
      }
    );
    
    // Define an element with a closed shadow root
    customElements.define('closed-shadow',
      class extends HTMLElement {
        constructor() {
          super();
          const pElem = document.createElement('p');
          pElem.textContent = this.getAttribute('text');
          const shadowRoot = this.attachShadow({mode: 'closed'});
          shadowRoot.appendChild(pElem);
        }
      }
    );
    
    // Listen for clicks on the document to inspect event properties
    document.querySelector('html').addEventListener('click', e => {
      console.log(e.composed);
      console.log(e.composedPath());
    });
  5. Use the <summary-display> custom element and its slotchange event

    main

    The <summary-display> custom element demonstrates how to react to changes in a slot's assigned nodes using the slotchange event.

    When an element is assigned to a slot (for example, by setting the slot="choice" attribute on a <p> element), the slotchange event fires on the <slot> element. You can listen for this event to detect when the content within a specific slot has changed and use slot.assignedNodes() to retrieve the new nodes.

  6. Implement CSS Shadow Parts in a Custom Element

    main

    You can use the part attribute on elements within a Shadow DOM to expose them to styling from the outside world via the ::part() CSS pseudo-element. In this implementation, elements inside the shadow root are identified by their part attribute, and their part property is updated dynamically during interaction (e.g., on click) to apply different styles (like an active state).

    let template = document.getElementById("tabbed-custom-element");
    
    globalThis.customElements.define(template.id, class extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({ mode: "open" });
        this.shadowRoot.appendChild(template.content);
    
        let tabs = [];
        let children = this.shadowRoot.children;
    
        for(let elem of children) {
          if(elem.getAttribute('part')) {
            tabs.push(elem);
          }
        }
    
        tabs.forEach((tab) => {
          tab.addEventListener('click', (e) => {
            tabs.forEach((tab) => {
              tab.part = 'tab';
            });
            e.target.part = 'tab active';
          });
        });
      }
    });
  7. Use the <word-count> custom element

    main

    The <word-count> element is a specialized version of the standard <p> (HTMLParagraphElement) that automatically displays a word count of its parent element within a shadow DOM.

    To use it, you must extend a paragraph element using the customElements.define API with the { extends: 'p' } option. Because it is a 'customized built-in element', you use it in HTML via the is attribute on a standard <p> tag.

  8. Use the <person-details> custom element

    main
    The <person-details> custom element is a component that renders a template provided in the document. It attaches a shadow root in open mode and clones the content of an element with the ID person-template into that shadow root. It also applies internal styles for layout (padding, borders, and margins).
  9. Use the <popup-info> Web Component

    main

    The <popup-info> custom element displays an information box containing an icon and text. It uses a Shadow DOM with an open mode and relies on an external stylesheet (style.css) for its presentation.

    To configure the component, use the following attributes:

    • data-text: Sets the text content to be displayed in the info span.
    • img: (Optional) Sets the URL for the icon image. If omitted, it defaults to img/default.png.
  10. Lifecycle callbacks in <custom-square>

    main

    The Square class implements the following standard Web Component lifecycle callbacks:

    • connectedCallback(): Triggered when the element is added to the document. It logs a message and calls updateStyle().
    • disconnectedCallback(): Triggered when the element is removed from the document.
    • adoptedCallback(): Triggered when the element is moved to a new document.
    • attributeChangedCallback(name, oldValue, newValue): Triggered when the size or color attributes are modified. It calls updateStyle() to apply the new values.