Headless / Date & time

DatePicker

DatePicker is a Calendar behind a trigger. A button shows the current date; clicking it opens a popover with the month grid, and choosing a day closes it.

Loading playground…
Updated 3 days agoEdit on GitHubWeb & native

What it is

A single component that composes Popover with Calendar. The trigger displays the selected date — formatted by Intl.DateTimeFormat against the locale — or the placeholder when nothing is chosen. Selecting a day fires onValueChange and closes the popover.

Use DatePicker when a date is one field among many and screen space is tight. When the calendar should always be visible, reach for Calendar directly.

Install

example.tsx
yarn add @usemotif/headless
example.tsx
import { DatePicker } from '@usemotif/headless';

API

DatePicker

stable
function DatePicker(props: DatePickerProps): JSX.Element
value / defaultValue / onValueChangeDate / Date / (next: Date) => void

The selected date, controlled or uncontrolled.

renderTrigger(info: { label: string; onClick: () => void }) => ReactNode

Custom trigger renderer. `label` is the formatted date or placeholder; `onClick` toggles the popover.

placeholderstring= "Pick a date"

Trigger text shown when no date is selected.

localestring

Locale for the trigger label and the calendar. Defaults to the navigator locale.

isDisabled / weekStartsOn / renderDayCalendarProps

Passed straight through to the inner Calendar.

triggerStyle / popoverStyleCSSProperties

Inline styles for the default trigger button and the popover surface.

Accessibility

DatePicker inherits both contracts it composes. The trigger is a Popover trigger — aria-expanded, aria-controls, click to open. The grid inside is Calendar's role="grid" with full keyboard navigation. Escape closes the popover and returns focus to the trigger.

The default trigger is a bare button showing the date. Give it an accessible name with renderTrigger — a visible "Due date" label, or an aria-label — so a screen-reader user knows what the date is for, not just what it is.

Examples

A due-date field:

example.tsx
<DatePicker
value={dueDate}
onValueChange={setDueDate}
placeholder="No due date"
isDisabled={(d) => d < new Date()}
renderTrigger={({ label, onClick }) => (
  <Button variant="outline" onPress={onClick} aria-label="Due date">
    {label}
  </Button>
)}
/>