DatePicker
Date selection built from Calendar and BottomSheet.
Installation
npx axiom add date-pickerpnpm dlx axiom add date-pickeryarn dlx axiom add date-pickerbun x axiom add date-pickerAlso copies: calendar, bottom-sheet, button, chip, input and their dependencies.
Requires the calendar icon in your icon registry. The field borrows the colors of Input: DatePicker brings no tokens of its own.
Usage
import { DatePicker } from "@/components/ui/date-picker";
<DatePicker label="Departure" value={date} onChange={setDate} />;How it’s built
date-picker
│
┌───────┴───────┐
↓ ↓
calendar bottom-sheetThe field opens a sheet containing a calendar, so the user picks a date without leaving the screen.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
mode | 'single' | 'range' | 'single' | One date, or a start and end date. Passed to the Calendar. |
value | Date | { from: Date; to?: Date } | null | — | The selected date or range. null shows the placeholder. |
onChange | (value) => void | — | Called with the new value when the user confirms. |
confirm | 'done' | 'instant' | 'done' | done: the value changes on Done, Cancel reverts it. instant: the sheet closes on the first press (single mode only). |
label | string | — | Label above the field, like Input. |
placeholder | string | 'Select a date' | Text in the empty field. |
helper | string | — | Note under the field, like Input. |
error | string | boolean | — | Puts the field in the invalid state. A string also replaces helper. |
format | (value) => string | locale medium date | How the value is written in the field, e.g. “Thu 17 Sep 2026”. |
title | string | label | Title of the sheet. |
minDate / maxDate | Date | — | Limits, passed to the calendar. |
isDateDisabled | (date: Date) => boolean | — | Disabled days, passed to the calendar. |
presets | Array<{ label: string; value: Date | Range }> | — | Shortcut chips above the calendar: “Today”, “Next weekend”. |
clearable | boolean | false | Adds a Clear action in the sheet that sets the value to null. |
disabled | boolean | false | The field can’t open the sheet. |
trigger | ReactElement | input field | Replaces the default field, for example with a Chip or a Button. |
calendarProps | Partial<CalendarRootProps> | — | Any other Calendar.Root prop, like weekStartsOn or minRange. |
renderCalendar | () => ReactNode | full calendar | Children of the Calendar.Root inside the sheet, to change its parts: event dots, a custom header. |
Use cases
Date of a task
confirm="instant": one press sets the date and closes the sheet. Presets cover the common choices.
<DatePicker
confirm="instant"
clearable
value={task.due}
onChange={(due) => update({ due })}
presets={[
{ label: "Today", value: today },
{ label: "Tomorrow", value: addDays(today, 1) },
{ label: "Next week", value: nextMonday(today) },
]}
trigger={
<Chip leading="calendar">
{task.due ? formatShort(task.due) : "Due date"}
</Chip>
}
/>Travel dates
mode="range" behind two fields that read as one. Done stays disabled until both dates are set.
<DatePicker
mode="range"
value={stay}
onChange={setStay}
minDate={today}
calendarProps={{ minRange: 1 }}
trigger={<StayField from={stay?.from} to={stay?.to} />}
/>Form field with validation
A regular field in a form, with label, maxDate and an error when the date is missing.
<DatePicker
label="Date of birth"
value={birthdate}
onChange={setBirthdate}
maxDate={subYears(today, 13)}
error={
submitted && !birthdate
? "We need your date of birth to continue."
: undefined
}
/>