Skip to content

Kobalte

Use Kobalte primitives to draw GistUI components in Solid and SolidStart, with form validation and bind:$var still working.

Updated View as Markdown

For Solid apps that use Kobalte, or solid-ui, which is built on it.

npm i @gistui/solid @gistui/styles @gistui/catalog @kobalte/core

A switch

Kobalte form primitives take name and render a native input (Switch.Input), so the GistUI Form around them can read the value.

GistSwitch.tsxtsx
import { Switch } from "@kobalte/core/switch";
import { createGistField, type GistUIComponentProps } from "@gistui/solid";

export function GistSwitch(p: GistUIComponentProps) {
  const field = createGistField(p, "bool"); // one on/off value
  return (
    <Switch
      class="switch-row"
      name={field().name}
      disabled={field().locked}
      checked={field().bound ? field().value === true : undefined}
      defaultChecked={field().bound ? undefined : p.props.checked === true}
      onChange={(on) => field().bound && field().setValue(on)}
    >
      <Switch.Input />
      <Switch.Control class="switch">
        <Switch.Thumb class="switch-thumb" />
      </Switch.Control>
      <Switch.Label>{field().label}</Switch.Label>
    </Switch>
  );
}

A card

GistCard.tsxtsx
import { GistChildren, type GistUIComponentProps } from "@gistui/solid";

export function GistCard(p: GistUIComponentProps) {
  return <section class="my-card" data-gistui="Card"><GistChildren /></section>;
}

Register them

import { GistUI } from "@gistui/solid";

<GistUI source={answer()} streaming={loading()} components={{ Switch: GistSwitch, Card: GistCard }} onAction={onAction} />;

Notes

  • createGistField returns an accessor: call it (field().name) so Solid tracks changes.
  • Keep GistUI’s built-in Button and style it with tokens: actions, form submits and dialogs then keep working.
  • Kobalte ships no styles. Use tokens so the GistUI components you did not replace match yours.
Navigation

Type to search…

↑↓ navigate↵ selectEsc close