Installation
Framework guides
The elements are standard custom elements: frameworks render them like any HTML element. Opt-in typings check properties and events in React, Vue, and Svelte templates.
Verified versions
| Framework | Version | Checked by |
|---|---|---|
| React | 19.3.1 | tests/frameworks/react (tsc) |
| Vue | 3.5.44 | tests/frameworks/vue (vue-tsc) |
| Svelte | 5.57.2 | tests/frameworks/svelte (svelte-check) |
The React, Vue, and Svelte typings are checked by compile-time fixtures in tests/frameworks as part of npm run typecheck: each fixture uses real elements and lists the mistakes its checker must reject.
React
React 19 sets properties on custom elements and listens to their events through on plus the event name. Import the typings once to type every registered element:
import type {} from '@oddkin/components/frameworks/react';
import '@oddkin/components/define/side-nav';
import type { NavigationItem } from '@oddkin/components/side-nav';
export function Shell({
items,
run,
}: {
items: readonly NavigationItem[];
run: (action: string) => void;
}) {
return (
<odd-side-nav
label="Primary"
items={items}
current="overview"
onodd-action={(event) => run(event.detail.action)}
/>
);
}Vue
Tell Vue’s compiler that odd-* tags are custom elements (compilerOptions.isCustomElement), then bind properties with : and events with @. v-model works on the form controls.
<script setup lang="ts">
import type {} from '@oddkin/components/frameworks/vue';
import '@oddkin/components/define/input';
import { ref } from 'vue';
const name = ref('Ada');
</script>
<template>
<odd-input v-model="name" label="Name" name="name" required />
</template>Svelte
Svelte 5 sets properties when the element has them; event attributes use on plus the event name.
<script lang="ts">
import type {} from '@oddkin/components/frameworks/svelte';
import '@oddkin/components/define/input';
let name = $state('Ada');
</script>
<odd-input
label="Name"
name="name"
value={name}
oninput={(event) => (name = event.currentTarget.value)}
></odd-input>Angular
Add CUSTOM_ELEMENTS_SCHEMA to the component that renders odd-* tags, bind properties with [property] and events with (odd-action). Angular has no typings fixture yet, so its templates are not type-checked against the elements.
External stores
A store with getSnapshot() and subscribe() (React’s useSyncExternalStore shape, Redux, Zustand) is read with fromExternal() from @oddkin/core/reactive, and any Oddkin signal is exposed the same way with toExternal(). See core-contracts.md §5.