# Input Components

> Generated reference (regen-owned; see [index.md](index.md)). Binds only under `primitives: nurix`.

## Shared Props

Enhanced form components support these props where applicable:

| Prop | Type | Description |
| --- | --- | --- |
| `value` | `any` | Controlled value |
| `onChange` | `(value) => void` | Change handler (text inputs receive the event) |
| `onSave` | `(value) => void` | Commit on blur/Enter/selection |
| `disabled` | `boolean` | Prevents interaction |
| `readOnly` | `boolean` | Display-only mode |
| `inline` | `boolean` | Click-to-edit mode |

## Cell

Compound component for form field layout with label, content, and helpers.

**Props:** `mode` [default|inline], `size` [sm|md|lg], `editable`, `labelPosition` [top|left], `disabled`

**Sub-components:** `Cell.Label`, `Cell.Content`, `Cell.Prefix`, `Cell.Suffix`, `Cell.Stepper`, `Cell.Helper`, `Cell.Error`

```tsx
<Cell mode="default" labelPosition="top">
  <Cell.Label>Email</Cell.Label>
  <Cell.Content>
    <Input value={email} onChange={(e) => setEmail(e.target.value)} />
  </Cell.Content>
  <Cell.Helper>We'll never share your email</Cell.Helper>
</Cell>
```

## Input

Text input with optional regex validation; commits on blur via `onSave`.

**Props:** `onSave`, `validator`, `onValidationError`, `hideBorder`

```tsx
<Input
  value={name}
  onChange={(e) => setName(e.target.value)}
  onSave={saveName}
  placeholder="Enter name"
/>
```

## NumberInput

Numeric input with constraints; commits on blur/Enter, Escape reverts.

**Props:** `min`, `max`, `step`, `allowDecimals`, `allowNegative`, `onSave`, `onValidationError`, `hideBorder`

```tsx
<NumberInput value={count} onSave={setCount} min={0} max={100} step={1} />
```

## Textarea

Multi-line text input. Controlled when `value` is set; otherwise `defaultValue` seeds an internal draft and Escape resets it. Blur and Cmd/Ctrl+Enter commit via `onSave`.

**Props:** `onSave`, `hideBorder`

```tsx
<Textarea
  value={description}
  onChange={(e) => setDescription(e.target.value)}
  onSave={saveDescription}
/>
```

## Checkbox

Boolean toggle supporting both `value`/`onChange` and `checked`/`onCheckedChange` APIs.

**Props:** `checked`, `onCheckedChange`, `value`, `onChange`, `indeterminate`

```tsx
<Checkbox checked={agreed} onCheckedChange={setAgreed} />
```

## Switch

Toggle switch supporting both `value`/`onChange` and `checked`/`onCheckedChange` APIs.

**Props:** `checked`, `onCheckedChange`, `value`, `onChange`, `size` [sm|default]

```tsx
<Switch checked={enabled} onCheckedChange={setEnabled} />
```

## Select

Compound select with search, multi-select, and async loading. `onChange`/`onSave` receive the selected option object(s), not raw values.

**Props:** `options`, `mode` [single|multi], `clearable`, `maxSelections`, `selectionIndicator` [checkbox|check-end|bg-only], `compact`, `loading`, `onSearch`, `onLoadMore`, `debounceMs`

**Sub-components:** `Select.Trigger` (`display` [tags|comma|count]), `Select.Content` (`searchable`, `searchPlaceholder`, `showSelectAll`, `maxHeight`), `Select.Item`, `Select.Search`, `Select.Loading`, `Select.Empty`, `Select.SelectAll`

```tsx
<Select
  options={statusOptions}
  value={status}
  onChange={(opt) => setStatus(opt?.value)}
>
  <Select.Trigger display="tags" />
  <Select.Content searchable>
    <Select.Item value="active">Active</Select.Item>
  </Select.Content>
</Select>
```

## Option

Standalone option display chip (exported from the `select` subpath).

**Props:** `variant` [text|pill|outline|ghost|soft], `color`, `prefix` ["dot"|ReactNode]

```tsx
<Option variant="pill" color="#ef4444" prefix="dot">
  High Priority
</Option>
```

## DatePicker

Date selection with calendar popover; accepts `Date`, ISO string, or null values.

**Props:** `onSave`, `inline`, `relativeFormat`, `formatPattern`, `showIcon`, `captionLayout` [label|dropdown|dropdown-months|dropdown-years], `buttonVariant`, `showOutsideDays`, `numberOfMonths`, `fromYear`, `toYear`, `fromDate`, `toDate`, `weekStartsOn`, `compact`

```tsx
<DatePicker
  value={date}
  onChange={setDate}
  onSave={handleSave}
  relativeFormat
  placeholder="Pick a date"
/>
```

## Slider

Range input with optional value display.

**Props:** `min`, `max`, `step`, `defaultValue`, `onSave`, `inline`, `showValue`, `showMinMax`, `formatValue`, `compact`

```tsx
<Slider
  value={volume}
  onChange={setVolume}
  onSave={handleSave}
  min={0}
  max={100}
/>
```

## Rating

Icon-based rating input.

**Props:** `maxRating`, `size`, `icon` [Star|Heart|ThumbsUp|Circle|Flame|Zap|Trophy|Diamond], `allowHalf`, `showValue`, `onSave`, `inline`, `compact`

```tsx
<Rating
  value={rating}
  onChange={setRating}
  onSave={handleSave}
  maxRating={5}
  allowHalf
/>
```

## Button

Standard action button.

**Props:** `variant` [default|destructive|outline|secondary|ghost|link], `size` [default|sm|lg|icon], `asChild`

```tsx
<Button variant="outline" size="sm">
  Cancel
</Button>
```

## Calendar

Calendar grid built on `react-day-picker`; accepts all `DayPicker` props. Also exports `CalendarDayButton`.

**Props:** `mode` [single|multiple|range], `selected`, `onSelect`, `captionLayout` [label|dropdown|dropdown-months|dropdown-years], `numberOfMonths`, `showOutsideDays`, `buttonVariant`

```tsx
<Calendar
  mode="single"
  selected={date}
  onSelect={setDate}
  captionLayout="dropdown"
/>
```

## DateRangePicker

Date range selection with calendar popover and optional presets sidebar; `onSave` fires only when both ends are selected, and closing with a partial selection reverts.

**Props:** `onSave`, `inline`, `showPresets`, `presets`, `relativeFormat`, `formatPattern`, `showIcon`, `captionLayout`, `numberOfMonths`, `fromDate`, `toDate`, `weekStartsOn`, `compact`

```tsx
<DateRangePicker
  value={range}
  onChange={setRange}
  onSave={handleSave}
  showPresets
/>
```

## IconPicker

Searchable Lucide icon picker popover; also exports `Icon` for rendering a picked icon by name.

**Props:** `value`, `defaultValue`, `onValueChange`, `open`, `onOpenChange`, `searchable`, `searchPlaceholder`, `triggerPlaceholder`, `iconsList`, `categorized`, `modal`

```tsx
<IconPicker value={iconName} onValueChange={setIconName} />
```

## InputOTP

One-time code input built on `input-otp`.

**Props:** `maxLength`, `value`, `onChange`, `containerClassName`

**Sub-components:** `InputOTPGroup`, `InputOTPSlot` (`index` required), `InputOTPSeparator`

```tsx
<InputOTP maxLength={4} value={code} onChange={setCode}>
  <InputOTPGroup>
    <InputOTPSlot index={0} />
    <InputOTPSlot index={1} />
    <InputOTPSlot index={2} />
    <InputOTPSlot index={3} />
  </InputOTPGroup>
</InputOTP>
```

## MediaFilePicker

File upload with drag-and-drop dialog and previews. `value` is `MediaFileOption` object(s): `{ value, label, type, previewUrl, size, file }`.

**Props:** `mode` [single|multi], `maxFiles`, `maxFileSize`, `acceptedTypes`, `viewMode` [card|list], `display` [thumbnails|comma|tags], `renderPlainText`, `renderComponent`

```tsx
<MediaFilePicker value={files} onChange={setFiles} mode="multi" maxFiles={5} />
```

## NativeSelect

Radix-based select primitive family on the `native-select` subpath (distinct from the compound `Select` above); exported symbols are named `Select*`.

**Props:** `value`, `onValueChange`, `defaultValue`, `disabled` (root passes through all Radix Select props)

**Sub-components:** `Select`, `SelectTrigger` (`size` [sm|default]), `SelectValue`, `SelectContent`, `SelectGroup`, `SelectLabel`, `SelectItem`

```tsx
<Select value={fruit} onValueChange={setFruit}>
  <SelectTrigger>
    <SelectValue placeholder="Pick one" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="apple">Apple</SelectItem>
  </SelectContent>
</Select>
```

## RadioGroup

Radix radio group with card and segmented-control variants.

**Props:** `value`, `defaultValue`, `onValueChange`

**Sub-components:** `RadioGroupItem`, `RadioGroupCard` (`variant` [card|list|chip]), `RadioGroupCardItem`, `RadioGroupLabel` (`clickable`), `RadioGroupDescription`, `RadioGroupItemHeader/Title/Subtitle/Description/Content/Indicator`, `RadioGroupSegmented`, `RadioGroupSegmentedItem` (`icon`)

```tsx
<RadioGroup value={plan} onValueChange={setPlan}>
  <RadioGroupCard>
    <RadioGroupItem value="free" />
    <RadioGroupLabel clickable>Free</RadioGroupLabel>
  </RadioGroupCard>
  <RadioGroupCard>
    <RadioGroupItem value="pro" />
    <RadioGroupLabel clickable>Pro</RadioGroupLabel>
  </RadioGroupCard>
</RadioGroup>
```

## Toggle

Pressed-state button supporting both `value`/`onChange` and `pressed`/`onPressedChange` APIs.

**Props:** `pressed`, `onPressedChange`, `value`, `onChange`, `variant` [default|outline|primary], `size` [default|sm|lg], `density` [compact|comfortable|spacious]

```tsx
<Toggle pressed={isBold} onPressedChange={setIsBold} variant="outline">
  B
</Toggle>
```

## ToggleGroup

Group of toggles with single or multiple selection; `variant`/`size`/`density` cascade to items.

**Props:** `type` [single|multiple], `value`, `defaultValue`, `onValueChange`, `variant` [default|outline|primary], `size` [default|sm|lg], `density` [compact|comfortable|spacious]

**Sub-components:** `ToggleGroupItem`

```tsx
<ToggleGroup
  type="single"
  value={align}
  onValueChange={setAlign}
  variant="outline"
>
  <ToggleGroupItem value="left">Left</ToggleGroupItem>
  <ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>
```
