@ringcentral/spring-ui 1.11.2 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/Accordion.js +90 -34
  2. package/AccordionHeader.js +72 -20
  3. package/Alert.js +120 -28
  4. package/Animation.js +2 -45
  5. package/Announcement.js +46 -35
  6. package/Autocomplete.js +1011 -580
  7. package/Avatar.js +134 -73
  8. package/AvatarGroup.js +50 -7
  9. package/Backdrop.js +45 -7
  10. package/Badge.js +77 -15
  11. package/Block.js +34 -12
  12. package/BlockHeader.js +55 -11
  13. package/BottomNavigation.js +181 -65
  14. package/BottomNavigationItem.js +93 -30
  15. package/Button.js +160 -24
  16. package/CallButton.js +53 -31
  17. package/Checkbox.js +88 -26
  18. package/Chip.js +126 -26
  19. package/CircularProgressIndicator.js +80 -8
  20. package/ClickAwayListener.js +4 -1
  21. package/ComponentsProps.js +1 -0
  22. package/DatePicker.js +611 -190
  23. package/DateUtilsContext.js +43 -25
  24. package/Dialer.js +576 -250
  25. package/Dialog.js +100 -45
  26. package/Divider.js +43 -7
  27. package/DragHandle.js +32 -6
  28. package/Drawer.js +117 -19
  29. package/Dropdown.js +154 -74
  30. package/EmptyState.js +63 -11
  31. package/FabButton.js +51 -17
  32. package/FocusTrap.js +109 -12
  33. package/FormField.js +106 -8
  34. package/FormLabel.js +81 -7
  35. package/Icon.js +1 -8
  36. package/IconButton.js +142 -26
  37. package/IconButtonGroup.js +35 -12
  38. package/InlineEditable.js +98 -44
  39. package/LinearProgressIndicator.js +73 -24
  40. package/Link.js +40 -11
  41. package/List.js +54 -9
  42. package/ListItem.js +152 -23
  43. package/ListItemText.js +44 -16
  44. package/ListNavigation.js +272 -20
  45. package/Menu.js +139 -23
  46. package/MenuActions.js +37 -12
  47. package/MenuDivider.js +34 -8
  48. package/MenuFooter.js +36 -12
  49. package/MenuHeader.js +54 -15
  50. package/MenuItem.js +402 -33
  51. package/MenuItemText.js +51 -8
  52. package/MenuList.js +87 -34
  53. package/Modal.js +345 -16
  54. package/NestedMenuContext.js +183 -11
  55. package/Option.js +32 -34
  56. package/Overlap.js +54 -7
  57. package/PageHeader.js +62 -24
  58. package/PickerTextField.js +156 -33
  59. package/Popover.js +262 -21
  60. package/Popper.js +130 -77
  61. package/PopperPaper.js +54 -8
  62. package/Portal.js +6 -1
  63. package/Radio.js +65 -21
  64. package/RadioGroup.js +56 -17
  65. package/Rating.js +223 -87
  66. package/Select.js +387 -41
  67. package/SingleFilter.js +148 -77
  68. package/Skeleton.js +68 -17
  69. package/Slider.js +168 -69
  70. package/Snackbar.js +122 -59
  71. package/SortableList.js +32 -12
  72. package/SortableListDndContext.js +69 -22
  73. package/SortableListItem.js +92 -47
  74. package/SortableVirtualizedList.js +52 -28
  75. package/SplitButton.js +124 -86
  76. package/Squircle.js +4 -7
  77. package/StatusIndicator.js +51 -9
  78. package/Step.js +63 -38
  79. package/StepButton.js +51 -23
  80. package/StepConnector.js +48 -8
  81. package/StepContent.js +68 -25
  82. package/StepIcon.js +90 -9
  83. package/StepLabel.js +90 -14
  84. package/Stepper.js +65 -23
  85. package/SubMenu.js +203 -99
  86. package/SwipeableDrawer.js +439 -194
  87. package/Switch.js +70 -23
  88. package/Tab.js +120 -57
  89. package/TabContext.js +59 -15
  90. package/TabPanel.js +40 -13
  91. package/Table.js +60 -17
  92. package/TableBody.js +42 -12
  93. package/TableCell.js +84 -50
  94. package/TableContainer.js +32 -10
  95. package/TableFooter.js +38 -10
  96. package/TableHead.js +49 -15
  97. package/TablePagination.js +153 -77
  98. package/TableRow.js +60 -21
  99. package/Tabs.js +593 -268
  100. package/Tag.js +51 -16
  101. package/Text.js +68 -37
  102. package/TextField.js +209 -29
  103. package/Textarea.js +51 -40
  104. package/TimePicker.js +490 -230
  105. package/Tooltip.js +48 -23
  106. package/Tray.js +237 -13
  107. package/TrayMenu.js +62 -41
  108. package/VirtualizedList.js +208 -109
  109. package/VirtualizedMenu.js +359 -29
  110. package/VisuallyHidden.js +29 -6
  111. package/chunks/1250.js +98 -0
  112. package/chunks/1294.js +126 -0
  113. package/chunks/2956.js +18 -0
  114. package/chunks/4476.js +460 -0
  115. package/chunks/4491.js +10 -0
  116. package/chunks/4535.js +364 -0
  117. package/chunks/5047.js +3 -0
  118. package/chunks/6335.js +24 -0
  119. package/chunks/7279.js +10 -0
  120. package/chunks/8011.js +8 -0
  121. package/chunks/8307.js +56 -0
  122. package/chunks/8467.js +8 -0
  123. package/chunks/8809.js +8 -0
  124. package/chunks/{RadioGroup.context.js → 9551.js} +12 -6
  125. package/chunks/987.js +8 -0
  126. package/index.css +2624 -2416
  127. package/index.js +245 -193
  128. package/internal/utils/index.d.ts +1 -0
  129. package/internal/utils/setRef.d.ts +2 -0
  130. package/package.json +8 -8
  131. package/src/Alert/Alert.type.d.ts +2 -1
  132. package/src/Animation/components/Fade/Fade.d.ts +4 -2
  133. package/src/Animation/components/Grow/Grow.d.ts +4 -2
  134. package/src/Animation/components/ShowHideEye/ShowHideEye.d.ts +1 -1
  135. package/src/Animation/components/SlideIn/SlideIn.d.ts +4 -2
  136. package/src/Animation/components/SlideIn/getSlideIn.d.ts +1 -1
  137. package/src/Animation/hooks/useMotionSafeTransition/useMotionSafeTransition.d.ts +2 -0
  138. package/src/Autocomplete/SuggestionList/SuggestionList.d.ts +1 -1
  139. package/src/Autocomplete/useAutocomplete.d.ts +18 -18
  140. package/src/Autocomplete/useAutocompleteTag.d.ts +18 -18
  141. package/src/Badge/Badge.d.ts +2 -1
  142. package/src/Button/Button.classes.d.ts +1 -1
  143. package/src/ComponentsProps.d.ts +111 -110
  144. package/src/DatePicker/DatePickerDataAttributes.d.ts +11 -0
  145. package/src/DatePicker/utils/DatePickerAriaLabelUtils.d.ts +2 -1
  146. package/src/DatePicker/utils/DatePickerUtils.d.ts +1 -1
  147. package/src/Dialer/DialDelete/DialDelete.d.ts +2 -2
  148. package/src/Dialer/DialPad/DialPad.d.ts +2 -2
  149. package/src/Dialer/Dialer.d.ts +4 -2
  150. package/src/Dropdown/Dropdown.type.d.ts +2 -2
  151. package/src/InlineEditable/InlineEditable.type.d.ts +2 -1
  152. package/src/ListNavigation/useListNavigation.d.ts +3 -3
  153. package/src/MenuActions/MenuActions.d.ts +2 -2
  154. package/src/MenuItem/MenuItem.type.d.ts +1 -0
  155. package/src/MenuItem/useMenuItem.d.ts +1 -1
  156. package/src/MenuItem/useVirtualizedMenuItem.d.ts +1 -1
  157. package/src/MenuList/MenuList.type.d.ts +1 -1
  158. package/src/MenuList/MenuListContext.d.ts +2 -3
  159. package/src/Modal/Modal.type.d.ts +1 -0
  160. package/src/NestedMenuContext/MenuOverlayGroupContext.d.ts +2 -2
  161. package/src/Popover/Popover.classes.d.ts +1 -1
  162. package/src/Popover/Popover.internal.d.ts +8 -0
  163. package/src/Popover/Popover.type.d.ts +1 -0
  164. package/src/Popper/Popper.type.d.ts +10 -7
  165. package/src/Rating/utils.d.ts +3 -2
  166. package/src/Select/Select.type.d.ts +7 -5
  167. package/src/Slider/Slider.d.ts +2 -2
  168. package/src/Slider/SliderThumb.d.ts +2 -1
  169. package/src/Squircle/Squircle.d.ts +1 -1
  170. package/src/StatusIndicator/StatusIndicator.d.ts +2 -1
  171. package/src/SubMenu/PopperMenu.type.d.ts +4 -1
  172. package/src/Table/Table.type.d.ts +3 -0
  173. package/src/Table/TableContext.d.ts +3 -0
  174. package/src/Table/TableRowContext.d.ts +7 -0
  175. package/src/Table/index.d.ts +1 -0
  176. package/src/TableCell/TableCell.classes.d.ts +1 -1
  177. package/src/TableFooter/TableFooter.classes.d.ts +1 -1
  178. package/src/TableFooter/TableFooter.type.d.ts +1 -0
  179. package/src/TableHead/TableHead.classes.d.ts +1 -1
  180. package/src/TableHead/TableHead.type.d.ts +1 -0
  181. package/src/TableRow/TableRow.type.d.ts +2 -0
  182. package/chunks/AccordionContext.js +0 -6
  183. package/chunks/Alert.js +0 -48
  184. package/chunks/AvatarGroup.js +0 -22
  185. package/chunks/Backdrop.js +0 -18
  186. package/chunks/Badge.js +0 -32
  187. package/chunks/BottomNavigationItem.js +0 -36
  188. package/chunks/Button.js +0 -88
  189. package/chunks/Chip.js +0 -73
  190. package/chunks/CircularProgressIndicator.js +0 -36
  191. package/chunks/Divider.js +0 -19
  192. package/chunks/DragHandle.js +0 -11
  193. package/chunks/Drawer.js +0 -32
  194. package/chunks/ExpandCollapseCaret.js +0 -24
  195. package/chunks/FormLabel.js +0 -27
  196. package/chunks/Icon.js +0 -25
  197. package/chunks/IconButtonLabel.js +0 -68
  198. package/chunks/List.js +0 -22
  199. package/chunks/ListItem.js +0 -83
  200. package/chunks/Menu.js +0 -61
  201. package/chunks/MenuDivider.js +0 -14
  202. package/chunks/MenuItemText.js +0 -17
  203. package/chunks/MenuList.js +0 -46
  204. package/chunks/Modal.js +0 -212
  205. package/chunks/Overlap.js +0 -25
  206. package/chunks/PickerTextField.js +0 -85
  207. package/chunks/Popover.js +0 -53
  208. package/chunks/PopperPaper.js +0 -15
  209. package/chunks/Select.js +0 -220
  210. package/chunks/ShowHideEye.js +0 -56
  211. package/chunks/SlideIn.js +0 -19
  212. package/chunks/SortableArrow.js +0 -73
  213. package/chunks/Squircle.js +0 -31
  214. package/chunks/StatusIndicator.js +0 -20
  215. package/chunks/StepConnector.js +0 -21
  216. package/chunks/StepIcon.js +0 -43
  217. package/chunks/StepLabel.js +0 -29
  218. package/chunks/StepperContext.js +0 -9
  219. package/chunks/TableContext.js +0 -6
  220. package/chunks/Tablelvl2Context.js +0 -6
  221. package/chunks/TabsContext.js +0 -6
  222. package/chunks/TextField.js +0 -110
  223. package/chunks/Tooltip.js +0 -217
  224. package/chunks/VirtualizedMenu.js +0 -164
  225. package/chunks/VisuallyHidden.js +0 -12
  226. package/chunks/getFade.js +0 -27
  227. package/chunks/getGrow.js +0 -70
  228. package/chunks/getSlideIn.js +0 -30
  229. package/chunks/hasContent.js +0 -3
  230. package/chunks/useAnimationFrame.js +0 -15
  231. package/chunks/useFocusTrapStack.js +0 -36
  232. package/chunks/useHelperTextId.js +0 -22
  233. package/chunks/useListNavigation.js +0 -199
  234. package/chunks/useMenuItemSelect.js +0 -273
  235. package/chunks/useMotionSafeTransition.js +0 -9
  236. package/chunks/useNestedMenuItem.js +0 -27
  237. package/chunks/useNestedParentMenu.js +0 -113
  238. package/chunks/usePrefersReducedMotion.js +0 -36
  239. package/chunks/useTooltipForceHide.js +0 -27
  240. package/chunks/useTrayNavigate.js +0 -150
  241. package/chunks/withTooltip.js +0 -15
package/Tabs.js CHANGED
@@ -1,87 +1,92 @@
1
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import React, { forwardRef, useState, useMemo, useRef, Children, isValidElement, cloneElement, useEffect, useLayoutEffect, useCallback } from 'react';
3
- import { useTab, useTabsList, TabsListProvider } from '@mui/base';
4
- import { useClasses, combineClasses, getTitle, combineProps, useFontLoaded, useWindowContext, logInDev, usePrevious, useEventCallback, useOnReRender, useForkRef } from '@ringcentral/spring-base';
5
- import { OverflowMd, CaretLeftMd, CaretRightMd } from '@ringcentral/spring-icon';
6
- import { useMode, motionTransition, useThemeProps, useClassesWithMode } from '@ringcentral/spring-theme';
7
- import { B as Badge } from './chunks/Badge.js';
8
- import { I as IconButton } from './chunks/IconButtonLabel.js';
9
- import { M as Menu } from './chunks/Menu.js';
10
- import { M as MenuItem } from './chunks/useMenuItemSelect.js';
11
- import 'tabbable';
12
- import './chunks/useListNavigation.js';
13
- import './VirtualizedList.js';
14
- import { M as MenuItemText } from './chunks/MenuItemText.js';
15
- import { M as MenuList } from './chunks/MenuList.js';
16
- import { T as Tooltip } from './chunks/Tooltip.js';
17
- import { u as useTabsContext, T as TabsContext } from './chunks/TabsContext.js';
18
- import { animate, useMotionValue, motion } from 'framer-motion';
19
- import './chunks/Icon.js';
20
- import { u as usePrefersReducedMotion } from './chunks/usePrefersReducedMotion.js';
21
- import { u as useMotionSafeTransition } from './chunks/useMotionSafeTransition.js';
22
- import isEqual from 'lodash/isEqual';
23
- import throttle from 'lodash/throttle';
24
- import { useInternalTabsContext, generateTabStableIds } from './TabContext.js';
25
- import 'lodash/isNumber';
26
- import 'lodash/kebabCase';
27
- import './chunks/Squircle.js';
28
- import './chunks/withTooltip.js';
29
- import './chunks/useNestedParentMenu.js';
30
- import './chunks/Popover.js';
31
- import '@floating-ui/react-dom';
32
- import './chunks/getGrow.js';
33
- import './chunks/Modal.js';
34
- import './chunks/getFade.js';
35
- import './chunks/useFocusTrapStack.js';
36
- import './chunks/Backdrop.js';
37
- import './Popper.js';
38
- import './chunks/PopperPaper.js';
39
- import './chunks/useAnimationFrame.js';
40
- import './chunks/useNestedMenuItem.js';
41
- import './ListNavigation.js';
42
- import 'react-virtuoso';
43
- import './chunks/List.js';
44
- import './chunks/hasContent.js';
45
- import 'clsx';
46
-
47
- const TabMenuItem = forwardRef((props, ref) => {
48
- const { label, component: MenuItemComponent = MenuItem, onKeyDown } = props;
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import react, { Children, cloneElement, forwardRef, isValidElement, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
3
+ import { TabsListProvider, useTab, useTabsList } from "@mui/base";
4
+ import { combineClasses, combineProps, getTitle, logInDev, useClasses, useEventCallback, useFontLoaded, useForkRef, useOnReRender, usePrevious, useWindowContext } from "@ringcentral/spring-base";
5
+ import { CaretLeftMd, CaretRightMd, OverflowMd } from "@ringcentral/spring-icon";
6
+ import { motionTransition, useClassesWithMode, useMode, useThemeProps } from "@ringcentral/spring-theme";
7
+ import { animate, motion, useMotionValue } from "framer-motion";
8
+ import isEqual from "lodash/isEqual";
9
+ import throttle from "lodash/throttle";
10
+ import { Badge as Badge_Badge } from "./Badge.js";
11
+ import { IconButton as IconButton_IconButton } from "./IconButton.js";
12
+ import { Menu as Menu_Menu } from "./Menu.js";
13
+ import { MenuItem as MenuItem_MenuItem } from "./MenuItem.js";
14
+ import { MenuItemText as MenuItemText_MenuItemText } from "./MenuItemText.js";
15
+ import { MenuList as MenuList_MenuList } from "./MenuList.js";
16
+ import "./Tooltip.js";
17
+ import { TabsContext, useTabsContext } from "./chunks/8809.js";
18
+ import "./chunks/4476.js";
19
+ import { useInternalTabsContext, generateTabStableIds } from "./TabContext.js";
20
+ import { Tooltip } from "./chunks/4535.js";
21
+ import { useMotionSafeTransition, usePrefersReducedMotion } from "./chunks/1294.js";
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+ const TabMenuItem = /*#__PURE__*/ forwardRef((props, ref)=>{
44
+ const { label, component: MenuItemComponent = MenuItem_MenuItem, onKeyDown } = props;
49
45
  const { onChange, ...rest } = props;
50
46
  const { getRootProps } = useTab({
51
47
  ...rest,
52
- rootRef: ref,
48
+ rootRef: ref
53
49
  });
54
- return (jsx(MenuItemComponent, { ...props, ...getRootProps(), onKeyDown: onKeyDown, children: jsx(MenuItemText, { children: label }) }));
50
+ return(// @ts-ignore
51
+ /*#__PURE__*/ jsx(MenuItemComponent, {
52
+ ...props,
53
+ ...getRootProps(),
54
+ onKeyDown: onKeyDown,
55
+ children: /*#__PURE__*/ jsx(MenuItemText_MenuItemText, {
56
+ children: label
57
+ })
58
+ }));
55
59
  });
56
- const TabMoreMenu = forwardRef((props, ref) => {
60
+ const TabMoreMenu = /*#__PURE__*/ forwardRef((props, ref)=>{
57
61
  const { classes, className, menuItems, TooltipProps, BadgeProps, ButtonProps, MenuProps, MenuItemComponent, ...rest } = props;
58
62
  const [anchor, setAnchor] = useState(null);
59
63
  const { mode } = useMode();
60
64
  const cls = useClasses('tab-more-menu', classes, className);
61
65
  const { pill } = useTabsContext();
62
- const iconButtonProps = useMemo(() => (pill
63
- ? {
66
+ const iconButtonProps = useMemo(()=>pill ? {
64
67
  shape: 'circular',
65
68
  variant: 'outlined',
66
69
  size: mode === 'compact' ? 'medium' : 'large',
67
- background: true,
68
- }
69
- : {
70
+ background: true
71
+ } : {
70
72
  shape: 'squircle',
71
73
  variant: 'contained',
72
74
  size: 'small',
73
- background: false,
74
- }), [pill, mode]);
75
+ background: false
76
+ }, [
77
+ pill,
78
+ mode
79
+ ]);
75
80
  let iconButtonClasses = {
76
- root: cls('button'),
81
+ root: cls('button')
77
82
  };
78
83
  if (ButtonProps?.classes) {
79
84
  iconButtonClasses = combineClasses(iconButtonClasses, ButtonProps.classes);
80
85
  }
81
86
  let badgeClasses = {
82
87
  root: cls('badge-root', {
83
- 'pill-badge': pill,
84
- }),
88
+ 'pill-badge': pill
89
+ })
85
90
  };
86
91
  if (BadgeProps?.classes) {
87
92
  badgeClasses = combineClasses(badgeClasses, BadgeProps.classes);
@@ -90,73 +95,173 @@ const TabMoreMenu = forwardRef((props, ref) => {
90
95
  color: 'secondary',
91
96
  variant: pill ? 'outlined' : 'contained',
92
97
  ...BadgeProps,
93
- classes: badgeClasses,
98
+ classes: badgeClasses
94
99
  };
95
- const handleClose = (event, reason) => {
100
+ const handleClose = (event, reason)=>{
96
101
  setAnchor(null);
97
102
  };
98
- const iconButton = (jsx(IconButton, { color: 'secondary', symbol: OverflowMd, ...iconButtonProps, onClick: (e) => {
99
- setAnchor((prev) => (prev ? null : e.currentTarget));
100
- }, "aria-expanded": Boolean(anchor), "aria-label": getTitle(TooltipProps?.title), ...ButtonProps, classes: iconButtonClasses }));
101
- return (jsxs(Fragment, { children: [jsxs("div", { className: cls('root'), ref: ref, ...rest, children: [TooltipProps ? (jsx(Tooltip, { ...TooltipProps, children: iconButton })) : (iconButton), Number(BadgeProps?.count) > 0 ? jsx(Badge, { ...badgeProps }) : null] }), jsx(Menu, { open: Boolean(anchor), anchorEl: anchor, ...combineProps({ onClose: handleClose }, MenuProps), children: jsx(MenuList, { children: menuItems.map(({ ref, ...props }, index) => (jsx(TabMenuItem, { ...props, ref: ref, component: MenuItemComponent }, props.value || `TabMenuItem-${index}`))) }) })] }));
103
+ const iconButton = /*#__PURE__*/ jsx(IconButton_IconButton, {
104
+ color: 'secondary',
105
+ symbol: OverflowMd,
106
+ ...iconButtonProps,
107
+ onClick: (e)=>{
108
+ setAnchor((prev)=>prev ? null : e.currentTarget);
109
+ },
110
+ "aria-expanded": Boolean(anchor),
111
+ "aria-label": getTitle(TooltipProps?.title),
112
+ ...ButtonProps,
113
+ classes: iconButtonClasses
114
+ });
115
+ return /*#__PURE__*/ jsxs(Fragment, {
116
+ children: [
117
+ /*#__PURE__*/ jsxs("div", {
118
+ className: cls('root'),
119
+ ref: ref,
120
+ ...rest,
121
+ children: [
122
+ TooltipProps ? /*#__PURE__*/ jsx(Tooltip, {
123
+ ...TooltipProps,
124
+ children: iconButton
125
+ }) : iconButton,
126
+ Number(BadgeProps?.count) > 0 ? /*#__PURE__*/ jsx(Badge_Badge, {
127
+ ...badgeProps
128
+ }) : null
129
+ ]
130
+ }),
131
+ /*#__PURE__*/ jsx(Menu_Menu, {
132
+ open: Boolean(anchor),
133
+ anchorEl: anchor,
134
+ ...combineProps({
135
+ onClose: handleClose
136
+ }, MenuProps),
137
+ children: /*#__PURE__*/ jsx(MenuList_MenuList, {
138
+ children: menuItems.map(({ ref, ...props }, index)=>/*#__PURE__*/ jsx(TabMenuItem, {
139
+ ...props,
140
+ ref: ref,
141
+ component: MenuItemComponent
142
+ }, props.value || `TabMenuItem-${index}`))
143
+ })
144
+ })
145
+ ]
146
+ });
102
147
  });
103
148
  TabMoreMenu.displayName = 'SuiTabMoreMenu';
104
149
 
105
- const TabScrollButton = forwardRef((props, ref) => {
150
+
151
+
152
+
153
+
154
+
155
+
156
+
157
+
158
+
159
+
160
+
161
+
162
+ const TabScrollButton = /*#__PURE__*/ forwardRef((props, ref)=>{
106
163
  const { classes, className, ButtonProps, direction = 'left', onClick, ...rest } = props;
107
164
  const { mode } = useMode();
108
165
  const cls = useClasses('tab-scroll-button', classes, className);
109
- const iconButtonClasses = useMemo(() => {
166
+ const iconButtonClasses = useMemo(()=>{
110
167
  let combinedClasses = {
111
- root: cls('button'),
168
+ root: cls('button')
112
169
  };
113
170
  if (ButtonProps?.classes) {
114
171
  combinedClasses = combineClasses(combinedClasses, ButtonProps.classes);
115
172
  }
116
173
  return combinedClasses;
117
- }, [ButtonProps?.classes, cls]);
174
+ }, [
175
+ ButtonProps?.classes,
176
+ cls
177
+ ]);
118
178
  const icon = direction === 'left' ? CaretLeftMd : CaretRightMd;
119
- const iconButtonSize = useMemo(() => {
179
+ const iconButtonSize = useMemo(()=>{
120
180
  return mode === 'compact' ? 'medium' : 'large';
121
- }, [mode]);
122
- return (jsx("div", { className: cls('root', {
123
- start: direction === 'left',
124
- }), ref: ref, ...rest, children: jsx(IconButton, { "aria-hidden": "true", role: "presentation", tabIndex: -1, component: "div", color: "secondary", symbol: icon, shape: "circular", variant: "outlined", size: iconButtonSize, background: true, onClick: onClick, ...ButtonProps, classes: iconButtonClasses }) }));
181
+ }, [
182
+ mode
183
+ ]);
184
+ return /*#__PURE__*/ jsx("div", {
185
+ className: cls('root', {
186
+ start: direction === 'left'
187
+ }),
188
+ ref: ref,
189
+ ...rest,
190
+ children: /*#__PURE__*/ jsx(IconButton_IconButton, {
191
+ "aria-hidden": "true",
192
+ role: "presentation",
193
+ tabIndex: -1,
194
+ component: "div",
195
+ color: "secondary",
196
+ symbol: icon,
197
+ shape: "circular",
198
+ variant: "outlined",
199
+ size: iconButtonSize,
200
+ background: true,
201
+ onClick: onClick,
202
+ ...ButtonProps,
203
+ classes: iconButtonClasses
204
+ })
205
+ });
125
206
  });
126
207
  TabScrollButton.displayName = 'SuiTabScrollButton';
127
208
 
209
+
210
+
211
+
212
+
213
+
214
+
215
+
216
+
217
+
218
+
219
+
220
+
221
+
222
+ /* oxlint-disable sonarjs/cognitive-complexity */
223
+
224
+
225
+
226
+
227
+
228
+
229
+
128
230
  function useComputedTabs(props) {
129
- const { variant, value, children, pill, pillGap, onGroupInfoUpdate, floatingUnderlineLeftMotionValue, floatingUnderlineWidthMotionValue, tabListRef, scrollerRef, moreRef, } = props;
231
+ const { variant, value, children, pill, pillGap, onGroupInfoUpdate, floatingUnderlineLeftMotionValue, floatingUnderlineWidthMotionValue, tabListRef, scrollerRef, moreRef } = props;
130
232
  const fontsLoaded = useFontLoaded(variant === 'moreMenu');
131
233
  const prefersReducedMotion = usePrefersReducedMotion();
132
234
  const { externalWindow } = useWindowContext();
133
235
  const ResizeObserverClass = (externalWindow || window).ResizeObserver;
134
236
  const [moreMenuItems, setMoreMenuItems] = useState([]);
237
+ // Render the more button initially to get the offsetWidth to compute
135
238
  const [showMore, setShowMore] = useState(variant === 'moreMenu');
136
239
  const moreBtnWidth = useRef(0);
137
240
  const switchToMoreMenu = useRef(variant === 'moreMenu');
241
+ // Store a ref to visibleTabs and hiddenTabs for data comparison
138
242
  const visibleTabsRef = useRef();
139
243
  const hiddenTabsRef = useRef();
140
244
  const shouldUpdate = useRef(false);
245
+ // Cache children info to reduce render times when computing more menu
141
246
  const tabsChildrenCache = useRef();
142
247
  const { tabsInstanceId } = useInternalTabsContext();
143
- const processedChildren = useMemo(() => {
248
+ const processedChildren = useMemo(()=>{
144
249
  let childIndex = 0;
145
250
  const visibleTabs = new Map();
146
- Children.forEach(children, (child) => {
251
+ Children.forEach(children, (child)=>{
147
252
  if (isValidElement(child)) {
148
- if (process.env.NODE_ENV !== 'production' &&
149
- child.type === React.Fragment) {
253
+ if (process.env.NODE_ENV !== 'production' && child.type === react.Fragment) {
150
254
  logInDev({
151
255
  scope: 'Tabs',
152
256
  level: 'error',
153
257
  message: [
154
258
  "The Tabs component doesn't accept a Fragment as a child.",
155
- 'Consider providing an array instead.',
156
- ].join('\n'),
259
+ 'Consider providing an array instead.'
260
+ ].join('\n')
157
261
  });
158
262
  }
159
263
  const childValue = child.props.value === undefined ? childIndex : child.props.value;
264
+ // Only clone element when necessary: no user-provided id
160
265
  let finalChild = child;
161
266
  if (child.props.id === undefined) {
162
267
  if (process.env.NODE_ENV !== 'production') {
@@ -172,167 +277,214 @@ function useComputedTabs(props) {
172
277
  `<Tab id="unique-tab-id" label="Your label" />`,
173
278
  '',
174
279
  'Unique ids are required for accessibility and correct tab-panel linking.',
175
- 'If no id is provided, each Tab element will be cloned to provide its auto-generated id, which may have a performance cost.',
176
- ].join('\n'),
280
+ 'If no id is provided, each Tab element will be cloned to provide its auto-generated id, which may have a performance cost.'
281
+ ].join('\n')
177
282
  });
178
283
  }
179
284
  const { tabId } = generateTabStableIds(tabsInstanceId, childValue);
180
285
  finalChild = cloneElement(child, {
181
286
  ...child.props,
182
- id: tabId,
287
+ id: tabId
183
288
  });
184
289
  }
185
- visibleTabs.set(childValue, { childIndex, child: finalChild });
290
+ visibleTabs.set(childValue, {
291
+ childIndex,
292
+ child: finalChild
293
+ });
186
294
  childIndex += 1;
187
295
  }
188
296
  });
189
297
  return visibleTabs;
190
- }, [children, tabsInstanceId]);
298
+ }, [
299
+ children,
300
+ tabsInstanceId
301
+ ]);
191
302
  const [visibleTabs, setVisibleTabs] = useState(processedChildren);
192
- const visibleTabsChildren = useMemo(() => {
193
- return Array.from(visibleTabs.entries()).map(([childValue, { child }]) => {
194
- return { ...child, props: { ...child.props, value: childValue } };
195
- });
196
- }, [visibleTabs]);
197
- const prevChildren = usePrevious(() => children);
198
- const cacheTabsChildren = useEventCallback(() => {
199
- if (shouldUpdate.current === 'full')
200
- tabsChildrenCache.current = new Map();
201
- if (!tabListRef.current?.children || !tabsChildrenCache.current)
202
- return;
303
+ const visibleTabsChildren = useMemo(()=>{
304
+ // Remapping Map → array makes these list children; React requires a key.
305
+ return Array.from(visibleTabs.entries()).map(([childValue, { child }])=>({
306
+ ...child,
307
+ key: child.key ?? childValue,
308
+ props: {
309
+ ...child.props,
310
+ value: childValue
311
+ }
312
+ }));
313
+ }, [
314
+ visibleTabs
315
+ ]);
316
+ const prevChildren = usePrevious(()=>children);
317
+ const cacheTabsChildren = useEventCallback(()=>{
318
+ // If this is a full update clear the cache
319
+ if (shouldUpdate.current === 'full') tabsChildrenCache.current = new Map();
320
+ // We can't cache if the tabListRef is not available
321
+ if (!tabListRef.current?.children || !tabsChildrenCache.current) return;
203
322
  const tabsChildren = tabListRef.current?.children;
204
- for (const [childValue, { childIndex, child }] of visibleTabs.entries()) {
323
+ for (const [childValue, { childIndex, child }] of visibleTabs.entries()){
205
324
  const childElement = tabsChildren[childIndex];
206
- if (!child || !childElement)
207
- return;
325
+ if (!child || !childElement) return;
208
326
  tabsChildrenCache.current?.set(childValue, {
327
+ // @ts-ignore
209
328
  child,
210
329
  element: childElement,
211
- width: childElement.offsetWidth,
330
+ width: childElement.offsetWidth
212
331
  });
213
332
  }
214
333
  });
215
- const getSelectedTabElement = useEventCallback(() => {
334
+ const getSelectedTabElement = useEventCallback(()=>{
216
335
  const children = tabListRef.current?.children;
217
- if (!children || children.length === 0 || value === null)
218
- return undefined;
336
+ if (!children || children.length === 0 || value === null) return undefined;
219
337
  let selectedIndex = -1;
220
338
  if (variant === 'moreMenu' && visibleTabsRef.current) {
221
- selectedIndex = Array.from(visibleTabsRef.current).findIndex(([key]) => {
339
+ /**
340
+ * When the variant is `moreMenu`, visibleTabs may have a different
341
+ * order than processed children as some tabs are hidden in the more menu.
342
+ */ selectedIndex = Array.from(visibleTabsRef.current).findIndex(([key])=>{
222
343
  return key === value;
223
344
  });
224
- }
225
- else {
345
+ } else {
226
346
  selectedIndex = visibleTabs.get(value)?.childIndex;
227
347
  }
228
348
  const selectedTabElement = children[selectedIndex];
229
- if (process.env.NODE_ENV !== 'production' &&
230
- selectedTabElement === undefined) {
349
+ if (process.env.NODE_ENV !== 'production' && selectedTabElement === undefined) {
231
350
  logInDev({
232
351
  scope: 'Tabs',
233
352
  message: [
234
353
  `The \`value\` provided to the Tabs component is invalid.`,
235
- `None of the Tabs' children match with "${value}".`,
236
- ].join('\n'),
354
+ `None of the Tabs' children match with "${value}".`
355
+ ].join('\n')
237
356
  });
238
357
  }
358
+ // provide the first tab as default selected tab when value is invalid
239
359
  return selectedTabElement || children[0];
240
360
  });
241
- const computeMoreMenuWithCache = useEventCallback(() => {
242
- if (variant !== 'moreMenu' || !tabsChildrenCache.current)
243
- return;
244
- const width = scrollerRef.current?.offsetWidth || 0;
245
- const visibleWidth = width +
246
- pillGap -
247
- (tabListRef.current ? getHorizontalPadding(tabListRef.current) : 0);
248
- const selectedItemWidth = (value !== null && tabsChildrenCache.current.get(value)?.width) || 0;
249
- const spaceForMoreBtn = moreBtnWidth.current + pillGap;
361
+ // main logic for computing whether show more menu when variant is 'moreMenu'
362
+ const computeMoreMenuWithCache = useEventCallback(()=>{
363
+ if (variant !== 'moreMenu' || !tabsChildrenCache.current) return;
364
+ const width = scrollerRef.current?.offsetWidth || 0; // Includes padding
365
+ const visibleWidth = width + pillGap - (tabListRef.current ? getHorizontalPadding(tabListRef.current) : 0); // Excludes padding
366
+ // The reserved slot must include the gap, like every other tab slot below,
367
+ // otherwise the more button loses its left margin at the overflow threshold
368
+ const selectedItemWidth = value !== null ? (tabsChildrenCache.current.get(value)?.width ?? 0) + pillGap : 0;
369
+ const spaceForMoreBtn = moreBtnWidth.current + pillGap; // more button needs left margin
250
370
  let consumedWidth = spaceForMoreBtn;
251
371
  let isSelectedItemVisible = false;
252
372
  let noWidthForUnselectedTab = false;
253
373
  const visibleItems = new Map();
254
374
  const hiddenItems = new Map();
255
375
  const cache = Array.from(tabsChildrenCache.current);
256
- for (let i = 0; i < cache.length; i++) {
376
+ for(let i = 0; i < cache.length; i++){
257
377
  const [key, itemInfo] = cache[i];
258
378
  const { child, width: itemWidth } = itemInfo;
259
379
  const width = itemWidth + pillGap;
260
- if (noWidthForUnselectedTab && key !== value) {
380
+ /**
381
+ * If there's not enough space to accommodate an unselected tab and
382
+ * the tab isn't selected we'll hide it, aka put it in the more menu.
383
+ */ if (noWidthForUnselectedTab && key !== value) {
261
384
  hiddenItems.set(key, child);
262
385
  continue;
263
386
  }
264
387
  if (isSelectedItemVisible) {
388
+ // Check if this is the last tab in the list
265
389
  if (cache.length === i + 1) {
390
+ // Check if there is enough space to accommodate the tab without the more button
266
391
  if (visibleWidth >= consumedWidth - spaceForMoreBtn + width) {
392
+ // There's enough space available, show the last tab
267
393
  visibleItems.set(key, child);
268
- }
269
- else {
394
+ } else {
395
+ // There's not enough space available, put the last item inside more menu
270
396
  hiddenItems.set(key, child);
271
397
  }
272
- }
273
- else {
398
+ } else {
399
+ // The current item is not the last tab in the list
400
+ // Check if there is enough space to accommodate this tab
274
401
  if (visibleWidth >= consumedWidth + width) {
275
402
  consumedWidth += width;
403
+ // There's enough space available, show this tab in the list
276
404
  visibleItems.set(key, child);
277
- }
278
- else {
405
+ } else {
406
+ // There's not enoguh space available put the tab inside the more menu (hide it)
279
407
  hiddenItems.set(key, child);
280
408
  noWidthForUnselectedTab = true;
281
409
  }
282
410
  }
283
411
  continue;
284
412
  }
413
+ // The selected tab is not visible yet. Check if the current tab is selected
285
414
  if (key === value) {
415
+ // Show the selected tab, it should never be inside the more menu
286
416
  visibleItems.set(key, child);
287
- if (cache.length !== i + 1)
288
- consumedWidth += width;
417
+ // Check if the current tab is not the last one in the list, if it isn't we need to account for its width
418
+ if (cache.length !== i + 1) consumedWidth += width;
289
419
  isSelectedItemVisible = true;
290
420
  continue;
291
421
  }
422
+ // The current tab is not selected. Check if there is enough space for the current tab, the selected tab and more button
292
423
  if (visibleWidth >= consumedWidth + width + selectedItemWidth) {
293
424
  consumedWidth += width;
294
425
  visibleItems.set(key, child);
295
426
  continue;
296
427
  }
428
+ // There's not enough space available. Check if current tab immediately precedes the last selected tab
297
429
  const isSecondToLast = cache.length - 1 === i + 1;
298
- const hasSpaceForLast2Items = visibleWidth >=
299
- consumedWidth - spaceForMoreBtn + width + selectedItemWidth;
430
+ // Check if there is enough space for the current tab and the last selected tab without the more button
431
+ const hasSpaceForLast2Items = visibleWidth >= consumedWidth - spaceForMoreBtn + width + selectedItemWidth;
300
432
  if (isSecondToLast && hasSpaceForLast2Items) {
433
+ // If it's second to last and has enough space, show the tab
301
434
  visibleItems.set(key, child);
302
- }
303
- else {
435
+ } else {
436
+ // Otherwise hide the tab and put it in the more menu
304
437
  hiddenItems.set(key, child);
305
438
  noWidthForUnselectedTab = true;
306
439
  }
307
440
  }
308
441
  if (hiddenItems.size) {
309
442
  setShowMore(true);
310
- setMoreMenuItems(Array.from(hiddenItems.entries()).map(([childValue, child]) => {
311
- return { ...child.props, value: childValue, ref: child.ref };
443
+ setMoreMenuItems(Array.from(hiddenItems.entries()).map(([childValue, child])=>{
444
+ return {
445
+ ...child.props,
446
+ value: childValue,
447
+ ref: child.ref
448
+ };
312
449
  }));
313
- }
314
- else {
450
+ } else {
315
451
  setShowMore(false);
316
452
  }
453
+ // @ts-ignore
317
454
  const newVisibleTabs = new Map();
318
455
  let childIndex = 0;
319
- for (const [childValue, child] of visibleItems.entries()) {
320
- newVisibleTabs.set(childValue, { childIndex, child });
456
+ for (const [childValue, child] of visibleItems.entries()){
457
+ newVisibleTabs.set(childValue, {
458
+ childIndex,
459
+ child
460
+ });
321
461
  childIndex++;
322
462
  }
323
463
  setVisibleTabs(newVisibleTabs);
324
464
  shouldUpdate.current = false;
325
- if (!isEqual([...(visibleTabsRef.current?.keys() || [])], [...visibleItems.keys()]) ||
326
- !isEqual([...(hiddenTabsRef.current?.keys() || [])], [...hiddenItems.keys()])) {
327
- onGroupInfoUpdate?.([...visibleItems.keys()], [...hiddenItems.keys()]);
465
+ // Check if visibleTabs or hiddenTabs has changed
466
+ if (!isEqual([
467
+ ...visibleTabsRef.current?.keys() || []
468
+ ], [
469
+ ...visibleItems.keys()
470
+ ]) || !isEqual([
471
+ ...hiddenTabsRef.current?.keys() || []
472
+ ], [
473
+ ...hiddenItems.keys()
474
+ ])) {
475
+ // If it has changed, invoke onGroupInfoUpdate with the updated group data
476
+ onGroupInfoUpdate?.([
477
+ ...visibleItems.keys()
478
+ ], [
479
+ ...hiddenItems.keys()
480
+ ]);
328
481
  }
329
482
  visibleTabsRef.current = visibleItems;
330
483
  hiddenTabsRef.current = hiddenItems;
331
484
  });
332
- const computeFloatingUnderline = useEventCallback((withoutAnimation = false) => {
485
+ const computeFloatingUnderline = useEventCallback((withoutAnimation = false)=>{
333
486
  const selectedTabElement = getSelectedTabElement();
334
- if (!selectedTabElement)
335
- return;
487
+ if (!selectedTabElement) return;
336
488
  const currentWidth = floatingUnderlineWidthMotionValue.get();
337
489
  const currentLeft = floatingUnderlineLeftMotionValue.get();
338
490
  const targetWidth = selectedTabElement.offsetWidth;
@@ -343,25 +495,28 @@ function useComputedTabs(props) {
343
495
  floatingUnderlineLeftMotionValue.set(targetLeft);
344
496
  return;
345
497
  }
498
+ // Only animate if either value has changed
346
499
  if (currentWidth !== targetWidth || currentLeft !== targetLeft) {
347
- const transition = motionTransition['spring-01-fast'];
500
+ const transition = motionTransition["spring-01-fast"];
348
501
  animate(floatingUnderlineWidthMotionValue, targetWidth, transition);
349
502
  animate(floatingUnderlineLeftMotionValue, targetLeft, transition);
350
503
  }
351
504
  });
352
- useEffect(() => {
353
- if (variant !== 'moreMenu')
354
- return;
505
+ // variant 'moreMenu', check if cache need to be updated when visibleTabs changed
506
+ // also need to update the cache when fonts are loaded after the initial mount
507
+ useEffect(()=>{
508
+ if (variant !== 'moreMenu') return;
355
509
  if (moreRef.current) {
356
510
  moreBtnWidth.current = moreRef.current.offsetWidth;
357
511
  }
358
512
  if (tabsChildrenCache.current) {
359
513
  if (!shouldUpdate.current) {
360
- for (const [childValue, { childIndex: index, child },] of visibleTabs.entries()) {
361
- if (shouldUpdate.current || !child)
362
- continue;
514
+ // Check if the rendered visibleTabs have a different width than the cached tabs
515
+ for (const [childValue, { childIndex: index, child }] of visibleTabs.entries()){
516
+ if (shouldUpdate.current || !child) continue;
363
517
  const cachedWidth = tabsChildrenCache.current?.get(childValue)?.width;
364
518
  const childElement = tabListRef.current?.children[index];
519
+ // If the cached width is different, we should perform a partial update
365
520
  if (cachedWidth !== childElement.offsetWidth) {
366
521
  shouldUpdate.current = 'partial';
367
522
  }
@@ -372,82 +527,122 @@ function useComputedTabs(props) {
372
527
  computeMoreMenuWithCache();
373
528
  }
374
529
  }
375
- }, [visibleTabs, fontsLoaded]);
376
- useEffect(() => {
530
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
531
+ }, [
532
+ visibleTabs,
533
+ fontsLoaded
534
+ ]);
535
+ useEffect(()=>{
377
536
  if (prevChildren && children !== prevChildren) {
378
537
  setVisibleTabs(processedChildren);
379
538
  shouldUpdate.current = 'full';
380
539
  }
381
- }, [children, prevChildren, processedChildren]);
382
- useLayoutEffect(() => {
540
+ }, [
541
+ children,
542
+ prevChildren,
543
+ processedChildren
544
+ ]);
545
+ // initial cache for variant 'moreMenu', used for computing more menu
546
+ useLayoutEffect(()=>{
383
547
  if (switchToMoreMenu.current && tabListRef.current?.children) {
384
548
  switchToMoreMenu.current = false;
549
+ // initial cache of tabsChildrenCache
385
550
  tabsChildrenCache.current = new Map();
386
551
  cacheTabsChildren();
552
+ // initial cache of moreBtnWidth
387
553
  moreBtnWidth.current = moreRef.current?.offsetWidth || 0;
388
554
  computeMoreMenuWithCache();
389
555
  }
390
- }, [showMore]);
391
- useOnReRender(() => {
556
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
557
+ }, [
558
+ showMore
559
+ ]);
560
+ // handle switch variant situation
561
+ useOnReRender(()=>{
392
562
  if (variant !== 'moreMenu') {
393
563
  setShowMore(false);
394
564
  setVisibleTabs(processedChildren);
395
- }
396
- else {
565
+ } else {
397
566
  switchToMoreMenu.current = true;
398
567
  setShowMore(true);
399
568
  }
400
- }, [variant]);
401
- useEffect(() => {
402
- if (variant !== 'moreMenu')
403
- return;
569
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
570
+ }, [
571
+ variant
572
+ ]);
573
+ // Check if we need to update the cache and update the more menu when any tab child is resized
574
+ useEffect(()=>{
575
+ if (variant !== 'moreMenu') return;
404
576
  let initialObservation = true;
405
- const handleResize = throttle((entries) => {
577
+ const handleResize = throttle((entries)=>{
406
578
  if (initialObservation) {
407
- initialObservation = false;
579
+ /**
580
+ * We handle the computation of the more menu after the initial mount,
581
+ * or we re-compute when the `showMore` prop has updated. There's
582
+ * no need to compute here.
583
+ */ initialObservation = false;
408
584
  return;
409
585
  }
410
586
  if (entries) {
587
+ // Partially update the cache before computing the more menu
411
588
  cacheTabsChildren();
412
- if (moreRef.current)
413
- moreBtnWidth.current = moreRef.current.offsetWidth;
589
+ if (moreRef.current) moreBtnWidth.current = moreRef.current.offsetWidth;
414
590
  }
415
591
  computeMoreMenuWithCache();
416
- computeFloatingUnderline(true);
592
+ /**
593
+ * For variants other than moreMenu, we compute the floating underline using a dedicated
594
+ * ResizeObserver for the selected tab. When we're on the moreMenu we already have a resize
595
+ * observer for the tabList, so we don't need to create a dedicated one for the selected tab,
596
+ * then we compute the floating underline as part of the resize event we otherwise use for
597
+ * the more menu.
598
+ */ computeFloatingUnderline(true);
417
599
  }, 200);
418
600
  let resizeObserver;
601
+ // Check if ResizeObserver is supported in this environment
419
602
  if (typeof ResizeObserverClass !== 'undefined') {
420
603
  resizeObserver = new ResizeObserverClass(handleResize);
421
- if (scrollerRef.current)
422
- resizeObserver.observe(scrollerRef.current);
604
+ if (scrollerRef.current) resizeObserver.observe(scrollerRef.current);
423
605
  if (tabListRef && tabListRef.current) {
424
606
  const tabsChildren = tabListRef.current.children;
425
- Array.from(tabsChildren).forEach((child, index) => {
426
- if (pill && index === tabsChildren.length - 1)
427
- return;
428
- if (!pill && index >= tabsChildren.length - 2)
429
- return;
607
+ Array.from(tabsChildren).forEach((child, index)=>{
608
+ // The last child when the pill prop is enabled is the underline element, no need to observe it
609
+ if (pill && index === tabsChildren.length - 1) return;
610
+ // When the pill props is disabled, the last 2 children are the underline and floating underline elements, no need to observe them
611
+ if (!pill && index >= tabsChildren.length - 2) return;
430
612
  resizeObserver?.observe(child);
431
613
  });
432
614
  }
433
615
  }
434
- return () => {
616
+ return ()=>{
435
617
  handleResize.cancel();
436
618
  resizeObserver?.disconnect();
437
619
  };
438
- }, [variant, pill, ResizeObserverClass]);
439
- useEffect(() => {
440
- if (variant === 'moreMenu')
441
- return;
620
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
621
+ }, [
622
+ variant,
623
+ pill,
624
+ ResizeObserverClass
625
+ ]);
626
+ useEffect(()=>{
627
+ // The ResizeObserver for the moreMenu automatically handles floating underline computation
628
+ if (variant === 'moreMenu') return;
442
629
  let initialObservation = true;
443
- const handleSelectedTabResize = throttle(() => {
630
+ const handleSelectedTabResize = throttle(()=>{
444
631
  if (initialObservation) {
445
- initialObservation = false;
632
+ /**
633
+ * We handle the initial computation of the floating underline in the
634
+ * Tabs component after the value has changed, we don't need to compute
635
+ * it here again. This also allows us to distinguish between when the
636
+ * selected tab is resized and when the user selects a different tab,
637
+ * meaning we can apply an instant transition during resizing, but use
638
+ * a spring transition when switching tabs.
639
+ */ initialObservation = false;
446
640
  return;
447
641
  }
448
642
  computeFloatingUnderline(true);
449
643
  }, 16);
450
644
  let selectedTabResizeObserver;
645
+ // Check if ResizeObserver is supported in this environment
451
646
  if (typeof ResizeObserverClass !== 'undefined') {
452
647
  selectedTabResizeObserver = new ResizeObserverClass(handleSelectedTabResize);
453
648
  const selectedTabElement = getSelectedTabElement();
@@ -455,24 +650,35 @@ function useComputedTabs(props) {
455
650
  selectedTabResizeObserver.observe(selectedTabElement);
456
651
  }
457
652
  }
458
- return () => {
653
+ return ()=>{
459
654
  handleSelectedTabResize.cancel();
460
655
  selectedTabResizeObserver?.disconnect();
461
656
  };
462
- }, [variant, value, ResizeObserverClass]);
463
- const prevVariant = usePrevious(() => variant);
464
- useEffect(() => {
657
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
658
+ }, [
659
+ variant,
660
+ value,
661
+ ResizeObserverClass
662
+ ]);
663
+ const prevVariant = usePrevious(()=>variant);
664
+ useEffect(()=>{
665
+ // If only the variant is changed, we need to update the floating underline without animation
465
666
  if (prevVariant !== variant) {
466
667
  computeFloatingUnderline(true);
467
668
  }
468
- }, [variant]);
469
- useEffect(() => {
470
- if (variant === 'moreMenu' &&
471
- value !== null &&
472
- hiddenTabsRef.current?.has(value)) {
669
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
670
+ }, [
671
+ variant
672
+ ]);
673
+ useEffect(()=>{
674
+ if (variant === 'moreMenu' && value !== null && hiddenTabsRef.current?.has(value)) {
675
+ // Re-compute when a hidden tab (i.e. tab in the more menu) is selected
473
676
  computeMoreMenuWithCache();
474
677
  }
475
- }, [value]);
678
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
679
+ }, [
680
+ value
681
+ ]);
476
682
  return {
477
683
  visibleTabsChildren,
478
684
  showMore,
@@ -480,7 +686,7 @@ function useComputedTabs(props) {
480
686
  processedChildren,
481
687
  getSelectedTabElement,
482
688
  computeMoreMenuWithCache,
483
- computeFloatingUnderline,
689
+ computeFloatingUnderline
484
690
  };
485
691
  }
486
692
  function getHorizontalPadding(element) {
@@ -490,25 +696,36 @@ function getHorizontalPadding(element) {
490
696
  return paddingLeft + paddingRight;
491
697
  }
492
698
 
699
+
700
+
701
+
702
+
703
+
704
+
705
+
706
+
707
+
493
708
  const THRESHOLD_FOR_SUB_PIXEL_CALCULATION = 0.5;
494
- const useTabsScroller = ({ enable, scrollerRef, tabListRef, scroll, ScrollButtonStartProps, ScrollButtonEndProps, }) => {
709
+ /**
710
+ * This `useTabsScroller` hook manages the state and behavior of scroll buttons at both ends of the tab list (start and end) when the tab list exceeds the visible container width
711
+ */ const useTabsScroller = ({ enable, scrollerRef, tabListRef, scroll, ScrollButtonStartProps, ScrollButtonEndProps })=>{
495
712
  const [displayStartScroll, setDisplayStartScroll] = useState(false);
496
713
  const [displayEndScroll, setDisplayEndScroll] = useState(false);
497
714
  const { externalWindow } = useWindowContext();
498
715
  const ResizeObserverClass = (externalWindow || window).ResizeObserver;
499
- useLayoutEffect(() => {
500
- if (!enable)
501
- return;
502
- const checkScroll = throttle(() => {
503
- if (!scrollerRef.current)
504
- return;
716
+ useLayoutEffect(()=>{
717
+ if (!enable) return;
718
+ const checkScroll = throttle(()=>{
719
+ if (!scrollerRef.current) return;
505
720
  const { scrollLeft, scrollWidth, clientWidth } = scrollerRef.current;
506
721
  const maxScrollLeft = scrollWidth - clientWidth;
507
722
  setDisplayStartScroll(scrollLeft > 0);
508
723
  setDisplayEndScroll(maxScrollLeft - scrollLeft > THRESHOLD_FOR_SUB_PIXEL_CALCULATION);
509
724
  }, 100);
725
+ // add scroll event listener
510
726
  const currentTabsRef = scrollerRef.current;
511
727
  currentTabsRef?.addEventListener('scroll', checkScroll);
728
+ // ResizeObserver for tabs list
512
729
  let resizeObserver;
513
730
  if (typeof ResizeObserverClass !== 'undefined') {
514
731
  resizeObserver = new ResizeObserverClass(checkScroll);
@@ -516,26 +733,31 @@ const useTabsScroller = ({ enable, scrollerRef, tabListRef, scroll, ScrollButton
516
733
  resizeObserver.observe(currentTabsRef);
517
734
  }
518
735
  }
519
- checkScroll();
520
- return () => {
736
+ checkScroll(); // Initial check
737
+ return ()=>{
521
738
  currentTabsRef?.removeEventListener('scroll', checkScroll);
522
739
  checkScroll.cancel();
740
+ // Disconnect the ResizeObserver on cleanup
523
741
  resizeObserver?.disconnect();
524
742
  };
525
- }, [enable, scrollerRef, ResizeObserverClass]);
526
- const moveTabsScroll = useCallback((delta) => {
527
- const scrollValue = scrollerRef.current
528
- ? scrollerRef.current.scrollLeft + delta * 1
529
- : 0;
743
+ }, [
744
+ enable,
745
+ scrollerRef,
746
+ ResizeObserverClass
747
+ ]);
748
+ const moveTabsScroll = useCallback((delta)=>{
749
+ const scrollValue = scrollerRef.current ? scrollerRef.current.scrollLeft + delta * 1 : 0;
530
750
  scroll(scrollValue, 'neutral-01-slow');
531
- }, [scroll, scrollerRef]);
532
- const getScrollSize = useCallback(() => {
533
- if (!scrollerRef.current || !tabListRef.current)
534
- return 0;
751
+ }, [
752
+ scroll,
753
+ scrollerRef
754
+ ]);
755
+ const getScrollSize = useCallback(()=>{
756
+ if (!scrollerRef.current || !tabListRef.current) return 0;
535
757
  const containerSize = scrollerRef.current.clientWidth;
536
758
  let totalSize = 0;
537
759
  const children = Array.from(tabListRef.current.children);
538
- for (let i = 0; i < children.length; i += 1) {
760
+ for(let i = 0; i < children.length; i += 1){
539
761
  const tab = children[i];
540
762
  if (totalSize + tab.clientWidth > containerSize) {
541
763
  if (i === 0) {
@@ -546,33 +768,65 @@ const useTabsScroller = ({ enable, scrollerRef, tabListRef, scroll, ScrollButton
546
768
  totalSize += tab.clientWidth;
547
769
  }
548
770
  return totalSize;
549
- }, [scrollerRef, tabListRef]);
550
- const handleStartScrollClick = useCallback(() => {
771
+ }, [
772
+ scrollerRef,
773
+ tabListRef
774
+ ]);
775
+ const handleStartScrollClick = useCallback(()=>{
551
776
  moveTabsScroll(-getScrollSize());
552
- }, [moveTabsScroll, getScrollSize]);
553
- const handleEndScrollClick = useCallback(() => {
777
+ }, [
778
+ moveTabsScroll,
779
+ getScrollSize
780
+ ]);
781
+ const handleEndScrollClick = useCallback(()=>{
554
782
  moveTabsScroll(getScrollSize());
555
- }, [moveTabsScroll, getScrollSize]);
556
- return useMemo(() => ({
557
- scrollButtonStart: enable && displayStartScroll ? (jsx(TabScrollButton, { direction: 'left', onClick: handleStartScrollClick, ButtonProps: ScrollButtonStartProps })) : null,
558
- scrollButtonEnd: enable && displayEndScroll ? (jsx(TabScrollButton, { direction: 'right', onClick: handleEndScrollClick, ButtonProps: ScrollButtonEndProps })) : null,
559
- }), [
783
+ }, [
784
+ moveTabsScroll,
785
+ getScrollSize
786
+ ]);
787
+ return useMemo(()=>({
788
+ scrollButtonStart: enable && displayStartScroll ? /*#__PURE__*/ jsx(TabScrollButton, {
789
+ direction: 'left',
790
+ onClick: handleStartScrollClick,
791
+ ButtonProps: ScrollButtonStartProps
792
+ }) : null,
793
+ scrollButtonEnd: enable && displayEndScroll ? /*#__PURE__*/ jsx(TabScrollButton, {
794
+ direction: 'right',
795
+ onClick: handleEndScrollClick,
796
+ ButtonProps: ScrollButtonEndProps
797
+ }) : null
798
+ }), [
560
799
  enable,
561
800
  displayStartScroll,
562
801
  handleStartScrollClick,
563
802
  ScrollButtonStartProps,
564
803
  displayEndScroll,
565
804
  handleEndScrollClick,
566
- ScrollButtonEndProps,
805
+ ScrollButtonEndProps
567
806
  ]);
568
807
  };
569
808
 
570
- var Tabs$1 = {"sui-tabs-root":"sui-tabs-root","sui-tabs-large":"sui-tabs-large","sui-tabs-scroller":"sui-tabs-scroller","sui-tabs-scrollable":"sui-tabs-scrollable","sui-tab":"sui-tab","sui-tabs-tab-list":"sui-tabs-tab-list","sui-tabs-underline":"sui-tabs-underline","sui-tabs-indicator":"sui-tabs-indicator","sui-tabs-compact":"sui-tabs-compact","sui-tabs-pill":"sui-tabs-pill","sui-tab-more-menu-root":"sui-tab-more-menu-root","sui-tab-more-menu-button":"sui-tab-more-menu-button","sui-tabs-scroll-left":"sui-tabs-scroll-left","sui-tabs-scroll-right":"sui-tabs-scroll-right","sui-tabs-scroll-both":"sui-tabs-scroll-both","sui-tabs-floating-underline":"sui-tabs-floating-underline","sui-tab-more-menu-badge-root":"sui-tab-more-menu-badge-root","sui-badge-dot":"sui-badge-dot","sui-badge-content":"sui-badge-content","sui-tab-more-menu-pill-badge":"sui-tab-more-menu-pill-badge","sui-tab-scroll-button-root":"sui-tab-scroll-button-root","sui-tab-scroll-button-start":"sui-tab-scroll-button-start","sui-compact":"sui-compact"};
809
+ // extracted by css-extract-rspack-plugin
810
+ /* export default */ var Tabs = ({"sui-tabs-root":"sui-tabs-root","sui-tabs-large":"sui-tabs-large","sui-tabs-scroller":"sui-tabs-scroller","sui-tabs-scrollable":"sui-tabs-scrollable","sui-tab":"sui-tab","sui-tabs-tab-list":"sui-tabs-tab-list","sui-tabs-underline":"sui-tabs-underline","sui-tabs-indicator":"sui-tabs-indicator","sui-tabs-compact":"sui-tabs-compact","sui-tabs-pill":"sui-tabs-pill","sui-tab-more-menu-root":"sui-tab-more-menu-root","sui-tab-more-menu-button":"sui-tab-more-menu-button","sui-tabs-scroll-left":"sui-tabs-scroll-left","sui-tabs-scroll-right":"sui-tabs-scroll-right","sui-tabs-scroll-both":"sui-tabs-scroll-both","sui-tabs-floating-underline":"sui-tabs-floating-underline","sui-tab-more-menu-badge-root":"sui-tab-more-menu-badge-root","sui-badge-dot":"sui-badge-dot","sui-badge-content":"sui-badge-content","sui-tab-more-menu-pill-badge":"sui-tab-more-menu-pill-badge","sui-tab-scroll-button-root":"sui-tab-scroll-button-root","sui-tab-scroll-button-start":"sui-tab-scroll-button-start","sui-compact":"sui-compact"});
811
+
812
+
813
+
814
+
815
+
816
+
817
+
818
+
819
+
820
+
821
+
571
822
 
572
823
  const DEFAULT_PILL_GAP = 4;
573
- const Tabs = forwardRef((inProps, ref) => {
574
- const props = useThemeProps({ props: inProps, name: 'Tabs' });
575
- const { classes, className, children, onBlur, onFocus, variant = 'standard', onGroupInfoUpdate, MoreMenuProps, pill, pillGap: pillGapProp = DEFAULT_PILL_GAP, color = 'default', size = 'medium', ScrollButtonStartProps, ScrollButtonEndProps, enableScrollButtons = true, ...rest } = props;
824
+ const Tabs_Tabs = /*#__PURE__*/ forwardRef((inProps, ref)=>{
825
+ const props = useThemeProps({
826
+ props: inProps,
827
+ name: 'Tabs'
828
+ });
829
+ const { classes, className, children, variant = 'standard', onGroupInfoUpdate, MoreMenuProps, pill, pillGap: pillGapProp = DEFAULT_PILL_GAP, color = 'default', size = 'medium', ScrollButtonStartProps, ScrollButtonEndProps, enableScrollButtons = true, ...rest } = props;
576
830
  const pillGap = pill ? pillGapProp : 0;
577
831
  const tabsRef = useRef(null);
578
832
  const scrollerRef = useRef(null);
@@ -583,15 +837,15 @@ const Tabs = forwardRef((inProps, ref) => {
583
837
  const floatingUnderlineWidthMotionValue = useMotionValue(0);
584
838
  const floatingUnderlineLeftMotionValue = useMotionValue(0);
585
839
  const floatingUnderlineOpacityMotionValue = useMotionValue(1);
586
- const floatingUnderlineTransition = useMotionSafeTransition(motionTransition['spring-01-fast']);
840
+ const floatingUnderlineTransition = useMotionSafeTransition(motionTransition["spring-01-fast"]);
587
841
  const prefersReducedMotion = usePrefersReducedMotion();
588
842
  const cls = useClassesWithMode('tabs', classes, className);
589
843
  const { onGroupInfoUpdate: groupInfoUpdateHandler, ...restProps } = props;
590
- const { getRootProps, contextValue, selectedValue: value, } = useTabsList({
844
+ const { getRootProps, contextValue, selectedValue: value } = useTabsList({
591
845
  ...restProps,
592
- rootRef,
846
+ rootRef
593
847
  });
594
- const { processedChildren, visibleTabsChildren, showMore, moreMenuItems, getSelectedTabElement, computeFloatingUnderline, } = useComputedTabs({
848
+ const { processedChildren, visibleTabsChildren, showMore, moreMenuItems, getSelectedTabElement, computeFloatingUnderline } = useComputedTabs({
595
849
  variant,
596
850
  value,
597
851
  children,
@@ -601,13 +855,14 @@ const Tabs = forwardRef((inProps, ref) => {
601
855
  floatingUnderlineWidthMotionValue,
602
856
  tabListRef,
603
857
  scrollerRef,
604
- moreRef,
858
+ moreRef
605
859
  });
606
- const getTabsMeta = useEventCallback(() => {
860
+ const getTabsMeta = useEventCallback(()=>{
607
861
  const tabsNode = scrollerRef.current;
608
862
  let tabsMeta;
609
863
  if (tabsNode) {
610
864
  const rect = tabsNode.getBoundingClientRect();
865
+ // create a new object with ClientRect class props + scrollLeft
611
866
  tabsMeta = {
612
867
  clientWidth: tabsNode.clientWidth,
613
868
  scrollLeft: tabsNode.scrollLeft,
@@ -616,7 +871,7 @@ const Tabs = forwardRef((inProps, ref) => {
616
871
  top: rect.top,
617
872
  bottom: rect.bottom,
618
873
  left: rect.left,
619
- right: rect.right,
874
+ right: rect.right
620
875
  };
621
876
  }
622
877
  let tabMeta;
@@ -625,6 +880,7 @@ const Tabs = forwardRef((inProps, ref) => {
625
880
  if (tab) {
626
881
  const rect = tab.getBoundingClientRect();
627
882
  tabMeta = {
883
+ // Use offsetWidth/offsetHeight to negate any transforms that might be applied
628
884
  height: tab.offsetHeight,
629
885
  width: tab.offsetWidth,
630
886
  x: rect.x,
@@ -632,47 +888,50 @@ const Tabs = forwardRef((inProps, ref) => {
632
888
  top: rect.top,
633
889
  right: rect.right,
634
890
  bottom: rect.bottom,
635
- left: rect.left,
891
+ left: rect.left
636
892
  };
637
893
  }
638
894
  }
639
- return { tabsMeta, tabMeta };
895
+ return {
896
+ tabsMeta,
897
+ tabMeta
898
+ };
640
899
  });
641
900
  const scrollStart = 'scrollLeft';
642
901
  const start = 'left';
643
902
  const end = 'right';
644
- const scroll = (scrollValue, transitionType) => {
645
- if (!scrollerRef.current)
646
- return;
903
+ const scroll = (scrollValue, transitionType)=>{
904
+ if (!scrollerRef.current) return;
647
905
  const from = scrollerRef.current[scrollStart];
648
906
  const to = Number(Number.parseFloat(scrollValue.toString()).toFixed(2));
649
907
  if (from.toFixed(2) === to.toFixed(2)) {
650
908
  return;
651
909
  }
652
910
  if (transitionType === null || prefersReducedMotion) {
911
+ // if transitionType is null or prefersReducedMotion, set the scroll value without animation
653
912
  scrollerRef.current[scrollStart] = to;
654
913
  return;
655
914
  }
656
915
  const transition = motionTransition[transitionType ? transitionType : 'haste-01-fast'];
657
916
  animate(from, to, {
658
917
  ...transition,
659
- onUpdate: (value) => {
660
- if (!scrollerRef.current)
661
- return;
918
+ onUpdate: (value)=>{
919
+ if (!scrollerRef.current) return;
662
920
  scrollerRef.current[scrollStart] = value;
663
- },
921
+ }
664
922
  });
665
923
  };
666
- const scrollSelectedIntoView = useEventCallback((noAnimation) => {
924
+ const scrollSelectedIntoView = useEventCallback((noAnimation)=>{
667
925
  const { tabsMeta, tabMeta } = getTabsMeta();
668
926
  if (!tabMeta || !tabsMeta) {
669
927
  return;
670
928
  }
929
+ // Check if the left side of the tab is out of view
671
930
  if (tabMeta[start] < tabsMeta[start]) {
672
931
  const nextScrollStart = tabsMeta[scrollStart] + (tabMeta[start] - tabsMeta[start]);
673
932
  scroll(nextScrollStart, noAnimation ? null : undefined);
674
- }
675
- else if (tabMeta[end] > tabsMeta[end]) {
933
+ // Check if the right side of the tab is out of view
934
+ } else if (tabMeta[end] > tabsMeta[end]) {
676
935
  const nextScrollStart = tabsMeta[scrollStart] + Math.abs(tabMeta[end] - tabsMeta[end]);
677
936
  scroll(nextScrollStart, noAnimation ? null : undefined);
678
937
  }
@@ -683,48 +942,114 @@ const Tabs = forwardRef((inProps, ref) => {
683
942
  tabListRef,
684
943
  scroll,
685
944
  ScrollButtonStartProps,
686
- ScrollButtonEndProps,
945
+ ScrollButtonEndProps
687
946
  });
688
947
  const prevValueAfterChildrenUpdate = useRef(value);
689
948
  const prevVisibleTabsChildren = useRef(visibleTabsChildren);
690
- useEffect(() => {
949
+ useEffect(()=>{
691
950
  const noAnimationWhenFirstRender = floatingUnderlineWidthMotionValue.get() === 0;
692
951
  if (variant !== 'moreMenu') {
693
- scrollSelectedIntoView(noAnimationWhenFirstRender);
952
+ /**
953
+ * Invoke scrollSelectedIntoView when visibleTabsChildren has been updated or the selected
954
+ * tab has changed. It will be updated when the variant is switched from `moreMenu`
955
+ * to another value. If the variant is `moreMenu`, `visibleTabsChildren` will also be
956
+ * updated when resized.
957
+ */ scrollSelectedIntoView(noAnimationWhenFirstRender);
694
958
  }
695
- const noAnimationWhenNoValueChange = prevVisibleTabsChildren.current !== visibleTabsChildren &&
696
- prevValueAfterChildrenUpdate.current === value;
959
+ // If the visibleTabsChildren has been updated but selected tab has not changed,
960
+ // we don't need to animate the floating underline
961
+ const noAnimationWhenNoValueChange = prevVisibleTabsChildren.current !== visibleTabsChildren && prevValueAfterChildrenUpdate.current === value;
697
962
  if (prevVisibleTabsChildren.current !== visibleTabsChildren) {
698
963
  prevVisibleTabsChildren.current = visibleTabsChildren;
699
964
  prevValueAfterChildrenUpdate.current = value;
700
965
  }
701
966
  computeFloatingUnderline(noAnimationWhenFirstRender || noAnimationWhenNoValueChange);
702
- }, [visibleTabsChildren, value]);
703
- const tabsContextValue = useMemo(() => ({
967
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
968
+ }, [
969
+ visibleTabsChildren,
970
+ value
971
+ ]);
972
+ const tabsContextValue = useMemo(()=>({
973
+ pill,
974
+ pillGap,
975
+ color,
976
+ size,
977
+ setFloatingUnderlineVisibility: (isVisible)=>{
978
+ floatingUnderlineOpacityMotionValue.set(isVisible ? 1 : 0);
979
+ }
980
+ }), [
981
+ floatingUnderlineOpacityMotionValue,
704
982
  pill,
705
983
  pillGap,
706
984
  color,
707
- size,
708
- setFloatingUnderlineVisibility: (isVisible) => {
709
- floatingUnderlineOpacityMotionValue.set(isVisible ? 1 : 0);
710
- },
711
- }), [floatingUnderlineOpacityMotionValue, pill, pillGap, color, size]);
985
+ size
986
+ ]);
712
987
  if (!processedChildren.size) {
713
988
  return null;
714
989
  }
715
- return (jsx(TabsListProvider, { value: contextValue, children: jsx(TabsContext.Provider, { value: tabsContextValue, children: jsxs("div", { className: cls('root', {
990
+ return /*#__PURE__*/ jsx(TabsListProvider, {
991
+ value: contextValue,
992
+ children: /*#__PURE__*/ jsx(TabsContext.Provider, {
993
+ value: tabsContextValue,
994
+ children: /*#__PURE__*/ jsxs("div", {
995
+ className: cls('root', {
716
996
  pill,
717
997
  scrollable: variant === 'scrollable',
718
998
  compact: variant === 'moreMenu',
719
999
  'scroll-left': !!scrollButtonStart,
720
1000
  'scroll-right': !!scrollButtonEnd,
721
- 'scroll-both': !!(scrollButtonStart && scrollButtonEnd),
722
- }, size), ...rest, ...getRootProps(), children: [scrollButtonStart, jsx("div", { className: cls('scroller'), ref: scrollerRef, children: jsxs("div", { className: cls('tab-list'), ref: tabListRef, children: [visibleTabsChildren, showMore && (jsx(TabMoreMenu, { menuItems: moreMenuItems, ...MoreMenuProps, ref: tabMoreMenuRef })), jsx("div", { className: cls('underline') }), !pill && (jsx(motion.div, { style: {
1001
+ 'scroll-both': !!(scrollButtonStart && scrollButtonEnd)
1002
+ }, size),
1003
+ ...getRootProps(rest),
1004
+ children: [
1005
+ scrollButtonStart,
1006
+ /*#__PURE__*/ jsx("div", {
1007
+ className: cls('scroller'),
1008
+ ref: scrollerRef,
1009
+ children: /*#__PURE__*/ jsxs("div", {
1010
+ className: cls('tab-list'),
1011
+ ref: tabListRef,
1012
+ children: [
1013
+ visibleTabsChildren,
1014
+ showMore && /*#__PURE__*/ jsx(TabMoreMenu, {
1015
+ menuItems: moreMenuItems,
1016
+ ...MoreMenuProps,
1017
+ ref: tabMoreMenuRef
1018
+ }),
1019
+ /*#__PURE__*/ jsx("div", {
1020
+ className: cls('underline')
1021
+ }),
1022
+ !pill && /*#__PURE__*/ jsx(motion.div, {
1023
+ style: {
723
1024
  left: floatingUnderlineLeftMotionValue,
724
1025
  width: floatingUnderlineWidthMotionValue,
725
- opacity: floatingUnderlineOpacityMotionValue,
726
- }, transition: floatingUnderlineTransition, className: cls('floating-underline') }))] }) }), scrollButtonEnd] }) }) }));
1026
+ opacity: floatingUnderlineOpacityMotionValue
1027
+ },
1028
+ transition: floatingUnderlineTransition,
1029
+ className: cls('floating-underline')
1030
+ })
1031
+ ]
1032
+ })
1033
+ }),
1034
+ scrollButtonEnd
1035
+ ]
1036
+ })
1037
+ })
1038
+ });
727
1039
  });
728
- Tabs.displayName = 'SuiTabs';
1040
+ Tabs_Tabs.displayName = 'SuiTabs';
1041
+
1042
+
1043
+
1044
+
1045
+
1046
+
1047
+
1048
+
1049
+
1050
+
1051
+
1052
+
729
1053
 
730
- export { TabMoreMenu, TabScrollButton, Tabs, TabsContext, Tabs$1 as tabsStyle, useComputedTabs, useTabsContext, useTabsScroller };
1054
+ export { TabMoreMenu, TabScrollButton, Tabs as tabsStyle, Tabs_Tabs as Tabs, useComputedTabs, useTabsScroller };
1055
+ export { TabsContext, useTabsContext } from "./chunks/8809.js";