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

customization.mddocs/

Customization Options

React Day Picker provides extensive customization capabilities through component replacement, formatters, labels, and styling systems.

Capabilities

Custom Components System

Replace any UI element with custom React components while maintaining full functionality and accessibility.

/**
 * The components that can be customized using the components prop
 */
type CustomComponents = {
  /** Render any button element in DayPicker (deprecated - use NextMonthButton or PreviousMonthButton instead) */
  Button: React.ComponentType<ButtonProps>;
  /** Render the chevron icon used in the navigation buttons and dropdowns */
  Chevron: React.ComponentType<ChevronProps>;
  /** Render the caption label of the month grid */
  CaptionLabel: React.ComponentType<CaptionLabelProps>;
  /** Render the day cell in the month grid */
  Day: React.ComponentType<DayProps>;
  /** Render the button containing the day in the day cell */
  DayButton: React.ComponentType<DayButtonProps>;
  /** Render the dropdown element to select years and months */
  Dropdown: React.ComponentType<DropdownProps>;
  /** Render the container of the dropdowns */
  DropdownNav: React.ComponentType<DropdownNavProps>;
  /** Render the footer element announced by screen readers */
  Footer: React.ComponentType<FooterProps>;
  /** Render the container of the MonthGrid */
  Month: React.ComponentType<MonthProps>;
  /** Render the caption of the month grid */
  MonthCaption: React.ComponentType<MonthCaptionProps>;
  /** Render the grid of days in a month */
  MonthGrid: React.ComponentType<MonthGridProps>;
  /** Wrapper of the month grids */
  Months: React.ComponentType<MonthsProps>;
  /** Render the navigation element with the next and previous buttons */
  Nav: React.ComponentType<NavProps>;
  /** Render the option HTML element in the dropdown */
  Option: React.ComponentType<OptionProps>;
  /** Render the previous month button element in the navigation */
  PreviousMonthButton: React.ComponentType<PreviousMonthButtonProps>;
  /** Render the next month button element in the navigation */
  NextMonthButton: React.ComponentType<NextMonthButtonProps>;
  /** Render the root element of the calendar */
  Root: React.ComponentType<RootProps>;
  /** Render the select element in the dropdowns */
  Select: React.ComponentType<SelectProps>;
  /** Render the weeks section in the month grid */
  Weeks: React.ComponentType<WeeksProps>;
  /** Render the week rows */
  Week: React.ComponentType<WeekProps>;
  /** Render the weekday name in the header */
  Weekday: React.ComponentType<WeekdayProps>;
  /** Render the row containing the week days */
  Weekdays: React.ComponentType<WeekdaysProps>;
  /** Render the cell with the number of the week */
  WeekNumber: React.ComponentType<WeekNumberProps>;
  /** Render the header of the week number column */
  WeekNumberHeader: React.ComponentType<WeekNumberHeaderProps>;
  /** Render the dropdown for selecting months */
  MonthsDropdown: React.ComponentType<MonthsDropdownProps>;
  /** Render the dropdown for selecting years */
  YearsDropdown: React.ComponentType<YearsDropdownProps>;
};

Usage Examples:

import { DayPicker, type DayProps } from "react-day-picker";

// Custom day component with tooltip
function CustomDay({ day, modifiers, ...props }: DayProps) {
  const isWeekend = modifiers.weekend;
  
  return (
    <div 
      {...props}
      title={isWeekend ? "Weekend" : "Weekday"}
      style={{
        ...props.style,
        backgroundColor: isWeekend ? "#f0f0f0" : "white"
      }}
    >
      {props.children}
    </div>
  );
}

// Custom footer showing selection count
function CustomFooter() {
  const { selected, mode } = useDayPicker();
  const count = mode === "multiple" ? selected?.length || 0 : 0;
  
  return (
    <div style={{ padding: "10px", textAlign: "center" }}>
      {mode === "multiple" && `${count} dates selected`}
    </div>
  );
}

// Using custom components
<DayPicker
  mode="multiple"
  components={{
    Day: CustomDay,
    Footer: CustomFooter
  }}
  modifiers={{
    weekend: { dayOfWeek: [0, 6] }
  }}
/>

Component Props Types

interface DayProps {
  /** Calendar day data */
  day: CalendarDay;
  /** Day modifiers */
  modifiers: Modifiers;
  /** CSS class name */
  className?: string;
  /** Inline styles */
  style?: React.CSSProperties;
  /** Children elements */
  children?: React.ReactNode;
  /** Standard HTML attributes */
  [key: string]: any;
}

interface DayButtonProps {
  /** Calendar day data */
  day: CalendarDay;
  /** Day modifiers */
  modifiers: Modifiers;
  /** CSS class name */
  className?: string;
  /** Inline styles */
  style?: React.CSSProperties;
  /** Button type */
  type: "button";
  /** Disabled state */
  disabled?: boolean;
  /** Tab index */
  tabIndex?: number;
  /** Accessibility label */
  "aria-label"?: string;
  /** Click handler */
  onClick?: React.MouseEventHandler;
  /** Focus handler */
  onFocus?: React.FocusEventHandler;
  /** Blur handler */
  onBlur?: React.FocusEventHandler;
  /** Key down handler */
  onKeyDown?: React.KeyboardEventHandler;
  /** Mouse enter handler */
  onMouseEnter?: React.MouseEventHandler;
  /** Mouse leave handler */
  onMouseLeave?: React.MouseEventHandler;
  /** Children elements */
  children?: React.ReactNode;
}

interface MonthProps {
  /** Display index in multi-month view */
  displayIndex: number;
  /** Calendar month data */
  calendarMonth: CalendarMonth;
  /** CSS class name */
  className?: string;
  /** Inline styles */  
  style?: React.CSSProperties;
  /** Children elements */
  children?: React.ReactNode;
}

interface NavProps {
  /** CSS class name */
  className?: string;
  /** Inline styles */
  style?: React.CSSProperties;
  /** Accessibility label */
  "aria-label"?: string;
  /** Previous month click handler */
  onPreviousClick?: () => void;
  /** Next month click handler */
  onNextClick?: () => void;
  /** Previous month data */
  previousMonth?: Date;
  /** Next month data */
  nextMonth?: Date;
  /** Children elements */
  children?: React.ReactNode;
}

Formatters System

Customize how dates and labels are displayed throughout the calendar.

/**
 * Interface for custom date and text formatters
 */
interface Formatters {
  /** Format the month caption (e.g., "November 2024") */
  formatCaption: (
    month: Date,
    options?: DateLibOptions,
    dateLib?: DateLib
  ) => string;
  
  /** Format individual day numbers */
  formatDay: (
    date: Date,
    options?: DateLibOptions,
    dateLib?: DateLib
  ) => string;
  
  /** Format month names in dropdown */
  formatMonthDropdown: (month: Date, dateLib?: DateLib) => string;
  
  /** Format year values in dropdown */
  formatYearDropdown: (year: Date, dateLib?: DateLib) => string;
  
  /** Format weekday names in header */
  formatWeekdayName: (
    weekday: Date,
    options?: DateLibOptions,
    dateLib?: DateLib
  ) => string;
  
  /** Format week numbers */
  formatWeekNumber: (weekNumber: number, dateLib?: DateLib) => string;
  
  /** Format week number column header */
  formatWeekNumberHeader: () => string;
}

Usage Examples:

const customFormatters: Partial<Formatters> = {
  formatCaption: (month, options, dateLib) => {
    return dateLib?.format(month, "MMMM yyyy", options) || "";
  },
  
  formatDay: (date, options, dateLib) => {
    // Add ordinal suffix to day numbers
    const day = dateLib?.getDate(date) || date.getDate();
    const suffix = getOrdinalSuffix(day);
    return `${day}${suffix}`;
  },
  
  formatWeekdayName: (weekday, options, dateLib) => {
    // Use single letter weekday names
    return dateLib?.format(weekday, "EEEEE", options) || "";
  }
};

function getOrdinalSuffix(day: number): string {
  if (day > 3 && day < 21) return "th";
  switch (day % 10) {
    case 1: return "st";
    case 2: return "nd"; 
    case 3: return "rd";
    default: return "th";
  }
}

<DayPicker formatters={customFormatters} />

Labels System

Customize accessibility labels for screen readers and assistive technologies.

/**
 * Interface for custom accessibility labels
 */
interface Labels {
  /** Label for day buttons */
  labelDayButton: (
    date: Date,
    modifiers: Modifiers,
    options?: DateLibOptions,
    dateLib?: DateLib
  ) => string;
  
  /** Label for the calendar grid */
  labelGrid: (
    month: Date,
    options?: DateLibOptions,
    dateLib?: DateLib
  ) => string;
  
  /** Label for non-interactive grid cells */
  labelGridcell: (
    date: Date,
    modifiers: Modifiers,
    options?: DateLibOptions,
    dateLib?: DateLib
  ) => string;
  
  /** Label for month dropdown */
  labelMonthDropdown: () => string;
  
  /** Label for year dropdown */
  labelYearDropdown: (options?: DateLibOptions) => string;
  
  /** Label for navigation toolbar */
  labelNav: () => string;
  
  /** Label for next month button */
  labelNext: (month?: Date) => string;
  
  /** Label for previous month button */
  labelPrevious: (month?: Date) => string;
  
  /** Label for weekday headers */
  labelWeekday: (
    weekday: Date,
    options?: DateLibOptions,
    dateLib?: DateLib
  ) => string;
  
  /** Label for week numbers */
  labelWeekNumber: (
    weekNumber: number,
    options?: { locale?: Locale }
  ) => string;
  
  /** Label for week number header */
  labelWeekNumberHeader: (options?: DateLibOptions) => string;
}

Usage Examples:

const customLabels: Partial<Labels> = {
  labelDayButton: (date, modifiers) => {
    const dayName = date.toLocaleDateString("en-US", { weekday: "long" });
    const monthName = date.toLocaleDateString("en-US", { month: "long" });
    const day = date.getDate();
    const year = date.getFullYear();
    
    let label = `${dayName}, ${monthName} ${day}, ${year}`;
    
    if (modifiers.selected) label += " (selected)";
    if (modifiers.disabled) label += " (disabled)";
    if (modifiers.today) label += " (today)";
    
    return label;
  },
  
  labelNext: (month) => {
    if (!month) return "Go to next month";
    const monthName = month.toLocaleDateString("en-US", { month: "long" });
    const year = month.getFullYear();
    return `Go to ${monthName} ${year}`;
  },
  
  labelPrevious: (month) => {
    if (!month) return "Go to previous month";
    const monthName = month.toLocaleDateString("en-US", { month: "long" });
    const year = month.getFullYear();
    return `Go to ${monthName} ${year}`;
  }
};

<DayPicker labels={customLabels} />

Data Classes

Core data structures used throughout the customization system.

/**
 * Represents a day in the calendar
 */
class CalendarDay {
  /** The date this day represents */
  date: Date;
  /** The month this day is displayed in */
  displayMonth: Date;
  /** Whether this day is outside the display month */
  outside: boolean;
  /** DateLib instance for date operations */
  dateLib: DateLib;
  
  constructor(date: Date, displayMonth: Date, dateLib?: DateLib);
  
  /** Check if this day is equal to another day */
  isEqualTo(day: CalendarDay): boolean;
}

/**
 * Represents a week in the calendar
 */
class CalendarWeek {
  /** Week number in the year */
  weekNumber: number;
  /** Array of days in this week */
  days: CalendarDay[];
  
  constructor(weekNumber: number, days: CalendarDay[]);
}

/**
 * Represents a month in the calendar
 */
class CalendarMonth {
  /** The date representing this month */
  date: Date;
  /** Array of weeks in this month */
  weeks: CalendarWeek[];
  
  constructor(date: Date, weeks: CalendarWeek[]);
}

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