UNPKG

@wordpress/components

Version:
161 lines (158 loc) 4.98 kB
/** * External dependencies */ import { differenceInCalendarDays } from 'date-fns'; import { DayPicker, rangeContainsModifiers } from 'react-day-picker'; import { enUS } from 'react-day-picker/locale'; /** * WordPress dependencies */ import { useMemo, useState, useCallback } from '@wordpress/element'; /** * Internal dependencies */ import { COMMON_PROPS, MODIFIER_CLASSNAMES } from '../utils/constants'; import { clampNumberOfMonths } from '../utils/misc'; import { useControlledValue } from '../../utils/hooks'; import { useLocalizationProps } from '../utils/use-localization-props'; import { jsx as _jsx } from "react/jsx-runtime"; export function usePreviewRange({ selected, hoveredDate, excludeDisabled, min, max, disabled }) { return useMemo(() => { if (!hoveredDate || !selected?.from) { return; } let previewHighlight; let potentialNewRange; // Hovering on a date before the start of the selected range if (hoveredDate < selected.from) { var _selected$to; previewHighlight = { from: hoveredDate, to: selected.from }; potentialNewRange = { from: hoveredDate, to: (_selected$to = selected.to) !== null && _selected$to !== void 0 ? _selected$to : selected.from }; } else if (selected.to && hoveredDate > selected.from && hoveredDate < selected.to) { // Hovering on a date between the start and end of the selected range previewHighlight = { from: selected.from, to: hoveredDate }; potentialNewRange = { from: selected.from, to: hoveredDate }; } else if (hoveredDate > selected.from) { var _selected$to2; // Hovering on a date after the end of the selected range (either // because it's greater than selected.to, or because it's not defined) previewHighlight = { from: (_selected$to2 = selected.to) !== null && _selected$to2 !== void 0 ? _selected$to2 : selected.from, to: hoveredDate }; potentialNewRange = { from: selected.from, to: hoveredDate }; } if (min !== undefined && min > 0 && potentialNewRange && differenceInCalendarDays(potentialNewRange.to, potentialNewRange.from) < min) { previewHighlight = { from: hoveredDate, to: hoveredDate }; } if (max !== undefined && max > 0 && potentialNewRange && differenceInCalendarDays(potentialNewRange.to, potentialNewRange.from) > max) { previewHighlight = { from: hoveredDate, to: hoveredDate }; } if (excludeDisabled && disabled && potentialNewRange && rangeContainsModifiers(potentialNewRange, disabled)) { previewHighlight = { from: hoveredDate, to: hoveredDate }; } return previewHighlight; }, [selected, hoveredDate, excludeDisabled, min, max, disabled]); } /** * `DateRangeCalendar` is a React component that provides a customizable calendar * interface for **date range** selection. * * The component is built with accessibility in mind and follows ARIA best * practices for calendar widgets. It provides keyboard navigation, screen reader * support, and customizable labels for internationalization. */ export const DateRangeCalendar = ({ defaultSelected, selected: selectedProp, onSelect, numberOfMonths = 1, excludeDisabled, min, max, disabled, locale = enUS, timeZone, ...props }) => { const localizationProps = useLocalizationProps({ locale, timeZone, mode: 'range' }); const onChange = useCallback((selected, triggerDate, modifiers, e) => { // Convert internal `null` to `undefined` for the public event handler. onSelect?.(selected !== null && selected !== void 0 ? selected : undefined, triggerDate, modifiers, e); }, [onSelect]); const [selected, setSelected] = useControlledValue({ defaultValue: defaultSelected, value: selectedProp, onChange }); const [hoveredDate, setHoveredDate] = useState(undefined); // Compute the preview range for hover effect const previewRange = usePreviewRange({ selected, hoveredDate, excludeDisabled, min, max, disabled }); const modifiers = useMemo(() => { return { preview: previewRange, preview_start: previewRange?.from, preview_end: previewRange?.to }; }, [previewRange]); return /*#__PURE__*/_jsx(DayPicker, { ...COMMON_PROPS, ...localizationProps, ...props, mode: "range", numberOfMonths: clampNumberOfMonths(numberOfMonths), disabled: disabled, excludeDisabled: excludeDisabled, min: min, max: max, selected: selected !== null && selected !== void 0 ? selected : undefined, onSelect: setSelected, onDayMouseEnter: date => setHoveredDate(date), onDayMouseLeave: () => setHoveredDate(undefined), modifiers: modifiers, modifiersClassNames: MODIFIER_CLASSNAMES }); }; //# sourceMappingURL=index.js.map