@fluentui/react-menu 9.3.0 → 9.4.0

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.json CHANGED
@@ -2,7 +2,188 @@
2
2
  "name": "@fluentui/react-menu",
3
3
  "entries": [
4
4
  {
5
- "date": "Thu, 13 Oct 2022 12:55:52 GMT",
5
+ "date": "Wed, 02 Nov 2022 11:54:55 GMT",
6
+ "tag": "@fluentui/react-menu_v9.4.0",
7
+ "version": "9.4.0",
8
+ "comments": {
9
+ "patch": [
10
+ {
11
+ "author": "olfedias@microsoft.com",
12
+ "package": "@fluentui/react-menu",
13
+ "commit": "c619ba066f11a8654e95375314824ba6b81b003e",
14
+ "comment": "chore: Update Griffel to latest version"
15
+ }
16
+ ],
17
+ "none": [
18
+ {
19
+ "author": "bernardo.sunderhus@gmail.com",
20
+ "package": "@fluentui/react-menu",
21
+ "commit": "f3bef94c75214f94749e760a4ab270e3b5a9b8d4",
22
+ "comment": "chore: adds disableButtonEnhancement on triggers"
23
+ }
24
+ ],
25
+ "minor": [
26
+ {
27
+ "author": "bernardo.sunderhus@gmail.com",
28
+ "package": "@fluentui/react-menu",
29
+ "commit": "1700a730052f17fa38992292a1dff9ece73e528e",
30
+ "comment": "removes exposing of internal type FluentTriggerComponent"
31
+ },
32
+ {
33
+ "author": "beachball",
34
+ "package": "@fluentui/react-menu",
35
+ "comment": "Bump @fluentui/react-aria to v9.3.0",
36
+ "commit": "393a7b169155997a97a6ce1ad36ee3eafc6f461b"
37
+ },
38
+ {
39
+ "author": "beachball",
40
+ "package": "@fluentui/react-menu",
41
+ "comment": "Bump @fluentui/react-context-selector to v9.1.0",
42
+ "commit": "393a7b169155997a97a6ce1ad36ee3eafc6f461b"
43
+ },
44
+ {
45
+ "author": "beachball",
46
+ "package": "@fluentui/react-menu",
47
+ "comment": "Bump @fluentui/react-portal to v9.0.9",
48
+ "commit": "393a7b169155997a97a6ce1ad36ee3eafc6f461b"
49
+ },
50
+ {
51
+ "author": "beachball",
52
+ "package": "@fluentui/react-menu",
53
+ "comment": "Bump @fluentui/react-positioning to v9.3.0",
54
+ "commit": "393a7b169155997a97a6ce1ad36ee3eafc6f461b"
55
+ },
56
+ {
57
+ "author": "beachball",
58
+ "package": "@fluentui/react-menu",
59
+ "comment": "Bump @fluentui/react-shared-contexts to v9.1.0",
60
+ "commit": "393a7b169155997a97a6ce1ad36ee3eafc6f461b"
61
+ },
62
+ {
63
+ "author": "beachball",
64
+ "package": "@fluentui/react-menu",
65
+ "comment": "Bump @fluentui/react-tabster to v9.2.1",
66
+ "commit": "393a7b169155997a97a6ce1ad36ee3eafc6f461b"
67
+ },
68
+ {
69
+ "author": "beachball",
70
+ "package": "@fluentui/react-menu",
71
+ "comment": "Bump @fluentui/react-utilities to v9.2.0",
72
+ "commit": "393a7b169155997a97a6ce1ad36ee3eafc6f461b"
73
+ },
74
+ {
75
+ "author": "beachball",
76
+ "package": "@fluentui/react-menu",
77
+ "comment": "Bump @fluentui/react-conformance-griffel to v9.0.0-beta.17",
78
+ "commit": "393a7b169155997a97a6ce1ad36ee3eafc6f461b"
79
+ }
80
+ ]
81
+ }
82
+ },
83
+ {
84
+ "date": "Tue, 25 Oct 2022 00:35:33 GMT",
85
+ "tag": "@fluentui/react-menu_v9.3.1",
86
+ "version": "9.3.1",
87
+ "comments": {
88
+ "none": [
89
+ {
90
+ "author": "miroslav.stastny@microsoft.com",
91
+ "package": "@fluentui/react-menu",
92
+ "commit": "6ced976a8d0e6a0e2e207da8fe0eb810e2bd19bc",
93
+ "comment": "Update package readme"
94
+ }
95
+ ]
96
+ }
97
+ },
98
+ {
99
+ "date": "Thu, 20 Oct 2022 08:39:37 GMT",
100
+ "tag": "@fluentui/react-menu_v9.3.1",
101
+ "version": "9.3.1",
102
+ "comments": {
103
+ "patch": [
104
+ {
105
+ "author": "lingfangao@hotmail.com",
106
+ "package": "@fluentui/react-menu",
107
+ "commit": "099d9f0f3d9e033ebb3bb450f31cf3e5765ec8f0",
108
+ "comment": "fix: Menu trigger should be focused when dismissed by menuitem click"
109
+ },
110
+ {
111
+ "author": "mgodbolt@microsoft.com",
112
+ "package": "@fluentui/react-menu",
113
+ "commit": "17096b3137d9d3e7c7443ddc3ce0738b2910a334",
114
+ "comment": "chore: Bump peer deps to support React 18"
115
+ },
116
+ {
117
+ "author": "tristan.watanabe@gmail.com",
118
+ "package": "@fluentui/react-menu",
119
+ "commit": "61915ced2a350da17f8d1a1c520070796dc90d46",
120
+ "comment": "chore: Migrate to new package structure"
121
+ },
122
+ {
123
+ "author": "olfedias@microsoft.com",
124
+ "package": "@fluentui/react-menu",
125
+ "commit": "06865dada128321804646582f564ee86d835d174",
126
+ "comment": "chore: Update Griffel to latest version"
127
+ },
128
+ {
129
+ "author": "beachball",
130
+ "package": "@fluentui/react-menu",
131
+ "comment": "Bump @fluentui/react-aria to v9.2.3",
132
+ "commit": "5ea1372675d910d76cf1b9cbd74d05b7c4e8fcbc"
133
+ },
134
+ {
135
+ "author": "beachball",
136
+ "package": "@fluentui/react-menu",
137
+ "comment": "Bump @fluentui/react-context-selector to v9.0.5",
138
+ "commit": "5ea1372675d910d76cf1b9cbd74d05b7c4e8fcbc"
139
+ },
140
+ {
141
+ "author": "beachball",
142
+ "package": "@fluentui/react-menu",
143
+ "comment": "Bump @fluentui/react-portal to v9.0.8",
144
+ "commit": "5ea1372675d910d76cf1b9cbd74d05b7c4e8fcbc"
145
+ },
146
+ {
147
+ "author": "beachball",
148
+ "package": "@fluentui/react-menu",
149
+ "comment": "Bump @fluentui/react-positioning to v9.2.2",
150
+ "commit": "5ea1372675d910d76cf1b9cbd74d05b7c4e8fcbc"
151
+ },
152
+ {
153
+ "author": "beachball",
154
+ "package": "@fluentui/react-menu",
155
+ "comment": "Bump @fluentui/react-shared-contexts to v9.0.2",
156
+ "commit": "5ea1372675d910d76cf1b9cbd74d05b7c4e8fcbc"
157
+ },
158
+ {
159
+ "author": "beachball",
160
+ "package": "@fluentui/react-menu",
161
+ "comment": "Bump @fluentui/react-tabster to v9.2.0",
162
+ "commit": "5ea1372675d910d76cf1b9cbd74d05b7c4e8fcbc"
163
+ },
164
+ {
165
+ "author": "beachball",
166
+ "package": "@fluentui/react-menu",
167
+ "comment": "Bump @fluentui/react-theme to v9.1.1",
168
+ "commit": "5ea1372675d910d76cf1b9cbd74d05b7c4e8fcbc"
169
+ },
170
+ {
171
+ "author": "beachball",
172
+ "package": "@fluentui/react-menu",
173
+ "comment": "Bump @fluentui/react-utilities to v9.1.2",
174
+ "commit": "5ea1372675d910d76cf1b9cbd74d05b7c4e8fcbc"
175
+ },
176
+ {
177
+ "author": "beachball",
178
+ "package": "@fluentui/react-menu",
179
+ "comment": "Bump @fluentui/react-conformance-griffel to v9.0.0-beta.16",
180
+ "commit": "5ea1372675d910d76cf1b9cbd74d05b7c4e8fcbc"
181
+ }
182
+ ]
183
+ }
184
+ },
185
+ {
186
+ "date": "Thu, 13 Oct 2022 12:56:30 GMT",
6
187
  "tag": "@fluentui/react-menu_v9.3.0",
7
188
  "version": "9.3.0",
8
189
  "comments": {
package/CHANGELOG.md CHANGED
@@ -1,12 +1,54 @@
1
1
  # Change Log - @fluentui/react-menu
2
2
 
3
- This log was last generated on Thu, 13 Oct 2022 12:55:52 GMT and should not be manually modified.
3
+ This log was last generated on Wed, 02 Nov 2022 11:54:55 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.4.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-menu_v9.4.0)
8
+
9
+ Wed, 02 Nov 2022 11:54:55 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-menu_v9.3.1..@fluentui/react-menu_v9.4.0)
11
+
12
+ ### Minor changes
13
+
14
+ - removes exposing of internal type FluentTriggerComponent ([PR #25410](https://github.com/microsoft/fluentui/pull/25410) by bernardo.sunderhus@gmail.com)
15
+ - Bump @fluentui/react-aria to v9.3.0 ([PR #25456](https://github.com/microsoft/fluentui/pull/25456) by beachball)
16
+ - Bump @fluentui/react-context-selector to v9.1.0 ([PR #25456](https://github.com/microsoft/fluentui/pull/25456) by beachball)
17
+ - Bump @fluentui/react-portal to v9.0.9 ([PR #25456](https://github.com/microsoft/fluentui/pull/25456) by beachball)
18
+ - Bump @fluentui/react-positioning to v9.3.0 ([PR #25456](https://github.com/microsoft/fluentui/pull/25456) by beachball)
19
+ - Bump @fluentui/react-shared-contexts to v9.1.0 ([PR #25456](https://github.com/microsoft/fluentui/pull/25456) by beachball)
20
+ - Bump @fluentui/react-tabster to v9.2.1 ([PR #25456](https://github.com/microsoft/fluentui/pull/25456) by beachball)
21
+ - Bump @fluentui/react-utilities to v9.2.0 ([PR #25456](https://github.com/microsoft/fluentui/pull/25456) by beachball)
22
+ - Bump @fluentui/react-conformance-griffel to v9.0.0-beta.17 ([PR #25456](https://github.com/microsoft/fluentui/pull/25456) by beachball)
23
+
24
+ ### Patches
25
+
26
+ - chore: Update Griffel to latest version ([PR #25412](https://github.com/microsoft/fluentui/pull/25412) by olfedias@microsoft.com)
27
+
28
+ ## [9.3.1](https://github.com/microsoft/fluentui/tree/@fluentui/react-menu_v9.3.1)
29
+
30
+ Thu, 20 Oct 2022 08:39:37 GMT
31
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-menu_v9.3.0..@fluentui/react-menu_v9.3.1)
32
+
33
+ ### Patches
34
+
35
+ - fix: Menu trigger should be focused when dismissed by menuitem click ([PR #25289](https://github.com/microsoft/fluentui/pull/25289) by lingfangao@hotmail.com)
36
+ - chore: Bump peer deps to support React 18 ([PR #24972](https://github.com/microsoft/fluentui/pull/24972) by mgodbolt@microsoft.com)
37
+ - chore: Migrate to new package structure ([PR #25015](https://github.com/microsoft/fluentui/pull/25015) by tristan.watanabe@gmail.com)
38
+ - chore: Update Griffel to latest version ([PR #25212](https://github.com/microsoft/fluentui/pull/25212) by olfedias@microsoft.com)
39
+ - Bump @fluentui/react-aria to v9.2.3 ([PR #25265](https://github.com/microsoft/fluentui/pull/25265) by beachball)
40
+ - Bump @fluentui/react-context-selector to v9.0.5 ([PR #25265](https://github.com/microsoft/fluentui/pull/25265) by beachball)
41
+ - Bump @fluentui/react-portal to v9.0.8 ([PR #25265](https://github.com/microsoft/fluentui/pull/25265) by beachball)
42
+ - Bump @fluentui/react-positioning to v9.2.2 ([PR #25265](https://github.com/microsoft/fluentui/pull/25265) by beachball)
43
+ - Bump @fluentui/react-shared-contexts to v9.0.2 ([PR #25265](https://github.com/microsoft/fluentui/pull/25265) by beachball)
44
+ - Bump @fluentui/react-tabster to v9.2.0 ([PR #25265](https://github.com/microsoft/fluentui/pull/25265) by beachball)
45
+ - Bump @fluentui/react-theme to v9.1.1 ([PR #25265](https://github.com/microsoft/fluentui/pull/25265) by beachball)
46
+ - Bump @fluentui/react-utilities to v9.1.2 ([PR #25265](https://github.com/microsoft/fluentui/pull/25265) by beachball)
47
+ - Bump @fluentui/react-conformance-griffel to v9.0.0-beta.16 ([PR #25265](https://github.com/microsoft/fluentui/pull/25265) by beachball)
48
+
7
49
  ## [9.3.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-menu_v9.3.0)
8
50
 
9
- Thu, 13 Oct 2022 12:55:52 GMT
51
+ Thu, 13 Oct 2022 12:56:30 GMT
10
52
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-menu_v9.2.3..@fluentui/react-menu_v9.3.0)
11
53
 
12
54
  ### Minor changes
package/README.md CHANGED
@@ -1,5 +1,3 @@
1
1
  # @fluentui/react-menu
2
2
 
3
- **React Menu components for [Fluent UI React](https://developer.microsoft.com/en-us/fluentui)**
4
-
5
- These are not production-ready components and **should never be used in product**. This space is useful for testing new components whose APIs might change before final release.
3
+ **React Menu components for [Fluent UI React](https://react.fluentui.dev)**
package/dist/index.d.ts CHANGED
@@ -7,14 +7,14 @@ import { ARIAButtonType } from '@fluentui/react-aria';
7
7
  import type { ComponentProps } from '@fluentui/react-utilities';
8
8
  import type { ComponentState } from '@fluentui/react-utilities';
9
9
  import type { ContextSelector } from '@fluentui/react-context-selector';
10
- import type { FluentTriggerComponent } from '@fluentui/react-utilities';
11
10
  import type { ForwardRefComponent } from '@fluentui/react-utilities';
12
11
  import type { PositioningShorthand } from '@fluentui/react-positioning';
12
+ import { PositioningVirtualElement } from '@fluentui/react-positioning';
13
13
  import * as React_2 from 'react';
14
+ import { SetVirtualMouseTarget } from '@fluentui/react-positioning';
14
15
  import type { Slot } from '@fluentui/react-utilities';
15
16
  import type { SlotClassNames } from '@fluentui/react-utilities';
16
17
  import type { TriggerProps } from '@fluentui/react-utilities';
17
- import { usePositioningMouseTarget } from '@fluentui/react-positioning';
18
18
 
19
19
  /**
20
20
  * Wrapper component that manages state for a popup MenuList and a MenuTrigger
@@ -420,7 +420,7 @@ export declare type MenuState = ComponentState<MenuSlots> & Pick<MenuProps, 'onO
420
420
  /**
421
421
  * Anchors the popper to the mouse click for context events
422
422
  */
423
- contextTarget: ReturnType<typeof usePositioningMouseTarget>[0];
423
+ contextTarget?: PositioningVirtualElement;
424
424
  /**
425
425
  * Whether this menu is a submenu
426
426
  */
@@ -440,7 +440,7 @@ export declare type MenuState = ComponentState<MenuSlots> & Pick<MenuProps, 'onO
440
440
  /**
441
441
  * A callback to set the target of the popper to the mouse click for context events
442
442
  */
443
- setContextTarget: ReturnType<typeof usePositioningMouseTarget>[1];
443
+ setContextTarget: SetVirtualMouseTarget;
444
444
  /**
445
445
  * Callback to open/close the popup
446
446
  */
@@ -459,7 +459,7 @@ export declare type MenuState = ComponentState<MenuSlots> & Pick<MenuProps, 'onO
459
459
  * Wraps a trigger element as an only child
460
460
  * and adds the necessary event handling to open a popup menu
461
461
  */
462
- export declare const MenuTrigger: React_2.FC<MenuTriggerProps> & FluentTriggerComponent;
462
+ export declare const MenuTrigger: React_2.FC<MenuTriggerProps>;
463
463
 
464
464
  /**
465
465
  * Props that are passed to the child of the MenuTrigger when cloned to ensure correct behaviour for the Menu
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.types.js","sourceRoot":"../src/","sources":["packages/react-components/react-menu/src/components/Menu/Menu.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { usePositioningMouseTarget } from '@fluentui/react-positioning';\nimport type { PositioningShorthand } from '@fluentui/react-positioning';\nimport type { ComponentProps, ComponentState } from '@fluentui/react-utilities';\nimport type { MenuContextValue } from '../../contexts/menuContext';\nimport type { MenuListProps } from '../MenuList/MenuList.types';\n\nexport type MenuSlots = {};\n\n/**\n * Extends and drills down Menulist props to simplify API\n */\nexport type MenuProps = ComponentProps<MenuSlots> &\n Pick<\n MenuListProps,\n 'checkedValues' | 'defaultCheckedValues' | 'hasCheckmarks' | 'hasIcons' | 'onCheckedValueChange'\n > & {\n /**\n * Can contain two children including {@link MenuTrigger} and {@link MenuPopover}.\n * Alternatively can only contain {@link MenuPopover} if using a custom `target`.\n */\n children: [JSX.Element, JSX.Element] | JSX.Element;\n\n /**\n * Whether the popup is open by default\n *\n * @default false\n */\n defaultOpen?: boolean;\n\n /**\n * Sets the delay for mouse open/close for the popover one mouse enter/leave\n */\n hoverDelay?: number;\n\n /**\n * Root menus are rendered out of DOM order on `document.body`, use this to render the menu in DOM order\n * This option is disregarded for submenus\n *\n * @default false\n */\n inline?: boolean;\n\n /**\n * Call back when the component requests to change value\n * The `open` value is used as a hint when directly controlling the component\n */\n onOpenChange?: (e: MenuOpenEvents, data: MenuOpenChangeData) => void;\n\n /**\n * Whether the popup is open\n *\n * @default false\n */\n open?: boolean;\n\n /**\n * Opens the menu on right click (context menu), removes all other menu open interactions\n *\n * @default false\n */\n openOnContext?: boolean;\n\n /**\n * Opens the menu on hover\n *\n * @default false\n */\n openOnHover?: boolean;\n\n /**\n * Do not dismiss the menu when a menu item is clicked\n *\n * @default false\n */\n persistOnItemClick?: boolean;\n\n /**\n * Configures the positioned menu\n */\n positioning?: PositioningShorthand;\n\n /**\n * Close when scroll outside of it\n *\n * @default false\n */\n closeOnScroll?: boolean;\n };\n\nexport type MenuState = ComponentState<MenuSlots> &\n Pick<MenuProps, 'onOpenChange' | 'defaultCheckedValues'> &\n Required<\n Pick<\n MenuProps,\n | 'hasCheckmarks'\n | 'hasIcons'\n | 'inline'\n | 'checkedValues'\n | 'onCheckedValueChange'\n | 'open'\n | 'openOnHover'\n | 'closeOnScroll'\n | 'hoverDelay'\n | 'openOnContext'\n | 'persistOnItemClick'\n >\n > & {\n /**\n * Anchors the popper to the mouse click for context events\n */\n contextTarget: ReturnType<typeof usePositioningMouseTarget>[0];\n\n /**\n * Whether this menu is a submenu\n */\n isSubmenu: boolean;\n\n /**\n * Internal react node that just simplifies handling children\n */\n menuPopover: React.ReactNode;\n\n /**\n * The ref for the popup\n */\n menuPopoverRef: React.MutableRefObject<HTMLElement>;\n\n /**\n * Internal react node that just simplifies handling children\n */\n menuTrigger: React.ReactNode;\n\n /**\n * A callback to set the target of the popper to the mouse click for context events\n */\n setContextTarget: ReturnType<typeof usePositioningMouseTarget>[1];\n\n /**\n * Callback to open/close the popup\n */\n setOpen: (e: MenuOpenEvents, data: MenuOpenChangeData) => void;\n\n /**\n * Id for the MenuTrigger element for aria relationship\n */\n triggerId: string;\n\n /**\n * The ref for the MenuTrigger, used for popup positioning\n */\n triggerRef: React.MutableRefObject<HTMLElement>;\n };\n\n/**\n * Data attached to open/close events\n */\nexport type MenuOpenChangeData = {\n /**\n * indicates whether the request for the open state was bubbled from a nested menu\n */\n bubble?: boolean;\n /**\n * Indicates whether the change of state was a keyboard interaction\n * @deprecated\n * This should not be used, since `Enter`, `Space` and click should be interpreted as the same thing as a click\n */\n keyboard?: boolean;\n open: boolean;\n};\n\nexport type MenuContextValues = {\n menu: MenuContextValue;\n};\n\n/**\n * The supported events that will trigger open/close of the menu\n */\nexport type MenuOpenEvents =\n | MouseEvent\n | TouchEvent\n | React.FocusEvent<HTMLElement>\n | React.KeyboardEvent<HTMLElement>\n | React.MouseEvent<HTMLElement>;\n"]}
1
+ {"version":3,"file":"Menu.types.js","sourceRoot":"../src/","sources":["packages/react-components/react-menu/src/components/Menu/Menu.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { PositioningVirtualElement, SetVirtualMouseTarget } from '@fluentui/react-positioning';\nimport type { PositioningShorthand } from '@fluentui/react-positioning';\nimport type { ComponentProps, ComponentState } from '@fluentui/react-utilities';\nimport type { MenuContextValue } from '../../contexts/menuContext';\nimport type { MenuListProps } from '../MenuList/MenuList.types';\n\nexport type MenuSlots = {};\n\n/**\n * Extends and drills down Menulist props to simplify API\n */\nexport type MenuProps = ComponentProps<MenuSlots> &\n Pick<\n MenuListProps,\n 'checkedValues' | 'defaultCheckedValues' | 'hasCheckmarks' | 'hasIcons' | 'onCheckedValueChange'\n > & {\n /**\n * Can contain two children including {@link MenuTrigger} and {@link MenuPopover}.\n * Alternatively can only contain {@link MenuPopover} if using a custom `target`.\n */\n children: [JSX.Element, JSX.Element] | JSX.Element;\n\n /**\n * Whether the popup is open by default\n *\n * @default false\n */\n defaultOpen?: boolean;\n\n /**\n * Sets the delay for mouse open/close for the popover one mouse enter/leave\n */\n hoverDelay?: number;\n\n /**\n * Root menus are rendered out of DOM order on `document.body`, use this to render the menu in DOM order\n * This option is disregarded for submenus\n *\n * @default false\n */\n inline?: boolean;\n\n /**\n * Call back when the component requests to change value\n * The `open` value is used as a hint when directly controlling the component\n */\n onOpenChange?: (e: MenuOpenEvents, data: MenuOpenChangeData) => void;\n\n /**\n * Whether the popup is open\n *\n * @default false\n */\n open?: boolean;\n\n /**\n * Opens the menu on right click (context menu), removes all other menu open interactions\n *\n * @default false\n */\n openOnContext?: boolean;\n\n /**\n * Opens the menu on hover\n *\n * @default false\n */\n openOnHover?: boolean;\n\n /**\n * Do not dismiss the menu when a menu item is clicked\n *\n * @default false\n */\n persistOnItemClick?: boolean;\n\n /**\n * Configures the positioned menu\n */\n positioning?: PositioningShorthand;\n\n /**\n * Close when scroll outside of it\n *\n * @default false\n */\n closeOnScroll?: boolean;\n };\n\nexport type MenuState = ComponentState<MenuSlots> &\n Pick<MenuProps, 'onOpenChange' | 'defaultCheckedValues'> &\n Required<\n Pick<\n MenuProps,\n | 'hasCheckmarks'\n | 'hasIcons'\n | 'inline'\n | 'checkedValues'\n | 'onCheckedValueChange'\n | 'open'\n | 'openOnHover'\n | 'closeOnScroll'\n | 'hoverDelay'\n | 'openOnContext'\n | 'persistOnItemClick'\n >\n > & {\n /**\n * Anchors the popper to the mouse click for context events\n */\n contextTarget?: PositioningVirtualElement;\n\n /**\n * Whether this menu is a submenu\n */\n isSubmenu: boolean;\n\n /**\n * Internal react node that just simplifies handling children\n */\n menuPopover: React.ReactNode;\n\n /**\n * The ref for the popup\n */\n menuPopoverRef: React.MutableRefObject<HTMLElement>;\n\n /**\n * Internal react node that just simplifies handling children\n */\n menuTrigger: React.ReactNode;\n\n /**\n * A callback to set the target of the popper to the mouse click for context events\n */\n setContextTarget: SetVirtualMouseTarget;\n\n /**\n * Callback to open/close the popup\n */\n setOpen: (e: MenuOpenEvents, data: MenuOpenChangeData) => void;\n\n /**\n * Id for the MenuTrigger element for aria relationship\n */\n triggerId: string;\n\n /**\n * The ref for the MenuTrigger, used for popup positioning\n */\n triggerRef: React.MutableRefObject<HTMLElement>;\n };\n\n/**\n * Data attached to open/close events\n */\nexport type MenuOpenChangeData = {\n /**\n * indicates whether the request for the open state was bubbled from a nested menu\n */\n bubble?: boolean;\n /**\n * Indicates whether the change of state was a keyboard interaction\n * @deprecated\n * This should not be used, since `Enter`, `Space` and click should be interpreted as the same thing as a click\n */\n keyboard?: boolean;\n open: boolean;\n};\n\nexport type MenuContextValues = {\n menu: MenuContextValue;\n};\n\n/**\n * The supported events that will trigger open/close of the menu\n */\nexport type MenuOpenEvents =\n | MouseEvent\n | TouchEvent\n | React.FocusEvent<HTMLElement>\n | React.KeyboardEvent<HTMLElement>\n | React.MouseEvent<HTMLElement>;\n"]}
@@ -155,7 +155,7 @@ const useMenuOpenState = state => {
155
155
 
156
156
  return (_a = state.onOpenChange) === null || _a === void 0 ? void 0 : _a.call(state, e, data);
157
157
  });
158
- const shouldHandleKeyboardRef = React.useRef(false);
158
+ const shouldHandleCloseRef = React.useRef(false);
159
159
  const shouldHandleTabRef = React.useRef(false);
160
160
  const pressedShiftRef = React.useRef(false);
161
161
  const setOpenTimeout = React.useRef(0);
@@ -176,11 +176,10 @@ const useMenuOpenState = state => {
176
176
 
177
177
  if (!data.open) {
178
178
  state.setContextTarget(undefined);
179
+ shouldHandleCloseRef.current = true;
179
180
  }
180
181
 
181
182
  if (e.type === 'keydown') {
182
- shouldHandleKeyboardRef.current = true;
183
-
184
183
  if (e.key === Tab) {
185
184
  shouldHandleTabRef.current = true;
186
185
  pressedShiftRef.current = e.shiftKey;
@@ -276,30 +275,25 @@ const useMenuOpenState = state => {
276
275
  const prevFocusable = findPrevFocusable(state.triggerRef.current);
277
276
  prevFocusable === null || prevFocusable === void 0 ? void 0 : prevFocusable.focus();
278
277
  }, [findPrevFocusable, state.triggerRef]);
279
- React.useEffect(() => {
280
- if (open) {
281
- focusFirst();
282
- }
283
- }, [open, focusFirst]);
284
278
  React.useEffect(() => {
285
279
  var _a;
286
280
 
287
281
  if (open) {
288
282
  focusFirst();
289
- }
290
-
291
- if (shouldHandleKeyboardRef.current && !open) {
292
- if (shouldHandleTabRef.current && !state.isSubmenu) {
293
- pressedShiftRef.current ? focusBeforeMenuTrigger() : focusAfterMenuTrigger();
294
- } else {
295
- (_a = state.triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
283
+ } else {
284
+ if (shouldHandleCloseRef.current) {
285
+ if (shouldHandleTabRef.current && !state.isSubmenu) {
286
+ pressedShiftRef.current ? focusBeforeMenuTrigger() : focusAfterMenuTrigger();
287
+ } else {
288
+ (_a = state.triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
289
+ }
296
290
  }
297
291
  }
298
292
 
299
- shouldHandleKeyboardRef.current = false;
293
+ shouldHandleCloseRef.current = false;
300
294
  shouldHandleTabRef.current = false;
301
295
  pressedShiftRef.current = false;
302
296
  }, [state.triggerRef, state.isSubmenu, open, focusFirst, focusAfterMenuTrigger, focusBeforeMenuTrigger]);
303
- return [open !== null && open !== void 0 ? open : false, setOpen];
297
+ return [open, setOpen];
304
298
  };
305
299
  //# sourceMappingURL=useMenu.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["packages/react-components/react-menu/src/components/Menu/useMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { usePositioningMouseTarget, usePositioning, resolvePositioningShorthand } 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, MenuOpenEvents, MenuProps, MenuState } from './Menu.types';\nimport { Tab } from '@fluentui/keyboard-keys';\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 } = props;\n const triggerId = useId('menu');\n const [contextTarget, setContextTarget] = usePositioningMouseTarget();\n\n const positioningState = {\n position: isSubmenu ? ('after' as const) : ('below' as const),\n align: isSubmenu ? ('top' as const) : ('start' as const),\n target: props.openOnContext ? contextTarget : undefined,\n ...resolvePositioningShorthand(props.positioning),\n };\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 const { targetRef: triggerRef, containerRef: menuPopoverRef } = usePositioning(positioningState);\n\n // TODO Better way to narrow types ?\n\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 triggerRef,\n menuPopoverRef,\n components: {},\n openOnContext,\n open,\n setOpen,\n checkedValues,\n defaultCheckedValues,\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 state: Pick<MenuProps, 'checkedValues' | 'defaultCheckedValues' | 'onCheckedValueChange'>,\n) => {\n const [checkedValues, setCheckedValues] = useControllableState({\n state: state.checkedValues,\n defaultState: state.defaultCheckedValues,\n initialState: {},\n });\n const { onCheckedValueChange: onCheckedValueChangeOriginal } = state;\n const onCheckedValueChange: MenuState['onCheckedValueChange'] = useEventCallback((e, { name, checkedItems }) => {\n if (onCheckedValueChangeOriginal) {\n onCheckedValueChangeOriginal(e, { name, checkedItems });\n }\n\n setCheckedValues(s => {\n return s ? { ...s, [name]: checkedItems } : { [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 | 'onOpenChange'\n | 'setContextTarget'\n | 'triggerRef'\n | 'openOnContext'\n | 'closeOnScroll'\n | 'hoverDelay'\n > &\n Pick<MenuProps, 'open' | 'defaultOpen'>,\n) => {\n const { targetDocument } = useFluent();\n const parentSetOpen = useMenuContext_unstable(context => context.setOpen);\n const onOpenChange: MenuState['onOpenChange'] = useEventCallback((e, data) => state.onOpenChange?.(e, data));\n\n const shouldHandleKeyboardRef = React.useRef(false);\n const shouldHandleTabRef = React.useRef(false);\n const pressedShiftRef = 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: MenuOpenEvents, 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 (e.type === 'keydown') {\n shouldHandleKeyboardRef.current = true;\n if ((e as React.KeyboardEvent<HTMLElement>).key === Tab) {\n shouldHandleTabRef.current = true;\n pressedShiftRef.current = (e as React.KeyboardEvent<HTMLElement>).shiftKey;\n }\n }\n\n if (data.bubble) {\n parentSetOpen(e, { ...data });\n }\n\n setOpenState(data.open);\n });\n\n const setOpen = useEventCallback((e: MenuOpenEvents, 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: e => setOpen(e, { open: false }),\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: ev => setOpen(ev, { open: false }),\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: e => {\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(e, { open: false });\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, findNextFocusable, findPrevFocusable } = useFocusFinders();\n const focusFirst = React.useCallback(() => {\n const firstFocusable = findFirstFocusable(state.menuPopoverRef.current);\n firstFocusable?.focus();\n }, [findFirstFocusable, state.menuPopoverRef]);\n\n const focusAfterMenuTrigger = React.useCallback(() => {\n const nextFocusable = findNextFocusable(state.triggerRef.current);\n nextFocusable?.focus();\n }, [findNextFocusable, state.triggerRef]);\n\n const focusBeforeMenuTrigger = React.useCallback(() => {\n const prevFocusable = findPrevFocusable(state.triggerRef.current);\n prevFocusable?.focus();\n }, [findPrevFocusable, state.triggerRef]);\n\n React.useEffect(() => {\n if (open) {\n focusFirst();\n }\n }, [open, focusFirst]);\n\n React.useEffect(() => {\n if (open) {\n focusFirst();\n }\n\n if (shouldHandleKeyboardRef.current && !open) {\n if (shouldHandleTabRef.current && !state.isSubmenu) {\n pressedShiftRef.current ? focusBeforeMenuTrigger() : focusAfterMenuTrigger();\n } else {\n state.triggerRef.current?.focus();\n }\n }\n\n shouldHandleKeyboardRef.current = false;\n shouldHandleTabRef.current = false;\n pressedShiftRef.current = false;\n }, [state.triggerRef, state.isSubmenu, open, focusFirst, focusAfterMenuTrigger, focusBeforeMenuTrigger]);\n\n return [open ?? false, setOpen] as const;\n};\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["packages/react-components/react-menu/src/components/Menu/useMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { usePositioningMouseTarget, usePositioning, resolvePositioningShorthand } 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, MenuOpenEvents, MenuProps, MenuState } from './Menu.types';\nimport { Tab } from '@fluentui/keyboard-keys';\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 } = props;\n const triggerId = useId('menu');\n const [contextTarget, setContextTarget] = usePositioningMouseTarget();\n\n const positioningState = {\n position: isSubmenu ? ('after' as const) : ('below' as const),\n align: isSubmenu ? ('top' as const) : ('start' as const),\n target: props.openOnContext ? contextTarget : undefined,\n ...resolvePositioningShorthand(props.positioning),\n };\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 const { targetRef: triggerRef, containerRef: menuPopoverRef } = usePositioning(positioningState);\n\n // TODO Better way to narrow types ?\n\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 triggerRef,\n menuPopoverRef,\n components: {},\n openOnContext,\n open,\n setOpen,\n checkedValues,\n defaultCheckedValues,\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 state: Pick<MenuProps, 'checkedValues' | 'defaultCheckedValues' | 'onCheckedValueChange'>,\n) => {\n const [checkedValues, setCheckedValues] = useControllableState({\n state: state.checkedValues,\n defaultState: state.defaultCheckedValues,\n initialState: {},\n });\n const { onCheckedValueChange: onCheckedValueChangeOriginal } = state;\n const onCheckedValueChange: MenuState['onCheckedValueChange'] = useEventCallback((e, { name, checkedItems }) => {\n if (onCheckedValueChangeOriginal) {\n onCheckedValueChangeOriginal(e, { name, checkedItems });\n }\n\n setCheckedValues(s => {\n return s ? { ...s, [name]: checkedItems } : { [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 | 'onOpenChange'\n | 'setContextTarget'\n | 'triggerRef'\n | 'openOnContext'\n | 'closeOnScroll'\n | 'hoverDelay'\n > &\n Pick<MenuProps, 'open' | 'defaultOpen'>,\n) => {\n const { targetDocument } = useFluent();\n const parentSetOpen = useMenuContext_unstable(context => context.setOpen);\n const onOpenChange: MenuState['onOpenChange'] = useEventCallback((e, data) => state.onOpenChange?.(e, data));\n\n const shouldHandleCloseRef = React.useRef(false);\n const shouldHandleTabRef = React.useRef(false);\n const pressedShiftRef = 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: MenuOpenEvents, 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 (e.type === 'keydown') {\n if ((e as React.KeyboardEvent<HTMLElement>).key === Tab) {\n shouldHandleTabRef.current = true;\n pressedShiftRef.current = (e as React.KeyboardEvent<HTMLElement>).shiftKey;\n }\n }\n\n if (data.bubble) {\n parentSetOpen(e, { ...data });\n }\n\n setOpenState(data.open);\n });\n\n const setOpen = useEventCallback((e: MenuOpenEvents, 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: e => setOpen(e, { open: false }),\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: ev => setOpen(ev, { open: false }),\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: e => {\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(e, { open: false });\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, findNextFocusable, findPrevFocusable } = useFocusFinders();\n const focusFirst = React.useCallback(() => {\n const firstFocusable = findFirstFocusable(state.menuPopoverRef.current);\n firstFocusable?.focus();\n }, [findFirstFocusable, state.menuPopoverRef]);\n\n const focusAfterMenuTrigger = React.useCallback(() => {\n const nextFocusable = findNextFocusable(state.triggerRef.current);\n nextFocusable?.focus();\n }, [findNextFocusable, state.triggerRef]);\n\n const focusBeforeMenuTrigger = React.useCallback(() => {\n const prevFocusable = findPrevFocusable(state.triggerRef.current);\n prevFocusable?.focus();\n }, [findPrevFocusable, state.triggerRef]);\n\n React.useEffect(() => {\n if (open) {\n focusFirst();\n } else {\n if (shouldHandleCloseRef.current) {\n if (shouldHandleTabRef.current && !state.isSubmenu) {\n pressedShiftRef.current ? focusBeforeMenuTrigger() : focusAfterMenuTrigger();\n } else {\n state.triggerRef.current?.focus();\n }\n }\n }\n\n shouldHandleCloseRef.current = false;\n shouldHandleTabRef.current = false;\n pressedShiftRef.current = false;\n }, [state.triggerRef, state.isSubmenu, open, focusFirst, focusAfterMenuTrigger, focusBeforeMenuTrigger]);\n\n return [open, setOpen] as const;\n};\n"],"sourceRoot":"../src/"}
@@ -9,6 +9,7 @@ export const MenuTrigger = props => {
9
9
  const state = useMenuTrigger_unstable(props);
10
10
  return renderMenuTrigger_unstable(state);
11
11
  };
12
- MenuTrigger.displayName = 'MenuTrigger';
12
+ MenuTrigger.displayName = 'MenuTrigger'; // type casting here is required to ensure internal type FluentTriggerComponent is not leaked
13
+
13
14
  MenuTrigger.isFluentTriggerComponent = true;
14
15
  //# sourceMappingURL=MenuTrigger.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["packages/react-components/react-menu/src/components/MenuTrigger/MenuTrigger.tsx"],"names":[],"mappings":"AACA,SAAS,uBAAT,QAAwC,kBAAxC;AACA,SAAS,0BAAT,QAA2C,qBAA3C;AAIA;;;AAGG;;AACH,OAAO,MAAM,WAAW,GAAwD,KAAK,IAAG;EACtF,MAAM,KAAK,GAAG,uBAAuB,CAAC,KAAD,CAArC;EAEA,OAAO,0BAA0B,CAAC,KAAD,CAAjC;AACD,CAJM;AAMP,WAAW,CAAC,WAAZ,GAA0B,aAA1B;AACA,WAAW,CAAC,wBAAZ,GAAuC,IAAvC","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> & FluentTriggerComponent = props => {\n const state = useMenuTrigger_unstable(props);\n\n return renderMenuTrigger_unstable(state);\n};\n\nMenuTrigger.displayName = 'MenuTrigger';\nMenuTrigger.isFluentTriggerComponent = true;\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["packages/react-components/react-menu/src/components/MenuTrigger/MenuTrigger.tsx"],"names":[],"mappings":"AACA,SAAS,uBAAT,QAAwC,kBAAxC;AACA,SAAS,0BAAT,QAA2C,qBAA3C;AAIA;;;AAGG;;AACH,OAAO,MAAM,WAAW,GAA+B,KAAK,IAAG;EAC7D,MAAM,KAAK,GAAG,uBAAuB,CAAC,KAAD,CAArC;EAEA,OAAO,0BAA0B,CAAC,KAAD,CAAjC;AACD,CAJM;AAMP,WAAW,CAAC,WAAZ,GAA0B,aAA1B,C,CACA;;AACC,WAAsC,CAAC,wBAAvC,GAAkE,IAAlE","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"],"sourceRoot":"../src/"}
@@ -174,7 +174,7 @@ const useMenuOpenState = state => {
174
174
 
175
175
  return (_a = state.onOpenChange) === null || _a === void 0 ? void 0 : _a.call(state, e, data);
176
176
  });
177
- const shouldHandleKeyboardRef = React.useRef(false);
177
+ const shouldHandleCloseRef = React.useRef(false);
178
178
  const shouldHandleTabRef = React.useRef(false);
179
179
  const pressedShiftRef = React.useRef(false);
180
180
  const setOpenTimeout = React.useRef(0);
@@ -195,11 +195,10 @@ const useMenuOpenState = state => {
195
195
 
196
196
  if (!data.open) {
197
197
  state.setContextTarget(undefined);
198
+ shouldHandleCloseRef.current = true;
198
199
  }
199
200
 
200
201
  if (e.type === 'keydown') {
201
- shouldHandleKeyboardRef.current = true;
202
-
203
202
  if (e.key === keyboard_keys_1.Tab) {
204
203
  shouldHandleTabRef.current = true;
205
204
  pressedShiftRef.current = e.shiftKey;
@@ -295,30 +294,25 @@ const useMenuOpenState = state => {
295
294
  const prevFocusable = findPrevFocusable(state.triggerRef.current);
296
295
  prevFocusable === null || prevFocusable === void 0 ? void 0 : prevFocusable.focus();
297
296
  }, [findPrevFocusable, state.triggerRef]);
298
- React.useEffect(() => {
299
- if (open) {
300
- focusFirst();
301
- }
302
- }, [open, focusFirst]);
303
297
  React.useEffect(() => {
304
298
  var _a;
305
299
 
306
300
  if (open) {
307
301
  focusFirst();
308
- }
309
-
310
- if (shouldHandleKeyboardRef.current && !open) {
311
- if (shouldHandleTabRef.current && !state.isSubmenu) {
312
- pressedShiftRef.current ? focusBeforeMenuTrigger() : focusAfterMenuTrigger();
313
- } else {
314
- (_a = state.triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
302
+ } else {
303
+ if (shouldHandleCloseRef.current) {
304
+ if (shouldHandleTabRef.current && !state.isSubmenu) {
305
+ pressedShiftRef.current ? focusBeforeMenuTrigger() : focusAfterMenuTrigger();
306
+ } else {
307
+ (_a = state.triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
308
+ }
315
309
  }
316
310
  }
317
311
 
318
- shouldHandleKeyboardRef.current = false;
312
+ shouldHandleCloseRef.current = false;
319
313
  shouldHandleTabRef.current = false;
320
314
  pressedShiftRef.current = false;
321
315
  }, [state.triggerRef, state.isSubmenu, open, focusFirst, focusAfterMenuTrigger, focusBeforeMenuTrigger]);
322
- return [open !== null && open !== void 0 ? open : false, setOpen];
316
+ return [open, setOpen];
323
317
  };
324
318
  //# sourceMappingURL=useMenu.js.map