@ringcentral/spring-ui 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Accordion.js +90 -34
- package/AccordionHeader.js +71 -21
- package/Alert.js +120 -28
- package/Animation.js +2 -46
- package/Announcement.js +46 -35
- package/Autocomplete.js +1011 -583
- package/Avatar.js +134 -73
- package/AvatarGroup.js +50 -7
- package/Backdrop.js +45 -7
- package/Badge.js +77 -15
- package/Block.js +34 -12
- package/BlockHeader.js +57 -15
- package/BottomNavigation.js +181 -65
- package/BottomNavigationItem.js +93 -30
- package/Button.js +160 -24
- package/CallButton.js +53 -31
- package/Checkbox.js +88 -26
- package/Chip.js +126 -26
- package/CircularProgressIndicator.js +80 -8
- package/ClickAwayListener.js +4 -1
- package/ComponentsProps.js +1 -0
- package/DatePicker.js +611 -192
- package/DateUtilsContext.js +43 -25
- package/Dialer.js +564 -253
- package/Dialog.js +99 -45
- package/Divider.js +43 -7
- package/DragHandle.js +32 -6
- package/Drawer.js +117 -19
- package/Dropdown.js +154 -77
- package/EmptyState.js +65 -15
- package/FabButton.js +51 -17
- package/FocusTrap.js +109 -12
- package/FormField.js +108 -12
- package/FormLabel.js +81 -7
- package/Icon.js +1 -8
- package/IconButton.js +142 -26
- package/IconButtonGroup.js +35 -12
- package/InlineEditable.js +98 -44
- package/LinearProgressIndicator.js +73 -24
- package/Link.js +40 -11
- package/List.js +54 -9
- package/ListItem.js +152 -23
- package/ListItemText.js +44 -17
- package/ListNavigation.js +272 -20
- package/Menu.js +139 -23
- package/MenuActions.js +37 -12
- package/MenuDivider.js +34 -8
- package/MenuFooter.js +36 -12
- package/MenuHeader.js +54 -16
- package/MenuItem.js +402 -35
- package/MenuItemText.js +51 -9
- package/MenuList.js +87 -36
- package/Modal.js +345 -16
- package/NestedMenuContext.js +183 -11
- package/Option.js +32 -36
- package/Overlap.js +54 -7
- package/PageHeader.js +62 -24
- package/PickerTextField.js +156 -35
- package/Popover.js +262 -21
- package/Popper.js +112 -62
- package/PopperPaper.js +54 -8
- package/Portal.js +6 -1
- package/Radio.js +65 -21
- package/RadioGroup.js +56 -17
- package/Rating.js +223 -87
- package/Select.js +387 -44
- package/SingleFilter.js +148 -79
- package/Skeleton.js +68 -17
- package/Slider.js +167 -69
- package/Snackbar.js +122 -59
- package/SortableList.js +32 -12
- package/SortableListDndContext.js +69 -22
- package/SortableListItem.js +92 -47
- package/SortableVirtualizedList.js +44 -20
- package/SplitButton.js +124 -89
- package/Squircle.js +4 -7
- package/StatusIndicator.js +51 -9
- package/Step.js +63 -38
- package/StepButton.js +51 -23
- package/StepConnector.js +48 -8
- package/StepContent.js +67 -24
- package/StepIcon.js +90 -9
- package/StepLabel.js +90 -14
- package/Stepper.js +65 -23
- package/SubMenu.js +203 -101
- package/SwipeableDrawer.js +439 -194
- package/Switch.js +70 -23
- package/Tab.js +120 -57
- package/TabContext.js +59 -15
- package/TabPanel.js +40 -13
- package/Table.js +60 -17
- package/TableBody.js +42 -12
- package/TableCell.js +84 -50
- package/TableContainer.js +32 -10
- package/TableFooter.js +38 -10
- package/TableHead.js +49 -15
- package/TablePagination.js +153 -79
- package/TableRow.js +60 -21
- package/Tabs.js +592 -271
- package/Tag.js +51 -16
- package/Text.js +68 -37
- package/TextField.js +209 -31
- package/Textarea.js +51 -42
- package/TimePicker.js +490 -232
- package/Tooltip.js +48 -23
- package/Tray.js +237 -13
- package/TrayMenu.js +62 -43
- package/VirtualizedList.js +205 -107
- package/VirtualizedMenu.js +359 -29
- package/VisuallyHidden.js +29 -6
- package/chunks/1250.js +98 -0
- package/chunks/1294.js +126 -0
- package/chunks/2956.js +18 -0
- package/chunks/4476.js +460 -0
- package/chunks/4491.js +10 -0
- package/chunks/4535.js +364 -0
- package/chunks/5047.js +3 -0
- package/chunks/6335.js +24 -0
- package/chunks/7279.js +10 -0
- package/chunks/8011.js +8 -0
- package/chunks/8307.js +56 -0
- package/chunks/8467.js +8 -0
- package/chunks/8809.js +8 -0
- package/chunks/{RadioGroup.context.js → 9551.js} +12 -6
- package/chunks/987.js +8 -0
- package/index.css +2436 -2261
- package/index.js +245 -195
- package/internal/utils/setRef.d.ts +2 -1
- package/package.json +4 -4
- package/src/Animation/hooks/useMotionSafeTransition/useMotionSafeTransition.d.ts +2 -0
- package/src/Autocomplete/SuggestionList/SuggestionList.d.ts +1 -1
- package/src/Button/Button.classes.d.ts +1 -1
- package/src/ComponentsProps.d.ts +111 -110
- package/src/DatePicker/DatePickerDataAttributes.d.ts +11 -0
- package/src/DatePicker/utils/DatePickerUtils.d.ts +1 -1
- package/src/MenuItem/MenuItem.type.d.ts +1 -0
- package/src/MenuList/MenuListContext.d.ts +2 -3
- package/src/Modal/Modal.type.d.ts +1 -0
- package/src/Popover/Popover.classes.d.ts +1 -1
- package/src/Popover/Popover.internal.d.ts +8 -0
- package/src/Popover/Popover.type.d.ts +1 -0
- package/src/Select/Select.type.d.ts +6 -4
- package/src/Table/Table.type.d.ts +3 -0
- package/src/Table/TableContext.d.ts +3 -0
- package/src/Table/TableRowContext.d.ts +7 -0
- package/src/Table/index.d.ts +1 -0
- package/src/TableCell/TableCell.classes.d.ts +1 -1
- package/src/TableFooter/TableFooter.classes.d.ts +1 -1
- package/src/TableFooter/TableFooter.type.d.ts +1 -0
- package/src/TableHead/TableHead.classes.d.ts +1 -1
- package/src/TableHead/TableHead.type.d.ts +1 -0
- package/src/TableRow/TableRow.type.d.ts +2 -0
- package/chunks/AccordionContext.js +0 -6
- package/chunks/Alert.js +0 -48
- package/chunks/AvatarGroup.js +0 -22
- package/chunks/Backdrop.js +0 -18
- package/chunks/Badge.js +0 -32
- package/chunks/BottomNavigationItem.js +0 -36
- package/chunks/Button.js +0 -88
- package/chunks/Chip.js +0 -73
- package/chunks/CircularProgressIndicator.js +0 -36
- package/chunks/Divider.js +0 -19
- package/chunks/DragHandle.js +0 -11
- package/chunks/Drawer.js +0 -33
- package/chunks/ExpandCollapseCaret.js +0 -24
- package/chunks/FormLabel.js +0 -27
- package/chunks/Icon.js +0 -25
- package/chunks/IconButtonLabel.js +0 -68
- package/chunks/List.js +0 -22
- package/chunks/ListItem.js +0 -83
- package/chunks/Menu.js +0 -61
- package/chunks/MenuDivider.js +0 -14
- package/chunks/MenuItemText.js +0 -18
- package/chunks/MenuList.js +0 -47
- package/chunks/Modal.js +0 -211
- package/chunks/Overlap.js +0 -25
- package/chunks/PickerTextField.js +0 -85
- package/chunks/Popover.js +0 -61
- package/chunks/PopperPaper.js +0 -15
- package/chunks/Select.js +0 -225
- package/chunks/ShowHideEye.js +0 -56
- package/chunks/SlideIn.js +0 -20
- package/chunks/SortableArrow.js +0 -73
- package/chunks/Squircle.js +0 -31
- package/chunks/StatusIndicator.js +0 -20
- package/chunks/StepConnector.js +0 -21
- package/chunks/StepIcon.js +0 -43
- package/chunks/StepLabel.js +0 -29
- package/chunks/StepperContext.js +0 -9
- package/chunks/TableContext.js +0 -6
- package/chunks/Tablelvl2Context.js +0 -6
- package/chunks/TabsContext.js +0 -6
- package/chunks/TextField.js +0 -110
- package/chunks/Tooltip.js +0 -217
- package/chunks/VirtualizedMenu.js +0 -162
- package/chunks/VisuallyHidden.js +0 -12
- package/chunks/composeEventHandlers.js +0 -10
- package/chunks/getFade.js +0 -27
- package/chunks/getGrow.js +0 -70
- package/chunks/getSlideIn.js +0 -30
- package/chunks/hasContent.js +0 -3
- package/chunks/useAnimationFrame.js +0 -15
- package/chunks/useFocusTrapStack.js +0 -38
- package/chunks/useHelperTextId.js +0 -24
- package/chunks/useListNavigation.js +0 -199
- package/chunks/useMenuItemSelect.js +0 -282
- package/chunks/useMotionSafeTransition.js +0 -9
- package/chunks/useNestedMenuItem.js +0 -27
- package/chunks/useNestedParentMenu.js +0 -113
- package/chunks/usePrefersReducedMotion.js +0 -36
- package/chunks/useTooltipForceHide.js +0 -27
- package/chunks/useTrayNavigate.js +0 -150
- package/chunks/withTooltip.js +0 -15
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useEventCallback } from '@ringcentral/spring-base';
|
|
3
|
-
import { createContext, useContext, useRef, useMemo, useImperativeHandle } from 'react';
|
|
4
|
-
|
|
5
|
-
const ListNavigationContext = createContext(null);
|
|
6
|
-
const useListNavigationContext = () => useContext(ListNavigationContext);
|
|
7
|
-
|
|
8
|
-
const useListNavigation = (props) => {
|
|
9
|
-
const { preventContainerScroll = true, searchAndFocusItemHandler: searchAndFocusItemHandlerProp = defaultSearchAndFocusItem, actions, } = props;
|
|
10
|
-
const currentFocusedItemRef = useRef(null);
|
|
11
|
-
const listRef = useRef(null);
|
|
12
|
-
const sentinelArrowNavRef = useRef(null);
|
|
13
|
-
const sentinelTabBoundaryRef = useRef(null);
|
|
14
|
-
const skipEnforceFocusRef = useRef(false);
|
|
15
|
-
const focusList = () => {
|
|
16
|
-
skipEnforceFocusRef.current = true;
|
|
17
|
-
listRef.current.focus();
|
|
18
|
-
};
|
|
19
|
-
const focusTabBoundary = () => {
|
|
20
|
-
skipEnforceFocusRef.current = true;
|
|
21
|
-
sentinelTabBoundaryRef.current.focus();
|
|
22
|
-
};
|
|
23
|
-
const itemActions = useMemo(() => ({
|
|
24
|
-
onTab: () => {
|
|
25
|
-
skipEnforceFocusRef.current = true;
|
|
26
|
-
sentinelTabBoundaryRef.current.focus();
|
|
27
|
-
},
|
|
28
|
-
onShiftTab: () => {
|
|
29
|
-
skipEnforceFocusRef.current = true;
|
|
30
|
-
listRef.current.focus();
|
|
31
|
-
},
|
|
32
|
-
updateFocusedItem: (el) => {
|
|
33
|
-
currentFocusedItemRef.current = el;
|
|
34
|
-
},
|
|
35
|
-
}), []);
|
|
36
|
-
const focusFirstItem = useEventCallback(() => {
|
|
37
|
-
const { focused } = searchAndFocusItemHandler('first');
|
|
38
|
-
if (!focused) {
|
|
39
|
-
focusList();
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
useImperativeHandle(actions, () => ({
|
|
43
|
-
focus: focusFirstItem,
|
|
44
|
-
}), []);
|
|
45
|
-
const sentinelFocusHandler = (e) => {
|
|
46
|
-
if (e.target === e.currentTarget) {
|
|
47
|
-
const skipEnforceFocus = skipEnforceFocusRef.current;
|
|
48
|
-
if (skipEnforceFocus) {
|
|
49
|
-
skipEnforceFocusRef.current = false;
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
focusFirstItem();
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
const searchAndFocusItemHandler = (searchElementOption) => {
|
|
56
|
-
return searchAndFocusItemHandlerProp(searchElementOption, {
|
|
57
|
-
sentinelEnd: sentinelArrowNavRef.current,
|
|
58
|
-
list: listRef.current,
|
|
59
|
-
});
|
|
60
|
-
};
|
|
61
|
-
const listKeyDownHandler = (e) => {
|
|
62
|
-
const focusedItem = currentFocusedItemRef.current;
|
|
63
|
-
const key = e.key;
|
|
64
|
-
if (focusedItem) {
|
|
65
|
-
const searchElementOption = {
|
|
66
|
-
ArrowDown: {
|
|
67
|
-
baseElement: focusedItem,
|
|
68
|
-
direction: 'down',
|
|
69
|
-
},
|
|
70
|
-
ArrowUp: {
|
|
71
|
-
baseElement: focusedItem,
|
|
72
|
-
direction: 'up',
|
|
73
|
-
},
|
|
74
|
-
Home: 'first',
|
|
75
|
-
End: 'last',
|
|
76
|
-
}[key];
|
|
77
|
-
if (searchElementOption) {
|
|
78
|
-
const { focused, isAfterBaseElement } = searchAndFocusItemHandler(searchElementOption);
|
|
79
|
-
if (!focused) {
|
|
80
|
-
focusList();
|
|
81
|
-
}
|
|
82
|
-
if (!isAfterBaseElement || preventContainerScroll) {
|
|
83
|
-
e.preventDefault();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
if (e.target === e.currentTarget && key === 'Tab' && !e.shiftKey) {
|
|
89
|
-
focusTabBoundary();
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
const getListProps = (otherHandler) => {
|
|
94
|
-
const { onKeyDown, onFocus } = otherHandler;
|
|
95
|
-
const handleKeyDown = (e) => {
|
|
96
|
-
onKeyDown?.(e);
|
|
97
|
-
if (e.defaultPrevented) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
listKeyDownHandler(e);
|
|
101
|
-
};
|
|
102
|
-
const handleFocus = (e) => {
|
|
103
|
-
sentinelFocusHandler(e);
|
|
104
|
-
onFocus?.(e);
|
|
105
|
-
};
|
|
106
|
-
return {
|
|
107
|
-
tabIndex: 0,
|
|
108
|
-
onKeyDown: handleKeyDown,
|
|
109
|
-
onFocus: handleFocus,
|
|
110
|
-
};
|
|
111
|
-
};
|
|
112
|
-
const renderItems = (items) => {
|
|
113
|
-
return (jsxs(ListNavigationContext.Provider, { value: itemActions, children: [items, jsx("div", { "aria-hidden": "true", ref: sentinelArrowNavRef })] }));
|
|
114
|
-
};
|
|
115
|
-
const renderTabBoundary = () => {
|
|
116
|
-
return (jsx("div", { style: { position: 'fixed', bottom: '50%' }, ref: sentinelTabBoundaryRef, tabIndex: 0, onFocus: sentinelFocusHandler }));
|
|
117
|
-
};
|
|
118
|
-
return { renderItems, renderTabBoundary, getListProps, listRef };
|
|
119
|
-
};
|
|
120
|
-
const isUnfocusable = (el) => el.matches('.sui-disabled, :disabled, hr, [role="separator"], [disabled]');
|
|
121
|
-
const defaultSearchAndFocusItem = (searchElementOption, helperElements) => {
|
|
122
|
-
const { list, sentinelEnd } = helperElements;
|
|
123
|
-
if (list.firstElementChild === sentinelEnd) {
|
|
124
|
-
return { focused: false };
|
|
125
|
-
}
|
|
126
|
-
const getFirstItem = () => {
|
|
127
|
-
const firstItem = list.firstElementChild;
|
|
128
|
-
if (firstItem === sentinelEnd) {
|
|
129
|
-
throw Error('SPRING [useListNavigation]: must have child element');
|
|
130
|
-
}
|
|
131
|
-
return firstItem;
|
|
132
|
-
};
|
|
133
|
-
const getLastItem = () => {
|
|
134
|
-
const lastItem = sentinelEnd.previousElementSibling;
|
|
135
|
-
if (!lastItem) {
|
|
136
|
-
throw Error('SPRING [useListNavigation]: must have child element');
|
|
137
|
-
}
|
|
138
|
-
return lastItem;
|
|
139
|
-
};
|
|
140
|
-
let direction;
|
|
141
|
-
let startElement;
|
|
142
|
-
if (typeof searchElementOption === 'string') {
|
|
143
|
-
if (searchElementOption === 'first') {
|
|
144
|
-
startElement = getFirstItem();
|
|
145
|
-
direction = 'down';
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
startElement = getLastItem();
|
|
149
|
-
direction = 'up';
|
|
150
|
-
}
|
|
151
|
-
if (!isUnfocusable(startElement)) {
|
|
152
|
-
startElement.focus();
|
|
153
|
-
return { focused: true };
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
startElement = searchElementOption.baseElement;
|
|
158
|
-
direction = searchElementOption.direction;
|
|
159
|
-
}
|
|
160
|
-
let pointer = startElement;
|
|
161
|
-
let isAfterBaseElement = true;
|
|
162
|
-
if (direction === 'up') {
|
|
163
|
-
do {
|
|
164
|
-
if (!pointer.previousElementSibling) {
|
|
165
|
-
pointer = getLastItem();
|
|
166
|
-
isAfterBaseElement = false;
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
pointer = pointer.previousElementSibling;
|
|
170
|
-
}
|
|
171
|
-
if (!isUnfocusable(pointer)) {
|
|
172
|
-
break;
|
|
173
|
-
}
|
|
174
|
-
} while (pointer !== startElement);
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
do {
|
|
178
|
-
if (pointer.nextElementSibling === sentinelEnd) {
|
|
179
|
-
pointer = getFirstItem();
|
|
180
|
-
isAfterBaseElement = false;
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
pointer = pointer.nextElementSibling;
|
|
184
|
-
}
|
|
185
|
-
if (!isUnfocusable(pointer)) {
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
} while (pointer !== startElement);
|
|
189
|
-
}
|
|
190
|
-
if (isUnfocusable(pointer)) {
|
|
191
|
-
return { focused: false };
|
|
192
|
-
}
|
|
193
|
-
pointer.focus();
|
|
194
|
-
return typeof searchElementOption === 'string'
|
|
195
|
-
? { focused: true }
|
|
196
|
-
: { focused: true, isAfterBaseElement };
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
export { ListNavigationContext as L, useListNavigation as a, useListNavigationContext as u };
|
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { createContext, useContext, forwardRef, useRef, useLayoutEffect, useCallback, useMemo } from 'react';
|
|
3
|
-
import { useFocusVisible, useActive, useForkRef, combineProps, useId, useHover, useEventCallback } from '@ringcentral/spring-base';
|
|
4
|
-
import { CheckBoldMd } from '@ringcentral/spring-icon';
|
|
5
|
-
import { useThemeProps, useClassesWithMode } from '@ringcentral/spring-theme';
|
|
6
|
-
import { I as Icon } from './Icon.js';
|
|
7
|
-
import { u as useAnimationFrame } from './useAnimationFrame.js';
|
|
8
|
-
import './useNestedParentMenu.js';
|
|
9
|
-
import { u as useNestedMenuItem } from './useNestedMenuItem.js';
|
|
10
|
-
import { useVirtualizedItemPropsContext } from '../VirtualizedList.js';
|
|
11
|
-
import { c as composeEventHandlers } from './composeEventHandlers.js';
|
|
12
|
-
import { unstable_setRef } from '@mui/utils';
|
|
13
|
-
import { useItemNavigation } from '../ListNavigation.js';
|
|
14
|
-
import { u as useMenuContext } from './Menu.js';
|
|
15
|
-
|
|
16
|
-
const MenuListContext = createContext({
|
|
17
|
-
nowrap: true,
|
|
18
|
-
});
|
|
19
|
-
const useMenuListContext = () => useContext(MenuListContext);
|
|
20
|
-
|
|
21
|
-
const SubMenuTriggerNestedIdContext = createContext(null);
|
|
22
|
-
|
|
23
|
-
const MenuItemSelectContext = createContext(null);
|
|
24
|
-
const useMenuItemSelectContext = () => useContext(MenuItemSelectContext);
|
|
25
|
-
|
|
26
|
-
const useMenuItem = (props) => {
|
|
27
|
-
const { onBlur, onFocus, onKeyDown, onKeyUp, onClick, ref, disabled, autoClose, } = props;
|
|
28
|
-
const { keyboardNavHandlers, itemRef } = useItemNavigation() ?? {};
|
|
29
|
-
const { focusVisible, focusVisibleRef, focusVisibleHandlers } = useFocusVisible({
|
|
30
|
-
onFocus: (e) => {
|
|
31
|
-
keyboardNavHandlers?.onFocus(e);
|
|
32
|
-
onFocus?.(e);
|
|
33
|
-
},
|
|
34
|
-
onBlur: (e) => {
|
|
35
|
-
keyboardNavHandlers?.onBlur(e);
|
|
36
|
-
onBlur?.(e);
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
const { close: closeMenu } = useMenuContext() ?? {};
|
|
40
|
-
const handleClick = disabled
|
|
41
|
-
? undefined
|
|
42
|
-
: composeEventHandlers(onClick, () => {
|
|
43
|
-
if (autoClose)
|
|
44
|
-
closeMenu?.();
|
|
45
|
-
});
|
|
46
|
-
const { active, activeHandlers } = useActive({
|
|
47
|
-
disabled,
|
|
48
|
-
onKeyDown: (e) => {
|
|
49
|
-
onKeyDown?.(e);
|
|
50
|
-
keyboardNavHandlers?.onKeyDown(e);
|
|
51
|
-
},
|
|
52
|
-
onKeyUp,
|
|
53
|
-
onClick: handleClick,
|
|
54
|
-
});
|
|
55
|
-
const handleItemRef = useForkRef(ref, focusVisibleRef, itemRef);
|
|
56
|
-
const getRootProps = (otherProps = {}) => {
|
|
57
|
-
const { ref: otherRef, ...restOtherProps } = otherProps;
|
|
58
|
-
return {
|
|
59
|
-
role: 'menuitem',
|
|
60
|
-
tabIndex: '-1',
|
|
61
|
-
...(disabled ? { 'aria-disabled': true } : null),
|
|
62
|
-
...combineProps(restOtherProps, {
|
|
63
|
-
...focusVisibleHandlers,
|
|
64
|
-
...activeHandlers,
|
|
65
|
-
}),
|
|
66
|
-
ref: (instance) => {
|
|
67
|
-
unstable_setRef(otherRef, instance);
|
|
68
|
-
unstable_setRef(handleItemRef, instance);
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
};
|
|
72
|
-
return { getRootProps, focusVisible, active };
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const useVirtualizedMenuItem = (props) => {
|
|
76
|
-
const { onBlur, onFocus, onKeyDown, onKeyUp, onClick, disabled, autoClose, ref, } = props;
|
|
77
|
-
const { keyboardNavHandlers, itemRef } = useItemNavigation() ?? {};
|
|
78
|
-
const vlItemProps = useVirtualizedItemPropsContext();
|
|
79
|
-
const { focusVisible, focusVisibleRef, focusVisibleHandlers } = useFocusVisible({
|
|
80
|
-
onFocus: (e) => {
|
|
81
|
-
keyboardNavHandlers?.onFocus(e);
|
|
82
|
-
onFocus?.(e);
|
|
83
|
-
},
|
|
84
|
-
onBlur: (e) => {
|
|
85
|
-
keyboardNavHandlers?.onBlur(e);
|
|
86
|
-
onBlur?.(e);
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
const { close: closeMenu } = useMenuContext() ?? {};
|
|
90
|
-
const handleClick = disabled
|
|
91
|
-
? undefined
|
|
92
|
-
: composeEventHandlers(onClick, () => {
|
|
93
|
-
if (autoClose)
|
|
94
|
-
closeMenu?.();
|
|
95
|
-
});
|
|
96
|
-
const { active, activeHandlers } = useActive({
|
|
97
|
-
disabled,
|
|
98
|
-
onKeyDown: (e) => {
|
|
99
|
-
onKeyDown?.(e);
|
|
100
|
-
keyboardNavHandlers?.onKeyDown(e);
|
|
101
|
-
},
|
|
102
|
-
onKeyUp,
|
|
103
|
-
onClick: handleClick,
|
|
104
|
-
});
|
|
105
|
-
const handleItemRef = useForkRef(ref, focusVisibleRef, itemRef);
|
|
106
|
-
const getRootProps = (otherProps = {}) => {
|
|
107
|
-
const { ref: otherRef, ...restOtherProps } = otherProps;
|
|
108
|
-
return {
|
|
109
|
-
role: 'menuitem',
|
|
110
|
-
tabIndex: -1,
|
|
111
|
-
...(disabled ? { 'aria-disabled': true } : null),
|
|
112
|
-
...combineProps(restOtherProps, {
|
|
113
|
-
...focusVisibleHandlers,
|
|
114
|
-
...activeHandlers,
|
|
115
|
-
...vlItemProps,
|
|
116
|
-
}),
|
|
117
|
-
ref: (instance) => {
|
|
118
|
-
unstable_setRef(otherRef, instance);
|
|
119
|
-
unstable_setRef(handleItemRef, instance);
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
};
|
|
123
|
-
return { getRootProps, focusVisible, active };
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
const MenuItem = forwardRef((inProps, ref) => {
|
|
127
|
-
const props = useThemeProps({ props: inProps, name: 'MenuItem' });
|
|
128
|
-
const { classes, className, children, selected, disabled, onMouseEnter, onMouseLeave, onPointerMove, onBlur, onFocus, onKeyDown, onKeyUp, onClick, highlighted = false, focused = false, autoClose = true, autoFocus, ...rest } = props;
|
|
129
|
-
const cls = useClassesWithMode('menu-item', classes, className);
|
|
130
|
-
const vlItemProps = useVirtualizedItemPropsContext();
|
|
131
|
-
const isInVlRef = useRef(Boolean(vlItemProps));
|
|
132
|
-
const { requestAnimationFrame } = useAnimationFrame();
|
|
133
|
-
const useMenuItemHook = (() => {
|
|
134
|
-
if (isInVlRef.current) {
|
|
135
|
-
return useVirtualizedMenuItem;
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
return useMenuItem;
|
|
139
|
-
}
|
|
140
|
-
})();
|
|
141
|
-
const itemRef = useRef(null);
|
|
142
|
-
const handleRef = useForkRef(itemRef, ref);
|
|
143
|
-
const { getRootProps, focusVisible, active } = useMenuItemHook({
|
|
144
|
-
autoClose,
|
|
145
|
-
disabled,
|
|
146
|
-
onBlur,
|
|
147
|
-
onClick,
|
|
148
|
-
onFocus,
|
|
149
|
-
onKeyDown,
|
|
150
|
-
onKeyUp,
|
|
151
|
-
ref: handleRef,
|
|
152
|
-
});
|
|
153
|
-
const selectable = !(selected === undefined);
|
|
154
|
-
const selectContextValue = useMenuItemSelectContext();
|
|
155
|
-
const menuListContextValue = useMenuListContext();
|
|
156
|
-
const selectMode = selectContextValue
|
|
157
|
-
? selectContextValue.selectMode
|
|
158
|
-
: 'single';
|
|
159
|
-
const subMenuTriggerNestedId = useContext(SubMenuTriggerNestedIdContext);
|
|
160
|
-
const generatedId = useId();
|
|
161
|
-
const id = subMenuTriggerNestedId ?? generatedId;
|
|
162
|
-
const isSubMenuTrigger = Boolean(subMenuTriggerNestedId);
|
|
163
|
-
const { requestItemHover } = useNestedMenuItem({ id });
|
|
164
|
-
const { hoverHandlers } = useHover({
|
|
165
|
-
onMouseEnter,
|
|
166
|
-
onMouseLeave,
|
|
167
|
-
});
|
|
168
|
-
const handlePointerMove = (event) => {
|
|
169
|
-
if (event.pointerType === 'mouse' &&
|
|
170
|
-
!requestItemHover(event, {
|
|
171
|
-
closeOpenedSubMenu: !isSubMenuTrigger,
|
|
172
|
-
})) {
|
|
173
|
-
event.preventDefault();
|
|
174
|
-
}
|
|
175
|
-
onPointerMove?.(event);
|
|
176
|
-
};
|
|
177
|
-
useLayoutEffect(() => {
|
|
178
|
-
if (autoFocus) {
|
|
179
|
-
itemRef.current?.focus();
|
|
180
|
-
requestAnimationFrame(() => {
|
|
181
|
-
if (process.env.NODE_ENV === 'test' &&
|
|
182
|
-
typeof itemRef.current?.scrollIntoView !== 'function') {
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
itemRef.current?.scrollIntoView({
|
|
186
|
-
block: 'nearest',
|
|
187
|
-
inline: 'nearest',
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
}, [autoFocus, requestAnimationFrame]);
|
|
192
|
-
return (jsx("div", { className: cls('root', {
|
|
193
|
-
selectable,
|
|
194
|
-
selected,
|
|
195
|
-
focusVisible,
|
|
196
|
-
disabled,
|
|
197
|
-
active,
|
|
198
|
-
highlighted,
|
|
199
|
-
focused,
|
|
200
|
-
nowrap: menuListContextValue.nowrap,
|
|
201
|
-
}), ...getRootProps(rest), ...hoverHandlers, onPointerMove: handlePointerMove, children: jsxs("div", { className: cls('container'), children: [selectable && (jsx("div", { className: cls('select-indicator'), children: selectMode === 'single' ? (jsx("span", { className: cls('select-dot') })) : (jsx(Icon, { symbol: CheckBoldMd, size: "small" })) })), children] }) }));
|
|
202
|
-
});
|
|
203
|
-
MenuItem.displayName = 'SuiMenuItem';
|
|
204
|
-
|
|
205
|
-
var Action;
|
|
206
|
-
(function (Action) {
|
|
207
|
-
Action["SELECT"] = "select";
|
|
208
|
-
Action["DESELECT"] = "deselect";
|
|
209
|
-
})(Action || (Action = {}));
|
|
210
|
-
const useMenuItemSelect = (props) => {
|
|
211
|
-
const { widget = 'menu', selectMode = 'single', value: valueProp = selectMode === 'single' ? null : [], onChange, onClose, autoFocus: autoFocusProp = true, } = props;
|
|
212
|
-
const isSingleMode = selectMode === 'single';
|
|
213
|
-
if (process.env.NODE_ENV !== 'production' &&
|
|
214
|
-
!isSingleMode &&
|
|
215
|
-
!Array.isArray(valueProp)) {
|
|
216
|
-
throw Error('SPRING [useMenuItemSelect]: value must be an array if selectMode is multiple');
|
|
217
|
-
}
|
|
218
|
-
const value = valueProp;
|
|
219
|
-
const getMenuItemProps = useCallback((itemValue) => {
|
|
220
|
-
let selected;
|
|
221
|
-
let autoFocus;
|
|
222
|
-
if (isSingleMode) {
|
|
223
|
-
selected = value === itemValue;
|
|
224
|
-
autoFocus = selected;
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
selected = value.includes(itemValue);
|
|
228
|
-
autoFocus = value[0] === itemValue;
|
|
229
|
-
}
|
|
230
|
-
const menuItemRole = selectMode === 'single' ? 'menuitemradio' : 'menuitemcheckbox';
|
|
231
|
-
const ariaProps = widget === 'menu'
|
|
232
|
-
? { 'aria-checked': selected }
|
|
233
|
-
: { 'aria-selected': selected };
|
|
234
|
-
return {
|
|
235
|
-
role: widget === 'menu' ? menuItemRole : 'option',
|
|
236
|
-
...ariaProps,
|
|
237
|
-
selected,
|
|
238
|
-
autoFocus: autoFocusProp && autoFocus,
|
|
239
|
-
};
|
|
240
|
-
}, [isSingleMode, selectMode, widget, autoFocusProp, value]);
|
|
241
|
-
const handleSelect = useEventCallback((itemValue) => {
|
|
242
|
-
let action = Action.SELECT;
|
|
243
|
-
if (isSingleMode) {
|
|
244
|
-
if (value === itemValue) {
|
|
245
|
-
onClose?.();
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
onChange?.(itemValue);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
else {
|
|
252
|
-
const index = value.indexOf(itemValue);
|
|
253
|
-
let newValue;
|
|
254
|
-
if (index >= 0) {
|
|
255
|
-
action = Action.DESELECT;
|
|
256
|
-
newValue = [
|
|
257
|
-
...value.slice(0, index),
|
|
258
|
-
...value.slice(index + 1),
|
|
259
|
-
];
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
newValue = [...value, itemValue];
|
|
263
|
-
}
|
|
264
|
-
onChange?.(newValue, {
|
|
265
|
-
value: itemValue,
|
|
266
|
-
action,
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
const contextValue = useMemo(() => ({
|
|
271
|
-
selectMode,
|
|
272
|
-
value,
|
|
273
|
-
handleSelect,
|
|
274
|
-
getMenuItemProps,
|
|
275
|
-
}), [getMenuItemProps, handleSelect, selectMode, value]);
|
|
276
|
-
return {
|
|
277
|
-
value,
|
|
278
|
-
contextValue,
|
|
279
|
-
};
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
export { Action as A, MenuItem as M, SubMenuTriggerNestedIdContext as S, MenuItemSelectContext as a, useMenuItem as b, useMenuItemSelect as c, useVirtualizedMenuItem as d, MenuListContext as e, useMenuListContext as f, useMenuItemSelectContext as u };
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { motionTransition } from '@ringcentral/spring-theme';
|
|
2
|
-
import { u as usePrefersReducedMotion } from './usePrefersReducedMotion.js';
|
|
3
|
-
|
|
4
|
-
const useMotionSafeTransition = (transition) => {
|
|
5
|
-
const prefersReducedMotion = usePrefersReducedMotion();
|
|
6
|
-
return prefersReducedMotion ? motionTransition.instant : transition;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export { useMotionSafeTransition as u };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect } from 'react';
|
|
2
|
-
import { u as useNestedMenuContext } from './useNestedParentMenu.js';
|
|
3
|
-
|
|
4
|
-
const useNestedMenuItem = (props) => {
|
|
5
|
-
const context = useNestedMenuContext();
|
|
6
|
-
const { hovered, id } = props;
|
|
7
|
-
const { isPointerMovingToSubMenu: isPointerMovingToSubMenuContext, onPointerGraceIntentChange, registHoveredItem, } = context ?? {};
|
|
8
|
-
const requestItemHover = useCallback((event, options) => {
|
|
9
|
-
const canApplyHover = registHoveredItem?.(id, event, options);
|
|
10
|
-
return canApplyHover ?? true;
|
|
11
|
-
}, [id, registHoveredItem]);
|
|
12
|
-
useEffect(() => {
|
|
13
|
-
if (hovered) {
|
|
14
|
-
requestItemHover();
|
|
15
|
-
}
|
|
16
|
-
}, [hovered, requestItemHover]);
|
|
17
|
-
const isPointerMovingToSubMenu = useCallback((event, intent) => {
|
|
18
|
-
return isPointerMovingToSubMenuContext?.(event, intent) ?? false;
|
|
19
|
-
}, [isPointerMovingToSubMenuContext]);
|
|
20
|
-
return {
|
|
21
|
-
isPointerMovingToSubMenu,
|
|
22
|
-
onPointerGraceIntentChange,
|
|
23
|
-
requestItemHover,
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export { useNestedMenuItem as u };
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext, useRef, useCallback, useMemo, useLayoutEffect } from 'react';
|
|
2
|
-
|
|
3
|
-
const NestedMenuContext = createContext(null);
|
|
4
|
-
const useNestedMenuContext = () => {
|
|
5
|
-
return useContext(NestedMenuContext);
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
const getPointFromPointerEvent = (event) => ({
|
|
9
|
-
x: event.clientX,
|
|
10
|
-
y: event.clientY,
|
|
11
|
-
});
|
|
12
|
-
const isPointInPolygon = (point, polygon) => {
|
|
13
|
-
let inside = false;
|
|
14
|
-
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
15
|
-
const pointI = polygon[i];
|
|
16
|
-
const pointJ = polygon[j];
|
|
17
|
-
const intersects = pointI.y > point.y !== pointJ.y > point.y &&
|
|
18
|
-
point.x <
|
|
19
|
-
((pointJ.x - pointI.x) * (point.y - pointI.y)) / (pointJ.y - pointI.y) +
|
|
20
|
-
pointI.x;
|
|
21
|
-
if (intersects) {
|
|
22
|
-
inside = !inside;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
return inside;
|
|
26
|
-
};
|
|
27
|
-
const isPointerInGraceArea = (event, area) => {
|
|
28
|
-
if (!area)
|
|
29
|
-
return false;
|
|
30
|
-
return isPointInPolygon(getPointFromPointerEvent(event), area);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const useNestedParentMenu = (props) => {
|
|
34
|
-
const openedSubMenuSymbolRef = useRef(null);
|
|
35
|
-
const pointerGraceIntentRef = useRef(null);
|
|
36
|
-
const pointerDirRef = useRef('right');
|
|
37
|
-
const lastPointerXRef = useRef(0);
|
|
38
|
-
const { open } = props;
|
|
39
|
-
const onPointerGraceIntentChange = useCallback((intent) => {
|
|
40
|
-
pointerGraceIntentRef.current = intent;
|
|
41
|
-
}, []);
|
|
42
|
-
const isPointerMovingToSubMenu = useCallback((event, intentArg) => {
|
|
43
|
-
const intent = intentArg === undefined ? pointerGraceIntentRef.current : intentArg;
|
|
44
|
-
const isMovingTowards = pointerDirRef.current === intent?.side;
|
|
45
|
-
return isMovingTowards && isPointerInGraceArea(event, intent?.area);
|
|
46
|
-
}, []);
|
|
47
|
-
const onContentPointerMove = useCallback((event) => {
|
|
48
|
-
const pointerXHasChanged = lastPointerXRef.current !== event.clientX;
|
|
49
|
-
if (pointerXHasChanged) {
|
|
50
|
-
pointerDirRef.current =
|
|
51
|
-
event.clientX > lastPointerXRef.current ? 'right' : 'left';
|
|
52
|
-
lastPointerXRef.current = event.clientX;
|
|
53
|
-
}
|
|
54
|
-
}, []);
|
|
55
|
-
const onContentClickCapture = useCallback((event) => {
|
|
56
|
-
const target = event.target;
|
|
57
|
-
const openedSubMenu = openedSubMenuSymbolRef.current;
|
|
58
|
-
if (!target || !event.currentTarget.contains(target)) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
if (openedSubMenu?.getAnchorElement?.()?.contains(target)) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
openedSubMenu?.closeSubMenu();
|
|
65
|
-
}, []);
|
|
66
|
-
const contextValue = useMemo(() => {
|
|
67
|
-
return {
|
|
68
|
-
registHoveredItem: (id, event, options) => {
|
|
69
|
-
const symbol = openedSubMenuSymbolRef.current;
|
|
70
|
-
if (!symbol || id === symbol.anchorId) {
|
|
71
|
-
return true;
|
|
72
|
-
}
|
|
73
|
-
if (event && isPointerMovingToSubMenu(event)) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
if (options?.closeOpenedSubMenu ?? true) {
|
|
77
|
-
symbol.closeSubMenu();
|
|
78
|
-
}
|
|
79
|
-
return true;
|
|
80
|
-
},
|
|
81
|
-
registOpenedSubMenu: (menuItemSymbol) => {
|
|
82
|
-
openedSubMenuSymbolRef.current?.closeSubMenu();
|
|
83
|
-
openedSubMenuSymbolRef.current = menuItemSymbol;
|
|
84
|
-
return () => {
|
|
85
|
-
if (openedSubMenuSymbolRef.current === menuItemSymbol) {
|
|
86
|
-
openedSubMenuSymbolRef.current = null;
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
},
|
|
90
|
-
isPointerMovingToSubMenu,
|
|
91
|
-
onPointerGraceIntentChange,
|
|
92
|
-
};
|
|
93
|
-
}, [isPointerMovingToSubMenu, onPointerGraceIntentChange]);
|
|
94
|
-
useLayoutEffect(() => {
|
|
95
|
-
if (!open) {
|
|
96
|
-
openedSubMenuSymbolRef.current?.closeSubMenu();
|
|
97
|
-
openedSubMenuSymbolRef.current = null;
|
|
98
|
-
onPointerGraceIntentChange(null);
|
|
99
|
-
}
|
|
100
|
-
}, [onPointerGraceIntentChange, open]);
|
|
101
|
-
return {
|
|
102
|
-
contentClickHandlers: {
|
|
103
|
-
onClickCapture: onContentClickCapture,
|
|
104
|
-
},
|
|
105
|
-
contentPointerHandlers: {
|
|
106
|
-
onPointerMove: onContentPointerMove,
|
|
107
|
-
},
|
|
108
|
-
contextValue,
|
|
109
|
-
getHaveOpenedSubMenu: () => Boolean(openedSubMenuSymbolRef.current),
|
|
110
|
-
};
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
export { NestedMenuContext as N, useNestedParentMenu as a, useNestedMenuContext as u };
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { useGlobalListener } from '@ringcentral/spring-base';
|
|
2
|
-
import { MotionConfigContext } from 'framer-motion';
|
|
3
|
-
import { useState, useContext } from 'react';
|
|
4
|
-
|
|
5
|
-
let instance;
|
|
6
|
-
const getPrefersReducedMotionMediaQuery = () => {
|
|
7
|
-
if (!instance ||
|
|
8
|
-
process.env.NODE_ENV === 'test') {
|
|
9
|
-
instance = window?.matchMedia?.('(prefers-reduced-motion)');
|
|
10
|
-
}
|
|
11
|
-
return instance;
|
|
12
|
-
};
|
|
13
|
-
const usePrefersReducedMotion = () => {
|
|
14
|
-
const mediaQuery = getPrefersReducedMotionMediaQuery();
|
|
15
|
-
const [shouldReduceMotion, setShouldReduceMotion] = useState(mediaQuery?.matches || false);
|
|
16
|
-
const context = useContext(MotionConfigContext);
|
|
17
|
-
useGlobalListener('change', ((event) => {
|
|
18
|
-
setShouldReduceMotion(event.matches);
|
|
19
|
-
}), {
|
|
20
|
-
target: mediaQuery,
|
|
21
|
-
customKey: 'prefers-reduced-motion',
|
|
22
|
-
});
|
|
23
|
-
if (context.reducedMotion === 'user') {
|
|
24
|
-
return shouldReduceMotion;
|
|
25
|
-
}
|
|
26
|
-
if (context.reducedMotion === 'always' ||
|
|
27
|
-
process.env.NODE_ENV === 'test') {
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
if (context.reducedMotion === 'never') {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
return shouldReduceMotion;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export { usePrefersReducedMotion as u };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
2
|
-
|
|
3
|
-
const useTooltipForceHide = (forceHide) => {
|
|
4
|
-
const [open, setOpen] = useState(false);
|
|
5
|
-
const openStateStore = useRef();
|
|
6
|
-
const onOpenStateChange = useCallback((event, isOpen) => {
|
|
7
|
-
if (openStateStore.current !== undefined) {
|
|
8
|
-
openStateStore.current = isOpen;
|
|
9
|
-
}
|
|
10
|
-
else {
|
|
11
|
-
setOpen(isOpen);
|
|
12
|
-
}
|
|
13
|
-
}, []);
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
if (open && forceHide) {
|
|
16
|
-
setOpen(false);
|
|
17
|
-
openStateStore.current = open;
|
|
18
|
-
}
|
|
19
|
-
if (!forceHide && openStateStore.current !== undefined) {
|
|
20
|
-
setOpen(openStateStore.current);
|
|
21
|
-
openStateStore.current = undefined;
|
|
22
|
-
}
|
|
23
|
-
}, [open, forceHide]);
|
|
24
|
-
return { open, onOpenStateChange };
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export { useTooltipForceHide as u };
|