Components
component() defines a real custom element and returns a typed factory for composition.
Props are signals
Declare props as a TypeScript interface. Inside setup, every prop is a Signal — read .value or use it in a template. The setup function must be synchronous.
import { component, computed, html } from '@nisli/core';
interface GreetingProps { name: string }
const Greeting = component<GreetingProps>('x-greeting', (props) => {
const upper = computed(() => props.name.value.toUpperCase());
return html`<p>Hello, ${upper}</p>`;
});
Factory composition
Calling Greeting({ name: 'nisli' }) returns a template you compose into other components. Pass a plain value for static props, or a signal to stay reactive.
Lifecycle
onMount() runs after the element connects; onCleanup() runs on teardown. Effects created in setup are disposed automatically.
import { component, onMount, onCleanup, html } from '@nisli/core';
component('x-clock', () => {
onMount(() => {
const id = setInterval(tick, 1000);
onCleanup(() => clearInterval(id));
});
return html`<time></time>`;
});