datePicker
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | 1 | 2 | 3 | 4 |
Jan | Feb | Mar | Apr |
May | Jun | Jul | Aug |
Sep | Oct | Nov | Dec |
2020 | 2021 | 2022 | 2023 |
2024 | 2025 | 2026 | 2027 |
2028 | 2029 |
A date picker is a text field with a calendar behind it. The field takes a date typed out; the calendar takes one chosen from a grid, which is what a reader wants when the answer depends on the day of the week or on what is nearby.
<DatePicker label="Due" defaultValue={parseDate(["2026-03-14"])} />
<DatePicker label="Due" :default-value="parseDate(['2026-03-14'])" />
The value is a DateValue, not a string
The picker holds DateValue objects rather than strings. parseDate builds them from ISO
strings or Date objects and is re-exported from both adapters, so reaching for it does
not mean adding Ark UI to your own dependencies.
It is always an array, whatever the selection mode: one entry for a single date, two for a range, as many as were picked for a multiple selection. One shape beats converting between three.
React takes value with onValueChange, or defaultValue to leave the state alone. Vue
takes v-model, with defaultValue as the uncontrolled counterpart.
const [date, setDate] = useState(() => parseDate(["2026-03-14"]));
<DatePicker value={date} onValueChange={(details) => setDate(details.value)} />;
<script setup lang="ts">
import { DatePicker, parseDate } from "@75neo/vue";
const date = ref(parseDate(["2026-03-14"]));
</script>
<template>
<DatePicker v-model="date" />
</template>
Three ways to select
selectionMode is "single", "multiple" or "range". A range draws two fields with a
separator between them and tints the days between the endpoints; rangeSeparator replaces
the en dash. A multiple selection keeps the calendar open, since closeOnSelect cannot
know when a reader is finished.
The field shows one date per input, which is one for a single selection and two for a range. A multiple selection has no fixed number of them, so the field shows the first date and the calendar is where the rest are read. Render the value alongside it if the whole list has to be visible.
<DatePicker label="Stay" selectionMode="range" />
<DatePicker label="Stay" selection-mode="range" />
Three views, one grid
The heading between the arrows is a button. Pressing it climbs from days to months, and
again to years, which is how a reader reaches a date eight decades back without pressing
the arrow ninety-six times. All three views are one table, one header row and one cell
trigger, so a theme that restyles tableCellTrigger restyles the calendar rather than a
third of it. Each view carries data-view for the cases where they should differ.
numOfMonths shows several months side by side, fixedWeeks always draws six weeks so
the popup does not change height between months, and startOfWeek overrides the locale’s
first day.
The bounds
min and max refuse a date outside them, and isDateUnavailable refuses one your own
rule rejects, such as a weekend or a day already booked. An unavailable day is struck
through rather than hidden, so a reader can tell “not this one” from “not shown”. Both are
adapter props rather than shared ones, because they are DateValue and that type comes
from each framework’s own copy of Ark.
Where the calendar lives
The calendar is rendered at the end of the document rather than where the component is
written, so a card, a dialog or a toolbar that clips its overflow cannot cut it off. The
move is delayed until the component mounts, which keeps the server-rendered markup and the
first client render identical. The positioner slot carries the stacking context, and
ui.positioner is where to raise it above something.
Forms
The component renders a hidden input, so a picker inside a form submits like any other
field. name names it. required and invalid do what they do on any input, and
readOnly shows a date without letting anyone change it, which is different from
disabled: a read-only field still takes focus.
Slots
The same word names the recipe slot, the data-slot attribute and the key in ui.
- base
- label
- control
- input
- separator
- trigger
- clearTrigger
- positioner
- content
- view
- viewControl
- prevTrigger
- viewTrigger
- nextTrigger
- table
- tableHead
- tableRow
- tableHeader
- tableBody
- tableCell
- tableCellTrigger
Variants
Read off the recipe, so these are the values that actually resolve. A Theme layer can change which one is the default; it cannot add a value.
- color
- primarysecondarysuccessinfowarningerrorneutral
- size
- smmdlg
Props
Taken by both adapters, read out of the component module. The same names and the same types work in React and Vue.
- ui
DatePickerUI
Per-slot class overrides.
- color
"primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral"
Defaults to
"primary"- size
"sm" | "md" | "lg"
Defaults to
"md"- label
string
Caption above the field.
- placeholder
string
Placeholder for the empty field.
- selectionMode
DatePickerSelectionMode
How many dates the calendar collects.
Defaults to
"single"- locale
string
BCP 47 language tag deciding the month names and the first day of the week.
Defaults to
"en-US"- timeZone
string
Defaults to
"UTC"- numOfMonths
number
Months shown side by side.
Defaults to
1- startOfWeek
number
First day of the week, `0` for Sunday, overriding the locale.
- fixedWeeks
boolean
Always draw six weeks, so the calendar does not change height month to month.
- rangeSeparator
string
Shown between the two fields of a range.
Defaults to
"–"- closeOnSelect
boolean
Close the calendar once the selection is complete.
Defaults to
true- openOnClick
boolean
Open the calendar when the field is clicked, rather than only from the button.
- clearable
boolean
Show the button that empties the field.
Defaults to
true- disabled
boolean
- readOnly
boolean
- invalid
boolean
- required
boolean
- name
string
Submits the date under this name inside a form.
- trailingIcon
ReactNode
Replaces the calendar glyph on the button that opens the popup.
- clearIcon
ReactNode
Replaces the cross that empties the field.
- prevIcon
ReactNode
Replaces the arrow to the previous month.
- nextIcon
ReactNode
Replaces the arrow to the next month.
React only
Also takes Omit<React.HTMLAttributes<HTMLDivElement>, "color" | "defaultValue" | "dir">, and Pick< DatePickerRootProps, | "value" | "defaultValue" | "onValueChange" | "onOpenChange" | "min" | "max" | "isDateUnavailable" | "ids" >. A className among them reaches the base slot.