@ozen-ui/kit
Version:
React component library
73 lines (72 loc) • 4.04 kB
JavaScript
import { __assign, __read } from "tslib";
import { useEffect, useState, useCallback } from 'react';
import { useMutableRef } from '../../../hooks/useMutableRef';
import { getNextIndex } from '../../../utils/getNextIndex';
import { getPrevIndex } from '../../../utils/getPrevIndex';
import { isKey } from '../../../utils/isKey';
import { isKeys } from '../../../utils/isKeys';
/** Навигация по элементам списка без перехвата фокуса с элемента контроля */
export function useDataListNavigation(_a) {
var selected = _a.selected, onSelect = _a.onSelect, _b = _a.active, active = _b === void 0 ? false : _b, itemsProps = _a.items;
var savedItems = useMutableRef(itemsProps);
var savedSelected = useMutableRef(selected);
var savedOnSelect = useMutableRef(onSelect);
var _c = __read(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; }); };
useEffect(function () {
if (!active) {
return;
}
setState(function (prevState) {
var _a, _b, _c;
return (__assign(__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]);
// Сброс
useEffect(function () {
if (!active) {
return undefined;
}
return function () {
setState({});
};
}, [active]);
var onClick = useCallback(function (event, item) {
var _a;
if (!active) {
return;
}
var focused = item === state.focused ? item : null;
setState(__assign(__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 = useCallback(function (event) {
var _a, _b, _c, _d, _e, _f, _g;
if (!active || !isKeys(event, ['Enter', 'ArrowUp', 'ArrowDown'])) {
return;
}
var current = (_a = state.focused) !== null && _a !== void 0 ? _a : state.current;
if (isKey(event, 'Enter')) {
// Не обрабатываем ввод в пустом списке
if (!((_b = savedItems.current) === null || _b === void 0 ? void 0 : _b.length)) {
return;
}
event.preventDefault();
setState(__assign(__assign({}, state), { current: current, focused: current }));
(_c = savedOnSelect.current) === null || _c === void 0 ? void 0 : _c.call(savedOnSelect, event, current);
}
if (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 = isKey(event, 'ArrowUp');
var newIndex = isArrowUp
? getPrevIndex(currentIndex !== null && currentIndex !== void 0 ? currentIndex : 0, ((_e = savedItems.current) === null || _e === void 0 ? void 0 : _e.length) || 0)
: 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(__assign(__assign({}, state), { focused: newItem }));
}
}, [state.focused, state.current, active]);
return __assign(__assign({}, state), { onClick: onClick, onKeyDown: onKeyDown });
}