@uiw/react-tabs
Version:
Tabs component
172 lines • 5.66 kB
JavaScript
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);
});
}
}