Created
July 29, 2026 11:57
-
-
Save kasperpeulen/445aef8550ad1279d57e77a749b88624 to your computer and use it in GitHub Desktop.
Custom Elements Manifest (schema 2.1.0) example exercising every field in the spec — validated against the official schema with ajv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "schemaVersion": "2.1.0", | |
| "readme": "README.md", | |
| "deprecated": false, | |
| "modules": [ | |
| { | |
| "kind": "javascript-module", | |
| "path": "src/base-element.js", | |
| "summary": "Shared base class, mixin, and utilities.", | |
| "description": "Longer markdown description of the module:\nbase primitives that `<my-button>` builds on.", | |
| "deprecated": false, | |
| "declarations": [ | |
| { | |
| "kind": "variable", | |
| "name": "VERSION", | |
| "summary": "Library version.", | |
| "description": "Injected at build time.", | |
| "type": { "text": "string" }, | |
| "default": "\"2.4.0\"", | |
| "readonly": true, | |
| "source": { "href": "https://github.com/acme/elements/blob/v2.4.0/src/base-element.js#L1" } | |
| }, | |
| { | |
| "kind": "function", | |
| "name": "formatLabel", | |
| "summary": "Uppercases a button label.", | |
| "description": "Used by `MyButton` to normalize labels.", | |
| "deprecated": "Use `Intl`-aware `localizeLabel()` instead.", | |
| "parameters": [ | |
| { | |
| "name": "label", | |
| "type": { "text": "string" }, | |
| "description": "The raw label.", | |
| "summary": "Raw label." | |
| }, | |
| { | |
| "name": "options", | |
| "type": { | |
| "text": "FormatOptions", | |
| "references": [ | |
| { | |
| "name": "FormatOptions", | |
| "package": "@acme/elements", | |
| "module": "src/types.js", | |
| "start": 0, | |
| "end": 13 | |
| } | |
| ], | |
| "source": { "href": "https://github.com/acme/elements/blob/v2.4.0/src/types.js#L4" } | |
| }, | |
| "default": "{}", | |
| "optional": true, | |
| "readonly": true | |
| }, | |
| { | |
| "name": "extra", | |
| "type": { "text": "unknown[]" }, | |
| "rest": true, | |
| "deprecated": true | |
| } | |
| ], | |
| "return": { | |
| "type": { "text": "string" }, | |
| "summary": "The formatted label.", | |
| "description": "Never returns `null`; empty input yields an empty string." | |
| }, | |
| "source": { "href": "https://github.com/acme/elements/blob/v2.4.0/src/base-element.js#L10" } | |
| }, | |
| { | |
| "kind": "mixin", | |
| "name": "DisabledMixin", | |
| "summary": "Adds a reflected `disabled` state to any element base class.", | |
| "description": "Classic subclass-factory mixin. Note a mixin is both class-like *and* function-like: it has `parameters` and a `return` in addition to `members`.", | |
| "parameters": [ | |
| { | |
| "name": "superClass", | |
| "type": { "text": "T" }, | |
| "description": "The base class to extend." | |
| } | |
| ], | |
| "return": { "type": { "text": "T & Constructor<DisabledInterface>" } }, | |
| "members": [ | |
| { | |
| "kind": "field", | |
| "name": "disabled", | |
| "privacy": "public", | |
| "type": { "text": "boolean" }, | |
| "default": "false", | |
| "description": "Whether the host is disabled." | |
| } | |
| ], | |
| "deprecated": false, | |
| "source": { "href": "https://github.com/acme/elements/blob/v2.4.0/src/base-element.js#L30" } | |
| }, | |
| { | |
| "kind": "class", | |
| "name": "BaseElement", | |
| "summary": "Plain (non-custom-element) base class.", | |
| "description": "A `kind: \"class\"` declaration *without* `customElement: true` — plain classes are valid declarations too.", | |
| "superclass": { "name": "HTMLElement" }, | |
| "members": [ | |
| { | |
| "kind": "method", | |
| "name": "requestUpdate", | |
| "privacy": "protected", | |
| "return": { "type": { "text": "void" } } | |
| }, | |
| { | |
| "kind": "field", | |
| "name": "renderRoot", | |
| "privacy": "protected", | |
| "readonly": true, | |
| "type": { "text": "ShadowRoot" }, | |
| "description": "Where templates render." | |
| } | |
| ] | |
| } | |
| ], | |
| "exports": [ | |
| { "kind": "js", "name": "VERSION", "declaration": { "name": "VERSION", "module": "src/base-element.js" } }, | |
| { "kind": "js", "name": "formatLabel", "declaration": { "name": "formatLabel", "module": "src/base-element.js" }, "deprecated": true }, | |
| { "kind": "js", "name": "DisabledMixin", "declaration": { "name": "DisabledMixin", "module": "src/base-element.js" } }, | |
| { "kind": "js", "name": "default", "declaration": { "name": "BaseElement", "module": "src/base-element.js" } } | |
| ] | |
| }, | |
| { | |
| "kind": "javascript-module", | |
| "path": "src/my-button.js", | |
| "declarations": [ | |
| { | |
| "kind": "class", | |
| "name": "MyButton", | |
| "customElement": true, | |
| "tagName": "my-button", | |
| "summary": "A themable button.", | |
| "description": "The full custom-element surface: attributes, events, slots, CSS parts, CSS custom properties, CSS custom states, and demos.", | |
| "superclass": { "name": "BaseElement", "module": "src/base-element.js" }, | |
| "mixins": [ | |
| { "name": "DisabledMixin", "module": "src/base-element.js" }, | |
| { "name": "FocusableMixin", "package": "@acme/a11y", "module": "src/focusable.js" } | |
| ], | |
| "members": [ | |
| { | |
| "kind": "field", | |
| "name": "disabled", | |
| "privacy": "public", | |
| "type": { "text": "boolean" }, | |
| "default": "false", | |
| "attribute": "disabled", | |
| "reflects": true, | |
| "inheritedFrom": { "name": "DisabledMixin", "module": "src/base-element.js" }, | |
| "description": "Disables the button. `attribute` + `reflects` mark the two-way attribute link (CustomElementField in schema.d.ts)." | |
| }, | |
| { | |
| "kind": "field", | |
| "name": "variant", | |
| "privacy": "public", | |
| "type": { | |
| "text": "\"primary\" | \"secondary\"", | |
| "references": [] | |
| }, | |
| "default": "\"primary\"", | |
| "attribute": "variant", | |
| "reflects": false | |
| }, | |
| { | |
| "kind": "field", | |
| "name": "styles", | |
| "static": true, | |
| "privacy": "public", | |
| "readonly": true, | |
| "type": { "text": "CSSResult" }, | |
| "summary": "Static stylesheet." | |
| }, | |
| { | |
| "kind": "field", | |
| "name": "#internals", | |
| "privacy": "private", | |
| "type": { "text": "ElementInternals" } | |
| }, | |
| { | |
| "kind": "method", | |
| "name": "focus", | |
| "privacy": "public", | |
| "static": false, | |
| "parameters": [ | |
| { | |
| "name": "options", | |
| "type": { "text": "FocusOptions" }, | |
| "optional": true | |
| } | |
| ], | |
| "return": { "type": { "text": "void" } }, | |
| "inheritedFrom": { "name": "FocusableMixin", "package": "@acme/a11y", "module": "src/focusable.js" } | |
| }, | |
| { | |
| "kind": "method", | |
| "name": "fire", | |
| "privacy": "protected", | |
| "deprecated": "Dispatch events directly instead.", | |
| "source": { "href": "https://github.com/acme/elements/blob/v2.4.0/src/my-button.js#L88" } | |
| } | |
| ], | |
| "attributes": [ | |
| { | |
| "name": "disabled", | |
| "fieldName": "disabled", | |
| "type": { "text": "boolean" }, | |
| "default": "false", | |
| "summary": "Disables the button.", | |
| "description": "Present/absent boolean attribute, linked to the `disabled` field via `fieldName`.", | |
| "inheritedFrom": { "name": "DisabledMixin", "module": "src/base-element.js" } | |
| }, | |
| { | |
| "name": "variant", | |
| "fieldName": "variant", | |
| "type": { "text": "\"primary\" | \"secondary\"" }, | |
| "default": "\"primary\"" | |
| }, | |
| { | |
| "name": "raised", | |
| "type": { "text": "boolean" }, | |
| "deprecated": "Use `variant` instead." | |
| } | |
| ], | |
| "events": [ | |
| { | |
| "name": "disabled-changed", | |
| "type": { "text": "CustomEvent<{ disabled: boolean }>" }, | |
| "summary": "Fired when `disabled` flips.", | |
| "description": "Bubbles, composed.", | |
| "inheritedFrom": { "name": "DisabledMixin", "module": "src/base-element.js" } | |
| }, | |
| { | |
| "name": "my-click", | |
| "type": { "text": "Event" }, | |
| "deprecated": true | |
| } | |
| ], | |
| "slots": [ | |
| { | |
| "name": "", | |
| "summary": "Default slot.", | |
| "description": "The button label. The empty-string name means the default slot." | |
| }, | |
| { "name": "icon", "summary": "Leading icon." }, | |
| { "name": "badge", "deprecated": "Use the `badge` attribute on `<my-icon>` instead." } | |
| ], | |
| "cssParts": [ | |
| { | |
| "name": "button", | |
| "summary": "The native button.", | |
| "description": "Style via `my-button::part(button)`." | |
| }, | |
| { "name": "label", "deprecated": true } | |
| ], | |
| "cssProperties": [ | |
| { | |
| "name": "--my-button-background", | |
| "syntax": "<color>", | |
| "default": "#2f6fc4", | |
| "summary": "Background color.", | |
| "description": "Any CSS color; participates in the theme cascade." | |
| }, | |
| { | |
| "name": "--my-button-radius", | |
| "syntax": "<length>", | |
| "default": "4px", | |
| "deprecated": "Use `--my-radius-m` from the global theme." | |
| } | |
| ], | |
| "cssStates": [ | |
| { | |
| "name": "pressed", | |
| "summary": "Active-press state.", | |
| "description": "Added via `ElementInternals.states`; style with `my-button:state(pressed)`. New in schema 2.x." | |
| }, | |
| { | |
| "name": "loading", | |
| "deprecated": "Use the `busy` state instead." | |
| } | |
| ], | |
| "demos": [ | |
| { | |
| "url": "https://elements.acme.dev/demos/my-button/", | |
| "description": "Interactive playground.", | |
| "source": { "href": "https://github.com/acme/elements/blob/v2.4.0/demos/my-button.html" } | |
| } | |
| ], | |
| "source": { "href": "https://github.com/acme/elements/blob/v2.4.0/src/my-button.js#L12" }, | |
| "deprecated": false | |
| }, | |
| { | |
| "kind": "mixin", | |
| "name": "ButtonBehaviorMixin", | |
| "customElement": true, | |
| "summary": "A custom-element *mixin* — mixin + the full CustomElement surface.", | |
| "parameters": [{ "name": "superClass", "type": { "text": "T" } }], | |
| "return": { "type": { "text": "T" } }, | |
| "attributes": [{ "name": "type", "type": { "text": "\"button\" | \"submit\"" } }], | |
| "events": [{ "name": "activate", "type": { "text": "Event" } }], | |
| "members": [ | |
| { "kind": "method", "name": "click", "return": { "type": { "text": "void" } } } | |
| ] | |
| } | |
| ], | |
| "exports": [ | |
| { | |
| "kind": "js", | |
| "name": "MyButton", | |
| "declaration": { "name": "MyButton", "module": "src/my-button.js" } | |
| }, | |
| { | |
| "kind": "custom-element-definition", | |
| "name": "my-button", | |
| "declaration": { "name": "MyButton", "module": "src/my-button.js" } | |
| } | |
| ] | |
| } | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment