CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-day-picker

Customizable Date Picker for React with extensive internationalization and accessibility support

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

selection.mddocs/

Selection System

React Day Picker provides a type-safe selection system supporting single date, multiple dates, and date range selection with both controlled and uncontrolled modes.

Capabilities

Selection Modes

The library supports three main selection modes with optional required validation.

/**
 * Selection mode types
 */
type Mode = "single" | "multiple" | "range";

/**
 * Type-safe selected value based on selection mode
 */
type SelectedValue<T extends DayPickerProps> = 
  T["mode"] extends "single" ? Date | undefined :
  T["mode"] extends "multiple" ? Date[] | undefined :
  T["mode"] extends "range" ? DateRange | undefined :
  never;

/**
 * Type-safe selection handler based on selection mode
 */
type SelectHandler<T extends DayPickerProps> = (
  value: SelectedValue<T>,
  triggerDate: Date,
  modifiers: Modifiers,
  e: React.MouseEvent
) => void;

Single Date Selection

Select a single date from the calendar.

/**
 * Props for single date selection mode
 */
interface PropsSingle {
  mode: "single";
  /** The selected date */
  selected?: Date;
  /** The default selected date for uncontrolled mode */
  defaultSelected?: Date;
  /** Event handler when a date is selected */
  onSelect?: (
    date: Date | undefined,
    triggerDate: Date,
    modifiers: Modifiers,
    e: React.MouseEvent
  ) => void;
}

/**
 * Props for required single date selection
 */
interface PropsSingleRequired {
  mode: "single";
  required: true;
  /** The selected date (required) */
  selected?: Date;
  /** The default selected date for uncontrolled mode (required) */
  defaultSelected?: Date;
  /** Event handler when a date is selected (cannot be undefined) */
  onSelect?: (
    date: Date,
    triggerDate: Date,
    modifiers: Modifiers,
    e: React.MouseEvent
  ) => void;
}

Usage Examples:

import React, { useState } from "react";
import { DayPicker } from "react-day-picker";

// Controlled single selection
function ControlledSingle() {
  const [selected, setSelected] = useState<Date>();

  return (
    <DayPicker
      mode="single"
      selected={selected}
      onSelect={setSelected}
    />
  );
}

// Uncontrolled single selection
function UncontrolledSingle() {
  return (
    <DayPicker
      mode="single"
      defaultSelected={new Date()}
      onSelect={(date) => console.log("Selected:", date)}
    />
  );
}

// Required single selection
function RequiredSingle() {
  const [selected, setSelected] = useState<Date>(new Date());

  return (
    <DayPicker
      mode="single"
      required
      selected={selected}
      onSelect={setSelected}
    />
  );
}

Multiple Date Selection

Select multiple individual dates from the calendar.

/**
 * Props for multiple date selection mode
 */
interface PropsMulti {
  mode: "multiple";
  /** The selected dates array */
  selected?: Date[];
  /** The default selected dates for uncontrolled mode */
  defaultSelected?: Date[];
  /** Minimum number of dates that must be selected */
  min?: number;
  /** Maximum number of dates that can be selected */
  max?: number;
  /** Event handler when dates are selected */
  onSelect?: (
    dates: Date[] | undefined,
    triggerDate: Date,
    modifiers: Modifiers,
    e: React.MouseEvent
  ) => void;
}

/**
 * Props for required multiple date selection
 */
interface PropsMultiRequired {
  mode: "multiple";
  required: true;
  /** The selected dates array (required) */
  selected?: Date[];
  /** The default selected dates for uncontrolled mode (required) */
  defaultSelected?: Date[];
  /** Minimum number of dates that must be selected */
  min?: number;
  /** Maximum number of dates that can be selected */
  max?: number;
  /** Event handler when dates are selected (cannot be empty) */
  onSelect?: (
    dates: Date[],
    triggerDate: Date,
    modifiers: Modifiers,
    e: React.MouseEvent
  ) => void;
}

Usage Examples:

// Controlled multiple selection
function ControlledMultiple() {
  const [selected, setSelected] = useState<Date[]>([]);

  return (
    <DayPicker
      mode="multiple"
      selected={selected}
      onSelect={setSelected}
      max={5} // limit to 5 dates
    />
  );
}

// Multiple selection with constraints
function ConstrainedMultiple() {
  const [selected, setSelected] = useState<Date[]>([]);

  return (
    <DayPicker
      mode="multiple" 
      selected={selected}
      onSelect={setSelected}
      min={2}
      max={7}
      disabled={{ dayOfWeek: [0, 6] }} // disable weekends
    />
  );
}

Date Range Selection

Select a continuous range of dates with start and end dates.

/**
 * Props for date range selection mode
 */
interface PropsRange {
  mode: "range";
  /** The selected date range */
  selected?: DateRange;
  /** The default selected range for uncontrolled mode */
  defaultSelected?: DateRange;
  /** Minimum number of days in the range */
  min?: number;
  /** Maximum number of days in the range */
  max?: number;
  /** Event handler when a range is selected */
  onSelect?: (
    range: DateRange | undefined,
    triggerDate: Date,
    modifiers: Modifiers,
    e: React.MouseEvent
  ) => void;
}

/**
 * Props for required date range selection
 */
interface PropsRangeRequired {
  mode: "range";
  required: true;
  /** The selected date range (required) */
  selected?: DateRange;
  /** The default selected range for uncontrolled mode (required) */
  defaultSelected?: DateRange;
  /** Minimum number of days in the range */
  min?: number;
  /** Maximum number of days in the range */
  max?: number;
  /** Event handler when a range is selected (cannot be undefined) */
  onSelect?: (
    range: DateRange,
    triggerDate: Date,
    modifiers: Modifiers,
    e: React.MouseEvent
  ) => void;
}

/**
 * Date range interface
 */
interface DateRange {
  from: Date | undefined;
  to?: Date | undefined;
}

Usage Examples:

// Controlled range selection
function ControlledRange() {
  const [range, setRange] = useState<DateRange | undefined>();

  return (
    <DayPicker
      mode="range"
      selected={range}
      onSelect={setRange}
      numberOfMonths={2}
    />
  );
}

// Range selection with constraints
function ConstrainedRange() {
  const [range, setRange] = useState<DateRange | undefined>();
  
  const handleSelect = (newRange: DateRange | undefined) => {
    // Custom validation logic
    if (newRange?.from && newRange?.to) {
      const daysDiff = Math.abs(
        newRange.to.getTime() - newRange.from.getTime()
      ) / (1000 * 60 * 60 * 24);
      
      if (daysDiff > 14) {
        alert("Range cannot exceed 14 days");
        return;
      }
    }
    setRange(newRange);
  };

  return (
    <DayPicker
      mode="range"
      selected={range}
      onSelect={handleSelect}
      min={3} // minimum 3 days
      max={14} // maximum 14 days
    />
  );
}

// Range selection with custom styling
function StyledRange() {
  const [range, setRange] = useState<DateRange | undefined>();

  return (
    <DayPicker
      mode="range"
      selected={range}
      onSelect={setRange}
      modifiersClassNames={{
        range_start: "range-start",
        range_middle: "range-middle", 
        range_end: "range-end"
      }}
    />
  );
}

Selection Context Hook

Hook for accessing selection state in custom components.

/**
 * Hook providing access to the DayPicker context
 * @returns DayPicker context with selection state and handlers
 */
function useDayPicker<T extends DayPickerProps>(): DayPickerContext<T>;

interface DayPickerContext<T extends DayPickerProps> {
  /** The DayPicker props */
  dayPickerProps: T;
  /** Current selected value */
  selected: SelectedValue<T>;
  /** Selection handler function */
  select: SelectHandler<T>;
  /** Function to check if a date is selected */
  isSelected?: (date: Date) => boolean;
  /** Calendar months data */
  months: CalendarMonth[];
  /** Next navigable month */
  nextMonth?: Date;
  /** Previous navigable month */
  previousMonth?: Date;
  /** Navigate to specific month */
  goToMonth: (month: Date) => void;
  /** Get modifiers for a day */
  getModifiers: (day: CalendarDay) => Modifiers;
  /** Custom components */
  components: CustomComponents;
  /** CSS class names */
  classNames: ClassNames;
  /** CSS styles */
  styles?: Partial<Styles>;
  /** Accessibility labels */
  labels: Labels;
  /** Date formatters */
  formatters: Formatters;
}

Usage Example:

import { useDayPicker } from "react-day-picker";

function CustomFooter() {
  const { selected, mode } = useDayPicker();
  
  if (mode === "single" && selected) {
    return <p>Selected: {selected.toDateString()}</p>;
  }
  
  if (mode === "range" && selected?.from) {
    return (
      <p>
        {selected.from.toDateString()} 
        {selected.to ? ` - ${selected.to.toDateString()}` : " (select end date)"}
      </p>
    );
  }
  
  return <p>No date selected</p>;
}

// Usage in DayPicker
<DayPicker
  mode="single"
  components={{ Footer: CustomFooter }}
/>

Install with Tessl CLI

npx tessl i tessl/npm-react-day-picker

docs

customization.md

date-utilities.md

index.md

internationalization.md

main-component.md

selection.md

styling.md

tile.json