@yamada-ui/calendar
Version:
Yamada UI calendar component
315 lines (313 loc) • 10.2 kB
JavaScript
"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