@ozen-ui/kit
Version:
React component library
76 lines (75 loc) • 4.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useDataListNavigation = useDataListNavigation;
var tslib_1 = require("tslib");
var react_1 = require("react");
var useMutableRef_1 = require("../../../hooks/useMutableRef");
var getNextIndex_1 = require("../../../utils/getNextIndex");
var getPrevIndex_1 = require("../../../utils/getPrevIndex");
var isKey_1 = require("../../../utils/isKey");
var isKeys_1 = require("../../../utils/isKeys");
/** Навигация по элементам списка без перехвата фокуса с элемента контроля */
function useDataListNavigation(_a) {
var selected = _a.selected, onSelect = _a.onSelect, _b = _a.active, active = _b === void 0 ? false : _b, itemsProps = _a.items;
var savedItems = (0, useMutableRef_1.useMutableRef)(itemsProps);
var savedSelected = (0, useMutableRef_1.useMutableRef)(selected);
var savedOnSelect = (0, useMutableRef_1.useMutableRef)(onSelect);
var _c = tslib_1.__read((0, react_1.useState)({}), 2), state = _c[0], setState = _c[1];
var findInItems = function (value) { var _a; return (_a = savedItems.current) === null || _a === void 0 ? void 0 : _a.find(function (item) { return item === value; }); };
(0, react_1.useEffect)(function () {
if (!active) {
return;
}
setState(function (prevState) {
var _a, _b, _c;
return (tslib_1.__assign(tslib_1.__assign({}, prevState), { focused: (_a = findInItems(prevState.focused)) !== null && _a !== void 0 ? _a : null, current: (_b = findInItems(savedSelected.current)) !== null && _b !== void 0 ? _b : (_c = savedItems.current) === null || _c === void 0 ? void 0 : _c[0] }));
});
}, [itemsProps, active]);
// Сброс
(0, react_1.useEffect)(function () {
if (!active) {
return undefined;
}
return function () {
setState({});
};
}, [active]);
var onClick = (0, react_1.useCallback)(function (event, item) {
var _a;
if (!active) {
return;
}
var focused = item === state.focused ? item : null;
setState(tslib_1.__assign(tslib_1.__assign({}, state), { focused: focused, current: item }));
(_a = savedOnSelect.current) === null || _a === void 0 ? void 0 : _a.call(savedOnSelect, event, item);
}, [state.focused, active]);
var onKeyDown = (0, react_1.useCallback)(function (event) {
var _a, _b, _c, _d, _e, _f, _g;
if (!active || !(0, isKeys_1.isKeys)(event, ['Enter', 'ArrowUp', 'ArrowDown'])) {
return;
}
var current = (_a = state.focused) !== null && _a !== void 0 ? _a : state.current;
if ((0, isKey_1.isKey)(event, 'Enter')) {
// Не обрабатываем ввод в пустом списке
if (!((_b = savedItems.current) === null || _b === void 0 ? void 0 : _b.length)) {
return;
}
event.preventDefault();
setState(tslib_1.__assign(tslib_1.__assign({}, state), { current: current, focused: current }));
(_c = savedOnSelect.current) === null || _c === void 0 ? void 0 : _c.call(savedOnSelect, event, current);
}
if ((0, isKeys_1.isKeys)(event, ['ArrowUp', 'ArrowDown'])) {
event.preventDefault();
var currentIndex = typeof current !== 'undefined'
? (_d = savedItems.current) === null || _d === void 0 ? void 0 : _d.indexOf(current)
: null;
var isArrowUp = (0, isKey_1.isKey)(event, 'ArrowUp');
var newIndex = isArrowUp
? (0, getPrevIndex_1.getPrevIndex)(currentIndex !== null && currentIndex !== void 0 ? currentIndex : 0, ((_e = savedItems.current) === null || _e === void 0 ? void 0 : _e.length) || 0)
: (0, getNextIndex_1.getNextIndex)(currentIndex !== null && currentIndex !== void 0 ? currentIndex : -1, ((_f = savedItems.current) === null || _f === void 0 ? void 0 : _f.length) || 0);
var newItem = (_g = savedItems.current) === null || _g === void 0 ? void 0 : _g[newIndex];
setState(tslib_1.__assign(tslib_1.__assign({}, state), { focused: newItem }));
}
}, [state.focused, state.current, active]);
return tslib_1.__assign(tslib_1.__assign({}, state), { onClick: onClick, onKeyDown: onKeyDown });
}