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 });