UNPKG

@talend/react-components

Version:
225 lines (222 loc) 7.34 kB
/* eslint-disable react/jsx-no-bind */ /* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react/no-find-dom-node */ import { useEffect, useRef, useState, createElement as _createElement } from 'react'; import ReactDOM from 'react-dom'; import classnames from 'classnames'; import PropTypes from 'prop-types'; import { Nav, NavItem, Tab } from '@talend/react-bootstrap'; import { ActionDropdown } from '../Actions'; import Icon from '../Icon'; import OverlayTrigger from '../OverlayTrigger'; import Tag from '../Tag'; import TooltipTrigger from '../TooltipTrigger'; import getTabBarBadgeLabel from '../utils/getTabBarBadgeLabel'; import theme from './TabBar.module.scss'; import { debounce, get } from "lodash"; import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime"; function TabBar(props) { const tabBarContainerRef = useRef(); const tabBarRef = useRef(); const needsRefocus = useRef(); const [showDropdown, setShowDropDown] = useState(false); const { responsive = true } = props; function tryShowDropdown() { const tabContainer = tabBarContainerRef.current; if (tabContainer) { // There is a TabBar, test if the right boundary point of this TabBar // is closer than the right boundary point of its last nav item. const lastChild = tabContainer.querySelector('li:last-child'); if (lastChild) { if (tabContainer.getBoundingClientRect().right < lastChild.getBoundingClientRect().right) { setShowDropDown(true); } } } else { // There is no TabBar, show it to test if dropdown is needed setShowDropDown(false); } } /** * Just show the tabBar and test if there is enough width. */ function showTabBarAndTest() { setShowDropDown(false); tryShowDropdown(); } useEffect(() => { if (responsive) { const resizeListener = window.addEventListener('resize', debounce(showTabBarAndTest, 200)); return () => window.removeEventListener('resize', resizeListener); } return undefined; }, []); useEffect(() => { if (!needsRefocus.current || !tabBarRef.current) { return; } const tabBarRefNode = ReactDOM.findDOMNode(tabBarRef.current); if (tabBarRefNode && typeof tabBarRefNode.querySelector === 'function') { const activeChild = tabBarRefNode.querySelector('[aria-selected=true]'); if (activeChild) { activeChild.focus({ preventScroll: true }); needsRefocus.current = false; } } }); useEffect(() => { if (responsive) { tryShowDropdown(); } }, []); const { onSelect } = props; // to avoid react/no-unused-prop-types function handleSelect(selectedKey, event) { if (selectedKey !== props.selectedKey) { if (event) { event.preventDefault(); } onSelect(event, props.items.find(({ key }) => selectedKey === key)); } } function handleKeyDown(event) { const { items } = props; switch (event.key) { case 'Home': needsRefocus.current = true; handleSelect(items[0].key, event); break; case 'End': needsRefocus.current = true; handleSelect(items[items.length - 1].key, event); break; default: break; } } const { className, id, items, selectedKey, children, generateChildId, tooltipPlacement, right } = props; const hasChildren = children || items.some(item => item.children); const tabContent = hasChildren && /*#__PURE__*/_jsx(Tab.Content, { children: items.map(item => /*#__PURE__*/_jsxs(Tab.Pane, { eventKey: item.key, children: [item.children, selectedKey === item.key ? children : null] }, item.key)) }); let tabMenu; if (responsive && showDropdown) { const selectedItem = items.find(item => item.key === selectedKey) || items[0]; const badgeLabel = get(selectedItem, 'badge.label', ''); tabMenu = /*#__PURE__*/_jsx(ActionDropdown, { id: id, className: classnames(theme['tc-tab-bar-dropdown'], 'tc-tab-bar-dropdown'), badge: selectedItem.badge, tooltipLabel: badgeLabel ? `${badgeLabel} ${selectedItem.label}` : selectedItem.label, label: selectedItem.label, icon: selectedItem.icon && selectedItem.icon.name, onSelect: (event, { key }) => handleSelect(key, event), items: items.map(item => ({ ...item, icon: item.icon && item.icon.name })), link: true }); } else { tabMenu = /*#__PURE__*/_jsx(Nav, { bsStyle: "tabs", className: classnames(theme['tc-tab-bar'], 'tc-tab-bar', responsive && theme['tc-tab-bar-responsive'], responsive && 'tc-tab-bar-responsive'), ref: tabBarRef, children: items.map(({ icon, badge, ...item }) => /*#__PURE__*/_createElement(NavItem, { className: classnames(theme['tc-tab-bar-item'], 'tc-tab-bar-item', item.className), ...item, key: item.key, eventKey: item.key, componentClass: "button" }, /*#__PURE__*/_jsx(TooltipTrigger, { label: badge && badge.label ? `${badge.label} ${item.label}` : item.label, tooltipPlacement: tooltipPlacement, children: /*#__PURE__*/_jsxs("span", { className: classnames(theme['tc-tab-bar-item-container'], 'tc-tab-bar-item-container'), children: [icon && /*#__PURE__*/_jsx(Icon, { className: classnames(theme['tc-tab-bar-item-icon'], 'tc-tab-bar-item-icon'), ...icon }), /*#__PURE__*/_jsx("span", { className: classnames(theme['tc-tab-bar-item-label']), children: item.label }), badge && /*#__PURE__*/_jsx(Tag, { className: classnames(theme['tc-tab-bar-item-badge'], 'tc-tab-bar-item-badge', badge.className), bsStyle: badge.bsStyle, children: getTabBarBadgeLabel(badge.label) })] }) }))) }); } return /*#__PURE__*/_jsx(Tab.Container, { id: id, activeKey: selectedKey, className: className, onSelect: handleSelect, onKeyDown: handleKeyDown, generateChildId: generateChildId, children: /*#__PURE__*/_jsxs("div", { ref: tabBarContainerRef, children: [/*#__PURE__*/_jsxs("div", { className: classnames(theme['tc-tab-bar-menu'], 'tc-tab-bar-menu'), children: [tabMenu, right] }), tabContent] }) }); } TabBar.displayName = 'TabBar'; TabBar.propTypes = { children: PropTypes.node, className: PropTypes.string, generateChildId: PropTypes.func, id: PropTypes.string.isRequired, items: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string, key: PropTypes.any.isRequired, label: PropTypes.string.isRequired, icon: PropTypes.object, badge: PropTypes.shape({ className: PropTypes.string, label: PropTypes.string, bsStyle: PropTypes.string }) }).isRequired).isRequired, onSelect: PropTypes.func.isRequired, responsive: PropTypes.bool, selectedKey: PropTypes.any, tooltipPlacement: OverlayTrigger.propTypes.placement, right: PropTypes.node }; TabBar.defaultProps = { tooltipPlacement: 'top' }; TabBar.Tab = Tab; export default TabBar; //# sourceMappingURL=TabBar.component.js.map