@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/SwipeableDrawer.js
CHANGED
|
@@ -19,15 +19,12 @@ import './chunks/Backdrop.js';
|
|
|
19
19
|
|
|
20
20
|
var SwipeableDrawer$1 = {"sui-swipeable-drawer-header-drag":"sui-swipeable-drawer-header-drag"};
|
|
21
21
|
|
|
22
|
-
// Keeps track of whether everything is good to go or not, in the most efficient way possible
|
|
23
22
|
function useReady() {
|
|
24
23
|
const [ready, setReady] = useState(false);
|
|
25
24
|
const [readyMap, updateReadyMap] = useState({});
|
|
26
25
|
const registerReady = useCallback((key) => {
|
|
27
|
-
// Register the check we're gonna wait for until it's ready
|
|
28
26
|
updateReadyMap((ready) => ({ ...ready, [key]: false }));
|
|
29
27
|
return () => {
|
|
30
|
-
// Set it to ready
|
|
31
28
|
updateReadyMap((ready) => ({ ...ready, [key]: true }));
|
|
32
29
|
};
|
|
33
30
|
}, []);
|
|
@@ -47,40 +44,26 @@ function useReady() {
|
|
|
47
44
|
return { ready, registerReady };
|
|
48
45
|
}
|
|
49
46
|
|
|
50
|
-
// Hook for determining the size of an element using the Resize Observer API
|
|
51
47
|
const observerOptions = {
|
|
52
|
-
// Respond to changes to padding, happens often on iOS when using env(safe-area-inset-bottom)
|
|
53
|
-
// And the user hides or shows the Safari browser toolbar
|
|
54
48
|
box: 'border-box',
|
|
55
49
|
};
|
|
56
|
-
/**
|
|
57
|
-
* Hook for determining the size of an element using the Resize Observer API.
|
|
58
|
-
*
|
|
59
|
-
* @param ref - A React ref to an element
|
|
60
|
-
*/
|
|
61
50
|
function useElementSizeObserver(ref, { enabled, resizeSourceRef, }) {
|
|
62
51
|
const [size, setSize] = useState(0);
|
|
63
52
|
const handleResize = useCallback((entries) => {
|
|
64
|
-
// we only observe one element, so accessing the first entry here is fine
|
|
65
53
|
const entry = entries?.[0];
|
|
66
54
|
if (!entry) {
|
|
67
|
-
// Early return if no entry - can happen during observer disconnect
|
|
68
55
|
return;
|
|
69
56
|
}
|
|
70
57
|
const el = entry.target;
|
|
71
58
|
if (!el) {
|
|
72
|
-
// Early return if no target element
|
|
73
59
|
return;
|
|
74
60
|
}
|
|
75
|
-
// Prefer intrinsic content size to visible height so drag doesn’t change the measured height
|
|
76
|
-
// @juggle/resize-observer provides consistent borderBoxSize access across browsers
|
|
77
61
|
const roBlock = entry?.borderBoxSize?.[0]?.blockSize ?? 0;
|
|
78
62
|
const contentRectH = entry?.contentRect?.height ?? 0;
|
|
79
63
|
const scrollH = el?.scrollHeight ?? 0;
|
|
80
64
|
const offsetH = el?.offsetHeight ?? 0;
|
|
81
65
|
const newSize = Math.max(scrollH, roBlock, contentRectH, offsetH);
|
|
82
66
|
setSize(newSize);
|
|
83
|
-
// Update resize source if provided
|
|
84
67
|
if (resizeSourceRef) {
|
|
85
68
|
resizeSourceRef.current = 'element';
|
|
86
69
|
}
|
|
@@ -96,20 +79,15 @@ function useElementSizeObserver(ref, { enabled, resizeSourceRef, }) {
|
|
|
96
79
|
const el = ref.current;
|
|
97
80
|
if (!el || !el.isConnected)
|
|
98
81
|
return;
|
|
99
|
-
// @juggle/resize-observer provides cross-browser compatibility and polyfills
|
|
100
82
|
resizeObserver = new ResizeObserver(handleResize);
|
|
101
83
|
resizeObserver.observe(el, observerOptions);
|
|
102
|
-
// Seed an initial measurement in case RO hasn't fired yet
|
|
103
84
|
initialMeasurementRafId = requestAnimationFrame(() => {
|
|
104
85
|
const initial = Math.max(el.scrollHeight, el.offsetHeight, el.getBoundingClientRect().height);
|
|
105
86
|
if (initial > 0) {
|
|
106
87
|
setSize(initial);
|
|
107
88
|
}
|
|
108
|
-
// else keep waiting for RO to update on next ticks
|
|
109
89
|
});
|
|
110
90
|
};
|
|
111
|
-
// If the element is not yet mounted (e.g. Modal shouldRender=false), keep
|
|
112
|
-
// polling via rAF until it's available, then attach the observer.
|
|
113
91
|
const waitForElement = () => {
|
|
114
92
|
if (ref.current) {
|
|
115
93
|
startObserving();
|
|
@@ -137,8 +115,6 @@ function useElementSizeObserver(ref, { enabled, resizeSourceRef, }) {
|
|
|
137
115
|
return enabled ? size : 0;
|
|
138
116
|
}
|
|
139
117
|
|
|
140
|
-
// Hook for measuring drawer dimensions
|
|
141
|
-
// Hook for tracking viewport height
|
|
142
118
|
function useMaxHeight(registerReady) {
|
|
143
119
|
const { globalThis } = useWindowContext();
|
|
144
120
|
const setReady = useMemo(() => {
|
|
@@ -147,28 +123,23 @@ function useMaxHeight(registerReady) {
|
|
|
147
123
|
const [maxHeight, setMaxHeight] = useState(() => globalThis.innerHeight ?? 0);
|
|
148
124
|
const raf = useRef(0);
|
|
149
125
|
const maxReadyCalledRef = useRef(false);
|
|
150
|
-
// Reset the ready flag when setReady changes (drawer reset)
|
|
151
126
|
useLayoutEffect(() => {
|
|
152
127
|
maxReadyCalledRef.current = false;
|
|
153
128
|
}, [setReady]);
|
|
154
129
|
useLayoutEffect(() => {
|
|
155
130
|
const handleResize = () => {
|
|
156
131
|
if (raf.current) {
|
|
157
|
-
// bail to throttle the amount of resize changes
|
|
158
132
|
return;
|
|
159
133
|
}
|
|
160
|
-
// throttle state changes using rAF
|
|
161
134
|
raf.current = requestAnimationFrame(() => {
|
|
162
|
-
// Check if cleanup already ran (raf.current would be 0)
|
|
163
135
|
if (raf.current !== 0) {
|
|
164
|
-
setMaxHeight(globalThis.innerHeight);
|
|
136
|
+
setMaxHeight(globalThis.innerHeight);
|
|
165
137
|
raf.current = 0;
|
|
166
138
|
}
|
|
167
139
|
});
|
|
168
140
|
};
|
|
169
141
|
globalThis.addEventListener('resize', handleResize);
|
|
170
142
|
setMaxHeight(globalThis.innerHeight);
|
|
171
|
-
// Call setReady exactly once for window height readiness
|
|
172
143
|
if (setReady && !maxReadyCalledRef.current) {
|
|
173
144
|
maxReadyCalledRef.current = true;
|
|
174
145
|
setReady();
|
|
@@ -180,9 +151,6 @@ function useMaxHeight(registerReady) {
|
|
|
180
151
|
}, [setReady, globalThis]);
|
|
181
152
|
return maxHeight;
|
|
182
153
|
}
|
|
183
|
-
/**
|
|
184
|
-
* Custom hook to preserve last non-zero height values
|
|
185
|
-
*/
|
|
186
154
|
function usePreservedHeight(currentHeight) {
|
|
187
155
|
const lastHeightRef = useRef(0);
|
|
188
156
|
useLayoutEffect(() => {
|
|
@@ -194,11 +162,7 @@ function usePreservedHeight(currentHeight) {
|
|
|
194
162
|
}
|
|
195
163
|
function useDimensions({ contentRef, footerEnabled, footerRef, headerEnabled, headerRef, registerReady, resizeSourceRef, open, }) {
|
|
196
164
|
const setReady = useMemo(() => registerReady('contentHeight'), [registerReady]);
|
|
197
|
-
// Do not re-register contentHeight readiness on disconnect; register once above and let
|
|
198
|
-
// the ResizeObserver drive readiness when size > 0. This avoids readiness loops.
|
|
199
|
-
// (Intentionally removed disconnection re-register logic)
|
|
200
165
|
const maxHeight = useMaxHeight(registerReady);
|
|
201
|
-
// Measure all elements - only when drawer is open
|
|
202
166
|
const headerHeight = useElementSizeObserver(headerRef, {
|
|
203
167
|
enabled: open && headerEnabled,
|
|
204
168
|
resizeSourceRef,
|
|
@@ -211,12 +175,9 @@ function useDimensions({ contentRef, footerEnabled, footerRef, headerEnabled, he
|
|
|
211
175
|
enabled: open && footerEnabled,
|
|
212
176
|
resizeSourceRef,
|
|
213
177
|
});
|
|
214
|
-
// Preserve last non-zero heights to avoid collapsing to 0 when the
|
|
215
|
-
// modal/portal temporarily unmounts or RO reports 0 during transitions
|
|
216
178
|
const effectiveContentHeight = usePreservedHeight(contentHeight);
|
|
217
179
|
const effectiveHeaderHeight = usePreservedHeight(headerHeight);
|
|
218
180
|
const effectiveFooterHeight = usePreservedHeight(footerHeight);
|
|
219
|
-
// When content is measured (>0), mark ready for contentHeight
|
|
220
181
|
useLayoutEffect(() => {
|
|
221
182
|
if (!setReady)
|
|
222
183
|
return;
|
|
@@ -225,7 +186,6 @@ function useDimensions({ contentRef, footerEnabled, footerRef, headerEnabled, he
|
|
|
225
186
|
setReady();
|
|
226
187
|
}
|
|
227
188
|
}, [contentHeight, contentRef, setReady]);
|
|
228
|
-
// Calculate available space for content, ensuring it's never negative
|
|
229
189
|
const availableContentSpace = Math.max(0, maxHeight - effectiveHeaderHeight - effectiveFooterHeight);
|
|
230
190
|
const minHeight = Math.min(availableContentSpace, effectiveContentHeight) +
|
|
231
191
|
effectiveHeaderHeight +
|
|
@@ -238,7 +198,6 @@ function useDimensions({ contentRef, footerEnabled, footerRef, headerEnabled, he
|
|
|
238
198
|
};
|
|
239
199
|
}
|
|
240
200
|
|
|
241
|
-
// Hook for calculating snap points
|
|
242
201
|
function roundAndCheckForNaN(value) {
|
|
243
202
|
const rounded = Math.round(value);
|
|
244
203
|
if (Number.isNaN(rounded)) {
|
|
@@ -246,15 +205,12 @@ function roundAndCheckForNaN(value) {
|
|
|
246
205
|
}
|
|
247
206
|
return rounded;
|
|
248
207
|
}
|
|
249
|
-
// Clamp function with clear NaN handling
|
|
250
208
|
function clamp(number, lower, upper) {
|
|
251
209
|
number = +number;
|
|
252
210
|
lower = +lower;
|
|
253
211
|
upper = +upper;
|
|
254
|
-
// Handle NaN values with sensible defaults
|
|
255
212
|
const safeLower = Number.isNaN(lower) ? 0 : lower;
|
|
256
213
|
const safeUpper = Number.isNaN(upper) ? Number.POSITIVE_INFINITY : upper;
|
|
257
|
-
// Ensure lower <= upper to avoid invalid ranges
|
|
258
214
|
const finalLower = Math.min(safeLower, safeUpper);
|
|
259
215
|
const finalUpper = Math.max(safeLower, safeUpper);
|
|
260
216
|
if (Number.isNaN(number)) {
|
|
@@ -263,11 +219,9 @@ function clamp(number, lower, upper) {
|
|
|
263
219
|
return Math.min(Math.max(number, finalLower), finalUpper);
|
|
264
220
|
}
|
|
265
221
|
function processSnapPoints(snapPoints, maxHeight) {
|
|
266
|
-
// Validate maxHeight input
|
|
267
222
|
if (!Number.isFinite(maxHeight) || maxHeight <= 0) {
|
|
268
223
|
throw new Error(`Invalid maxHeight: ${maxHeight}. Must be a positive finite number.`);
|
|
269
224
|
}
|
|
270
|
-
// Match React Spring Bottom Sheet implementation exactly
|
|
271
225
|
const safeSnaps = []
|
|
272
226
|
.concat(snapPoints)
|
|
273
227
|
.map(roundAndCheckForNaN);
|
|
@@ -276,7 +230,6 @@ function processSnapPoints(snapPoints, maxHeight) {
|
|
|
276
230
|
return acc;
|
|
277
231
|
}, new Set());
|
|
278
232
|
const processedPoints = Array.from(snapPointsDedupedSet);
|
|
279
|
-
// Handle empty snap points array
|
|
280
233
|
if (processedPoints.length === 0) {
|
|
281
234
|
throw new Error('No valid snap points available. The snapPoints function must return at least one valid number.\n' +
|
|
282
235
|
'Example: snapPoints: ({ minHeight, maxHeight }) => [minHeight, maxHeight]');
|
|
@@ -316,7 +269,6 @@ function useSnapPoints({ contentRef, footerEnabled, footerRef, getSnapPoints, he
|
|
|
316
269
|
})
|
|
317
270
|
: [0], maxHeight);
|
|
318
271
|
function findSnap(numberOrCallback) {
|
|
319
|
-
// Defensive check: should never happen due to processSnapPoints validation
|
|
320
272
|
if (snapPoints.length === 0) {
|
|
321
273
|
throw new Error('Cannot find snap point: no snap points available');
|
|
322
274
|
}
|
|
@@ -334,7 +286,6 @@ function useSnapPoints({ contentRef, footerEnabled, footerRef, getSnapPoints, he
|
|
|
334
286
|
});
|
|
335
287
|
}
|
|
336
288
|
catch (error) {
|
|
337
|
-
// If callback throws, fall back to current position or minSnap
|
|
338
289
|
unsafeSearch = heightRef.current ?? minSnap;
|
|
339
290
|
}
|
|
340
291
|
}
|
|
@@ -346,69 +297,51 @@ function useSnapPoints({ contentRef, footerEnabled, footerRef, getSnapPoints, he
|
|
|
346
297
|
querySnap = roundAndCheckForNaN(unsafeSearch);
|
|
347
298
|
}
|
|
348
299
|
catch (error) {
|
|
349
|
-
// If number is invalid (NaN, etc), fall back to current position or minSnap
|
|
350
300
|
querySnap = heightRef.current ?? minSnap;
|
|
351
301
|
}
|
|
352
|
-
// Support index-based selection: if querySnap is a small integer and within bounds, treat as index
|
|
353
302
|
const isValidIndex = querySnap >= 0 &&
|
|
354
303
|
querySnap < snapPoints.length &&
|
|
355
304
|
Number.isInteger(querySnap);
|
|
356
305
|
if (isValidIndex) {
|
|
357
306
|
return snapPoints[querySnap];
|
|
358
307
|
}
|
|
359
|
-
// Otherwise, find closest snap point by value
|
|
360
308
|
return snapPoints.reduce((prev, curr) => Math.abs(curr - querySnap) < Math.abs(prev - querySnap) ? curr : prev, minSnap);
|
|
361
309
|
}
|
|
362
310
|
return { minSnap, maxSnap, findSnap, maxHeight, snapPoints };
|
|
363
311
|
}
|
|
364
312
|
|
|
365
|
-
//implementation for Drawer gestures
|
|
366
|
-
// Standardized spring configuration
|
|
367
313
|
const SPRING_CONFIG = {
|
|
368
314
|
type: 'spring',
|
|
369
315
|
stiffness: 600,
|
|
370
316
|
damping: 50,
|
|
371
317
|
mass: 1,
|
|
372
318
|
};
|
|
373
|
-
// Rubberband effect constants
|
|
374
319
|
const RUBBERBAND_RESISTANCE = 0.8;
|
|
375
320
|
const SINGLE_SNAP_STRETCH_FACTOR = 1.2;
|
|
376
321
|
const MULTI_SNAP_STRETCH_FACTOR = 1.8;
|
|
377
|
-
|
|
378
|
-
const
|
|
379
|
-
const
|
|
380
|
-
const
|
|
381
|
-
const DISMISS_POSITION_FACTOR = 2; // Divisor for calculating dismiss threshold (minSnap / 2)
|
|
382
|
-
// Default functions
|
|
322
|
+
const DISMISS_THRESHOLD = 50;
|
|
323
|
+
const VELOCITY_THRESHOLD = 0.1;
|
|
324
|
+
const PREDICTION_MULTIPLIER = 2;
|
|
325
|
+
const DISMISS_POSITION_FACTOR = 2;
|
|
383
326
|
function defaultSnapPoints({ minHeight }) {
|
|
384
|
-
// When no snap points are specified, just use content height
|
|
385
|
-
// This means the drawer shows content at natural size and can only dismiss
|
|
386
327
|
return [minHeight];
|
|
387
328
|
}
|
|
388
329
|
function defaultInitialSnap({ snapPoints, lastSnap: _lastSnap, }) {
|
|
389
|
-
// Default behavior: choose the smallest snap point (usually content height)
|
|
390
|
-
// Users can override this in their initialSnap function if they want lastSnap behavior
|
|
391
330
|
return Math.min(...snapPoints);
|
|
392
331
|
}
|
|
393
332
|
function useDrawerGestures(options) {
|
|
394
333
|
const { anchor, open, onClose, snapPoints: getSnapPoints = defaultSnapPoints, initialSnap: getInitialSnap = defaultInitialSnap, contentRef, headerRef, footerRef, headerEnabled, footerEnabled, } = options;
|
|
395
334
|
const { ready, registerReady } = useReady();
|
|
396
|
-
// Height tracking refs
|
|
397
335
|
const heightRef = useRef(0);
|
|
398
336
|
const lastSnapRef = useRef(null);
|
|
399
337
|
const resizeSourceRef = useRef('window');
|
|
400
|
-
// Animation cleanup ref to prevent memory leaks
|
|
401
338
|
const animationRef = useRef(null);
|
|
402
|
-
// Cleanup animations on unmount to prevent memory leaks
|
|
403
339
|
useLayoutEffect(() => {
|
|
404
340
|
return () => {
|
|
405
341
|
animationRef.current?.stop();
|
|
406
342
|
};
|
|
407
343
|
}, []);
|
|
408
|
-
// Motion values
|
|
409
344
|
const heightMotionValue = useMotionValue(0);
|
|
410
|
-
// We animate with spring only on release; during drag we set the value directly for immediate follow
|
|
411
|
-
// Ensure motion value starts with correct value when drawer opens
|
|
412
345
|
useLayoutEffect(() => {
|
|
413
346
|
if (open &&
|
|
414
347
|
ready &&
|
|
@@ -417,7 +350,6 @@ function useDrawerGestures(options) {
|
|
|
417
350
|
heightMotionValue.set(heightRef.current);
|
|
418
351
|
}
|
|
419
352
|
}, [open, ready, heightMotionValue]);
|
|
420
|
-
// Snap points calculation
|
|
421
353
|
const { minSnap, maxSnap, findSnap, maxHeight } = useSnapPoints({
|
|
422
354
|
contentRef: contentRef,
|
|
423
355
|
footerEnabled,
|
|
@@ -432,14 +364,11 @@ function useDrawerGestures(options) {
|
|
|
432
364
|
resizeSourceRef,
|
|
433
365
|
open,
|
|
434
366
|
});
|
|
435
|
-
// Calculate initial snap
|
|
436
367
|
const defaultSnap = useMemo(() => {
|
|
437
368
|
if (!ready)
|
|
438
369
|
return 0;
|
|
439
|
-
// If initial snap is a function, it receives state via findSnap
|
|
440
370
|
return findSnap(getInitialSnap);
|
|
441
371
|
}, [ready, getInitialSnap, findSnap]);
|
|
442
|
-
// Only set the initial height once per open cycle when content is present
|
|
443
372
|
const didInitRef = useRef(false);
|
|
444
373
|
const isContentPresent = !!contentRef?.current && contentRef.current.isConnected;
|
|
445
374
|
useLayoutEffect(() => {
|
|
@@ -447,16 +376,11 @@ function useDrawerGestures(options) {
|
|
|
447
376
|
return;
|
|
448
377
|
if (didInitRef.current)
|
|
449
378
|
return;
|
|
450
|
-
// Use the calculated defaultSnap (which may or may not include lastSnap based on user's initialSnap function)
|
|
451
379
|
const safeInitial = defaultSnap > 0 ? defaultSnap : minSnap;
|
|
452
|
-
// If we don't have content present and no valid fallback height, wait
|
|
453
380
|
if (!isContentPresent && safeInitial <= 0)
|
|
454
381
|
return;
|
|
455
|
-
// 1. Set to 0 immediately
|
|
456
382
|
heightMotionValue.set(0);
|
|
457
|
-
// 2. Update heightRef
|
|
458
383
|
heightRef.current = safeInitial;
|
|
459
|
-
// 3. Animate to target position
|
|
460
384
|
animationRef.current = animate(heightMotionValue, safeInitial, SPRING_CONFIG);
|
|
461
385
|
didInitRef.current = true;
|
|
462
386
|
}, [
|
|
@@ -468,13 +392,11 @@ function useDrawerGestures(options) {
|
|
|
468
392
|
heightMotionValue,
|
|
469
393
|
lastSnapRef.current,
|
|
470
394
|
]);
|
|
471
|
-
// Content resize:
|
|
472
395
|
useLayoutEffect(() => {
|
|
473
396
|
if (!open || !ready || !isContentPresent)
|
|
474
397
|
return;
|
|
475
398
|
if (!didInitRef.current)
|
|
476
|
-
return;
|
|
477
|
-
// Find closest snap point to current height (preserves user positioning)
|
|
399
|
+
return;
|
|
478
400
|
const currentHeight = heightRef.current ?? 0;
|
|
479
401
|
if (currentHeight > 0) {
|
|
480
402
|
const closestSnap = findSnap(currentHeight);
|
|
@@ -482,37 +404,29 @@ function useDrawerGestures(options) {
|
|
|
482
404
|
heightRef.current = closestSnap;
|
|
483
405
|
lastSnapRef.current = closestSnap;
|
|
484
406
|
}
|
|
485
|
-
}, [minSnap, maxSnap]);
|
|
486
|
-
// Reset init flag when closing so next open can initialize again
|
|
407
|
+
}, [minSnap, maxSnap]);
|
|
487
408
|
useLayoutEffect(() => {
|
|
488
409
|
if (!open) {
|
|
489
410
|
didInitRef.current = false;
|
|
490
|
-
// Preserve the current height as lastSnap for next open
|
|
491
411
|
if (heightRef.current > 0) {
|
|
492
412
|
lastSnapRef.current = heightRef.current;
|
|
493
413
|
}
|
|
494
|
-
// Animate motion value to 0 on close
|
|
495
414
|
animationRef.current = animate(heightMotionValue, 0, SPRING_CONFIG);
|
|
496
415
|
}
|
|
497
416
|
}, [open, heightMotionValue]);
|
|
498
|
-
// Drag handler
|
|
499
417
|
const handleDrag = useEventCallback(({ args: [{ closeOnTap = false } = {}] = [], cancel, down, last, memo = heightMotionValue.get(), movement: [_mx, _my], tap, velocity: [_, velocityY], event, }) => {
|
|
500
418
|
if (!ready) {
|
|
501
419
|
cancel();
|
|
502
420
|
return memo;
|
|
503
421
|
}
|
|
504
|
-
// Handle close on tap (backdrop tap)
|
|
505
422
|
if (closeOnTap && tap) {
|
|
506
423
|
cancel();
|
|
507
|
-
// Use timeout to avoid tap events on backdrop triggering click events underneath
|
|
508
424
|
onClose(event, 'gestureSwipe');
|
|
509
425
|
return memo;
|
|
510
426
|
}
|
|
511
|
-
// Filter out taps
|
|
512
427
|
if (tap) {
|
|
513
428
|
return memo;
|
|
514
429
|
}
|
|
515
|
-
// dismissal logic for all anchors
|
|
516
430
|
const getDismissInfo = () => {
|
|
517
431
|
switch (anchor) {
|
|
518
432
|
case 'bottom':
|
|
@@ -548,10 +462,8 @@ function useDrawerGestures(options) {
|
|
|
548
462
|
}
|
|
549
463
|
};
|
|
550
464
|
const { isDismissDirection, movement, threshold } = getDismissInfo();
|
|
551
|
-
// For horizontal drawers, only handle dismiss (no snap points)
|
|
552
465
|
const isVertical = anchor === 'top' || anchor === 'bottom';
|
|
553
466
|
if (!isVertical) {
|
|
554
|
-
// Check for dismiss condition (horizontal drawers only)
|
|
555
467
|
if (!down && isDismissDirection && movement > threshold) {
|
|
556
468
|
cancel();
|
|
557
469
|
onClose(event, 'gestureSwipe');
|
|
@@ -563,7 +475,6 @@ function useDrawerGestures(options) {
|
|
|
563
475
|
const rawY = memo + my;
|
|
564
476
|
const predictedDistance = my * velocityY;
|
|
565
477
|
const predictedY = Math.max(minSnap, Math.min(maxHeight, rawY + predictedDistance * PREDICTION_MULTIPLIER));
|
|
566
|
-
// Check for vertical dismissal - only when trying to go below minimum snap point
|
|
567
478
|
if (!down && isDismissDirection) {
|
|
568
479
|
const dismissThreshold = minSnap / DISMISS_POSITION_FACTOR;
|
|
569
480
|
const currentPosition = rawY + predictedDistance;
|
|
@@ -576,28 +487,22 @@ function useDrawerGestures(options) {
|
|
|
576
487
|
let newY;
|
|
577
488
|
if (down) {
|
|
578
489
|
if (minSnap === maxSnap) {
|
|
579
|
-
// Special case when min and max snap are the same (only one snap point)
|
|
580
490
|
if (rawY < minSnap) {
|
|
581
|
-
newY = rawY;
|
|
491
|
+
newY = rawY;
|
|
582
492
|
}
|
|
583
493
|
else {
|
|
584
|
-
// Strong resistance when dragging up beyond content
|
|
585
494
|
newY = rubberbandIfOutOfBounds(rawY, minSnap, maxSnap * SINGLE_SNAP_STRETCH_FACTOR, RUBBERBAND_RESISTANCE);
|
|
586
495
|
}
|
|
587
496
|
}
|
|
588
497
|
else {
|
|
589
|
-
// Multiple snap points: allow stretching beyond maxSnap for rubberband effect
|
|
590
498
|
newY = rubberbandIfOutOfBounds(rawY, 0, maxSnap * MULTI_SNAP_STRETCH_FACTOR, RUBBERBAND_RESISTANCE);
|
|
591
499
|
}
|
|
592
500
|
}
|
|
593
501
|
else {
|
|
594
|
-
// On release: use predicted position
|
|
595
502
|
newY = predictedY;
|
|
596
503
|
}
|
|
597
504
|
if (last) {
|
|
598
|
-
// End of gesture: find closest snap point and animate to it
|
|
599
505
|
const targetSnap = findSnap(newY);
|
|
600
|
-
// Animate to target snap point using spring
|
|
601
506
|
animationRef.current = animate(heightMotionValue, targetSnap, {
|
|
602
507
|
...SPRING_CONFIG,
|
|
603
508
|
velocity: Math.abs(velocityY) > VELOCITY_THRESHOLD ? velocityY : 0,
|
|
@@ -606,29 +511,22 @@ function useDrawerGestures(options) {
|
|
|
606
511
|
lastSnapRef.current = targetSnap;
|
|
607
512
|
return memo;
|
|
608
513
|
}
|
|
609
|
-
// During drag: directly set height to follow finger with rubberband
|
|
610
514
|
heightMotionValue.set(newY);
|
|
611
515
|
return memo;
|
|
612
516
|
});
|
|
613
|
-
// Gesture binding
|
|
614
517
|
const isVertical = anchor === 'top' || anchor === 'bottom';
|
|
615
518
|
const bind = useDrag(handleDrag, {
|
|
616
519
|
filterTaps: true,
|
|
617
520
|
});
|
|
618
|
-
// animate height for vertical drawers only
|
|
619
521
|
const heightStyle = useTransform(heightMotionValue, (y) => {
|
|
620
|
-
// Ensure drawer never exceeds viewport bounds
|
|
621
522
|
const clamped = Math.max(0, Math.min(y, maxHeight));
|
|
622
523
|
return `${Math.round(clamped)}px`;
|
|
623
524
|
});
|
|
624
|
-
// Imperative snapTo function
|
|
625
525
|
const snapTo = useCallback((numberOrCallback) => {
|
|
626
526
|
if (!ready)
|
|
627
527
|
return;
|
|
628
528
|
const targetSnap = findSnap(numberOrCallback);
|
|
629
|
-
// Animate to target snap point
|
|
630
529
|
animationRef.current = animate(heightMotionValue, targetSnap, SPRING_CONFIG);
|
|
631
|
-
// Update refs
|
|
632
530
|
heightRef.current = targetSnap;
|
|
633
531
|
lastSnapRef.current = targetSnap;
|
|
634
532
|
}, [ready, findSnap, heightMotionValue, heightRef, lastSnapRef]);
|
|
@@ -649,45 +547,16 @@ function useDrawerGestures(options) {
|
|
|
649
547
|
};
|
|
650
548
|
}
|
|
651
549
|
|
|
652
|
-
/**
|
|
653
|
-
* SwipeableDrawer Component - Gesture-enhanced drawer with swipe support
|
|
654
|
-
*
|
|
655
|
-
* Wraps the base Drawer component and adds touch/mouse gesture support for resizing and closing.
|
|
656
|
-
* Perfect for mobile bottom sheets and interactive panels.
|
|
657
|
-
*
|
|
658
|
-
* @example
|
|
659
|
-
* ```tsx
|
|
660
|
-
* bottom sheet with gestures
|
|
661
|
-
* <SwipeableDrawer
|
|
662
|
-
* open={open}
|
|
663
|
-
* onClose={onClose}
|
|
664
|
-
* anchor="bottom"
|
|
665
|
-
* gestureControlsProps={{
|
|
666
|
-
* snapPoints: ({ minHeight, maxHeight }) => [
|
|
667
|
-
* minHeight, // Content height
|
|
668
|
-
* maxHeight * 0.6, // 60% of screen
|
|
669
|
-
* maxHeight // Full screen
|
|
670
|
-
* ],
|
|
671
|
-
* initialSnap: 0 // Start at content height
|
|
672
|
-
* }}
|
|
673
|
-
* >
|
|
674
|
-
* <Content />
|
|
675
|
-
* </SwipeableDrawer>
|
|
676
|
-
* ```
|
|
677
|
-
*/
|
|
678
550
|
const SwipeableDrawer = forwardRef((inProps, ref) => {
|
|
679
551
|
const props = useThemeProps({
|
|
680
552
|
props: inProps,
|
|
681
553
|
name: 'SwipeableDrawer',
|
|
682
554
|
});
|
|
683
555
|
const { anchor = 'bottom', bodyProps, classes, className, children, header, footer, open, onClose, variant = 'temporary', blocking = true, gestureControlsProps, ...rest } = props;
|
|
684
|
-
// Refs for gesture system
|
|
685
556
|
const contentRef = useRef(null);
|
|
686
557
|
const headerRef = useRef(null);
|
|
687
558
|
const footerRef = useRef(null);
|
|
688
559
|
const isVertical = anchor === 'top' || anchor === 'bottom';
|
|
689
|
-
// Stabilize header/footer enabled state to prevent measurement fluctuations
|
|
690
|
-
// Header is enabled if there's a header prop OR if there's a drag handle (for vertical drawers)
|
|
691
560
|
const headerEnabled = useMemo(() => !!header || isVertical, [header, isVertical]);
|
|
692
561
|
const footerEnabled = useMemo(() => !!footer, [footer]);
|
|
693
562
|
const cls = useClasses('swipeable-drawer', classes, className);
|
|
@@ -705,32 +574,25 @@ const SwipeableDrawer = forwardRef((inProps, ref) => {
|
|
|
705
574
|
footerEnabled,
|
|
706
575
|
...gestureProps,
|
|
707
576
|
});
|
|
708
|
-
// Expose snapTo function through action ref
|
|
709
577
|
useImperativeHandle(action, () => ({
|
|
710
578
|
snapTo: gestureControls.snapTo,
|
|
711
579
|
}), [gestureControls.snapTo]);
|
|
712
580
|
const gestureBindProps = gestureControls.bind();
|
|
713
|
-
// Enhanced body props that include gesture motion
|
|
714
581
|
const enhancedBodyProps = {
|
|
715
582
|
...bodyProps,
|
|
716
|
-
// Apply gesture bindings for horizontal drawers (left/right)
|
|
717
|
-
// Vertical drawers (top/bottom) use motion values instead
|
|
718
583
|
...(!isVertical ? gestureBindProps : {}),
|
|
719
584
|
style: {
|
|
720
585
|
...bodyProps?.style,
|
|
721
|
-
// Apply motion styles for vertical drawers (top/bottom)
|
|
722
586
|
...(isVertical && {
|
|
723
587
|
...gestureControls.motionProps.style,
|
|
724
588
|
}),
|
|
725
589
|
},
|
|
726
590
|
};
|
|
727
|
-
// Consolidate measurement refs (refs only)
|
|
728
591
|
const measurementRefs = {
|
|
729
592
|
header: headerRef,
|
|
730
593
|
footer: footerRef,
|
|
731
594
|
content: contentRef,
|
|
732
595
|
};
|
|
733
|
-
// Gesture props for header
|
|
734
596
|
const headerGestureProps = {
|
|
735
597
|
className: clsx(isVertical && cls('header-drag')),
|
|
736
598
|
...(isVertical && gestureBindProps),
|
package/Switch.js
CHANGED
|
@@ -9,9 +9,7 @@ var Switch$1 = {"sui-switch-root":"sui-switch-root","sui-focus-visible":"sui-foc
|
|
|
9
9
|
|
|
10
10
|
const Switch = forwardRef((inProps, ref) => {
|
|
11
11
|
const props = useThemeProps({ props: inProps, name: 'Switch' });
|
|
12
|
-
const { classes, className, inputRef: inputRefProp, inputProps: inputPropsProp,
|
|
13
|
-
/* ⬇️ for input */
|
|
14
|
-
checked: checkedProp, defaultChecked, disabled: disabledProp, autoFocus = false, onBlur, onChange, onFocus, onFocusVisible, required, ...rest } = props;
|
|
12
|
+
const { classes, className, inputRef: inputRefProp, inputProps: inputPropsProp, checked: checkedProp, defaultChecked, disabled: disabledProp, autoFocus = false, onBlur, onChange, onFocus, onFocusVisible, required, ...rest } = props;
|
|
15
13
|
const cls = useClasses('switch', classes, className);
|
|
16
14
|
const { disabled, id } = useFormLabel({
|
|
17
15
|
disabled: disabledProp,
|
|
@@ -34,7 +32,6 @@ const Switch = forwardRef((inProps, ref) => {
|
|
|
34
32
|
if (autoFocus) {
|
|
35
33
|
inputRef.current?.focus();
|
|
36
34
|
}
|
|
37
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
38
35
|
}, []);
|
|
39
36
|
return (jsxs("span", { className: cls('root', { focusVisible }), ...rest, ref: ref, children: [jsx("input", { ...inputProps, id: id, className: cls('input', { checked }), ref: forkRef }), jsx("span", { className: cls('track') }), jsx("span", { className: cls('dot') })] }));
|
|
40
37
|
});
|
package/Tab.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { forwardRef, useRef, useEffect, useImperativeHandle } from 'react';
|
|
3
3
|
import { useTab } from '@mui/base';
|
|
4
|
-
import { useForkRef,
|
|
5
|
-
import { useThemeProps } from '@ringcentral/spring-theme';
|
|
4
|
+
import { useForkRef, combineClasses } from '@ringcentral/spring-base';
|
|
5
|
+
import { useThemeProps, useClassesWithMode } from '@ringcentral/spring-theme';
|
|
6
6
|
import { B as Badge } from './chunks/Badge.js';
|
|
7
7
|
import { I as Icon } from './chunks/Icon.js';
|
|
8
8
|
import { u as useTabsContext } from './chunks/TabsContext.js';
|
|
@@ -21,15 +21,16 @@ import './chunks/useFocusTrapStack.js';
|
|
|
21
21
|
import './chunks/Backdrop.js';
|
|
22
22
|
import './chunks/PopperPaper.js';
|
|
23
23
|
|
|
24
|
-
var Tab$1 = {"sui-tab-container":"sui-tab-container","sui-tab-pill-badge":"sui-tab-pill-badge","sui-tab-badge-root":"sui-tab-badge-root","sui-tab-root":"sui-tab-root","sui-selected":"sui-selected","sui-focus-visible":"sui-focus-visible","sui-tab-badge":"sui-tab-badge","sui-active":"sui-active","sui-tab-label":"sui-tab-label","sui-tab-label-container":"sui-tab-label-container","sui-tab-label-text":"sui-tab-label-text","sui-tab-label-badge-root":"sui-tab-label-badge-root","sui-tab-icon":"sui-tab-icon","sui-tab-icon-container":"sui-tab-icon-container","sui-tab-icon-pill":"sui-tab-icon-pill","sui-tab-icon-badge-root":"sui-tab-icon-badge-root","sui-tab-pill":"sui-tab-pill","sui-tab-label-pill-cobranding":"sui-tab-label-pill-cobranding","sui-tab-icon-pill-cobranding":"sui-tab-icon-pill-cobranding"};
|
|
24
|
+
var Tab$1 = {"sui-tab-container":"sui-tab-container","sui-tab-pill-badge":"sui-tab-pill-badge","sui-tab-badge-root":"sui-tab-badge-root","sui-tab-root":"sui-tab-root","sui-selected":"sui-selected","sui-focus-visible":"sui-focus-visible","sui-tab-badge":"sui-tab-badge","sui-active":"sui-active","sui-tab-label":"sui-tab-label","sui-tab-label-container":"sui-tab-label-container","sui-tab-label-text":"sui-tab-label-text","sui-tab-label-badge-root":"sui-tab-label-badge-root","sui-tab-icon":"sui-tab-icon","sui-tab-icon-container":"sui-tab-icon-container","sui-tab-icon-pill":"sui-tab-icon-pill","sui-tab-icon-badge-root":"sui-tab-icon-badge-root","sui-tab-large":"sui-tab-large","sui-tab-pill":"sui-tab-pill","sui-tab-pill-small":"sui-tab-pill-small","sui-tab-label-pill-cobranding":"sui-tab-label-pill-cobranding","sui-tab-icon-pill-cobranding":"sui-tab-icon-pill-cobranding","sui-compact":"sui-compact"};
|
|
25
25
|
|
|
26
26
|
const Tab = forwardRef((inProps, ref) => {
|
|
27
27
|
const props = useThemeProps({ props: inProps, name: 'Tab' });
|
|
28
28
|
const { classes, className, children: childrenProp, action, onChange, variant = 'label', color: colorProp, label, symbol, TooltipProps, BadgeProps: badgePropsProp, title, style, value, ...rest } = props;
|
|
29
29
|
const tabRef = useRef(null);
|
|
30
30
|
const handleRef = useForkRef(tabRef, ref);
|
|
31
|
-
const { pill, pillGap, color: contextColor, setFloatingUnderlineVisibility, } = useTabsContext();
|
|
31
|
+
const { pill, pillGap, color: contextColor, size: contextSize, setFloatingUnderlineVisibility, } = useTabsContext();
|
|
32
32
|
const color = colorProp ?? contextColor ?? 'default';
|
|
33
|
+
const size = contextSize ?? 'medium';
|
|
33
34
|
const { active, focusVisible, setFocusVisible, selected, getRootProps, index, } = useTab({
|
|
34
35
|
...rest,
|
|
35
36
|
value,
|
|
@@ -39,11 +40,9 @@ const Tab = forwardRef((inProps, ref) => {
|
|
|
39
40
|
if (!setFloatingUnderlineVisibility)
|
|
40
41
|
return;
|
|
41
42
|
if (focusVisible && selected) {
|
|
42
|
-
// Hide the floating underline when the currently selected tab is also focused
|
|
43
43
|
setFloatingUnderlineVisibility(false);
|
|
44
44
|
}
|
|
45
45
|
else if (selected) {
|
|
46
|
-
// Show the floating underline when this tab is selected but not focused
|
|
47
46
|
setFloatingUnderlineVisibility(true);
|
|
48
47
|
}
|
|
49
48
|
}, [focusVisible, selected, setFloatingUnderlineVisibility]);
|
|
@@ -53,7 +52,7 @@ const Tab = forwardRef((inProps, ref) => {
|
|
|
53
52
|
tabRef.current?.focus();
|
|
54
53
|
},
|
|
55
54
|
}), [setFocusVisible]);
|
|
56
|
-
const cls =
|
|
55
|
+
const cls = useClassesWithMode('tab', classes, className);
|
|
57
56
|
let children = null;
|
|
58
57
|
if (childrenProp) {
|
|
59
58
|
children = childrenProp;
|
|
@@ -89,7 +88,7 @@ const Tab = forwardRef((inProps, ref) => {
|
|
|
89
88
|
active,
|
|
90
89
|
focusVisible,
|
|
91
90
|
selected,
|
|
92
|
-
}, pill && `${variant}-pill`, pill && color !== 'default' && `${variant}-pill-${color}`), title: nativeTitle, tabIndex: selected ? 0 : -1, style: {
|
|
91
|
+
}, size, pill && `pill-${size}`, pill && `${variant}-pill`, pill && color !== 'default' && `${variant}-pill-${color}`), title: nativeTitle, tabIndex: selected ? 0 : -1, style: {
|
|
93
92
|
...style,
|
|
94
93
|
...(pill && index !== 0 ? { marginLeft: `${pillGap}px` } : {}),
|
|
95
94
|
}, ...getRootProps(rest), onChange: onChange, children: children }));
|
package/TabContext.js
CHANGED
|
@@ -4,13 +4,8 @@ export { useTabsContext as useTabContext } from '@mui/base';
|
|
|
4
4
|
import { createContext, useContext, useMemo } from 'react';
|
|
5
5
|
import { useId } from '@ringcentral/spring-base';
|
|
6
6
|
|
|
7
|
-
// Create a separate context for internal use that both Tab and TabPanel can access
|
|
8
7
|
const InternalTabsContext = createContext({ tabsInstanceId: undefined });
|
|
9
8
|
const useInternalTabsContext = () => useContext(InternalTabsContext);
|
|
10
|
-
/**
|
|
11
|
-
* Generate stable IDs for tab and tabpanel pairs
|
|
12
|
-
* This ensures consistent IDs regardless of whether the tab is visible or in more menu
|
|
13
|
-
*/
|
|
14
9
|
const generateTabStableIds = (tabsInstanceId, identifier) => {
|
|
15
10
|
const prefix = tabsInstanceId || 'Tabs';
|
|
16
11
|
return {
|
package/TableBody.js
CHANGED
|
@@ -12,7 +12,7 @@ const TableBody = forwardRef((inProps, ref) => {
|
|
|
12
12
|
const { component: TableBodyRoot = defaultComponent, classes, className, children, ...rest } = props;
|
|
13
13
|
const cls = useClasses('table-body', classes, className);
|
|
14
14
|
const table = useTableContext();
|
|
15
|
-
const fillerRowForStickyFooter = table && table.stickyFooter ? (jsx("tr", { "aria-hidden": true, className: "invisible" })) : null;
|
|
15
|
+
const fillerRowForStickyFooter = table && table.stickyFooter ? (jsx("tr", { "aria-hidden": true, className: "invisible" })) : null;
|
|
16
16
|
return (jsxs(TableBodyRoot, { role: TableBodyRoot === defaultComponent ? undefined : 'rowgroup', className: cls('root'), ...rest, ref: ref, children: [children, fillerRowForStickyFooter] }));
|
|
17
17
|
});
|
|
18
18
|
TableBody.displayName = 'SuiTableBody';
|
package/TableCell.js
CHANGED
|
@@ -13,10 +13,6 @@ import './chunks/usePrefersReducedMotion.js';
|
|
|
13
13
|
|
|
14
14
|
var TableCell$1 = {"sui-table-cell-root":"sui-table-cell-root","sui-table-cell-padding-checkbox":"sui-table-cell-padding-checkbox","sui-table-cell-content":"sui-table-cell-content","sui-table-cell-head":"sui-table-cell-head","sui-table-cell-sortable":"sui-table-cell-sortable","sui-table-cell-content-sortable":"sui-table-cell-content-sortable","sui-table-cell-sort-icon":"sui-table-cell-sort-icon","sui-focus-visible":"sui-focus-visible","sui-table-cell-padding-none":"sui-table-cell-padding-none","sui-table-cell-align-left":"sui-table-cell-align-left","sui-table-cell-align-center":"sui-table-cell-align-center","sui-table-cell-align-right":"sui-table-cell-align-right","sui-table-cell-align-justify":"sui-table-cell-align-justify","sui-table-cell-sticky-header-default-bg":"sui-table-cell-sticky-header-default-bg","sui-table-cell-content-padding-checkbox":"sui-table-cell-content-padding-checkbox","sui-table-cell-content-align-center":"sui-table-cell-content-align-center","sui-table-cell-content-align-right":"sui-table-cell-content-align-right","sui-table-cell-content-align-justify":"sui-table-cell-content-align-justify","sui-table-cell-sorted":"sui-table-cell-sorted","sui-table-cell-sort-indicator":"sui-table-cell-sort-indicator","sui-table-cell-sort-icon-sorted":"sui-table-cell-sort-icon-sorted","sui-table-cell-column-divider":"sui-table-cell-column-divider"};
|
|
15
15
|
|
|
16
|
-
/**
|
|
17
|
-
* The component renders a `<th>` element when the parent context is a header
|
|
18
|
-
* or otherwise a `<td>` element.
|
|
19
|
-
*/
|
|
20
16
|
const TableCell = forwardRef((inProps, ref) => {
|
|
21
17
|
const props = useThemeProps({ props: inProps, name: 'TableCell' });
|
|
22
18
|
const { component: componentProp, variant: variantProp, padding = 'normal', align = 'inherit', scope: scopeProp, sortDirection, showSortIndicator = false, initialSortIconDirection = 'asc', classes, className, children, SortIconProps, ...rest } = props;
|
|
@@ -36,8 +32,6 @@ const TableCell = forwardRef((inProps, ref) => {
|
|
|
36
32
|
}
|
|
37
33
|
const { focusVisible, focusVisibleRef, focusVisibleHandlers } = useFocusVisible();
|
|
38
34
|
let scope = scopeProp;
|
|
39
|
-
// scope is not a valid attribute for <td/> elements.
|
|
40
|
-
// source: https://html.spec.whatwg.org/multipage/tables.html#the-td-element
|
|
41
35
|
if (TableCellRoot === 'td') {
|
|
42
36
|
scope = undefined;
|
|
43
37
|
}
|