@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
135 lines (134 loc) • 5.05 kB
JavaScript
"use client";
const require_get_cascader_columns = require("./get-cascader-columns.cjs");
const require_get_cascader_path_options = require("./get-cascader-path-options.cjs");
let react = require("react");
let _mantine_hooks = require("@mantine/hooks");
//#region packages/@mantine/core/src/components/Cascader/use-cascader.ts
function pathsEqual(a, b) {
return !!a && a.length === b.length && a.every((item, index) => item === b[index]);
}
function findEnabledIndex(options, from, direction) {
let index = from + direction;
while (index >= 0 && index < options.length) {
if (!options[index].disabled) return index;
index += direction;
}
return -1;
}
function useCascader({ data, value, defaultValue, onChange, changeOnSelect, allowDeselect, expandTrigger, onLeafSelect }) {
const [keyboardNav, setKeyboardNav] = (0, react.useState)(false);
const [_value, setValue] = (0, _mantine_hooks.useUncontrolled)({
value,
defaultValue,
finalValue: null,
onChange: (val) => onChange?.(val, require_get_cascader_path_options.getCascaderPathOptions(data, val))
});
const [activePath, setActivePath] = (0, react.useState)(() => _value ?? []);
const activePathRef = (0, react.useRef)(activePath);
activePathRef.current = activePath;
const resetActivePath = (0, react.useCallback)(() => {
setActivePath(_value ?? []);
}, [_value]);
const selectPath = (0, react.useCallback)((path) => {
setValue(allowDeselect && pathsEqual(_value, path) ? null : path);
}, [
allowDeselect,
_value,
setValue
]);
const expandOption = (0, react.useCallback)((level, option) => {
const optionPath = [...activePathRef.current.slice(0, level), option.value];
const children = option.children;
if (Array.isArray(children) && children.length > 0) {
const first = findEnabledIndex(children, -1, 1);
setActivePath(first >= 0 ? [...optionPath, children[first].value] : optionPath);
} else setActivePath(optionPath);
}, []);
return {
value: _value,
setValue,
selectPath,
activePath,
setActivePath,
resetActivePath,
keyboardNav,
setKeyboardNav,
handleOptionClick: (0, react.useCallback)((level, option) => {
setKeyboardNav(false);
const path = [...activePath.slice(0, level), option.value];
if (require_get_cascader_columns.cascaderOptionHasChildren(option)) {
if (changeOnSelect) selectPath(path);
expandOption(level, option);
if (changeOnSelect) onLeafSelect?.();
} else {
selectPath(path);
onLeafSelect?.();
}
}, [
activePath,
changeOnSelect,
selectPath,
expandOption,
onLeafSelect
]),
handleOptionMouseEnter: (0, react.useCallback)((level, option) => {
setKeyboardNav(false);
if (expandTrigger !== "hover") return;
if (require_get_cascader_columns.cascaderOptionHasChildren(option)) expandOption(level, option);
else setActivePath([...activePath.slice(0, level), option.value]);
}, [
expandTrigger,
activePath,
expandOption
]),
handleColumnsKeyDown: (0, react.useCallback)((event) => {
setKeyboardNav(true);
const columns = require_get_cascader_columns.getCascaderColumns(data, activePath);
const focusedLevel = Math.max(0, activePath.length - 1);
const currentColumn = columns[focusedLevel] ?? columns[0] ?? [];
const focusedIndex = currentColumn.findIndex((item) => item.value === activePath[focusedLevel]);
const focusedOption = focusedIndex >= 0 ? currentColumn[focusedIndex] : void 0;
switch (event.key) {
case "ArrowDown": {
const next = findEnabledIndex(currentColumn, focusedIndex, 1);
if (next >= 0) setActivePath([...activePath.slice(0, focusedLevel), currentColumn[next].value]);
return true;
}
case "ArrowUp": {
const prev = findEnabledIndex(currentColumn, focusedIndex < 0 ? currentColumn.length : focusedIndex, -1);
if (prev >= 0) setActivePath([...activePath.slice(0, focusedLevel), currentColumn[prev].value]);
return true;
}
case "ArrowRight":
if (focusedOption && require_get_cascader_columns.cascaderOptionHasChildren(focusedOption)) expandOption(focusedLevel, focusedOption);
return true;
case "ArrowLeft":
if (activePath.length > 1) setActivePath(activePath.slice(0, -1));
return true;
case "Enter":
if (!focusedOption) return false;
if (require_get_cascader_columns.cascaderOptionHasChildren(focusedOption)) {
if (changeOnSelect) selectPath([...activePath.slice(0, focusedLevel), focusedOption.value]);
expandOption(focusedLevel, focusedOption);
if (changeOnSelect) onLeafSelect?.();
} else {
selectPath([...activePath.slice(0, focusedLevel), focusedOption.value]);
onLeafSelect?.();
}
return true;
default: return false;
}
}, [
data,
activePath,
changeOnSelect,
selectPath,
expandOption,
onLeafSelect
]),
pathOptions: (0, react.useMemo)(() => require_get_cascader_path_options.getCascaderPathOptions(data, _value), [data, _value])
};
}
//#endregion
exports.useCascader = useCascader;
//# sourceMappingURL=use-cascader.cjs.map