@ant-design/x
Version:
Craft AI-driven interfaces effortlessly
103 lines (101 loc) • 3.02 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useActive;
var _rcUtil = require("rc-util");
var _react = _interopRequireDefault(require("react"));
/**
* Since Cascader not support ref active, we use `value` to mock the active item.
*/
function useActive(items, open, rtl, onSelect, onCancel) {
const [activePaths, setActivePaths] = _react.default.useState([]);
/** Get items by column index */
const getItems = (colIndex, paths = activePaths) => {
let currentItems = items;
for (let i = 0; i < colIndex - 1; i += 1) {
const activePath = paths[i];
const activeItem = currentItems.find(item => item.value === activePath);
if (!activeItem) {
break;
}
currentItems = activeItem.children || [];
}
return currentItems;
};
const getValues = paths => {
return paths.map((path, index) => {
const currentItems = getItems(index + 1, paths);
const currentItem = currentItems.find(item => item.value === path);
return currentItem?.value;
});
};
const offsetRow = offset => {
const currentColIndex = activePaths.length || 1;
const currentItems = getItems(currentColIndex);
const currentRowIndex = currentItems.findIndex(item => item.value === activePaths[currentColIndex - 1]);
const itemCount = currentItems.length;
const nextItem = currentItems[(currentRowIndex + offset + itemCount) % itemCount];
setActivePaths([...activePaths.slice(0, currentColIndex - 1), nextItem.value]);
};
const offsetPrev = () => {
if (activePaths.length > 1) {
setActivePaths(activePaths.slice(0, activePaths.length - 1));
}
};
const offsetNext = () => {
const nextItems = getItems(activePaths.length + 1);
if (nextItems.length) {
setActivePaths([...activePaths, nextItems[0].value]);
}
};
const onKeyDown = (0, _rcUtil.useEvent)(e => {
if (!open) {
return;
}
switch (e.key) {
case 'ArrowDown':
offsetRow(1);
e.preventDefault();
break;
case 'ArrowUp':
offsetRow(-1);
e.preventDefault();
break;
case 'ArrowRight':
if (rtl) {
offsetPrev();
} else {
offsetNext();
}
e.preventDefault();
break;
case 'ArrowLeft':
if (rtl) {
offsetNext();
} else {
offsetPrev();
}
e.preventDefault();
break;
case 'Enter':
// Submit if not have children
if (!getItems(activePaths.length + 1).length) {
onSelect(getValues(activePaths));
}
e.preventDefault();
break;
case 'Escape':
onCancel();
e.preventDefault();
break;
}
});
_react.default.useEffect(() => {
if (open) {
setActivePaths([items[0].value]);
}
}, [open]);
return [activePaths, onKeyDown];
}