@yamada-ui/calendar
Version:
Yamada UI calendar component
190 lines (188 loc) • 5.61 kB
JavaScript
"use client"
import {
useCalendarContext
} from "./chunk-UMK6LUR5.mjs";
import {
disableAllTabIndex,
getFocused,
getFormattedLabel,
onShouldFocus
} from "./chunk-BPJGE3HG.mjs";
// src/use-year-list.tsx
import {
ariaAttr,
dataAttr,
handlerAll,
isArray,
isDisabled,
isNumber,
mergeRefs,
useUnmountEffect,
useUpdateEffect
} from "@yamada-ui/utils";
import { createRef, useCallback, useRef } from "react";
var useYearList = () => {
var _a, _b;
const {
internalYear,
locale,
maxYear,
minYear,
month,
rangeYears,
setInternalYear,
setMonth,
setType,
setYear,
value: selectedValue,
year,
yearFormat,
yearRefs,
__selectType
} = useCalendarContext();
const multi = isArray(selectedValue);
const containerRef = useRef(null);
const beforeInternalYear = useRef(null);
const minRangeYear = (_a = rangeYears[0]) != null ? _a : minYear;
const maxRangeYear = (_b = rangeYears[rangeYears.length - 1]) != null ? _b : maxYear;
const minYearLabel = getFormattedLabel(minRangeYear, locale, yearFormat);
const maxYearLabel = getFormattedLabel(maxRangeYear, locale, yearFormat);
const label = `${minYearLabel} - ${maxYearLabel}`;
const ariaLabel = `From ${minYearLabel} to ${maxYearLabel}`;
const onFocusPrev = useCallback(
(targetIndex) => {
if (targetIndex < 0) {
if (minRangeYear <= minYear) return;
setInternalYear((prev) => {
beforeInternalYear.current = prev;
return prev - 12;
});
} else {
const ref = yearRefs.current.get(targetIndex);
if (ref == null ? void 0 : ref.current) {
ref.current.focus();
ref.current.tabIndex = 0;
}
}
},
[minYear, minRangeYear, setInternalYear, yearRefs]
);
const onFocusNext = useCallback(
(targetIndex) => {
if (11 < targetIndex) {
if (maxYear <= maxRangeYear) return;
setInternalYear((prev) => {
beforeInternalYear.current = prev;
return prev + 12;
});
} else {
const ref = yearRefs.current.get(targetIndex);
if (ref == null ? void 0 : ref.current) {
ref.current.focus();
ref.current.tabIndex = 0;
}
}
},
[maxYear, maxRangeYear, setInternalYear, yearRefs]
);
const onKeyDown = useCallback(
(ev) => {
var _a2;
const focusedIndex = (_a2 = getFocused(yearRefs)) != null ? _a2 : 0;
const actions = {
ArrowDown: () => focusedIndex + 4 <= 11 ? onFocusNext(focusedIndex + 4) : {},
ArrowLeft: () => onFocusPrev(focusedIndex - 1),
ArrowRight: () => onFocusNext(focusedIndex + 1),
ArrowUp: () => focusedIndex - 4 >= 0 ? onFocusPrev(focusedIndex - 4) : {},
End: () => onFocusNext(11),
Home: () => onFocusPrev(0)
};
const action = actions[ev.key];
if (!action) return;
ev.preventDefault();
ev.stopPropagation();
disableAllTabIndex(yearRefs);
action(ev);
},
[onFocusNext, onFocusPrev, yearRefs]
);
const onClick = useCallback(
(ev, year2) => {
ev.preventDefault();
ev.stopPropagation();
if (isDisabled(ev.target)) return;
setYear(year2);
setMonth((prev) => new Date(prev.setFullYear(year2)));
setType("month", year2, month.getMonth());
},
[month, setMonth, setType, setYear]
);
const getIsSelected = useCallback(
(value) => {
var _a2;
if (__selectType === "date" || __selectType === "month") {
return year === value;
} else {
const year2 = !multi ? selectedValue == null ? void 0 : selectedValue.getFullYear() : (_a2 = selectedValue[0]) == null ? void 0 : _a2.getFullYear();
return year2 === value;
}
},
[__selectType, multi, selectedValue, year]
);
useUpdateEffect(() => {
if (!isNumber(beforeInternalYear.current)) return;
onShouldFocus(
yearRefs,
() => false,
beforeInternalYear.current < internalYear
);
beforeInternalYear.current = null;
}, [internalYear]);
useUnmountEffect(() => {
yearRefs.current.clear();
});
const getGridProps = useCallback(
(props = {}, ref = null) => ({
ref: mergeRefs(ref, containerRef),
"aria-label": ariaLabel,
role: "grid",
...props,
onKeyDown: handlerAll(onKeyDown, props.onKeyDown)
}),
[ariaLabel, onKeyDown]
);
const getButtonProps = useCallback(
({ index, value, ...props }, ref = null) => {
const controlled = isNumber(beforeInternalYear.current);
const selected = getIsSelected(value);
const disabled = value < minYear || value > maxYear;
yearRefs.current.set(index, createRef());
let tabIndex = -1;
if (controlled) {
tabIndex = -1;
} else if (!rangeYears.includes(year) && rangeYears[0] === value) {
tabIndex = 0;
} else if (selected) {
tabIndex = 0;
}
return {
ref: mergeRefs(ref, yearRefs.current.get(index)),
disabled,
...props,
"aria-disabled": ariaAttr(disabled),
"aria-selected": ariaAttr(selected),
"data-disabled": dataAttr(disabled),
"data-selected": dataAttr(selected),
"data-value": value,
tabIndex,
onClick: handlerAll(props.onClick, (ev) => onClick(ev, value))
};
},
[getIsSelected, minYear, maxYear, yearRefs, rangeYears, year, onClick]
);
return { label, rangeYears, getButtonProps, getGridProps };
};
export {
useYearList
};
//# sourceMappingURL=chunk-4JE7HHCS.mjs.map