@ringcentral/spring-ui 1.7.0 → 1.8.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.
- package/Alert.js +3 -3
- package/Announcement.js +1 -1
- package/Autocomplete.js +174 -236
- package/Avatar.js +27 -13
- package/BottomNavigation.js +0 -3
- package/Checkbox.js +0 -2
- package/DatePicker.js +5 -13
- package/DateUtilsContext.js +0 -1
- package/Dialer.js +2 -50
- package/Dialog.js +4 -4
- package/Dropdown.js +0 -7
- package/FocusTrap.js +0 -32
- package/InlineEditable.js +0 -4
- package/Link.js +1 -1
- package/ListItem.js +1 -1
- package/ListNavigation.js +0 -6
- package/Menu.js +1 -1
- package/MenuDivider.js +2 -2
- package/MenuFooter.js +4 -4
- package/MenuHeader.js +4 -4
- package/MenuItem.js +1 -1
- package/MenuItemText.js +1 -1
- package/PageHeader.js +6 -4
- package/Popper.js +0 -1
- package/Rating.js +0 -5
- package/SingleFilter.js +0 -1
- package/Slider.js +1 -4
- package/Snackbar.js +0 -14
- package/SortableListItem.js +0 -1
- package/SplitButton.js +1 -3
- package/StatusIndicator.js +1 -1
- package/SubMenu.js +0 -4
- package/SwipeableDrawer.js +8 -146
- package/Switch.js +1 -4
- package/Tab.js +7 -8
- package/TabContext.js +0 -5
- package/TableBody.js +1 -1
- package/TableCell.js +0 -6
- package/TableRow.js +0 -1
- package/Tabs.js +20 -118
- package/Text.js +2 -4
- package/TimePicker.js +7 -46
- package/VirtualizedList.js +2 -30
- package/chunks/Alert.js +8 -7
- package/chunks/BottomNavigationItem.js +0 -1
- package/chunks/Button.js +0 -1
- package/chunks/Chip.js +0 -5
- package/chunks/Drawer.js +1 -30
- package/chunks/ListItem.js +3 -6
- package/chunks/Menu.js +3 -3
- package/chunks/MenuDivider.js +2 -3
- package/chunks/MenuItemText.js +3 -3
- package/chunks/MenuList.js +0 -3
- package/chunks/PickerTextField.js +0 -1
- package/chunks/Popover.js +0 -5
- package/chunks/Select.js +2 -39
- package/chunks/Squircle.js +0 -7
- package/chunks/StatusIndicator.js +1 -0
- package/chunks/StepIcon.js +1 -3
- package/chunks/StepperContext.js +0 -7
- package/chunks/Tooltip.js +0 -36
- package/chunks/VirtualizedMenu.js +2 -78
- package/chunks/getFade.js +2 -0
- package/chunks/useFocusTrapStack.js +0 -8
- package/chunks/useHelperTextId.js +0 -24
- package/chunks/useListNavigation.js +2 -17
- package/chunks/useMenuItemSelect.js +6 -19
- package/chunks/useMotionSafeTransition.js +0 -4
- package/chunks/useNestedParentMenu.js +0 -2
- package/chunks/usePrefersReducedMotion.js +0 -10
- package/chunks/useTooltipForceHide.js +0 -4
- package/chunks/useTrayNavigate.js +0 -1
- package/index.css +392 -120
- package/index.js +1 -1
- package/package.json +4 -4
- package/src/Accordion/Accordion.type.d.ts +0 -21
- package/src/AccordionHeader/AccordionHeader.type.d.ts +0 -14
- package/src/Alert/Alert.type.d.ts +0 -32
- package/src/Animation/components/ExpandCollapseCaret/ExpandCollapseCaret.d.ts +0 -4
- package/src/Animation/components/ShowHideEye/ShowHideEye.d.ts +0 -4
- package/src/Animation/hooks/useMotionSafeTransition/useMotionSafeTransition.d.ts +0 -4
- package/src/Autocomplete/Autocomplete.d.ts +0 -5
- package/src/Autocomplete/Autocomplete.type.d.ts +0 -84
- package/src/Autocomplete/SuggestionList/SuggestionList.d.ts +5 -89
- package/src/Autocomplete/SuggestionList/SuggestionListItem.d.ts +0 -2
- package/src/Autocomplete/SuggestionList/utils/SuggestionListItem.d.ts +1 -13
- package/src/Autocomplete/SuggestionList/utils/useDynamicHeight.d.ts +0 -6
- package/src/Autocomplete/SuggestionList/utils/useHighlightScroll.d.ts +0 -20
- package/src/Autocomplete/SuggestionList/utils/useSuggestionList.d.ts +3 -41
- package/src/Autocomplete/SuggestionList/utils/useSuggestionListGroup.d.ts +0 -49
- package/src/Autocomplete/useAutocomplete.d.ts +1 -62
- package/src/Autocomplete/useAutocompleteTag.d.ts +0 -33
- package/src/Avatar/Avatar.type.d.ts +0 -58
- package/src/AvatarGroup/AvatarGroup.type.d.ts +0 -3
- package/src/Backdrop/Backdrop.type.d.ts +0 -4
- package/src/Badge/Badge.type.d.ts +0 -33
- package/src/Block/Block.type.d.ts +0 -24
- package/src/BlockHeader/BlockHeader.type.d.ts +0 -5
- package/src/BottomNavigation/BottomNavigation.type.d.ts +0 -34
- package/src/BottomNavigationItem/BottomNavigationItem.type.d.ts +0 -39
- package/src/Button/Button.type.d.ts +0 -30
- package/src/CallButton/CallButton.type.d.ts +0 -4
- package/src/Checkbox/Checkbox.type.d.ts +0 -17
- package/src/Chip/Chip.type.d.ts +0 -41
- package/src/CircularProgressIndicator/CircularProgressIndicator.type.d.ts +0 -19
- package/src/DatePicker/Calendar.d.ts +1 -20
- package/src/DatePicker/DatePicker.type.d.ts +0 -18
- package/src/DatePicker/DatePickerHeader.d.ts +1 -12
- package/src/DatePicker/Day.d.ts +0 -7
- package/src/DatePicker/Year.d.ts +0 -6
- package/src/DatePicker/Years.d.ts +0 -7
- package/src/Dialer/DialDelete/DialDelete.d.ts +0 -3
- package/src/Dialer/DialPad/DialPad.d.ts +0 -106
- package/src/Dialer/DialPad/utils/types.d.ts +0 -5
- package/src/Dialer/DialPad/utils/useDialKeyboard.d.ts +0 -5
- package/src/Dialer/DialPad/utils/useKeyAudio.d.ts +0 -9
- package/src/Dialer/DialPadButton/DialPadButton.d.ts +0 -14
- package/src/Dialer/DialTextField/DialTextField.d.ts +0 -23
- package/src/Dialer/DialTextField/utils/getDialPadValueOnlyRegex.d.ts +0 -3
- package/src/Dialer/DialTextField/utils/useFixedEndSelection.d.ts +0 -3
- package/src/Dialog/Dialog.type.d.ts +0 -11
- package/src/Divider/Divider.type.d.ts +0 -17
- package/src/DragHandle/DragHandle.type.d.ts +0 -4
- package/src/Drawer/Drawer.d.ts +0 -28
- package/src/Drawer/Drawer.type.d.ts +0 -84
- package/src/Dropdown/Dropdown.type.d.ts +0 -64
- package/src/EmptyState/EmptyState.type.d.ts +0 -12
- package/src/FabButton/FabButton.type.d.ts +0 -5
- package/src/FocusTrap/FocusTrap.d.ts +0 -38
- package/src/FocusTrap/useFocusTrapStack.d.ts +0 -9
- package/src/FormField/FormField.type.d.ts +0 -26
- package/src/FormField/useHelperTextId.d.ts +0 -25
- package/src/FormLabel/FormLabel.type.d.ts +0 -14
- package/src/Icon/Icon.type.d.ts +0 -15
- package/src/IconButton/IconButton.type.d.ts +0 -30
- package/src/IconButton/IconButtonLabel.type.d.ts +0 -3
- package/src/IconButtonGroup/IconButtonGroup.type.d.ts +0 -8
- package/src/InlineEditable/InlineEditable.type.d.ts +0 -75
- package/src/LinearProgressIndicator/LinearProgressIndicator.type.d.ts +0 -31
- package/src/Link/Link.classes.d.ts +1 -1
- package/src/Link/Link.type.d.ts +1 -10
- package/src/ListItem/ListItem.type.d.ts +0 -41
- package/src/ListItemText/ListItemText.type.d.ts +0 -21
- package/src/ListNavigation/useListNavigation.d.ts +0 -16
- package/src/Menu/Menu.type.d.ts +0 -10
- package/src/MenuFooter/MenuFooter.type.d.ts +0 -4
- package/src/MenuHeader/MenuHeader.type.d.ts +0 -10
- package/src/MenuItem/MenuItem.type.d.ts +0 -19
- package/src/MenuItem/MenuItemSelectContext.d.ts +0 -3
- package/src/MenuItem/useMenuItemSelect.d.ts +0 -21
- package/src/MenuItemText/MenuItemText.type.d.ts +0 -17
- package/src/MenuList/MenuList.type.d.ts +0 -4
- package/src/MenuList/MenuListContext.d.ts +0 -6
- package/src/Modal/InnerModal.type.d.ts +0 -5
- package/src/Modal/Modal.type.d.ts +0 -11
- package/src/Modal/ModalContext.d.ts +0 -4
- package/src/Option/Option.type.d.ts +0 -3
- package/src/Overlap/Overlap.type.d.ts +0 -11
- package/src/PageHeader/PageHeader.type.d.ts +0 -4
- package/src/PickerTextField/PickerTextField.type.d.ts +0 -10
- package/src/Popover/Popover.type.d.ts +0 -29
- package/src/Popper/Popper.type.d.ts +0 -61
- package/src/Radio/Radio.type.d.ts +0 -5
- package/src/RadioGroup/RadioGroup.type.d.ts +0 -4
- package/src/Rating/Rating.type.d.ts +0 -74
- package/src/Select/Select.type.d.ts +0 -84
- package/src/SingleFilter/FilterButton/FilterButton.type.d.ts +0 -16
- package/src/SingleFilter/SingleFilter.type.d.ts +0 -26
- package/src/Skeleton/Skeleton.type.d.ts +0 -1
- package/src/Skeleton/SkeletonContainer/SkeletonContainer.classes.d.ts +1 -1
- package/src/Slider/Slider.classes.d.ts +1 -5
- package/src/Slider/Slider.type.d.ts +0 -104
- package/src/Snackbar/Snackbar.type.d.ts +0 -18
- package/src/SplitButton/SplitButton.type.d.ts +0 -21
- package/src/Squircle/Squircle.type.d.ts +0 -3
- package/src/StatusIndicator/StatusIndicator.classes.d.ts +1 -1
- package/src/StatusIndicator/StatusIndicator.type.d.ts +1 -9
- package/src/Step/Step.type.d.ts +0 -29
- package/src/Step/StepContext.d.ts +0 -7
- package/src/StepButton/StepButton.type.d.ts +0 -15
- package/src/StepContent/StepContent.type.d.ts +0 -7
- package/src/StepIcon/StepIcon.type.d.ts +0 -26
- package/src/StepLabel/StepLabel.type.d.ts +0 -23
- package/src/Stepper/Stepper.type.d.ts +0 -27
- package/src/SwipeableDrawer/SwipeableDrawer.d.ts +0 -26
- package/src/SwipeableDrawer/SwipeableDrawer.types.d.ts +0 -67
- package/src/SwipeableDrawer/hooks/useDrawerGestures.d.ts +0 -110
- package/src/SwipeableDrawer/hooks/useElementSizeObserver.d.ts +0 -5
- package/src/SwipeableDrawer/hooks/useSnapPoints.d.ts +0 -60
- package/src/Switch/Switch.type.d.ts +0 -9
- package/src/Tab/Tab.classes.d.ts +3 -2
- package/src/Tab/Tab.type.d.ts +0 -29
- package/src/TabContext/TabContext.d.ts +0 -4
- package/src/TabContext/TabContext.type.d.ts +0 -7
- package/src/TabPanel/TabPanel.type.d.ts +0 -10
- package/src/Table/Table.type.d.ts +0 -19
- package/src/TableBody/TableBody.type.d.ts +0 -3
- package/src/TableCell/TableCell.d.ts +0 -4
- package/src/TableCell/TableCell.type.d.ts +0 -35
- package/src/TableContainer/TableContainer.type.d.ts +0 -7
- package/src/TableFooter/TableFooter.type.d.ts +0 -3
- package/src/TableHead/TableHead.type.d.ts +0 -6
- package/src/TablePagination/TablePagination.type.d.ts +0 -47
- package/src/TableRow/TableRow.type.d.ts +0 -17
- package/src/Tabs/TabMoreMenu.d.ts +0 -16
- package/src/Tabs/TabScrollButton.d.ts +0 -10
- package/src/Tabs/Tabs.classes.d.ts +1 -1
- package/src/Tabs/Tabs.d.ts +1 -1
- package/src/Tabs/Tabs.type.d.ts +2 -36
- package/src/Tabs/TabsContext.d.ts +2 -0
- package/src/Tabs/hooks/useTabsScroller.d.ts +0 -30
- package/src/Tag/Tag.type.d.ts +0 -12
- package/src/Text/Text.type.d.ts +0 -13
- package/src/TextField/TextField.type.d.ts +0 -64
- package/src/Textarea/Textarea.type.d.ts +0 -13
- package/src/TimePicker/NumberPicker.type.d.ts +0 -12
- package/src/TimePicker/SelectionView.d.ts +0 -6
- package/src/TimePicker/TimeButton.d.ts +0 -3
- package/src/TimePicker/TimePicker.type.d.ts +0 -11
- package/src/TimePicker/ToggleText.type.d.ts +0 -3
- package/src/TimePicker/utils/TimeBoundary.d.ts +0 -3
- package/src/TimePicker/utils/TimePickerHelper.d.ts +0 -19
- package/src/TimePicker/utils/getNumberPickerBoundary.d.ts +0 -3
- package/src/Tooltip/TooltipTrigger.a11y.d.ts +0 -9
- package/src/Tooltip/TooltipTrigger.type.d.ts +0 -44
- package/src/Tooltip/TooltipView.type.d.ts +0 -25
- package/src/Tooltip/useTooltipForceHide.d.ts +0 -4
- package/src/Tray/Tray.type.d.ts +0 -13
- package/src/Tray/TrayContext.d.ts +0 -4
- package/src/Tray/hooks/useTray.d.ts +0 -16
- package/src/Tray/hooks/useTrayPanel.d.ts +0 -3
- package/src/VirtualizedList/VirtualizedList.type.d.ts +0 -27
- package/src/VirtualizedMenu/VirtualizedMenu.type.d.ts +0 -17
package/TableRow.js
CHANGED
|
@@ -22,7 +22,6 @@ const TableRow = forwardRef((inProps, ref) => {
|
|
|
22
22
|
rootRef: ref,
|
|
23
23
|
});
|
|
24
24
|
const rootProps = getRootProps();
|
|
25
|
-
// Determine the appropriate role
|
|
26
25
|
const role = roleProp ?? (TableRowRoot !== defaultComponent ? 'row' : undefined);
|
|
27
26
|
return (jsx(TableRowRoot, { className: cls('root', variant, {
|
|
28
27
|
hoverable,
|
package/Tabs.js
CHANGED
|
@@ -3,6 +3,7 @@ import React, { forwardRef, useState, useMemo, useRef, Children, isValidElement,
|
|
|
3
3
|
import { useTab, useTabsList, TabsListProvider } from '@mui/base';
|
|
4
4
|
import { useClasses, combineClasses, getTitle, useFontLoaded, useWindowContext, logInDev, usePrevious, useEventCallback, useOnReRender, useForkRef } from '@ringcentral/spring-base';
|
|
5
5
|
import { OverflowMd, CaretLeftMd, CaretRightMd } from '@ringcentral/spring-icon';
|
|
6
|
+
import { useMode, motionTransition, useThemeProps, useClassesWithMode } from '@ringcentral/spring-theme';
|
|
6
7
|
import { B as Badge } from './chunks/Badge.js';
|
|
7
8
|
import { I as IconButton } from './chunks/IconButtonLabel.js';
|
|
8
9
|
import { M as Menu } from './chunks/Menu.js';
|
|
@@ -15,7 +16,6 @@ import { M as MenuList } from './chunks/MenuList.js';
|
|
|
15
16
|
import { T as Tooltip } from './chunks/Tooltip.js';
|
|
16
17
|
import { u as useTabsContext, T as TabsContext } from './chunks/TabsContext.js';
|
|
17
18
|
import { animate, useMotionValue, motion } from 'framer-motion';
|
|
18
|
-
import { motionTransition, useThemeProps } from '@ringcentral/spring-theme';
|
|
19
19
|
import './chunks/Icon.js';
|
|
20
20
|
import { u as usePrefersReducedMotion } from './chunks/usePrefersReducedMotion.js';
|
|
21
21
|
import { u as useMotionSafeTransition } from './chunks/useMotionSafeTransition.js';
|
|
@@ -49,20 +49,19 @@ const TabMenuItem = forwardRef((props, ref) => {
|
|
|
49
49
|
...rest,
|
|
50
50
|
rootRef: ref,
|
|
51
51
|
});
|
|
52
|
-
return (
|
|
53
|
-
// @ts-ignore
|
|
54
|
-
jsx(MenuItemComponent, { ...props, ...getRootProps(), onKeyDown: onKeyDown, children: jsx(MenuItemText, { children: label }) }));
|
|
52
|
+
return (jsx(MenuItemComponent, { ...props, ...getRootProps(), onKeyDown: onKeyDown, children: jsx(MenuItemText, { children: label }) }));
|
|
55
53
|
});
|
|
56
54
|
const TabMoreMenu = forwardRef((props, ref) => {
|
|
57
55
|
const { classes, className, menuItems, TooltipProps, BadgeProps, ButtonProps, MenuProps, MenuItemComponent, ...rest } = props;
|
|
58
56
|
const [anchor, setAnchor] = useState(null);
|
|
57
|
+
const { mode } = useMode();
|
|
59
58
|
const cls = useClasses('tab-more-menu', classes, className);
|
|
60
59
|
const { pill } = useTabsContext();
|
|
61
60
|
const iconButtonProps = useMemo(() => (pill
|
|
62
61
|
? {
|
|
63
62
|
shape: 'circular',
|
|
64
63
|
variant: 'outlined',
|
|
65
|
-
size: 'large',
|
|
64
|
+
size: mode === 'compact' ? 'medium' : 'large',
|
|
66
65
|
background: true,
|
|
67
66
|
}
|
|
68
67
|
: {
|
|
@@ -70,7 +69,7 @@ const TabMoreMenu = forwardRef((props, ref) => {
|
|
|
70
69
|
variant: 'contained',
|
|
71
70
|
size: 'small',
|
|
72
71
|
background: false,
|
|
73
|
-
}), [pill]);
|
|
72
|
+
}), [pill, mode]);
|
|
74
73
|
let iconButtonClasses = {
|
|
75
74
|
root: cls('button'),
|
|
76
75
|
};
|
|
@@ -104,6 +103,7 @@ TabMoreMenu.displayName = 'SuiTabMoreMenu';
|
|
|
104
103
|
|
|
105
104
|
const TabScrollButton = forwardRef((props, ref) => {
|
|
106
105
|
const { classes, className, ButtonProps, direction = 'left', onClick, ...rest } = props;
|
|
106
|
+
const { mode } = useMode();
|
|
107
107
|
const cls = useClasses('tab-scroll-button', classes, className);
|
|
108
108
|
const iconButtonClasses = useMemo(() => {
|
|
109
109
|
let combinedClasses = {
|
|
@@ -115,13 +115,15 @@ const TabScrollButton = forwardRef((props, ref) => {
|
|
|
115
115
|
return combinedClasses;
|
|
116
116
|
}, [ButtonProps?.classes, cls]);
|
|
117
117
|
const icon = direction === 'left' ? CaretLeftMd : CaretRightMd;
|
|
118
|
+
const iconButtonSize = useMemo(() => {
|
|
119
|
+
return mode === 'compact' ? 'medium' : 'large';
|
|
120
|
+
}, [mode]);
|
|
118
121
|
return (jsx("div", { className: cls('root', {
|
|
119
122
|
start: direction === 'left',
|
|
120
|
-
}), ref: ref, ...rest, children: jsx(IconButton, { "aria-hidden": "true", role: "presentation", tabIndex: -1, component: "div", color: "secondary", symbol: icon, shape: "circular", variant: "outlined", size:
|
|
123
|
+
}), 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 }) }));
|
|
121
124
|
});
|
|
122
125
|
TabScrollButton.displayName = 'SuiTabScrollButton';
|
|
123
126
|
|
|
124
|
-
/* eslint-disable sonarjs/cognitive-complexity */
|
|
125
127
|
function useComputedTabs(props) {
|
|
126
128
|
const { variant, value, children, pill, pillGap, onGroupInfoUpdate, floatingUnderlineLeftMotionValue, floatingUnderlineWidthMotionValue, tabListRef, scrollerRef, moreRef, } = props;
|
|
127
129
|
const fontsLoaded = useFontLoaded(variant === 'moreMenu');
|
|
@@ -129,15 +131,12 @@ function useComputedTabs(props) {
|
|
|
129
131
|
const { externalWindow } = useWindowContext();
|
|
130
132
|
const ResizeObserverClass = (externalWindow || window).ResizeObserver;
|
|
131
133
|
const [moreMenuItems, setMoreMenuItems] = useState([]);
|
|
132
|
-
// Render the more button initially to get the offsetWidth to compute
|
|
133
134
|
const [showMore, setShowMore] = useState(variant === 'moreMenu');
|
|
134
135
|
const moreBtnWidth = useRef(0);
|
|
135
136
|
const switchToMoreMenu = useRef(variant === 'moreMenu');
|
|
136
|
-
// Store a ref to visibleTabs and hiddenTabs for data comparison
|
|
137
137
|
const visibleTabsRef = useRef();
|
|
138
138
|
const hiddenTabsRef = useRef();
|
|
139
139
|
const shouldUpdate = useRef(false);
|
|
140
|
-
// Cache children info to reduce render times when computing more menu
|
|
141
140
|
const tabsChildrenCache = useRef();
|
|
142
141
|
const { tabsInstanceId } = useInternalTabsContext();
|
|
143
142
|
const processedChildren = useMemo(() => {
|
|
@@ -157,7 +156,6 @@ function useComputedTabs(props) {
|
|
|
157
156
|
});
|
|
158
157
|
}
|
|
159
158
|
const childValue = child.props.value === undefined ? childIndex : child.props.value;
|
|
160
|
-
// Only clone element when necessary: no user-provided id
|
|
161
159
|
let finalChild = child;
|
|
162
160
|
if (child.props.id === undefined) {
|
|
163
161
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -197,10 +195,8 @@ function useComputedTabs(props) {
|
|
|
197
195
|
}, [visibleTabs]);
|
|
198
196
|
const prevChildren = usePrevious(() => children);
|
|
199
197
|
const cacheTabsChildren = useEventCallback(() => {
|
|
200
|
-
// If this is a full update clear the cache
|
|
201
198
|
if (shouldUpdate.current === 'full')
|
|
202
199
|
tabsChildrenCache.current = new Map();
|
|
203
|
-
// We can't cache if the tabListRef is not available
|
|
204
200
|
if (!tabListRef.current?.children || !tabsChildrenCache.current)
|
|
205
201
|
return;
|
|
206
202
|
const tabsChildren = tabListRef.current?.children;
|
|
@@ -209,7 +205,6 @@ function useComputedTabs(props) {
|
|
|
209
205
|
if (!child || !childElement)
|
|
210
206
|
return;
|
|
211
207
|
tabsChildrenCache.current?.set(childValue, {
|
|
212
|
-
// @ts-ignore
|
|
213
208
|
child,
|
|
214
209
|
element: childElement,
|
|
215
210
|
width: childElement.offsetWidth,
|
|
@@ -222,10 +217,6 @@ function useComputedTabs(props) {
|
|
|
222
217
|
return undefined;
|
|
223
218
|
let selectedIndex = -1;
|
|
224
219
|
if (variant === 'moreMenu' && visibleTabsRef.current) {
|
|
225
|
-
/**
|
|
226
|
-
* When the variant is `moreMenu`, visibleTabs may have a different
|
|
227
|
-
* order than processed children as some tabs are hidden in the more menu.
|
|
228
|
-
*/
|
|
229
220
|
selectedIndex = Array.from(visibleTabsRef.current).findIndex(([key]) => {
|
|
230
221
|
return key === value;
|
|
231
222
|
});
|
|
@@ -244,19 +235,17 @@ function useComputedTabs(props) {
|
|
|
244
235
|
].join('\n'),
|
|
245
236
|
});
|
|
246
237
|
}
|
|
247
|
-
// provide the first tab as default selected tab when value is invalid
|
|
248
238
|
return selectedTabElement || children[0];
|
|
249
239
|
});
|
|
250
|
-
// main logic for computing whether show more menu when variant is 'moreMenu'
|
|
251
240
|
const computeMoreMenuWithCache = useEventCallback(() => {
|
|
252
241
|
if (variant !== 'moreMenu' || !tabsChildrenCache.current)
|
|
253
242
|
return;
|
|
254
|
-
const width = scrollerRef.current?.offsetWidth || 0;
|
|
243
|
+
const width = scrollerRef.current?.offsetWidth || 0;
|
|
255
244
|
const visibleWidth = width +
|
|
256
245
|
pillGap -
|
|
257
|
-
(tabListRef.current ? getHorizontalPadding(tabListRef.current) : 0);
|
|
246
|
+
(tabListRef.current ? getHorizontalPadding(tabListRef.current) : 0);
|
|
258
247
|
const selectedItemWidth = (value !== null && tabsChildrenCache.current.get(value)?.width) || 0;
|
|
259
|
-
const spaceForMoreBtn = moreBtnWidth.current + pillGap;
|
|
248
|
+
const spaceForMoreBtn = moreBtnWidth.current + pillGap;
|
|
260
249
|
let consumedWidth = spaceForMoreBtn;
|
|
261
250
|
let isSelectedItemVisible = false;
|
|
262
251
|
let noWidthForUnselectedTab = false;
|
|
@@ -267,70 +256,50 @@ function useComputedTabs(props) {
|
|
|
267
256
|
const [key, itemInfo] = cache[i];
|
|
268
257
|
const { child, width: itemWidth } = itemInfo;
|
|
269
258
|
const width = itemWidth + pillGap;
|
|
270
|
-
/**
|
|
271
|
-
* If there's not enough space to accommodate an unselected tab and
|
|
272
|
-
* the tab isn't selected we'll hide it, aka put it in the more menu.
|
|
273
|
-
*/
|
|
274
259
|
if (noWidthForUnselectedTab && key !== value) {
|
|
275
260
|
hiddenItems.set(key, child);
|
|
276
261
|
continue;
|
|
277
262
|
}
|
|
278
263
|
if (isSelectedItemVisible) {
|
|
279
|
-
// Check if this is the last tab in the list
|
|
280
264
|
if (cache.length === i + 1) {
|
|
281
|
-
// Check if there is enough space to accommodate the tab without the more button
|
|
282
265
|
if (visibleWidth >= consumedWidth - spaceForMoreBtn + width) {
|
|
283
|
-
// There's enough space available, show the last tab
|
|
284
266
|
visibleItems.set(key, child);
|
|
285
267
|
}
|
|
286
268
|
else {
|
|
287
|
-
// There's not enough space available, put the last item inside more menu
|
|
288
269
|
hiddenItems.set(key, child);
|
|
289
270
|
}
|
|
290
271
|
}
|
|
291
272
|
else {
|
|
292
|
-
// The current item is not the last tab in the list
|
|
293
|
-
// Check if there is enough space to accommodate this tab
|
|
294
273
|
if (visibleWidth >= consumedWidth + width) {
|
|
295
274
|
consumedWidth += width;
|
|
296
|
-
// There's enough space available, show this tab in the list
|
|
297
275
|
visibleItems.set(key, child);
|
|
298
276
|
}
|
|
299
277
|
else {
|
|
300
|
-
// There's not enoguh space available put the tab inside the more menu (hide it)
|
|
301
278
|
hiddenItems.set(key, child);
|
|
302
279
|
noWidthForUnselectedTab = true;
|
|
303
280
|
}
|
|
304
281
|
}
|
|
305
282
|
continue;
|
|
306
283
|
}
|
|
307
|
-
// The selected tab is not visible yet. Check if the current tab is selected
|
|
308
284
|
if (key === value) {
|
|
309
|
-
// Show the selected tab, it should never be inside the more menu
|
|
310
285
|
visibleItems.set(key, child);
|
|
311
|
-
// Check if the current tab is not the last one in the list, if it isn't we need to account for its width
|
|
312
286
|
if (cache.length !== i + 1)
|
|
313
287
|
consumedWidth += width;
|
|
314
288
|
isSelectedItemVisible = true;
|
|
315
289
|
continue;
|
|
316
290
|
}
|
|
317
|
-
// The current tab is not selected. Check if there is enough space for the current tab, the selected tab and more button
|
|
318
291
|
if (visibleWidth >= consumedWidth + width + selectedItemWidth) {
|
|
319
292
|
consumedWidth += width;
|
|
320
293
|
visibleItems.set(key, child);
|
|
321
294
|
continue;
|
|
322
295
|
}
|
|
323
|
-
// There's not enough space available. Check if current tab immediately precedes the last selected tab
|
|
324
296
|
const isSecondToLast = cache.length - 1 === i + 1;
|
|
325
|
-
// Check if there is enough space for the current tab and the last selected tab without the more button
|
|
326
297
|
const hasSpaceForLast2Items = visibleWidth >=
|
|
327
298
|
consumedWidth - spaceForMoreBtn + width + selectedItemWidth;
|
|
328
299
|
if (isSecondToLast && hasSpaceForLast2Items) {
|
|
329
|
-
// If it's second to last and has enough space, show the tab
|
|
330
300
|
visibleItems.set(key, child);
|
|
331
301
|
}
|
|
332
302
|
else {
|
|
333
|
-
// Otherwise hide the tab and put it in the more menu
|
|
334
303
|
hiddenItems.set(key, child);
|
|
335
304
|
noWidthForUnselectedTab = true;
|
|
336
305
|
}
|
|
@@ -344,7 +313,6 @@ function useComputedTabs(props) {
|
|
|
344
313
|
else {
|
|
345
314
|
setShowMore(false);
|
|
346
315
|
}
|
|
347
|
-
// @ts-ignore
|
|
348
316
|
const newVisibleTabs = new Map();
|
|
349
317
|
let childIndex = 0;
|
|
350
318
|
for (const [childValue, child] of visibleItems.entries()) {
|
|
@@ -353,10 +321,8 @@ function useComputedTabs(props) {
|
|
|
353
321
|
}
|
|
354
322
|
setVisibleTabs(newVisibleTabs);
|
|
355
323
|
shouldUpdate.current = false;
|
|
356
|
-
// Check if visibleTabs or hiddenTabs has changed
|
|
357
324
|
if (!isEqual([...(visibleTabsRef.current?.keys() || [])], [...visibleItems.keys()]) ||
|
|
358
325
|
!isEqual([...(hiddenTabsRef.current?.keys() || [])], [...hiddenItems.keys()])) {
|
|
359
|
-
// If it has changed, invoke onGroupInfoUpdate with the updated group data
|
|
360
326
|
onGroupInfoUpdate?.([...visibleItems.keys()], [...hiddenItems.keys()]);
|
|
361
327
|
}
|
|
362
328
|
visibleTabsRef.current = visibleItems;
|
|
@@ -376,15 +342,12 @@ function useComputedTabs(props) {
|
|
|
376
342
|
floatingUnderlineLeftMotionValue.set(targetLeft);
|
|
377
343
|
return;
|
|
378
344
|
}
|
|
379
|
-
// Only animate if either value has changed
|
|
380
345
|
if (currentWidth !== targetWidth || currentLeft !== targetLeft) {
|
|
381
346
|
const transition = motionTransition['spring-01-fast'];
|
|
382
347
|
animate(floatingUnderlineWidthMotionValue, targetWidth, transition);
|
|
383
348
|
animate(floatingUnderlineLeftMotionValue, targetLeft, transition);
|
|
384
349
|
}
|
|
385
350
|
});
|
|
386
|
-
// variant 'moreMenu', check if cache need to be updated when visibleTabs changed
|
|
387
|
-
// also need to update the cache when fonts are loaded after the initial mount
|
|
388
351
|
useEffect(() => {
|
|
389
352
|
if (variant !== 'moreMenu')
|
|
390
353
|
return;
|
|
@@ -393,13 +356,11 @@ function useComputedTabs(props) {
|
|
|
393
356
|
}
|
|
394
357
|
if (tabsChildrenCache.current) {
|
|
395
358
|
if (!shouldUpdate.current) {
|
|
396
|
-
// Check if the rendered visibleTabs have a different width than the cached tabs
|
|
397
359
|
for (const [childValue, { childIndex: index, child },] of visibleTabs.entries()) {
|
|
398
360
|
if (shouldUpdate.current || !child)
|
|
399
361
|
continue;
|
|
400
362
|
const cachedWidth = tabsChildrenCache.current?.get(childValue)?.width;
|
|
401
363
|
const childElement = tabListRef.current?.children[index];
|
|
402
|
-
// If the cached width is different, we should perform a partial update
|
|
403
364
|
if (cachedWidth !== childElement.offsetWidth) {
|
|
404
365
|
shouldUpdate.current = 'partial';
|
|
405
366
|
}
|
|
@@ -410,7 +371,6 @@ function useComputedTabs(props) {
|
|
|
410
371
|
computeMoreMenuWithCache();
|
|
411
372
|
}
|
|
412
373
|
}
|
|
413
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
414
374
|
}, [visibleTabs, fontsLoaded]);
|
|
415
375
|
useEffect(() => {
|
|
416
376
|
if (prevChildren && children !== prevChildren) {
|
|
@@ -418,20 +378,15 @@ function useComputedTabs(props) {
|
|
|
418
378
|
shouldUpdate.current = 'full';
|
|
419
379
|
}
|
|
420
380
|
}, [children, prevChildren, processedChildren]);
|
|
421
|
-
// initial cache for variant 'moreMenu', used for computing more menu
|
|
422
381
|
useLayoutEffect(() => {
|
|
423
382
|
if (switchToMoreMenu.current && tabListRef.current?.children) {
|
|
424
383
|
switchToMoreMenu.current = false;
|
|
425
|
-
// initial cache of tabsChildrenCache
|
|
426
384
|
tabsChildrenCache.current = new Map();
|
|
427
385
|
cacheTabsChildren();
|
|
428
|
-
// initial cache of moreBtnWidth
|
|
429
386
|
moreBtnWidth.current = moreRef.current?.offsetWidth || 0;
|
|
430
387
|
computeMoreMenuWithCache();
|
|
431
388
|
}
|
|
432
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
433
389
|
}, [showMore]);
|
|
434
|
-
// handle switch variant situation
|
|
435
390
|
useOnReRender(() => {
|
|
436
391
|
if (variant !== 'moreMenu') {
|
|
437
392
|
setShowMore(false);
|
|
@@ -441,41 +396,25 @@ function useComputedTabs(props) {
|
|
|
441
396
|
switchToMoreMenu.current = true;
|
|
442
397
|
setShowMore(true);
|
|
443
398
|
}
|
|
444
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
445
399
|
}, [variant]);
|
|
446
|
-
// Check if we need to update the cache and update the more menu when any tab child is resized
|
|
447
400
|
useEffect(() => {
|
|
448
401
|
if (variant !== 'moreMenu')
|
|
449
402
|
return;
|
|
450
403
|
let initialObservation = true;
|
|
451
404
|
const handleResize = throttle((entries) => {
|
|
452
405
|
if (initialObservation) {
|
|
453
|
-
/**
|
|
454
|
-
* We handle the computation of the more menu after the initial mount,
|
|
455
|
-
* or we re-compute when the `showMore` prop has updated. There's
|
|
456
|
-
* no need to compute here.
|
|
457
|
-
*/
|
|
458
406
|
initialObservation = false;
|
|
459
407
|
return;
|
|
460
408
|
}
|
|
461
409
|
if (entries) {
|
|
462
|
-
// Partially update the cache before computing the more menu
|
|
463
410
|
cacheTabsChildren();
|
|
464
411
|
if (moreRef.current)
|
|
465
412
|
moreBtnWidth.current = moreRef.current.offsetWidth;
|
|
466
413
|
}
|
|
467
414
|
computeMoreMenuWithCache();
|
|
468
|
-
/**
|
|
469
|
-
* For variants other than moreMenu, we compute the floating underline using a dedicated
|
|
470
|
-
* ResizeObserver for the selected tab. When we're on the moreMenu we already have a resize
|
|
471
|
-
* observer for the tabList, so we don't need to create a dedicated one for the selected tab,
|
|
472
|
-
* then we compute the floating underline as part of the resize event we otherwise use for
|
|
473
|
-
* the more menu.
|
|
474
|
-
*/
|
|
475
415
|
computeFloatingUnderline(true);
|
|
476
416
|
}, 200);
|
|
477
417
|
let resizeObserver;
|
|
478
|
-
// Check if ResizeObserver is supported in this environment
|
|
479
418
|
if (typeof ResizeObserverClass !== 'undefined') {
|
|
480
419
|
resizeObserver = new ResizeObserverClass(handleResize);
|
|
481
420
|
if (scrollerRef.current)
|
|
@@ -483,10 +422,8 @@ function useComputedTabs(props) {
|
|
|
483
422
|
if (tabListRef && tabListRef.current) {
|
|
484
423
|
const tabsChildren = tabListRef.current.children;
|
|
485
424
|
Array.from(tabsChildren).forEach((child, index) => {
|
|
486
|
-
// The last child when the pill prop is enabled is the underline element, no need to observe it
|
|
487
425
|
if (pill && index === tabsChildren.length - 1)
|
|
488
426
|
return;
|
|
489
|
-
// When the pill props is disabled, the last 2 children are the underline and floating underline elements, no need to observe them
|
|
490
427
|
if (!pill && index >= tabsChildren.length - 2)
|
|
491
428
|
return;
|
|
492
429
|
resizeObserver?.observe(child);
|
|
@@ -497,30 +434,19 @@ function useComputedTabs(props) {
|
|
|
497
434
|
handleResize.cancel();
|
|
498
435
|
resizeObserver?.disconnect();
|
|
499
436
|
};
|
|
500
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
501
437
|
}, [variant, pill, ResizeObserverClass]);
|
|
502
438
|
useEffect(() => {
|
|
503
|
-
// The ResizeObserver for the moreMenu automatically handles floating underline computation
|
|
504
439
|
if (variant === 'moreMenu')
|
|
505
440
|
return;
|
|
506
441
|
let initialObservation = true;
|
|
507
442
|
const handleSelectedTabResize = throttle(() => {
|
|
508
443
|
if (initialObservation) {
|
|
509
|
-
/**
|
|
510
|
-
* We handle the initial computation of the floating underline in the
|
|
511
|
-
* Tabs component after the value has changed, we don't need to compute
|
|
512
|
-
* it here again. This also allows us to distinguish between when the
|
|
513
|
-
* selected tab is resized and when the user selects a different tab,
|
|
514
|
-
* meaning we can apply an instant transition during resizing, but use
|
|
515
|
-
* a spring transition when switching tabs.
|
|
516
|
-
*/
|
|
517
444
|
initialObservation = false;
|
|
518
445
|
return;
|
|
519
446
|
}
|
|
520
447
|
computeFloatingUnderline(true);
|
|
521
448
|
}, 16);
|
|
522
449
|
let selectedTabResizeObserver;
|
|
523
|
-
// Check if ResizeObserver is supported in this environment
|
|
524
450
|
if (typeof ResizeObserverClass !== 'undefined') {
|
|
525
451
|
selectedTabResizeObserver = new ResizeObserverClass(handleSelectedTabResize);
|
|
526
452
|
const selectedTabElement = getSelectedTabElement();
|
|
@@ -532,24 +458,19 @@ function useComputedTabs(props) {
|
|
|
532
458
|
handleSelectedTabResize.cancel();
|
|
533
459
|
selectedTabResizeObserver?.disconnect();
|
|
534
460
|
};
|
|
535
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
536
461
|
}, [variant, value, ResizeObserverClass]);
|
|
537
462
|
const prevVariant = usePrevious(() => variant);
|
|
538
463
|
useEffect(() => {
|
|
539
|
-
// If only the variant is changed, we need to update the floating underline without animation
|
|
540
464
|
if (prevVariant !== variant) {
|
|
541
465
|
computeFloatingUnderline(true);
|
|
542
466
|
}
|
|
543
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
544
467
|
}, [variant]);
|
|
545
468
|
useEffect(() => {
|
|
546
469
|
if (variant === 'moreMenu' &&
|
|
547
470
|
value !== null &&
|
|
548
471
|
hiddenTabsRef.current?.has(value)) {
|
|
549
|
-
// Re-compute when a hidden tab (i.e. tab in the more menu) is selected
|
|
550
472
|
computeMoreMenuWithCache();
|
|
551
473
|
}
|
|
552
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
553
474
|
}, [value]);
|
|
554
475
|
return {
|
|
555
476
|
visibleTabsChildren,
|
|
@@ -569,9 +490,6 @@ function getHorizontalPadding(element) {
|
|
|
569
490
|
}
|
|
570
491
|
|
|
571
492
|
const THRESHOLD_FOR_SUB_PIXEL_CALCULATION = 0.5;
|
|
572
|
-
/**
|
|
573
|
-
* 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
|
|
574
|
-
*/
|
|
575
493
|
const useTabsScroller = ({ enable, scrollerRef, tabListRef, scroll, ScrollButtonStartProps, ScrollButtonEndProps, }) => {
|
|
576
494
|
const [displayStartScroll, setDisplayStartScroll] = useState(false);
|
|
577
495
|
const [displayEndScroll, setDisplayEndScroll] = useState(false);
|
|
@@ -588,10 +506,8 @@ const useTabsScroller = ({ enable, scrollerRef, tabListRef, scroll, ScrollButton
|
|
|
588
506
|
setDisplayStartScroll(scrollLeft > 0);
|
|
589
507
|
setDisplayEndScroll(maxScrollLeft - scrollLeft > THRESHOLD_FOR_SUB_PIXEL_CALCULATION);
|
|
590
508
|
}, 100);
|
|
591
|
-
// add scroll event listener
|
|
592
509
|
const currentTabsRef = scrollerRef.current;
|
|
593
510
|
currentTabsRef?.addEventListener('scroll', checkScroll);
|
|
594
|
-
// ResizeObserver for tabs list
|
|
595
511
|
let resizeObserver;
|
|
596
512
|
if (typeof ResizeObserverClass !== 'undefined') {
|
|
597
513
|
resizeObserver = new ResizeObserverClass(checkScroll);
|
|
@@ -599,11 +515,10 @@ const useTabsScroller = ({ enable, scrollerRef, tabListRef, scroll, ScrollButton
|
|
|
599
515
|
resizeObserver.observe(currentTabsRef);
|
|
600
516
|
}
|
|
601
517
|
}
|
|
602
|
-
checkScroll();
|
|
518
|
+
checkScroll();
|
|
603
519
|
return () => {
|
|
604
520
|
currentTabsRef?.removeEventListener('scroll', checkScroll);
|
|
605
521
|
checkScroll.cancel();
|
|
606
|
-
// Disconnect the ResizeObserver on cleanup
|
|
607
522
|
resizeObserver?.disconnect();
|
|
608
523
|
};
|
|
609
524
|
}, [enable, scrollerRef, ResizeObserverClass]);
|
|
@@ -651,12 +566,12 @@ const useTabsScroller = ({ enable, scrollerRef, tabListRef, scroll, ScrollButton
|
|
|
651
566
|
]);
|
|
652
567
|
};
|
|
653
568
|
|
|
654
|
-
var Tabs$1 = {"sui-tabs-root":"sui-tabs-root","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"};
|
|
569
|
+
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"};
|
|
655
570
|
|
|
656
571
|
const DEFAULT_PILL_GAP = 4;
|
|
657
572
|
const Tabs = forwardRef((inProps, ref) => {
|
|
658
573
|
const props = useThemeProps({ props: inProps, name: 'Tabs' });
|
|
659
|
-
const { classes, className, children, onBlur, onFocus, variant = 'standard', onGroupInfoUpdate, MoreMenuProps, pill, pillGap: pillGapProp = DEFAULT_PILL_GAP, color = 'default', ScrollButtonStartProps, ScrollButtonEndProps, enableScrollButtons = true, ...rest } = props;
|
|
574
|
+
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;
|
|
660
575
|
const pillGap = pill ? pillGapProp : 0;
|
|
661
576
|
const tabsRef = useRef(null);
|
|
662
577
|
const scrollerRef = useRef(null);
|
|
@@ -669,7 +584,7 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
669
584
|
const floatingUnderlineOpacityMotionValue = useMotionValue(1);
|
|
670
585
|
const floatingUnderlineTransition = useMotionSafeTransition(motionTransition['spring-01-fast']);
|
|
671
586
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
672
|
-
const cls =
|
|
587
|
+
const cls = useClassesWithMode('tabs', classes, className);
|
|
673
588
|
const { onGroupInfoUpdate: groupInfoUpdateHandler, ...restProps } = props;
|
|
674
589
|
const { getRootProps, contextValue, selectedValue: value, } = useTabsList({
|
|
675
590
|
...restProps,
|
|
@@ -692,7 +607,6 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
692
607
|
let tabsMeta;
|
|
693
608
|
if (tabsNode) {
|
|
694
609
|
const rect = tabsNode.getBoundingClientRect();
|
|
695
|
-
// create a new object with ClientRect class props + scrollLeft
|
|
696
610
|
tabsMeta = {
|
|
697
611
|
clientWidth: tabsNode.clientWidth,
|
|
698
612
|
scrollLeft: tabsNode.scrollLeft,
|
|
@@ -710,7 +624,6 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
710
624
|
if (tab) {
|
|
711
625
|
const rect = tab.getBoundingClientRect();
|
|
712
626
|
tabMeta = {
|
|
713
|
-
// Use offsetWidth/offsetHeight to negate any transforms that might be applied
|
|
714
627
|
height: tab.offsetHeight,
|
|
715
628
|
width: tab.offsetWidth,
|
|
716
629
|
x: rect.x,
|
|
@@ -736,7 +649,6 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
736
649
|
return;
|
|
737
650
|
}
|
|
738
651
|
if (transitionType === null || prefersReducedMotion) {
|
|
739
|
-
// if transitionType is null or prefersReducedMotion, set the scroll value without animation
|
|
740
652
|
scrollerRef.current[scrollStart] = to;
|
|
741
653
|
return;
|
|
742
654
|
}
|
|
@@ -755,11 +667,9 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
755
667
|
if (!tabMeta || !tabsMeta) {
|
|
756
668
|
return;
|
|
757
669
|
}
|
|
758
|
-
// Check if the left side of the tab is out of view
|
|
759
670
|
if (tabMeta[start] < tabsMeta[start]) {
|
|
760
671
|
const nextScrollStart = tabsMeta[scrollStart] + (tabMeta[start] - tabsMeta[start]);
|
|
761
672
|
scroll(nextScrollStart, noAnimation ? null : undefined);
|
|
762
|
-
// Check if the right side of the tab is out of view
|
|
763
673
|
}
|
|
764
674
|
else if (tabMeta[end] > tabsMeta[end]) {
|
|
765
675
|
const nextScrollStart = tabsMeta[scrollStart] + Math.abs(tabMeta[end] - tabsMeta[end]);
|
|
@@ -779,16 +689,8 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
779
689
|
useEffect(() => {
|
|
780
690
|
const noAnimationWhenFirstRender = floatingUnderlineWidthMotionValue.get() === 0;
|
|
781
691
|
if (variant !== 'moreMenu') {
|
|
782
|
-
/**
|
|
783
|
-
* Invoke scrollSelectedIntoView when visibleTabsChildren has been updated or the selected
|
|
784
|
-
* tab has changed. It will be updated when the variant is switched from `moreMenu`
|
|
785
|
-
* to another value. If the variant is `moreMenu`, `visibleTabsChildren` will also be
|
|
786
|
-
* updated when resized.
|
|
787
|
-
*/
|
|
788
692
|
scrollSelectedIntoView(noAnimationWhenFirstRender);
|
|
789
693
|
}
|
|
790
|
-
// If the visibleTabsChildren has been updated but selected tab has not changed,
|
|
791
|
-
// we don't need to animate the floating underline
|
|
792
694
|
const noAnimationWhenNoValueChange = prevVisibleTabsChildren.current !== visibleTabsChildren &&
|
|
793
695
|
prevValueAfterChildrenUpdate.current === value;
|
|
794
696
|
if (prevVisibleTabsChildren.current !== visibleTabsChildren) {
|
|
@@ -796,16 +698,16 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
796
698
|
prevValueAfterChildrenUpdate.current = value;
|
|
797
699
|
}
|
|
798
700
|
computeFloatingUnderline(noAnimationWhenFirstRender || noAnimationWhenNoValueChange);
|
|
799
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
800
701
|
}, [visibleTabsChildren, value]);
|
|
801
702
|
const tabsContextValue = useMemo(() => ({
|
|
802
703
|
pill,
|
|
803
704
|
pillGap,
|
|
804
705
|
color,
|
|
706
|
+
size,
|
|
805
707
|
setFloatingUnderlineVisibility: (isVisible) => {
|
|
806
708
|
floatingUnderlineOpacityMotionValue.set(isVisible ? 1 : 0);
|
|
807
709
|
},
|
|
808
|
-
}), [floatingUnderlineOpacityMotionValue, pill, pillGap, color]);
|
|
710
|
+
}), [floatingUnderlineOpacityMotionValue, pill, pillGap, color, size]);
|
|
809
711
|
if (!processedChildren.size) {
|
|
810
712
|
return null;
|
|
811
713
|
}
|
|
@@ -816,7 +718,7 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
816
718
|
'scroll-left': !!scrollButtonStart,
|
|
817
719
|
'scroll-right': !!scrollButtonEnd,
|
|
818
720
|
'scroll-both': !!(scrollButtonStart && scrollButtonEnd),
|
|
819
|
-
}), ...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: {
|
|
721
|
+
}, 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: {
|
|
820
722
|
left: floatingUnderlineLeftMotionValue,
|
|
821
723
|
width: floatingUnderlineWidthMotionValue,
|
|
822
724
|
opacity: floatingUnderlineOpacityMotionValue,
|
package/Text.js
CHANGED
|
@@ -25,14 +25,12 @@ const Text = forwardRef((inProps, ref) => {
|
|
|
25
25
|
const [isShowTitle, setIsShowTitle] = useState(false);
|
|
26
26
|
const innerRef = useRef(null);
|
|
27
27
|
const textRef = useForkRef(innerRef, ref);
|
|
28
|
-
// * here put hook in if else, titleWhenOverflow not change any more
|
|
29
28
|
if (titleWhenOverflow) {
|
|
30
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
31
29
|
useOverflow(innerRef, (state) => setIsShowTitle(state));
|
|
32
30
|
}
|
|
33
31
|
const cls = useClasses('text', {}, className);
|
|
34
|
-
const title = isShowTitle || useTooltip
|
|
35
|
-
?
|
|
32
|
+
const title = isShowTitle || useTooltip
|
|
33
|
+
?
|
|
36
34
|
_title ?? (isString(children) ? children : undefined)
|
|
37
35
|
: undefined;
|
|
38
36
|
const showTooltip = Boolean(useTooltip) && isShowTitle && !!title && !!children;
|