@fluentui/react-menu 9.10.0 → 9.11.1
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.json +98 -1
- package/CHANGELOG.md +30 -2
- package/dist/index.d.ts +12 -0
- package/lib/components/Menu/useMenu.js +2 -22
- package/lib/components/Menu/useMenu.js.map +1 -1
- package/lib/components/MenuItem/useMenuItemStyles.styles.js +3 -3
- package/lib/components/MenuItem/useMenuItemStyles.styles.js.map +1 -1
- package/lib/components/MenuPopover/useMenuPopover.js +8 -0
- package/lib/components/MenuPopover/useMenuPopover.js.map +1 -1
- package/lib/components/MenuTrigger/MenuTrigger.js +1 -1
- package/lib/components/MenuTrigger/MenuTrigger.js.map +1 -1
- package/lib/components/MenuTrigger/index.js +1 -1
- package/lib/components/MenuTrigger/index.js.map +1 -1
- package/lib/components/MenuTrigger/useMenuTrigger.js +164 -0
- package/lib/components/MenuTrigger/useMenuTrigger.js.map +1 -0
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/utils/useOnMenuEnter.js +2 -2
- package/lib/utils/useOnMenuEnter.js.map +1 -1
- package/lib-commonjs/components/Menu/useMenu.js +1 -20
- package/lib-commonjs/components/Menu/useMenu.js.map +1 -1
- package/lib-commonjs/components/MenuItem/useMenuItemStyles.styles.js +6 -6
- package/lib-commonjs/components/MenuItem/useMenuItemStyles.styles.js.map +1 -1
- package/lib-commonjs/components/MenuPopover/useMenuPopover.js +8 -0
- package/lib-commonjs/components/MenuPopover/useMenuPopover.js.map +1 -1
- package/lib-commonjs/components/MenuTrigger/MenuTrigger.js +2 -2
- package/lib-commonjs/components/MenuTrigger/MenuTrigger.js.map +1 -1
- package/lib-commonjs/components/MenuTrigger/index.js +1 -1
- package/lib-commonjs/components/MenuTrigger/index.js.map +1 -1
- package/lib-commonjs/components/MenuTrigger/{useMenuTrigger.styles.js → useMenuTrigger.js} +3 -1
- package/lib-commonjs/components/MenuTrigger/useMenuTrigger.js.map +1 -0
- package/lib-commonjs/index.js +2 -0
- package/lib-commonjs/index.js.map +1 -1
- package/lib-commonjs/utils/useOnMenuEnter.js.map +1 -1
- package/package.json +8 -8
- package/lib/components/MenuTrigger/useMenuTrigger.styles.js +0 -168
- package/lib/components/MenuTrigger/useMenuTrigger.styles.js.map +0 -1
- package/lib-commonjs/components/MenuTrigger/useMenuTrigger.styles.js.map +0 -1
package/CHANGELOG.json
CHANGED
@@ -2,7 +2,104 @@
|
|
2
2
|
"name": "@fluentui/react-menu",
|
3
3
|
"entries": [
|
4
4
|
{
|
5
|
-
"date": "Tue,
|
5
|
+
"date": "Tue, 25 Jul 2023 13:26:22 GMT",
|
6
|
+
"tag": "@fluentui/react-menu_v9.11.1",
|
7
|
+
"version": "9.11.1",
|
8
|
+
"comments": {
|
9
|
+
"patch": [
|
10
|
+
{
|
11
|
+
"author": "ololubek@microsoft.com",
|
12
|
+
"package": "@fluentui/react-menu",
|
13
|
+
"commit": "1082207b08959996cd736725735cadc01d0849b0",
|
14
|
+
"comment": "chore: Update react-icons version to pick up fowardref change."
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"author": "lingfan.gao@microsoft.com",
|
18
|
+
"package": "@fluentui/react-menu",
|
19
|
+
"commit": "c0c62f9383781f0dbebd800eaa2c64ef761075a2",
|
20
|
+
"comment": "refactor: Remove custom focus code in favour of useRestoreFocus hooks"
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"author": "beachball",
|
24
|
+
"package": "@fluentui/react-menu",
|
25
|
+
"comment": "Bump @fluentui/react-portal to v9.3.3",
|
26
|
+
"commit": "c0c62f9383781f0dbebd800eaa2c64ef761075a2"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"author": "beachball",
|
30
|
+
"package": "@fluentui/react-menu",
|
31
|
+
"comment": "Bump @fluentui/react-tabster to v9.11.0",
|
32
|
+
"commit": "c0c62f9383781f0dbebd800eaa2c64ef761075a2"
|
33
|
+
}
|
34
|
+
]
|
35
|
+
}
|
36
|
+
},
|
37
|
+
{
|
38
|
+
"date": "Thu, 20 Jul 2023 18:27:30 GMT",
|
39
|
+
"tag": "@fluentui/react-menu_v9.11.0",
|
40
|
+
"version": "9.11.0",
|
41
|
+
"comments": {
|
42
|
+
"none": [
|
43
|
+
{
|
44
|
+
"author": "olfedias@microsoft.com",
|
45
|
+
"package": "@fluentui/react-menu",
|
46
|
+
"commit": "5a4b16715e8e929f11d8113f710e578ca73acaa6",
|
47
|
+
"comment": "chore: migrate to monosize"
|
48
|
+
}
|
49
|
+
],
|
50
|
+
"patch": [
|
51
|
+
{
|
52
|
+
"author": "lingfangao@hotmail.com",
|
53
|
+
"package": "@fluentui/react-menu",
|
54
|
+
"commit": "631543d26bfef45b5288f19d2d0c396aea3b880a",
|
55
|
+
"comment": "fix: MenuItem content should be spaced 12px from the boundary"
|
56
|
+
}
|
57
|
+
],
|
58
|
+
"minor": [
|
59
|
+
{
|
60
|
+
"author": "Humberto.Morimoto@microsoft.com",
|
61
|
+
"package": "@fluentui/react-menu",
|
62
|
+
"commit": "5918d226f4561f9682fa60fab92341f0f7cbe435",
|
63
|
+
"comment": "chore: Exporting MENU_ENTER_EVENT and dispatchMenuEnterEvent utilities."
|
64
|
+
},
|
65
|
+
{
|
66
|
+
"author": "beachball",
|
67
|
+
"package": "@fluentui/react-menu",
|
68
|
+
"comment": "Bump @fluentui/react-aria to v9.3.27",
|
69
|
+
"commit": "5a4b16715e8e929f11d8113f710e578ca73acaa6"
|
70
|
+
},
|
71
|
+
{
|
72
|
+
"author": "beachball",
|
73
|
+
"package": "@fluentui/react-menu",
|
74
|
+
"comment": "Bump @fluentui/react-portal to v9.3.2",
|
75
|
+
"commit": "5a4b16715e8e929f11d8113f710e578ca73acaa6"
|
76
|
+
},
|
77
|
+
{
|
78
|
+
"author": "beachball",
|
79
|
+
"package": "@fluentui/react-menu",
|
80
|
+
"comment": "Bump @fluentui/react-jsx-runtime to v9.0.0-alpha.12",
|
81
|
+
"commit": "5a4b16715e8e929f11d8113f710e578ca73acaa6"
|
82
|
+
}
|
83
|
+
]
|
84
|
+
}
|
85
|
+
},
|
86
|
+
{
|
87
|
+
"date": "Thu, 13 Jul 2023 21:25:42 GMT",
|
88
|
+
"tag": "@fluentui/react-menu_v9.10.0",
|
89
|
+
"version": "9.10.0",
|
90
|
+
"comments": {
|
91
|
+
"none": [
|
92
|
+
{
|
93
|
+
"author": "martinhochel@microsoft.com",
|
94
|
+
"package": "@fluentui/react-menu",
|
95
|
+
"commit": "8a9e1018f2abb2c7608c49d32acf44e93c43cba6",
|
96
|
+
"comment": "chore: update devDependencies to use * for inner workspace dependencies"
|
97
|
+
}
|
98
|
+
]
|
99
|
+
}
|
100
|
+
},
|
101
|
+
{
|
102
|
+
"date": "Tue, 11 Jul 2023 18:46:35 GMT",
|
6
103
|
"tag": "@fluentui/react-menu_v9.10.0",
|
7
104
|
"version": "9.10.0",
|
8
105
|
"comments": {
|
package/CHANGELOG.md
CHANGED
@@ -1,12 +1,40 @@
|
|
1
1
|
# Change Log - @fluentui/react-menu
|
2
2
|
|
3
|
-
This log was last generated on Tue,
|
3
|
+
This log was last generated on Tue, 25 Jul 2023 13:26:22 GMT and should not be manually modified.
|
4
4
|
|
5
5
|
<!-- Start content -->
|
6
6
|
|
7
|
+
## [9.11.1](https://github.com/microsoft/fluentui/tree/@fluentui/react-menu_v9.11.1)
|
8
|
+
|
9
|
+
Tue, 25 Jul 2023 13:26:22 GMT
|
10
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-menu_v9.11.0..@fluentui/react-menu_v9.11.1)
|
11
|
+
|
12
|
+
### Patches
|
13
|
+
|
14
|
+
- chore: Update react-icons version to pick up fowardref change. ([PR #28590](https://github.com/microsoft/fluentui/pull/28590) by ololubek@microsoft.com)
|
15
|
+
- refactor: Remove custom focus code in favour of useRestoreFocus hooks ([PR #28530](https://github.com/microsoft/fluentui/pull/28530) by lingfan.gao@microsoft.com)
|
16
|
+
- Bump @fluentui/react-portal to v9.3.3 ([PR #28530](https://github.com/microsoft/fluentui/pull/28530) by beachball)
|
17
|
+
- Bump @fluentui/react-tabster to v9.11.0 ([PR #28530](https://github.com/microsoft/fluentui/pull/28530) by beachball)
|
18
|
+
|
19
|
+
## [9.11.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-menu_v9.11.0)
|
20
|
+
|
21
|
+
Thu, 20 Jul 2023 18:27:30 GMT
|
22
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-menu_v9.10.0..@fluentui/react-menu_v9.11.0)
|
23
|
+
|
24
|
+
### Minor changes
|
25
|
+
|
26
|
+
- chore: Exporting MENU_ENTER_EVENT and dispatchMenuEnterEvent utilities. ([PR #28499](https://github.com/microsoft/fluentui/pull/28499) by Humberto.Morimoto@microsoft.com)
|
27
|
+
- Bump @fluentui/react-aria to v9.3.27 ([PR #26826](https://github.com/microsoft/fluentui/pull/26826) by beachball)
|
28
|
+
- Bump @fluentui/react-portal to v9.3.2 ([PR #26826](https://github.com/microsoft/fluentui/pull/26826) by beachball)
|
29
|
+
- Bump @fluentui/react-jsx-runtime to v9.0.0-alpha.12 ([PR #26826](https://github.com/microsoft/fluentui/pull/26826) by beachball)
|
30
|
+
|
31
|
+
### Patches
|
32
|
+
|
33
|
+
- fix: MenuItem content should be spaced 12px from the boundary ([PR #28162](https://github.com/microsoft/fluentui/pull/28162) by lingfangao@hotmail.com)
|
34
|
+
|
7
35
|
## [9.10.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-menu_v9.10.0)
|
8
36
|
|
9
|
-
Tue, 11 Jul 2023 18:
|
37
|
+
Tue, 11 Jul 2023 18:46:35 GMT
|
10
38
|
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-menu_v9.9.1..@fluentui/react-menu_v9.10.0)
|
11
39
|
|
12
40
|
### Minor changes
|
package/dist/index.d.ts
CHANGED
@@ -17,11 +17,23 @@ import type { SlotClassNames } from '@fluentui/react-utilities';
|
|
17
17
|
import type { TriggerProps } from '@fluentui/react-utilities';
|
18
18
|
import type { UseOnClickOrScrollOutsideOptions } from '@fluentui/react-utilities';
|
19
19
|
|
20
|
+
/**
|
21
|
+
* Dispatches the custom MouseEvent enter event. Similar to calling `el.click()`
|
22
|
+
* @param el - element for the event target
|
23
|
+
* @param nativeEvent - the native mouse event this is mapped to
|
24
|
+
*/
|
25
|
+
export declare const dispatchMenuEnterEvent: (el: HTMLElement, nativeEvent: MouseEvent) => void;
|
26
|
+
|
20
27
|
/**
|
21
28
|
* Wrapper component that manages state for a popup MenuList and a MenuTrigger
|
22
29
|
*/
|
23
30
|
export declare const Menu: React_2.FC<MenuProps>;
|
24
31
|
|
32
|
+
/**
|
33
|
+
* Name of the custom event
|
34
|
+
*/
|
35
|
+
export declare const MENU_ENTER_EVENT = "fuimenuenter";
|
36
|
+
|
25
37
|
export declare type MenuCheckedValueChangeData = {
|
26
38
|
/** The items for this value that are checked */
|
27
39
|
checkedItems: string[];
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import * as React from 'react';
|
2
2
|
import { usePositioningMouseTarget, usePositioning, resolvePositioningShorthand } from '@fluentui/react-positioning';
|
3
|
-
import { useControllableState, useId, useOnClickOutside, useEventCallback, useOnScrollOutside
|
3
|
+
import { useControllableState, useId, useOnClickOutside, useEventCallback, useOnScrollOutside } from '@fluentui/react-utilities';
|
4
4
|
import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
|
5
5
|
import { elementContains } from '@fluentui/react-portal';
|
6
6
|
import { useFocusFinders } from '@fluentui/react-tabster';
|
@@ -239,33 +239,13 @@ const useMenuOpenState = (state)=>{
|
|
239
239
|
findFirstFocusable,
|
240
240
|
state.menuPopoverRef
|
241
241
|
]);
|
242
|
-
const firstMount = useFirstMount();
|
243
242
|
React.useEffect(()=>{
|
244
243
|
if (open) {
|
245
244
|
focusFirst();
|
246
|
-
} else {
|
247
|
-
if (!firstMount) {
|
248
|
-
if ((targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.activeElement) === (targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.body)) {
|
249
|
-
var // We know that React effects are sync so we focus the trigger here
|
250
|
-
// after any event handler (event handlers will update state and re-render).
|
251
|
-
// Since the browser only performs the default behaviour for the Tab key once
|
252
|
-
// keyboard events have fully bubbled up the window, the browser will move
|
253
|
-
// focus to the next tabbable element before/after the trigger if needed.
|
254
|
-
// If the Tab key was not pressed, focus will remain on the trigger as expected.
|
255
|
-
_state_triggerRef_current;
|
256
|
-
(_state_triggerRef_current = state.triggerRef.current) === null || _state_triggerRef_current === void 0 ? void 0 : _state_triggerRef_current.focus();
|
257
|
-
}
|
258
|
-
}
|
259
245
|
}
|
260
|
-
// firstMount change should not re-run this effect
|
261
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
262
246
|
}, [
|
263
|
-
state.triggerRef,
|
264
|
-
state.isSubmenu,
|
265
247
|
open,
|
266
|
-
focusFirst
|
267
|
-
targetDocument,
|
268
|
-
state.menuPopoverRef
|
248
|
+
focusFirst
|
269
249
|
]);
|
270
250
|
return [
|
271
251
|
open,
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["useMenu.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n usePositioningMouseTarget,\n usePositioning,\n resolvePositioningShorthand,\n PositioningShorthandValue,\n} from '@fluentui/react-positioning';\nimport {\n useControllableState,\n useId,\n useOnClickOutside,\n useEventCallback,\n useOnScrollOutside,\n useFirstMount,\n} from '@fluentui/react-utilities';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport { elementContains } from '@fluentui/react-portal';\nimport { useFocusFinders } from '@fluentui/react-tabster';\nimport { useMenuContext_unstable } from '../../contexts/menuContext';\nimport { MENU_ENTER_EVENT, useOnMenuMouseEnter } from '../../utils/index';\nimport { useIsSubmenu } from '../../utils/useIsSubmenu';\nimport type { MenuOpenChangeData, MenuOpenEvent, MenuProps, MenuState } from './Menu.types';\n\n// If it's not possible to position the submenu in smaller viewports, try\n// and fallback to this order of positions\nconst submenuFallbackPositions: PositioningShorthandValue[] = [\n 'after',\n 'after-bottom',\n 'before-top',\n 'before',\n 'before-bottom',\n 'above',\n];\n\n/**\n * Create the state required to render Menu.\n *\n * The returned state can be modified with hooks such as useMenuStyles,\n * before being passed to renderMenu_unstable.\n *\n * @param props - props from this instance of Menu\n */\nexport const useMenu_unstable = (props: MenuProps): MenuState => {\n const isSubmenu = useIsSubmenu();\n const {\n hoverDelay = 500,\n inline = false,\n hasCheckmarks = false,\n hasIcons = false,\n closeOnScroll = false,\n openOnContext = false,\n persistOnItemClick = false,\n openOnHover = isSubmenu,\n defaultCheckedValues,\n mountNode = null,\n } = props;\n const triggerId = useId('menu');\n const [contextTarget, setContextTarget] = usePositioningMouseTarget();\n\n const positioningState = {\n position: isSubmenu ? 'after' : 'below',\n align: isSubmenu ? 'top' : 'start',\n target: props.openOnContext ? contextTarget : undefined,\n fallbackPositions: isSubmenu ? submenuFallbackPositions : undefined,\n ...resolvePositioningShorthand(props.positioning),\n } as const;\n\n const children = React.Children.toArray(props.children) as React.ReactElement[];\n\n if (process.env.NODE_ENV !== 'production') {\n if (children.length === 0) {\n // eslint-disable-next-line no-console\n console.warn('Menu must contain at least one child');\n }\n\n if (children.length > 2) {\n // eslint-disable-next-line no-console\n console.warn('Menu must contain at most two children');\n }\n }\n\n let menuTrigger: React.ReactElement | undefined = undefined;\n let menuPopover: React.ReactElement | undefined = undefined;\n if (children.length === 2) {\n menuTrigger = children[0];\n menuPopover = children[1];\n } else if (children.length === 1) {\n menuPopover = children[0];\n }\n\n const { targetRef: triggerRef, containerRef: menuPopoverRef } = usePositioning(positioningState);\n\n // TODO Better way to narrow types ?\n const [open, setOpen] = useMenuOpenState({\n hoverDelay,\n isSubmenu,\n setContextTarget,\n closeOnScroll,\n menuPopoverRef,\n triggerRef,\n open: props.open,\n defaultOpen: props.defaultOpen,\n onOpenChange: props.onOpenChange,\n openOnContext,\n });\n\n const [checkedValues, onCheckedValueChange] = useMenuSelectableState({\n checkedValues: props.checkedValues,\n defaultCheckedValues,\n onCheckedValueChange: props.onCheckedValueChange,\n });\n\n return {\n inline,\n hoverDelay,\n triggerId,\n isSubmenu,\n openOnHover,\n contextTarget,\n setContextTarget,\n hasCheckmarks,\n hasIcons,\n closeOnScroll,\n menuTrigger,\n menuPopover,\n mountNode,\n triggerRef,\n menuPopoverRef,\n components: {},\n openOnContext,\n open,\n setOpen,\n checkedValues,\n onCheckedValueChange,\n persistOnItemClick,\n };\n};\n\n/**\n * Adds appropriate state values and handlers for selectable items\n * i.e checkboxes and radios\n */\nconst useMenuSelectableState = (\n props: Pick<MenuProps, 'checkedValues' | 'defaultCheckedValues' | 'onCheckedValueChange'>,\n) => {\n const [checkedValues, setCheckedValues] = useControllableState({\n state: props.checkedValues,\n defaultState: props.defaultCheckedValues,\n initialState: {},\n });\n const onCheckedValueChange: MenuState['onCheckedValueChange'] = useEventCallback((e, { name, checkedItems }) => {\n props.onCheckedValueChange?.(e, { name, checkedItems });\n\n setCheckedValues(currentValue => ({\n ...currentValue,\n [name]: checkedItems,\n }));\n });\n\n return [checkedValues, onCheckedValueChange] as const;\n};\n\nconst useMenuOpenState = (\n state: Pick<\n MenuState,\n | 'isSubmenu'\n | 'menuPopoverRef'\n | 'setContextTarget'\n | 'triggerRef'\n | 'openOnContext'\n | 'closeOnScroll'\n | 'hoverDelay'\n > &\n Pick<MenuProps, 'open' | 'defaultOpen' | 'onOpenChange'>,\n) => {\n const { targetDocument } = useFluent();\n const parentSetOpen = useMenuContext_unstable(context => context.setOpen);\n const onOpenChange: MenuProps['onOpenChange'] = useEventCallback((e, data) => state.onOpenChange?.(e, data));\n\n const setOpenTimeout = React.useRef(0);\n const enteringTriggerRef = React.useRef(false);\n\n const [open, setOpenState] = useControllableState({\n state: state.open,\n defaultState: state.defaultOpen,\n initialState: false,\n });\n\n const trySetOpen = useEventCallback((e: MenuOpenEvent, data: MenuOpenChangeData) => {\n const event = e instanceof CustomEvent && e.type === MENU_ENTER_EVENT ? e.detail.nativeEvent : e;\n onOpenChange?.(event, { ...data });\n if (data.open && e.type === 'contextmenu') {\n state.setContextTarget(e as React.MouseEvent);\n }\n\n if (!data.open) {\n state.setContextTarget(undefined);\n }\n\n if (data.bubble) {\n parentSetOpen(e, { ...data });\n }\n\n setOpenState(data.open);\n });\n\n const setOpen = useEventCallback((e: MenuOpenEvent, data: MenuOpenChangeData) => {\n clearTimeout(setOpenTimeout.current);\n if (!(e instanceof Event) && e.persist) {\n // < React 17 still uses pooled synthetic events\n e.persist();\n }\n\n if (e.type === 'mouseleave' || e.type === 'mouseenter' || e.type === 'mousemove' || e.type === MENU_ENTER_EVENT) {\n if (state.triggerRef.current?.contains(e.target as HTMLElement)) {\n enteringTriggerRef.current = e.type === 'mouseenter' || e.type === 'mousemove';\n }\n\n // FIXME leaking Node timeout type\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n setOpenTimeout.current = setTimeout(() => trySetOpen(e, data), state.hoverDelay);\n } else {\n trySetOpen(e, data);\n }\n });\n\n useOnClickOutside({\n contains: elementContains,\n disabled: !open,\n element: targetDocument,\n refs: [state.menuPopoverRef, !state.openOnContext && state.triggerRef].filter(\n Boolean,\n ) as React.MutableRefObject<HTMLElement>[],\n callback: event => setOpen(event, { open: false, type: 'clickOutside', event }),\n });\n\n // only close on scroll for context, or when closeOnScroll is specified\n const closeOnScroll = state.openOnContext || state.closeOnScroll;\n useOnScrollOutside({\n contains: elementContains,\n element: targetDocument,\n callback: event => setOpen(event, { open: false, type: 'scrollOutside', event }),\n refs: [state.menuPopoverRef, !state.openOnContext && state.triggerRef].filter(\n Boolean,\n ) as React.MutableRefObject<HTMLElement>[],\n disabled: !open || !closeOnScroll,\n });\n\n useOnMenuMouseEnter({\n element: targetDocument,\n callback: event => {\n // When moving from a menu directly back to its trigger, this handler can close the menu\n // Explicitly check a flag to see if this situation happens\n if (!enteringTriggerRef.current) {\n setOpen(event, { open: false, type: 'menuMouseEnter', event });\n }\n },\n disabled: !open,\n refs: [state.menuPopoverRef],\n });\n\n // Clear timeout on unmount\n // Setting state after a component unmounts can cause memory leaks\n React.useEffect(() => {\n return () => {\n clearTimeout(setOpenTimeout.current);\n };\n }, []);\n\n // Manage focus for open state\n const { findFirstFocusable } = useFocusFinders();\n const focusFirst = React.useCallback(() => {\n const firstFocusable = findFirstFocusable(state.menuPopoverRef.current);\n firstFocusable?.focus();\n }, [findFirstFocusable, state.menuPopoverRef]);\n\n const firstMount = useFirstMount();\n React.useEffect(() => {\n if (open) {\n focusFirst();\n } else {\n if (!firstMount) {\n if (targetDocument?.activeElement === targetDocument?.body) {\n // We know that React effects are sync so we focus the trigger here\n // after any event handler (event handlers will update state and re-render).\n // Since the browser only performs the default behaviour for the Tab key once\n // keyboard events have fully bubbled up the window, the browser will move\n // focus to the next tabbable element before/after the trigger if needed.\n // If the Tab key was not pressed, focus will remain on the trigger as expected.\n state.triggerRef.current?.focus();\n }\n }\n }\n // firstMount change should not re-run this effect\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [state.triggerRef, state.isSubmenu, open, focusFirst, targetDocument, state.menuPopoverRef]);\n\n return [open, setOpen] as const;\n};\n"],"names":["React","usePositioningMouseTarget","usePositioning","resolvePositioningShorthand","useControllableState","useId","useOnClickOutside","useEventCallback","useOnScrollOutside","useFirstMount","useFluent_unstable","useFluent","elementContains","useFocusFinders","useMenuContext_unstable","MENU_ENTER_EVENT","useOnMenuMouseEnter","useIsSubmenu","submenuFallbackPositions","useMenu_unstable","props","isSubmenu","hoverDelay","inline","hasCheckmarks","hasIcons","closeOnScroll","openOnContext","persistOnItemClick","openOnHover","defaultCheckedValues","mountNode","triggerId","contextTarget","setContextTarget","positioningState","position","align","target","undefined","fallbackPositions","positioning","children","Children","toArray","process","env","NODE_ENV","length","console","warn","menuTrigger","menuPopover","targetRef","triggerRef","containerRef","menuPopoverRef","open","setOpen","useMenuOpenState","defaultOpen","onOpenChange","checkedValues","onCheckedValueChange","useMenuSelectableState","components","setCheckedValues","state","defaultState","initialState","e","name","checkedItems","currentValue","targetDocument","parentSetOpen","context","data","setOpenTimeout","useRef","enteringTriggerRef","setOpenState","trySetOpen","event","CustomEvent","type","detail","nativeEvent","bubble","clearTimeout","current","Event","persist","contains","setTimeout","disabled","element","refs","filter","Boolean","callback","useEffect","findFirstFocusable","focusFirst","useCallback","firstFocusable","focus","firstMount","activeElement","body"],"mappings":"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"}
|
1
|
+
{"version":3,"sources":["useMenu.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n usePositioningMouseTarget,\n usePositioning,\n resolvePositioningShorthand,\n PositioningShorthandValue,\n} from '@fluentui/react-positioning';\nimport {\n useControllableState,\n useId,\n useOnClickOutside,\n useEventCallback,\n useOnScrollOutside,\n} from '@fluentui/react-utilities';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport { elementContains } from '@fluentui/react-portal';\nimport { useFocusFinders } from '@fluentui/react-tabster';\nimport { useMenuContext_unstable } from '../../contexts/menuContext';\nimport { MENU_ENTER_EVENT, useOnMenuMouseEnter } from '../../utils/index';\nimport { useIsSubmenu } from '../../utils/useIsSubmenu';\nimport type { MenuOpenChangeData, MenuOpenEvent, MenuProps, MenuState } from './Menu.types';\n\n// If it's not possible to position the submenu in smaller viewports, try\n// and fallback to this order of positions\nconst submenuFallbackPositions: PositioningShorthandValue[] = [\n 'after',\n 'after-bottom',\n 'before-top',\n 'before',\n 'before-bottom',\n 'above',\n];\n\n/**\n * Create the state required to render Menu.\n *\n * The returned state can be modified with hooks such as useMenuStyles,\n * before being passed to renderMenu_unstable.\n *\n * @param props - props from this instance of Menu\n */\nexport const useMenu_unstable = (props: MenuProps): MenuState => {\n const isSubmenu = useIsSubmenu();\n const {\n hoverDelay = 500,\n inline = false,\n hasCheckmarks = false,\n hasIcons = false,\n closeOnScroll = false,\n openOnContext = false,\n persistOnItemClick = false,\n openOnHover = isSubmenu,\n defaultCheckedValues,\n mountNode = null,\n } = props;\n const triggerId = useId('menu');\n const [contextTarget, setContextTarget] = usePositioningMouseTarget();\n\n const positioningState = {\n position: isSubmenu ? 'after' : 'below',\n align: isSubmenu ? 'top' : 'start',\n target: props.openOnContext ? contextTarget : undefined,\n fallbackPositions: isSubmenu ? submenuFallbackPositions : undefined,\n ...resolvePositioningShorthand(props.positioning),\n } as const;\n\n const children = React.Children.toArray(props.children) as React.ReactElement[];\n\n if (process.env.NODE_ENV !== 'production') {\n if (children.length === 0) {\n // eslint-disable-next-line no-console\n console.warn('Menu must contain at least one child');\n }\n\n if (children.length > 2) {\n // eslint-disable-next-line no-console\n console.warn('Menu must contain at most two children');\n }\n }\n\n let menuTrigger: React.ReactElement | undefined = undefined;\n let menuPopover: React.ReactElement | undefined = undefined;\n if (children.length === 2) {\n menuTrigger = children[0];\n menuPopover = children[1];\n } else if (children.length === 1) {\n menuPopover = children[0];\n }\n\n const { targetRef: triggerRef, containerRef: menuPopoverRef } = usePositioning(positioningState);\n\n // TODO Better way to narrow types ?\n const [open, setOpen] = useMenuOpenState({\n hoverDelay,\n isSubmenu,\n setContextTarget,\n closeOnScroll,\n menuPopoverRef,\n triggerRef,\n open: props.open,\n defaultOpen: props.defaultOpen,\n onOpenChange: props.onOpenChange,\n openOnContext,\n });\n\n const [checkedValues, onCheckedValueChange] = useMenuSelectableState({\n checkedValues: props.checkedValues,\n defaultCheckedValues,\n onCheckedValueChange: props.onCheckedValueChange,\n });\n\n return {\n inline,\n hoverDelay,\n triggerId,\n isSubmenu,\n openOnHover,\n contextTarget,\n setContextTarget,\n hasCheckmarks,\n hasIcons,\n closeOnScroll,\n menuTrigger,\n menuPopover,\n mountNode,\n triggerRef,\n menuPopoverRef,\n components: {},\n openOnContext,\n open,\n setOpen,\n checkedValues,\n onCheckedValueChange,\n persistOnItemClick,\n };\n};\n\n/**\n * Adds appropriate state values and handlers for selectable items\n * i.e checkboxes and radios\n */\nconst useMenuSelectableState = (\n props: Pick<MenuProps, 'checkedValues' | 'defaultCheckedValues' | 'onCheckedValueChange'>,\n) => {\n const [checkedValues, setCheckedValues] = useControllableState({\n state: props.checkedValues,\n defaultState: props.defaultCheckedValues,\n initialState: {},\n });\n const onCheckedValueChange: MenuState['onCheckedValueChange'] = useEventCallback((e, { name, checkedItems }) => {\n props.onCheckedValueChange?.(e, { name, checkedItems });\n\n setCheckedValues(currentValue => ({\n ...currentValue,\n [name]: checkedItems,\n }));\n });\n\n return [checkedValues, onCheckedValueChange] as const;\n};\n\nconst useMenuOpenState = (\n state: Pick<\n MenuState,\n | 'isSubmenu'\n | 'menuPopoverRef'\n | 'setContextTarget'\n | 'triggerRef'\n | 'openOnContext'\n | 'closeOnScroll'\n | 'hoverDelay'\n > &\n Pick<MenuProps, 'open' | 'defaultOpen' | 'onOpenChange'>,\n) => {\n const { targetDocument } = useFluent();\n const parentSetOpen = useMenuContext_unstable(context => context.setOpen);\n const onOpenChange: MenuProps['onOpenChange'] = useEventCallback((e, data) => state.onOpenChange?.(e, data));\n\n const setOpenTimeout = React.useRef(0);\n const enteringTriggerRef = React.useRef(false);\n\n const [open, setOpenState] = useControllableState({\n state: state.open,\n defaultState: state.defaultOpen,\n initialState: false,\n });\n\n const trySetOpen = useEventCallback((e: MenuOpenEvent, data: MenuOpenChangeData) => {\n const event = e instanceof CustomEvent && e.type === MENU_ENTER_EVENT ? e.detail.nativeEvent : e;\n onOpenChange?.(event, { ...data });\n if (data.open && e.type === 'contextmenu') {\n state.setContextTarget(e as React.MouseEvent);\n }\n\n if (!data.open) {\n state.setContextTarget(undefined);\n }\n\n if (data.bubble) {\n parentSetOpen(e, { ...data });\n }\n\n setOpenState(data.open);\n });\n\n const setOpen = useEventCallback((e: MenuOpenEvent, data: MenuOpenChangeData) => {\n clearTimeout(setOpenTimeout.current);\n if (!(e instanceof Event) && e.persist) {\n // < React 17 still uses pooled synthetic events\n e.persist();\n }\n\n if (e.type === 'mouseleave' || e.type === 'mouseenter' || e.type === 'mousemove' || e.type === MENU_ENTER_EVENT) {\n if (state.triggerRef.current?.contains(e.target as HTMLElement)) {\n enteringTriggerRef.current = e.type === 'mouseenter' || e.type === 'mousemove';\n }\n\n // FIXME leaking Node timeout type\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n setOpenTimeout.current = setTimeout(() => trySetOpen(e, data), state.hoverDelay);\n } else {\n trySetOpen(e, data);\n }\n });\n\n useOnClickOutside({\n contains: elementContains,\n disabled: !open,\n element: targetDocument,\n refs: [state.menuPopoverRef, !state.openOnContext && state.triggerRef].filter(\n Boolean,\n ) as React.MutableRefObject<HTMLElement>[],\n callback: event => setOpen(event, { open: false, type: 'clickOutside', event }),\n });\n\n // only close on scroll for context, or when closeOnScroll is specified\n const closeOnScroll = state.openOnContext || state.closeOnScroll;\n useOnScrollOutside({\n contains: elementContains,\n element: targetDocument,\n callback: event => setOpen(event, { open: false, type: 'scrollOutside', event }),\n refs: [state.menuPopoverRef, !state.openOnContext && state.triggerRef].filter(\n Boolean,\n ) as React.MutableRefObject<HTMLElement>[],\n disabled: !open || !closeOnScroll,\n });\n\n useOnMenuMouseEnter({\n element: targetDocument,\n callback: event => {\n // When moving from a menu directly back to its trigger, this handler can close the menu\n // Explicitly check a flag to see if this situation happens\n if (!enteringTriggerRef.current) {\n setOpen(event, { open: false, type: 'menuMouseEnter', event });\n }\n },\n disabled: !open,\n refs: [state.menuPopoverRef],\n });\n\n // Clear timeout on unmount\n // Setting state after a component unmounts can cause memory leaks\n React.useEffect(() => {\n return () => {\n clearTimeout(setOpenTimeout.current);\n };\n }, []);\n\n // Manage focus for open state\n const { findFirstFocusable } = useFocusFinders();\n const focusFirst = React.useCallback(() => {\n const firstFocusable = findFirstFocusable(state.menuPopoverRef.current);\n firstFocusable?.focus();\n }, [findFirstFocusable, state.menuPopoverRef]);\n\n React.useEffect(() => {\n if (open) {\n focusFirst();\n }\n }, [open, focusFirst]);\n\n return [open, setOpen] as const;\n};\n"],"names":["React","usePositioningMouseTarget","usePositioning","resolvePositioningShorthand","useControllableState","useId","useOnClickOutside","useEventCallback","useOnScrollOutside","useFluent_unstable","useFluent","elementContains","useFocusFinders","useMenuContext_unstable","MENU_ENTER_EVENT","useOnMenuMouseEnter","useIsSubmenu","submenuFallbackPositions","useMenu_unstable","props","isSubmenu","hoverDelay","inline","hasCheckmarks","hasIcons","closeOnScroll","openOnContext","persistOnItemClick","openOnHover","defaultCheckedValues","mountNode","triggerId","contextTarget","setContextTarget","positioningState","position","align","target","undefined","fallbackPositions","positioning","children","Children","toArray","process","env","NODE_ENV","length","console","warn","menuTrigger","menuPopover","targetRef","triggerRef","containerRef","menuPopoverRef","open","setOpen","useMenuOpenState","defaultOpen","onOpenChange","checkedValues","onCheckedValueChange","useMenuSelectableState","components","setCheckedValues","state","defaultState","initialState","e","name","checkedItems","currentValue","targetDocument","parentSetOpen","context","data","setOpenTimeout","useRef","enteringTriggerRef","setOpenState","trySetOpen","event","CustomEvent","type","detail","nativeEvent","bubble","clearTimeout","current","Event","persist","contains","setTimeout","disabled","element","refs","filter","Boolean","callback","useEffect","findFirstFocusable","focusFirst","useCallback","firstFocusable","focus"],"mappings":"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"}
|
@@ -52,8 +52,8 @@ const useStyles = /*#__PURE__*/__styles({
|
|
52
52
|
qhf8xq: "f10pi13n",
|
53
53
|
sj55zd: "fkfq4zb",
|
54
54
|
De3pzq: "fxugw4r",
|
55
|
-
z189sj: ["
|
56
|
-
uwmqm3: ["
|
55
|
+
z189sj: ["f1sgzk6v", "f1bg5zqg"],
|
56
|
+
uwmqm3: ["f1bg5zqg", "f1sgzk6v"],
|
57
57
|
Bqenvij: "f1d2rq10",
|
58
58
|
mc9l5x: "f22iagw",
|
59
59
|
Bt984gj: "f122n59",
|
@@ -116,7 +116,7 @@ const useStyles = /*#__PURE__*/__styles({
|
|
116
116
|
}, {
|
117
117
|
f: [".ftqa4ok:focus{outline-style:none;}", ".fc1cou1:focus{color:var(--colorNeutralForeground3Hover);}", ".ft33916:focus{color:var(--colorNeutralForegroundDisabled);}"],
|
118
118
|
i: [".f2hkw1w:focus-visible{outline-style:none;}"],
|
119
|
-
d: [".f8hki3x[data-fui-focus-visible]{border-top-color:transparent;}", ".f1d2448m[data-fui-focus-visible]{border-right-color:transparent;}", ".ffh67wi[data-fui-focus-visible]{border-left-color:transparent;}", ".f1bjia2o[data-fui-focus-visible]{border-bottom-color:transparent;}", ".f15bsgw9[data-fui-focus-visible]::after{content:\"\";}", ".f14e48fq[data-fui-focus-visible]::after{position:absolute;}", ".f18yb2kv[data-fui-focus-visible]::after{pointer-events:none;}", ".fd6o370[data-fui-focus-visible]::after{z-index:1;}", ".fh1cnn4[data-fui-focus-visible]::after{border-top-style:solid;}", ".fy7oxxb[data-fui-focus-visible]::after{border-right-style:solid;}", ".f184ne2d[data-fui-focus-visible]::after{border-left-style:solid;}", ".fpukqih[data-fui-focus-visible]::after{border-bottom-style:solid;}", ".frrh606[data-fui-focus-visible]::after{border-top-width:2px;}", ".f1v5zibi[data-fui-focus-visible]::after{border-right-width:2px;}", ".fo2hd23[data-fui-focus-visible]::after{border-left-width:2px;}", ".ful5kiu[data-fui-focus-visible]::after{border-bottom-width:2px;}", ".f1jqcqds[data-fui-focus-visible]::after{border-bottom-right-radius:var(--borderRadiusMedium);}", ".ftffrms[data-fui-focus-visible]::after{border-bottom-left-radius:var(--borderRadiusMedium);}", ".f2e7qr6[data-fui-focus-visible]::after{border-top-right-radius:var(--borderRadiusMedium);}", ".fsr1zz6[data-fui-focus-visible]::after{border-top-left-radius:var(--borderRadiusMedium);}", ".f1dvezut[data-fui-focus-visible]::after{border-top-color:var(--colorStrokeFocus2);}", ".fd0oaoj[data-fui-focus-visible]::after{border-right-color:var(--colorStrokeFocus2);}", ".f1cwg4i8[data-fui-focus-visible]::after{border-left-color:var(--colorStrokeFocus2);}", ".fjvm52t[data-fui-focus-visible]::after{border-bottom-color:var(--colorStrokeFocus2);}", ".f57olzd[data-fui-focus-visible]::after{top:calc(2px * -1);}", ".f4stah7[data-fui-focus-visible]::after{right:calc(2px * -1);}", ".fs1por5[data-fui-focus-visible]::after{left:calc(2px * -1);}", ".f480a47[data-fui-focus-visible]::after{bottom:calc(2px * -1);}", ".f1aa9q02{border-bottom-right-radius:var(--borderRadiusMedium);}", ".f16jpd5f{border-bottom-left-radius:var(--borderRadiusMedium);}", ".f1jar5jt{border-top-right-radius:var(--borderRadiusMedium);}", ".fyu767a{border-top-left-radius:var(--borderRadiusMedium);}", ".f10pi13n{position:relative;}", ".fkfq4zb{color:var(--colorNeutralForeground2);}", ".fxugw4r{background-color:var(--colorNeutralBackground1);}", ".
|
119
|
+
d: [".f8hki3x[data-fui-focus-visible]{border-top-color:transparent;}", ".f1d2448m[data-fui-focus-visible]{border-right-color:transparent;}", ".ffh67wi[data-fui-focus-visible]{border-left-color:transparent;}", ".f1bjia2o[data-fui-focus-visible]{border-bottom-color:transparent;}", ".f15bsgw9[data-fui-focus-visible]::after{content:\"\";}", ".f14e48fq[data-fui-focus-visible]::after{position:absolute;}", ".f18yb2kv[data-fui-focus-visible]::after{pointer-events:none;}", ".fd6o370[data-fui-focus-visible]::after{z-index:1;}", ".fh1cnn4[data-fui-focus-visible]::after{border-top-style:solid;}", ".fy7oxxb[data-fui-focus-visible]::after{border-right-style:solid;}", ".f184ne2d[data-fui-focus-visible]::after{border-left-style:solid;}", ".fpukqih[data-fui-focus-visible]::after{border-bottom-style:solid;}", ".frrh606[data-fui-focus-visible]::after{border-top-width:2px;}", ".f1v5zibi[data-fui-focus-visible]::after{border-right-width:2px;}", ".fo2hd23[data-fui-focus-visible]::after{border-left-width:2px;}", ".ful5kiu[data-fui-focus-visible]::after{border-bottom-width:2px;}", ".f1jqcqds[data-fui-focus-visible]::after{border-bottom-right-radius:var(--borderRadiusMedium);}", ".ftffrms[data-fui-focus-visible]::after{border-bottom-left-radius:var(--borderRadiusMedium);}", ".f2e7qr6[data-fui-focus-visible]::after{border-top-right-radius:var(--borderRadiusMedium);}", ".fsr1zz6[data-fui-focus-visible]::after{border-top-left-radius:var(--borderRadiusMedium);}", ".f1dvezut[data-fui-focus-visible]::after{border-top-color:var(--colorStrokeFocus2);}", ".fd0oaoj[data-fui-focus-visible]::after{border-right-color:var(--colorStrokeFocus2);}", ".f1cwg4i8[data-fui-focus-visible]::after{border-left-color:var(--colorStrokeFocus2);}", ".fjvm52t[data-fui-focus-visible]::after{border-bottom-color:var(--colorStrokeFocus2);}", ".f57olzd[data-fui-focus-visible]::after{top:calc(2px * -1);}", ".f4stah7[data-fui-focus-visible]::after{right:calc(2px * -1);}", ".fs1por5[data-fui-focus-visible]::after{left:calc(2px * -1);}", ".f480a47[data-fui-focus-visible]::after{bottom:calc(2px * -1);}", ".f1aa9q02{border-bottom-right-radius:var(--borderRadiusMedium);}", ".f16jpd5f{border-bottom-left-radius:var(--borderRadiusMedium);}", ".f1jar5jt{border-top-right-radius:var(--borderRadiusMedium);}", ".fyu767a{border-top-left-radius:var(--borderRadiusMedium);}", ".f10pi13n{position:relative;}", ".fkfq4zb{color:var(--colorNeutralForeground2);}", ".fxugw4r{background-color:var(--colorNeutralBackground1);}", ".f1sgzk6v{padding-right:6px;}", ".f1bg5zqg{padding-left:6px;}", ".f1d2rq10{height:32px;}", ".f22iagw{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}", ".f122n59{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}", ".fkhj508{font-size:var(--fontSizeBase300);}", ".f1k6fduh{cursor:pointer;}", ".f1q8lukm{-webkit-column-gap:4px;column-gap:4px;}", ".f1ma2n7n{row-gap:4px;}", ".f1xqy1su{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}", ".f161knb0{padding-left:2px;}", ".f12huiiw{padding-right:2px;}", ".f3rmtva{background-color:transparent;}", ".fqerorx{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}", ".f11d4kpn{color:var(--colorNeutralForeground3);}", ".f64fuq3{width:20px;}", ".fjamq6b{height:20px;}", ".fe5j1ua{font-size:20px;}", ".fez10in{line-height:0;}", ".ftuwxu6{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;}", ".f4d9j23{-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}", ".f1s2aq7o{color:var(--colorNeutralForegroundDisabled);}"],
|
120
120
|
h: [".f1knas48:hover{background-color:var(--colorNeutralBackground1Hover);}", ".fnwyq0v:hover{color:var(--colorNeutralForeground2Hover);}", ".ft1hn21:hover .fui-Icon-filled{display:inline;}", ".fuxngvv:hover .fui-Icon-regular{display:none;}", ".fp258yr:hover .fui-MenuItem__icon{color:var(--colorNeutralForeground2BrandSelected);}", ".f1jp5ecu:hover{color:var(--colorNeutralForeground3Hover);}", ".fvgxktp:hover{color:var(--colorNeutralForegroundDisabled);}", ".f1ijtazh:hover{background-color:var(--colorNeutralBackground1);}", ".fphbwmw:hover{cursor:not-allowed;}", ".f19vpps7:hover .fui-Icon-filled{display:none;}", ".fv5swzo:hover .fui-Icon-regular{display:inline;}", ".f1q1x1ba:hover .fui-MenuItem__icon{color:var(--colorNeutralForegroundDisabled);}"],
|
121
121
|
m: [["@media (forced-colors: active){.f1dcs8yz{color:GrayText;}}", {
|
122
122
|
m: "(forced-colors: active)"
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"names":["mergeClasses","__styles","shorthands","iconFilledClassName","iconRegularClassName","createFocusOutlineStyle","tokens","useCheckmarkStyles_unstable","menuItemClassNames","root","icon","checkmark","submenuIndicator","content","secondaryContent","useStyles","focusIndicator","Brovlpu","B486eqv","B8q5s1w","Bci5o5g","n8qw10","Bdrgwmp","Bm4h7ae","B7ys5i9","Busjfv9","Bhk32uz","Bf4ptjt","kclons","Bhdgwq3","Blkhhs4","Bqtpl0w","clg4pj","hgwjuy","Bonggc9","B1tsrr9","Dah5zi","Bkh64rk","qqdqy8","B6dhp37","i03rao","Boxcth7","Bsom6fd","J0r882","Bule8hv","Bjwuhne","Ghsupd","Bbmb7ep","Beyfa6y","B7oj6ja","Btl43ni","qhf8xq","sj55zd","De3pzq","z189sj","uwmqm3","Bqenvij","mc9l5x","Bt984gj","Be2twd7","Bceei9c","i8kkvl","Belr9w4","Jwef8y","Bi91k9c","Bk3fhr4","Bmfj8id","Bg7n49j","famaaq","Bh6795r","t0hwav","a9b677","Bg96gwp","Brf1p80","disabled","eoavqd","Bbusuzp","ze5xyy","Bctn1xl","Bh6z0a4","f","i","d","h","m","useMenuItemStyles_unstable","state","styles","className"],"sources":["useMenuItemStyles.styles.js"],"sourcesContent":["import { mergeClasses, makeStyles, shorthands } from '@griffel/react';\nimport { iconFilledClassName, iconRegularClassName } from '@fluentui/react-icons';\nimport { createFocusOutlineStyle } from '@fluentui/react-tabster';\nimport { tokens } from '@fluentui/react-theme';\nimport { useCheckmarkStyles_unstable } from '../../selectable/index';\nexport const menuItemClassNames = {\n root: 'fui-MenuItem',\n icon: 'fui-MenuItem__icon',\n checkmark: 'fui-MenuItem__checkmark',\n submenuIndicator: 'fui-MenuItem__submenuIndicator',\n content: 'fui-MenuItem__content',\n secondaryContent: 'fui-MenuItem__secondaryContent'\n};\nconst useStyles = makeStyles({\n focusIndicator: createFocusOutlineStyle(),\n // TODO: this should be extracted to another package\n root: {\n ...shorthands.borderRadius(tokens.borderRadiusMedium),\n position: 'relative',\n color: tokens.colorNeutralForeground2,\n backgroundColor: tokens.colorNeutralBackground1,\n paddingRight: '
|
1
|
+
{"version":3,"names":["mergeClasses","__styles","shorthands","iconFilledClassName","iconRegularClassName","createFocusOutlineStyle","tokens","useCheckmarkStyles_unstable","menuItemClassNames","root","icon","checkmark","submenuIndicator","content","secondaryContent","useStyles","focusIndicator","Brovlpu","B486eqv","B8q5s1w","Bci5o5g","n8qw10","Bdrgwmp","Bm4h7ae","B7ys5i9","Busjfv9","Bhk32uz","Bf4ptjt","kclons","Bhdgwq3","Blkhhs4","Bqtpl0w","clg4pj","hgwjuy","Bonggc9","B1tsrr9","Dah5zi","Bkh64rk","qqdqy8","B6dhp37","i03rao","Boxcth7","Bsom6fd","J0r882","Bule8hv","Bjwuhne","Ghsupd","Bbmb7ep","Beyfa6y","B7oj6ja","Btl43ni","qhf8xq","sj55zd","De3pzq","z189sj","uwmqm3","Bqenvij","mc9l5x","Bt984gj","Be2twd7","Bceei9c","i8kkvl","Belr9w4","Jwef8y","Bi91k9c","Bk3fhr4","Bmfj8id","Bg7n49j","famaaq","Bh6795r","t0hwav","a9b677","Bg96gwp","Brf1p80","disabled","eoavqd","Bbusuzp","ze5xyy","Bctn1xl","Bh6z0a4","f","i","d","h","m","useMenuItemStyles_unstable","state","styles","className"],"sources":["useMenuItemStyles.styles.js"],"sourcesContent":["import { mergeClasses, makeStyles, shorthands } from '@griffel/react';\nimport { iconFilledClassName, iconRegularClassName } from '@fluentui/react-icons';\nimport { createFocusOutlineStyle } from '@fluentui/react-tabster';\nimport { tokens } from '@fluentui/react-theme';\nimport { useCheckmarkStyles_unstable } from '../../selectable/index';\nexport const menuItemClassNames = {\n root: 'fui-MenuItem',\n icon: 'fui-MenuItem__icon',\n checkmark: 'fui-MenuItem__checkmark',\n submenuIndicator: 'fui-MenuItem__submenuIndicator',\n content: 'fui-MenuItem__content',\n secondaryContent: 'fui-MenuItem__secondaryContent'\n};\nconst useStyles = makeStyles({\n focusIndicator: createFocusOutlineStyle(),\n // TODO: this should be extracted to another package\n root: {\n ...shorthands.borderRadius(tokens.borderRadiusMedium),\n position: 'relative',\n color: tokens.colorNeutralForeground2,\n backgroundColor: tokens.colorNeutralBackground1,\n paddingRight: '6px',\n paddingLeft: '6px',\n height: '32px',\n display: 'flex',\n alignItems: 'center',\n fontSize: tokens.fontSizeBase300,\n cursor: 'pointer',\n ...shorthands.gap('4px'),\n ':hover': {\n backgroundColor: tokens.colorNeutralBackground1Hover,\n color: tokens.colorNeutralForeground2Hover,\n [`& .${iconFilledClassName}`]: {\n display: 'inline'\n },\n [`& .${iconRegularClassName}`]: {\n display: 'none'\n },\n [`& .${menuItemClassNames.icon}`]: {\n color: tokens.colorNeutralForeground2BrandSelected\n }\n },\n userSelect: 'none'\n },\n content: {\n paddingLeft: '2px',\n paddingRight: '2px',\n backgroundColor: 'transparent',\n flexGrow: 1\n },\n secondaryContent: {\n paddingLeft: '2px',\n paddingRight: '2px',\n color: tokens.colorNeutralForeground3,\n ':hover': {\n color: tokens.colorNeutralForeground3Hover\n },\n ':focus': {\n color: tokens.colorNeutralForeground3Hover\n }\n },\n icon: {\n width: '20px',\n height: '20px',\n fontSize: '20px',\n lineHeight: 0,\n alignItems: 'center',\n display: 'inline-flex',\n justifyContent: 'center'\n },\n submenuIndicator: {\n width: '20px',\n height: '20px',\n fontSize: '20px',\n lineHeight: 0,\n alignItems: 'center',\n display: 'inline-flex',\n justifyContent: 'center'\n },\n disabled: {\n color: tokens.colorNeutralForegroundDisabled,\n ':hover': {\n color: tokens.colorNeutralForegroundDisabled,\n backgroundColor: tokens.colorNeutralBackground1,\n cursor: 'not-allowed',\n [`& .${iconFilledClassName}`]: {\n display: 'none'\n },\n [`& .${iconRegularClassName}`]: {\n display: 'inline'\n },\n [`& .${menuItemClassNames.icon}`]: {\n color: tokens.colorNeutralForegroundDisabled\n }\n },\n ':focus': {\n color: tokens.colorNeutralForegroundDisabled\n },\n '@media (forced-colors: active)': {\n color: 'GrayText',\n ':hover': {\n color: 'GrayText',\n [`& .${menuItemClassNames.icon}`]: {\n color: 'GrayText'\n }\n },\n ':focus': {\n color: 'GrayText'\n }\n }\n }\n});\n/** Applies style classnames to slots */ export const useMenuItemStyles_unstable = (state)=>{\n const styles = useStyles();\n state.root.className = mergeClasses(menuItemClassNames.root, styles.root, styles.focusIndicator, state.disabled && styles.disabled, state.root.className);\n if (state.content) {\n state.content.className = mergeClasses(menuItemClassNames.content, styles.content, state.content.className);\n }\n if (state.checkmark) {\n state.checkmark.className = mergeClasses(menuItemClassNames.checkmark, state.checkmark.className);\n }\n if (state.secondaryContent) {\n state.secondaryContent.className = mergeClasses(menuItemClassNames.secondaryContent, !state.disabled && styles.secondaryContent, state.secondaryContent.className);\n }\n if (state.icon) {\n state.icon.className = mergeClasses(menuItemClassNames.icon, styles.icon, state.icon.className);\n }\n if (state.submenuIndicator) {\n state.submenuIndicator.className = mergeClasses(menuItemClassNames.submenuIndicator, styles.submenuIndicator, state.submenuIndicator.className);\n }\n useCheckmarkStyles_unstable(state);\n};\n"],"mappings":"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"}
|
@@ -5,6 +5,7 @@ import { useMenuContext_unstable } from '../../contexts/menuContext';
|
|
5
5
|
import { dispatchMenuEnterEvent } from '../../utils/index';
|
6
6
|
import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
|
7
7
|
import { useIsSubmenu } from '../../utils/useIsSubmenu';
|
8
|
+
import { useRestoreFocusSource } from '@fluentui/react-tabster';
|
8
9
|
/**
|
9
10
|
* Create the state required to render MenuPopover.
|
10
11
|
*
|
@@ -18,9 +19,11 @@ import { useIsSubmenu } from '../../utils/useIsSubmenu';
|
|
18
19
|
const setOpen = useMenuContext_unstable((context)=>context.setOpen);
|
19
20
|
const open = useMenuContext_unstable((context)=>context.open);
|
20
21
|
const openOnHover = useMenuContext_unstable((context)=>context.openOnHover);
|
22
|
+
const triggerRef = useMenuContext_unstable((context)=>context.triggerRef);
|
21
23
|
const isSubmenu = useIsSubmenu();
|
22
24
|
const canDispatchCustomEventRef = React.useRef(true);
|
23
25
|
const throttleDispatchTimerRef = React.useRef(0);
|
26
|
+
const restoreFocusSourceAttributes = useRestoreFocusSource();
|
24
27
|
const { dir } = useFluent();
|
25
28
|
const CloseArrowKey = dir === 'ltr' ? ArrowLeft : ArrowRight;
|
26
29
|
// use DOM listener since react events propagate up the react tree
|
@@ -52,6 +55,7 @@ import { useIsSubmenu } from '../../utils/useIsSubmenu';
|
|
52
55
|
const mountNode = useMenuContext_unstable((context)=>context.mountNode);
|
53
56
|
const rootProps = getNativeElementProps('div', {
|
54
57
|
role: 'presentation',
|
58
|
+
...restoreFocusSourceAttributes,
|
55
59
|
...props,
|
56
60
|
ref: useMergedRefs(ref, popoverRef, mouseOverListenerCallbackRef)
|
57
61
|
});
|
@@ -90,6 +94,10 @@ import { useIsSubmenu } from '../../utils/useIsSubmenu';
|
|
90
94
|
type: 'menuPopoverKeyDown',
|
91
95
|
event
|
92
96
|
});
|
97
|
+
if (!isSubmenu) {
|
98
|
+
var _triggerRef_current;
|
99
|
+
(_triggerRef_current = triggerRef.current) === null || _triggerRef_current === void 0 ? void 0 : _triggerRef_current.focus();
|
100
|
+
}
|
93
101
|
}
|
94
102
|
onKeyDownOriginal === null || onKeyDownOriginal === void 0 ? void 0 : onKeyDownOriginal(event);
|
95
103
|
});
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["useMenuPopover.ts"],"sourcesContent":["import * as React from 'react';\nimport { ArrowLeft, Tab, ArrowRight, Escape } from '@fluentui/keyboard-keys';\nimport { getNativeElementProps, useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { MenuPopoverProps, MenuPopoverState } from './MenuPopover.types';\nimport { useMenuContext_unstable } from '../../contexts/menuContext';\nimport { dispatchMenuEnterEvent } from '../../utils/index';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport { useIsSubmenu } from '../../utils/useIsSubmenu';\n\n/**\n * Create the state required to render MenuPopover.\n *\n * The returned state can be modified with hooks such as useMenuPopoverStyles_unstable,\n * before being passed to renderMenuPopover_unstable.\n *\n * @param props - props from this instance of MenuPopover\n * @param ref - reference to root HTMLElement of MenuPopover\n */\nexport const useMenuPopover_unstable = (props: MenuPopoverProps, ref: React.Ref<HTMLElement>): MenuPopoverState => {\n const popoverRef = useMenuContext_unstable(context => context.menuPopoverRef);\n const setOpen = useMenuContext_unstable(context => context.setOpen);\n const open = useMenuContext_unstable(context => context.open);\n const openOnHover = useMenuContext_unstable(context => context.openOnHover);\n const isSubmenu = useIsSubmenu();\n const canDispatchCustomEventRef = React.useRef(true);\n const throttleDispatchTimerRef = React.useRef(0);\n\n const { dir } = useFluent();\n const CloseArrowKey = dir === 'ltr' ? ArrowLeft : ArrowRight;\n\n // use DOM listener since react events propagate up the react tree\n // no need to do `contains` logic as menus are all positioned in different portals\n const mouseOverListenerCallbackRef = React.useCallback(\n (node: HTMLElement) => {\n if (node) {\n // Dispatches the custom menu mouse enter event with throttling\n // Needs to trigger on mouseover to support keyboard + mouse together\n // i.e. keyboard opens submenus while cursor is still on the parent\n node.addEventListener('mouseover', e => {\n if (canDispatchCustomEventRef.current) {\n canDispatchCustomEventRef.current = false;\n dispatchMenuEnterEvent(popoverRef.current as HTMLElement, e);\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore #16889 Node setTimeout type leaking\n throttleDispatchTimerRef.current = setTimeout(() => (canDispatchCustomEventRef.current = true), 250);\n }\n });\n }\n },\n [popoverRef, throttleDispatchTimerRef],\n );\n\n React.useEffect(() => {\n () => clearTimeout(throttleDispatchTimerRef.current);\n }, []);\n\n const inline = useMenuContext_unstable(context => context.inline) ?? false;\n const mountNode = useMenuContext_unstable(context => context.mountNode);\n\n const rootProps = getNativeElementProps('div', {\n role: 'presentation',\n ...props,\n ref: useMergedRefs(ref, popoverRef, mouseOverListenerCallbackRef),\n });\n\n const { onMouseEnter: onMouseEnterOriginal, onKeyDown: onKeyDownOriginal } = rootProps;\n\n rootProps.onMouseEnter = useEventCallback((event: React.MouseEvent<HTMLElement>) => {\n if (openOnHover) {\n setOpen(event, { open: true, keyboard: false, type: 'menuPopoverMouseEnter', event });\n }\n\n onMouseEnterOriginal?.(event);\n });\n\n rootProps.onKeyDown = useEventCallback((event: React.KeyboardEvent<HTMLElement>) => {\n const key = event.key;\n\n if (key === Escape || (isSubmenu && key === CloseArrowKey)) {\n if (open && popoverRef.current?.contains(event.target as HTMLElement)) {\n setOpen(event, { open: false, keyboard: true, type: 'menuPopoverKeyDown', event });\n // stop propagation to avoid conflicting with other elements that listen for `Escape`\n // e,g: Dialog, Popover and Tooltip\n event.stopPropagation();\n }\n }\n\n if (key === Tab) {\n setOpen(event, { open: false, keyboard: true, type: 'menuPopoverKeyDown', event });\n }\n\n onKeyDownOriginal?.(event);\n });\n\n return {\n inline,\n mountNode,\n components: {\n root: 'div',\n },\n root: rootProps,\n };\n};\n"],"names":["React","ArrowLeft","Tab","ArrowRight","Escape","getNativeElementProps","useEventCallback","useMergedRefs","useMenuContext_unstable","dispatchMenuEnterEvent","useFluent_unstable","useFluent","useIsSubmenu","useMenuPopover_unstable","props","ref","popoverRef","context","menuPopoverRef","setOpen","open","openOnHover","isSubmenu","canDispatchCustomEventRef","useRef","throttleDispatchTimerRef","dir","CloseArrowKey","mouseOverListenerCallbackRef","useCallback","node","addEventListener","e","current","setTimeout","useEffect","clearTimeout","inline","mountNode","rootProps","role","onMouseEnter","onMouseEnterOriginal","onKeyDown","onKeyDownOriginal","event","keyboard","type","key","contains","target","stopPropagation","components","root"],"mappings":"AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,SAAS,EAAEC,GAAG,EAAEC,UAAU,EAAEC,MAAM,QAAQ,0BAA0B;AAC7E,SAASC,qBAAqB,EAAEC,gBAAgB,EAAEC,aAAa,QAAQ,4BAA4B;AAEnG,SAASC,uBAAuB,QAAQ,6BAA6B;AACrE,SAASC,sBAAsB,QAAQ,oBAAoB;AAC3D,SAASC,sBAAsBC,SAAS,QAAQ,kCAAkC;AAClF,SAASC,YAAY,QAAQ,2BAA2B;
|
1
|
+
{"version":3,"sources":["useMenuPopover.ts"],"sourcesContent":["import * as React from 'react';\nimport { ArrowLeft, Tab, ArrowRight, Escape } from '@fluentui/keyboard-keys';\nimport { getNativeElementProps, useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { MenuPopoverProps, MenuPopoverState } from './MenuPopover.types';\nimport { useMenuContext_unstable } from '../../contexts/menuContext';\nimport { dispatchMenuEnterEvent } from '../../utils/index';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport { useIsSubmenu } from '../../utils/useIsSubmenu';\nimport { useRestoreFocusSource } from '@fluentui/react-tabster';\n\n/**\n * Create the state required to render MenuPopover.\n *\n * The returned state can be modified with hooks such as useMenuPopoverStyles_unstable,\n * before being passed to renderMenuPopover_unstable.\n *\n * @param props - props from this instance of MenuPopover\n * @param ref - reference to root HTMLElement of MenuPopover\n */\nexport const useMenuPopover_unstable = (props: MenuPopoverProps, ref: React.Ref<HTMLElement>): MenuPopoverState => {\n const popoverRef = useMenuContext_unstable(context => context.menuPopoverRef);\n const setOpen = useMenuContext_unstable(context => context.setOpen);\n const open = useMenuContext_unstable(context => context.open);\n const openOnHover = useMenuContext_unstable(context => context.openOnHover);\n const triggerRef = useMenuContext_unstable(context => context.triggerRef);\n const isSubmenu = useIsSubmenu();\n const canDispatchCustomEventRef = React.useRef(true);\n const throttleDispatchTimerRef = React.useRef(0);\n const restoreFocusSourceAttributes = useRestoreFocusSource();\n\n const { dir } = useFluent();\n const CloseArrowKey = dir === 'ltr' ? ArrowLeft : ArrowRight;\n\n // use DOM listener since react events propagate up the react tree\n // no need to do `contains` logic as menus are all positioned in different portals\n const mouseOverListenerCallbackRef = React.useCallback(\n (node: HTMLElement) => {\n if (node) {\n // Dispatches the custom menu mouse enter event with throttling\n // Needs to trigger on mouseover to support keyboard + mouse together\n // i.e. keyboard opens submenus while cursor is still on the parent\n node.addEventListener('mouseover', e => {\n if (canDispatchCustomEventRef.current) {\n canDispatchCustomEventRef.current = false;\n dispatchMenuEnterEvent(popoverRef.current as HTMLElement, e);\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore #16889 Node setTimeout type leaking\n throttleDispatchTimerRef.current = setTimeout(() => (canDispatchCustomEventRef.current = true), 250);\n }\n });\n }\n },\n [popoverRef, throttleDispatchTimerRef],\n );\n\n React.useEffect(() => {\n () => clearTimeout(throttleDispatchTimerRef.current);\n }, []);\n\n const inline = useMenuContext_unstable(context => context.inline) ?? false;\n const mountNode = useMenuContext_unstable(context => context.mountNode);\n\n const rootProps = getNativeElementProps('div', {\n role: 'presentation',\n ...restoreFocusSourceAttributes,\n ...props,\n ref: useMergedRefs(ref, popoverRef, mouseOverListenerCallbackRef),\n });\n\n const { onMouseEnter: onMouseEnterOriginal, onKeyDown: onKeyDownOriginal } = rootProps;\n\n rootProps.onMouseEnter = useEventCallback((event: React.MouseEvent<HTMLElement>) => {\n if (openOnHover) {\n setOpen(event, { open: true, keyboard: false, type: 'menuPopoverMouseEnter', event });\n }\n\n onMouseEnterOriginal?.(event);\n });\n\n rootProps.onKeyDown = useEventCallback((event: React.KeyboardEvent<HTMLElement>) => {\n const key = event.key;\n\n if (key === Escape || (isSubmenu && key === CloseArrowKey)) {\n if (open && popoverRef.current?.contains(event.target as HTMLElement)) {\n setOpen(event, { open: false, keyboard: true, type: 'menuPopoverKeyDown', event });\n // stop propagation to avoid conflicting with other elements that listen for `Escape`\n // e,g: Dialog, Popover and Tooltip\n event.stopPropagation();\n }\n }\n\n if (key === Tab) {\n setOpen(event, { open: false, keyboard: true, type: 'menuPopoverKeyDown', event });\n if (!isSubmenu) {\n triggerRef.current?.focus();\n }\n }\n\n onKeyDownOriginal?.(event);\n });\n\n return {\n inline,\n mountNode,\n components: {\n root: 'div',\n },\n root: rootProps,\n };\n};\n"],"names":["React","ArrowLeft","Tab","ArrowRight","Escape","getNativeElementProps","useEventCallback","useMergedRefs","useMenuContext_unstable","dispatchMenuEnterEvent","useFluent_unstable","useFluent","useIsSubmenu","useRestoreFocusSource","useMenuPopover_unstable","props","ref","popoverRef","context","menuPopoverRef","setOpen","open","openOnHover","triggerRef","isSubmenu","canDispatchCustomEventRef","useRef","throttleDispatchTimerRef","restoreFocusSourceAttributes","dir","CloseArrowKey","mouseOverListenerCallbackRef","useCallback","node","addEventListener","e","current","setTimeout","useEffect","clearTimeout","inline","mountNode","rootProps","role","onMouseEnter","onMouseEnterOriginal","onKeyDown","onKeyDownOriginal","event","keyboard","type","key","contains","target","stopPropagation","focus","components","root"],"mappings":"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"}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import * as React from 'react';
|
2
|
-
import { useMenuTrigger_unstable } from './useMenuTrigger
|
2
|
+
import { useMenuTrigger_unstable } from './useMenuTrigger';
|
3
3
|
import { renderMenuTrigger_unstable } from './renderMenuTrigger';
|
4
4
|
/**
|
5
5
|
* Wraps a trigger element as an only child
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["MenuTrigger.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useMenuTrigger_unstable } from './useMenuTrigger
|
1
|
+
{"version":3,"sources":["MenuTrigger.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useMenuTrigger_unstable } from './useMenuTrigger';\nimport { renderMenuTrigger_unstable } from './renderMenuTrigger';\nimport type { MenuTriggerProps } from './MenuTrigger.types';\nimport type { FluentTriggerComponent } from '@fluentui/react-utilities';\n\n/**\n * Wraps a trigger element as an only child\n * and adds the necessary event handling to open a popup menu\n */\nexport const MenuTrigger: React.FC<MenuTriggerProps> = props => {\n const state = useMenuTrigger_unstable(props);\n\n return renderMenuTrigger_unstable(state);\n};\n\nMenuTrigger.displayName = 'MenuTrigger';\n// type casting here is required to ensure internal type FluentTriggerComponent is not leaked\n(MenuTrigger as FluentTriggerComponent).isFluentTriggerComponent = true;\n"],"names":["React","useMenuTrigger_unstable","renderMenuTrigger_unstable","MenuTrigger","props","state","displayName","isFluentTriggerComponent"],"mappings":"AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,uBAAuB,QAAQ,mBAAmB;AAC3D,SAASC,0BAA0B,QAAQ,sBAAsB;AAIjE;;;CAGC,GACD,OAAO,MAAMC,cAA0CC,CAAAA,QAAS;IAC9D,MAAMC,QAAQJ,wBAAwBG;IAEtC,OAAOF,2BAA2BG;AACpC,EAAE;AAEFF,YAAYG,WAAW,GAAG;AAC1B,6FAA6F;AAC5FH,YAAuCI,wBAAwB,GAAG,IAAI"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["index.ts"],"sourcesContent":["export * from './MenuTrigger';\nexport * from './MenuTrigger.types';\nexport * from './renderMenuTrigger';\nexport * from './useMenuTrigger
|
1
|
+
{"version":3,"sources":["index.ts"],"sourcesContent":["export * from './MenuTrigger';\nexport * from './MenuTrigger.types';\nexport * from './renderMenuTrigger';\nexport * from './useMenuTrigger';\n"],"names":[],"mappings":"AAAA,cAAc,gBAAgB;AAC9B,cAAc,sBAAsB;AACpC,cAAc,sBAAsB;AACpC,cAAc,mBAAmB"}
|