UNPKG

@yamada-ui/calendar

Version:

Yamada UI calendar component

315 lines (313 loc) • 10.2 kB
"use client" import { useCalendarPicker } from "./chunk-RUQS2HL6.mjs"; import { isAfterDate, isBeforeDate } from "./chunk-BPJGE3HG.mjs"; // src/use-range-date-picker.ts import { useControllableState } from "@yamada-ui/use-controllable-state"; import { getActiveElement, handlerAll, isActiveElement, isContains, isNumber, mergeRefs, useUpdateEffect } from "@yamada-ui/utils"; import dayjs from "dayjs"; import { useCallback, useRef, useState } from "react"; var useRangeDatePicker = ({ allowInputBeyond = false, closeOnSelect = true, defaultValue = [], endPlaceholder, maxSelectValues, placeholder, startPlaceholder, value: valueProp, onChange: onChangeProp, ...rest }) => { var _a, _b; const composition = useRef(false); const startInputRef = useRef(null); const endInputRef = useRef(null); const draftValue = useRef(void 0); const [value, setValue] = useControllableState({ defaultValue, value: valueProp, onChange: onChangeProp }); const [startValue, endValue] = value; const minDate = endValue && isNumber(maxSelectValues) ? dayjs(endValue).subtract(maxSelectValues - 1, "day").toDate() : void 0; const maxDate = startValue && isNumber(maxSelectValues) ? dayjs(startValue).add(maxSelectValues - 1, "day").toDate() : void 0; const { allowInput, containerRef, dateToString, inputFormat, locale, open, pattern, stringToDate, formControlProps, getCalendarProps, getContainerProps, getFieldProps, getIconProps, getPopoverProps, inputProps, onClose } = useCalendarPicker({ ...rest, allowInputBeyond, autoFocus: false, defaultValue, enableRange: true, maxSelectValues, value, onChange: ([startValue2, endValue2]) => { var _a2, _b2; setStartInputValue((_a2 = dateToString(startValue2)) != null ? _a2 : ""); setEndInputValue((_b2 = dateToString(endValue2)) != null ? _b2 : ""); draftValue.current = [startValue2, endValue2]; setValue([startValue2, endValue2]); if (closeOnSelect && startValue2 && endValue2) onClose(); }, onClear: () => { var _a2; setStartInputValue(""); setEndInputValue(""); setValue([]); draftValue.current = void 0; if (allowInput && open) (_a2 = startInputRef.current) == null ? void 0 : _a2.focus(); }, onClick: (ev) => { var _a2, _b2, _c; if (open) { if (!startValue) { (_a2 = startInputRef.current) == null ? void 0 : _a2.focus(); } else { (_b2 = endInputRef.current) == null ? void 0 : _b2.focus(); } } (_c = rest.onClick) == null ? void 0 : _c.call(rest, ev); }, onClose: () => { var _a2, _b2, _c, _d; const [startValue2, endValue2] = (_a2 = draftValue.current) != null ? _a2 : value; setStartInputValue((_b2 = dateToString(startValue2)) != null ? _b2 : ""); setEndInputValue((_c = dateToString(endValue2)) != null ? _c : ""); draftValue.current = void 0; (_d = rest.onClose) == null ? void 0 : _d.call(rest); }, onDelete: (ev) => { var _a2, _b2, _c, _d; if (!endInputRef.current || endInputRef.current.value.length > 1) return; if (!containerRef.current) return; const activeEl = getActiveElement(containerRef.current); if (!isContains(activeEl, endInputRef.current)) return; ev.preventDefault(); ev.stopPropagation(); setEndInputValue(""); setValue([startValue, void 0]); const startInputValue2 = (_b2 = (_a2 = startInputRef.current) == null ? void 0 : _a2.value) != null ? _b2 : ""; const index = startInputValue2.length; (_c = startInputRef.current) == null ? void 0 : _c.focus(); (_d = startInputRef.current) == null ? void 0 : _d.setSelectionRange(index, index); }, onEnter: () => { var _a2, _b2, _c, _d; if (composition.current) return; if (!containerRef.current) return; const activeEl = getActiveElement(containerRef.current); const start = isContains(activeEl, startInputRef.current); if (start) { const value2 = dateToString(startValue); if (value2) { setStartInputValue(value2); const endInputValue2 = (_b2 = (_a2 = endInputRef.current) == null ? void 0 : _a2.value) != null ? _b2 : ""; const index = endInputValue2.length; (_c = endInputRef.current) == null ? void 0 : _c.focus(); (_d = endInputRef.current) == null ? void 0 : _d.setSelectionRange(index, index); } } else { const value2 = dateToString(endValue); if (value2) setEndInputValue(value2); } } }); const [startInputValue, setStartInputValue] = useState( (_a = dateToString(startValue)) != null ? _a : "" ); const [endInputValue, setEndInputValue] = useState( (_b = dateToString(endValue)) != null ? _b : "" ); const onStartChange = useCallback( (ev) => { let inputValue = ev.target.value; if (!composition.current) inputValue = inputValue.replace(pattern, ""); let startValue2 = stringToDate(inputValue); if (!!startValue2 && dayjs(startValue2).isValid()) { if (!allowInputBeyond) { if (minDate && isBeforeDate(startValue2, minDate)) startValue2 = minDate; } if (endValue && isAfterDate(startValue2, endValue)) startValue2 = endValue; } else { startValue2 = void 0; } draftValue.current = [startValue2, endValue]; setValue([startValue2, endValue]); setStartInputValue(inputValue); }, [pattern, stringToDate, allowInputBeyond, minDate, setValue, endValue] ); const onEndChange = useCallback( (ev) => { let inputValue = ev.target.value; if (!composition.current) inputValue = inputValue.replace(pattern, ""); let endValue2 = stringToDate(inputValue); if (!!endValue2 && dayjs(endValue2).isValid()) { if (!allowInputBeyond) { if (maxDate && isAfterDate(endValue2, maxDate)) endValue2 = maxDate; } if (startValue && isBeforeDate(endValue2, startValue)) endValue2 = startValue; } else { endValue2 = void 0; } draftValue.current = [startValue, endValue2]; setValue([startValue, endValue2]); setEndInputValue(inputValue); }, [startValue, allowInputBeyond, maxDate, pattern, stringToDate, setValue] ); useUpdateEffect(() => { setValue(valueProp != null ? valueProp : []); }, [valueProp]); useUpdateEffect(() => { var _a2; if (startInputRef.current && isActiveElement(startInputRef.current)) return; setStartInputValue((_a2 = dateToString(startValue)) != null ? _a2 : ""); }, [value]); useUpdateEffect(() => { var _a2; if (endInputRef.current && isActiveElement(endInputRef.current)) return; setEndInputValue((_a2 = dateToString(endValue)) != null ? _a2 : ""); }, [value]); useUpdateEffect(() => { var _a2, _b2; setStartInputValue((_a2 = dateToString(startValue)) != null ? _a2 : ""); setEndInputValue((_b2 = dateToString(endValue)) != null ? _b2 : ""); }, [locale, inputFormat]); const getStartInputProps = useCallback( (props = {}, ref) => { const style = { ...props.style, ...inputProps.style, ...formControlProps.disabled || !allowInput ? { pointerEvents: "none" } : {} }; return { "aria-label": "Start Date", placeholder: startPlaceholder != null ? startPlaceholder : placeholder, tabIndex: !allowInput ? -1 : 0, zIndex: !startInputValue ? 1 : void 0, ...formControlProps, ...inputProps, ...props, ref: mergeRefs(ref, startInputRef), style, value: startInputValue, onChange: handlerAll(props.onChange, onStartChange), onClick: handlerAll(props.onClick, (ev) => { ev.preventDefault(); ev.stopPropagation(); }), onCompositionEnd: handlerAll(props.onCompositionEnd, () => { composition.current = false; setStartInputValue((prev) => prev.replace(pattern, "")); }), onCompositionStart: handlerAll( props.onCompositionStart, () => composition.current = true ) }; }, [ inputProps, allowInput, startPlaceholder, placeholder, formControlProps, startInputValue, onStartChange, pattern ] ); const getEndInputProps = useCallback( (props = {}, ref) => { const style = { ...props.style, ...inputProps.style, ...!allowInput ? { pointerEvents: "none" } : {} }; return { "aria-label": "End Date", placeholder: endPlaceholder != null ? endPlaceholder : placeholder, ...formControlProps, ...inputProps, ...props, ref: mergeRefs(ref, endInputRef), style, cursor: formControlProps.readOnly ? "default" : "text", pointerEvents: formControlProps.disabled ? "none" : "auto", tabIndex: !allowInput || !startInputValue ? -1 : 0, value: endInputValue, onChange: handlerAll(props.onChange, onEndChange), onClick: handlerAll(props.onClick, (ev) => { ev.preventDefault(); ev.stopPropagation(); }), onCompositionEnd: handlerAll(props.onCompositionEnd, () => { composition.current = false; setEndInputValue((prev) => prev.replace(pattern, "")); }), onCompositionStart: handlerAll( props.onCompositionStart, () => composition.current = true ) }; }, [ startInputValue, inputProps, allowInput, endPlaceholder, placeholder, formControlProps, endInputValue, onEndChange, pattern ] ); return { dateToString, inputValue: [startInputValue, endInputValue], value, getCalendarProps, getContainerProps, getEndInputProps, getFieldProps, getIconProps, getPopoverProps, getStartInputProps, onClose }; }; export { useRangeDatePicker }; //# sourceMappingURL=chunk-OAW6VVLJ.mjs.map