# Forms & Inputs ## Contents - Forms use Field.FieldGroup + Field.Field - InputGroup requires InputGroup.Input/InputGroup.Textarea - Buttons inside inputs use InputGroup.Root + InputGroup.Addon - Option sets (2–7 choices) use ToggleGroup.Root + ToggleGroup.Item - Field.FieldSet + Field.FieldLegend for grouping related fields - Field validation and disabled states --- ## Forms use Field.FieldGroup + Field.Field Always use `Field.FieldGroup` + `Field.Field` — never raw `div` with `space-y-*`: ```svelte Email Password ``` Use `Field` with `orientation="horizontal"` for settings pages. Use `Field.FieldLabel` with `class="sr-only"` for visually hidden labels. **Choosing form controls:** - Simple text input → `Input` - Dropdown with predefined options → `Select` - Searchable dropdown → `Combobox` - Native HTML select (no JS) → `native-select` - Boolean toggle → `Switch` (for settings) or `Checkbox` (for forms) - Single choice from few options → `RadioGroup` - Toggle between 2–5 options → `ToggleGroup.Root` + `ToggleGroup.Item` - OTP/verification code → `InputOTP` - Multi-line text → `Textarea` --- ## InputGroup requires InputGroup.Input/InputGroup.Textarea Never use raw `Input` or `Textarea` inside an `InputGroup.Root`. **Incorrect:** ```svelte ``` **Correct:** ```svelte ``` --- ## Buttons inside inputs use InputGroup.Root + InputGroup.Addon Never place a `Button` directly inside or adjacent to an `Input` with custom positioning. **Incorrect:** ```svelte
``` **Correct:** ```svelte ``` --- ## Option sets (2–7 choices) use ToggleGroup.Root + ToggleGroup.Item Don't manually loop `Button` components with active state. **Incorrect:** ```svelte
{#each ["daily", "weekly", "monthly"] as option (option)} {/each}
``` **Correct:** ```svelte Daily Weekly Monthly ``` Combine with `Field` for labelled toggle groups: ```svelte Theme Light Dark System ``` --- ## Field.FieldSet + Field.FieldLegend for grouping related fields Use `Field.FieldSet` + `Field.FieldLegend` for related checkboxes, radios, or switches — not `div` with a heading: ```svelte Preferences Select all that apply. Dark mode ``` --- ## Field validation and disabled states Both attributes are needed — `data-invalid`/`data-disabled` styles the field (label, description), while `aria-invalid`/`disabled` styles the control. ```svelte Email Invalid email address. Email ``` Works for all controls: `Input`, `Textarea`, `Select`, `Checkbox`, `RadioGroupItem`, `Switch`, `Slider`, `NativeSelect`, `InputOTP`.