@fluentui/react-menu 9.7.6 → 9.7.8

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.json CHANGED
@@ -2,34 +2,97 @@
2
2
  "name": "@fluentui/react-menu",
3
3
  "entries": [
4
4
  {
5
- "date": "Thu, 23 Mar 2023 12:28:45 GMT",
6
- "tag": "@fluentui/react-menu_v9.7.6",
7
- "version": "9.7.6",
5
+ "date": "Wed, 12 Apr 2023 09:28:17 GMT",
6
+ "tag": "@fluentui/react-menu_v9.7.8",
7
+ "version": "9.7.8",
8
8
  "comments": {
9
9
  "patch": [
10
10
  {
11
11
  "author": "beachball",
12
12
  "package": "@fluentui/react-menu",
13
- "comment": "Bump @fluentui/react-portal to v9.2.3",
14
- "commit": "be0ca69899300abe3c8478c435e0f6837138479b"
13
+ "comment": "Bump @fluentui/react-aria to v9.3.17",
14
+ "commit": "b48890859f5ce28fe12fd40f6bda26ed486c5e47"
15
15
  },
16
16
  {
17
17
  "author": "beachball",
18
18
  "package": "@fluentui/react-menu",
19
- "comment": "Bump @fluentui/react-positioning to v9.5.7",
20
- "commit": "be0ca69899300abe3c8478c435e0f6837138479b"
19
+ "comment": "Bump @fluentui/react-context-selector to v9.1.17",
20
+ "commit": "b48890859f5ce28fe12fd40f6bda26ed486c5e47"
21
21
  },
22
22
  {
23
23
  "author": "beachball",
24
24
  "package": "@fluentui/react-menu",
25
- "comment": "Bump @fluentui/react-shared-contexts to v9.3.3",
26
- "commit": "be0ca69899300abe3c8478c435e0f6837138479b"
25
+ "comment": "Bump @fluentui/react-portal to v9.2.5",
26
+ "commit": "b48890859f5ce28fe12fd40f6bda26ed486c5e47"
27
27
  },
28
28
  {
29
29
  "author": "beachball",
30
30
  "package": "@fluentui/react-menu",
31
- "comment": "Bump @fluentui/react-tabster to v9.6.2",
32
- "commit": "be0ca69899300abe3c8478c435e0f6837138479b"
31
+ "comment": "Bump @fluentui/react-positioning to v9.5.9",
32
+ "commit": "b48890859f5ce28fe12fd40f6bda26ed486c5e47"
33
+ },
34
+ {
35
+ "author": "beachball",
36
+ "package": "@fluentui/react-menu",
37
+ "comment": "Bump @fluentui/react-tabster to v9.6.4",
38
+ "commit": "b48890859f5ce28fe12fd40f6bda26ed486c5e47"
39
+ },
40
+ {
41
+ "author": "beachball",
42
+ "package": "@fluentui/react-menu",
43
+ "comment": "Bump @fluentui/react-utilities to v9.7.4",
44
+ "commit": "b48890859f5ce28fe12fd40f6bda26ed486c5e47"
45
+ }
46
+ ]
47
+ }
48
+ },
49
+ {
50
+ "date": "Tue, 04 Apr 2023 18:44:49 GMT",
51
+ "tag": "@fluentui/react-menu_v9.7.7",
52
+ "version": "9.7.7",
53
+ "comments": {
54
+ "patch": [
55
+ {
56
+ "author": "lingfangao@hotmail.com",
57
+ "package": "@fluentui/react-menu",
58
+ "commit": "15a497fda9801df50990a42c9fe09d6b98b51144",
59
+ "comment": "fix: Menu should not steal focus on close"
60
+ },
61
+ {
62
+ "author": "beachball",
63
+ "package": "@fluentui/react-menu",
64
+ "comment": "Bump @fluentui/react-aria to v9.3.16",
65
+ "commit": "6778d76bbbad7e1975c151c797f28c2708cde2ce"
66
+ },
67
+ {
68
+ "author": "beachball",
69
+ "package": "@fluentui/react-menu",
70
+ "comment": "Bump @fluentui/react-context-selector to v9.1.16",
71
+ "commit": "6778d76bbbad7e1975c151c797f28c2708cde2ce"
72
+ },
73
+ {
74
+ "author": "beachball",
75
+ "package": "@fluentui/react-menu",
76
+ "comment": "Bump @fluentui/react-portal to v9.2.4",
77
+ "commit": "6778d76bbbad7e1975c151c797f28c2708cde2ce"
78
+ },
79
+ {
80
+ "author": "beachball",
81
+ "package": "@fluentui/react-menu",
82
+ "comment": "Bump @fluentui/react-positioning to v9.5.8",
83
+ "commit": "6778d76bbbad7e1975c151c797f28c2708cde2ce"
84
+ },
85
+ {
86
+ "author": "beachball",
87
+ "package": "@fluentui/react-menu",
88
+ "comment": "Bump @fluentui/react-tabster to v9.6.3",
89
+ "commit": "6778d76bbbad7e1975c151c797f28c2708cde2ce"
90
+ },
91
+ {
92
+ "author": "beachball",
93
+ "package": "@fluentui/react-menu",
94
+ "comment": "Bump @fluentui/react-utilities to v9.7.3",
95
+ "commit": "6778d76bbbad7e1975c151c797f28c2708cde2ce"
33
96
  }
34
97
  ]
35
98
  }
package/CHANGELOG.md CHANGED
@@ -1,20 +1,37 @@
1
1
  # Change Log - @fluentui/react-menu
2
2
 
3
- This log was last generated on Thu, 23 Mar 2023 12:28:45 GMT and should not be manually modified.
3
+ This log was last generated on Wed, 12 Apr 2023 09:28:17 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
- ## [9.7.6](https://github.com/microsoft/fluentui/tree/@fluentui/react-menu_v9.7.6)
7
+ ## [9.7.8](https://github.com/microsoft/fluentui/tree/@fluentui/react-menu_v9.7.8)
8
8
 
9
- Thu, 23 Mar 2023 12:28:45 GMT
10
- [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-menu_v9.7.5..@fluentui/react-menu_v9.7.6)
9
+ Wed, 12 Apr 2023 09:28:17 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-menu_v9.7.7..@fluentui/react-menu_v9.7.8)
11
11
 
12
12
  ### Patches
13
13
 
14
- - Bump @fluentui/react-portal to v9.2.3 ([PR #27286](https://github.com/microsoft/fluentui/pull/27286) by beachball)
15
- - Bump @fluentui/react-positioning to v9.5.7 ([PR #27286](https://github.com/microsoft/fluentui/pull/27286) by beachball)
16
- - Bump @fluentui/react-shared-contexts to v9.3.3 ([PR #27286](https://github.com/microsoft/fluentui/pull/27286) by beachball)
17
- - Bump @fluentui/react-tabster to v9.6.2 ([PR #27286](https://github.com/microsoft/fluentui/pull/27286) by beachball)
14
+ - Bump @fluentui/react-aria to v9.3.17 ([commit](https://github.com/microsoft/fluentui/commit/b48890859f5ce28fe12fd40f6bda26ed486c5e47) by beachball)
15
+ - Bump @fluentui/react-context-selector to v9.1.17 ([commit](https://github.com/microsoft/fluentui/commit/b48890859f5ce28fe12fd40f6bda26ed486c5e47) by beachball)
16
+ - Bump @fluentui/react-portal to v9.2.5 ([commit](https://github.com/microsoft/fluentui/commit/b48890859f5ce28fe12fd40f6bda26ed486c5e47) by beachball)
17
+ - Bump @fluentui/react-positioning to v9.5.9 ([commit](https://github.com/microsoft/fluentui/commit/b48890859f5ce28fe12fd40f6bda26ed486c5e47) by beachball)
18
+ - Bump @fluentui/react-tabster to v9.6.4 ([commit](https://github.com/microsoft/fluentui/commit/b48890859f5ce28fe12fd40f6bda26ed486c5e47) by beachball)
19
+ - Bump @fluentui/react-utilities to v9.7.4 ([commit](https://github.com/microsoft/fluentui/commit/b48890859f5ce28fe12fd40f6bda26ed486c5e47) by beachball)
20
+
21
+ ## [9.7.7](https://github.com/microsoft/fluentui/tree/@fluentui/react-menu_v9.7.7)
22
+
23
+ Tue, 04 Apr 2023 18:44:49 GMT
24
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-menu_v9.7.5..@fluentui/react-menu_v9.7.7)
25
+
26
+ ### Patches
27
+
28
+ - fix: Menu should not steal focus on close ([PR #27414](https://github.com/microsoft/fluentui/pull/27414) by lingfangao@hotmail.com)
29
+ - Bump @fluentui/react-aria to v9.3.16 ([PR #27434](https://github.com/microsoft/fluentui/pull/27434) by beachball)
30
+ - Bump @fluentui/react-context-selector to v9.1.16 ([PR #27434](https://github.com/microsoft/fluentui/pull/27434) by beachball)
31
+ - Bump @fluentui/react-portal to v9.2.4 ([PR #27434](https://github.com/microsoft/fluentui/pull/27434) by beachball)
32
+ - Bump @fluentui/react-positioning to v9.5.8 ([PR #27434](https://github.com/microsoft/fluentui/pull/27434) by beachball)
33
+ - Bump @fluentui/react-tabster to v9.6.3 ([PR #27434](https://github.com/microsoft/fluentui/pull/27434) by beachball)
34
+ - Bump @fluentui/react-utilities to v9.7.3 ([PR #27434](https://github.com/microsoft/fluentui/pull/27434) by beachball)
18
35
 
19
36
  ## [9.7.5](https://github.com/microsoft/fluentui/tree/@fluentui/react-menu_v9.7.5)
20
37
 
@@ -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 } from '@fluentui/react-utilities';
3
+ import { useControllableState, useId, useOnClickOutside, useEventCallback, useOnScrollOutside, useFirstMount } 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';
@@ -142,7 +142,6 @@ const useMenuOpenState = state => {
142
142
  var _state_onOpenChange;
143
143
  return (_state_onOpenChange = state.onOpenChange) === null || _state_onOpenChange === void 0 ? void 0 : _state_onOpenChange.call(state, e, data);
144
144
  });
145
- const shouldHandleCloseRef = React.useRef(false);
146
145
  const setOpenTimeout = React.useRef(0);
147
146
  const enteringTriggerRef = React.useRef(false);
148
147
  const [open, setOpenState] = useControllableState({
@@ -160,7 +159,6 @@ const useMenuOpenState = state => {
160
159
  }
161
160
  if (!data.open) {
162
161
  state.setContextTarget(undefined);
163
- shouldHandleCloseRef.current = true;
164
162
  }
165
163
  if (data.bubble) {
166
164
  parentSetOpen(e, {
@@ -243,24 +241,26 @@ const useMenuOpenState = state => {
243
241
  const firstFocusable = findFirstFocusable(state.menuPopoverRef.current);
244
242
  firstFocusable === null || firstFocusable === void 0 ? void 0 : firstFocusable.focus();
245
243
  }, [findFirstFocusable, state.menuPopoverRef]);
244
+ const firstMount = useFirstMount();
246
245
  React.useEffect(() => {
247
246
  if (open) {
248
247
  focusFirst();
249
248
  } else {
250
- if (shouldHandleCloseRef.current) {
251
- var
252
- // We know that React effects are sync so we focus the trigger here
253
- // after any event handler (event handlers will update state and re-render).
254
- // Since the browser only performs the default behaviour for the Tab key once
255
- // keyboard events have fully bubbled up the window, the browser will move
256
- // focus to the next tabbable element before/after the trigger if needed.
257
- // If the Tab key was not pressed, focus will remain on the trigger as expected.
258
- _state_triggerRef_current;
259
- (_state_triggerRef_current = state.triggerRef.current) === null || _state_triggerRef_current === void 0 ? void 0 : _state_triggerRef_current.focus();
249
+ if (!firstMount) {
250
+ if ((targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.activeElement) === (targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.body)) {
251
+ var
252
+ // We know that React effects are sync so we focus the trigger here
253
+ // after any event handler (event handlers will update state and re-render).
254
+ // Since the browser only performs the default behaviour for the Tab key once
255
+ // keyboard events have fully bubbled up the window, the browser will move
256
+ // focus to the next tabbable element before/after the trigger if needed.
257
+ // If the Tab key was not pressed, focus will remain on the trigger as expected.
258
+ _state_triggerRef_current;
259
+ (_state_triggerRef_current = state.triggerRef.current) === null || _state_triggerRef_current === void 0 ? void 0 : _state_triggerRef_current.focus();
260
+ }
260
261
  }
261
262
  }
262
- shouldHandleCloseRef.current = false;
263
- }, [state.triggerRef, state.isSubmenu, open, focusFirst]);
263
+ }, [state.triggerRef, state.isSubmenu, open, focusFirst, firstMount, targetDocument, state.menuPopoverRef]);
264
264
  return [open, setOpen];
265
265
  };
266
266
  //# sourceMappingURL=useMenu.js.map
@@ -1 +1 @@
1
- {"version":3,"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","_props_onCheckedValueChange","call","currentValue","targetDocument","parentSetOpen","context","data","_state_onOpenChange","shouldHandleCloseRef","useRef","setOpenTimeout","enteringTriggerRef","setOpenState","trySetOpen","event","CustomEvent","type","detail","nativeEvent","current","bubble","clearTimeout","Event","persist","_state_triggerRef_current","contains","setTimeout","disabled","element","refs","filter","Boolean","callback","useEffect","findFirstFocusable","focusFirst","useCallback","firstFocusable","focus"],"sources":["../../../src/components/Menu/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 shouldHandleCloseRef = React.useRef(false);\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 shouldHandleCloseRef.current = true;\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 } else {\n if (shouldHandleCloseRef.current) {\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 shouldHandleCloseRef.current = false;\n }, [state.triggerRef, state.isSubmenu, open, focusFirst]);\n\n return [open, setOpen] as const;\n};\n"],"mappings":"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"}
1
+ {"version":3,"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","_props_onCheckedValueChange","call","currentValue","targetDocument","parentSetOpen","context","data","_state_onOpenChange","setOpenTimeout","useRef","enteringTriggerRef","setOpenState","trySetOpen","event","CustomEvent","type","detail","nativeEvent","bubble","clearTimeout","current","Event","persist","_state_triggerRef_current","contains","setTimeout","disabled","element","refs","filter","Boolean","callback","useEffect","findFirstFocusable","focusFirst","useCallback","firstFocusable","focus","firstMount","activeElement","body"],"sources":["../../../src/components/Menu/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 }, [state.triggerRef, state.isSubmenu, open, focusFirst, firstMount, targetDocument, state.menuPopoverRef]);\n\n return [open, setOpen] as const;\n};\n"],"mappings":"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"}
@@ -133,7 +133,6 @@ const useMenuOpenState = (state)=>{
133
133
  var _state_onOpenChange;
134
134
  return (_state_onOpenChange = state.onOpenChange) === null || _state_onOpenChange === void 0 ? void 0 : _state_onOpenChange.call(state, e, data);
135
135
  });
136
- const shouldHandleCloseRef = _react.useRef(false);
137
136
  const setOpenTimeout = _react.useRef(0);
138
137
  const enteringTriggerRef = _react.useRef(false);
139
138
  const [open, setOpenState] = (0, _reactUtilities.useControllableState)({
@@ -151,7 +150,6 @@ const useMenuOpenState = (state)=>{
151
150
  }
152
151
  if (!data.open) {
153
152
  state.setContextTarget(undefined);
154
- shouldHandleCloseRef.current = true;
155
153
  }
156
154
  if (data.bubble) {
157
155
  parentSetOpen(e, {
@@ -243,27 +241,32 @@ const useMenuOpenState = (state)=>{
243
241
  findFirstFocusable,
244
242
  state.menuPopoverRef
245
243
  ]);
244
+ const firstMount = (0, _reactUtilities.useFirstMount)();
246
245
  _react.useEffect(()=>{
247
246
  if (open) {
248
247
  focusFirst();
249
248
  } else {
250
- if (shouldHandleCloseRef.current) {
251
- var // We know that React effects are sync so we focus the trigger here
252
- // after any event handler (event handlers will update state and re-render).
253
- // Since the browser only performs the default behaviour for the Tab key once
254
- // keyboard events have fully bubbled up the window, the browser will move
255
- // focus to the next tabbable element before/after the trigger if needed.
256
- // If the Tab key was not pressed, focus will remain on the trigger as expected.
257
- _state_triggerRef_current;
258
- (_state_triggerRef_current = state.triggerRef.current) === null || _state_triggerRef_current === void 0 ? void 0 : _state_triggerRef_current.focus();
249
+ if (!firstMount) {
250
+ if ((targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.activeElement) === (targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.body)) {
251
+ var // We know that React effects are sync so we focus the trigger here
252
+ // after any event handler (event handlers will update state and re-render).
253
+ // Since the browser only performs the default behaviour for the Tab key once
254
+ // keyboard events have fully bubbled up the window, the browser will move
255
+ // focus to the next tabbable element before/after the trigger if needed.
256
+ // If the Tab key was not pressed, focus will remain on the trigger as expected.
257
+ _state_triggerRef_current;
258
+ (_state_triggerRef_current = state.triggerRef.current) === null || _state_triggerRef_current === void 0 ? void 0 : _state_triggerRef_current.focus();
259
+ }
259
260
  }
260
261
  }
261
- shouldHandleCloseRef.current = false;
262
262
  }, [
263
263
  state.triggerRef,
264
264
  state.isSubmenu,
265
265
  open,
266
- focusFirst
266
+ focusFirst,
267
+ firstMount,
268
+ targetDocument,
269
+ state.menuPopoverRef
267
270
  ]);
268
271
  return [
269
272
  open,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../lib/components/Menu/useMenu.js"],"sourcesContent":["import * as React from 'react';\nimport { usePositioningMouseTarget, usePositioning, resolvePositioningShorthand } from '@fluentui/react-positioning';\nimport { useControllableState, useId, useOnClickOutside, useEventCallback, useOnScrollOutside } 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';\n// If it's not possible to position the submenu in smaller viewports, try\n// and fallback to this order of positions\nconst submenuFallbackPositions = ['after', 'after-bottom', 'before-top', 'before', 'before-bottom', 'above'];\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 => {\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 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 };\n const children = React.Children.toArray(props.children);\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 if (children.length > 2) {\n // eslint-disable-next-line no-console\n console.warn('Menu must contain at most two children');\n }\n }\n let menuTrigger = undefined;\n let menuPopover = 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 const {\n targetRef: triggerRef,\n containerRef: menuPopoverRef\n } = usePositioning(positioningState);\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 const [checkedValues, onCheckedValueChange] = useMenuSelectableState({\n checkedValues: props.checkedValues,\n defaultCheckedValues,\n onCheckedValueChange: props.onCheckedValueChange\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 * Adds appropriate state values and handlers for selectable items\n * i.e checkboxes and radios\n */\nconst useMenuSelectableState = props => {\n const [checkedValues, setCheckedValues] = useControllableState({\n state: props.checkedValues,\n defaultState: props.defaultCheckedValues,\n initialState: {}\n });\n const onCheckedValueChange = useEventCallback((e, {\n name,\n checkedItems\n }) => {\n var _props_onCheckedValueChange;\n (_props_onCheckedValueChange = props.onCheckedValueChange) === null || _props_onCheckedValueChange === void 0 ? void 0 : _props_onCheckedValueChange.call(props, e, {\n name,\n checkedItems\n });\n setCheckedValues(currentValue => ({\n ...currentValue,\n [name]: checkedItems\n }));\n });\n return [checkedValues, onCheckedValueChange];\n};\nconst useMenuOpenState = state => {\n const {\n targetDocument\n } = useFluent();\n const parentSetOpen = useMenuContext_unstable(context => context.setOpen);\n const onOpenChange = useEventCallback((e, data) => {\n var _state_onOpenChange;\n return (_state_onOpenChange = state.onOpenChange) === null || _state_onOpenChange === void 0 ? void 0 : _state_onOpenChange.call(state, e, data);\n });\n const shouldHandleCloseRef = React.useRef(false);\n const setOpenTimeout = React.useRef(0);\n const enteringTriggerRef = React.useRef(false);\n const [open, setOpenState] = useControllableState({\n state: state.open,\n defaultState: state.defaultOpen,\n initialState: false\n });\n const trySetOpen = useEventCallback((e, data) => {\n const event = e instanceof CustomEvent && e.type === MENU_ENTER_EVENT ? e.detail.nativeEvent : e;\n onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(event, {\n ...data\n });\n if (data.open && e.type === 'contextmenu') {\n state.setContextTarget(e);\n }\n if (!data.open) {\n state.setContextTarget(undefined);\n shouldHandleCloseRef.current = true;\n }\n if (data.bubble) {\n parentSetOpen(e, {\n ...data\n });\n }\n setOpenState(data.open);\n });\n const setOpen = useEventCallback((e, data) => {\n clearTimeout(setOpenTimeout.current);\n if (!(e instanceof Event) && e.persist) {\n // < React 17 still uses pooled synthetic events\n e.persist();\n }\n if (e.type === 'mouseleave' || e.type === 'mouseenter' || e.type === 'mousemove' || e.type === MENU_ENTER_EVENT) {\n var _state_triggerRef_current;\n if ((_state_triggerRef_current = state.triggerRef.current) === null || _state_triggerRef_current === void 0 ? void 0 : _state_triggerRef_current.contains(e.target)) {\n enteringTriggerRef.current = e.type === 'mouseenter' || e.type === 'mousemove';\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 useOnClickOutside({\n contains: elementContains,\n disabled: !open,\n element: targetDocument,\n refs: [state.menuPopoverRef, !state.openOnContext && state.triggerRef].filter(Boolean),\n callback: event => setOpen(event, {\n open: false,\n type: 'clickOutside',\n 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, {\n open: false,\n type: 'scrollOutside',\n event\n }),\n refs: [state.menuPopoverRef, !state.openOnContext && state.triggerRef].filter(Boolean),\n disabled: !open || !closeOnScroll\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, {\n open: false,\n type: 'menuMouseEnter',\n event\n });\n }\n },\n disabled: !open,\n refs: [state.menuPopoverRef]\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 // Manage focus for open state\n const {\n findFirstFocusable\n } = useFocusFinders();\n const focusFirst = React.useCallback(() => {\n const firstFocusable = findFirstFocusable(state.menuPopoverRef.current);\n firstFocusable === null || firstFocusable === void 0 ? void 0 : firstFocusable.focus();\n }, [findFirstFocusable, state.menuPopoverRef]);\n React.useEffect(() => {\n if (open) {\n focusFirst();\n } else {\n if (shouldHandleCloseRef.current) {\n var\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;\n (_state_triggerRef_current = state.triggerRef.current) === null || _state_triggerRef_current === void 0 ? void 0 : _state_triggerRef_current.focus();\n }\n }\n shouldHandleCloseRef.current = false;\n }, [state.triggerRef, state.isSubmenu, open, focusFirst]);\n return [open, setOpen];\n};\n//# sourceMappingURL=useMenu.js.map"],"names":["useMenu_unstable","submenuFallbackPositions","props","isSubmenu","useIsSubmenu","hoverDelay","inline","hasCheckmarks","hasIcons","closeOnScroll","openOnContext","persistOnItemClick","openOnHover","defaultCheckedValues","mountNode","triggerId","useId","contextTarget","setContextTarget","usePositioningMouseTarget","positioningState","position","align","target","undefined","fallbackPositions","resolvePositioningShorthand","positioning","children","React","Children","toArray","process","env","NODE_ENV","length","console","warn","menuTrigger","menuPopover","targetRef","triggerRef","containerRef","menuPopoverRef","usePositioning","open","setOpen","useMenuOpenState","defaultOpen","onOpenChange","checkedValues","onCheckedValueChange","useMenuSelectableState","components","setCheckedValues","useControllableState","state","defaultState","initialState","useEventCallback","e","name","checkedItems","_props_onCheckedValueChange","call","currentValue","targetDocument","useFluent","parentSetOpen","useMenuContext_unstable","context","data","_state_onOpenChange","shouldHandleCloseRef","useRef","setOpenTimeout","enteringTriggerRef","setOpenState","trySetOpen","event","CustomEvent","type","MENU_ENTER_EVENT","detail","nativeEvent","current","bubble","clearTimeout","Event","persist","_state_triggerRef_current","contains","setTimeout","useOnClickOutside","elementContains","disabled","element","refs","filter","Boolean","callback","useOnScrollOutside","useOnMenuMouseEnter","useEffect","findFirstFocusable","useFocusFinders","focusFirst","useCallback","firstFocusable","focus"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../lib/components/Menu/useMenu.js"],"sourcesContent":["import * as React from 'react';\nimport { usePositioningMouseTarget, usePositioning, resolvePositioningShorthand } from '@fluentui/react-positioning';\nimport { useControllableState, useId, useOnClickOutside, useEventCallback, useOnScrollOutside, useFirstMount } 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';\n// If it's not possible to position the submenu in smaller viewports, try\n// and fallback to this order of positions\nconst submenuFallbackPositions = ['after', 'after-bottom', 'before-top', 'before', 'before-bottom', 'above'];\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 => {\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 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 };\n const children = React.Children.toArray(props.children);\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 if (children.length > 2) {\n // eslint-disable-next-line no-console\n console.warn('Menu must contain at most two children');\n }\n }\n let menuTrigger = undefined;\n let menuPopover = 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 const {\n targetRef: triggerRef,\n containerRef: menuPopoverRef\n } = usePositioning(positioningState);\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 const [checkedValues, onCheckedValueChange] = useMenuSelectableState({\n checkedValues: props.checkedValues,\n defaultCheckedValues,\n onCheckedValueChange: props.onCheckedValueChange\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 * Adds appropriate state values and handlers for selectable items\n * i.e checkboxes and radios\n */\nconst useMenuSelectableState = props => {\n const [checkedValues, setCheckedValues] = useControllableState({\n state: props.checkedValues,\n defaultState: props.defaultCheckedValues,\n initialState: {}\n });\n const onCheckedValueChange = useEventCallback((e, {\n name,\n checkedItems\n }) => {\n var _props_onCheckedValueChange;\n (_props_onCheckedValueChange = props.onCheckedValueChange) === null || _props_onCheckedValueChange === void 0 ? void 0 : _props_onCheckedValueChange.call(props, e, {\n name,\n checkedItems\n });\n setCheckedValues(currentValue => ({\n ...currentValue,\n [name]: checkedItems\n }));\n });\n return [checkedValues, onCheckedValueChange];\n};\nconst useMenuOpenState = state => {\n const {\n targetDocument\n } = useFluent();\n const parentSetOpen = useMenuContext_unstable(context => context.setOpen);\n const onOpenChange = useEventCallback((e, data) => {\n var _state_onOpenChange;\n return (_state_onOpenChange = state.onOpenChange) === null || _state_onOpenChange === void 0 ? void 0 : _state_onOpenChange.call(state, e, data);\n });\n const setOpenTimeout = React.useRef(0);\n const enteringTriggerRef = React.useRef(false);\n const [open, setOpenState] = useControllableState({\n state: state.open,\n defaultState: state.defaultOpen,\n initialState: false\n });\n const trySetOpen = useEventCallback((e, data) => {\n const event = e instanceof CustomEvent && e.type === MENU_ENTER_EVENT ? e.detail.nativeEvent : e;\n onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(event, {\n ...data\n });\n if (data.open && e.type === 'contextmenu') {\n state.setContextTarget(e);\n }\n if (!data.open) {\n state.setContextTarget(undefined);\n }\n if (data.bubble) {\n parentSetOpen(e, {\n ...data\n });\n }\n setOpenState(data.open);\n });\n const setOpen = useEventCallback((e, data) => {\n clearTimeout(setOpenTimeout.current);\n if (!(e instanceof Event) && e.persist) {\n // < React 17 still uses pooled synthetic events\n e.persist();\n }\n if (e.type === 'mouseleave' || e.type === 'mouseenter' || e.type === 'mousemove' || e.type === MENU_ENTER_EVENT) {\n var _state_triggerRef_current;\n if ((_state_triggerRef_current = state.triggerRef.current) === null || _state_triggerRef_current === void 0 ? void 0 : _state_triggerRef_current.contains(e.target)) {\n enteringTriggerRef.current = e.type === 'mouseenter' || e.type === 'mousemove';\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 useOnClickOutside({\n contains: elementContains,\n disabled: !open,\n element: targetDocument,\n refs: [state.menuPopoverRef, !state.openOnContext && state.triggerRef].filter(Boolean),\n callback: event => setOpen(event, {\n open: false,\n type: 'clickOutside',\n 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, {\n open: false,\n type: 'scrollOutside',\n event\n }),\n refs: [state.menuPopoverRef, !state.openOnContext && state.triggerRef].filter(Boolean),\n disabled: !open || !closeOnScroll\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, {\n open: false,\n type: 'menuMouseEnter',\n event\n });\n }\n },\n disabled: !open,\n refs: [state.menuPopoverRef]\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 // Manage focus for open state\n const {\n findFirstFocusable\n } = useFocusFinders();\n const focusFirst = React.useCallback(() => {\n const firstFocusable = findFirstFocusable(state.menuPopoverRef.current);\n firstFocusable === null || firstFocusable === void 0 ? void 0 : firstFocusable.focus();\n }, [findFirstFocusable, state.menuPopoverRef]);\n const firstMount = useFirstMount();\n React.useEffect(() => {\n if (open) {\n focusFirst();\n } else {\n if (!firstMount) {\n if ((targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.activeElement) === (targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.body)) {\n var\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;\n (_state_triggerRef_current = state.triggerRef.current) === null || _state_triggerRef_current === void 0 ? void 0 : _state_triggerRef_current.focus();\n }\n }\n }\n }, [state.triggerRef, state.isSubmenu, open, focusFirst, firstMount, targetDocument, state.menuPopoverRef]);\n return [open, setOpen];\n};\n//# sourceMappingURL=useMenu.js.map"],"names":["useMenu_unstable","submenuFallbackPositions","props","isSubmenu","useIsSubmenu","hoverDelay","inline","hasCheckmarks","hasIcons","closeOnScroll","openOnContext","persistOnItemClick","openOnHover","defaultCheckedValues","mountNode","triggerId","useId","contextTarget","setContextTarget","usePositioningMouseTarget","positioningState","position","align","target","undefined","fallbackPositions","resolvePositioningShorthand","positioning","children","React","Children","toArray","process","env","NODE_ENV","length","console","warn","menuTrigger","menuPopover","targetRef","triggerRef","containerRef","menuPopoverRef","usePositioning","open","setOpen","useMenuOpenState","defaultOpen","onOpenChange","checkedValues","onCheckedValueChange","useMenuSelectableState","components","setCheckedValues","useControllableState","state","defaultState","initialState","useEventCallback","e","name","checkedItems","_props_onCheckedValueChange","call","currentValue","targetDocument","useFluent","parentSetOpen","useMenuContext_unstable","context","data","_state_onOpenChange","setOpenTimeout","useRef","enteringTriggerRef","setOpenState","trySetOpen","event","CustomEvent","type","MENU_ENTER_EVENT","detail","nativeEvent","bubble","clearTimeout","current","Event","persist","_state_triggerRef_current","contains","setTimeout","useOnClickOutside","elementContains","disabled","element","refs","filter","Boolean","callback","useOnScrollOutside","useOnMenuMouseEnter","useEffect","findFirstFocusable","useFocusFinders","focusFirst","useCallback","firstFocusable","focus","firstMount","useFirstMount","activeElement","body"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui/react-menu",
3
- "version": "9.7.6",
3
+ "version": "9.7.8",
4
4
  "description": "Fluent UI menu component",
5
5
  "main": "lib-commonjs/index.js",
6
6
  "module": "lib/index.js",
@@ -36,15 +36,15 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@fluentui/keyboard-keys": "^9.0.2",
39
- "@fluentui/react-aria": "^9.3.15",
40
- "@fluentui/react-context-selector": "^9.1.15",
39
+ "@fluentui/react-aria": "^9.3.17",
40
+ "@fluentui/react-context-selector": "^9.1.17",
41
41
  "@fluentui/react-icons": "^2.0.196",
42
- "@fluentui/react-portal": "^9.2.3",
43
- "@fluentui/react-positioning": "^9.5.7",
42
+ "@fluentui/react-portal": "^9.2.5",
43
+ "@fluentui/react-positioning": "^9.5.9",
44
44
  "@fluentui/react-shared-contexts": "^9.3.3",
45
- "@fluentui/react-tabster": "^9.6.2",
45
+ "@fluentui/react-tabster": "^9.6.4",
46
46
  "@fluentui/react-theme": "^9.1.7",
47
- "@fluentui/react-utilities": "^9.7.2",
47
+ "@fluentui/react-utilities": "^9.7.4",
48
48
  "@griffel/react": "^1.5.2",
49
49
  "@swc/helpers": "^0.4.14"
50
50
  },