All stakeholders can be involved in developing the communication layer:
Independent of any framework
Independent of any framework
<!DOCTYPE html> <html lang="en"> <body> <hello-world type="amazing"></hello-world> <script type="module" src="hello-world.js"></script> </body> </html>
<!DOCTYPE html> <html lang="en"> <body> <hello-world type="amazing"></hello-world> <script type="module" src="hello-world.js"></script> </body> </html>
index.html
Many tools need some machine-readable descriptions of custom elements: IDEs, documentation viewers, linters, graphical design tools, etc.
Custom elements manifest is an effort to bring together tool owners to standardize on a common specification for a description format.
{ "kind": "javascript-module", "path": "components/hello-world.ts", "declarations": [ { "kind": "class", "description": "Hello generated world! Click for a gift or a bomb", "name": "HelloWorld", "cssProperties": [ { "description": "Controls the text colour", "name": "--text-color", "default": "black" }, { "description": "Controls the background colour", "name": "--background-color", "default": "red" } ], "members": [ { "kind": "field", "name": "type", "type": { "text": "string" }, "default": "\"wonderful\"", "description": "What type is the world today?", "attribute": "type" }, { "kind": "method", "name": "eventFunctionGift", "privacy": "private", "description": "Write function that dispatches the event Gift" }, { "kind": "method", "name": "eventFunctionBomb", "privacy": "private", "description": "Write function that dispatches the event Bomb" } ], "events": [ { "name": "Gift", "type": { "text": "Event" }, "description": "gift - I'm bearing a gift" }, { "name": "Bomb", "type": { "text": "Event" }, "description": "bomb - This was a mistake..." } ], "attributes": [ { "name": "type", "type": { "text": "string" }, "default": "wonderful", "description": "What type is the world today?", "fieldName": "type" } ], "superclass": { "name": "LitElement", "package": "lit" }, "tagName": "hello-world", "customElement": true } ], "exports": [ { "kind": "js", "name": "HelloWorld", "declaration": { "name": "HelloWorld", "module": "components/hello-world.ts" } }, { "kind": "custom-element-definition", "name": "hello-world", "declaration": { "name": "HelloWorld", "module": "components/hello-world.ts" } } ] }
{ "kind": "javascript-module", "path": "components/hello-world.ts", "declarations": [ { "kind": "class", "description": "Hello generated world! Click for a gift or a bomb", "name": "HelloWorld", "cssProperties": [ { "description": "Controls the text colour", "name": "--text-color", "default": "black" }, { "description": "Controls the background colour", "name": "--background-color", "default": "red" } ], "members": [ { "kind": "field", "name": "type", "type": { "text": "string" }, "default": "\"wonderful\"", "description": "What type is the world today?", "attribute": "type" }, { "kind": "method", "name": "eventFunctionGift", "privacy": "private", "description": "Write function that dispatches the event Gift" }, { "kind": "method", "name": "eventFunctionBomb", "privacy": "private", "description": "Write function that dispatches the event Bomb" } ], "events": [ { "name": "Gift", "type": { "text": "Event" }, "description": "gift - I'm bearing a gift" }, { "name": "Bomb", "type": { "text": "Event" }, "description": "bomb - This was a mistake..." } ], "attributes": [ { "name": "type", "type": { "text": "string" }, "default": "wonderful", "description": "What type is the world today?", "fieldName": "type" } ], "superclass": { "name": "LitElement", "package": "lit" }, "tagName": "hello-world", "customElement": true } ], "exports": [ { "kind": "js", "name": "HelloWorld", "declaration": { "name": "HelloWorld", "module": "components/hello-world.ts" } }, { "kind": "custom-element-definition", "name": "hello-world", "declaration": { "name": "HelloWorld", "module": "components/hello-world.ts" } } ] }
{ "kind": "javascript-module", "path": "components/hello-world.ts", "declarations": [ { "kind": "class", "description": "Hello generated world! Click for a gift or a bomb", "name": "HelloWorld", "cssProperties": [ { "description": "Controls the text colour", "name": "--text-color", "default": "black" }, { "description": "Controls the background colour", "name": "--background-color", "default": "red" } ], "members": [ { "kind": "field", "name": "type", "type": { "text": "string" }, "default": "\"wonderful\"", "description": "What type is the world today?", "attribute": "type" }, { "kind": "method", "name": "eventFunctionGift", "privacy": "private", "description": "Write function that dispatches the event Gift" }, { "kind": "method", "name": "eventFunctionBomb", "privacy": "private", "description": "Write function that dispatches the event Bomb" } ], "events": [ { "name": "Gift", "type": { "text": "Event" }, "description": "gift - I'm bearing a gift" }, { "name": "Bomb", "type": { "text": "Event" }, "description": "bomb - This was a mistake..." } ], "attributes": [ { "name": "type", "type": { "text": "string" }, "default": "wonderful", "description": "What type is the world today?", "fieldName": "type" } ], "superclass": { "name": "LitElement", "package": "lit" }, "tagName": "hello-world", "customElement": true } ], "exports": [ { "kind": "js", "name": "HelloWorld", "declaration": { "name": "HelloWorld", "module": "components/hello-world.ts" } }, { "kind": "custom-element-definition", "name": "hello-world", "declaration": { "name": "HelloWorld", "module": "components/hello-world.ts" } } ] }
{ "kind": "javascript-module", "path": "components/hello-world.ts", "declarations": [ { "kind": "class", "description": "Hello generated world! Click for a gift or a bomb", "name": "HelloWorld", "cssProperties": [ { "description": "Controls the text colour", "name": "--text-color", "default": "black" }, { "description": "Controls the background colour", "name": "--background-color", "default": "red" } ], "members": [ { "kind": "field", "name": "type", "type": { "text": "string" }, "default": "\"wonderful\"", "description": "What type is the world today?", "attribute": "type" }, { "kind": "method", "name": "eventFunctionGift", "privacy": "private", "description": "Write function that dispatches the event Gift" }, { "kind": "method", "name": "eventFunctionBomb", "privacy": "private", "description": "Write function that dispatches the event Bomb" } ], "events": [ { "name": "Gift", "type": { "text": "Event" }, "description": "gift - I'm bearing a gift" }, { "name": "Bomb", "type": { "text": "Event" }, "description": "bomb - This was a mistake..." } ], "attributes": [ { "name": "type", "type": { "text": "string" }, "default": "wonderful", "description": "What type is the world today?", "fieldName": "type" } ], "superclass": { "name": "LitElement", "package": "lit" }, "tagName": "hello-world", "customElement": true } ], "exports": [ { "kind": "js", "name": "HelloWorld", "declaration": { "name": "HelloWorld", "module": "components/hello-world.ts" } }, { "kind": "custom-element-definition", "name": "hello-world", "declaration": { "name": "HelloWorld", "module": "components/hello-world.ts" } } ] }
custom-elements.json
import { html, css, LitElement } from "lit" import { customElement, property } from "lit/decorators.js" @customElement("hello-world") export class HelloWorld extends LitElement { static styles = css` :host { color: var(--text-color, black); background-color: var(--background-color, red); } ` @property() type = "wonderful" private eventFunctionGift() { this.dispatchEvent(new Event("Gift")) } private eventFunctionBomb() { this.dispatchEvent(new Event("Bomb")) } render() { return html` <h1>HelloWorld - <hello-world></hello-world></h1> <p>Hello generated world! Click for a gift or a bomb</p> <h2>CSS variables</h2> <ul> <li> <span style="color: var(--text-color, black)" >current text-color: --text-color default value: black</span > </li> <li> <span style="color: var(--background-color, red)" >current text-color: --background-color default value: red</span > </li> </ul> <h2>Attributes</h2> <ul> <li>type = ${this.type}</li> </ul> <h2>Events</h2> <ul> <li><button @click=${this.eventFunctionGift}>trigger Gift</button></li> <li><button @click=${this.eventFunctionBomb}>trigger Bomb</button></li> </ul> ` } }
import { html, css, LitElement } from "lit" import { customElement, property } from "lit/decorators.js" @customElement("hello-world") export class HelloWorld extends LitElement { static styles = css` :host { color: var(--text-color, black); background-color: var(--background-color, red); } ` @property() type = "wonderful" private eventFunctionGift() { this.dispatchEvent(new Event("Gift")) } private eventFunctionBomb() { this.dispatchEvent(new Event("Bomb")) } render() { return html` <h1>HelloWorld - <hello-world></hello-world></h1> <p>Hello generated world! Click for a gift or a bomb</p> <h2>CSS variables</h2> <ul> <li> <span style="color: var(--text-color, black)" >current text-color: --text-color default value: black</span > </li> <li> <span style="color: var(--background-color, red)" >current text-color: --background-color default value: red</span > </li> </ul> <h2>Attributes</h2> <ul> <li>type = ${this.type}</li> </ul> <h2>Events</h2> <ul> <li><button @click=${this.eventFunctionGift}>trigger Gift</button></li> <li><button @click=${this.eventFunctionBomb}>trigger Bomb</button></li> </ul> ` } }
import { html, css, LitElement } from "lit" import { customElement, property } from "lit/decorators.js" @customElement("hello-world") export class HelloWorld extends LitElement { static styles = css` :host { color: var(--text-color, black); background-color: var(--background-color, red); } ` @property() type = "wonderful" private eventFunctionGift() { this.dispatchEvent(new Event("Gift")) } private eventFunctionBomb() { this.dispatchEvent(new Event("Bomb")) } render() { return html` <h1>HelloWorld - <hello-world></hello-world></h1> <p>Hello generated world! Click for a gift or a bomb</p> <h2>CSS variables</h2> <ul> <li> <span style="color: var(--text-color, black)" >current text-color: --text-color default value: black</span > </li> <li> <span style="color: var(--background-color, red)" >current text-color: --background-color default value: red</span > </li> </ul> <h2>Attributes</h2> <ul> <li>type = ${this.type}</li> </ul> <h2>Events</h2> <ul> <li><button @click=${this.eventFunctionGift}>trigger Gift</button></li> <li><button @click=${this.eventFunctionBomb}>trigger Bomb</button></li> </ul> ` } }
import { html, css, LitElement } from "lit" import { customElement, property } from "lit/decorators.js" @customElement("hello-world") export class HelloWorld extends LitElement { static styles = css` :host { color: var(--text-color, black); background-color: var(--background-color, red); } ` @property() type = "wonderful" private eventFunctionGift() { this.dispatchEvent(new Event("Gift")) } private eventFunctionBomb() { this.dispatchEvent(new Event("Bomb")) } render() { return html` <h1>HelloWorld - <hello-world></hello-world></h1> <p>Hello generated world! Click for a gift or a bomb</p> <h2>CSS variables</h2> <ul> <li> <span style="color: var(--text-color, black)" >current text-color: --text-color default value: black</span > </li> <li> <span style="color: var(--background-color, red)" >current text-color: --background-color default value: red</span > </li> </ul> <h2>Attributes</h2> <ul> <li>type = ${this.type}</li> </ul> <h2>Events</h2> <ul> <li><button @click=${this.eventFunctionGift}>trigger Gift</button></li> <li><button @click=${this.eventFunctionBomb}>trigger Bomb</button></li> </ul> ` } }
hello-world.ts
import { html, css, LitElement } from "lit" import { customElement, property } from "lit/decorators.js" /** * Hello generated world! Click for a gift or a bomb * * @cssprop [--text-color=black] - Controls the text colour * @cssprop [--background-color=red] - Controls the background colour */ @customElement("hello-world") export class HelloWorld extends LitElement { static styles = css` :host { color: var(--text-color, black); background-color: var(--background-color, red); } ` /** What type is the world today? */ @property() type = "wonderful" /** Write function that dispatches the event Gift */ private eventFunctionGift() { /** @type {Event} gift - I'm bearing a gift */ this.dispatchEvent(new Event("Gift")) } /** Write function that dispatches the event Bomb */ private eventFunctionBomb() { /** @type {Event} bomb - This was a mistake... */ this.dispatchEvent(new Event("Bomb")) } render() { return html` <h1>HelloWorld - <hello-world></hello-world></h1> <p>Hello generated world! Click for a gift or a bomb</p> <h2>CSS variables</h2> <ul> <li> <span style="color: var(--text-color, black)" >current text-color: --text-color default value: black</span > </li> <li> <span style="color: var(--background-color, red)" >current text-color: --background-color default value: red</span > </li> </ul> <h2>Attributes</h2> <ul> <li>type = ${this.type}</li> </ul> <h2>Events</h2> <ul> <li><button @click=${this.eventFunctionGift}>trigger Gift</button></li> <li><button @click=${this.eventFunctionBomb}>trigger Bomb</button></li> </ul> ` } }
import { html, css, LitElement } from "lit" import { customElement, property } from "lit/decorators.js" /** * Hello generated world! Click for a gift or a bomb * * @cssprop [--text-color=black] - Controls the text colour * @cssprop [--background-color=red] - Controls the background colour */ @customElement("hello-world") export class HelloWorld extends LitElement { static styles = css` :host { color: var(--text-color, black); background-color: var(--background-color, red); } ` /** What type is the world today? */ @property() type = "wonderful" /** Write function that dispatches the event Gift */ private eventFunctionGift() { /** @type {Event} gift - I'm bearing a gift */ this.dispatchEvent(new Event("Gift")) } /** Write function that dispatches the event Bomb */ private eventFunctionBomb() { /** @type {Event} bomb - This was a mistake... */ this.dispatchEvent(new Event("Bomb")) } render() { return html` <h1>HelloWorld - <hello-world></hello-world></h1> <p>Hello generated world! Click for a gift or a bomb</p> <h2>CSS variables</h2> <ul> <li> <span style="color: var(--text-color, black)" >current text-color: --text-color default value: black</span > </li> <li> <span style="color: var(--background-color, red)" >current text-color: --background-color default value: red</span > </li> </ul> <h2>Attributes</h2> <ul> <li>type = ${this.type}</li> </ul> <h2>Events</h2> <ul> <li><button @click=${this.eventFunctionGift}>trigger Gift</button></li> <li><button @click=${this.eventFunctionBomb}>trigger Bomb</button></li> </ul> ` } }
import { html, css, LitElement } from "lit" import { customElement, property } from "lit/decorators.js" /** * Hello generated world! Click for a gift or a bomb * * @cssprop [--text-color=black] - Controls the text colour * @cssprop [--background-color=red] - Controls the background colour */ @customElement("hello-world") export class HelloWorld extends LitElement { static styles = css` :host { color: var(--text-color, black); background-color: var(--background-color, red); } ` /** What type is the world today? */ @property() type = "wonderful" /** Write function that dispatches the event Gift */ private eventFunctionGift() { /** @type {Event} gift - I'm bearing a gift */ this.dispatchEvent(new Event("Gift")) } /** Write function that dispatches the event Bomb */ private eventFunctionBomb() { /** @type {Event} bomb - This was a mistake... */ this.dispatchEvent(new Event("Bomb")) } render() { return html` <h1>HelloWorld - <hello-world></hello-world></h1> <p>Hello generated world! Click for a gift or a bomb</p> <h2>CSS variables</h2> <ul> <li> <span style="color: var(--text-color, black)" >current text-color: --text-color default value: black</span > </li> <li> <span style="color: var(--background-color, red)" >current text-color: --background-color default value: red</span > </li> </ul> <h2>Attributes</h2> <ul> <li>type = ${this.type}</li> </ul> <h2>Events</h2> <ul> <li><button @click=${this.eventFunctionGift}>trigger Gift</button></li> <li><button @click=${this.eventFunctionBomb}>trigger Bomb</button></li> </ul> ` } }
hello-world.ts
Automation as a Gift
๐ธ this is the best time to take a picture
Contact me:
๐ฆ @lucienimmink.bsky.social
๐ข linkedin.com/in/lucien-immink