UNPKG

@yandex/ui

Version:

Yandex UI components

75 lines (74 loc) 4.29 kB
import { __assign, __rest } from "tslib"; import React, { useCallback, createRef, useMemo } from 'react'; import { cn } from '@bem-react/classname'; import { isKeyCode, Keys } from '../lib/keyboard'; import { TabsMenuTab } from './Tab/TabsMenu-Tab'; import './TabsMenu.css'; export var cnTabsMenu = cn('TabsMenu'); /** * Компонент для создания горизонтального меню. * @param {ITabsMenuProps} props */ export var TabsMenu = function (_a) { var activeTab = _a.activeTab, onChange = _a.onChange, className = _a.className, innerRef = _a.innerRef, tabs = _a.tabs, addonAfter = _a.addonAfter, _b = _a.orientation, orientation = _b === void 0 ? 'vertical' : _b, externalTabsRefs = _a.tabsRefs, // @ts-ignore _theme = _a.theme, // @ts-ignore _layout = _a.layout, props = __rest(_a, ["activeTab", "onChange", "className", "innerRef", "tabs", "addonAfter", "orientation", "tabsRefs", "theme", "layout"]); // eslint-disable-next-line react-hooks/rules-of-hooks var tabsRefs = externalTabsRefs || useMemo(function () { return tabs.map(function () { return createRef(); }); }, [tabs]); var onKeyDown = useCallback(function (event) { if (isKeyCode(event.keyCode, [Keys.LEFT, Keys.DOWN, Keys.RIGHT, Keys.UP])) { event.preventDefault(); var nextTabMenuIndex = 0; var direction = isKeyCode(event.keyCode, [Keys.LEFT, Keys.UP]) ? -1 : 1; for (var i = 0; i < tabs.length; i++) { if (tabs[i].id === activeTab) { nextTabMenuIndex = i; break; } } for (var i = nextTabMenuIndex; i < tabs.length; i += direction) { nextTabMenuIndex += direction; // При необходимости тут можно реализовать цикличный выбор табов, // при попадании индекса за границу списка, // выставлять nextTabMenuIndex в противоположное значение. var isEdge = nextTabMenuIndex >= tabs.length || nextTabMenuIndex < 0; var isTabNonDisabled = tabs[nextTabMenuIndex] && !tabs[nextTabMenuIndex].disabled; if (isEdge || isTabNonDisabled) { break; } } var nextTabMenu = tabs[nextTabMenuIndex]; var nextTabMenuRef = tabsRefs[nextTabMenuIndex]; if (nextTabMenu !== undefined && nextTabMenuRef !== undefined && nextTabMenuRef.current !== null && (nextTabMenu.onClick !== undefined || onChange !== undefined)) { nextTabMenuRef.current.focus(); // Не совем удачное решение, переключать табики через onClick, // тут могут возникнуть проблемы с event, т.к. в этом кейсе это KeyboardEvent. if (nextTabMenu.onClick !== undefined) { nextTabMenu.onClick(event); } if (onChange !== undefined) { onChange(nextTabMenuIndex.toString()); } } } }, [activeTab, tabsRefs, tabs, onChange]); return (React.createElement("ul", __assign({}, props, { "aria-orientation": orientation, className: cnTabsMenu(null, [className]), ref: innerRef, role: "tablist" }), tabs.map(function (_a, index) { var id = _a.id, disabled = _a.disabled, tabProps = __rest(_a, ["id", "disabled"]); return (React.createElement(TabsMenuTab, __assign({}, tabProps, { innerRef: tabsRefs[index], first: index === 0, disabled: disabled, onClick: disabled || (!onChange && !tabProps.onClick) ? undefined : function (event) { if (tabProps.onClick !== undefined) { tabProps.onClick(event); } if (onChange !== undefined) { onChange(id); } }, active: id === activeTab, key: id, onKeyDown: onKeyDown }))); }), addonAfter)); }; TabsMenu.displayName = cnTabsMenu();