Date Picker
A trigger button paired with a popover Calendar. Closes on selection by default. Click-outside and Escape dismiss the popover. Uses the same Calendar primitives under the hood — render any Calendar.* parts inside DatePicker.Calendar.
Features
Composes with the
Calendar component.Closes on selection by default (override with
closeOnSelect={false}).Click-outside and Escape close the popover.
Controlled and uncontrolled date and open state.
Locale-aware formatted display via Intl.DateTimeFormat.
data-state on root, trigger, and content for open/closed styling.
Example
Anatomy
import { Calendar, DatePicker } from '@wire-ui/react'
<DatePicker.Root>
<DatePicker.Trigger>
<DatePicker.Value placeholder="Pick a date" />
</DatePicker.Trigger>
<DatePicker.Content>
<DatePicker.Calendar>
<Calendar.Nav>
<Calendar.PrevButton />
<Calendar.Title />
<Calendar.NextButton />
</Calendar.Nav>
<Calendar.Grid
renderDay={(day) => <button {...day.props}>{day.dayOfMonth}</button>}
renderWeekday={(wd) => <div>{wd.short}</div>}
/>
</DatePicker.Calendar>
</DatePicker.Content>
</DatePicker.Root>Styling
The Root and Trigger expose data-state="open" / "closed" so you can ring-focus the trigger when the popover is open. The Content unmounts when closed.
<DatePicker.Trigger className="
data-[state=open]:ring-2 data-[state=open]:ring-black
" />Using data attributes
[data-state="open"] { /* expanded */ }
[data-state="closed"] { /* collapsed */ }
[data-disabled] { opacity: 0.5; cursor: not-allowed; }
[data-placeholder] { color: #a3a3a3; } /* Value with no selection */Root props
| Prop | Type | Default | Description |
|---|---|---|---|
value | Date | null | — | Controlled date |
defaultValue | Date | null | null | Initial date |
onChange | (date: Date | null) => void | — | Called when selection changes |
open | boolean | — | Controlled open state |
defaultOpen | boolean | false | Initial open state |
onOpenChange | (open: boolean) => void | — | Called when open state changes |
disabled | boolean | false | Disables the trigger |
closeOnSelect | boolean | true | Close the popover when a date is picked |
locale | string | 'en-US' | Locale used by the Value formatter |
formatOptions | Intl.DateTimeFormatOptions | { year: 'numeric', month: 'short', day: 'numeric' } | Format options for the Value display |
Value props
| Prop | Type | Description |
|---|---|---|
placeholder | ReactNode | Rendered when no date is selected |
children | (date: Date | null, formatted: string) => ReactNode | Custom render function — overrides the default formatted string |
Calendar prop
DatePicker.Calendar accepts all Calendar.Root props except value / onChange (which are wired internally). Use it to pass minDate, maxDate, isDateDisabled, weekStartsOn, etc.
Data attributes
| Attribute | Element | Values |
|---|---|---|
data-state | Root, Trigger | "open" / "closed" |
data-disabled | Root | Present when disabled |
data-placeholder | Value | Present when no date is selected |
Accessibility
- Trigger sets
aria-haspopup="dialog",aria-expanded, andaria-controls. - Content has
role="dialog"andaria-labelledbypointing to the trigger. - Escape closes the popover; click-outside dismisses it.
Keyboard Interactions
| Key | Description |
|---|---|
| Enter / Space | Opens the popover when the trigger is focused. |
| Escape | Closes the popover. |
| Tab | Moves focus through the grid; closes on outside focus via click-outside. |
Last updated on