Customizable Date Picker for React with extensive internationalization and accessibility support
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
React Day Picker provides utility functions for working with dates, date ranges, intervals, and matching patterns.
Utilities for creating, manipulating, and validating date ranges.
/**
* Date range interface
*/
interface DateRange {
from: Date | undefined;
to?: Date | undefined;
}
/**
* Adds a date to an existing range, considering constraints like minimum and
* maximum range size.
* @param date - The date to add to the range
* @param initialRange - The initial range to which the date will be added
* @param min - The minimum number of days in the range
* @param max - The maximum number of days in the range
* @param required - Whether the range must always include at least one date
* @param dateLib - The date utility library instance
* @returns The updated date range, or undefined if the range is cleared
*/
function addToRange(
date: Date,
initialRange: DateRange | undefined,
min?: number,
max?: number,
required?: boolean,
dateLib?: DateLib
): DateRange | undefined;
/**
* Check if a date is included in a date range
* @param range - The date range to check
* @param date - The date to check for inclusion
* @param excludeEnds - Whether to exclude the start and end dates
* @param dateLib - Optional DateLib instance for date operations
* @returns True if date is within the range
*/
function rangeIncludesDate(
range: DateRange,
date: Date,
excludeEnds?: boolean,
dateLib?: DateLib
): boolean;
/**
* Determines if two date ranges overlap
* @param rangeLeft - The first date range
* @param rangeRight - The second date range
* @param dateLib - The date utility library instance
* @returns True if the ranges overlap, otherwise false
*/
function rangeOverlaps(
rangeLeft: { from: Date; to: Date },
rangeRight: { from: Date; to: Date },
dateLib?: DateLib
): boolean;
/**
* Checks if a date range contains one or more specified days of the week
* @param range - The date range to check
* @param dayOfWeek - The day(s) of the week to check for (0-6, where 0 is Sunday)
* @param dateLib - The date utility library instance
* @returns True if the range contains the specified day(s) of the week, otherwise false
*/
function rangeContainsDayOfWeek(
range: { from: Date; to: Date },
dayOfWeek: number | number[],
dateLib?: DateLib
): boolean;
/**
* Checks if a date range contains dates that match the given modifiers
* @param range - The date range to check
* @param modifiers - The modifiers to match against
* @param dateLib - The date utility library instance
* @returns True if the range contains matching dates, otherwise false
*/
function rangeContainsModifiers(
range: { from: Date; to: Date },
modifiers: Matcher | Matcher[],
dateLib?: DateLib
): boolean;Usage Examples:
import {
addToRange,
rangeIncludesDate,
rangeOverlaps,
type DateRange
} from "react-day-picker";
// Building a date range interactively
function InteractiveRange() {
const [range, setRange] = useState<DateRange | undefined>();
const handleDateClick = (date: Date) => {
// Add clicked date to range with max 14 days constraint
const newRange = addToRange(date, range, { max: 14 });
setRange(newRange);
};
return (
<DayPicker
mode="single"
onDayClick={handleDateClick}
selected={range?.from}
modifiers={{
range_start: range?.from,
range_end: range?.to,
range_middle: (date: Date) =>
range ? rangeIncludesDate(range, date, true) : false
}}
/>
);
}
// Check for overlapping vacation periods
function VacationChecker() {
const vacation1: DateRange = {
from: new Date(2024, 6, 10),
to: new Date(2024, 6, 20)
};
const vacation2: DateRange = {
from: new Date(2024, 6, 15),
to: new Date(2024, 6, 25)
};
const hasOverlap = rangeOverlaps(vacation1, vacation2);
console.log(`Vacations overlap: ${hasOverlap}`); // true
return (
<DayPicker
mode="range"
modifiers={{
vacation1: vacation1,
vacation2: vacation2,
overlap: (date: Date) =>
rangeIncludesDate(vacation1, date) &&
rangeIncludesDate(vacation2, date)
}}
/>
);
}
// Check if range includes weekends
const businessRange: DateRange = {
from: new Date(2024, 6, 1),
to: new Date(2024, 6, 31)
};
const includesWeekends = rangeContainsDayOfWeek(
businessRange,
[0, 6] // Sunday and Saturday
);Utilities for matching dates against various criteria.
/**
* Checks if a given date matches at least one of the specified Matcher
* @param date - The date to check
* @param matchers - The matchers to check against
* @param dateLib - The date utility library instance
* @returns True if the date matches any of the matchers, otherwise false
*/
function dateMatchModifiers(
date: Date,
matchers: Matcher | Matcher[],
dateLib?: DateLib
): boolean;
/**
* Union type for various date matching patterns
*/
type Matcher =
| boolean
| ((date: Date) => boolean)
| Date
| Date[]
| DateRange
| DateInterval
| DateBefore
| DateAfter
| DayOfWeek;
/**
* Date interval matcher (between two dates)
*/
interface DateInterval {
before: Date;
after: Date;
}
/**
* Before date matcher
*/
interface DateBefore {
before: Date;
}
/**
* After date matcher
*/
interface DateAfter {
after: Date;
}
/**
* Day of week matcher
*/
interface DayOfWeek {
dayOfWeek: number | number[];
}Usage Examples:
import { dateMatchModifiers, type Matcher } from "react-day-picker";
// Complex date matching
const matchers: Matcher[] = [
new Date(2024, 6, 4), // July 4th
{ before: new Date(2024, 0, 1) }, // Before New Year
{ after: new Date(2024, 11, 31) }, // After New Year's Eve
{ dayOfWeek: [0, 6] }, // Weekends
{ before: new Date(2024, 6, 1), after: new Date(2024, 5, 1) }, // June
(date: Date) => date.getDate() === 13 // Friday the 13th check elsewhere
];
const testDate = new Date(2024, 6, 4);
const matches = dateMatchModifiers(testDate, matchers);
console.log(`Date matches: ${matches}`); // true (July 4th)Utility functions to determine the type of matchers and values.
/**
* Checks if the given value is of type DateRange
* @param value - The value to check
* @returns True if the value is a DateRange, otherwise false
*/
function isDateRange(value: unknown): value is DateRange;
/**
* Checks if the given value is of type DateInterval
* @param matcher - The value to check
* @returns True if the value is a DateInterval, otherwise false
*/
function isDateInterval(matcher: unknown): matcher is DateInterval;
/**
* Checks if the given value is of type DateAfter
* @param value - The value to check
* @returns True if the value is a DateAfter, otherwise false
*/
function isDateAfterType(value: unknown): value is DateAfter;
/**
* Checks if the given value is of type DateBefore
* @param value - The value to check
* @returns True if the value is a DateBefore, otherwise false
*/
function isDateBeforeType(value: unknown): value is DateBefore;
/**
* Checks if the given value is an array of valid dates
* @param value - The value to check
* @param dateLib - The date utility library instance
* @returns True if the value is an array of valid dates, otherwise false
*/
function isDatesArray(value: unknown, dateLib: DateLib): value is Date[];
/**
* Checks if the given value is of type DayOfWeek
* @param value - The value to check
* @returns True if the value is a DayOfWeek, otherwise false
*/
function isDayOfWeekType(value: unknown): value is DayOfWeek;Usage Examples:
import {
isDateRange,
isDateInterval,
isDayOfWeekType,
type DateRange,
type DateInterval,
type DayOfWeek
} from "react-day-picker";
function processDateMatcher(matcher: any) {
if (isDateRange(matcher)) {
console.log(`Range from ${matcher.from} to ${matcher.to}`);
} else if (isDateInterval(matcher)) {
console.log(`Interval between ${matcher.after} and ${matcher.before}`);
} else if (isDayOfWeekType(matcher)) {
const days = Array.isArray(matcher.dayOfWeek)
? matcher.dayOfWeek
: [matcher.dayOfWeek];
console.log(`Days of week: ${days.join(', ')}`);
}
}
// Usage in component
function SmartCalendar({ disabledDates }: { disabledDates: any[] }) {
const processedDisabled = disabledDates.filter(matcher => {
// Only include valid matchers
return isDateRange(matcher) ||
isDateInterval(matcher) ||
isDayOfWeekType(matcher) ||
matcher instanceof Date ||
typeof matcher === 'function';
});
return (
<DayPicker
disabled={processedDisabled}
modifiers={{
weekend: { dayOfWeek: [0, 6] },
holiday: [
new Date(2024, 6, 4),
new Date(2024, 11, 25)
]
}}
/>
);
}Additional utility functions for common calendar operations.
/**
* Get default CSS class names for all UI elements
* @returns Complete ClassNames mapping with default values
*/
function getDefaultClassNames(): ClassNames;
/**
* Calculate focus target for keyboard navigation
* @param focusTarget - Current focus target
* @param moveBy - Type of movement
* @param moveDir - Direction of movement
* @param focusableDate - Date that can receive focus
* @param dateLib - DateLib instance
* @returns New focus target date
*/
function calculateFocusTarget(
focusTarget: CalendarDay,
moveBy: MoveFocusBy,
moveDir: MoveFocusDir,
focusableDate: Date,
dateLib: DateLib
): Date;
/**
* Movement types for keyboard navigation
*/
type MoveFocusBy =
| "day"
| "week"
| "month"
| "year"
| "startOfWeek"
| "endOfWeek";
/**
* Movement directions
*/
type MoveFocusDir = "before" | "after";Usage Examples:
import { getDefaultClassNames } from "react-day-picker";
// Get default class names for customization
const defaultClassNames = getDefaultClassNames();
const customClassNames = {
...defaultClassNames,
day: `${defaultClassNames.day} my-custom-day`,
selected: `${defaultClassNames.selected} my-selected-day`
};
<DayPicker classNames={customClassNames} />
// Custom keyboard navigation handler
function CustomNavigationCalendar() {
const handleKeyDown = (
date: Date,
modifiers: Modifiers,
e: React.KeyboardEvent
) => {
if (e.key === 'Enter') {
console.log(`Selected date: ${date.toDateString()}`);
}
};
return (
<DayPicker
mode="single"
onDayKeyDown={handleKeyDown}
/>
);
}Install with Tessl CLI
npx tessl i tessl/npm-react-day-picker