@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.
Files changed (213) hide show
  1. package/Accordion.js +90 -34
  2. package/AccordionHeader.js +71 -21
  3. package/Alert.js +120 -28
  4. package/Animation.js +2 -46
  5. package/Announcement.js +46 -35
  6. package/Autocomplete.js +1011 -583
  7. package/Avatar.js +134 -73
  8. package/AvatarGroup.js +50 -7
  9. package/Backdrop.js +45 -7
  10. package/Badge.js +77 -15
  11. package/Block.js +34 -12
  12. package/BlockHeader.js +57 -15
  13. package/BottomNavigation.js +181 -65
  14. package/BottomNavigationItem.js +93 -30
  15. package/Button.js +160 -24
  16. package/CallButton.js +53 -31
  17. package/Checkbox.js +88 -26
  18. package/Chip.js +126 -26
  19. package/CircularProgressIndicator.js +80 -8
  20. package/ClickAwayListener.js +4 -1
  21. package/ComponentsProps.js +1 -0
  22. package/DatePicker.js +611 -192
  23. package/DateUtilsContext.js +43 -25
  24. package/Dialer.js +564 -253
  25. package/Dialog.js +99 -45
  26. package/Divider.js +43 -7
  27. package/DragHandle.js +32 -6
  28. package/Drawer.js +117 -19
  29. package/Dropdown.js +154 -77
  30. package/EmptyState.js +65 -15
  31. package/FabButton.js +51 -17
  32. package/FocusTrap.js +109 -12
  33. package/FormField.js +108 -12
  34. package/FormLabel.js +81 -7
  35. package/Icon.js +1 -8
  36. package/IconButton.js +142 -26
  37. package/IconButtonGroup.js +35 -12
  38. package/InlineEditable.js +98 -44
  39. package/LinearProgressIndicator.js +73 -24
  40. package/Link.js +40 -11
  41. package/List.js +54 -9
  42. package/ListItem.js +152 -23
  43. package/ListItemText.js +44 -17
  44. package/ListNavigation.js +272 -20
  45. package/Menu.js +139 -23
  46. package/MenuActions.js +37 -12
  47. package/MenuDivider.js +34 -8
  48. package/MenuFooter.js +36 -12
  49. package/MenuHeader.js +54 -16
  50. package/MenuItem.js +402 -35
  51. package/MenuItemText.js +51 -9
  52. package/MenuList.js +87 -36
  53. package/Modal.js +345 -16
  54. package/NestedMenuContext.js +183 -11
  55. package/Option.js +32 -36
  56. package/Overlap.js +54 -7
  57. package/PageHeader.js +62 -24
  58. package/PickerTextField.js +156 -35
  59. package/Popover.js +262 -21
  60. package/Popper.js +112 -62
  61. package/PopperPaper.js +54 -8
  62. package/Portal.js +6 -1
  63. package/Radio.js +65 -21
  64. package/RadioGroup.js +56 -17
  65. package/Rating.js +223 -87
  66. package/Select.js +387 -44
  67. package/SingleFilter.js +148 -79
  68. package/Skeleton.js +68 -17
  69. package/Slider.js +167 -69
  70. package/Snackbar.js +122 -59
  71. package/SortableList.js +32 -12
  72. package/SortableListDndContext.js +69 -22
  73. package/SortableListItem.js +92 -47
  74. package/SortableVirtualizedList.js +44 -20
  75. package/SplitButton.js +124 -89
  76. package/Squircle.js +4 -7
  77. package/StatusIndicator.js +51 -9
  78. package/Step.js +63 -38
  79. package/StepButton.js +51 -23
  80. package/StepConnector.js +48 -8
  81. package/StepContent.js +67 -24
  82. package/StepIcon.js +90 -9
  83. package/StepLabel.js +90 -14
  84. package/Stepper.js +65 -23
  85. package/SubMenu.js +203 -101
  86. package/SwipeableDrawer.js +439 -194
  87. package/Switch.js +70 -23
  88. package/Tab.js +120 -57
  89. package/TabContext.js +59 -15
  90. package/TabPanel.js +40 -13
  91. package/Table.js +60 -17
  92. package/TableBody.js +42 -12
  93. package/TableCell.js +84 -50
  94. package/TableContainer.js +32 -10
  95. package/TableFooter.js +38 -10
  96. package/TableHead.js +49 -15
  97. package/TablePagination.js +153 -79
  98. package/TableRow.js +60 -21
  99. package/Tabs.js +592 -271
  100. package/Tag.js +51 -16
  101. package/Text.js +68 -37
  102. package/TextField.js +209 -31
  103. package/Textarea.js +51 -42
  104. package/TimePicker.js +490 -232
  105. package/Tooltip.js +48 -23
  106. package/Tray.js +237 -13
  107. package/TrayMenu.js +62 -43
  108. package/VirtualizedList.js +205 -107
  109. package/VirtualizedMenu.js +359 -29
  110. package/VisuallyHidden.js +29 -6
  111. package/chunks/1250.js +98 -0
  112. package/chunks/1294.js +126 -0
  113. package/chunks/2956.js +18 -0
  114. package/chunks/4476.js +460 -0
  115. package/chunks/4491.js +10 -0
  116. package/chunks/4535.js +364 -0
  117. package/chunks/5047.js +3 -0
  118. package/chunks/6335.js +24 -0
  119. package/chunks/7279.js +10 -0
  120. package/chunks/8011.js +8 -0
  121. package/chunks/8307.js +56 -0
  122. package/chunks/8467.js +8 -0
  123. package/chunks/8809.js +8 -0
  124. package/chunks/{RadioGroup.context.js → 9551.js} +12 -6
  125. package/chunks/987.js +8 -0
  126. package/index.css +2436 -2261
  127. package/index.js +245 -195
  128. package/internal/utils/setRef.d.ts +2 -1
  129. package/package.json +4 -4
  130. package/src/Animation/hooks/useMotionSafeTransition/useMotionSafeTransition.d.ts +2 -0
  131. package/src/Autocomplete/SuggestionList/SuggestionList.d.ts +1 -1
  132. package/src/Button/Button.classes.d.ts +1 -1
  133. package/src/ComponentsProps.d.ts +111 -110
  134. package/src/DatePicker/DatePickerDataAttributes.d.ts +11 -0
  135. package/src/DatePicker/utils/DatePickerUtils.d.ts +1 -1
  136. package/src/MenuItem/MenuItem.type.d.ts +1 -0
  137. package/src/MenuList/MenuListContext.d.ts +2 -3
  138. package/src/Modal/Modal.type.d.ts +1 -0
  139. package/src/Popover/Popover.classes.d.ts +1 -1
  140. package/src/Popover/Popover.internal.d.ts +8 -0
  141. package/src/Popover/Popover.type.d.ts +1 -0
  142. package/src/Select/Select.type.d.ts +6 -4
  143. package/src/Table/Table.type.d.ts +3 -0
  144. package/src/Table/TableContext.d.ts +3 -0
  145. package/src/Table/TableRowContext.d.ts +7 -0
  146. package/src/Table/index.d.ts +1 -0
  147. package/src/TableCell/TableCell.classes.d.ts +1 -1
  148. package/src/TableFooter/TableFooter.classes.d.ts +1 -1
  149. package/src/TableFooter/TableFooter.type.d.ts +1 -0
  150. package/src/TableHead/TableHead.classes.d.ts +1 -1
  151. package/src/TableHead/TableHead.type.d.ts +1 -0
  152. package/src/TableRow/TableRow.type.d.ts +2 -0
  153. package/chunks/AccordionContext.js +0 -6
  154. package/chunks/Alert.js +0 -48
  155. package/chunks/AvatarGroup.js +0 -22
  156. package/chunks/Backdrop.js +0 -18
  157. package/chunks/Badge.js +0 -32
  158. package/chunks/BottomNavigationItem.js +0 -36
  159. package/chunks/Button.js +0 -88
  160. package/chunks/Chip.js +0 -73
  161. package/chunks/CircularProgressIndicator.js +0 -36
  162. package/chunks/Divider.js +0 -19
  163. package/chunks/DragHandle.js +0 -11
  164. package/chunks/Drawer.js +0 -33
  165. package/chunks/ExpandCollapseCaret.js +0 -24
  166. package/chunks/FormLabel.js +0 -27
  167. package/chunks/Icon.js +0 -25
  168. package/chunks/IconButtonLabel.js +0 -68
  169. package/chunks/List.js +0 -22
  170. package/chunks/ListItem.js +0 -83
  171. package/chunks/Menu.js +0 -61
  172. package/chunks/MenuDivider.js +0 -14
  173. package/chunks/MenuItemText.js +0 -18
  174. package/chunks/MenuList.js +0 -47
  175. package/chunks/Modal.js +0 -211
  176. package/chunks/Overlap.js +0 -25
  177. package/chunks/PickerTextField.js +0 -85
  178. package/chunks/Popover.js +0 -61
  179. package/chunks/PopperPaper.js +0 -15
  180. package/chunks/Select.js +0 -225
  181. package/chunks/ShowHideEye.js +0 -56
  182. package/chunks/SlideIn.js +0 -20
  183. package/chunks/SortableArrow.js +0 -73
  184. package/chunks/Squircle.js +0 -31
  185. package/chunks/StatusIndicator.js +0 -20
  186. package/chunks/StepConnector.js +0 -21
  187. package/chunks/StepIcon.js +0 -43
  188. package/chunks/StepLabel.js +0 -29
  189. package/chunks/StepperContext.js +0 -9
  190. package/chunks/TableContext.js +0 -6
  191. package/chunks/Tablelvl2Context.js +0 -6
  192. package/chunks/TabsContext.js +0 -6
  193. package/chunks/TextField.js +0 -110
  194. package/chunks/Tooltip.js +0 -217
  195. package/chunks/VirtualizedMenu.js +0 -162
  196. package/chunks/VisuallyHidden.js +0 -12
  197. package/chunks/composeEventHandlers.js +0 -10
  198. package/chunks/getFade.js +0 -27
  199. package/chunks/getGrow.js +0 -70
  200. package/chunks/getSlideIn.js +0 -30
  201. package/chunks/hasContent.js +0 -3
  202. package/chunks/useAnimationFrame.js +0 -15
  203. package/chunks/useFocusTrapStack.js +0 -38
  204. package/chunks/useHelperTextId.js +0 -24
  205. package/chunks/useListNavigation.js +0 -199
  206. package/chunks/useMenuItemSelect.js +0 -282
  207. package/chunks/useMotionSafeTransition.js +0 -9
  208. package/chunks/useNestedMenuItem.js +0 -27
  209. package/chunks/useNestedParentMenu.js +0 -113
  210. package/chunks/usePrefersReducedMotion.js +0 -36
  211. package/chunks/useTooltipForceHide.js +0 -27
  212. package/chunks/useTrayNavigate.js +0 -150
  213. 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 };