Text Input
Input with Label
Subscribe Pattern
Documentation
Forms
Source files: input.tsx, select.tsx, textarea.tsx, checkbox.tsx, switch.tsx, slider.tsx, calendar.tsx, form.tsx, label.tsx
Note: radio-group.tsx and date-picker.tsx do not exist in the current Patina build.
Input
File: input.tsx
Primitive: Native <input>
Single-variant text input. Height h-9, responsive text (text-base / md:text-sm).
Token usage
| Token | Usage |
|---|---|
border-input |
Default border |
text-foreground |
File input text |
text-muted-foreground |
Placeholder |
primary, primary-foreground |
Selection highlight |
ring, border-ring |
Focus state |
destructive |
Invalid state (aria-invalid) |
bg-input/30 |
Dark mode background |
Select
File: select.tsx
Primitive: @radix-ui/react-select
Sub-components
| Component | Purpose |
|---|---|
Select |
Root (controlled/uncontrolled) |
SelectTrigger |
Button that opens the dropdown |
SelectValue |
Display for selected value |
SelectContent |
Dropdown panel (portaled) |
SelectGroup |
Option group container |
SelectLabel |
Group heading |
SelectItem |
Individual option (with check indicator) |
SelectSeparator |
Divider between groups |
SelectScrollUpButton / SelectScrollDownButton |
Scroll affordances |
SelectTrigger sizes
| Size | Dimensions |
|---|---|
default |
h-9 |
sm |
h-8 |
icon |
(no explicit height, icon-only) |
Props (SelectTrigger)
| Prop | Type | Default |
|---|---|---|
size |
"sm" \| "default" \| "icon" |
"default" |
dropdownIcon |
React.ReactNode |
<ChevronDownIcon> |
Token usage
bg-popover,text-popover-foreground(dropdown content)border-input,text-muted-foreground(trigger)bg-accent,text-accent-foreground(focused item)bg-border(separator)- Focus ring:
ring,border-ring
Textarea
File: textarea.tsx
Primitive: Native <textarea>
Auto-sizing via field-sizing-content, minimum height min-h-16. Shares the same border/focus/invalid token pattern as Input.
Checkbox
File: checkbox.tsx
Primitive: @radix-ui/react-checkbox
Fixed size-4, rounded-[4px]. Checked state uses bg-primary text-primary-foreground border-primary. Indicator renders a CheckIcon at size-3.5.
Token usage
border-input,bg-input/30(unchecked, dark)bg-primary,text-primary-foreground,border-primary(checked)- Focus / invalid: same ring pattern as Input
Switch
File: switch.tsx
Primitive: @radix-ui/react-switch
Track: h-[1.15rem] w-8 rounded-full. Thumb: size-4 rounded-full.
| State | Track | Thumb |
|---|---|---|
| Unchecked | bg-input |
bg-background (dark: bg-foreground) |
| Checked | bg-primary |
bg-background (dark: bg-primary-foreground) |
Slider
File: slider.tsx
Primitive: @radix-ui/react-slider
Supports single and range values. Track height: h-1.5. Thumb: size-4 rounded-full border-primary.
Props
| Prop | Type | Default | Notes |
|---|---|---|---|
tooltip |
boolean |
false |
Shows value tooltip on drag |
formatTooltip |
(value: number) => string |
toString |
Custom tooltip formatter |
rangeClassName |
string |
– | Additional class for the filled range |
rangeStyle |
CSSProperties |
– | Inline style for the filled range |
Token usage
bg-muted(track),bg-primary(range fill)border-primary,bg-background(thumb)ring-ring/50(thumb hover/focus)
Calendar
File: calendar.tsx
Primitive: react-day-picker (DayPicker)
Full calendar widget with day/month navigation. Supports single select, range select, and dropdown month/year pickers via captionLayout.
Props
| Prop | Type | Default |
|---|---|---|
showOutsideDays |
boolean |
true |
captionLayout |
"label" \| "dropdown" \| ... |
"label" |
buttonVariant |
Button variant | "ghost" |
Token usage
bg-background(calendar surface)bg-accent,text-accent-foreground(today, range middle, selected)bg-primary,text-primary-foreground(range start/end, single selected)text-muted-foreground(outside days, disabled, weekday headers)- CSS var
--cell-size: --spacing(8)controls cell dimensions
Sub-component: CalendarDayButton
Custom day cell that wraps Button with variant="ghost" size="icon". Adds data attributes for selection states (data-selected-single, data-range-start, data-range-end, data-range-middle).
Form (react-hook-form integration)
File: form.tsx
Primitive: react-hook-form FormProvider + Controller
Provides accessible form field wiring: auto-generated IDs, aria-describedby, aria-invalid, and error display.
Sub-components
| Component | Purpose |
|---|---|
Form |
Re-export of FormProvider |
FormField |
Wraps Controller, provides field context |
FormItem |
Container (grid gap-2) |
FormLabel |
Label with error styling (text-destructive on error) |
FormControl |
Radix Slot that injects id, aria-* attributes |
FormDescription |
Help text (text-muted-foreground text-sm) |
FormMessage |
Error message (text-destructive text-sm) |
Hook: useFormField()
Returns { id, name, formItemId, formDescriptionId, formMessageId, ...fieldState }.
Label
File: label.tsx
Primitive: @radix-ui/react-label
Styled label: text-sm font-medium, select-none. Respects group-data-[disabled=true] and peer-disabled for opacity changes.