UNPKG

@vonage/element-f

Version:

A functional shim to custom element definition

97 lines (74 loc) 2.9 kB
# element-f A functional shim to custom element definition. ### Installation ``` npm i @vonage/element-f ``` ### Basics In order to define a custom-element, you only need one definition function: ```javascript import elementF from "@voange/element-f"; const MyElement = elementF(()=> { // Your logic goes here const shadow = this.attachShadow({mode: 'open'}); }); ``` To tap into lifecycle events, this function can use the "life" event emitter: ```javascript const MyElement = elementF((life)=> { const shadow = this.attachShadow({mode: 'open'}); // Listen once to when this component connects to a document life.once('connect', ()=> shadow.innerHTML = `I'm Alive!`); }); ``` The "life" event emitter supports three methods: * **`once(name, fn)`<br/>`on(name, fn)`** - Registers **`fn`** for events of name **`name`**. **`once()`** will invoke **fn** once. * **`name`** - The name of the event to listen to * **`fn(payload)`** - The function to be called when an event occurs * **`payload`** - An object containing information regarding the event * **`off(name, fn)`** - Removes an event handler previously registered using **on** or **once**. The following events are thrown: * **`connect`** - Fired upon `connectedCallback`. Delivers no payload. * **`disconnect`** - Fired upon `disconnectedCallback`. Delivers no payload. * **`attribute`** - Fired when an observed attribute changes. Delivers **name**, **previousValue** and **newValue** as payload. To observe attributes, just add their list to `elementF` call: ```javascript const MyElement = elementF((life)=> { life.on('attribute', ({ name, previousValue, newValue })=> { // name can be "one" or "two" }); }, ["one", "two"]); ``` #### Usage Examples To define a custom element using standard class notation, you'd write something like: ```javascript class MyButton extends HTMLElement { constructor(){ super(); console.log(`I'm alive!`); } static get observedAttributes(){ return ['disabled']; } attributeChangedCallback(name, oldValue, newValue) { this.classList.toggle('disabled', newValue); } connectCallback() { this.innerHTML = "<b>I'm an x-foo-with-markup!</b>"; } } ``` To defining the same element using **element-f** would look like this: ```javascript const MyButton = elementF((life)=> { life.on('connect', ()=> { this.innerHTML = "<b>I'm an x-foo-with-markup!</b>"; }); life.on('attribute', ({ name, newValue, oldValue })=> { this.classList.toggle('disabled', newValue); }); console.log(`I'm alive!`); }, ['disabled']); ``` ### What does Element-F solve? **Element-F** supplies a stylistic framework, not a fundamental solution to a problem. If you're happy with OOP-styled constructs, you would probably not draw much enjoyment from using it :)