Component script

The first <script> inside a <custom-element> is the component script. It is plain JavaScript in strict mode.

<custom-element name="todo-app">
  <script type="realm">
    const props = defineProps({ title: prop.string().default("Todo") });
    const todo = useState({ items: [], draft: "" });

    function add() {
      todo.items.push({ id: crypto.randomUUID(), title: todo.draft });
      todo.draft = "";
    }

    observe(() => {
      document.title = `${todo.items.length} · ${props.title}`;
    });
  </script>
  …
</custom-element>

How it runs

Helpers in scope

These names are available without importing. They are not exposed to markup unless you assign them to a top-level name.

Signatures

defineProps<T extends Record<string, PropType>>(schema: T): Record<keyof T, unknown>
useState<T extends object>(initial: T): T
observe(fn: () => unknown): () => void
tick(): Promise<void>
defineStore<T extends object>(name: string, initial: T, options?: StoreOptions): T
useChildren(selector: string, attributes?: string[]): Element[]
defineMethods(methods: object): void
dispatch(type: string, detail?: unknown, options?: CustomEventInit): boolean
listen(type: string, handler: (event: Event) => unknown, target?: EventTarget): void
lookup(name: string): unknown
onConnected(fn: () => unknown): void
onDisconnected(fn: () => void): void
onFormReset(fn: () => void): void
onFormDisabled(fn: (disabled: boolean) => void): void
onFormStateRestore(fn: (state: unknown, mode: string) => void): void
setTimeout(callback: (...args: unknown[]) => void, delay?: number, ...args: unknown[]): number
setInterval(callback: (...args: unknown[]) => void, delay?: number, ...args: unknown[]): number
clearTimeout(id?: number): void
clearInterval(id?: number): void

attrs: Record<string, string | null>
host: HTMLElement
refs: Record<string, Element>
signal: AbortSignal
internals: ElementInternals
prop: { string, number, boolean, enum, date, array, object }

The Context type exported by @realmorg/realm describes this object.

Order

Write scripts in this order, so they read the same way across components:

  1. defineProps
  2. useState (and defineStore)
  3. functions
  4. defineMethods, listen, lifecycle hooks
  5. observe

Edit this page on GitHub · View as Markdown