| description | Use when authoring a custom HTML element with `customElements.define`, attaching a shadow root with `attachShadow`, distributing children via `<slot>`, reacting to attribute changes via `observedAttributes` + `attributeChangedCallback`, server-rendering the shadow root via declarative shadow DOM (`<template shadowrootmode="open">`), building a custom form control that participates in `<form>` submission via `ElementInternals` (`static formAssociated = true`, `setFormValue`, `setValidity`, `formAssociatedCallback`, `formResetCallback`, `formStateRestoreCallback`), or shipping a framework-agnostic UI primitive that needs to work in every framework (and no framework). Use when reviewing custom-element code for the canonical lifecycle bugs : missing `observedAttributes`, DOM work in the constructor, attribute reads before the element is upgraded, single-word element names, closed shadow without reason, form-custom-elements without `setFormValue`. Prevents the seven dominant web-component failures : missing `static get observedAttributes()` so `attributeChangedCallback` silently never fires; DOM mutations in the constructor (the element is not connected yet, parent is undefined, children may not exist); single-word element names (the spec REQUIRES a hyphen, the element is rejected without one); using `connectedCallback` for one-time init without guarding against re-insertion (the callback fires every time the element re-enters the DOM); shadow DOM `mode: "closed"` chosen by default ("for security") which silently destroys debuggability without buying any real isolation; form-associated custom elements that forget `setFormValue()`, so `<form>` submission ships an empty value for that field; and `innerHTML` of user-supplied content inside the shadow root without sanitization, opening an XSS surface that shadow DOM does NOT block. Covers the full `CustomElementRegistry.define(name, ctor, options?)` signature with `options.extends` for customized built-ins, the four lifecycle callbacks (`connectedCallback`, `disconnectedCallback`, `adoptedCallback`, `attributeChangedCallback`) and the `observedAttributes` static getter that gates the last one, `attachShadow({ mode, delegatesFocus, slotAssignment })`, slot distribution mechanics (`<slot name>`, `Element.assignedSlot`, the `slotchange` event, `slot.assignedElements()` / `assignedNodes()`), declarative shadow DOM via `<template shadowrootmode="open|closed">` (Baseline 2024), the form-associated custom-element story (static `formAssociated`, `this.attachInternals()`, `setFormValue(value, state?)`, `setValidity(flags, message?, anchor?)`, `checkValidity`, `reportValidity`, `formAssociatedCallback`, `formDisabledCallback`, `formResetCallback`, `formStateRestoreCallback`), the shadow-DOM CSS hooks (`:host`, `:host()`, `:host-context()`, `::slotted`, `::part`, `:state()`), scoped registries (`new CustomElementRegistry()` + `customElementRegistry` option on `attachShadow`, Limited availability), and the kebab-case naming requirement. Keywords: web components, custom elements, customElements define, customElementRegistry, HTMLElement, extends HTMLElement, observedAttributes, attributeChangedCallback, connectedCallback, disconnectedCallback, adoptedCallback, attachShadow, shadow DOM, open shadow DOM, closed shadow DOM, delegatesFocus, slotAssignment, slot, named slot, default slot, slotchange, assignedSlot, assignedNodes, assignedElements, declarative shadow DOM, shadowrootmode, ElementInternals, attachInternals, formAssociated, setFormValue, setValidity, checkValidity, reportValidity, formAssociatedCallback, formResetCallback, formStateRestoreCallback, formDisabledCallback, :host, :host(), :host-context, ::slotted, ::part, :state, scoped registry, kebab-case, custom element not upgrading, custom element not registering, slot not rendering, slot not filling, shadow DOM hides content, attribute change not detected, form value not submitting, form custom element not in submit, styles leaking into shadow DOM, how to make a web component, how to write a custom element, what is shadow DOM, how to slot content, how to make a custom form input, declarative shadow DOM tutorial, framework-agnostic component.
|