Field
Reusable field layout primitives for labels, descriptions, errors, fieldsets, grouped controls, separators, titles, and responsive rows.
import { Field, FieldLabel, FieldSet, FieldLegend, FieldGroup, FieldContent } from 'radcn/field'Live package example
Compose input, textarea, select, switch, checkbox, radio, slider, grouped sections, responsive rows, and choice cards with Field primitives.
Workspace Settings
Compose input, textarea, select, switch, checkbox, radio, slider, grouped sections, responsive rows, and choice cards with Field primitives.
import { Button } from 'radcn/button'
import { Checkbox } from 'radcn/checkbox'
import {
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSeparator,
FieldSet,
FieldTitle,
} from 'radcn/field'
import { Input } from 'radcn/input'
import { RadioGroup, RadioGroupItem } from 'radcn/radio-group'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from 'radcn/select'
import { Slider } from 'radcn/slider'
import { Switch } from 'radcn/switch'
import { Textarea } from 'radcn/textarea'
export function FieldPreview() {
return (
<form action="/checkout" method="post">
<FieldGroup>
<FieldSet>
<FieldLegend>Workspace</FieldLegend>
<FieldDescription>Field owns reusable layout; form owns submission.</FieldDescription>
<FieldGroup>
<Field>
<FieldLabel for="workspace">Workspace name</FieldLabel>
<Input id="workspace" name="workspace" value="RadCN" />
</Field>
<Field orientation="responsive">
<FieldContent>
<FieldLabel for="notes">Launch notes</FieldLabel>
<FieldDescription>Responsive fields collapse on small screens.</FieldDescription>
</FieldContent>
<Textarea id="notes" name="notes" value="Ship web-first components." />
</Field>
</FieldGroup>
</FieldSet>
<FieldSeparator />
<FieldSet>
<FieldLegend>Controls</FieldLegend>
<Field>
<FieldLabel for="payment">Payment method</FieldLabel>
<Select defaultValue="card" id="payment" name="payment">
<SelectTrigger ariaLabel="Payment method"><SelectValue>Card</SelectValue></SelectTrigger>
<SelectContent><SelectItem value="card">Card</SelectItem></SelectContent>
</Select>
</Field>
<Field orientation="horizontal">
<Switch checked id="alerts" name="alerts" />
<FieldContent>
<FieldLabel for="alerts">Security alerts</FieldLabel>
<FieldDescription>Horizontal rows keep label copy beside the control.</FieldDescription>
</FieldContent>
</Field>
<Field>
<FieldTitle>Budget range</FieldTitle>
<FieldDescription>Use native range controls and server defaults.</FieldDescription>
<Slider ariaLabel="Budget minimum" defaultValue={200} name="budget_min" />
</Field>
</FieldSet>
<RadioGroup name="plan">
<Field class="radcn-field--choice-card border border-[var(--radcn-field-choice-border,var(--radcn-border))] rounded-md p-[0.875rem]" orientation="horizontal">
<RadioGroupItem checked id="plan-pro" name="plan" value="pro" />
<FieldContent>
<FieldLabel for="plan-pro"><FieldTitle>Pro</FieldTitle></FieldLabel>
<FieldDescription>Card-like choices are composition, not a separate component.</FieldDescription>
</FieldContent>
</Field>
</RadioGroup>
<Field orientation="horizontal">
<Checkbox checked id="save" name="save" value="yes" />
<FieldContent>
<FieldLabel for="save">Save as template</FieldLabel>
<FieldDescription>Checkbox rows use the same FieldContent pattern.</FieldDescription>
</FieldContent>
</Field>
<Button type="submit">Save workspace</Button>
</FieldGroup>
</form>
)
}Installation
Intended future install command. RadCN is private and not published to npm yet, so this snippet documents the target user-facing API rather than something external consumers can run today.
pnpm add radcn # intended future package
import { Field, FieldLabel, FieldSet, FieldLegend, FieldGroup, FieldContent } from 'radcn/field'Theming
RadCN tokens read the resolved theme from the document. Store the user's preference separately, then resolve system preferences to a concrete light or dark theme before setting package tokens.
<html data-radcn-theme-mode="system" data-radcn-theme="dark">
...
</html>Accessibility
- FieldLabel renders a real label, FieldSet renders fieldset, and FieldLegend renders legend so grouped controls keep platform semantics.
- Field orientation is represented with data-orientation and CSS classes; it does not change form submission or accessible naming.
- Descriptions, errors, and titles are explicit content elements that apps wire to controls with native IDs and ARIA attributes when needed.
Customization
- Field parts expose data-radcn-field, field-label, field-set, field-legend, field-group, field-content, field-title, field-description, field-error, and field-separator hooks.
- Vertical, horizontal, responsive, and choice-card layouts are token-driven CSS hooks, so apps can restyle spacing and borders without replacing primitives.
- Field composes with existing input, textarea, select, checkbox, radio, switch, slider, and button primitives instead of owning control state.
Remix 3 Notes
- shadcn/ui Field examples use React composition and, for slider value text, React state. RadCN maps this to native controls, server defaults, and optional app-owned browser enhancement.
- radcn/field owns reusable layout and grouping primitives. radcn/form remains the explicit server/action wiring API for submitted forms and validation messages.
- RadCN does not require DOM equivalence with shadcn/ui; parity is visual behavior, accessibility, and author-facing modifiability with Remix 3 host elements.
