React state management hooks for date picker components with internationalization and accessibility support.
—
State management for date picker components that combine a text field with a calendar popover. Provides comprehensive date and time selection with validation, formatting, and overlay state management.
Creates a state object for managing date picker component state including date/time values, overlay visibility, and validation.
/**
* Provides state management for a date picker component.
* A date picker combines a DateField and a Calendar popover to allow users to enter or select a date and time value.
* @param props - Configuration options for the date picker state
* @returns DatePickerState object with date/time management and overlay controls
*/
function useDatePickerState<T extends DateValue = DateValue>(
props: DatePickerStateOptions<T>
): DatePickerState;
interface DatePickerStateOptions<T extends DateValue> extends DatePickerProps<T> {
/**
* Determines whether the date picker popover should close automatically when a date is selected.
* @default true
*/
shouldCloseOnSelect?: boolean | (() => boolean);
}
interface DatePickerState extends OverlayTriggerState, FormValidationState {
/** The currently selected date. */
value: DateValue | null;
/** The default date. */
defaultValue: DateValue | null;
/** Sets the selected date. */
setValue(value: DateValue | null): void;
/** The date portion of the value. This may be set prior to `value` if the user has selected a date but has not yet selected a time. */
dateValue: DateValue | null;
/** Sets the date portion of the value. */
setDateValue(value: DateValue): void;
/** The time portion of the value. This may be set prior to `value` if the user has selected a time but has not yet selected a date. */
timeValue: TimeValue | null;
/** Sets the time portion of the value. */
setTimeValue(value: TimeValue): void;
/** The granularity for the field, based on the `granularity` prop and current value. */
granularity: Granularity;
/** Whether the date picker supports selecting a time, according to the `granularity` prop and current value. */
hasTime: boolean;
/** Whether the calendar popover is currently open. */
isOpen: boolean;
/** Sets whether the calendar popover is open. */
setOpen(isOpen: boolean): void;
/** The current validation state of the date picker, based on the `validationState`, `minValue`, and `maxValue` props. @deprecated Use `isInvalid` instead. */
validationState: ValidationState | null;
/** Whether the date picker is invalid, based on the `isInvalid`, `minValue`, and `maxValue` props. */
isInvalid: boolean;
/** Formats the selected value using the given options. */
formatValue(locale: string, fieldOptions: FieldOptions): string;
/** Gets a formatter based on state's props. */
getDateFormatter(locale: string, formatOptions: FormatterOptions): DateFormatter;
}Usage Examples:
import { useDatePickerState } from "@react-stately/datepicker";
import { CalendarDate, CalendarDateTime } from "@internationalized/date";
// Basic date picker
function BasicDatePicker() {
const state = useDatePickerState({
defaultValue: new CalendarDate(2023, 6, 15),
onChange: (value) => console.log("Selected:", value?.toString())
});
return (
<div>
<input
value={state.formatValue('en-US', {})}
readOnly
onClick={() => state.setOpen(true)}
/>
{state.isOpen && <div>Calendar popover</div>}
</div>
);
}
// Date and time picker with validation
function DateTimePicker() {
const state = useDatePickerState({
granularity: 'minute',
minValue: new CalendarDateTime(2023, 1, 1, 0, 0),
maxValue: new CalendarDateTime(2024, 12, 31, 23, 59),
isInvalid: false,
onChange: (value) => {
if (value) {
console.log("Date:", value.toDate('UTC'));
}
}
});
return (
<div>
<input
value={state.formatValue('en-US', { hour: 'numeric', minute: '2-digit' })}
style={{ borderColor: state.isInvalid ? 'red' : 'gray' }}
readOnly
onClick={() => state.setOpen(true)}
/>
{state.hasTime && <span>Includes time selection</span>}
</div>
);
}
// Controlled date picker with custom close behavior
function ControlledDatePicker({ value, onChange }) {
const state = useDatePickerState({
value,
onChange,
shouldCloseOnSelect: () => !state.hasTime, // Keep open for time selection
granularity: 'second'
});
return (
<div>
<button onClick={() => state.setOpen(!state.isOpen)}>
{state.value?.toString() || "Select date & time"}
</button>
{state.isOpen && (
<div>
{!state.hasTime ? "Date only" : "Date and time"}
<button onClick={() => state.setOpen(false)}>Close</button>
</div>
)}
</div>
);
}The date picker state manages separate date and time portions that are combined into the final value.
/**
* Sets the date portion of the value
* @param value - The date value to set
*/
setDateValue(value: DateValue): void;
/**
* Sets the time portion of the value
* @param value - The time value to set
*/
setTimeValue(value: TimeValue): void;Extends OverlayTriggerState to provide popover/modal control for the calendar.
/**
* Sets whether the calendar popover is open
* Automatically commits selected date/time when closing if hasTime is true
* @param isOpen - Whether the popover should be open
*/
setOpen(isOpen: boolean): void;Provides formatting and validation capabilities integrated with form validation.
/**
* Formats the selected value using the given options
* @param locale - The locale to format in (e.g. 'en-US', 'fr-FR')
* @param fieldOptions - Formatting options for different date/time parts
* @returns Formatted date string or empty string if no value
*/
formatValue(locale: string, fieldOptions: FieldOptions): string;
/**
* Gets a formatter based on state's props
* @param locale - The locale for formatting
* @param formatOptions - Additional formatting options
* @returns DateFormatter instance for custom formatting
*/
getDateFormatter(locale: string, formatOptions: FormatterOptions): DateFormatter;interface DatePickerProps<T extends DateValue> {
/** The current value (controlled). */
value?: T | null;
/** The default value (uncontrolled). */
defaultValue?: T | null;
/** Handler that is called when the value changes. */
onChange?: (value: MappedDateValue<T> | null) => void;
/** The minimum allowed date that a user may select. */
minValue?: DateValue;
/** The maximum allowed date that a user may select. */
maxValue?: DateValue;
/** Callback that is called for each date of the calendar. If true, the date is unavailable. */
isDateUnavailable?: (date: DateValue) => boolean;
/** Whether the calendar is disabled. */
isDisabled?: boolean;
/** Whether the calendar is read only. */
isReadOnly?: boolean;
/** The date that is focused in the calendar on first mount. */
autoFocus?: boolean;
/** A placeholder date that influences the format of the placeholder shown when no value is selected. */
placeholderValue?: T;
/** Determines the smallest unit that is displayed in the date picker. */
granularity?: Granularity;
/** Whether to hide the time zone abbreviation. */
hideTimeZone?: boolean;
/** Whether to display the time in 12 or 24 hour format. */
hourCycle?: 12 | 24;
/** Whether to always show leading zeros in the month, day, and hour fields. */
shouldForceLeadingZeros?: boolean;
/** Whether the element should receive focus on render. */
autoFocus?: boolean;
/** The name of the input element, used when submitting an HTML form. */
name?: string;
/** Whether user input is required on the input before form submission. */
isRequired?: boolean;
/** Whether the input value is invalid. */
isInvalid?: boolean;
/** The current validation state of the date picker. */
validationState?: ValidationState;
/** An error message for the field. */
errorMessage?: ReactNode;
/** A description for the field. */
description?: ReactNode;
}Install with Tessl CLI
npx tessl i tessl/npm-react-stately--datepicker