Getting started
Author custom elements
Typed properties, templates that update only what changed, scoped styles, and cleanup that follows the element.
Declare the element
OddkinElement.with() declares public properties with their attribute conversion, defaults, and reflection; the metadata and the TypeScript types come from the same declaration.
import { OddkinElement, prop } from '@oddkin/core';
export class DemoGreeting extends OddkinElement.with({
name: prop.string({ default: 'world', description: 'Who to greet.' }),
excited: prop.boolean({ reflect: true, description: 'Adds emphasis.' }),
}) {}Template, styles, and registration
A definition joins the class, its template, and its styles; define() registers it. Keep registration in its own module so importing the element registers nothing.
import { compose, css, define, html } from '@oddkin/core';
import { DemoGreeting } from './demo-greeting.js';
export const demoGreetingDefinition = compose({
name: 'demo-greeting',
element: DemoGreeting,
template: (el: DemoGreeting) => html`<p>Hello, ${el.name}${el.excited ? '!' : '.'}</p>`,
styles: css`
:host {
display: block;
}
`,
});
define(demoGreetingDefinition);Reactivity and ownership
Reading a property or a signal’s .value while rendering tracks it, so the element renders again when it changes. Work started in connected(scope) belongs to that scope and stops when the element disconnects. Core concepts explains both.