@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
JavaScript
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;