CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-stately--datepicker

React state management hooks for date picker components with internationalization and accessibility support.

Pending
Overview
Eval results
Files

date-picker-state.mddocs/

Date Picker State

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.

Capabilities

useDatePickerState Hook

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>
  );
}

State Value Management

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;

Overlay State Management

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;

Formatting and Validation

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;

Props Interface

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

docs

date-field-state.md

date-picker-state.md

date-range-picker-state.md

index.md

time-field-state.md

tile.json