UNPKG

tdesign-react

Version:
340 lines (335 loc) 14.5 kB
/** * tdesign v1.15.1 * (c) 2025 tdesign * @license MIT */ import { _ as _defineProperty } from '../_chunks/dep-cb0a3966.js'; import { _ as _slicedToArray } from '../_chunks/dep-48805ab8.js'; import React, { useRef, useCallback, useState, useEffect } from 'react'; import classNames from 'classnames'; import { AddIcon, ChevronLeftIcon, ChevronRightIcon } from 'tdesign-icons-react'; import { debounce, omit } from 'lodash-es'; import noop from '../_util/noop.js'; import { useTabClass } from './useTabClass.js'; import TabNavItem from './TabNavItem.js'; import TabBar from './TabBar.js'; import useGlobalIcon from '../hooks/useGlobalIcon.js'; import parseTNode from '../_util/parseTNode.js'; import '../_chunks/dep-eca3a3de.js'; import '../_chunks/dep-026a4c6b.js'; import '../hooks/useConfig.js'; import '../config-provider/ConfigContext.js'; import '../_chunks/dep-f97636ce.js'; import '../_chunks/dep-9dbbf468.js'; import 'dayjs'; import '../hooks/useRipple.js'; import '../_chunks/dep-c48e2ca1.js'; import '../hooks/useAnimation.js'; import '../_chunks/dep-3a09424a.js'; import '../hooks/useDomRefCallback.js'; import '../hooks/useMutationObserver.js'; import '../hooks/useLatest.js'; import '../hooks/useResizeObserver.js'; import '../hooks/useLayoutEffect.js'; import '../_chunks/dep-b908e1fe.js'; var getDomWidth = function getDomWidth(dom) { return (dom === null || dom === void 0 ? void 0 : dom.offsetWidth) || 0; }; var getDomOffsetLeft = function getDomOffsetLeft(dom) { return (dom === null || dom === void 0 ? void 0 : dom.offsetLeft) || 0; }; function calculateOffset(depElement, offset, scrollPosition) { var navsContainer = depElement.navsContainer, activeTab = depElement.activeTab, rightOperations = depElement.rightOperations, leftOperations = depElement.leftOperations; var tabWidth = getDomWidth(activeTab); var wrapWidth = getDomWidth(navsContainer); var tabOffset = getDomOffsetLeft(activeTab); var rightOperationsWidth = getDomWidth(rightOperations); var leftOperationsWidth = getDomWidth(leftOperations); if (scrollPosition === "auto") { if (tabOffset - leftOperationsWidth < offset) { return tabOffset - leftOperationsWidth; } if (tabOffset + tabWidth > offset + wrapWidth - rightOperationsWidth) { return tabOffset + tabWidth - wrapWidth + rightOperationsWidth; } } else if (scrollPosition === "start") { return tabOffset - leftOperationsWidth; } else if (scrollPosition === "center") { return tabOffset + (tabWidth - wrapWidth) / 2; } else if (scrollPosition === "end") { return tabOffset + tabWidth - wrapWidth + rightOperationsWidth; } return offset; } function calcPrevOrNextOffset(elements, offset, action) { var navsContainer = elements.navsContainer, activeTab = elements.activeTab; var navsContainerWidth = getDomWidth(navsContainer); var activeTabWidth = getDomWidth(activeTab); var diffWidth = Math.abs(navsContainerWidth - activeTabWidth); if (action === "next") { return offset + diffWidth; } return offset - diffWidth; } function calcMaxOffset(elements) { var navsWrap = elements.navsWrap, navsContainer = elements.navsContainer, rightOperations = elements.rightOperations, toRightBtn = elements.toRightBtn; var wrapWidth = getDomWidth(navsWrap); var containerWidth = getDomWidth(navsContainer); var rightOperationsWidth = getDomWidth(rightOperations); var toRightBtnWidth = getDomWidth(toRightBtn); return wrapWidth - containerWidth + rightOperationsWidth - toRightBtnWidth; } function calcValidOffset(offset, maxOffset) { return Math.max(0, Math.min(offset, maxOffset)); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var TabNav = function TabNav(props) { var _props$placement = props.placement, placement = _props$placement === void 0 ? "top" : _props$placement, _props$itemList = props.itemList, itemList = _props$itemList === void 0 ? [] : _props$itemList, theme = props.theme, addable = props.addable, onAdd = props.onAdd, _props$scrollPosition = props.scrollPosition, scrollPosition = _props$scrollPosition === void 0 ? "auto" : _props$scrollPosition, _props$size = props.size, size = _props$size === void 0 ? "medium" : _props$size, _props$disabled = props.disabled, disabled = _props$disabled === void 0 ? false : _props$disabled, _props$onRemove = props.onRemove, onRemove = _props$onRemove === void 0 ? noop : _props$onRemove, _props$onChange = props.onChange, onChange = _props$onChange === void 0 ? noop : _props$onChange, activeValue = props.activeValue, children = props.children, action = props.action, getDragProps = props.getDragProps; var _useGlobalIcon = useGlobalIcon({ AddIcon: AddIcon, ChevronLeftIcon: ChevronLeftIcon, ChevronRightIcon: ChevronRightIcon }), AddIcon$1 = _useGlobalIcon.AddIcon, ChevronLeftIcon$1 = _useGlobalIcon.ChevronLeftIcon, ChevronRightIcon$1 = _useGlobalIcon.ChevronRightIcon; var isCard = theme === "card"; var _useTabClass = useTabClass(), tdTabsClassGenerator = _useTabClass.tdTabsClassGenerator, tdClassGenerator = _useTabClass.tdClassGenerator, tdSizeClassGenerator = _useTabClass.tdSizeClassGenerator; var navsContainerRef = useRef(null); var navsWrapRef = useRef(null); var getIndex = useCallback(function (value) { var index = itemList.findIndex(function (item) { return item.value === value; }); return index > -1 ? index : -1; }, [itemList]); var activeIndex = getIndex(activeValue); var _useState = useState(false), _useState2 = _slicedToArray(_useState, 2), canToLeft = _useState2[0], setToLeftBtnVisible = _useState2[1]; var _useState3 = useState(false), _useState4 = _slicedToArray(_useState3, 2), canToRight = _useState4[0], setToRightBtnVisible = _useState4[1]; var scrollBarRef = useRef(null); var leftOperationsRef = useRef(null); var rightOperationsRef = useRef(null); var toLeftBtnRef = useRef(null); var toRightBtnRef = useRef(null); var _useState5 = useState(0), _useState6 = _slicedToArray(_useState5, 2), scrollLeft = _useState6[0], setScrollLeft = _useState6[1]; var _useState7 = useState(0), _useState8 = _slicedToArray(_useState7, 2), maxScrollLeft = _useState8[0], setMaxScrollLeft = _useState8[1]; var _useState9 = useState(null), _useState0 = _slicedToArray(_useState9, 2), activeTab = _useState0[0], setActiveTab = _useState0[1]; var setOffset = function setOffset(offset) { setScrollLeft(calcValidOffset(offset, maxScrollLeft)); }; var getMaxScrollLeft = useCallback(function () { if (["top", "bottom"].includes(placement.toLowerCase())) { var maxOffset = calcMaxOffset({ navsWrap: navsWrapRef.current, navsContainer: navsContainerRef.current, rightOperations: rightOperationsRef.current, toRightBtn: toRightBtnRef.current }); setMaxScrollLeft(maxOffset); } }, [placement]); var moveActiveTabIntoView = function moveActiveTabIntoView() { var offset = calculateOffset({ activeTab: activeTab, navsContainer: navsContainerRef.current, leftOperations: leftOperationsRef.current, rightOperations: rightOperationsRef.current }, scrollLeft, scrollPosition); setOffset(offset); }; useEffect(function () { var timeout = setTimeout(function () { moveActiveTabIntoView(); }, 100); return function () { return clearTimeout(timeout); }; }, [activeTab, maxScrollLeft, scrollPosition]); useEffect(function () { if (["top", "bottom"].includes(placement.toLowerCase())) { var canToLeft2 = scrollLeft > 1; var canToRight2 = scrollLeft < maxScrollLeft - 1; setToLeftBtnVisible(canToLeft2); setToRightBtnVisible(canToRight2); } }, [placement, scrollLeft, maxScrollLeft]); var handleScroll = function handleScroll(action2) { var offset = calcPrevOrNextOffset({ activeTab: activeTab, navsContainer: navsContainerRef.current }, scrollLeft, action2); setOffset(offset); }; useEffect(function () { var scrollBar = scrollBarRef.current; if (!scrollBar) return; var handleWheel = function handleWheel(e) { if (!canToLeft && !canToRight) return; e.preventDefault(); var deltaX = e.deltaX, deltaY = e.deltaY; if (Math.abs(deltaX) > Math.abs(deltaY)) { setOffset(scrollLeft + deltaX); } else { setOffset(scrollLeft + deltaY); } }; scrollBar.addEventListener("wheel", handleWheel, { passive: false }); return function () { scrollBar === null || scrollBar === void 0 || scrollBar.removeEventListener("wheel", handleWheel); }; }); useEffect(function () { var onResize = debounce(getMaxScrollLeft, 300); window.addEventListener("resize", onResize); return function () { window.removeEventListener("resize", onResize); onResize.cancel(); }; }); useEffect(function () { getMaxScrollLeft(); }, [itemList.length, children, getMaxScrollLeft]); var TabBarCom = isCard ? null : /* @__PURE__ */React.createElement(TabBar, { tabPosition: placement, activeId: activeIndex, containerRef: navsWrapRef, navsWrapRef: navsWrapRef }); var handleTabItemRemove = function handleTabItemRemove(removeItem) { var removeValue = removeItem.value, removeIndex = removeItem.index; if (removeValue === activeValue) { var _itemList; onChange(removeIndex === 0 ? (_itemList = itemList[removeIndex + 1]) === null || _itemList === void 0 ? void 0 : _itemList.value : itemList[removeIndex - 1].value); } onRemove(removeItem); }; var handleTabItemClick = function handleTabItemClick(clickItem) { var _clickItem$onClick; if (activeValue !== clickItem.value) { onChange(clickItem.value); } clickItem === null || clickItem === void 0 || (_clickItem$onClick = clickItem.onClick) === null || _clickItem$onClick === void 0 || _clickItem$onClick.call(clickItem, clickItem.value); }; var handleTabAdd = function handleTabAdd(e) { onAdd({ e: e }); }; return /* @__PURE__ */React.createElement("div", { ref: navsContainerRef, className: classNames(tdTabsClassGenerator("nav")), style: { minHeight: 48 } }, /* @__PURE__ */React.createElement("div", { ref: leftOperationsRef, className: classNames(tdTabsClassGenerator("operations"), tdTabsClassGenerator("operations--left")) }, canToLeft ? /* @__PURE__ */React.createElement("div", { onClick: function onClick() { handleScroll("prev"); }, className: classNames(tdTabsClassGenerator("btn"), tdTabsClassGenerator("btn--left"), tdSizeClassGenerator(size)), ref: toLeftBtnRef }, /* @__PURE__ */React.createElement(ChevronLeftIcon$1, null)) : null), /* @__PURE__ */React.createElement("div", { ref: rightOperationsRef, className: classNames(tdTabsClassGenerator("operations"), tdTabsClassGenerator("operations--right")) }, canToRight ? /* @__PURE__ */React.createElement("div", { onClick: function onClick() { handleScroll("next"); }, className: classNames(tdTabsClassGenerator("btn"), tdTabsClassGenerator("btn--right"), tdSizeClassGenerator(size)), ref: toRightBtnRef }, /* @__PURE__ */React.createElement(ChevronRightIcon$1, null)) : null, addable ? /* @__PURE__ */React.createElement("div", { className: classNames(tdTabsClassGenerator("add-btn"), tdTabsClassGenerator("btn"), tdSizeClassGenerator(size)), onClick: handleTabAdd }, /* @__PURE__ */React.createElement(AddIcon$1, null)) : null, action ? /* @__PURE__ */React.createElement("div", { className: classNames(tdTabsClassGenerator("btn"), tdTabsClassGenerator("nav-action"), tdSizeClassGenerator(size)) }, parseTNode(action)) : null), /* @__PURE__ */React.createElement("div", { className: classNames(tdTabsClassGenerator("nav-container"), isCard ? tdTabsClassGenerator("nav--card") : "", tdClassGenerator("is-".concat(placement)), addable ? tdClassGenerator("is-addable") : "") }, /* @__PURE__ */React.createElement("div", { className: classNames(tdTabsClassGenerator("nav-scroll"), canToLeft || canToRight ? tdClassGenerator("is-scrollable") : ""), ref: scrollBarRef }, /* @__PURE__ */React.createElement("div", { className: classNames(tdTabsClassGenerator("nav-wrap"), ["left", "right"].includes(placement) ? tdClassGenerator("is-vertical") : "", tdClassGenerator("is-smooth")), style: { transform: "translate(".concat(-scrollLeft, "px, 0)") }, ref: navsWrapRef }, placement !== "bottom" ? TabBarCom : null, !isCard && /* @__PURE__ */React.createElement("div", { className: classNames(tdTabsClassGenerator("bar"), tdClassGenerator("is-".concat(placement))) }), itemList.map(function (v, index) { return /* @__PURE__ */React.createElement(TabNavItem, _objectSpread(_objectSpread(_objectSpread({}, omit(props, ["className", "style"])), v), {}, { dragProps: _objectSpread({}, getDragProps === null || getDragProps === void 0 ? void 0 : getDragProps(index, v)), onRemove: v.onRemove, key: v.value, label: v.label, isActive: activeValue === v.value, theme: theme, placement: placement, index: index, disabled: disabled || v.disabled, onClick: function onClick() { return handleTabItemClick(v); }, onTabRemove: handleTabItemRemove, innerRef: function innerRef(ref) { if (activeValue === v.value) { setActiveTab(ref); } } })); }), placement === "bottom" ? TabBarCom : null)))); }; TabNav.displayName = "TabNav"; export { TabNav as default }; //# sourceMappingURL=TabNav.js.map