Docs

Theming

Try theme, size, layout, colorScheme and classNames live, and copy the props.

Every knob on this page writes props on <Form> (or KibbleProvider); nothing here needs a stylesheet beyond the one import from Styling. Change the controls and copy the code.

Preview

Usage

import { Form } from 'kibbleforms';

<Form
  schema={demoRequest}
  client={kibble}
  theme={{ primary: '#2563eb', radius: 'lg', colorScheme: 'auto' }}
  size="md"
  layout={{ columns: 2 }}
  classNames={{ label: 'uppercase tracking-wide', submit: 'rounded-full' }}
/>

Set the same theme, size and classNames once for the whole site on KibbleProvider; a form's own props win (theme per key, classNames per slot with both kept).

Props

theme

Key Variable Description
primary --kb-primary Submit button, selected rating, progress bar, checked boxes and radios.
primaryForeground --kb-primary-fg Text on primary, and the check or dot in a checked box.
background --kb-bg (and --kb-input-bg unless inputBackground is set) Surfaces inside the form.
foreground --kb-fg Text.
muted --kb-muted Hover, segmented track, success card.
mutedForeground --kb-muted-fg Help text, placeholders, progress text.
border --kb-border Control and card borders, unchecked boxes.
ring --kb-ring Focus ring, checked choice border.
error --kb-error Error text, invalid borders, required mark.
inputBackground --kb-input-bg Control background, unchecked boxes.
radius --kb-radius 'none' 0, 'sm' 0.25rem, 'md' 0.5rem, 'lg' 0.75rem, 'full' 9999px, or any CSS length.
font --kb-font Default inherit.
colorScheme data-kb-color-scheme 'dark' forces the built-in dark values, 'light' forces light, 'auto' follows prefers-color-scheme. Unset: follow a .dark / [data-theme="dark"] ancestor.

Values are applied as inline variables on the form root, so they beat stylesheet values, including the dark ones.

size

Size --kb-control-h --kb-text --kb-space --kb-gap
sm 2.25rem 14px 1rem 0.5rem
md (default) 2.5rem 15px 1.25rem 0.5rem
lg 3rem 16px 1.5rem 0.625rem

Rendered as data-kb-size on the root. md declares nothing, so your own :root values for these tokens keep working.

layout (Form only)

Key Type Description
columns 1 | 2 | 3 Grid for the auto-rendered fields and Page. One column below 640px.
full string[] Field keys that span every column. long_text, single_choice, multiple_choice and consent always do; so does the page header.

classNames

Slots: root, form, page, pageHeader, field, label, help, input (Input, Textarea, Select, DatePicker), option (each choice row), segment (each YesNo button), rating (each rating button), consent, error (FieldError), submit, button (Back and Next), progress, success. Merged with tailwind-merge in this order: the component's defaults, the provider's slot, the form's slot, then the component's own className.

Variants and states

<Form schema={waitlist} client={kibble} theme={{ primary: '#2563eb', ring: '#2563eb', radius: 'full', border: '#bfdbfe', muted: '#eff6ff', mutedForeground: '#1d4ed8' }} />
<div className="dark">   {/* or theme={{ colorScheme: 'dark' }} on the form */}
  <Form schema={waitlist} client={kibble} />
</div>

Customization

For anything the props don't cover, use the variables directly (:root, .dark, or a wrapper), the data-kb hooks from plain CSS, or the headless layer. See Styling for the five layers.

Accessibility

Keep contrast when you change colors: primaryForeground on primary and foreground on background should reach 4.5:1. Focus rings use ring; don't set it to the background color. colorScheme also sets the CSS color-scheme, so native controls (date picker, scrollbars) match.

Styling, Form, KibbleProvider, Components