function-web-components
v0.0.6
Published
Write Web Components as a single function.
Downloads
9
Readme
Function Web Components
Write Web Components as a single function.
Components written using this library look similar to Function Components in React:
- You declare attributes and properties for your Custom Element. Both are passed to the function as the first argument.
- Internal state can saved using
useState
; similar to Hooks. - Your function is invoked every time attributes/properties or state changes.
- The function should return HTML, which is then rendered to the elements Shadow DOM (rendering can be overridden to use libraries like lit-html).
Table of Contents
Install
# npm
npm install function-web-components
# yarn
yarn add function-web-components
Usage
Simple example:
import { makeWebComponent } from "function-web-components";
function myGreeting({ name = "You" }) {
return `<p>Hello ${name}.</p>`;
}
customElements.define(
"my-greeting",
makeWebComponent(myGreeting, {
attrs: ["name"],
})
);
<my-greeting name="Jan"></my-greeting>
Advanced example showing properties, state and using lit-html:
import { makeWebComponent, useState } from "function-web-components";
import { html, render } from "lit-html";
function myTodo({ todo }) {
const [done, setDone] = useState(false);
const toggleDone = () => {
setDone(!done);
};
return html`
<div class="${done ? "done" : "todo"}">
<h3>${todo.title}</h3>
<p>${todo.description}</p>
<button @click=${toggleDone}>Toggle</button>
</div>
`;
}
customElements.define(
"my-todo",
makeWebComponent(myTodo, {
props: ["todo"],
render,
})
);
const element = document.createElement("my-todo");
element.todo = {
title: "Buy apples",
description: "I really need that.",
};
document.body.appendChild(element);
API
makeWebComponent(functionComponent[, options])
Creates a Custom Element (a class extending HTMLElement
), which can be passed to customElements.define()
.
Arguments
functionComponent
- The component function.It receives one argument:
props
. This is an object containing the values of all declared attributes and properties (seeoptions.attrs
andoptions.props
).In addition the object contains a setter function for each value called
set<PropertyName>
. For example the propertygivenName
would have the setter functionsetGivenName
.options.attrs
- String array of attributes used in the component. For each attribute a corresponding property is created. When either attribute or property are changed, the other will reflect that change. Attributes are bound to DOM restrictions and can only be strings. Example:makeWebComponent(myComp, { attrs: ["age", "givenName"] });
Names written in camel case are converted to kebab case for attribute names. The example above makes the component listen for attributes
age
andgiven-name
.options.props
- String array of properties used in the component. Properties are not reflected as attributes and can have any type. Example:makeWebComponent(myComp, { props: ["userObject"] });
options.render
- If specified this function will be invoked every time the components needs to be rendered to the DOM. It's invoked with the result of the functionComponent invocation and the first and the parent node as the second argument. Example:function renderInnerHTML(html, parentNode) { parentNode.innerHTML = html; }
useState([initialValue])
Provides a way for function components to store internal state. Returns an array with two entries. The first is the current value, the second is a setter function for this piece of state. You can call this function multiple times, if you want to store multiple pieces of state.
Constraints
- It must be called syncronously in the
functionComponent
function. - It must not be called conditionally.
- The setter must not be invoked syncronously in the
functionComponent
function. It should be called on user interaction or at least in a new microtask. This is because setting state triggers another render.
Arguments
initialValue
- The initial value for this piece of state.
Example
const [fruit, setFruit] = useState("Apple");
const [amount, setAmount] = useState(42);
setTimeout(() => {
setAmount(amount - 1);
}, 5000);
props.set<PropertyName>(newValue[, options])
For every declared attribute or property a function component gets passed a corresponding setter function. For example the property givenName
would have the setter function setGivenName
. This sets the attribute/property to a new value and can optionally dispatch a change event. It does not trigger a render.
Arguments
newValue
- The new value for this attribute or property.options.eventName
- If specified, the function dispatches a custom event with name. The new value is used as thedetail
.
Contributing
Please see CONTRIBUTING.md.