@ringcentral/spring-ui 1.7.0 → 1.9.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 +216 -243
- 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 +18 -6
- 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/Modal.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/StepButton.js +2 -3
- package/StepContent.js +3 -8
- package/SubMenu.js +0 -4
- package/SwipeableDrawer.js +37 -162
- 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 +2 -4
- package/Tabs.js +22 -121
- package/Text.js +2 -4
- package/TimePicker.js +7 -46
- package/VirtualizedList.js +6 -39
- package/VirtualizedMenu.js +1 -1
- 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 +6 -5
- package/chunks/MenuDivider.js +2 -3
- package/chunks/MenuItemText.js +3 -3
- package/chunks/MenuList.js +3 -6
- package/chunks/Modal.js +1 -1
- 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 +45 -99
- package/chunks/getFade.js +4 -0
- package/chunks/useFocusTrapStack.js +0 -8
- package/chunks/useHelperTextId.js +0 -24
- package/chunks/useListNavigation.js +5 -17
- package/chunks/useMenuItemSelect.js +9 -22
- package/chunks/useMotionSafeTransition.js +0 -4
- package/chunks/useNestedParentMenu.js +5 -18
- package/chunks/usePrefersReducedMotion.js +6 -12
- package/chunks/useTooltipForceHide.js +0 -4
- package/chunks/useTrayNavigate.js +0 -1
- package/index.css +434 -135
- package/index.js +1 -1
- package/package.json +4 -4
- package/src/Accordion/Accordion.d.ts +1 -1
- package/src/Accordion/Accordion.type.d.ts +0 -21
- package/src/AccordionHeader/AccordionHeader.d.ts +1 -1
- package/src/AccordionHeader/AccordionHeader.type.d.ts +0 -14
- package/src/Alert/Alert.d.ts +1 -1
- 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 +4 -23
- 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 +5 -66
- package/src/Autocomplete/useAutocompleteTag.d.ts +3 -36
- 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.d.ts +1 -1
- 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 +1 -8
- package/src/DatePicker/Year.d.ts +1 -7
- 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.classes.d.ts +1 -1
- package/src/Dialog/Dialog.d.ts +1 -1
- package/src/Dialog/Dialog.type.d.ts +3 -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 +1 -29
- package/src/Drawer/Drawer.type.d.ts +0 -84
- package/src/Dropdown/Dropdown.type.d.ts +0 -64
- package/src/EmptyState/EmptyState.d.ts +1 -1
- 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.d.ts +1 -1
- package/src/FormLabel/FormLabel.type.d.ts +0 -14
- package/src/Icon/Icon.d.ts +1 -1
- package/src/Icon/Icon.type.d.ts +0 -15
- package/src/IconButton/IconButton.type.d.ts +0 -30
- package/src/IconButton/IconButtonLabel.d.ts +1 -1
- 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.d.ts +1 -1
- package/src/ListItemText/ListItemText.type.d.ts +0 -21
- package/src/ListNavigation/useListNavigation.d.ts +0 -16
- package/src/Menu/Menu.d.ts +1 -1
- 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.d.ts +1 -1
- 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.d.ts +1 -1
- 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.d.ts +2 -2
- package/src/Modal/InnerModal.type.d.ts +0 -5
- package/src/Modal/Modal.classes.d.ts +1 -1
- package/src/Modal/Modal.d.ts +3 -3
- package/src/Modal/Modal.type.d.ts +0 -11
- package/src/Modal/ModalContext.d.ts +0 -4
- package/src/NestedMenuContext/NestedMenuContext.d.ts +1 -1
- package/src/Option/Option.d.ts +1 -1
- 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.d.ts +1 -1
- package/src/Popover/Popover.type.d.ts +0 -29
- package/src/Popper/Popper.d.ts +1 -1
- package/src/Popper/Popper.type.d.ts +0 -61
- package/src/PopperPaper/PopperPaper.d.ts +1 -1
- package/src/Radio/Radio.type.d.ts +0 -5
- package/src/RadioGroup/RadioGroup.d.ts +1 -1
- package/src/RadioGroup/RadioGroup.type.d.ts +0 -4
- package/src/Rating/Rating.d.ts +1 -1
- package/src/Rating/Rating.type.d.ts +0 -74
- package/src/Rating/RatingItem.d.ts +1 -1
- package/src/Select/Select.type.d.ts +0 -84
- package/src/SingleFilter/FilterButton/FilterButton.d.ts +1 -1
- package/src/SingleFilter/FilterButton/FilterButton.type.d.ts +0 -16
- package/src/SingleFilter/SingleFilter.d.ts +1 -1
- 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.d.ts +2 -2
- package/src/Slider/Slider.type.d.ts +0 -104
- package/src/Snackbar/Snackbar.type.d.ts +0 -18
- package/src/SortableListItem/SortableListItemOverlay.d.ts +1 -1
- package/src/SplitButton/SplitButton.d.ts +1 -1
- 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.d.ts +1 -1
- package/src/StepContent/StepContent.type.d.ts +0 -7
- package/src/StepIcon/StepIcon.type.d.ts +0 -26
- package/src/StepLabel/StepLabel.d.ts +1 -1
- package/src/StepLabel/StepLabel.type.d.ts +0 -23
- package/src/Stepper/Stepper.type.d.ts +0 -27
- package/src/SubMenu/PopperMenu.d.ts +1 -1
- package/src/SubMenu/SubMenu.d.ts +1 -1
- package/src/SwipeableDrawer/SwipeableDrawer.d.ts +1 -27
- 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.d.ts +1 -1
- 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.d.ts +1 -1
- 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 +1 -11
- 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.d.ts +1 -1
- 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.d.ts +1 -1
- package/src/Textarea/Textarea.type.d.ts +0 -13
- package/src/TimePicker/NumberPicker.d.ts +1 -1
- package/src/TimePicker/NumberPicker.type.d.ts +0 -12
- package/src/TimePicker/SelectionView.d.ts +0 -6
- package/src/TimePicker/TimeButton.d.ts +1 -4
- package/src/TimePicker/TimePicker.type.d.ts +0 -11
- package/src/TimePicker/ToggleText.d.ts +1 -1
- 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.d.ts +1 -1
- 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/TrayMenu/TrayMenu.d.ts +1 -1
- package/src/TrayMenu/TrayMenuItem.d.ts +1 -1
- package/src/VirtualizedList/VirtualizedList.type.d.ts +0 -27
- package/src/VirtualizedMenu/VirtualizedMenu.classes.d.ts +1 -1
- package/src/VirtualizedMenu/VirtualizedMenu.type.d.ts +0 -17
package/Tabs.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import React, { forwardRef, useState, useMemo, useRef, Children, isValidElement, cloneElement, useEffect, useLayoutEffect, useCallback } from 'react';
|
|
3
3
|
import { useTab, useTabsList, TabsListProvider } from '@mui/base';
|
|
4
|
-
import { useClasses, combineClasses, getTitle, useFontLoaded, useWindowContext, logInDev, usePrevious, useEventCallback, useOnReRender, useForkRef } from '@ringcentral/spring-base';
|
|
4
|
+
import { useClasses, combineClasses, getTitle, combineProps, 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
|
};
|
|
@@ -93,17 +92,17 @@ const TabMoreMenu = forwardRef((props, ref) => {
|
|
|
93
92
|
};
|
|
94
93
|
const handleClose = (event, reason) => {
|
|
95
94
|
setAnchor(null);
|
|
96
|
-
MenuProps?.onClose?.(event, reason);
|
|
97
95
|
};
|
|
98
96
|
const iconButton = (jsx(IconButton, { color: 'secondary', symbol: OverflowMd, ...iconButtonProps, onClick: (e) => {
|
|
99
97
|
setAnchor((prev) => (prev ? null : e.currentTarget));
|
|
100
98
|
}, "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, onClose: handleClose, children: jsx(MenuList, { children: menuItems.map(({ ref, ...props }, index) => (jsx(TabMenuItem, { ...props, ref: ref, component: MenuItemComponent }, props.value || `TabMenuItem-${index}`))) }) })] }));
|
|
99
|
+
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}`))) }) })] }));
|
|
102
100
|
});
|
|
103
101
|
TabMoreMenu.displayName = 'SuiTabMoreMenu';
|
|
104
102
|
|
|
105
103
|
const TabScrollButton = forwardRef((props, ref) => {
|
|
106
104
|
const { classes, className, ButtonProps, direction = 'left', onClick, ...rest } = props;
|
|
105
|
+
const { mode } = useMode();
|
|
107
106
|
const cls = useClasses('tab-scroll-button', classes, className);
|
|
108
107
|
const iconButtonClasses = useMemo(() => {
|
|
109
108
|
let combinedClasses = {
|
|
@@ -115,13 +114,15 @@ const TabScrollButton = forwardRef((props, ref) => {
|
|
|
115
114
|
return combinedClasses;
|
|
116
115
|
}, [ButtonProps?.classes, cls]);
|
|
117
116
|
const icon = direction === 'left' ? CaretLeftMd : CaretRightMd;
|
|
117
|
+
const iconButtonSize = useMemo(() => {
|
|
118
|
+
return mode === 'compact' ? 'medium' : 'large';
|
|
119
|
+
}, [mode]);
|
|
118
120
|
return (jsx("div", { className: cls('root', {
|
|
119
121
|
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:
|
|
122
|
+
}), 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
123
|
});
|
|
122
124
|
TabScrollButton.displayName = 'SuiTabScrollButton';
|
|
123
125
|
|
|
124
|
-
/* eslint-disable sonarjs/cognitive-complexity */
|
|
125
126
|
function useComputedTabs(props) {
|
|
126
127
|
const { variant, value, children, pill, pillGap, onGroupInfoUpdate, floatingUnderlineLeftMotionValue, floatingUnderlineWidthMotionValue, tabListRef, scrollerRef, moreRef, } = props;
|
|
127
128
|
const fontsLoaded = useFontLoaded(variant === 'moreMenu');
|
|
@@ -129,15 +130,12 @@ function useComputedTabs(props) {
|
|
|
129
130
|
const { externalWindow } = useWindowContext();
|
|
130
131
|
const ResizeObserverClass = (externalWindow || window).ResizeObserver;
|
|
131
132
|
const [moreMenuItems, setMoreMenuItems] = useState([]);
|
|
132
|
-
// Render the more button initially to get the offsetWidth to compute
|
|
133
133
|
const [showMore, setShowMore] = useState(variant === 'moreMenu');
|
|
134
134
|
const moreBtnWidth = useRef(0);
|
|
135
135
|
const switchToMoreMenu = useRef(variant === 'moreMenu');
|
|
136
|
-
// Store a ref to visibleTabs and hiddenTabs for data comparison
|
|
137
136
|
const visibleTabsRef = useRef();
|
|
138
137
|
const hiddenTabsRef = useRef();
|
|
139
138
|
const shouldUpdate = useRef(false);
|
|
140
|
-
// Cache children info to reduce render times when computing more menu
|
|
141
139
|
const tabsChildrenCache = useRef();
|
|
142
140
|
const { tabsInstanceId } = useInternalTabsContext();
|
|
143
141
|
const processedChildren = useMemo(() => {
|
|
@@ -157,7 +155,6 @@ function useComputedTabs(props) {
|
|
|
157
155
|
});
|
|
158
156
|
}
|
|
159
157
|
const childValue = child.props.value === undefined ? childIndex : child.props.value;
|
|
160
|
-
// Only clone element when necessary: no user-provided id
|
|
161
158
|
let finalChild = child;
|
|
162
159
|
if (child.props.id === undefined) {
|
|
163
160
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -197,10 +194,8 @@ function useComputedTabs(props) {
|
|
|
197
194
|
}, [visibleTabs]);
|
|
198
195
|
const prevChildren = usePrevious(() => children);
|
|
199
196
|
const cacheTabsChildren = useEventCallback(() => {
|
|
200
|
-
// If this is a full update clear the cache
|
|
201
197
|
if (shouldUpdate.current === 'full')
|
|
202
198
|
tabsChildrenCache.current = new Map();
|
|
203
|
-
// We can't cache if the tabListRef is not available
|
|
204
199
|
if (!tabListRef.current?.children || !tabsChildrenCache.current)
|
|
205
200
|
return;
|
|
206
201
|
const tabsChildren = tabListRef.current?.children;
|
|
@@ -209,7 +204,6 @@ function useComputedTabs(props) {
|
|
|
209
204
|
if (!child || !childElement)
|
|
210
205
|
return;
|
|
211
206
|
tabsChildrenCache.current?.set(childValue, {
|
|
212
|
-
// @ts-ignore
|
|
213
207
|
child,
|
|
214
208
|
element: childElement,
|
|
215
209
|
width: childElement.offsetWidth,
|
|
@@ -222,10 +216,6 @@ function useComputedTabs(props) {
|
|
|
222
216
|
return undefined;
|
|
223
217
|
let selectedIndex = -1;
|
|
224
218
|
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
219
|
selectedIndex = Array.from(visibleTabsRef.current).findIndex(([key]) => {
|
|
230
220
|
return key === value;
|
|
231
221
|
});
|
|
@@ -244,19 +234,17 @@ function useComputedTabs(props) {
|
|
|
244
234
|
].join('\n'),
|
|
245
235
|
});
|
|
246
236
|
}
|
|
247
|
-
// provide the first tab as default selected tab when value is invalid
|
|
248
237
|
return selectedTabElement || children[0];
|
|
249
238
|
});
|
|
250
|
-
// main logic for computing whether show more menu when variant is 'moreMenu'
|
|
251
239
|
const computeMoreMenuWithCache = useEventCallback(() => {
|
|
252
240
|
if (variant !== 'moreMenu' || !tabsChildrenCache.current)
|
|
253
241
|
return;
|
|
254
|
-
const width = scrollerRef.current?.offsetWidth || 0;
|
|
242
|
+
const width = scrollerRef.current?.offsetWidth || 0;
|
|
255
243
|
const visibleWidth = width +
|
|
256
244
|
pillGap -
|
|
257
|
-
(tabListRef.current ? getHorizontalPadding(tabListRef.current) : 0);
|
|
245
|
+
(tabListRef.current ? getHorizontalPadding(tabListRef.current) : 0);
|
|
258
246
|
const selectedItemWidth = (value !== null && tabsChildrenCache.current.get(value)?.width) || 0;
|
|
259
|
-
const spaceForMoreBtn = moreBtnWidth.current + pillGap;
|
|
247
|
+
const spaceForMoreBtn = moreBtnWidth.current + pillGap;
|
|
260
248
|
let consumedWidth = spaceForMoreBtn;
|
|
261
249
|
let isSelectedItemVisible = false;
|
|
262
250
|
let noWidthForUnselectedTab = false;
|
|
@@ -267,70 +255,50 @@ function useComputedTabs(props) {
|
|
|
267
255
|
const [key, itemInfo] = cache[i];
|
|
268
256
|
const { child, width: itemWidth } = itemInfo;
|
|
269
257
|
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
258
|
if (noWidthForUnselectedTab && key !== value) {
|
|
275
259
|
hiddenItems.set(key, child);
|
|
276
260
|
continue;
|
|
277
261
|
}
|
|
278
262
|
if (isSelectedItemVisible) {
|
|
279
|
-
// Check if this is the last tab in the list
|
|
280
263
|
if (cache.length === i + 1) {
|
|
281
|
-
// Check if there is enough space to accommodate the tab without the more button
|
|
282
264
|
if (visibleWidth >= consumedWidth - spaceForMoreBtn + width) {
|
|
283
|
-
// There's enough space available, show the last tab
|
|
284
265
|
visibleItems.set(key, child);
|
|
285
266
|
}
|
|
286
267
|
else {
|
|
287
|
-
// There's not enough space available, put the last item inside more menu
|
|
288
268
|
hiddenItems.set(key, child);
|
|
289
269
|
}
|
|
290
270
|
}
|
|
291
271
|
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
272
|
if (visibleWidth >= consumedWidth + width) {
|
|
295
273
|
consumedWidth += width;
|
|
296
|
-
// There's enough space available, show this tab in the list
|
|
297
274
|
visibleItems.set(key, child);
|
|
298
275
|
}
|
|
299
276
|
else {
|
|
300
|
-
// There's not enoguh space available put the tab inside the more menu (hide it)
|
|
301
277
|
hiddenItems.set(key, child);
|
|
302
278
|
noWidthForUnselectedTab = true;
|
|
303
279
|
}
|
|
304
280
|
}
|
|
305
281
|
continue;
|
|
306
282
|
}
|
|
307
|
-
// The selected tab is not visible yet. Check if the current tab is selected
|
|
308
283
|
if (key === value) {
|
|
309
|
-
// Show the selected tab, it should never be inside the more menu
|
|
310
284
|
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
285
|
if (cache.length !== i + 1)
|
|
313
286
|
consumedWidth += width;
|
|
314
287
|
isSelectedItemVisible = true;
|
|
315
288
|
continue;
|
|
316
289
|
}
|
|
317
|
-
// The current tab is not selected. Check if there is enough space for the current tab, the selected tab and more button
|
|
318
290
|
if (visibleWidth >= consumedWidth + width + selectedItemWidth) {
|
|
319
291
|
consumedWidth += width;
|
|
320
292
|
visibleItems.set(key, child);
|
|
321
293
|
continue;
|
|
322
294
|
}
|
|
323
|
-
// There's not enough space available. Check if current tab immediately precedes the last selected tab
|
|
324
295
|
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
296
|
const hasSpaceForLast2Items = visibleWidth >=
|
|
327
297
|
consumedWidth - spaceForMoreBtn + width + selectedItemWidth;
|
|
328
298
|
if (isSecondToLast && hasSpaceForLast2Items) {
|
|
329
|
-
// If it's second to last and has enough space, show the tab
|
|
330
299
|
visibleItems.set(key, child);
|
|
331
300
|
}
|
|
332
301
|
else {
|
|
333
|
-
// Otherwise hide the tab and put it in the more menu
|
|
334
302
|
hiddenItems.set(key, child);
|
|
335
303
|
noWidthForUnselectedTab = true;
|
|
336
304
|
}
|
|
@@ -344,7 +312,6 @@ function useComputedTabs(props) {
|
|
|
344
312
|
else {
|
|
345
313
|
setShowMore(false);
|
|
346
314
|
}
|
|
347
|
-
// @ts-ignore
|
|
348
315
|
const newVisibleTabs = new Map();
|
|
349
316
|
let childIndex = 0;
|
|
350
317
|
for (const [childValue, child] of visibleItems.entries()) {
|
|
@@ -353,10 +320,8 @@ function useComputedTabs(props) {
|
|
|
353
320
|
}
|
|
354
321
|
setVisibleTabs(newVisibleTabs);
|
|
355
322
|
shouldUpdate.current = false;
|
|
356
|
-
// Check if visibleTabs or hiddenTabs has changed
|
|
357
323
|
if (!isEqual([...(visibleTabsRef.current?.keys() || [])], [...visibleItems.keys()]) ||
|
|
358
324
|
!isEqual([...(hiddenTabsRef.current?.keys() || [])], [...hiddenItems.keys()])) {
|
|
359
|
-
// If it has changed, invoke onGroupInfoUpdate with the updated group data
|
|
360
325
|
onGroupInfoUpdate?.([...visibleItems.keys()], [...hiddenItems.keys()]);
|
|
361
326
|
}
|
|
362
327
|
visibleTabsRef.current = visibleItems;
|
|
@@ -376,15 +341,12 @@ function useComputedTabs(props) {
|
|
|
376
341
|
floatingUnderlineLeftMotionValue.set(targetLeft);
|
|
377
342
|
return;
|
|
378
343
|
}
|
|
379
|
-
// Only animate if either value has changed
|
|
380
344
|
if (currentWidth !== targetWidth || currentLeft !== targetLeft) {
|
|
381
345
|
const transition = motionTransition['spring-01-fast'];
|
|
382
346
|
animate(floatingUnderlineWidthMotionValue, targetWidth, transition);
|
|
383
347
|
animate(floatingUnderlineLeftMotionValue, targetLeft, transition);
|
|
384
348
|
}
|
|
385
349
|
});
|
|
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
350
|
useEffect(() => {
|
|
389
351
|
if (variant !== 'moreMenu')
|
|
390
352
|
return;
|
|
@@ -393,13 +355,11 @@ function useComputedTabs(props) {
|
|
|
393
355
|
}
|
|
394
356
|
if (tabsChildrenCache.current) {
|
|
395
357
|
if (!shouldUpdate.current) {
|
|
396
|
-
// Check if the rendered visibleTabs have a different width than the cached tabs
|
|
397
358
|
for (const [childValue, { childIndex: index, child },] of visibleTabs.entries()) {
|
|
398
359
|
if (shouldUpdate.current || !child)
|
|
399
360
|
continue;
|
|
400
361
|
const cachedWidth = tabsChildrenCache.current?.get(childValue)?.width;
|
|
401
362
|
const childElement = tabListRef.current?.children[index];
|
|
402
|
-
// If the cached width is different, we should perform a partial update
|
|
403
363
|
if (cachedWidth !== childElement.offsetWidth) {
|
|
404
364
|
shouldUpdate.current = 'partial';
|
|
405
365
|
}
|
|
@@ -410,7 +370,6 @@ function useComputedTabs(props) {
|
|
|
410
370
|
computeMoreMenuWithCache();
|
|
411
371
|
}
|
|
412
372
|
}
|
|
413
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
414
373
|
}, [visibleTabs, fontsLoaded]);
|
|
415
374
|
useEffect(() => {
|
|
416
375
|
if (prevChildren && children !== prevChildren) {
|
|
@@ -418,20 +377,15 @@ function useComputedTabs(props) {
|
|
|
418
377
|
shouldUpdate.current = 'full';
|
|
419
378
|
}
|
|
420
379
|
}, [children, prevChildren, processedChildren]);
|
|
421
|
-
// initial cache for variant 'moreMenu', used for computing more menu
|
|
422
380
|
useLayoutEffect(() => {
|
|
423
381
|
if (switchToMoreMenu.current && tabListRef.current?.children) {
|
|
424
382
|
switchToMoreMenu.current = false;
|
|
425
|
-
// initial cache of tabsChildrenCache
|
|
426
383
|
tabsChildrenCache.current = new Map();
|
|
427
384
|
cacheTabsChildren();
|
|
428
|
-
// initial cache of moreBtnWidth
|
|
429
385
|
moreBtnWidth.current = moreRef.current?.offsetWidth || 0;
|
|
430
386
|
computeMoreMenuWithCache();
|
|
431
387
|
}
|
|
432
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
433
388
|
}, [showMore]);
|
|
434
|
-
// handle switch variant situation
|
|
435
389
|
useOnReRender(() => {
|
|
436
390
|
if (variant !== 'moreMenu') {
|
|
437
391
|
setShowMore(false);
|
|
@@ -441,41 +395,25 @@ function useComputedTabs(props) {
|
|
|
441
395
|
switchToMoreMenu.current = true;
|
|
442
396
|
setShowMore(true);
|
|
443
397
|
}
|
|
444
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
445
398
|
}, [variant]);
|
|
446
|
-
// Check if we need to update the cache and update the more menu when any tab child is resized
|
|
447
399
|
useEffect(() => {
|
|
448
400
|
if (variant !== 'moreMenu')
|
|
449
401
|
return;
|
|
450
402
|
let initialObservation = true;
|
|
451
403
|
const handleResize = throttle((entries) => {
|
|
452
404
|
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
405
|
initialObservation = false;
|
|
459
406
|
return;
|
|
460
407
|
}
|
|
461
408
|
if (entries) {
|
|
462
|
-
// Partially update the cache before computing the more menu
|
|
463
409
|
cacheTabsChildren();
|
|
464
410
|
if (moreRef.current)
|
|
465
411
|
moreBtnWidth.current = moreRef.current.offsetWidth;
|
|
466
412
|
}
|
|
467
413
|
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
414
|
computeFloatingUnderline(true);
|
|
476
415
|
}, 200);
|
|
477
416
|
let resizeObserver;
|
|
478
|
-
// Check if ResizeObserver is supported in this environment
|
|
479
417
|
if (typeof ResizeObserverClass !== 'undefined') {
|
|
480
418
|
resizeObserver = new ResizeObserverClass(handleResize);
|
|
481
419
|
if (scrollerRef.current)
|
|
@@ -483,10 +421,8 @@ function useComputedTabs(props) {
|
|
|
483
421
|
if (tabListRef && tabListRef.current) {
|
|
484
422
|
const tabsChildren = tabListRef.current.children;
|
|
485
423
|
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
424
|
if (pill && index === tabsChildren.length - 1)
|
|
488
425
|
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
426
|
if (!pill && index >= tabsChildren.length - 2)
|
|
491
427
|
return;
|
|
492
428
|
resizeObserver?.observe(child);
|
|
@@ -497,30 +433,19 @@ function useComputedTabs(props) {
|
|
|
497
433
|
handleResize.cancel();
|
|
498
434
|
resizeObserver?.disconnect();
|
|
499
435
|
};
|
|
500
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
501
436
|
}, [variant, pill, ResizeObserverClass]);
|
|
502
437
|
useEffect(() => {
|
|
503
|
-
// The ResizeObserver for the moreMenu automatically handles floating underline computation
|
|
504
438
|
if (variant === 'moreMenu')
|
|
505
439
|
return;
|
|
506
440
|
let initialObservation = true;
|
|
507
441
|
const handleSelectedTabResize = throttle(() => {
|
|
508
442
|
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
443
|
initialObservation = false;
|
|
518
444
|
return;
|
|
519
445
|
}
|
|
520
446
|
computeFloatingUnderline(true);
|
|
521
447
|
}, 16);
|
|
522
448
|
let selectedTabResizeObserver;
|
|
523
|
-
// Check if ResizeObserver is supported in this environment
|
|
524
449
|
if (typeof ResizeObserverClass !== 'undefined') {
|
|
525
450
|
selectedTabResizeObserver = new ResizeObserverClass(handleSelectedTabResize);
|
|
526
451
|
const selectedTabElement = getSelectedTabElement();
|
|
@@ -532,24 +457,19 @@ function useComputedTabs(props) {
|
|
|
532
457
|
handleSelectedTabResize.cancel();
|
|
533
458
|
selectedTabResizeObserver?.disconnect();
|
|
534
459
|
};
|
|
535
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
536
460
|
}, [variant, value, ResizeObserverClass]);
|
|
537
461
|
const prevVariant = usePrevious(() => variant);
|
|
538
462
|
useEffect(() => {
|
|
539
|
-
// If only the variant is changed, we need to update the floating underline without animation
|
|
540
463
|
if (prevVariant !== variant) {
|
|
541
464
|
computeFloatingUnderline(true);
|
|
542
465
|
}
|
|
543
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
544
466
|
}, [variant]);
|
|
545
467
|
useEffect(() => {
|
|
546
468
|
if (variant === 'moreMenu' &&
|
|
547
469
|
value !== null &&
|
|
548
470
|
hiddenTabsRef.current?.has(value)) {
|
|
549
|
-
// Re-compute when a hidden tab (i.e. tab in the more menu) is selected
|
|
550
471
|
computeMoreMenuWithCache();
|
|
551
472
|
}
|
|
552
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
553
473
|
}, [value]);
|
|
554
474
|
return {
|
|
555
475
|
visibleTabsChildren,
|
|
@@ -569,9 +489,6 @@ function getHorizontalPadding(element) {
|
|
|
569
489
|
}
|
|
570
490
|
|
|
571
491
|
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
492
|
const useTabsScroller = ({ enable, scrollerRef, tabListRef, scroll, ScrollButtonStartProps, ScrollButtonEndProps, }) => {
|
|
576
493
|
const [displayStartScroll, setDisplayStartScroll] = useState(false);
|
|
577
494
|
const [displayEndScroll, setDisplayEndScroll] = useState(false);
|
|
@@ -588,10 +505,8 @@ const useTabsScroller = ({ enable, scrollerRef, tabListRef, scroll, ScrollButton
|
|
|
588
505
|
setDisplayStartScroll(scrollLeft > 0);
|
|
589
506
|
setDisplayEndScroll(maxScrollLeft - scrollLeft > THRESHOLD_FOR_SUB_PIXEL_CALCULATION);
|
|
590
507
|
}, 100);
|
|
591
|
-
// add scroll event listener
|
|
592
508
|
const currentTabsRef = scrollerRef.current;
|
|
593
509
|
currentTabsRef?.addEventListener('scroll', checkScroll);
|
|
594
|
-
// ResizeObserver for tabs list
|
|
595
510
|
let resizeObserver;
|
|
596
511
|
if (typeof ResizeObserverClass !== 'undefined') {
|
|
597
512
|
resizeObserver = new ResizeObserverClass(checkScroll);
|
|
@@ -599,11 +514,10 @@ const useTabsScroller = ({ enable, scrollerRef, tabListRef, scroll, ScrollButton
|
|
|
599
514
|
resizeObserver.observe(currentTabsRef);
|
|
600
515
|
}
|
|
601
516
|
}
|
|
602
|
-
checkScroll();
|
|
517
|
+
checkScroll();
|
|
603
518
|
return () => {
|
|
604
519
|
currentTabsRef?.removeEventListener('scroll', checkScroll);
|
|
605
520
|
checkScroll.cancel();
|
|
606
|
-
// Disconnect the ResizeObserver on cleanup
|
|
607
521
|
resizeObserver?.disconnect();
|
|
608
522
|
};
|
|
609
523
|
}, [enable, scrollerRef, ResizeObserverClass]);
|
|
@@ -651,12 +565,12 @@ const useTabsScroller = ({ enable, scrollerRef, tabListRef, scroll, ScrollButton
|
|
|
651
565
|
]);
|
|
652
566
|
};
|
|
653
567
|
|
|
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"};
|
|
568
|
+
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
569
|
|
|
656
570
|
const DEFAULT_PILL_GAP = 4;
|
|
657
571
|
const Tabs = forwardRef((inProps, ref) => {
|
|
658
572
|
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;
|
|
573
|
+
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
574
|
const pillGap = pill ? pillGapProp : 0;
|
|
661
575
|
const tabsRef = useRef(null);
|
|
662
576
|
const scrollerRef = useRef(null);
|
|
@@ -669,7 +583,7 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
669
583
|
const floatingUnderlineOpacityMotionValue = useMotionValue(1);
|
|
670
584
|
const floatingUnderlineTransition = useMotionSafeTransition(motionTransition['spring-01-fast']);
|
|
671
585
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
672
|
-
const cls =
|
|
586
|
+
const cls = useClassesWithMode('tabs', classes, className);
|
|
673
587
|
const { onGroupInfoUpdate: groupInfoUpdateHandler, ...restProps } = props;
|
|
674
588
|
const { getRootProps, contextValue, selectedValue: value, } = useTabsList({
|
|
675
589
|
...restProps,
|
|
@@ -692,7 +606,6 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
692
606
|
let tabsMeta;
|
|
693
607
|
if (tabsNode) {
|
|
694
608
|
const rect = tabsNode.getBoundingClientRect();
|
|
695
|
-
// create a new object with ClientRect class props + scrollLeft
|
|
696
609
|
tabsMeta = {
|
|
697
610
|
clientWidth: tabsNode.clientWidth,
|
|
698
611
|
scrollLeft: tabsNode.scrollLeft,
|
|
@@ -710,7 +623,6 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
710
623
|
if (tab) {
|
|
711
624
|
const rect = tab.getBoundingClientRect();
|
|
712
625
|
tabMeta = {
|
|
713
|
-
// Use offsetWidth/offsetHeight to negate any transforms that might be applied
|
|
714
626
|
height: tab.offsetHeight,
|
|
715
627
|
width: tab.offsetWidth,
|
|
716
628
|
x: rect.x,
|
|
@@ -736,7 +648,6 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
736
648
|
return;
|
|
737
649
|
}
|
|
738
650
|
if (transitionType === null || prefersReducedMotion) {
|
|
739
|
-
// if transitionType is null or prefersReducedMotion, set the scroll value without animation
|
|
740
651
|
scrollerRef.current[scrollStart] = to;
|
|
741
652
|
return;
|
|
742
653
|
}
|
|
@@ -755,11 +666,9 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
755
666
|
if (!tabMeta || !tabsMeta) {
|
|
756
667
|
return;
|
|
757
668
|
}
|
|
758
|
-
// Check if the left side of the tab is out of view
|
|
759
669
|
if (tabMeta[start] < tabsMeta[start]) {
|
|
760
670
|
const nextScrollStart = tabsMeta[scrollStart] + (tabMeta[start] - tabsMeta[start]);
|
|
761
671
|
scroll(nextScrollStart, noAnimation ? null : undefined);
|
|
762
|
-
// Check if the right side of the tab is out of view
|
|
763
672
|
}
|
|
764
673
|
else if (tabMeta[end] > tabsMeta[end]) {
|
|
765
674
|
const nextScrollStart = tabsMeta[scrollStart] + Math.abs(tabMeta[end] - tabsMeta[end]);
|
|
@@ -779,16 +688,8 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
779
688
|
useEffect(() => {
|
|
780
689
|
const noAnimationWhenFirstRender = floatingUnderlineWidthMotionValue.get() === 0;
|
|
781
690
|
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
691
|
scrollSelectedIntoView(noAnimationWhenFirstRender);
|
|
789
692
|
}
|
|
790
|
-
// If the visibleTabsChildren has been updated but selected tab has not changed,
|
|
791
|
-
// we don't need to animate the floating underline
|
|
792
693
|
const noAnimationWhenNoValueChange = prevVisibleTabsChildren.current !== visibleTabsChildren &&
|
|
793
694
|
prevValueAfterChildrenUpdate.current === value;
|
|
794
695
|
if (prevVisibleTabsChildren.current !== visibleTabsChildren) {
|
|
@@ -796,16 +697,16 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
796
697
|
prevValueAfterChildrenUpdate.current = value;
|
|
797
698
|
}
|
|
798
699
|
computeFloatingUnderline(noAnimationWhenFirstRender || noAnimationWhenNoValueChange);
|
|
799
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
800
700
|
}, [visibleTabsChildren, value]);
|
|
801
701
|
const tabsContextValue = useMemo(() => ({
|
|
802
702
|
pill,
|
|
803
703
|
pillGap,
|
|
804
704
|
color,
|
|
705
|
+
size,
|
|
805
706
|
setFloatingUnderlineVisibility: (isVisible) => {
|
|
806
707
|
floatingUnderlineOpacityMotionValue.set(isVisible ? 1 : 0);
|
|
807
708
|
},
|
|
808
|
-
}), [floatingUnderlineOpacityMotionValue, pill, pillGap, color]);
|
|
709
|
+
}), [floatingUnderlineOpacityMotionValue, pill, pillGap, color, size]);
|
|
809
710
|
if (!processedChildren.size) {
|
|
810
711
|
return null;
|
|
811
712
|
}
|
|
@@ -816,7 +717,7 @@ const Tabs = forwardRef((inProps, ref) => {
|
|
|
816
717
|
'scroll-left': !!scrollButtonStart,
|
|
817
718
|
'scroll-right': !!scrollButtonEnd,
|
|
818
719
|
'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: {
|
|
720
|
+
}, 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
721
|
left: floatingUnderlineLeftMotionValue,
|
|
821
722
|
width: floatingUnderlineWidthMotionValue,
|
|
822
723
|
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;
|