# Date field (goodtabs UI)

A native date input with a calendar icon and an optional hint line below it.

## Install

```bash
npx shadcn@latest add https://ui.goodtabs.co/r/date-field.json
```

Or, with the @goodtabs namespace configured in components.json: `npx shadcn@latest add @goodtabs/date-field`

## Usage

```tsx
import { DateField } from "@/components/ui/date-field"

<Label htmlFor="due">Due date</Label>
<DateField id="due" min="2026-11-01" onChange={(e) => setDue(e.target.value)} />
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| hint | `ReactNode` |  | A line under the field, for example the allowed range. Off by default because the browser formats the value for its locale. |
| min | `string` |  | Earliest date as YYYY-MM-DD. Native Input prop. |
| max | `string` |  | Latest date as YYYY-MM-DD. Native Input prop. |
| value, defaultValue, onChange | `Input props` |  | Controlled or uncontrolled, always as a YYYY-MM-DD string. |

## When to use

- Due dates, birthdays, start and end dates in a form
- Anywhere a single day is enough and the platform picker is welcome
- Date ranges, as two fields bounded by each other

## When not to use

- Picking a range on one calendar or showing availability: build a custom calendar
- Date and time together, which needs type="datetime-local" and its own layout
- Anything that must look the same in every browser; native pickers differ by platform

## Notes for agents

- Server component: it holds no state. It extends shadcn's Input, so value, min, max, disabled and onChange pass through
- The value is always a YYYY-MM-DD string whatever the display locale; the browser displays it in the user's locale, so do not promise a display format in a hint
- The native picker glyph is hidden and its hit area sits over the calendar icon, so clicking the icon still opens the picker in Chromium
- Pair it with a Label through id; the hint is linked by aria-describedby when shown

Docs: https://ui.goodtabs.co/components/date-field