# DatePicker

> A date field people can type into or fill from a calendar popover.

Category: Forms · Status: stable · Package: @bindshq/stance-react@0.1.1 · Docs: https://stanceui.com/components/date-picker

Use DatePicker for a single date in a form. People can type the date in their locale’s order (for example 31/01/2026 in the UK), or open the calendar with the button or Alt+↓. Typed input is validated on blur and Enter. Inside a form, name submits the value as ISO yyyy-mm-dd.

## Import

```tsx
import { DatePicker } from '@bindshq/stance-react';
```

Styles are imported once per app: `@bindshq/stance-tokens/css` and `@bindshq/stance-react/styles.css`.

## Examples

### Basic

```tsx
import { DatePicker, FormField } from '@bindshq/stance-react';

const TODAY = new Date(2026, 10, 11);

export function Basic() {
  return (
    <FormField
      label="Go-live date"
      description="Signatures update at 00:00 on this day."
      style={{ width: 280 }}
    >
      <DatePicker locale="en-GB" today={TODAY} name="goLive" />
    </FormField>
  );
}
```

### With constraints

Weekdays from today onwards.

```tsx
import { DatePicker, FormField } from '@bindshq/stance-react';

const TODAY = new Date(2026, 10, 11);

export function WithConstraints() {
  return (
    <FormField label="Roll-out date" style={{ width: 280 }}>
      <DatePicker
        locale="en-GB"
        today={TODAY}
        min={TODAY}
        isDateDisabled={(d) => d.getDay() === 0 || d.getDay() === 6}
      />
    </FormField>
  );
}
```

### Controlled

```tsx
import { useState } from 'react';
import { DatePicker, FormField } from '@bindshq/stance-react';

const TODAY = new Date(2026, 10, 11);

export function Controlled() {
  const [date, setDate] = useState<Date | null>(new Date(2026, 11, 1));
  return (
    <div style={{ display: 'grid', gap: 8, width: 280 }}>
      <FormField label="Contract renewal">
        <DatePicker locale="en-GB" today={TODAY} value={date} onValueChange={setDate} />
      </FormField>
      <p style={{ margin: 0, fontSize: 13 }}>{date ? date.toDateString() : 'No date chosen'}</p>
    </div>
  );
}
```

### Sizes and states

```tsx
import { DatePicker, FormField } from '@bindshq/stance-react';

const TODAY = new Date(2026, 10, 11);

export function Sizes() {
  return (
    <div style={{ display: 'grid', gap: 12, width: 280 }}>
      <DatePicker aria-label="Small" size="sm" locale="en-GB" today={TODAY} />
      <DatePicker aria-label="Large" size="lg" locale="en-GB" today={TODAY} defaultValue={TODAY} />
      <FormField label="Invalid" error="Choose a date after today">
        <DatePicker locale="en-GB" today={TODAY} defaultValue={new Date(2026, 9, 1)} />
      </FormField>
      <DatePicker aria-label="Disabled" disabled locale="en-GB" today={TODAY} />
    </div>
  );
}
```

## API reference

| Component | Prop | Type | Default | Description |
| --- | --- | --- | --- | --- |
| DatePicker | `value / defaultValue` | `Date \| null` | None | Selected date. |
| DatePicker | `onValueChange` | `(value: Date \| null) => void` | None | Called with the new date, or null when cleared. |
| DatePicker | `name` | `string` | None | Submits the ISO date in a hidden input. |
| DatePicker | `min / max` | `Date \| null` | None | Selectable window; typed dates outside it are invalid. |
| DatePicker | `isDateDisabled` | `(date: Date) => boolean` | None | Unavailable dates. |
| DatePicker | `locale` | `string` | None | Controls parsing order, display and calendar names. |
| DatePicker | `weekStartsOn` | `0 to 6` | `1` | First day of the week in the calendar. |
| DatePicker | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Field height. |
| DatePicker | `clearable` | `boolean` | `true` | Show a clear button when a date is set. |
| DatePicker | `invalid` | `boolean` | None | Marks the field invalid (set automatically inside an erroring FormField). |
| DatePicker | `placeholder` | `string` | `locale pattern, e.g. dd/mm/yyyy` | Placeholder text. |
| DatePicker | `labels` | `Partial<DatePickerLabels>` | None | openCalendar, clear, calendar. |
| DatePicker | `disabled / readOnly / required` | `boolean` | None | Native field states, also inherited from FormField. |

## Accessibility

- The text input gets its label, description and error from FormField.
- The calendar button is labelled “Choose date” and reports aria-expanded; the popover is a labelled dialog.
- Opening moves focus to the selected (or today’s) day; choosing a date closes the popover and returns focus to the button.
- Unparseable or out-of-range typed input sets aria-invalid instead of silently discarding what was typed.

## Keyboard

| Keys | Action |
| --- | --- |
| `Alt + ↓` | Open the calendar from the text field. |
| `Enter` | Commit typed text. |
| `Esc` | Close the calendar. |
| `Arrows` `Page Up/Down` | Navigate days in the calendar (see Calendar). |

## Guidelines

**Do**

- Show the expected format in the description when typing is likely.
- Use min/max rather than validating after submit.

**Don’t**

- Use for date ranges; use DateRangePicker.

## Related

- https://stanceui.com/components/calendar
- https://stanceui.com/components/date-range-picker
- https://stanceui.com/components/time-picker
- https://stanceui.com/components/form-field
