Built on Vercel’s UI SDK 0.1.0-beta.1. Its API may change.
Date picker
A date picker on Vercel's UI SDK where people type a date in their language or pick it, with ranges, presets and ISO values.
- Form components
- 18 parts
- 9 examples
@tabler/icons-react@ui-sdk/core@ui-sdk/react
pnpm dlx shadcn@latest add https://hextaui.com/r/ui-sdk-date-picker.jsonAdds the component, the HextaUI theme tokens and any HextaUI components it depends on.
Add the theme tokens to your global CSS, if you haven’t yet.
Install the dependencies.
pnpm add @ui-sdk/react@0.1.0-beta.1 @ui-sdk/core@0.1.0-beta.1 @tabler/icons-react cnCopy and paste the following code into your project.
components/ui/ui-sdk-date-picker.tsx components/ui/button.tsx Update the import paths to match your project setup.
UI SDK adds a little CSS of its own in a cascade layer named ui-sdk. Declare that layer at the top of your global stylesheet, above the Tailwind import, so your classes win over it.
Values are ISO date strings like 2026-11-20, with no time or time zone, so you don’t need a date library. People type in their own date order, like 11/20/2026 or 20.11.2026, and the field formats the date when they press Enter or leave it. DatePickerContent with no children renders a styled calendar.
With mode="range", add a second input with end. The calendar stays open after the first date and closes after the second. months={2} shows two months side by side, stacked on small screens.
A DatePickerPreset picks its value and closes the popup. It shows as pressed while its value is selected.
min, max and unavailable apply to typing and picking. Here weekends and two holidays can’t be picked, and a typed one is marked invalid.
locale sets the typed format, the hint and the calendar’s names. Without it, the picker reads the page’s lang. The buttons have English names, so pass aria-label to translate them.
With a name, the date submits as an ISO string. required blocks an empty submit, text that isn’t a date blocks one too, and reset goes back to defaultValue.
A controller from createDatePickerController() sets the date or opens the calendar from anywhere, and onValueChange reports each change. Leave value unset here, so the calendar can move to the month the controller picks.
disabled stops typing and opening. readOnly still opens the calendar so people can look, but nothing can change.
With an Arabic locale inside dir=rtl, the field, the arrows and the calendar all run from the right.
| Key | Action |
|---|---|
| Enter | In the input, reads the typed date. On a day, picks it. |
| ←→↑↓ | Moves between days, or by a week up and down. |
| Page UpPage Down | Moves a month back or forward. |
| HomeEnd | Moves to the start or end of the week. |
| Esc | Cancels an unfinished range, or else closes the calendar. |
The calendar opens as a dialog with a grid of days, each named in full, like “Friday, November 20, 2026”. The hint describes the input, so screen readers hear the format to type. Text that isn’t a date sets aria-invalid and keeps the old value, and unavailable days stay focusable so keyboard users still hear them.
The trigger, popup and arrows have English names. Pass aria-label to each to translate them. Inputs use a 16px font on touch screens so iOS doesn’t zoom, and the popup only scales in when motion is allowed.
Each part wraps the UI SDK part of the same name and accepts all of its props, including render and a className that can be a function of the part’s state. DatePickerControl, DatePickerSeparator and DatePickerCalendar are HextaUI layout parts.
| Prop | Type | Default |
|---|---|---|
mode | "single" | "range" | "single" |
value | string | [string, string] | null | – |
defaultValue | string | [string, string] | null | – |
onValueChange | (value, details) => void | – |
min | string | – |
max | string | – |
unavailableISO dates, { from, to }, { weekday }, { before }, { after } or a function. | DateMatchers | – |
months | number | 1 |
pageBy | "month" | "page" | "month" |
locale | string | – |
weekStartsOn | number | – |
minDays | number | – |
maxDays | number | – |
closeOnSelect | boolean | true |
disabled | boolean | false |
readOnly | boolean | false |
name | string | – |
startName | string | – |
endName | string | – |
required | boolean | false |
open | boolean | – |
onOpenChange | (open, details) => void | – |
controllerFrom createDatePickerController(). | DatePickerController | – |
| Attribute | Description |
|---|---|
data-slot="date-picker" | Target the date picker in CSS. |
data-open | Present while open. |
data-invalid | Present while an input holds text that isn’t a date. |
data-disabled | Present when disabled. |
data-readonly | Present when read-only. |
| Prop | Type | Default |
|---|---|---|
endMakes it a range’s end. | boolean | false |
| Prop | Type | Default |
|---|---|---|
childrenDefaults to a calendar icon. | ReactNode | – |
aria-label | string | "Choose date" |
| Prop | Type | Default |
|---|---|---|
childrenDefaults to an X icon named Clear. It hides while there’s nothing to clear. | ReactNode | – |
| Prop | Type | Default |
|---|---|---|
childrenDefaults to a DatePickerCalendar. | ReactNode | – |
align | Align | "start" |
sideOffset | number | 6 |
collisionPadding | number | 8 |
| Attribute | Description |
|---|---|
data-slot="date-picker-content" | Target the popup in CSS. |
--cell-size | The size of each day, larger on touch screens. |
| Prop | Type | Default |
|---|---|---|
monthsHow many grids to render, side by side. | number | 1 |
| Prop | Type | Default |
|---|---|---|
value | string | [string, string] | – |
render | ReactElement | (props, state) => ReactElement | – |
| Attribute | Description |
|---|---|
data-slot="calendar-day" | Target a day in CSS. |
data-today | Present on today. |
data-range-start | Present where a range starts. |
data-range-end | Present where a range ends. |
data-unavailable | Present on a day that can’t be picked. |
data-outside | Present on a day of the next or previous month. |
- ButtonButtons in every variant and size, with a built-in loading, success and error flow that skips the spinner for fast requests.
- CalendarA date grid for single, range and multiple selection, with sliding months, range previews and touch-sized days.
- CheckboxA checkbox whose check draws in, with indeterminate parents, groups and labels that share its hover.
- ComboboxA filterable select with chips, groups and async results, in a popup that resizes as you type.
- Date pickerA button that opens a calendar in a popover, or a bottom sheet on phones, for single dates and ranges.
- FieldLabels, descriptions and errors wired to their control, with validation states and layouts for forms.