UNPKG

@ozen-ui/kit

Version:

React component library

76 lines (75 loc) 4.44 kB
"use strict"; 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 }); }