DatePicker
React DatePicker components are used to select a single date from a calendar. They are commonly used in forms, filters, booking flows, and scheduling features.
This DatePicker component is built with React Aria Components and styled using Tailwind CSS. It supports date selection with keyboard-friendly interaction.
Installation
The Date Picker relies on @internationalized/date for date manipulation.
Install the component using the Tailgrids CLI.
npx @tailgrids/cli add date-pickerUsage
The following example demonstrates how to use the DatePicker compound components.
import {
DatePicker,
DatePickerGroup,
DatePickerPopover,
DatePickerTrigger
} from "@/registry/core/date-picker";
import { DateInput, DateSegment } from "@/registry/core/date-field";
import { CalendarDate, getLocalTimeZone, today } from "@internationalized/date";
import { useState } from "react";
export default function DatePickerUsage() {
const [date, setDate] = useState<CalendarDate | null>(
today(getLocalTimeZone())
);
return (
<DatePicker value={date} onChange={setDate}>
<DatePickerGroup>
<DateInput>{segment => <DateSegment segment={segment} />}</DateInput>
<DatePickerTrigger />
</DatePickerGroup>
<DatePickerPopover />
</DatePicker>
);
}Examples
Basic Usage
A simple date picker with a label and helper description. The popover opens when clicking the calendar icon.
Controlled
Manage the date value externally using value and onChange props.
Uncontrolled
An uncontrolled DatePicker with a default value.
Disabled
Use disabled prop to disable the DatePicker.
With Date Constraints
Restrict date selection to a valid range using minValue and maxValue.
With Date and Time
Combine date and time by using a CalendarDateTime value. Set granularity other then "day" to expose time segments.
Validation
A DatePicker with custom validation that rejects weekend selections using the validate prop.
Service Booking
A DatePicker for selecting a service date, followed by a time slot picker that appears after a date is chosen.
Availability Indicators
A DatePicker that uses isDateUnavailable to mark weekend dates as unavailable, with a legend inside the popover footer showing available and unavailable indicators.
Weekday Only
A DatePicker restricted to weekdays only using isWeekday from @internationalized/date. Useful for scheduling business appointments and professional meetings.
Delivery Date Estimate
A DatePicker with a 3-day minimum notice period and shipping speed selection (Standard or Express) that estimates the arrival date.
International Calendar
Wrap the DatePicker with an I18nProvider and set the locale prop to use a different calendar system.
API Reference
DatePicker (Root)
The root component that wraps react-aria-components DatePicker. Accepts all AriaDatePickerProps with renamed boolean props.
| Prop | Type | Default | Description |
|---|---|---|---|
value | DateValue | null | — | The currently selected date (controlled). |
defaultValue | DateValue | — | The initial default value (uncontrolled). |
onChange | (value: DateValue | null) => void | — | Callback when the value changes. |
disabled | boolean | false | Whether the input is disabled. |
readOnly | boolean | false | Whether the input is read-only. |
required | boolean | false | Whether the input is required. |
invalid | boolean | false | Whether the input is in an invalid state. |
minValue | DateValue | — | The minimum allowed date. |
maxValue | DateValue | — | The maximum allowed date. |
className | string | — | Custom class for the root wrapper. |
name | string | — | Input name for HTML form submission. |
autoFocus | boolean | — | Whether to auto-focus on render. |
granularity | "day" | "hour" | "minute" | "second" | "day" | Smallest displayed unit. |
hourCycle | 12 | 24 | — | Display time in 12 or 24 hour format. |
hideTimeZone | boolean | false | Whether to hide the time zone abbreviation. |
placeholderValue | DateValue | null | — | Placeholder date influencing display format when no value is selected. |
firstDayOfWeek | "sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "sat" | — | The day that starts the week. |
isDateUnavailable | (date: DateValue) => boolean | — | Callback to mark specific dates as unavailable. |
isOpen | boolean | — | Whether the popover is open (controlled). |
defaultOpen | boolean | — | Whether the popover is open by default (uncontrolled). |
onOpenChange | (isOpen: boolean) => void | — | Handler called when the popover open state changes. |
shouldCloseOnSelect | boolean | (() => boolean) | true | Whether the popover closes automatically when a date is selected. |
validate | (value: DateValue) => string | true | undefined | — | Validation function. Return error message for invalid values. |
validationBehavior | "aria" | "native" | "native" | Whether to use native HTML form validation or ARIA. |
DatePickerGroup
A styled wrapper that groups the input and trigger button. Wraps react-aria-components Group.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | ((props: GroupRenderProps) => string) | — | Custom class for the group element. |
isDisabled | boolean | — | Whether the group is disabled. |
isInvalid | boolean | — | Whether the group is invalid. |
isReadOnly | boolean | — | Whether the group is read only. |
role | "group" | "presentation" | "region" | "group" | ARIA role for the group. |
slot | string | null | — | Slot name to receive props from a parent component. |
autoFocus | boolean | — | Whether to auto-focus on render. |
id | string | — | The element's unique identifier. |
style | CSSProperties | ((props) => CSSProperties) | — | Inline style for the element. |
render | DOMRenderFunction | — | Override the default DOM element with a custom render function. |
children | ReactNode | ((props) => ReactNode) | — | The children of the component. |
DatePickerTrigger
Renders the calendar trigger button. Wraps react-aria-components Button.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | ((props: ButtonRenderProps) => string) | — | Custom class for the trigger button. |
isDisabled | boolean | — | Whether the button is disabled. |
isPending | boolean | — | Whether the button is in a pending state. |
type | "button" | "reset" | "submit" | "button" | The behavior of the button when used in an HTML form. |
autoFocus | boolean | — | Whether to auto-focus on render. |
excludeFromTabOrder | boolean | — | Whether to exclude from sequential tab order. |
preventFocusOnPress | boolean | — | Whether to prevent focus from moving to the button when pressing. |
slot | string | null | — | Slot name to receive props from a parent component. |
form | string | — | The <form> element to associate the button with. |
formAction | string | ((data: FormData) => void | Promise) | — | URL that processes form submission. |
formEncType | string | — | How to encode form data that is submitted. |
formMethod | string | — | HTTP method used to submit the form. |
formNoValidate | boolean | — | Whether form validation is skipped on submission. |
formTarget | string | — | Overrides the target attribute of the button's form owner. |
name | string | — | Submitted as a pair with the button's value as part of form data. |
value | string | — | The value associated with the button's name when submitted. |
id | string | — | The element's unique identifier. |
style | CSSProperties | ((props) => CSSProperties) | — | Inline style for the element. |
render | DOMRenderFunction | — | Override the default DOM element with a custom render function. |
children | ReactNode | ((props) => ReactNode) | — | The children of the component. |
onPress | (e: PressEvent) => void | — | Handler called when the press is released over the target. |
onPressStart | (e: PressEvent) => void | — | Handler called when a press interaction starts. |
onPressEnd | (e: PressEvent) => void | — | Handler called when a press interaction ends. |
onPressChange | (isPressed: boolean) => void | — | Handler called when the press state changes. |
onPressUp | (e: PressEvent) => void | — | Handler called when a press is released over the target. |
onFocus | (e: FocusEvent) => void | — | Handler called when the element receives focus. |
onBlur | (e: FocusEvent) => void | — | Handler called when the element loses focus. |
onFocusChange | (isFocused: boolean) => void | — | Handler called when the element's focus status changes. |
onKeyDown | (e: KeyboardEvent) => void | — | Handler called when a key is pressed. |
onKeyUp | (e: KeyboardEvent) => void | — | Handler called when a key is released. |
onHoverStart | (e: HoverEvent) => void | — | Handler called when a hover interaction starts. |
onHoverEnd | (e: HoverEvent) => void | — | Handler called when a hover interaction ends. |
onHoverChange | (isHovering: boolean) => void | — | Handler called when the hover state changes. |
DatePickerPopover
Renders the calendar popover. Wraps react-aria-components Popover.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | ((props: PopoverRenderProps) => string) | — | Custom class for the popover element. |
placement | Placement | "bottom" | The placement of the popover relative to its anchor element. |
offset | number | 8 | Additional offset along the main axis between the popover and anchor. |
crossOffset | number | 0 | Additional offset along the cross axis between the popover and anchor. |
containerPadding | number | 12 | Padding between the popover and its surrounding container. |
arrowBoundaryOffset | number | 0 | Minimum distance the arrow's edge from the edge of the overlay. |
maxHeight | number | — | Maximum height of the popover. Defaults to available viewport height. |
shouldFlip | boolean | true | Whether to flip orientation when there is insufficient room. |
shouldUpdatePosition | boolean | true | Whether to update position automatically. |
isKeyboardDismissDisabled | boolean | false | Whether pressing Escape to close is disabled. |
isNonModal | boolean | — | Whether elements outside the popover may be interacted with by assistive tech. |
shouldCloseOnInteractOutside | (element: Element) => boolean | — | Filter interactions outside the popover that should not dismiss it. |
isOpen | boolean | — | Whether the overlay is open (controlled). |
defaultOpen | boolean | — | Whether the overlay is open by default (uncontrolled). |
onOpenChange | (isOpen: boolean) => void | — | Handler called when the overlay's open state changes. |
isEntering | boolean | — | Whether the popover is performing an entry animation. |
isExiting | boolean | — | Whether the popover is performing an exit animation. |
triggerRef | RefObject<Element | null> | — | Ref for the element the popover positions relative to. |
scrollRef | RefObject<Element | null> | — | Ref for the scrollable region within the overlay. |
arrowRef | RefObject<Element | null> | — | Ref for the popover arrow element. |
boundaryElement | Element | document.body | Element that serves as the positioning boundary. |
trigger | string | — | Name of the component that triggered the popover (reflected as data-trigger attribute). |
slot | string | null | — | Slot name to receive props from a parent component. |
id | string | — | The element's unique identifier. |
style | CSSProperties | ((props) => CSSProperties) | — | Inline style for the element. |
render | DOMRenderFunction | — | Override the default DOM element with a custom render function. |
children | ReactNode | ((props) => ReactNode) | — | The children of the component. |
Composition
The Date Picker is composed of the root DatePicker component plus DatePickerGroup, DatePickerTrigger, and DatePickerPopover. It can be combined with shared field components (FieldLabel, FieldDescription, FieldError) for a complete form control.
DatePicker — Root container. Manages date state, popover open state, and ARIA context.
├── FieldLabel — Visible label.
├── DatePickerGroup — Groups the date input and trigger button.
│ ├── DateInput — Wraps editable segments in a styled input area.
│ │ └── DateSegment — Individual editable segment (day, month, year).
│ └── DatePickerTrigger — Calendar icon button that opens the popover.
└── DatePickerPopover — Floating popover containing the calendar.
└── Calendar — The calendar grid for date selection.
├── CalendarHeader — Month/year navigation row.
│ ├── NavButton (previous) — Previous month button.
│ ├── CalendarHeading — Current month/year label.
│ └── NavButton (next) — Next month button.
├── CalendarGrid — The week grid container.
│ ├── CalendarGridHeader — Day-of-week header row.
│ └── CalendarGridBody — Date cell rows.
│ └── CalendarCell — Individual date cell.- Use
DatePickeras the root. It provides the date value, validation state, and popover open state to all children. - Use
FieldLabelto label the field. Pair it witharia-labelledbyfor accessibility. - Use
DatePickerGroupto wrap theDateInputandDatePickerTrigger. - Use
DateInputto render the segment group. It accepts a render function that receives eachsegmentand returns aDateSegment. - Use
DateSegmentinsideDateInputto render each editable part of the date. It handles focus, typing, and arrow-key incrementing. - Use
DatePickerTriggerfor the calendar icon button that opens the popover. - Use
DatePickerPopoveras the floating container for the calendar. - Use
Calendarand its sub-components inside the popover to render the date selection grid. - Use
FieldDescriptionfor helper text. It is automatically announced by screen readers. - Use
FieldErrorfor validation messages. It is linked viaaria-errormessagewheninvalidis set.
Accessibility
- All buttons and calendar controls are keyboard accessible
- Month navigation buttons support keyboard interaction
- Uses standard
<button>elements for all interactive controls - Focus is managed to allow closing the calendar without mouse input
- Built on
react-aria-componentswhich follows WAI-ARIA authoring practices - Date segments are individually editable and accessible via keyboard
- Validation errors are announced to screen readers via
aria-describedby
