phx-react
Version:
PHX REACT
97 lines • 6.62 kB
JavaScript
import { CalendarDaysIcon } from '@heroicons/react/20/solid';
import { format, parse, subDays } from 'date-fns';
import React, { useEffect, useRef, useState } from 'react';
import Calendar from './components/Calendar';
import { caculateTotalDay, formatViewResult } from './utils';
import ErrorMessage from '../../commons/ErrorMessage';
function classNames(...classes) {
return classes.filter(Boolean).join(' ');
}
export function PHXDateRangePicker({ className, defaultValue, disabled, disabledDate, error, errorType, label, max, min, onChange, position_component, origin = 'bottom-left', isFullWidth = false, defaultRange, hide365Days = false, }) {
const message = (type) => {
let errorMessage = '';
switch (type) {
case 'required-field':
errorMessage = 'Vui lòng nhập thông tin';
break;
default:
break;
}
return errorMessage;
};
const inputRef = useRef(null);
const calendarRef = useRef(null);
const [isCalendarVisible, setIsCalendarVisible] = useState(false);
const handleToggleCalendar = () => {
setIsCalendarVisible(!isCalendarVisible);
};
useEffect(() => {
const handleClickOutside = (event) => {
if (calendarRef.current &&
!calendarRef.current.contains(event.target) &&
inputRef.current &&
!inputRef.current.contains(event.target)) {
setIsCalendarVisible(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
if ((defaultRange === null || defaultRange === void 0 ? void 0 : defaultRange.start) && (defaultRange === null || defaultRange === void 0 ? void 0 : defaultRange.end)) {
const totalDays = caculateTotalDay(defaultRange.start, defaultRange.end);
const endDate = new Date(defaultRange.end);
const startDate = subDays(endDate, totalDays);
const formattedStartDate = format(startDate, 'dd-MM-yyyy');
const formattedEndDate = format(endDate, 'dd-MM-yyyy');
const parsedStartDate = parse(formattedStartDate, 'dd-MM-yyyy', new Date());
const parsedEndDate = parse(formattedEndDate, 'dd-MM-yyyy', new Date());
handleResult(parsedStartDate, parsedEndDate);
return;
}
if (defaultValue) {
const endDate = new Date();
const startDate = subDays(endDate, defaultValue - 1);
const formattedStartDate = format(startDate, 'dd-MM-yyyy');
const formattedEndDate = format(endDate, 'dd-MM-yyyy');
const parsedStartDate = parse(formattedStartDate, 'dd-MM-yyyy', new Date());
const parsedEndDate = parse(formattedEndDate, 'dd-MM-yyyy', new Date());
handleResult(parsedStartDate, parsedEndDate);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [defaultValue, defaultRange === null || defaultRange === void 0 ? void 0 : defaultRange.start, defaultRange === null || defaultRange === void 0 ? void 0 : defaultRange.end]);
const [viewResult, setViewResult] = useState('Ngày hôm nay');
const handleResult = (startDate, endDate) => {
if (!startDate || !endDate) {
return;
}
const startDateResult = format(startDate, 'yyyy/MM/dd');
const endDateResult = format(endDate, 'yyyy/MM/dd');
if (onChange && startDateResult && endDateResult) {
onChange({ startDate: startDateResult, endDate: endDateResult });
}
const viewDate = formatViewResult(startDate, endDate);
setViewResult(viewDate);
setIsCalendarVisible(false);
};
const handleCancel = () => {
setIsCalendarVisible(false);
};
return (React.createElement("div", { className: className },
label && React.createElement("label", { className: 'mb-1 block text-xs font-normal text-gray-700' }, label),
React.createElement("div", { className: 'relative' },
React.createElement("button", { disabled: disabled, className: classNames(`bg-white px-2.5 py-1 transition-all relative flex items-center justify-center text-xs rounded-lg font-normal text-gray-900 shadow-[inset_0_0_0_1px_#e3e3e3] active:bg-[#f7f7f7] active:shadow-[inset_0_2px_1px_0_#1a1a1a33,inset_-1px_0_1px_0_#1a1a1a1f,inset_1px_0_1px_0_#1a1a1a1f] md:shadow-[inset_0_-1px_0_0_#b5b5b5,inset_0_0_0_1px_#0000001a,inset_0_0.5px_0_1.5px_#fff] ${isCalendarVisible
? 'shadow-[inset_0_2px_1px_0_#1a1a1a33,inset_-1px_0_1px_0_#1a1a1a1f,inset_1px_0_1px_0_#1a1a1a1f]'
: ''}`, 'before:transtion-opacity shadow-[inset_0_1px_theme(colors.white/0.07),0_0.12px_0_theme(colors.gray.900/0.5)] group relative isolate flex items-center justify-center overflow-hidden transition duration-300 ease-[cubic-bezier(0.4,0.36,0,1)] before:pointer-events-none before:absolute before:inset-0 before:-z-10 before:bg-gradient-to-b before:from-white/20 before:opacity-50 before:duration-300 before:ease-[cubic-bezier(0.4,0.36,0,1)] after:pointer-events-none after:absolute after:inset-0 after:-z-10 after:bg-gradient-to-b after:from-white/10 after:from-[46%] after:to-[54%] after:mix-blend-overlay hover:before:opacity-100', isFullWidth ? 'w-full' : '', className), onClick: handleToggleCalendar, ref: inputRef, type: 'button' },
React.createElement(CalendarDaysIcon, { className: 'mr-1 h-4 w-4 text-gray-500' }),
viewResult),
error && errorType ? React.createElement(ErrorMessage, { message: message(errorType) }) : null,
React.createElement("div", { ref: calendarRef, className: position_component === 'left'
? classNames('left-30 absolute right-[8px] top-10 z-50', isCalendarVisible ? '' : 'hidden')
: classNames('absolute z-50', origin === 'top-left' && '-top-60 left-0', origin === 'top-right' && '-top-60 right-0', origin === 'bottom-left' && 'left-0 top-10', origin === 'bottom-right' && 'right-0 top-10', isCalendarVisible ? '' : 'hidden') },
React.createElement(Calendar, { defaultDate: defaultValue, disabledDate: disabledDate, handleCancel: handleCancel, handleResult: handleResult, max: max, min: min, defaultRange: defaultRange, hide365Days: hide365Days })))));
}
//# sourceMappingURL=DatePicker.js.map