UNPKG

@uiw/react-tabs

Version:
172 lines 5.66 kB
import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose"; var _excluded = ["prefixCls", "className", "children", "type", "activeKey", "onTabClick"]; import React, { useEffect, useState, useRef, useCallback } from 'react'; import Pane from './Pane'; import "./style/index.css"; import Popover from '@uiw/react-popover'; import { jsx as _jsx } from "react/jsx-runtime"; import { jsxs as _jsxs } from "react/jsx-runtime"; export * from './Pane'; Tabs.Pane = Pane; export default function Tabs(props) { var _flowNav$nav; var { prefixCls = 'w-tabs', className, children, type = 'default', onTabClick } = props, elementProps = _objectWithoutPropertiesLoose(props, _excluded); var [activeKey, setActiveKey] = useState(props.activeKey); var [slideStyle, setSlideStyle] = useState({ width: 0, left: 0 }); var activeItem = useRef(); var cls = [prefixCls, className, type ? prefixCls + "-" + type : null].filter(Boolean).join(' ').trim(); var [flowNav, flowNavSet] = useState({ content: 0, nav: [], flowLeft: -1, displayStart: 0, displayEnd: 0 }); var [hiddenNav, hiddenNavSet] = useState([]); var deviation = 15; var [nodes, nodesSet] = useState(); var divContentRef = useCallback(node => { if (node !== null) { nodesSet(nodes); node.addEventListener('scroll', e => { var { clientWidth, scrollLeft } = e.target; flowNav.displayStart = scrollLeft; flowNav.displayEnd = clientWidth + scrollLeft; flowNavSet(_extends({}, flowNav)); }); flowNav.displayEnd = node.getBoundingClientRect().width; flowNavSet(_extends({}, flowNav)); } }, []); var divNavRef = useCallback((node, key, itemKey, activeKey) => { if (node !== null) { // node.addEventListener('click', (e: any) => { // activeItem.current = node; // }); divNavWidthChange(node.getBoundingClientRect().width, key); if (itemKey === activeKey) { activeItem.current = node; } } }, []); var divNavWidthChange = (width, index) => { var curWidth = 0; flowNav.nav.slice(0, index + 1).forEach(nav => curWidth += nav.width); flowNav.nav[index] = { width, curWidth: Math.floor(curWidth), index }; flowNavSet(flowNav); }; useEffect(() => { showHideenNav(); }, [flowNav.displayEnd > ((_flowNav$nav = flowNav.nav[flowNav.nav.length - 1]) == null ? void 0 : _flowNav$nav.curWidth)]); var showHideenNav = () => { var hiddenNav = []; if (flowNav.nav.length > 0) { flowNav.nav.forEach(item => { var curWidth = item.curWidth - deviation; if (flowNav.displayStart > 0 || flowNav.displayEnd > 0) { if (curWidth < flowNav.displayStart || curWidth > flowNav.displayEnd) { hiddenNav.push(item.index); } } }); hiddenNavSet(hiddenNav); } }; useEffect(() => setActiveKey((props == null ? void 0 : props.activeKey) || ''), [props.activeKey]); useEffect(() => calcSlideStyle(), [activeKey]); function calcSlideStyle() { if (activeItem.current && type === 'line') { setSlideStyle({ width: activeItem.current.clientWidth, left: activeItem.current.offsetLeft }); } } return /*#__PURE__*/_jsxs("div", _extends({ className: cls }, elementProps, { children: [/*#__PURE__*/_jsxs("div", { style: { display: 'flex' }, children: [/*#__PURE__*/_jsx("div", { style: { overflow: 'hidden' }, children: /*#__PURE__*/_jsx("div", { className: prefixCls + "-bar", ref: divContentRef, children: /*#__PURE__*/_jsxs("div", { className: prefixCls + "-nav", style: { width: 'max-content' }, children: [renderNav(children), /*#__PURE__*/_jsx("div", { style: slideStyle, className: prefixCls + "-slide" })] }) }) }), hiddenNav.length > 0 && /*#__PURE__*/_jsx(Popover, { trigger: "click", placement: "bottomRight", visibleArrow: false, content: /*#__PURE__*/_jsx("div", { className: prefixCls + "-nav-hidden", children: renderNav(hiddenNav.map(idx => children[idx])) }), children: /*#__PURE__*/_jsx("div", { onClick: showHideenNav, className: prefixCls + "-flow-content", children: /*#__PURE__*/_jsx("span", { children: "\u2026" }) }) })] }), React.Children.map(children, item => { if (!item || activeKey !== item.key) { return null; } return /*#__PURE__*/React.cloneElement(item, Object.assign({}, item.props, {})); })] })); function renderNav(children) { return React.Children.map(children, (item, key) => { if (!item) { return null; } var divProps = { className: [prefixCls + "-item", item.key === activeKey ? 'active' : null, item.props.disabled ? 'disabled' : null].filter(Boolean).join(' ').trim(), children: item.props.label }; if (!item.props.disabled) { divProps.onClick = e => { setActiveKey(item.key); onTabClick && onTabClick(item.key, item, e); calcSlideStyle(); }; } return /*#__PURE__*/_jsx("div", _extends({ ref: _ref => divNavRef(_ref, key, item.key, activeKey) }, divProps), key); }); } }