DatePicker
Overview
A date picker that pairs a keyboard-editable segmented date field with a calendar popup for visual selection. Type a date directly into the segments or click the calendar toggle to pick from a month grid. Use it whenever a user must choose a single date — booking, scheduling, filtering, or any form that needs a validated date range. For pure typing with no popup, prefer SDateField; for browsing a standalone calendar grid, use SCalendar.
Usage
Features
- 📅 Field + popup combo — the segmented
DateFieldstays editable while a calendar popover offers visual selection - 🎚 Controlled / uncontrolled —
v-model/defaultValuefor the value plusopen/defaultOpenfor the popup, both backed byuseControllableState - ⌨️ Full keyboard editing — segment increment/decrement/typing in the field, arrow-key grid navigation in the calendar,
Escapecloses - ⛓ Range validation —
minValue/maxValue/isDateUnavailabledisable out-of-range and unavailable days in both the field and the calendar - 🌍 Locale-aware accessibility — default
aria-labels for the calendar toggle and popup dialog come from the active locale messages and are overridable viatriggerProps/popupProps - 🧩 Composable slots —
leadingfor content before the segments,defaultslot props exposeopen/close/calendarPropsfor a fully custom popup - 🎨 Fine-grained styling —
uicovers the field plustrigger/positioner/popupslots, andcalendarUitargets the embedded calendar independently - 🚫 Disabled state —
disabledblocks both field editing and popup opening
Component family
SDatePicker— the styled wrapper that forwards props to the Aria compact, injectsdatePickerVariants(extendingdateFieldVariants), and rendersSCalendarinside the popupDatePickerCompact(Aria) — data-driven composition ofDateFieldCompact+PopoverCompact(calendar-icon trigger) that exposes the popup state andcalendarPropsthrough its default slot; import from@vean/aria/date-pickerfor unstyled usageDateFieldCompact/PopoverCompact/CalendarCompact(Aria) — the segmented field, the popover mechanics, and the calendar grid that back the picker
Demos
Basic
Custom Styling
API
Aria Layer
2DatePicker
Props
| Prop | Type | Default | Description |
|---|---|---|---|
class | ClassValue | — | Additional class names applied to the root element. |
size | ThemeSize | — | Visual size of the component. |
ui | Partial<DatePickerUi> | — | Per-slot class overrides for the component. |
calendarUi | Partial<CalendarUi> | — | Per-slot class overrides for the Calendar component within the DatePicker. |
dateFieldProps | BaseProps | — | — |
placement | import("@/index").Placement | — | Placement. |
showArrow | boolean | — | Whether to show an arrow. |
triggerProps | PopoverTriggerProps | — | Properties forwarded to the trigger element. |
portalProps | PopperPortalProps | — | Properties forwarded to the portal element. |
positionerProps | PopoverPositionerProps | — | Properties forwarded to the positioner element. |
popupProps | PopoverPopupProps | — | Properties forwarded to the popup element. |
arrowProps | PopperArrowProps | — | Properties forwarded to the arrow element. |
closeProps | PopoverCloseProps | — | Properties forwarded to the close element. |
dir | Direction | — | Reading direction of the component. |
open | boolean | — | — |
defaultOpen | boolean | — | — |
modal | boolean | — | — |
disabled | boolean | — | Whether the component is disabled. |
headerProps | CalendarHeaderProps | — | Properties forwarded to the header element. |
headingProps | CalendarHeadingProps | — | Properties forwarded to the heading element. |
prevProps | CalendarPrevProps | — | Properties forwarded to the prev element. |
nextProps | CalendarNextProps | — | Properties forwarded to the next element. |
gridProps | CalendarGridProps | — | Properties forwarded to the grid element. |
gridHeadProps | CalendarGridHeadProps | — | Properties forwarded to the grid head element. |
gridBodyProps | CalendarGridBodyProps | — | Properties forwarded to the grid body element. |
gridRowProps | CalendarGridRowProps | — | Properties forwarded to the grid row element. |
headCellProps | CalendarHeadCellProps | — | Properties forwarded to the head cell element. |
cellProps | CalendarCellProps | — | Properties forwarded to the cell element. |
cellTriggerProps | CalendarCellTriggerProps | — | Properties forwarded to the cell trigger element. |
locale | string | — | Locale. |
modelValue | DateValue | — | Current model value. |
defaultValue | DateValue | — | Default value. |
multiple | false | — | Whether multiple values are supported. |
placeholder | DateValue | — | Placeholder. |
defaultPlaceholder | DateValue | — | Default placeholder. |
readonly | boolean | — | Whether the component is readonly. |
pagedNavigation | boolean | — | Whether paged navigation. |
preventDeselect | boolean | — | Whether prevent deselect. |
weekStartsOn | WeekStartsOn | — | Week starts on. |
weekdayFormat | WeekDayFormat | — | Weekday format. |
calendarLabel | string | — | Calendar label. |
fixedWeeks | boolean | — | Whether fixed weeks. |
maxValue | DateValue | — | Max value. |
minValue | DateValue | — | Min value. |
numberOfMonths | number | — | Number of months. |
initialFocus | boolean | — | Whether initial focus. |
isDateDisabled | DateMatcher | — | Whether the date is disabled. |
isDateUnavailable | DateMatcher | — | Whether the date is unavailable. |
nextPage | ((placeholder: DateValue) => DateValue) | — | Next page. |
prevPage | ((placeholder: DateValue) => DateValue) | — | Prev page. |
disableDaysOutsideCurrentView | boolean | — | Whether to disable days outside current view. |
asChild | boolean | — | Change the default rendered element for the one passed as a child, merging their props and behavior. |
as | AsTag | Component | 'div' | The element or component this component should render as. Can be overwrite by `asChild` |
Emits
| Emit Name | Parameters | Description |
|---|---|---|
update:open | boolean | Event handler called when the open state of the dialog changes. |
escapeKeyDown | KeyboardEvent | Event handler called when the escape key is down. Can be prevented. |
pointerDownOutside | PointerDownOutsideEvent | Event handler called when a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented. |
focusOutside | FocusOutsideEvent | Event handler called when the focus moves outside of the `DismissableLayer`. Can be prevented. |
interactOutside | PointerDownOutsideEvent | FocusOutsideEvent | Event handler called when an interaction happens outside the `DismissableLayer`. Specifically, when a `pointerdown`
event happens outside or focus moves outside of it. Can be prevented. |
openAutoFocus | Event | Event handler called when auto-focusing on open. Can be prevented. |
closeAutoFocus | Event | Event handler called when auto-focusing on close. Can be prevented. |
placed | — | — |
update:modelValue | DateValue | undefined | Emitted when the model value changes. |
update:placeholder | DateValue | Emitted when the placeholder value changes. |
Slots
| Slot Name | Parameters | Description |
|---|---|---|
leading | — | Custom content rendered before the date segments. |
DatePickerCompact
Props
| Prop | Type | Default | Description |
|---|---|---|---|
dateFieldProps | BaseProps | — | — |
placement | import("@/index").Placement | — | Placement. |
showArrow | boolean | — | Whether to show an arrow. |
triggerProps | PopoverTriggerProps | — | Properties forwarded to the trigger element. |
portalProps | PopperPortalProps | — | Properties forwarded to the portal element. |
positionerProps | PopoverPositionerProps | — | Properties forwarded to the positioner element. |
popupProps | PopoverPopupProps | — | Properties forwarded to the popup element. |
arrowProps | PopperArrowProps | — | Properties forwarded to the arrow element. |
closeProps | PopoverCloseProps | — | Properties forwarded to the close element. |
dir | Direction | — | Reading direction of the component. |
open | boolean | — | — |
defaultOpen | boolean | — | — |
modal | boolean | — | — |
disabled | boolean | — | Whether the component is disabled. |
headerProps | CalendarHeaderProps | — | Properties forwarded to the header element. |
headingProps | CalendarHeadingProps | — | Properties forwarded to the heading element. |
prevProps | CalendarPrevProps | — | Properties forwarded to the prev element. |
nextProps | CalendarNextProps | — | Properties forwarded to the next element. |
gridProps | CalendarGridProps | — | Properties forwarded to the grid element. |
gridHeadProps | CalendarGridHeadProps | — | Properties forwarded to the grid head element. |
gridBodyProps | CalendarGridBodyProps | — | Properties forwarded to the grid body element. |
gridRowProps | CalendarGridRowProps | — | Properties forwarded to the grid row element. |
headCellProps | CalendarHeadCellProps | — | Properties forwarded to the head cell element. |
cellProps | CalendarCellProps | — | Properties forwarded to the cell element. |
cellTriggerProps | CalendarCellTriggerProps | — | Properties forwarded to the cell trigger element. |
locale | string | — | Locale. |
modelValue | DateValue | — | Current model value. |
defaultValue | DateValue | — | Default value. |
multiple | false | — | Whether multiple values are supported. |
placeholder | DateValue | — | Placeholder. |
defaultPlaceholder | DateValue | — | Default placeholder. |
readonly | boolean | — | Whether the component is readonly. |
pagedNavigation | boolean | — | Whether paged navigation. |
preventDeselect | boolean | — | Whether prevent deselect. |
weekStartsOn | WeekStartsOn | — | Week starts on. |
weekdayFormat | WeekDayFormat | — | Weekday format. |
calendarLabel | string | — | Calendar label. |
fixedWeeks | boolean | — | Whether fixed weeks. |
maxValue | DateValue | — | Max value. |
minValue | DateValue | — | Min value. |
numberOfMonths | number | — | Number of months. |
initialFocus | boolean | — | Whether initial focus. |
isDateDisabled | DateMatcher | — | Whether the date is disabled. |
isDateUnavailable | DateMatcher | — | Whether the date is unavailable. |
nextPage | ((placeholder: DateValue) => DateValue) | — | Next page. |
prevPage | ((placeholder: DateValue) => DateValue) | — | Prev page. |
disableDaysOutsideCurrentView | boolean | — | Whether to disable days outside current view. |
asChild | boolean | — | Change the default rendered element for the one passed as a child, merging their props and behavior. |
as | AsTag | Component | 'div' | The element or component this component should render as. Can be overwrite by `asChild` |
Emits
| Emit Name | Parameters | Description |
|---|---|---|
update:open | boolean | Event handler called when the open state of the dialog changes. |
escapeKeyDown | KeyboardEvent | Event handler called when the escape key is down. Can be prevented. |
pointerDownOutside | PointerDownOutsideEvent | Event handler called when a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented. |
focusOutside | FocusOutsideEvent | Event handler called when the focus moves outside of the `DismissableLayer`. Can be prevented. |
interactOutside | PointerDownOutsideEvent | FocusOutsideEvent | Event handler called when an interaction happens outside the `DismissableLayer`. Specifically, when a `pointerdown`
event happens outside or focus moves outside of it. Can be prevented. |
openAutoFocus | Event | Event handler called when auto-focusing on open. Can be prevented. |
closeAutoFocus | Event | Event handler called when auto-focusing on close. Can be prevented. |
placed | — | — |
update:modelValue | DateValue | undefined | Emitted when the model value changes. |
update:placeholder | DateValue | Emitted when the placeholder value changes. |
Slots
| Slot Name | Parameters | Description |
|---|---|---|
leading | — | Custom content rendered before the date segments. |
default | DatePickerCompactSlotProps | Custom content for the calendar popup, receiving the open/close controls and calendar props. |
Notes
Architecture and benchmark differences
SDatePicker forwards props to DatePickerCompact, which wires DateFieldCompact (segments + validation) and PopoverCompact (a lucide:calendar icon trigger with aria-haspopup="dialog"). The styled layer injects datePickerVariants classes through provideDatePickerUi so the nested popover parts get trigger/positioner/popup styling, then renders SCalendar in the default slot with the forwarded calendarProps. Selecting a day emits update:modelValue and closes the popup. The popup is a role="dialog" with a default accessible name from the locale popupLabel message; the toggle gets toggle. Most benchmark libraries ship a plain text input plus a picker panel; the segmented-field-plus-popover combo and the Aria/styled split are the differentiators.
| Capability | VeanUI | Ant Design | Element Plus | Mantine | Naive UI | shadcn |
|---|---|---|---|---|---|---|
| Aria/styled split | ✅ | — | — | — | — | — |
| Segmented field + calendar popup | ✅ | — | — | — | — | — |
| Controlled / uncontrolled value | ✅ | ✅ | ✅ | ✅ | ✅ | — |
| Controlled / uncontrolled open | ✅ | — | — | — | — | — |
| Keyboard segment editing | ✅ | — | — | — | — | — |
| Calendar keyboard navigation | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Range validation | ✅ | ✅ | ✅ | ✅ | ✅ | — |
isDateUnavailable | ✅ | — | — | — | — | — |
| Disabled state | ✅ | ✅ | ✅ | ✅ | ✅ | — |
| Locale-driven accessible names | ✅ | — | — | — | — | — |
leading slot | ✅ | — | — | — | — | — |
Independent calendarUi | ✅ | — | — | — | — | — |
Cautions
- The value is a
DateValue(Dateor{ date, time? }) — not astring. Use it withSDateField,SCalendar, and the other date-family components. defaultValue/defaultOpenare only read on mount — usev-model/openfor external control.- The toggle button is the calendar icon; its default
aria-label(localetoggle) can be overridden throughtriggerProps['aria-label']. The icon itself is fixed — to render a custom trigger, composeDatePickerCompactfrom@vean/aria/date-pickerwith your own popover content. - The popup
role="dialog"gets its accessible name from the localepopupLabelmessage; override it throughpopupProps['aria-label']. - Pass
dateFieldProps(e.g.placeholder,locale,granularity) to configure the embedded segmented field; field and calendar shareminValue/maxValue/isDateUnavailable. calendarUiis consumed by the embedded calendar and never reaches the DOM — the same applies todateFieldProps.
FAQ
How do I choose a date with the keyboard?
Tab into the segmented field and type digits or use arrow keys, or press the calendar toggle and navigate the month grid with arrow keys, Home/End and PageUp/PageDown; Enter selects and closes, Escape closes without selecting.
How do I restrict the selectable range?
Pass minValue/maxValue — out-of-range days are disabled in the calendar and the field marks itself data-invalid. isDateUnavailable accepts a predicate for arbitrary exclusions and applies to both the field and the calendar.
How do I configure the embedded date field?
Use dateFieldProps — for example { placeholder }, { locale }, { granularity: 'minute' } or { hourCycle: 12 }. The field accepts the same props as SDateField itself.
How do I customize the calendar look?
calendarUi overrides the calendar’s per-slot classes independently of ui. For deeper customization, the default slot receives calendarProps (plus open/close) so you can render your own popup content with CalendarCompact from @vean/aria/calendar.
How is SDatePicker different from SDateField?
SDateField is a pure segmented input with no popup — fastest for typing and form submission. SDatePicker adds the calendar popover on top of the same field, trading a little footprint for visual selection.