UNPKG

@ozen-ui/kit

Version:

React component library

73 lines (72 loc) 4.04 kB
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 }); }