swiss-element
v0.16.0
Published
🇨🇭 Swiss Element library
Downloads
13
Readme
npm: npm install swiss-element --save
cdn: https://unpkg.com/swiss-element@latest/dist/swiss-element.js
Intro
Swiss provides a functional way of defining custom elements.
- React-like hooks (useEffect, useState, useCallback, useMemo, useReducer, useRef)
- Extend the custom element with composition via enhancers
- Observed attributes are also accessible via element properties
- Choose your own renderer:
Htm-preact
Lighterhtml
Lit-html
Nanomorph
Stage0
Superfine
Example - Counter
import { html, render } from 'lit-html';
import { element, renderer } from 'swiss-element';
import { useState } from 'swiss-hooks';
function Counter(element) {
const [count, setCount] = useState(0);
return html`
<a href="#" @click="${() => setCount(count + 1)}">
Clicked ${count} times
</a>
`;
}
element('s-counter', Counter, renderer(render));
A starter app is available at https://codesandbox.io/s/github/luwes/swiss-element-starter-app/tree/master/
Example - Hello world
document.body.appendChild(
element('hello-world', ({ w }) => `Hello ${w}`, ['w'])()
).w = 'world';
API
element(name, comp, [enhancer], [options]) ⇒ HTMLElement
Defines a custom element in the CustomElementRegistry
which renders the component which is passed as an argument.
Kind: global function
| Param | Type | Description |
| ---------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | string | The tag name for the custom element. |
| comp | function | The component that is rendered in the element. |
| [enhancer] | function | The element enhancer. You may optionally specify it to enhance the element with third-party capabilities such as middleware, custom renderer, public API, etc. The only element enhancers that ship with Swiss are applyMiddleware
and renderer
. |
| [options] | Object | Array | Options object or observedAttributes
only array for shorter syntax. |
| [options.observedAttributes] | Array | Attributes to observe for adding, removing or changing which will trigger a component update if needed. |
| [options.extends] | string | Specifies the built-in element your element inherits from if any (e.g. extends: 'button'
). |
| [options.shadow] | 'open' | 'closed' | Defines the shadow root mode, by default no shadow root is created and everything is rendered straight on the custom element. The options object is also passed to all the enhancers. |
Enhancers
- applyMiddleware(...middleware) ⇒ function
- renderer(customRenderer) ⇒ function
applyMiddleware(...middleware) ⇒ function
Middleware lets you wrap the element's render method for fun and profit. The key feature of middleware is that it is composable. Multiple middleware can be combined together, where each middleware requires no knowledge of what comes before or after it in the chain.
Kind: global function
| Param | Type | Description |
| ------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ...middleware | function | Functions that conform to the Swiss middleware API. Each middleware receives SwissElement
's render
function as a named argument, and returns a function. That function will be given the next
middleware's render method, and is expected to return a function of fragment
calling next(fragment)
with a potentially different argument, or at a different time, or maybe not calling it at all. The last middleware in the chain will receive the real element's render
method as the next
parameter, thus ending the chain. So, the middleware signature is ({ render }) => next => fragment
. |
renderer(customRenderer) ⇒ function
Adds a simple way to define your own renderer.
Verified libraries working by passing just the render
or patch
function:
- Lighterhtml
- Lit-html
- HTM-Preact
- Superfine
Kind: global function
| Param | Type | Description |
| -------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| customRenderer | function | A function that takes the custom element root and a function html
which once executed renders the created dom nodes to the root node of the custom element. |
FAQ
Why another dude?
There are dozens of custom element libraries out there, sorry to say, I didn't find one that fit my exact requirements.
- No ES6 classes and classical inheritance ~~hyperHTML-element, lit-element, skatejs~~
- Choose your own render engine ~~neverland, hybrids~~
- Opt-in web component features like ShadowDOM and minimal polyfill requirements ~~switzerland, haunted~~
Swiss doesn't use ES6 classes, Proxy, Shadow DOM (can be configured), etc because IE11 should still be easy to support. The only needed polyfill is the one for window.customElements
.
<script src="https://unpkg.com/@webcomponents/custom-elements"></script>