Overview
Field primitives provide the visual building blocks for form fields when you can't use FormBlock. They match the styling of FormBlock forms so participants see consistent forms regardless of how they're built.
Key Features
- Visual consistency with FormBlock forms
- Works without react-hook-form context
- Five components: Wrapper, Label, Description, Error, HelpText
- Composable with any input primitives
When to Use
Use Field Primitives When
- Building forms in wizard steps controlled by parent state
- Creating dynamic form renderers (FormEngineBlock)
- Needing consistent field styling without FormBlock
Skip When
- -Building standalone forms with Zod schemas (use FormBlock)
- -Forms with auto-save or complex validation (use FormBlock)
Examples
Basic Field
Simple field with label and required indicator.
With Description
Field with description text and help text.
We'll use this for notifications
Your email will never be shared
Error State
Field showing validation error.
Password must be at least 8 characters
Long Text Field
Textarea field with description and help text.
Tell us about yourself
Maximum 500 characters
Module Exports
| Component | Purpose |
|---|---|
| FieldWrapper | Container with consistent spacing (space-y-2) |
| FieldLabel | Label with optional required indicator |
| FieldDescription | Helper text above the input (text-sm) |
| FieldError | Error message display (text-destructive) |
| FieldHelpText | Additional hints below input (text-xs) |
Props Reference
FieldLabel Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | - | Label text content |
required | boolean | false | Shows red asterisk (*) indicator |
htmlFor | string | - | Associates label with input via id |
className | string | - | Additional CSS classes |
Usage
import { FieldWrapper, FieldLabel, FieldDescription, FieldError, FieldHelpText } from '@/ui/blocks';
import { Input, Textarea } from '@/ui/primitives';
// Basic field with label and input
<FieldWrapper>
<FieldLabel htmlFor="name" required>Name</FieldLabel>
<Input id="name" placeholder="Enter your name" />
</FieldWrapper>
// Field with description and help text
<FieldWrapper>
<FieldLabel htmlFor="email">Email</FieldLabel>
<FieldDescription>We'll use this for notifications</FieldDescription>
<Input id="email" type="email" />
<FieldHelpText>Your email will never be shared</FieldHelpText>
</FieldWrapper>
// Field with error state
<FieldWrapper>
<FieldLabel htmlFor="password" required>Password</FieldLabel>
<Input id="password" type="password" className="border-destructive" />
<FieldError>Password must be at least 8 characters</FieldError>
</FieldWrapper>
// Long text field
<FieldWrapper>
<FieldLabel htmlFor="bio">Bio</FieldLabel>
<FieldDescription>Tell us about yourself</FieldDescription>
<Textarea id="bio" rows={4} />
<FieldHelpText>Maximum 500 characters</FieldHelpText>
</FieldWrapper>