Overview
Define custom elements
Osagai let you define your custom elements in a functional way, making than reusable and think about the separation of the component logic from the view. Custom elements can be defined using the define
function, passing the name of the component with the Component
function
Component function
Osagai Components are functions that will define your custom element. They need to return a Template
function and can be used to add the logic of your custom element. Like adding event listeners, making api calls or initialize variables. Osagai will pass useful arguments to the Component like the element
reference and methods like query
and queryAll
that you can use to query elements in the element DOM tree. Both methods return a promise resolving the value as the element that match the query.
function Component({element, query, queryAll}) {
/* ✨ Some magic here ✨ */
return () => `<h1>Hello</h1>`
}
Template function
The template function is what will define the layout of your custom element and it will be executed during the connectedCallback lifecycle. The interface of the Template
function is simple, it needs to return a string that will define the layout of the custom element:
function Template() {
return '<h1>Hello</h1>'
}
If your components doesn't need a layout (Renderless component), you do not need to return a string, just execute your logic inside this function.
function RenderlessTemplate() {
window.addEventListener('resize', runSomething)
}
Osagai will pass as argument of the Template
function the data needed for your layout. This is usually changed with the update
function of the osagai/dom
module.
const initialData = {name: 'world'}
function Template(data = initialData) {
return `<h1>Hello ${data.name}</h1>`
}
Custom renderer
Osagai consider the template of the custom element as string. Initialization and updates of the element are all based of strings, it uses innerHTML
for the initialization and morphdom for the updates. But if you want to have a custom initialization and update, you can use the renderer
option on the definition of the custom element. This is a function that receives the element
and the template
result with the current data. For example, you could use lit-html for manipulating the DOM in this way:
import { define } from 'osagai'
import { render, html } from 'lit-html';
function renderer(element, template) {
render(template, element);
}
function LitComponent() {
return () => html`<h1>Hello</h1>`;
}
define('lit-component', LitComponent, { renderer });