UNPKG

@pagamio/frontend-commons-lib

Version:

Pagamio library for Frontend reusable components like the form engine and table container

93 lines (92 loc) 3.53 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { addDays, endOfDay, startOfDay } from 'date-fns'; import { DateRangePicker } from 'react-date-range'; import 'react-date-range/dist/styles.css'; // main style file import 'react-date-range/dist/theme/default.css'; import { useEffect, useMemo, useState } from 'react'; import { cn } from '../../helpers'; /** * A flexible date range picker component using react-date-range * * @see For more customization options, refer to: * - https://hypeserver.github.io/react-date-range/ * - https://www.npmjs.com/package/react-date-range * * @example * ```tsx * const [selectedRange, setSelectedRange] = useState({ * startDate: startOfDay(new Date()), * endDate: endOfDay(addDays(new Date(), 3)), * }); * * return ( * <RangeDatePicker * dateRange={selectedRange} * onChange={setSelectedRange} * showPreview={true} * /> * ) * ``` */ const FALLBACK_PRIMARY = '#b45dae'; const getPrimaryColorFromTheme = () => { if (typeof window === 'undefined') { return FALLBACK_PRIMARY; } try { const probe = document.createElement('span'); probe.style.display = 'none'; probe.className = 'bg-primary-500'; document.body.appendChild(probe); const computedColor = window.getComputedStyle(probe).backgroundColor; document.body.removeChild(probe); return computedColor || FALLBACK_PRIMARY; } catch (error) { console.warn('Unable to infer primary color from theme; falling back.', error); return FALLBACK_PRIMARY; } }; const RangeDatePicker = ({ dateRange, onChange, minDate, maxDate, className, months = 2, direction = 'horizontal', showPreview = true, rangeKey = 'selection', }) => { // Default range: today to 7 days from now const defaultRange = { startDate: startOfDay(new Date()), endDate: endOfDay(addDays(new Date(), 7)), key: rangeKey, }; const [range, setRange] = useState(dateRange ?? defaultRange); const [primaryColor, setPrimaryColor] = useState(FALLBACK_PRIMARY); const memoizedRangeColors = useMemo(() => [primaryColor], [primaryColor]); // Update internal state when dateRange prop changes useEffect(() => { if (dateRange) { setRange({ ...dateRange, key: rangeKey, }); } }, [dateRange, rangeKey]); useEffect(() => { setPrimaryColor(getPrimaryColorFromTheme()); }, []); // Handle date range changes const handleRangeChange = (rangesByKey) => { const newRange = rangesByKey[rangeKey]; if (newRange?.startDate) { // Ensure start/end of day applied appropriately const updatedRange = { startDate: startOfDay(newRange.startDate), endDate: endOfDay(newRange.endDate ?? newRange.startDate), key: rangeKey, }; setRange(updatedRange); // Notify parent component if onChange is provided if (onChange) { onChange(updatedRange); } } }; return (_jsx("div", { className: cn('range-date-picker', className), children: _jsx(DateRangePicker, { ranges: [range], onChange: handleRangeChange, moveRangeOnFirstSelection: false, months: months, direction: direction, showPreview: showPreview, showDateDisplay: true, minDate: minDate, maxDate: maxDate, rangeColors: memoizedRangeColors }) })); }; export default RangeDatePicker;