index.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
  3. import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
  4. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  5. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  6. /* eslint-disable react-hooks/exhaustive-deps */
  7. import classNames from 'classnames';
  8. import ResizeObserver from 'rc-resize-observer';
  9. import useEvent from "rc-util/es/hooks/useEvent";
  10. import { useComposeRef } from "rc-util/es/ref";
  11. import * as React from 'react';
  12. import { useEffect, useRef, useState } from 'react';
  13. import TabContext from "../TabContext";
  14. import useIndicator from "../hooks/useIndicator";
  15. import useOffsets from "../hooks/useOffsets";
  16. import useSyncState from "../hooks/useSyncState";
  17. import useTouchMove from "../hooks/useTouchMove";
  18. import useUpdate, { useUpdateState } from "../hooks/useUpdate";
  19. import useVisibleRange from "../hooks/useVisibleRange";
  20. import { genDataNodeKey, getRemovable, stringify } from "../util";
  21. import AddButton from "./AddButton";
  22. import ExtraContent from "./ExtraContent";
  23. import OperationNode from "./OperationNode";
  24. import TabNode from "./TabNode";
  25. var getTabSize = function getTabSize(tab, containerRect) {
  26. // tabListRef
  27. var offsetWidth = tab.offsetWidth,
  28. offsetHeight = tab.offsetHeight,
  29. offsetTop = tab.offsetTop,
  30. offsetLeft = tab.offsetLeft;
  31. var _tab$getBoundingClien = tab.getBoundingClientRect(),
  32. width = _tab$getBoundingClien.width,
  33. height = _tab$getBoundingClien.height,
  34. left = _tab$getBoundingClien.left,
  35. top = _tab$getBoundingClien.top;
  36. // Use getBoundingClientRect to avoid decimal inaccuracy
  37. if (Math.abs(width - offsetWidth) < 1) {
  38. return [width, height, left - containerRect.left, top - containerRect.top];
  39. }
  40. return [offsetWidth, offsetHeight, offsetLeft, offsetTop];
  41. };
  42. var getSize = function getSize(refObj) {
  43. var _ref = refObj.current || {},
  44. _ref$offsetWidth = _ref.offsetWidth,
  45. offsetWidth = _ref$offsetWidth === void 0 ? 0 : _ref$offsetWidth,
  46. _ref$offsetHeight = _ref.offsetHeight,
  47. offsetHeight = _ref$offsetHeight === void 0 ? 0 : _ref$offsetHeight;
  48. // Use getBoundingClientRect to avoid decimal inaccuracy
  49. if (refObj.current) {
  50. var _refObj$current$getBo = refObj.current.getBoundingClientRect(),
  51. width = _refObj$current$getBo.width,
  52. height = _refObj$current$getBo.height;
  53. if (Math.abs(width - offsetWidth) < 1) {
  54. return [width, height];
  55. }
  56. }
  57. return [offsetWidth, offsetHeight];
  58. };
  59. /**
  60. * Convert `SizeInfo` to unit value. Such as [123, 456] with `top` position get `123`
  61. */
  62. var getUnitValue = function getUnitValue(size, tabPositionTopOrBottom) {
  63. return size[tabPositionTopOrBottom ? 0 : 1];
  64. };
  65. var TabNavList = /*#__PURE__*/React.forwardRef(function (props, ref) {
  66. var className = props.className,
  67. style = props.style,
  68. id = props.id,
  69. animated = props.animated,
  70. activeKey = props.activeKey,
  71. rtl = props.rtl,
  72. extra = props.extra,
  73. editable = props.editable,
  74. locale = props.locale,
  75. tabPosition = props.tabPosition,
  76. tabBarGutter = props.tabBarGutter,
  77. children = props.children,
  78. onTabClick = props.onTabClick,
  79. onTabScroll = props.onTabScroll,
  80. indicator = props.indicator;
  81. var _React$useContext = React.useContext(TabContext),
  82. prefixCls = _React$useContext.prefixCls,
  83. tabs = _React$useContext.tabs;
  84. var containerRef = useRef(null);
  85. var extraLeftRef = useRef(null);
  86. var extraRightRef = useRef(null);
  87. var tabsWrapperRef = useRef(null);
  88. var tabListRef = useRef(null);
  89. var operationsRef = useRef(null);
  90. var innerAddButtonRef = useRef(null);
  91. var tabPositionTopOrBottom = tabPosition === 'top' || tabPosition === 'bottom';
  92. var _useSyncState = useSyncState(0, function (next, prev) {
  93. if (tabPositionTopOrBottom && onTabScroll) {
  94. onTabScroll({
  95. direction: next > prev ? 'left' : 'right'
  96. });
  97. }
  98. }),
  99. _useSyncState2 = _slicedToArray(_useSyncState, 2),
  100. transformLeft = _useSyncState2[0],
  101. setTransformLeft = _useSyncState2[1];
  102. var _useSyncState3 = useSyncState(0, function (next, prev) {
  103. if (!tabPositionTopOrBottom && onTabScroll) {
  104. onTabScroll({
  105. direction: next > prev ? 'top' : 'bottom'
  106. });
  107. }
  108. }),
  109. _useSyncState4 = _slicedToArray(_useSyncState3, 2),
  110. transformTop = _useSyncState4[0],
  111. setTransformTop = _useSyncState4[1];
  112. var _useState = useState([0, 0]),
  113. _useState2 = _slicedToArray(_useState, 2),
  114. containerExcludeExtraSize = _useState2[0],
  115. setContainerExcludeExtraSize = _useState2[1];
  116. var _useState3 = useState([0, 0]),
  117. _useState4 = _slicedToArray(_useState3, 2),
  118. tabContentSize = _useState4[0],
  119. setTabContentSize = _useState4[1];
  120. var _useState5 = useState([0, 0]),
  121. _useState6 = _slicedToArray(_useState5, 2),
  122. addSize = _useState6[0],
  123. setAddSize = _useState6[1];
  124. var _useState7 = useState([0, 0]),
  125. _useState8 = _slicedToArray(_useState7, 2),
  126. operationSize = _useState8[0],
  127. setOperationSize = _useState8[1];
  128. var _useUpdateState = useUpdateState(new Map()),
  129. _useUpdateState2 = _slicedToArray(_useUpdateState, 2),
  130. tabSizes = _useUpdateState2[0],
  131. setTabSizes = _useUpdateState2[1];
  132. var tabOffsets = useOffsets(tabs, tabSizes, tabContentSize[0]);
  133. // ========================== Unit =========================
  134. var containerExcludeExtraSizeValue = getUnitValue(containerExcludeExtraSize, tabPositionTopOrBottom);
  135. var tabContentSizeValue = getUnitValue(tabContentSize, tabPositionTopOrBottom);
  136. var addSizeValue = getUnitValue(addSize, tabPositionTopOrBottom);
  137. var operationSizeValue = getUnitValue(operationSize, tabPositionTopOrBottom);
  138. var needScroll = Math.floor(containerExcludeExtraSizeValue) < Math.floor(tabContentSizeValue + addSizeValue);
  139. var visibleTabContentValue = needScroll ? containerExcludeExtraSizeValue - operationSizeValue : containerExcludeExtraSizeValue - addSizeValue;
  140. // ========================== Util =========================
  141. var operationsHiddenClassName = "".concat(prefixCls, "-nav-operations-hidden");
  142. var transformMin = 0;
  143. var transformMax = 0;
  144. if (!tabPositionTopOrBottom) {
  145. transformMin = Math.min(0, visibleTabContentValue - tabContentSizeValue);
  146. transformMax = 0;
  147. } else if (rtl) {
  148. transformMin = 0;
  149. transformMax = Math.max(0, tabContentSizeValue - visibleTabContentValue);
  150. } else {
  151. transformMin = Math.min(0, visibleTabContentValue - tabContentSizeValue);
  152. transformMax = 0;
  153. }
  154. function alignInRange(value) {
  155. if (value < transformMin) {
  156. return transformMin;
  157. }
  158. if (value > transformMax) {
  159. return transformMax;
  160. }
  161. return value;
  162. }
  163. // ========================= Mobile ========================
  164. var touchMovingRef = useRef(null);
  165. var _useState9 = useState(),
  166. _useState10 = _slicedToArray(_useState9, 2),
  167. lockAnimation = _useState10[0],
  168. setLockAnimation = _useState10[1];
  169. function doLockAnimation() {
  170. setLockAnimation(Date.now());
  171. }
  172. function clearTouchMoving() {
  173. if (touchMovingRef.current) {
  174. clearTimeout(touchMovingRef.current);
  175. }
  176. }
  177. useTouchMove(tabsWrapperRef, function (offsetX, offsetY) {
  178. function doMove(setState, offset) {
  179. setState(function (value) {
  180. var newValue = alignInRange(value + offset);
  181. return newValue;
  182. });
  183. }
  184. // Skip scroll if place is enough
  185. if (!needScroll) {
  186. return false;
  187. }
  188. if (tabPositionTopOrBottom) {
  189. doMove(setTransformLeft, offsetX);
  190. } else {
  191. doMove(setTransformTop, offsetY);
  192. }
  193. clearTouchMoving();
  194. doLockAnimation();
  195. return true;
  196. });
  197. useEffect(function () {
  198. clearTouchMoving();
  199. if (lockAnimation) {
  200. touchMovingRef.current = setTimeout(function () {
  201. setLockAnimation(0);
  202. }, 100);
  203. }
  204. return clearTouchMoving;
  205. }, [lockAnimation]);
  206. // ===================== Visible Range =====================
  207. // Render tab node & collect tab offset
  208. var _useVisibleRange = useVisibleRange(tabOffsets,
  209. // Container
  210. visibleTabContentValue,
  211. // Transform
  212. tabPositionTopOrBottom ? transformLeft : transformTop,
  213. // Tabs
  214. tabContentSizeValue,
  215. // Add
  216. addSizeValue,
  217. // Operation
  218. operationSizeValue, _objectSpread(_objectSpread({}, props), {}, {
  219. tabs: tabs
  220. })),
  221. _useVisibleRange2 = _slicedToArray(_useVisibleRange, 2),
  222. visibleStart = _useVisibleRange2[0],
  223. visibleEnd = _useVisibleRange2[1];
  224. // ========================= Scroll ========================
  225. var scrollToTab = useEvent(function () {
  226. var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : activeKey;
  227. var tabOffset = tabOffsets.get(key) || {
  228. width: 0,
  229. height: 0,
  230. left: 0,
  231. right: 0,
  232. top: 0
  233. };
  234. if (tabPositionTopOrBottom) {
  235. // ============ Align with top & bottom ============
  236. var newTransform = transformLeft;
  237. // RTL
  238. if (rtl) {
  239. if (tabOffset.right < transformLeft) {
  240. newTransform = tabOffset.right;
  241. } else if (tabOffset.right + tabOffset.width > transformLeft + visibleTabContentValue) {
  242. newTransform = tabOffset.right + tabOffset.width - visibleTabContentValue;
  243. }
  244. }
  245. // LTR
  246. else if (tabOffset.left < -transformLeft) {
  247. newTransform = -tabOffset.left;
  248. } else if (tabOffset.left + tabOffset.width > -transformLeft + visibleTabContentValue) {
  249. newTransform = -(tabOffset.left + tabOffset.width - visibleTabContentValue);
  250. }
  251. setTransformTop(0);
  252. setTransformLeft(alignInRange(newTransform));
  253. } else {
  254. // ============ Align with left & right ============
  255. var _newTransform = transformTop;
  256. if (tabOffset.top < -transformTop) {
  257. _newTransform = -tabOffset.top;
  258. } else if (tabOffset.top + tabOffset.height > -transformTop + visibleTabContentValue) {
  259. _newTransform = -(tabOffset.top + tabOffset.height - visibleTabContentValue);
  260. }
  261. setTransformLeft(0);
  262. setTransformTop(alignInRange(_newTransform));
  263. }
  264. });
  265. // ========================= Focus =========================
  266. var _useState11 = useState(),
  267. _useState12 = _slicedToArray(_useState11, 2),
  268. focusKey = _useState12[0],
  269. setFocusKey = _useState12[1];
  270. var _useState13 = useState(false),
  271. _useState14 = _slicedToArray(_useState13, 2),
  272. isMouse = _useState14[0],
  273. setIsMouse = _useState14[1];
  274. var enabledTabs = tabs.filter(function (tab) {
  275. return !tab.disabled;
  276. }).map(function (tab) {
  277. return tab.key;
  278. });
  279. var onOffset = function onOffset(offset) {
  280. var currentIndex = enabledTabs.indexOf(focusKey || activeKey);
  281. var len = enabledTabs.length;
  282. var nextIndex = (currentIndex + offset + len) % len;
  283. var newKey = enabledTabs[nextIndex];
  284. setFocusKey(newKey);
  285. };
  286. var handleRemoveTab = function handleRemoveTab(removalTabKey, e) {
  287. var removeIndex = enabledTabs.indexOf(removalTabKey);
  288. var removeTab = tabs.find(function (tab) {
  289. return tab.key === removalTabKey;
  290. });
  291. var removable = getRemovable(removeTab === null || removeTab === void 0 ? void 0 : removeTab.closable, removeTab === null || removeTab === void 0 ? void 0 : removeTab.closeIcon, editable, removeTab === null || removeTab === void 0 ? void 0 : removeTab.disabled);
  292. if (removable) {
  293. e.preventDefault();
  294. e.stopPropagation();
  295. editable.onEdit('remove', {
  296. key: removalTabKey,
  297. event: e
  298. });
  299. // when remove last tab, focus previous tab
  300. if (removeIndex === enabledTabs.length - 1) {
  301. onOffset(-1);
  302. } else {
  303. onOffset(1);
  304. }
  305. }
  306. };
  307. var handleMouseDown = function handleMouseDown(key, e) {
  308. setIsMouse(true);
  309. // Middle mouse button
  310. if (e.button === 1) {
  311. handleRemoveTab(key, e);
  312. }
  313. };
  314. var handleKeyDown = function handleKeyDown(e) {
  315. var code = e.code;
  316. var isRTL = rtl && tabPositionTopOrBottom;
  317. var firstEnabledTab = enabledTabs[0];
  318. var lastEnabledTab = enabledTabs[enabledTabs.length - 1];
  319. switch (code) {
  320. // LEFT
  321. case 'ArrowLeft':
  322. {
  323. if (tabPositionTopOrBottom) {
  324. onOffset(isRTL ? 1 : -1);
  325. }
  326. break;
  327. }
  328. // RIGHT
  329. case 'ArrowRight':
  330. {
  331. if (tabPositionTopOrBottom) {
  332. onOffset(isRTL ? -1 : 1);
  333. }
  334. break;
  335. }
  336. // UP
  337. case 'ArrowUp':
  338. {
  339. e.preventDefault();
  340. if (!tabPositionTopOrBottom) {
  341. onOffset(-1);
  342. }
  343. break;
  344. }
  345. // DOWN
  346. case 'ArrowDown':
  347. {
  348. e.preventDefault();
  349. if (!tabPositionTopOrBottom) {
  350. onOffset(1);
  351. }
  352. break;
  353. }
  354. // HOME
  355. case 'Home':
  356. {
  357. e.preventDefault();
  358. setFocusKey(firstEnabledTab);
  359. break;
  360. }
  361. // END
  362. case 'End':
  363. {
  364. e.preventDefault();
  365. setFocusKey(lastEnabledTab);
  366. break;
  367. }
  368. // Enter & Space
  369. case 'Enter':
  370. case 'Space':
  371. {
  372. e.preventDefault();
  373. onTabClick(focusKey !== null && focusKey !== void 0 ? focusKey : activeKey, e);
  374. break;
  375. }
  376. // Backspace
  377. case 'Backspace':
  378. case 'Delete':
  379. {
  380. handleRemoveTab(focusKey, e);
  381. break;
  382. }
  383. }
  384. };
  385. // ========================== Tab ==========================
  386. var tabNodeStyle = {};
  387. if (tabPositionTopOrBottom) {
  388. tabNodeStyle[rtl ? 'marginRight' : 'marginLeft'] = tabBarGutter;
  389. } else {
  390. tabNodeStyle.marginTop = tabBarGutter;
  391. }
  392. var tabNodes = tabs.map(function (tab, i) {
  393. var key = tab.key;
  394. return /*#__PURE__*/React.createElement(TabNode, {
  395. id: id,
  396. prefixCls: prefixCls,
  397. key: key,
  398. tab: tab
  399. /* first node should not have margin left */,
  400. style: i === 0 ? undefined : tabNodeStyle,
  401. closable: tab.closable,
  402. editable: editable,
  403. active: key === activeKey,
  404. focus: key === focusKey,
  405. renderWrapper: children,
  406. removeAriaLabel: locale === null || locale === void 0 ? void 0 : locale.removeAriaLabel,
  407. tabCount: enabledTabs.length,
  408. currentPosition: i + 1,
  409. onClick: function onClick(e) {
  410. onTabClick(key, e);
  411. },
  412. onKeyDown: handleKeyDown,
  413. onFocus: function onFocus() {
  414. if (!isMouse) {
  415. setFocusKey(key);
  416. }
  417. scrollToTab(key);
  418. doLockAnimation();
  419. if (!tabsWrapperRef.current) {
  420. return;
  421. }
  422. // Focus element will make scrollLeft change which we should reset back
  423. if (!rtl) {
  424. tabsWrapperRef.current.scrollLeft = 0;
  425. }
  426. tabsWrapperRef.current.scrollTop = 0;
  427. },
  428. onBlur: function onBlur() {
  429. setFocusKey(undefined);
  430. },
  431. onMouseDown: function onMouseDown(e) {
  432. return handleMouseDown(key, e);
  433. },
  434. onMouseUp: function onMouseUp() {
  435. setIsMouse(false);
  436. }
  437. });
  438. });
  439. // Update buttons records
  440. var updateTabSizes = function updateTabSizes() {
  441. return setTabSizes(function () {
  442. var _tabListRef$current;
  443. var newSizes = new Map();
  444. var listRect = (_tabListRef$current = tabListRef.current) === null || _tabListRef$current === void 0 ? void 0 : _tabListRef$current.getBoundingClientRect();
  445. tabs.forEach(function (_ref2) {
  446. var _tabListRef$current2;
  447. var key = _ref2.key;
  448. var btnNode = (_tabListRef$current2 = tabListRef.current) === null || _tabListRef$current2 === void 0 ? void 0 : _tabListRef$current2.querySelector("[data-node-key=\"".concat(genDataNodeKey(key), "\"]"));
  449. if (btnNode) {
  450. var _getTabSize = getTabSize(btnNode, listRect),
  451. _getTabSize2 = _slicedToArray(_getTabSize, 4),
  452. width = _getTabSize2[0],
  453. height = _getTabSize2[1],
  454. left = _getTabSize2[2],
  455. top = _getTabSize2[3];
  456. newSizes.set(key, {
  457. width: width,
  458. height: height,
  459. left: left,
  460. top: top
  461. });
  462. }
  463. });
  464. return newSizes;
  465. });
  466. };
  467. useEffect(function () {
  468. updateTabSizes();
  469. }, [tabs.map(function (tab) {
  470. return tab.key;
  471. }).join('_')]);
  472. var onListHolderResize = useUpdate(function () {
  473. // Update wrapper records
  474. var containerSize = getSize(containerRef);
  475. var extraLeftSize = getSize(extraLeftRef);
  476. var extraRightSize = getSize(extraRightRef);
  477. setContainerExcludeExtraSize([containerSize[0] - extraLeftSize[0] - extraRightSize[0], containerSize[1] - extraLeftSize[1] - extraRightSize[1]]);
  478. var newAddSize = getSize(innerAddButtonRef);
  479. setAddSize(newAddSize);
  480. var newOperationSize = getSize(operationsRef);
  481. setOperationSize(newOperationSize);
  482. // Which includes add button size
  483. var tabContentFullSize = getSize(tabListRef);
  484. setTabContentSize([tabContentFullSize[0] - newAddSize[0], tabContentFullSize[1] - newAddSize[1]]);
  485. // Update buttons records
  486. updateTabSizes();
  487. });
  488. // ======================== Dropdown =======================
  489. var startHiddenTabs = tabs.slice(0, visibleStart);
  490. var endHiddenTabs = tabs.slice(visibleEnd + 1);
  491. var hiddenTabs = [].concat(_toConsumableArray(startHiddenTabs), _toConsumableArray(endHiddenTabs));
  492. // =================== Link & Operations ===================
  493. var activeTabOffset = tabOffsets.get(activeKey);
  494. var _useIndicator = useIndicator({
  495. activeTabOffset: activeTabOffset,
  496. horizontal: tabPositionTopOrBottom,
  497. indicator: indicator,
  498. rtl: rtl
  499. }),
  500. indicatorStyle = _useIndicator.style;
  501. // ========================= Effect ========================
  502. useEffect(function () {
  503. scrollToTab();
  504. }, [activeKey, transformMin, transformMax, stringify(activeTabOffset), stringify(tabOffsets), tabPositionTopOrBottom]);
  505. // Should recalculate when rtl changed
  506. useEffect(function () {
  507. onListHolderResize();
  508. // eslint-disable-next-line
  509. }, [rtl]);
  510. // ========================= Render ========================
  511. var hasDropdown = !!hiddenTabs.length;
  512. var wrapPrefix = "".concat(prefixCls, "-nav-wrap");
  513. var pingLeft;
  514. var pingRight;
  515. var pingTop;
  516. var pingBottom;
  517. if (tabPositionTopOrBottom) {
  518. if (rtl) {
  519. pingRight = transformLeft > 0;
  520. pingLeft = transformLeft !== transformMax;
  521. } else {
  522. pingLeft = transformLeft < 0;
  523. pingRight = transformLeft !== transformMin;
  524. }
  525. } else {
  526. pingTop = transformTop < 0;
  527. pingBottom = transformTop !== transformMin;
  528. }
  529. return /*#__PURE__*/React.createElement(ResizeObserver, {
  530. onResize: onListHolderResize
  531. }, /*#__PURE__*/React.createElement("div", {
  532. ref: useComposeRef(ref, containerRef),
  533. role: "tablist",
  534. "aria-orientation": tabPositionTopOrBottom ? 'horizontal' : 'vertical',
  535. className: classNames("".concat(prefixCls, "-nav"), className),
  536. style: style,
  537. onKeyDown: function onKeyDown() {
  538. // No need animation when use keyboard
  539. doLockAnimation();
  540. }
  541. }, /*#__PURE__*/React.createElement(ExtraContent, {
  542. ref: extraLeftRef,
  543. position: "left",
  544. extra: extra,
  545. prefixCls: prefixCls
  546. }), /*#__PURE__*/React.createElement(ResizeObserver, {
  547. onResize: onListHolderResize
  548. }, /*#__PURE__*/React.createElement("div", {
  549. className: classNames(wrapPrefix, _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, "".concat(wrapPrefix, "-ping-left"), pingLeft), "".concat(wrapPrefix, "-ping-right"), pingRight), "".concat(wrapPrefix, "-ping-top"), pingTop), "".concat(wrapPrefix, "-ping-bottom"), pingBottom)),
  550. ref: tabsWrapperRef
  551. }, /*#__PURE__*/React.createElement(ResizeObserver, {
  552. onResize: onListHolderResize
  553. }, /*#__PURE__*/React.createElement("div", {
  554. ref: tabListRef,
  555. className: "".concat(prefixCls, "-nav-list"),
  556. style: {
  557. transform: "translate(".concat(transformLeft, "px, ").concat(transformTop, "px)"),
  558. transition: lockAnimation ? 'none' : undefined
  559. }
  560. }, tabNodes, /*#__PURE__*/React.createElement(AddButton, {
  561. ref: innerAddButtonRef,
  562. prefixCls: prefixCls,
  563. locale: locale,
  564. editable: editable,
  565. style: _objectSpread(_objectSpread({}, tabNodes.length === 0 ? undefined : tabNodeStyle), {}, {
  566. visibility: hasDropdown ? 'hidden' : null
  567. })
  568. }), /*#__PURE__*/React.createElement("div", {
  569. className: classNames("".concat(prefixCls, "-ink-bar"), _defineProperty({}, "".concat(prefixCls, "-ink-bar-animated"), animated.inkBar)),
  570. style: indicatorStyle
  571. }))))), /*#__PURE__*/React.createElement(OperationNode, _extends({}, props, {
  572. removeAriaLabel: locale === null || locale === void 0 ? void 0 : locale.removeAriaLabel,
  573. ref: operationsRef,
  574. prefixCls: prefixCls,
  575. tabs: hiddenTabs,
  576. className: !hasDropdown && operationsHiddenClassName,
  577. tabMoving: !!lockAnimation
  578. })), /*#__PURE__*/React.createElement(ExtraContent, {
  579. ref: extraRightRef,
  580. position: "right",
  581. extra: extra,
  582. prefixCls: prefixCls
  583. })));
  584. /* eslint-enable */
  585. });
  586. export default TabNavList;