UNPKG

@drivy/cobalt

Version:

Opinionated design system for Drivy's projects.

202 lines (201 loc) 11 kB
import { jsx, jsxs } from "react/jsx-runtime"; import classnames from "classnames"; import { differenceInCalendarDays, format, isSameDay } from "date-fns"; import { useCallback, useMemo } from "react"; import { getMonthDaysByWeeks, getWeekDays } from "../utils.js"; import { CalendarRangePickerDay } from "./CalendarRangePickerDay.js"; function isDisabled(day, firstAvailableDate, lastAvailableDate) { return day.getTime() < firstAvailableDate.getTime() || null != lastAvailableDate && day.getTime() > lastAvailableDate.getTime(); } function isInvalidOppositeBound({ isEditingStartDate, isEditingEndDate, isStartDay, isEndDay, startDate, endDate }) { return null != startDate && null != endDate && startDate > endDate && (isEditingStartDate && isEndDay || isEditingEndDate && isStartDay); } function isDayOutOfRange({ day, rangeConstraints, startDate }) { return null != rangeConstraints && null != rangeConstraints.max && null != startDate && differenceInCalendarDays(day, startDate) >= rangeConstraints.max.value; } function isDayInvalid({ day, isDaySelected, rangeConstraints, rangeTooShort, rangeExceeded, isEditingStartDate, isEditingEndDate, isStartDay, isEndDay, isDayInvalidForSelectionFn, startDate, endDate }) { if (!isDaySelected) return false; let isInvalid = false; isInvalid = isEditingStartDate || isEditingEndDate ? rangeTooShort && (!isStartDay || isEndDay) ? true : isInvalidOppositeBound({ isEditingStartDate, isEditingEndDate, isStartDay, isEndDay, startDate, endDate }) ? true : isDayOutOfRange({ day, rangeConstraints, startDate }) : rangeTooShort || rangeExceeded; if (!isInvalid && isDayInvalidForSelectionFn && (isEditingStartDate && isStartDay || isEditingEndDate && isEndDay)) isInvalid = isDayInvalidForSelectionFn(day); return isInvalid; } function isSelected({ day, startDate, endDate, isStartDay, isEndDay, isOutOfRangeStartDate, rangeTooShort, isEditingStartDate, isEditingEndDate }) { return !!(isStartDay || isEndDay || (!rangeTooShort || !isEditingStartDate && !isEditingEndDate) && !isOutOfRangeStartDate && endDate && day.getTime() <= endDate.getTime() && startDate && day.getTime() > startDate.getTime()); } function isRangeExceeded(rangeInDays, rangeLimit) { return null != rangeLimit && rangeInDays > rangeLimit; } function isRangeTooShort(rangeInDays, rangeLimit) { return rangeInDays <= 0 ? false : null != rangeLimit && rangeInDays < rangeLimit; } function buildTooltipMessage({ rangeInDays, isEditingStartDate, isStartDay, isEditingEndDate, isEndDay, rangeConstraints }) { let tooltipMessage; if (rangeConstraints && rangeInDays >= 0 && (isEditingStartDate && isStartDay || isEditingEndDate && isEndDay)) { if (isRangeTooShort(rangeInDays, rangeConstraints.min?.value)) tooltipMessage = rangeConstraints?.min?.message; else if (isRangeExceeded(rangeInDays, rangeConstraints.max?.value)) tooltipMessage = rangeConstraints?.max?.message; } return tooltipMessage; } function getRangeInDays(range) { return range.startDate && range.endDate ? differenceInCalendarDays(range.endDate, range.startDate) + 1 : 0; } function CalendarRangePickerMonth({ date, onSelectDate, onChangeDate, onLeaveDate, startDate, endDate, isEditingStartDate = false, isEditingEndDate = false, firstAvailableDate, lastAvailableDate, isDayDisabledFn, isDayInvalidForSelectionFn, hasDayNotificationFn, dayHoverTooltipFn, rangeConstraints, isSundayFirstDayOfWeek, locale }) { const byWeeks = useMemo(()=>getMonthDaysByWeeks(date, isSundayFirstDayOfWeek), [ date, isSundayFirstDayOfWeek ]); const today = new Date().setHours(0, 0, 0, 0); const weekdays = useMemo(()=>getWeekDays(isSundayFirstDayOfWeek), [ isSundayFirstDayOfWeek ]); const rangeInDays = getRangeInDays({ startDate, endDate }); const rangeExceeded = isRangeExceeded(rangeInDays, rangeConstraints?.max?.value); const rangeTooShort = isRangeTooShort(rangeInDays, rangeConstraints?.min?.value); const isOutOfRangeStartDate = isEditingStartDate && rangeExceeded; const onMouseEnter = (day, disabled)=>{ const status = {}; if (disabled) status.isDisabled = true; if (!disabled && endDate && startDate) { const currentRange = isEditingStartDate ? { startDate: day, endDate: endDate } : { startDate: startDate, endDate: day }; const currentRangeInDays = getRangeInDays({ startDate: currentRange.startDate, endDate: currentRange.endDate }); const currentRangeExceeded = isRangeExceeded(currentRangeInDays, rangeConstraints?.max?.value); if (currentRangeExceeded) status.isRangeExceeded = true; else { const currentRangeTooShort = isRangeTooShort(currentRangeInDays, rangeConstraints?.min?.value); if (currentRangeTooShort) status.isRangeTooShort = true; else status.isCustomInvalid = isDayInvalidForSelectionFn?.(day); } } onChangeDate(day, status); }; const onSelectDateCallback = useCallback((date)=>{ isEditingStartDate ? onSelectDate(date, isRangeExceeded(getRangeInDays({ startDate: date, endDate }), rangeConstraints?.max?.value)) : onSelectDate(date, isRangeExceeded(getRangeInDays({ startDate, endDate: date }), rangeConstraints?.max?.value)); }, [ isEditingStartDate, onSelectDate, rangeConstraints?.max?.value, startDate, endDate ]); return /*#__PURE__*/ jsxs("div", { className: classnames("cobalt-CalendarRangePicker__month", { "cobalt-CalendarRangePicker__month--invalid": rangeExceeded && !isEditingStartDate }), "data-month": format(date, "yyyy-MM"), children: [ /*#__PURE__*/ jsx("div", { className: "cobalt-CalendarRangePicker__month-header", children: format(date, "MMMM yyyy", { locale }) }), /*#__PURE__*/ jsxs("div", { className: "cobalt-CalendarRangePicker__month__weeks-container", children: [ /*#__PURE__*/ jsx("div", { className: "cobalt-CalendarRangePicker__month__week-header", children: weekdays.map((weekday)=>/*#__PURE__*/ jsx("div", { className: "cobalt-CalendarRangePicker__month__day-header", children: format(weekday, "iiiiii", { locale }) }, weekday.getTime())) }), byWeeks.map((week, index)=>/*#__PURE__*/ jsx("div", { className: "cobalt-CalendarRangePicker__month__week", children: week.map((day)=>{ const isStartDay = null != startDate && isSameDay(day, startDate); const isEndDay = null != endDate && isSameDay(day, endDate); const disabled = isDisabled(day, firstAvailableDate, lastAvailableDate) || isDayDisabledFn?.(day); const hasNotification = !disabled && null != hasDayNotificationFn && hasDayNotificationFn(day); const isRange = 0 !== rangeInDays && (isStartDay || isEndDay) && (!rangeTooShort || !isEditingStartDate && !isEditingEndDate); const isDaySelected = isSelected({ day, startDate, endDate, isStartDay, isEndDay, isOutOfRangeStartDate, rangeTooShort, isEditingStartDate, isEditingEndDate }); const tooltip = buildTooltipMessage({ rangeInDays, isEditingStartDate: !!isEditingStartDate, isEditingEndDate: !!isEditingEndDate, isStartDay, isEndDay, rangeConstraints }); return /*#__PURE__*/ jsx(CalendarRangePickerDay, { date: day, onMouseEnter: onMouseEnter, onMouseLeave: onLeaveDate, onSelect: onSelectDateCallback, isToday: isSameDay(day, today), isActive: isEditingStartDate && isStartDay || isEditingEndDate && isEndDay, isStartDay: isStartDay, isEndDay: isEndDay, isRange: isRange, isEditingStartDate: isEditingStartDate, isEditingEndDate: isEditingEndDate, isInvalid: isDayInvalid({ day, isDayInvalidForSelectionFn, isDaySelected, startDate, rangeConstraints, rangeTooShort, rangeExceeded, isEditingStartDate, isEditingEndDate, isStartDay, isEndDay, endDate }), hasNotification: hasNotification, isDisabled: disabled, tooltipMessage: tooltip, hoverTooltipMessage: dayHoverTooltipFn ? dayHoverTooltipFn(day) : void 0, isSelected: isDaySelected }, day.getTime()); }) }, `week-${index}-${week.map((day)=>day.getTime()).join("-")}`)) ] }) ] }); } export { CalendarRangePickerMonth }; //# sourceMappingURL=CalendarRangePickerMonth.js.map