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.