Frameworks
The elements are custom elements, so any framework that renders custom elements can use them.
The elements are custom elements, so any framework that renders custom elements can use them. For React and Vue the package also ships one component per element, typed from the element. For Preact, Solid, Svelte and Vue templates it ships types for the elements’ own tags.
Load the stylesheet once, as in plain HTML:
React
React 19 is required. Each element has a component named after it without the tp- prefix: <tp-select> is Select and <tp-select-option> is SelectOption. Import components from @tweakpad/ui/react, widgets from @tweakpad/ui/widgets/react, or one component folder from @tweakpad/ui/react/<name>:
- Props. Every property of the element is a prop with the element’s own type, including objects, arrays and functions (
items,filter,renderItem). A prop you leave out keeps the element’s default. - Changes. A controllable value has a callback prop named after it:
onValueChange,onCheckedChange,onOpenChange,onPressedChange. It receives the proposal event (the new value isevent.detail.value) for the element’s own value only, not for its descendants. Write the value back to state to accept it, write nothing to keep the current one, or write another value to replace it. Callevent.preventDefault()to refuse a proposal outright. - Events. Every event is a prop named
onTpand the rest of the event name:tp-open-change-completeisonTpOpenChangeComplete. Events bubble, so a handler on a group also receives its items’ events of the same name; the callback props do not. - Uncontrolled. Pass
defaultValue,defaultCheckedordefaultOpenand leave the value out; the element keeps its own state. - Slots. Put
slot="…"on a child:<Button slot="trigger">. - Refs.
refis the element, with its methods:ref.current.focus(),ref.current.setOpen(true). - Registration. A component defines its element when it first renders, so nothing needs registering first, and importing a component bundles only its element.
- Server rendering. The components are client components (
'use client') and import on the server. The server renders the element’s tag with its string, number and boolean props as attributes; the element renders itself when it loads in the browser.
To write the tags themselves instead (<tp-select>), import the tag types once, for example in a .d.ts file, and register the elements before React renders them:
React then sets the elements’ properties, and listens to an event through a prop with the exact event name: ontp-value-change. React reads any on… prop on a tag as a listener, so the callback properties (onValueChange) are not available on tags; use the components for them.
Vue
Vue 3.4 or later. Components come from @tweakpad/ui/vue (widgets from @tweakpad/ui/widgets/vue), named as for React:
v-model. Each controllable value has its ownv-model:<name>(v-model:checked,v-model:open,v-model:value); plainv-modelbinds the element’s main value. Give the model a value from the start: an element whose value starts asundefinedstays uncontrolled.- Props. Every element property is a prop, typed by the element, set as a property, so objects and arrays work and
<Button disabled />is disabled. An omitted prop keeps the element’s default. - Events. Listen with the event name:
@tp-open-change-complete="…". The callback props (:on-value-change, or@value-change) receive the element’s own proposals, as in React. - Slots, refs and registration work as in React:
slot="…"on a child, a template ref is the element, and a component defines its element when it is set up.
To write the tags themselves, register the elements, tell the compiler they are custom elements and add the tag types:
Use .prop for an object property on a tag (:items.prop="items") and @tp-… for events.
Preact, Solid and Svelte
Register the elements and add the tag types for the framework, which declare every element’s properties and events:
ontp-value-change={…}on:tp-value-change={…}ontp-value-change={…}bind: is not available.Angular
Add CUSTOM_ELEMENTS_SCHEMA to the components that use the elements, register them in main.ts, bind properties with [items]="items" and events with (tp-value-change)="…". Angular does not type-check custom element templates.