@yamada-ui/calendar
Version:
Yamada UI calendar component
178 lines (176 loc) • 4.7 kB
JavaScript
"use client"
import {
useCalendarPicker
} from "./chunk-RUQS2HL6.mjs";
import {
isSameDate
} from "./chunk-BPJGE3HG.mjs";
// src/use-multi-date-picker.ts
import { useControllableState } from "@yamada-ui/use-controllable-state";
import { handlerAll, isNumber, useUpdateEffect } from "@yamada-ui/utils";
import dayjs from "dayjs";
import { useCallback, useRef, useState } from "react";
var getResolvedValue = (value) => {
const timestamps = new Set(
value.map((date) => date == null ? void 0 : date.getTime()).filter(Boolean)
);
return Array.from(timestamps).map(
(timestamp) => new Date(timestamp)
);
};
var useMultiDatePicker = ({
closeOnMaxSelect = true,
closeOnSelect = false,
defaultValue = [],
excludeDate,
maxSelectValues,
placeholder,
value: valueProp,
onChange: onChangeProp,
...rest
}) => {
const composition = useRef(false);
const draftValue = useRef(void 0);
const [value, setValue] = useControllableState({
defaultValue,
value: valueProp,
onChange: onChangeProp
});
const [inputValue, setInputValue] = useState("");
const resolvedValue = getResolvedValue([...value, draftValue.current]);
const {
allowInput,
dateToString,
open,
pattern,
stringToDate,
formControlProps,
getCalendarProps,
getContainerProps,
getFieldProps,
getIconProps,
getPopoverProps,
inputProps,
onClose
} = useCalendarPicker({
excludeDate,
...rest,
defaultValue,
enableMultiple: true,
maxSelectValues,
value: resolvedValue,
onChange: (value2) => {
value2 = value2.filter((value3) => !isSameDate(value3, draftValue.current));
setValue(value2);
setInputValue("");
draftValue.current = void 0;
if (closeOnSelect && !!value2.length) onClose();
},
onClear: () => {
setValue([]);
setInputValue("");
},
onClose: () => {
var _a;
setInputValue("");
(_a = rest.onClose) == null ? void 0 : _a.call(rest);
},
onDelete: (ev) => {
if (inputValue.length) return;
ev.preventDefault();
ev.stopPropagation();
setValue((prev) => prev.slice(0, -1));
},
onEnter: () => {
if (composition.current) return;
const value2 = stringToDate(inputValue);
if (!!value2 && dayjs(value2).isValid()) {
setValue((prev) => {
if (prev.length === maxSelectValues) return prev;
const isSelected = prev.some(
(prevValue) => isSameDate(prevValue, value2)
);
return !isSelected ? [...prev, value2] : prev;
});
}
setInputValue("");
draftValue.current = void 0;
}
});
useUpdateEffect(() => {
setValue(valueProp != null ? valueProp : []);
}, [valueProp]);
useUpdateEffect(() => {
if (!closeOnMaxSelect || !isNumber(maxSelectValues)) return;
if (maxSelectValues <= value.length) onClose();
}, [value]);
const onChange = useCallback(
(ev) => {
let inputValue2 = ev.target.value;
if (!composition.current) inputValue2 = inputValue2.replace(pattern, "");
setInputValue(inputValue2);
const value2 = stringToDate(inputValue2);
draftValue.current = dayjs(value2).isValid() ? value2 : void 0;
},
[pattern, stringToDate]
);
const onCompositionStart = useCallback(() => {
composition.current = true;
}, []);
const onCompositionEnd = useCallback(() => {
composition.current = false;
setInputValue((prev) => prev.replace(pattern, ""));
}, [pattern]);
const getInputProps = useCallback(
(props = {}, ref = null) => {
const style = {
...props.style,
...inputProps.style,
...formControlProps.disabled || !allowInput ? { pointerEvents: "none" } : {}
};
return {
placeholder,
tabIndex: !allowInput ? -1 : 0,
...formControlProps,
...inputProps,
...props,
ref,
style,
value: inputValue,
onChange: handlerAll(props.onChange, onChange),
onCompositionEnd: handlerAll(props.onCompositionEnd, onCompositionEnd),
onCompositionStart: handlerAll(
props.onCompositionStart,
onCompositionStart
)
};
},
[
inputProps,
allowInput,
placeholder,
formControlProps,
inputValue,
onChange,
onCompositionStart,
onCompositionEnd
]
);
return {
dateToString,
open,
setValue,
value,
getCalendarProps,
getContainerProps,
getFieldProps,
getIconProps,
getInputProps,
getPopoverProps,
onClose
};
};
export {
useMultiDatePicker
};
//# sourceMappingURL=chunk-MSRNKBM7.mjs.map