@react-aria/menu 3.19.3 → 3.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  module.exports = {
2
- "longPressMessage": `Premere a lungo o premere Alt + Freccia gi\xf9 per aprire il menu`
2
+ "longPressMessage": `Premi a lungo o premi Alt + Freccia gi\xf9 per aprire il menu`
3
3
  };
4
4
 
5
5
 
@@ -1 +1 @@
1
- {"mappings":"AAAA,iBAAiB;IAAG,oBAAoB,CAAC,iEAA8D,CAAC;AACxG","sources":["packages/@react-aria/menu/intl/it-IT.json"],"sourcesContent":["{\n \"longPressMessage\": \"Premere a lungo o premere Alt + Freccia giù per aprire il menu\"\n}\n"],"names":[],"version":3,"file":"it-IT.main.js.map"}
1
+ {"mappings":"AAAA,iBAAiB;IAAG,oBAAoB,CAAC,6DAA0D,CAAC;AACpG","sources":["packages/@react-aria/menu/intl/it-IT.json"],"sourcesContent":["{\n \"longPressMessage\": \"Premi a lungo o premi Alt + Freccia giù per aprire il menu\"\n}\n"],"names":[],"version":3,"file":"it-IT.main.js.map"}
package/dist/it-IT.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  var $edc7c66594a0ae8a$exports = {};
2
2
  $edc7c66594a0ae8a$exports = {
3
- "longPressMessage": `Premere a lungo o premere Alt + Freccia gi\xf9 per aprire il menu`
3
+ "longPressMessage": `Premi a lungo o premi Alt + Freccia gi\xf9 per aprire il menu`
4
4
  };
5
5
 
6
6
 
@@ -1,6 +1,6 @@
1
1
  var $edc7c66594a0ae8a$exports = {};
2
2
  $edc7c66594a0ae8a$exports = {
3
- "longPressMessage": `Premere a lungo o premere Alt + Freccia gi\xf9 per aprire il menu`
3
+ "longPressMessage": `Premi a lungo o premi Alt + Freccia gi\xf9 per aprire il menu`
4
4
  };
5
5
 
6
6
 
@@ -1 +1 @@
1
- {"mappings":";AAAA,4BAAiB;IAAG,oBAAoB,CAAC,iEAA8D,CAAC;AACxG","sources":["packages/@react-aria/menu/intl/it-IT.json"],"sourcesContent":["{\n \"longPressMessage\": \"Premere a lungo o premere Alt + Freccia giù per aprire il menu\"\n}\n"],"names":[],"version":3,"file":"it-IT.module.js.map"}
1
+ {"mappings":";AAAA,4BAAiB;IAAG,oBAAoB,CAAC,6DAA0D,CAAC;AACpG","sources":["packages/@react-aria/menu/intl/it-IT.json"],"sourcesContent":["{\n \"longPressMessage\": \"Premi a lungo o premi Alt + Freccia giù per aprire il menu\"\n}\n"],"names":[],"version":3,"file":"it-IT.module.js.map"}
package/dist/types.d.ts CHANGED
@@ -93,9 +93,11 @@ export interface AriaMenuItemProps extends DOMProps, PressEvents, HoverEvents, K
93
93
  onClose?: () => void;
94
94
  /**
95
95
  * Whether the menu should close when the menu item is selected.
96
- * @default true
96
+ * @deprecated - use shouldCloseOnSelect instead.
97
97
  */
98
98
  closeOnSelect?: boolean;
99
+ /** Whether the menu should close when the menu item is selected. */
100
+ shouldCloseOnSelect?: boolean;
99
101
  /** Whether the menu item is contained in a virtual scrolling menu. */
100
102
  isVirtualized?: boolean;
101
103
  /**
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-aria/menu/src/packages/@react-aria/menu/src/utils.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/useMenu.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/useMenuTrigger.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/useMenuItem.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/useMenuSection.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/useSafelyMouseToSubmenu.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/useSubmenuTrigger.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/index.ts","packages/@react-aria/menu/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {useMenuTrigger} from './useMenuTrigger';\nexport {useMenu} from './useMenu';\nexport {useMenuItem} from './useMenuItem';\nexport {useMenuSection} from './useMenuSection';\nexport {useSubmenuTrigger} from './useSubmenuTrigger';\n\nexport type {AriaMenuProps} from '@react-types/menu';\nexport type {AriaMenuTriggerProps, MenuTriggerAria} from './useMenuTrigger';\nexport type {AriaMenuOptions, MenuAria} from './useMenu';\nexport type {AriaMenuItemProps, MenuItemAria} from './useMenuItem';\nexport type {AriaMenuSectionProps, MenuSectionAria} from './useMenuSection';\nexport type {AriaSubmenuTriggerProps, SubmenuTriggerAria} from './useSubmenuTrigger';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
1
+ {"mappings":";;;;;;;;ACmBA;IACE,kCAAkC;IAClC,SAAS,EAAE,aAAa,CAAA;CACzB;AAED,iCAAiC,CAAC,CAAE,SAAQ,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,cAAc;IAC5F,+CAA+C;IAC/C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC;AAED;;;;;GAKG;AACH,wBAAwB,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,WAAW,GAAG,IAAI,CAAC,GAAG,QAAQ,CAyCvH;AC7DD;IACE,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,eAAe,CAAA;CAC1B;AAED,iCAAiC,CAAC;IAChC,0CAA0C;IAC1C,gBAAgB,EAAE,eAAe,CAAC;IAElC,0BAA0B;IAC1B,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAA;CAC9B;AAED;;;;;GAKG;AACH,+BAA+B,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,UAAU,OAAO,GAAG,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC,CA4G1I;ACrID;IACE,uCAAuC;IACvC,aAAa,EAAE,aAAa,CAAC;IAE7B,4DAA4D;IAC5D,UAAU,EAAE,aAAa,CAAC;IAE1B,2EAA2E;IAC3E,gBAAgB,EAAE,aAAa,CAAC;IAEhC,4EAA4E;IAC5E,qBAAqB,EAAE,aAAa,CAAC;IAErC,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,4CAA4C;IAC5C,cAAc,EAAE,OAAO,CAAC;IACxB,8CAA8C;IAC9C,UAAU,EAAE,OAAO,CAAC;IACpB,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IACnB,oCAAoC;IACpC,UAAU,EAAE,OAAO,CAAA;CACpB;AAED,kCAAmC,SAAQ,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW;IACxG;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,wCAAwC;IACxC,GAAG,EAAE,GAAG,CAAC;IAET;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,oEAAoE;IACpE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B,sEAAsE;IACtE,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;IAE9B,yCAAyC;IACzC,eAAe,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAEpC,gFAAgF;IAChF,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IAE7C,0GAA0G;IAC1G,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CACpC;AAED;;;;;GAKG;AACH,4BAA4B,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,gBAAgB,GAAG,IAAI,CAAC,GAAG,YAAY,CAgPnI;AC7UD;IACE,mCAAmC;IACnC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,oFAAoF;IACpF,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;IACE,uCAAuC;IACvC,SAAS,EAAE,aAAa,CAAC;IAEzB,6CAA6C;IAC7C,YAAY,EAAE,aAAa,CAAC;IAE5B,mCAAmC;IACnC,UAAU,EAAE,aAAa,CAAA;CAC1B;AAED;;;;GAIG;AACH,+BAA+B,KAAK,EAAE,oBAAoB,GAAG,eAAe,CAqB3E;AEtCD;IACE;;;OAGG;IACH,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IACrB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IACzB,yDAAyD;IACzD,aAAa,EAAE,UAAU,WAAW,GAAG,IAAI,CAAC,CAAC;IAC7C,wDAAwD;IACxD,UAAU,EAAE,UAAU,WAAW,GAAG,IAAI,CAAC,CAAC;IAC1C;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC;AAED,6BAA8B,SAAQ,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC;IAClE,2DAA2D;IAC3D,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,uBAAuB,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC;IAClD,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,oCAAoC,CAAC;IACnC,+CAA+C;IAC/C,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,yEAAyE;IACzE,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC;IAC9B,iDAAiD;IACjD,YAAY,EAAE,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,8BAA8B,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,wBAAwB,CAAC,CAAA;CACnI;AAED;;;;;GAKG;AACH,kCAAkC,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,KAAK,EAAE,mBAAmB,EAAE,GAAG,EAAE,UAAU,gBAAgB,GAAG,IAAI,CAAC,GAAG,mBAAmB,CAAC,CAAC,CA+L/J;ACnPD,YAAY,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC","sources":["packages/@react-aria/menu/src/packages/@react-aria/menu/src/utils.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/useMenu.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/useMenuTrigger.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/useMenuItem.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/useMenuSection.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/useSafelyMouseToSubmenu.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/useSubmenuTrigger.ts","packages/@react-aria/menu/src/packages/@react-aria/menu/src/index.ts","packages/@react-aria/menu/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {useMenuTrigger} from './useMenuTrigger';\nexport {useMenu} from './useMenu';\nexport {useMenuItem} from './useMenuItem';\nexport {useMenuSection} from './useMenuSection';\nexport {useSubmenuTrigger} from './useSubmenuTrigger';\n\nexport type {AriaMenuProps} from '@react-types/menu';\nexport type {AriaMenuTriggerProps, MenuTriggerAria} from './useMenuTrigger';\nexport type {AriaMenuOptions, MenuAria} from './useMenu';\nexport type {AriaMenuItemProps, MenuItemAria} from './useMenuItem';\nexport type {AriaMenuSectionProps, MenuSectionAria} from './useMenuSection';\nexport type {AriaSubmenuTriggerProps, SubmenuTriggerAria} from './useSubmenuTrigger';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
@@ -28,7 +28,7 @@ $parcel$export(module.exports, "useMenuItem", () => $38191ed02615ec07$export$9d3
28
28
 
29
29
 
30
30
  function $38191ed02615ec07$export$9d32628fc2aea7da(props, state, ref) {
31
- let { id: id, key: key, closeOnSelect: closeOnSelect, isVirtualized: isVirtualized, 'aria-haspopup': hasPopup, onPressStart: onPressStart, onPressUp: pressUpProp, onPress: onPress, onPressChange: pressChangeProp, onPressEnd: onPressEnd, onClick: onClickProp, onHoverStart: hoverStartProp, onHoverChange: onHoverChange, onHoverEnd: onHoverEnd, onKeyDown: onKeyDown, onKeyUp: onKeyUp, onFocus: onFocus, onFocusChange: onFocusChange, onBlur: onBlur, selectionManager: selectionManager = state.selectionManager } = props;
31
+ let { id: id, key: key, closeOnSelect: closeOnSelect, shouldCloseOnSelect: shouldCloseOnSelect, isVirtualized: isVirtualized, 'aria-haspopup': hasPopup, onPressStart: onPressStart, onPressUp: pressUpProp, onPress: onPress, onPressChange: pressChangeProp, onPressEnd: onPressEnd, onClick: onClickProp, onHoverStart: hoverStartProp, onHoverChange: onHoverChange, onHoverEnd: onHoverEnd, onKeyDown: onKeyDown, onKeyUp: onKeyUp, onFocus: onFocus, onFocusChange: onFocusChange, onBlur: onBlur, selectionManager: selectionManager = state.selectionManager } = props;
32
32
  let isTrigger = !!hasPopup;
33
33
  let isTriggerExpanded = isTrigger && props['aria-expanded'] === 'true';
34
34
  var _props_isDisabled;
@@ -100,7 +100,8 @@ function $38191ed02615ec07$export$9d32628fc2aea7da(props, state, ref) {
100
100
  performAction();
101
101
  (0, $byVdR$reactariautils.handleLinkClick)(e, router, item.props.href, item === null || item === void 0 ? void 0 : item.props.routerOptions);
102
102
  let shouldClose = ((_interaction_current = interaction.current) === null || _interaction_current === void 0 ? void 0 : _interaction_current.pointerType) === 'keyboard' ? ((_interaction_current1 = interaction.current) === null || _interaction_current1 === void 0 ? void 0 : _interaction_current1.key) === 'Enter' || selectionManager.selectionMode === 'none' || selectionManager.isLink(key) : selectionManager.selectionMode !== 'multiple' || selectionManager.isLink(key);
103
- shouldClose = closeOnSelect !== null && closeOnSelect !== void 0 ? closeOnSelect : shouldClose;
103
+ var _ref;
104
+ shouldClose = (_ref = shouldCloseOnSelect !== null && shouldCloseOnSelect !== void 0 ? shouldCloseOnSelect : closeOnSelect) !== null && _ref !== void 0 ? _ref : shouldClose;
104
105
  if (onClose && !isTrigger && shouldClose) onClose();
105
106
  interaction.current = null;
106
107
  };
@@ -171,11 +172,11 @@ function $38191ed02615ec07$export$9d32628fc2aea7da(props, state, ref) {
171
172
  },
172
173
  onKeyUp: onKeyUp
173
174
  });
174
- let { focusProps: focusProps } = (0, $byVdR$reactariainteractions.useFocus)({
175
+ let { focusableProps: focusableProps } = (0, $byVdR$reactariainteractions.useFocusable)({
175
176
  onBlur: onBlur,
176
177
  onFocus: onFocus,
177
178
  onFocusChange: onFocusChange
178
- });
179
+ }, ref);
179
180
  let domProps = (0, $byVdR$reactariautils.filterDOMProps)(item === null || item === void 0 ? void 0 : item.props);
180
181
  delete domProps.id;
181
182
  let linkProps = (0, $byVdR$reactariautils.useLinkProps)(item === null || item === void 0 ? void 0 : item.props);
@@ -186,7 +187,7 @@ function $38191ed02615ec07$export$9d32628fc2aea7da(props, state, ref) {
186
187
  onFocus: itemProps.onFocus,
187
188
  'data-collection': itemProps['data-collection'],
188
189
  'data-key': itemProps['data-key']
189
- } : itemProps, pressProps, hoverProps, keyboardProps, focusProps, // Prevent DOM focus from moving on mouse down when using virtual focus or this is a submenu/subdialog trigger.
190
+ } : itemProps, pressProps, hoverProps, keyboardProps, focusableProps, // Prevent DOM focus from moving on mouse down when using virtual focus or this is a submenu/subdialog trigger.
190
191
  data.shouldUseVirtualFocus || isTrigger ? {
191
192
  onMouseDown: (e)=>e.preventDefault()
192
193
  } : undefined, isDisabled ? undefined : {
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-aria/menu/src/useMenuItem.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {DOMAttributes, DOMProps, FocusableElement, FocusEvents, HoverEvents, Key, KeyboardEvents, PressEvent, PressEvents, RefObject} from '@react-types/shared';\nimport {filterDOMProps, handleLinkClick, mergeProps, useLinkProps, useRouter, useSlotId} from '@react-aria/utils';\nimport {getItemCount} from '@react-stately/collections';\nimport {isFocusVisible, useFocus, useHover, useKeyboard, usePress} from '@react-aria/interactions';\nimport {menuData} from './utils';\nimport {MouseEvent, useRef} from 'react';\nimport {SelectionManager} from '@react-stately/selection';\nimport {TreeState} from '@react-stately/tree';\nimport {useSelectableItem} from '@react-aria/selection';\n\nexport interface MenuItemAria {\n /** Props for the menu item element. */\n menuItemProps: DOMAttributes,\n\n /** Props for the main text element inside the menu item. */\n labelProps: DOMAttributes,\n\n /** Props for the description text element inside the menu item, if any. */\n descriptionProps: DOMAttributes,\n\n /** Props for the keyboard shortcut text element inside the item, if any. */\n keyboardShortcutProps: DOMAttributes,\n\n /** Whether the item is currently focused. */\n isFocused: boolean,\n /** Whether the item is keyboard focused. */\n isFocusVisible: boolean,\n /** Whether the item is currently selected. */\n isSelected: boolean,\n /** Whether the item is currently in a pressed state. */\n isPressed: boolean,\n /** Whether the item is disabled. */\n isDisabled: boolean\n}\n\nexport interface AriaMenuItemProps extends DOMProps, PressEvents, HoverEvents, KeyboardEvents, FocusEvents {\n /**\n * Whether the menu item is disabled.\n * @deprecated - pass disabledKeys to useTreeState instead.\n */\n isDisabled?: boolean,\n\n /**\n * Whether the menu item is selected.\n * @deprecated - pass selectedKeys to useTreeState instead.\n */\n isSelected?: boolean,\n\n /** A screen reader only label for the menu item. */\n 'aria-label'?: string,\n\n /** The unique key for the menu item. */\n key: Key,\n\n /**\n * Handler that is called when the menu should close after selecting an item.\n * @deprecated - pass to the menu instead.\n */\n onClose?: () => void,\n\n /**\n * Whether the menu should close when the menu item is selected.\n * @default true\n */\n closeOnSelect?: boolean,\n\n /** Whether the menu item is contained in a virtual scrolling menu. */\n isVirtualized?: boolean,\n\n /**\n * Handler that is called when the user activates the item.\n * @deprecated - pass to the menu instead.\n */\n onAction?: (key: Key) => void,\n\n /** What kind of popup the item opens. */\n 'aria-haspopup'?: 'menu' | 'dialog',\n\n /** Indicates whether the menu item's popup element is expanded or collapsed. */\n 'aria-expanded'?: boolean | 'true' | 'false',\n\n /** Identifies the menu item's popup element whose contents or presence is controlled by the menu item. */\n 'aria-controls'?: string,\n\n /** Override of the selection manager. By default, `state.selectionManager` is used. */\n selectionManager?: SelectionManager\n}\n\n/**\n * Provides the behavior and accessibility implementation for an item in a menu.\n * See `useMenu` for more details about menus.\n * @param props - Props for the item.\n * @param state - State for the menu, as returned by `useTreeState`.\n */\nexport function useMenuItem<T>(props: AriaMenuItemProps, state: TreeState<T>, ref: RefObject<FocusableElement | null>): MenuItemAria {\n let {\n id,\n key,\n closeOnSelect,\n isVirtualized,\n 'aria-haspopup': hasPopup,\n onPressStart,\n onPressUp: pressUpProp,\n onPress,\n onPressChange: pressChangeProp,\n onPressEnd,\n onClick: onClickProp,\n onHoverStart: hoverStartProp,\n onHoverChange,\n onHoverEnd,\n onKeyDown,\n onKeyUp,\n onFocus,\n onFocusChange,\n onBlur,\n selectionManager = state.selectionManager\n } = props;\n\n let isTrigger = !!hasPopup;\n let isTriggerExpanded = isTrigger && props['aria-expanded'] === 'true';\n let isDisabled = props.isDisabled ?? selectionManager.isDisabled(key);\n let isSelected = props.isSelected ?? selectionManager.isSelected(key);\n let data = menuData.get(state)!;\n let item = state.collection.getItem(key);\n let onClose = props.onClose || data.onClose;\n let router = useRouter();\n let performAction = () => {\n if (isTrigger) {\n return;\n }\n\n if (item?.props?.onAction) {\n item.props.onAction();\n } else if (props.onAction) {\n props.onAction(key);\n }\n\n if (data.onAction) {\n // Must reassign to variable otherwise `this` binding gets messed up. Something to do with WeakMap.\n let onAction = data.onAction;\n onAction(key);\n }\n };\n\n let role = 'menuitem';\n if (!isTrigger) {\n if (selectionManager.selectionMode === 'single') {\n role = 'menuitemradio';\n } else if (selectionManager.selectionMode === 'multiple') {\n role = 'menuitemcheckbox';\n }\n }\n\n let labelId = useSlotId();\n let descriptionId = useSlotId();\n let keyboardId = useSlotId();\n\n let ariaProps = {\n id,\n 'aria-disabled': isDisabled || undefined,\n role,\n 'aria-label': props['aria-label'],\n 'aria-labelledby': labelId,\n 'aria-describedby': [descriptionId, keyboardId].filter(Boolean).join(' ') || undefined,\n 'aria-controls': props['aria-controls'],\n 'aria-haspopup': hasPopup,\n 'aria-expanded': props['aria-expanded']\n };\n\n if (selectionManager.selectionMode !== 'none' && !isTrigger) {\n ariaProps['aria-checked'] = isSelected;\n }\n\n if (isVirtualized) {\n ariaProps['aria-posinset'] = item?.index;\n ariaProps['aria-setsize'] = getItemCount(state.collection);\n }\n\n let isPressedRef = useRef(false);\n let onPressChange = (isPressed: boolean) => {\n pressChangeProp?.(isPressed);\n isPressedRef.current = isPressed;\n };\n\n let interaction = useRef<{pointerType: string, key?: string} | null>(null);\n let onPressUp = (e: PressEvent) => {\n if (e.pointerType !== 'keyboard') {\n interaction.current = {pointerType: e.pointerType};\n }\n\n // If interacting with mouse, allow the user to mouse down on the trigger button,\n // drag, and release over an item (matching native behavior).\n if (e.pointerType === 'mouse') {\n if (!isPressedRef.current) {\n (e.target as HTMLElement).click();\n }\n }\n\n pressUpProp?.(e);\n };\n\n let onClick = (e: MouseEvent<FocusableElement>) => {\n onClickProp?.(e);\n performAction();\n handleLinkClick(e, router, item!.props.href, item?.props.routerOptions);\n\n let shouldClose = interaction.current?.pointerType === 'keyboard'\n // Always close when pressing Enter key, or if item is not selectable.\n ? interaction.current?.key === 'Enter' || selectionManager.selectionMode === 'none' || selectionManager.isLink(key)\n // Close except if multi-select is enabled.\n : selectionManager.selectionMode !== 'multiple' || selectionManager.isLink(key);\n \n shouldClose = closeOnSelect ?? shouldClose;\n if (onClose && !isTrigger && shouldClose) {\n onClose();\n }\n\n interaction.current = null;\n };\n\n let {itemProps, isFocused} = useSelectableItem({\n id,\n selectionManager: selectionManager,\n key,\n ref,\n shouldSelectOnPressUp: true,\n allowsDifferentPressOrigin: true,\n // Disable all handling of links in useSelectable item\n // because we handle it ourselves. The behavior of menus\n // is slightly different from other collections because\n // actions are performed on key down rather than key up.\n linkBehavior: 'none',\n shouldUseVirtualFocus: data.shouldUseVirtualFocus\n });\n\n let {pressProps, isPressed} = usePress({\n onPressStart,\n onPress,\n onPressUp,\n onPressChange,\n onPressEnd,\n isDisabled\n });\n let {hoverProps} = useHover({\n isDisabled,\n onHoverStart(e) {\n // Hovering over an already expanded sub dialog trigger should keep focus in the dialog.\n if (!isFocusVisible() && !(isTriggerExpanded && hasPopup)) {\n selectionManager.setFocused(true);\n selectionManager.setFocusedKey(key);\n }\n hoverStartProp?.(e);\n },\n onHoverChange,\n onHoverEnd\n });\n\n let {keyboardProps} = useKeyboard({\n onKeyDown: (e) => {\n // Ignore repeating events, which may have started on the menu trigger before moving\n // focus to the menu item. We want to wait for a second complete key press sequence.\n if (e.repeat) {\n e.continuePropagation();\n return;\n }\n\n switch (e.key) {\n case ' ':\n interaction.current = {pointerType: 'keyboard', key: ' '};\n (e.target as HTMLElement).click();\n break;\n case 'Enter':\n interaction.current = {pointerType: 'keyboard', key: 'Enter'};\n\n // Trigger click unless this is a link. Links trigger click natively.\n if ((e.target as HTMLElement).tagName !== 'A') {\n (e.target as HTMLElement).click();\n }\n break;\n default:\n if (!isTrigger) {\n e.continuePropagation();\n }\n\n onKeyDown?.(e);\n break;\n }\n },\n onKeyUp\n });\n\n let {focusProps} = useFocus({onBlur, onFocus, onFocusChange});\n let domProps = filterDOMProps(item?.props);\n delete domProps.id;\n let linkProps = useLinkProps(item?.props);\n\n return {\n menuItemProps: {\n ...ariaProps,\n ...mergeProps(\n domProps,\n linkProps,\n isTrigger \n ? {onFocus: itemProps.onFocus, 'data-collection': itemProps['data-collection'], 'data-key': itemProps['data-key']} \n : itemProps,\n pressProps,\n hoverProps,\n keyboardProps,\n focusProps,\n // Prevent DOM focus from moving on mouse down when using virtual focus or this is a submenu/subdialog trigger.\n data.shouldUseVirtualFocus || isTrigger ? {onMouseDown: e => e.preventDefault()} : undefined,\n isDisabled ? undefined : {onClick}\n ),\n // If a submenu is expanded, set the tabIndex to -1 so that shift tabbing goes out of the menu instead of the parent menu item.\n tabIndex: itemProps.tabIndex != null && isTriggerExpanded && !data.shouldUseVirtualFocus ? -1 : itemProps.tabIndex\n },\n labelProps: {\n id: labelId\n },\n descriptionProps: {\n id: descriptionId\n },\n keyboardShortcutProps: {\n id: keyboardId\n },\n isFocused,\n isFocusVisible: isFocused && selectionManager.isFocused && isFocusVisible() && !isTriggerExpanded,\n isSelected,\n isPressed,\n isDisabled\n };\n}\n"],"names":[],"version":3,"file":"useMenuItem.main.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-aria/menu/src/useMenuItem.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {DOMAttributes, DOMProps, FocusableElement, FocusEvents, HoverEvents, Key, KeyboardEvents, PressEvent, PressEvents, RefObject} from '@react-types/shared';\nimport {filterDOMProps, handleLinkClick, mergeProps, useLinkProps, useRouter, useSlotId} from '@react-aria/utils';\nimport {getItemCount} from '@react-stately/collections';\nimport {isFocusVisible, useFocusable, useHover, useKeyboard, usePress} from '@react-aria/interactions';\nimport {menuData} from './utils';\nimport {MouseEvent, useRef} from 'react';\nimport {SelectionManager} from '@react-stately/selection';\nimport {TreeState} from '@react-stately/tree';\nimport {useSelectableItem} from '@react-aria/selection';\n\nexport interface MenuItemAria {\n /** Props for the menu item element. */\n menuItemProps: DOMAttributes,\n\n /** Props for the main text element inside the menu item. */\n labelProps: DOMAttributes,\n\n /** Props for the description text element inside the menu item, if any. */\n descriptionProps: DOMAttributes,\n\n /** Props for the keyboard shortcut text element inside the item, if any. */\n keyboardShortcutProps: DOMAttributes,\n\n /** Whether the item is currently focused. */\n isFocused: boolean,\n /** Whether the item is keyboard focused. */\n isFocusVisible: boolean,\n /** Whether the item is currently selected. */\n isSelected: boolean,\n /** Whether the item is currently in a pressed state. */\n isPressed: boolean,\n /** Whether the item is disabled. */\n isDisabled: boolean\n}\n\nexport interface AriaMenuItemProps extends DOMProps, PressEvents, HoverEvents, KeyboardEvents, FocusEvents {\n /**\n * Whether the menu item is disabled.\n * @deprecated - pass disabledKeys to useTreeState instead.\n */\n isDisabled?: boolean,\n\n /**\n * Whether the menu item is selected.\n * @deprecated - pass selectedKeys to useTreeState instead.\n */\n isSelected?: boolean,\n\n /** A screen reader only label for the menu item. */\n 'aria-label'?: string,\n\n /** The unique key for the menu item. */\n key: Key,\n\n /**\n * Handler that is called when the menu should close after selecting an item.\n * @deprecated - pass to the menu instead.\n */\n onClose?: () => void,\n\n /**\n * Whether the menu should close when the menu item is selected.\n * @deprecated - use shouldCloseOnSelect instead.\n */\n closeOnSelect?: boolean,\n\n /** Whether the menu should close when the menu item is selected. */\n shouldCloseOnSelect?: boolean,\n\n /** Whether the menu item is contained in a virtual scrolling menu. */\n isVirtualized?: boolean,\n\n /**\n * Handler that is called when the user activates the item.\n * @deprecated - pass to the menu instead.\n */\n onAction?: (key: Key) => void,\n\n /** What kind of popup the item opens. */\n 'aria-haspopup'?: 'menu' | 'dialog',\n\n /** Indicates whether the menu item's popup element is expanded or collapsed. */\n 'aria-expanded'?: boolean | 'true' | 'false',\n\n /** Identifies the menu item's popup element whose contents or presence is controlled by the menu item. */\n 'aria-controls'?: string,\n\n /** Override of the selection manager. By default, `state.selectionManager` is used. */\n selectionManager?: SelectionManager\n}\n\n/**\n * Provides the behavior and accessibility implementation for an item in a menu.\n * See `useMenu` for more details about menus.\n * @param props - Props for the item.\n * @param state - State for the menu, as returned by `useTreeState`.\n */\nexport function useMenuItem<T>(props: AriaMenuItemProps, state: TreeState<T>, ref: RefObject<FocusableElement | null>): MenuItemAria {\n let {\n id,\n key,\n closeOnSelect,\n shouldCloseOnSelect,\n isVirtualized,\n 'aria-haspopup': hasPopup,\n onPressStart,\n onPressUp: pressUpProp,\n onPress,\n onPressChange: pressChangeProp,\n onPressEnd,\n onClick: onClickProp,\n onHoverStart: hoverStartProp,\n onHoverChange,\n onHoverEnd,\n onKeyDown,\n onKeyUp,\n onFocus,\n onFocusChange,\n onBlur,\n selectionManager = state.selectionManager\n } = props;\n\n let isTrigger = !!hasPopup;\n let isTriggerExpanded = isTrigger && props['aria-expanded'] === 'true';\n let isDisabled = props.isDisabled ?? selectionManager.isDisabled(key);\n let isSelected = props.isSelected ?? selectionManager.isSelected(key);\n let data = menuData.get(state)!;\n let item = state.collection.getItem(key);\n let onClose = props.onClose || data.onClose;\n let router = useRouter();\n let performAction = () => {\n if (isTrigger) {\n return;\n }\n\n if (item?.props?.onAction) {\n item.props.onAction();\n } else if (props.onAction) {\n props.onAction(key);\n }\n\n if (data.onAction) {\n // Must reassign to variable otherwise `this` binding gets messed up. Something to do with WeakMap.\n let onAction = data.onAction;\n onAction(key);\n }\n };\n\n let role = 'menuitem';\n if (!isTrigger) {\n if (selectionManager.selectionMode === 'single') {\n role = 'menuitemradio';\n } else if (selectionManager.selectionMode === 'multiple') {\n role = 'menuitemcheckbox';\n }\n }\n\n let labelId = useSlotId();\n let descriptionId = useSlotId();\n let keyboardId = useSlotId();\n\n let ariaProps = {\n id,\n 'aria-disabled': isDisabled || undefined,\n role,\n 'aria-label': props['aria-label'],\n 'aria-labelledby': labelId,\n 'aria-describedby': [descriptionId, keyboardId].filter(Boolean).join(' ') || undefined,\n 'aria-controls': props['aria-controls'],\n 'aria-haspopup': hasPopup,\n 'aria-expanded': props['aria-expanded']\n };\n\n if (selectionManager.selectionMode !== 'none' && !isTrigger) {\n ariaProps['aria-checked'] = isSelected;\n }\n\n if (isVirtualized) {\n ariaProps['aria-posinset'] = item?.index;\n ariaProps['aria-setsize'] = getItemCount(state.collection);\n }\n\n let isPressedRef = useRef(false);\n let onPressChange = (isPressed: boolean) => {\n pressChangeProp?.(isPressed);\n isPressedRef.current = isPressed;\n };\n\n let interaction = useRef<{pointerType: string, key?: string} | null>(null);\n let onPressUp = (e: PressEvent) => {\n if (e.pointerType !== 'keyboard') {\n interaction.current = {pointerType: e.pointerType};\n }\n\n // If interacting with mouse, allow the user to mouse down on the trigger button,\n // drag, and release over an item (matching native behavior).\n if (e.pointerType === 'mouse') {\n if (!isPressedRef.current) {\n (e.target as HTMLElement).click();\n }\n }\n\n pressUpProp?.(e);\n };\n\n let onClick = (e: MouseEvent<FocusableElement>) => {\n onClickProp?.(e);\n performAction();\n handleLinkClick(e, router, item!.props.href, item?.props.routerOptions);\n\n let shouldClose = interaction.current?.pointerType === 'keyboard'\n // Always close when pressing Enter key, or if item is not selectable.\n ? interaction.current?.key === 'Enter' || selectionManager.selectionMode === 'none' || selectionManager.isLink(key)\n // Close except if multi-select is enabled.\n : selectionManager.selectionMode !== 'multiple' || selectionManager.isLink(key);\n\n\n shouldClose = shouldCloseOnSelect ?? closeOnSelect ?? shouldClose;\n\n if (onClose && !isTrigger && shouldClose) {\n onClose();\n }\n\n interaction.current = null;\n };\n\n let {itemProps, isFocused} = useSelectableItem({\n id,\n selectionManager: selectionManager,\n key,\n ref,\n shouldSelectOnPressUp: true,\n allowsDifferentPressOrigin: true,\n // Disable all handling of links in useSelectable item\n // because we handle it ourselves. The behavior of menus\n // is slightly different from other collections because\n // actions are performed on key down rather than key up.\n linkBehavior: 'none',\n shouldUseVirtualFocus: data.shouldUseVirtualFocus\n });\n\n let {pressProps, isPressed} = usePress({\n onPressStart,\n onPress,\n onPressUp,\n onPressChange,\n onPressEnd,\n isDisabled\n });\n let {hoverProps} = useHover({\n isDisabled,\n onHoverStart(e) {\n // Hovering over an already expanded sub dialog trigger should keep focus in the dialog.\n if (!isFocusVisible() && !(isTriggerExpanded && hasPopup)) {\n selectionManager.setFocused(true);\n selectionManager.setFocusedKey(key);\n }\n hoverStartProp?.(e);\n },\n onHoverChange,\n onHoverEnd\n });\n\n let {keyboardProps} = useKeyboard({\n onKeyDown: (e) => {\n // Ignore repeating events, which may have started on the menu trigger before moving\n // focus to the menu item. We want to wait for a second complete key press sequence.\n if (e.repeat) {\n e.continuePropagation();\n return;\n }\n\n switch (e.key) {\n case ' ':\n interaction.current = {pointerType: 'keyboard', key: ' '};\n (e.target as HTMLElement).click();\n break;\n case 'Enter':\n interaction.current = {pointerType: 'keyboard', key: 'Enter'};\n\n // Trigger click unless this is a link. Links trigger click natively.\n if ((e.target as HTMLElement).tagName !== 'A') {\n (e.target as HTMLElement).click();\n }\n break;\n default:\n if (!isTrigger) {\n e.continuePropagation();\n }\n\n onKeyDown?.(e);\n break;\n }\n },\n onKeyUp\n });\n\n let {focusableProps} = useFocusable({onBlur, onFocus, onFocusChange}, ref);\n let domProps = filterDOMProps(item?.props);\n delete domProps.id;\n let linkProps = useLinkProps(item?.props);\n\n return {\n menuItemProps: {\n ...ariaProps,\n ...mergeProps(\n domProps,\n linkProps,\n isTrigger\n ? {onFocus: itemProps.onFocus, 'data-collection': itemProps['data-collection'], 'data-key': itemProps['data-key']}\n : itemProps,\n pressProps,\n hoverProps,\n keyboardProps,\n focusableProps,\n // Prevent DOM focus from moving on mouse down when using virtual focus or this is a submenu/subdialog trigger.\n data.shouldUseVirtualFocus || isTrigger ? {onMouseDown: e => e.preventDefault()} : undefined,\n isDisabled ? undefined : {onClick}\n ),\n // If a submenu is expanded, set the tabIndex to -1 so that shift tabbing goes out of the menu instead of the parent menu item.\n tabIndex: itemProps.tabIndex != null && isTriggerExpanded && !data.shouldUseVirtualFocus ? -1 : itemProps.tabIndex\n },\n labelProps: {\n id: labelId\n },\n descriptionProps: {\n id: descriptionId\n },\n keyboardShortcutProps: {\n id: keyboardId\n },\n isFocused,\n isFocusVisible: isFocused && selectionManager.isFocused && isFocusVisible() && !isTriggerExpanded,\n isSelected,\n isPressed,\n isDisabled\n };\n}\n"],"names":[],"version":3,"file":"useMenuItem.main.js.map"}
@@ -1,7 +1,7 @@
1
1
  import {menuData as $fc79756100351201$export$6f49b4016bfc8d56} from "./utils.mjs";
2
2
  import {useRouter as $7Kjv5$useRouter, useSlotId as $7Kjv5$useSlotId, handleLinkClick as $7Kjv5$handleLinkClick, filterDOMProps as $7Kjv5$filterDOMProps, useLinkProps as $7Kjv5$useLinkProps, mergeProps as $7Kjv5$mergeProps} from "@react-aria/utils";
3
3
  import {getItemCount as $7Kjv5$getItemCount} from "@react-stately/collections";
4
- import {usePress as $7Kjv5$usePress, useHover as $7Kjv5$useHover, isFocusVisible as $7Kjv5$isFocusVisible, useKeyboard as $7Kjv5$useKeyboard, useFocus as $7Kjv5$useFocus} from "@react-aria/interactions";
4
+ import {usePress as $7Kjv5$usePress, useHover as $7Kjv5$useHover, isFocusVisible as $7Kjv5$isFocusVisible, useKeyboard as $7Kjv5$useKeyboard, useFocusable as $7Kjv5$useFocusable} from "@react-aria/interactions";
5
5
  import {useRef as $7Kjv5$useRef} from "react";
6
6
  import {useSelectableItem as $7Kjv5$useSelectableItem} from "@react-aria/selection";
7
7
 
@@ -22,7 +22,7 @@ import {useSelectableItem as $7Kjv5$useSelectableItem} from "@react-aria/selecti
22
22
 
23
23
 
24
24
  function $a2e5df62f93c7633$export$9d32628fc2aea7da(props, state, ref) {
25
- let { id: id, key: key, closeOnSelect: closeOnSelect, isVirtualized: isVirtualized, 'aria-haspopup': hasPopup, onPressStart: onPressStart, onPressUp: pressUpProp, onPress: onPress, onPressChange: pressChangeProp, onPressEnd: onPressEnd, onClick: onClickProp, onHoverStart: hoverStartProp, onHoverChange: onHoverChange, onHoverEnd: onHoverEnd, onKeyDown: onKeyDown, onKeyUp: onKeyUp, onFocus: onFocus, onFocusChange: onFocusChange, onBlur: onBlur, selectionManager: selectionManager = state.selectionManager } = props;
25
+ let { id: id, key: key, closeOnSelect: closeOnSelect, shouldCloseOnSelect: shouldCloseOnSelect, isVirtualized: isVirtualized, 'aria-haspopup': hasPopup, onPressStart: onPressStart, onPressUp: pressUpProp, onPress: onPress, onPressChange: pressChangeProp, onPressEnd: onPressEnd, onClick: onClickProp, onHoverStart: hoverStartProp, onHoverChange: onHoverChange, onHoverEnd: onHoverEnd, onKeyDown: onKeyDown, onKeyUp: onKeyUp, onFocus: onFocus, onFocusChange: onFocusChange, onBlur: onBlur, selectionManager: selectionManager = state.selectionManager } = props;
26
26
  let isTrigger = !!hasPopup;
27
27
  let isTriggerExpanded = isTrigger && props['aria-expanded'] === 'true';
28
28
  var _props_isDisabled;
@@ -94,7 +94,8 @@ function $a2e5df62f93c7633$export$9d32628fc2aea7da(props, state, ref) {
94
94
  performAction();
95
95
  (0, $7Kjv5$handleLinkClick)(e, router, item.props.href, item === null || item === void 0 ? void 0 : item.props.routerOptions);
96
96
  let shouldClose = ((_interaction_current = interaction.current) === null || _interaction_current === void 0 ? void 0 : _interaction_current.pointerType) === 'keyboard' ? ((_interaction_current1 = interaction.current) === null || _interaction_current1 === void 0 ? void 0 : _interaction_current1.key) === 'Enter' || selectionManager.selectionMode === 'none' || selectionManager.isLink(key) : selectionManager.selectionMode !== 'multiple' || selectionManager.isLink(key);
97
- shouldClose = closeOnSelect !== null && closeOnSelect !== void 0 ? closeOnSelect : shouldClose;
97
+ var _ref;
98
+ shouldClose = (_ref = shouldCloseOnSelect !== null && shouldCloseOnSelect !== void 0 ? shouldCloseOnSelect : closeOnSelect) !== null && _ref !== void 0 ? _ref : shouldClose;
98
99
  if (onClose && !isTrigger && shouldClose) onClose();
99
100
  interaction.current = null;
100
101
  };
@@ -165,11 +166,11 @@ function $a2e5df62f93c7633$export$9d32628fc2aea7da(props, state, ref) {
165
166
  },
166
167
  onKeyUp: onKeyUp
167
168
  });
168
- let { focusProps: focusProps } = (0, $7Kjv5$useFocus)({
169
+ let { focusableProps: focusableProps } = (0, $7Kjv5$useFocusable)({
169
170
  onBlur: onBlur,
170
171
  onFocus: onFocus,
171
172
  onFocusChange: onFocusChange
172
- });
173
+ }, ref);
173
174
  let domProps = (0, $7Kjv5$filterDOMProps)(item === null || item === void 0 ? void 0 : item.props);
174
175
  delete domProps.id;
175
176
  let linkProps = (0, $7Kjv5$useLinkProps)(item === null || item === void 0 ? void 0 : item.props);
@@ -180,7 +181,7 @@ function $a2e5df62f93c7633$export$9d32628fc2aea7da(props, state, ref) {
180
181
  onFocus: itemProps.onFocus,
181
182
  'data-collection': itemProps['data-collection'],
182
183
  'data-key': itemProps['data-key']
183
- } : itemProps, pressProps, hoverProps, keyboardProps, focusProps, // Prevent DOM focus from moving on mouse down when using virtual focus or this is a submenu/subdialog trigger.
184
+ } : itemProps, pressProps, hoverProps, keyboardProps, focusableProps, // Prevent DOM focus from moving on mouse down when using virtual focus or this is a submenu/subdialog trigger.
184
185
  data.shouldUseVirtualFocus || isTrigger ? {
185
186
  onMouseDown: (e)=>e.preventDefault()
186
187
  } : undefined, isDisabled ? undefined : {
@@ -1,7 +1,7 @@
1
1
  import {menuData as $fc79756100351201$export$6f49b4016bfc8d56} from "./utils.module.js";
2
2
  import {useRouter as $7Kjv5$useRouter, useSlotId as $7Kjv5$useSlotId, handleLinkClick as $7Kjv5$handleLinkClick, filterDOMProps as $7Kjv5$filterDOMProps, useLinkProps as $7Kjv5$useLinkProps, mergeProps as $7Kjv5$mergeProps} from "@react-aria/utils";
3
3
  import {getItemCount as $7Kjv5$getItemCount} from "@react-stately/collections";
4
- import {usePress as $7Kjv5$usePress, useHover as $7Kjv5$useHover, isFocusVisible as $7Kjv5$isFocusVisible, useKeyboard as $7Kjv5$useKeyboard, useFocus as $7Kjv5$useFocus} from "@react-aria/interactions";
4
+ import {usePress as $7Kjv5$usePress, useHover as $7Kjv5$useHover, isFocusVisible as $7Kjv5$isFocusVisible, useKeyboard as $7Kjv5$useKeyboard, useFocusable as $7Kjv5$useFocusable} from "@react-aria/interactions";
5
5
  import {useRef as $7Kjv5$useRef} from "react";
6
6
  import {useSelectableItem as $7Kjv5$useSelectableItem} from "@react-aria/selection";
7
7
 
@@ -22,7 +22,7 @@ import {useSelectableItem as $7Kjv5$useSelectableItem} from "@react-aria/selecti
22
22
 
23
23
 
24
24
  function $a2e5df62f93c7633$export$9d32628fc2aea7da(props, state, ref) {
25
- let { id: id, key: key, closeOnSelect: closeOnSelect, isVirtualized: isVirtualized, 'aria-haspopup': hasPopup, onPressStart: onPressStart, onPressUp: pressUpProp, onPress: onPress, onPressChange: pressChangeProp, onPressEnd: onPressEnd, onClick: onClickProp, onHoverStart: hoverStartProp, onHoverChange: onHoverChange, onHoverEnd: onHoverEnd, onKeyDown: onKeyDown, onKeyUp: onKeyUp, onFocus: onFocus, onFocusChange: onFocusChange, onBlur: onBlur, selectionManager: selectionManager = state.selectionManager } = props;
25
+ let { id: id, key: key, closeOnSelect: closeOnSelect, shouldCloseOnSelect: shouldCloseOnSelect, isVirtualized: isVirtualized, 'aria-haspopup': hasPopup, onPressStart: onPressStart, onPressUp: pressUpProp, onPress: onPress, onPressChange: pressChangeProp, onPressEnd: onPressEnd, onClick: onClickProp, onHoverStart: hoverStartProp, onHoverChange: onHoverChange, onHoverEnd: onHoverEnd, onKeyDown: onKeyDown, onKeyUp: onKeyUp, onFocus: onFocus, onFocusChange: onFocusChange, onBlur: onBlur, selectionManager: selectionManager = state.selectionManager } = props;
26
26
  let isTrigger = !!hasPopup;
27
27
  let isTriggerExpanded = isTrigger && props['aria-expanded'] === 'true';
28
28
  var _props_isDisabled;
@@ -94,7 +94,8 @@ function $a2e5df62f93c7633$export$9d32628fc2aea7da(props, state, ref) {
94
94
  performAction();
95
95
  (0, $7Kjv5$handleLinkClick)(e, router, item.props.href, item === null || item === void 0 ? void 0 : item.props.routerOptions);
96
96
  let shouldClose = ((_interaction_current = interaction.current) === null || _interaction_current === void 0 ? void 0 : _interaction_current.pointerType) === 'keyboard' ? ((_interaction_current1 = interaction.current) === null || _interaction_current1 === void 0 ? void 0 : _interaction_current1.key) === 'Enter' || selectionManager.selectionMode === 'none' || selectionManager.isLink(key) : selectionManager.selectionMode !== 'multiple' || selectionManager.isLink(key);
97
- shouldClose = closeOnSelect !== null && closeOnSelect !== void 0 ? closeOnSelect : shouldClose;
97
+ var _ref;
98
+ shouldClose = (_ref = shouldCloseOnSelect !== null && shouldCloseOnSelect !== void 0 ? shouldCloseOnSelect : closeOnSelect) !== null && _ref !== void 0 ? _ref : shouldClose;
98
99
  if (onClose && !isTrigger && shouldClose) onClose();
99
100
  interaction.current = null;
100
101
  };
@@ -165,11 +166,11 @@ function $a2e5df62f93c7633$export$9d32628fc2aea7da(props, state, ref) {
165
166
  },
166
167
  onKeyUp: onKeyUp
167
168
  });
168
- let { focusProps: focusProps } = (0, $7Kjv5$useFocus)({
169
+ let { focusableProps: focusableProps } = (0, $7Kjv5$useFocusable)({
169
170
  onBlur: onBlur,
170
171
  onFocus: onFocus,
171
172
  onFocusChange: onFocusChange
172
- });
173
+ }, ref);
173
174
  let domProps = (0, $7Kjv5$filterDOMProps)(item === null || item === void 0 ? void 0 : item.props);
174
175
  delete domProps.id;
175
176
  let linkProps = (0, $7Kjv5$useLinkProps)(item === null || item === void 0 ? void 0 : item.props);
@@ -180,7 +181,7 @@ function $a2e5df62f93c7633$export$9d32628fc2aea7da(props, state, ref) {
180
181
  onFocus: itemProps.onFocus,
181
182
  'data-collection': itemProps['data-collection'],
182
183
  'data-key': itemProps['data-key']
183
- } : itemProps, pressProps, hoverProps, keyboardProps, focusProps, // Prevent DOM focus from moving on mouse down when using virtual focus or this is a submenu/subdialog trigger.
184
+ } : itemProps, pressProps, hoverProps, keyboardProps, focusableProps, // Prevent DOM focus from moving on mouse down when using virtual focus or this is a submenu/subdialog trigger.
184
185
  data.shouldUseVirtualFocus || isTrigger ? {
185
186
  onMouseDown: (e)=>e.preventDefault()
186
187
  } : undefined, isDisabled ? undefined : {
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-aria/menu/src/useMenuItem.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {DOMAttributes, DOMProps, FocusableElement, FocusEvents, HoverEvents, Key, KeyboardEvents, PressEvent, PressEvents, RefObject} from '@react-types/shared';\nimport {filterDOMProps, handleLinkClick, mergeProps, useLinkProps, useRouter, useSlotId} from '@react-aria/utils';\nimport {getItemCount} from '@react-stately/collections';\nimport {isFocusVisible, useFocus, useHover, useKeyboard, usePress} from '@react-aria/interactions';\nimport {menuData} from './utils';\nimport {MouseEvent, useRef} from 'react';\nimport {SelectionManager} from '@react-stately/selection';\nimport {TreeState} from '@react-stately/tree';\nimport {useSelectableItem} from '@react-aria/selection';\n\nexport interface MenuItemAria {\n /** Props for the menu item element. */\n menuItemProps: DOMAttributes,\n\n /** Props for the main text element inside the menu item. */\n labelProps: DOMAttributes,\n\n /** Props for the description text element inside the menu item, if any. */\n descriptionProps: DOMAttributes,\n\n /** Props for the keyboard shortcut text element inside the item, if any. */\n keyboardShortcutProps: DOMAttributes,\n\n /** Whether the item is currently focused. */\n isFocused: boolean,\n /** Whether the item is keyboard focused. */\n isFocusVisible: boolean,\n /** Whether the item is currently selected. */\n isSelected: boolean,\n /** Whether the item is currently in a pressed state. */\n isPressed: boolean,\n /** Whether the item is disabled. */\n isDisabled: boolean\n}\n\nexport interface AriaMenuItemProps extends DOMProps, PressEvents, HoverEvents, KeyboardEvents, FocusEvents {\n /**\n * Whether the menu item is disabled.\n * @deprecated - pass disabledKeys to useTreeState instead.\n */\n isDisabled?: boolean,\n\n /**\n * Whether the menu item is selected.\n * @deprecated - pass selectedKeys to useTreeState instead.\n */\n isSelected?: boolean,\n\n /** A screen reader only label for the menu item. */\n 'aria-label'?: string,\n\n /** The unique key for the menu item. */\n key: Key,\n\n /**\n * Handler that is called when the menu should close after selecting an item.\n * @deprecated - pass to the menu instead.\n */\n onClose?: () => void,\n\n /**\n * Whether the menu should close when the menu item is selected.\n * @default true\n */\n closeOnSelect?: boolean,\n\n /** Whether the menu item is contained in a virtual scrolling menu. */\n isVirtualized?: boolean,\n\n /**\n * Handler that is called when the user activates the item.\n * @deprecated - pass to the menu instead.\n */\n onAction?: (key: Key) => void,\n\n /** What kind of popup the item opens. */\n 'aria-haspopup'?: 'menu' | 'dialog',\n\n /** Indicates whether the menu item's popup element is expanded or collapsed. */\n 'aria-expanded'?: boolean | 'true' | 'false',\n\n /** Identifies the menu item's popup element whose contents or presence is controlled by the menu item. */\n 'aria-controls'?: string,\n\n /** Override of the selection manager. By default, `state.selectionManager` is used. */\n selectionManager?: SelectionManager\n}\n\n/**\n * Provides the behavior and accessibility implementation for an item in a menu.\n * See `useMenu` for more details about menus.\n * @param props - Props for the item.\n * @param state - State for the menu, as returned by `useTreeState`.\n */\nexport function useMenuItem<T>(props: AriaMenuItemProps, state: TreeState<T>, ref: RefObject<FocusableElement | null>): MenuItemAria {\n let {\n id,\n key,\n closeOnSelect,\n isVirtualized,\n 'aria-haspopup': hasPopup,\n onPressStart,\n onPressUp: pressUpProp,\n onPress,\n onPressChange: pressChangeProp,\n onPressEnd,\n onClick: onClickProp,\n onHoverStart: hoverStartProp,\n onHoverChange,\n onHoverEnd,\n onKeyDown,\n onKeyUp,\n onFocus,\n onFocusChange,\n onBlur,\n selectionManager = state.selectionManager\n } = props;\n\n let isTrigger = !!hasPopup;\n let isTriggerExpanded = isTrigger && props['aria-expanded'] === 'true';\n let isDisabled = props.isDisabled ?? selectionManager.isDisabled(key);\n let isSelected = props.isSelected ?? selectionManager.isSelected(key);\n let data = menuData.get(state)!;\n let item = state.collection.getItem(key);\n let onClose = props.onClose || data.onClose;\n let router = useRouter();\n let performAction = () => {\n if (isTrigger) {\n return;\n }\n\n if (item?.props?.onAction) {\n item.props.onAction();\n } else if (props.onAction) {\n props.onAction(key);\n }\n\n if (data.onAction) {\n // Must reassign to variable otherwise `this` binding gets messed up. Something to do with WeakMap.\n let onAction = data.onAction;\n onAction(key);\n }\n };\n\n let role = 'menuitem';\n if (!isTrigger) {\n if (selectionManager.selectionMode === 'single') {\n role = 'menuitemradio';\n } else if (selectionManager.selectionMode === 'multiple') {\n role = 'menuitemcheckbox';\n }\n }\n\n let labelId = useSlotId();\n let descriptionId = useSlotId();\n let keyboardId = useSlotId();\n\n let ariaProps = {\n id,\n 'aria-disabled': isDisabled || undefined,\n role,\n 'aria-label': props['aria-label'],\n 'aria-labelledby': labelId,\n 'aria-describedby': [descriptionId, keyboardId].filter(Boolean).join(' ') || undefined,\n 'aria-controls': props['aria-controls'],\n 'aria-haspopup': hasPopup,\n 'aria-expanded': props['aria-expanded']\n };\n\n if (selectionManager.selectionMode !== 'none' && !isTrigger) {\n ariaProps['aria-checked'] = isSelected;\n }\n\n if (isVirtualized) {\n ariaProps['aria-posinset'] = item?.index;\n ariaProps['aria-setsize'] = getItemCount(state.collection);\n }\n\n let isPressedRef = useRef(false);\n let onPressChange = (isPressed: boolean) => {\n pressChangeProp?.(isPressed);\n isPressedRef.current = isPressed;\n };\n\n let interaction = useRef<{pointerType: string, key?: string} | null>(null);\n let onPressUp = (e: PressEvent) => {\n if (e.pointerType !== 'keyboard') {\n interaction.current = {pointerType: e.pointerType};\n }\n\n // If interacting with mouse, allow the user to mouse down on the trigger button,\n // drag, and release over an item (matching native behavior).\n if (e.pointerType === 'mouse') {\n if (!isPressedRef.current) {\n (e.target as HTMLElement).click();\n }\n }\n\n pressUpProp?.(e);\n };\n\n let onClick = (e: MouseEvent<FocusableElement>) => {\n onClickProp?.(e);\n performAction();\n handleLinkClick(e, router, item!.props.href, item?.props.routerOptions);\n\n let shouldClose = interaction.current?.pointerType === 'keyboard'\n // Always close when pressing Enter key, or if item is not selectable.\n ? interaction.current?.key === 'Enter' || selectionManager.selectionMode === 'none' || selectionManager.isLink(key)\n // Close except if multi-select is enabled.\n : selectionManager.selectionMode !== 'multiple' || selectionManager.isLink(key);\n \n shouldClose = closeOnSelect ?? shouldClose;\n if (onClose && !isTrigger && shouldClose) {\n onClose();\n }\n\n interaction.current = null;\n };\n\n let {itemProps, isFocused} = useSelectableItem({\n id,\n selectionManager: selectionManager,\n key,\n ref,\n shouldSelectOnPressUp: true,\n allowsDifferentPressOrigin: true,\n // Disable all handling of links in useSelectable item\n // because we handle it ourselves. The behavior of menus\n // is slightly different from other collections because\n // actions are performed on key down rather than key up.\n linkBehavior: 'none',\n shouldUseVirtualFocus: data.shouldUseVirtualFocus\n });\n\n let {pressProps, isPressed} = usePress({\n onPressStart,\n onPress,\n onPressUp,\n onPressChange,\n onPressEnd,\n isDisabled\n });\n let {hoverProps} = useHover({\n isDisabled,\n onHoverStart(e) {\n // Hovering over an already expanded sub dialog trigger should keep focus in the dialog.\n if (!isFocusVisible() && !(isTriggerExpanded && hasPopup)) {\n selectionManager.setFocused(true);\n selectionManager.setFocusedKey(key);\n }\n hoverStartProp?.(e);\n },\n onHoverChange,\n onHoverEnd\n });\n\n let {keyboardProps} = useKeyboard({\n onKeyDown: (e) => {\n // Ignore repeating events, which may have started on the menu trigger before moving\n // focus to the menu item. We want to wait for a second complete key press sequence.\n if (e.repeat) {\n e.continuePropagation();\n return;\n }\n\n switch (e.key) {\n case ' ':\n interaction.current = {pointerType: 'keyboard', key: ' '};\n (e.target as HTMLElement).click();\n break;\n case 'Enter':\n interaction.current = {pointerType: 'keyboard', key: 'Enter'};\n\n // Trigger click unless this is a link. Links trigger click natively.\n if ((e.target as HTMLElement).tagName !== 'A') {\n (e.target as HTMLElement).click();\n }\n break;\n default:\n if (!isTrigger) {\n e.continuePropagation();\n }\n\n onKeyDown?.(e);\n break;\n }\n },\n onKeyUp\n });\n\n let {focusProps} = useFocus({onBlur, onFocus, onFocusChange});\n let domProps = filterDOMProps(item?.props);\n delete domProps.id;\n let linkProps = useLinkProps(item?.props);\n\n return {\n menuItemProps: {\n ...ariaProps,\n ...mergeProps(\n domProps,\n linkProps,\n isTrigger \n ? {onFocus: itemProps.onFocus, 'data-collection': itemProps['data-collection'], 'data-key': itemProps['data-key']} \n : itemProps,\n pressProps,\n hoverProps,\n keyboardProps,\n focusProps,\n // Prevent DOM focus from moving on mouse down when using virtual focus or this is a submenu/subdialog trigger.\n data.shouldUseVirtualFocus || isTrigger ? {onMouseDown: e => e.preventDefault()} : undefined,\n isDisabled ? undefined : {onClick}\n ),\n // If a submenu is expanded, set the tabIndex to -1 so that shift tabbing goes out of the menu instead of the parent menu item.\n tabIndex: itemProps.tabIndex != null && isTriggerExpanded && !data.shouldUseVirtualFocus ? -1 : itemProps.tabIndex\n },\n labelProps: {\n id: labelId\n },\n descriptionProps: {\n id: descriptionId\n },\n keyboardShortcutProps: {\n id: keyboardId\n },\n isFocused,\n isFocusVisible: isFocused && selectionManager.isFocused && isFocusVisible() && !isTriggerExpanded,\n isSelected,\n isPressed,\n isDisabled\n };\n}\n"],"names":[],"version":3,"file":"useMenuItem.module.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-aria/menu/src/useMenuItem.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {DOMAttributes, DOMProps, FocusableElement, FocusEvents, HoverEvents, Key, KeyboardEvents, PressEvent, PressEvents, RefObject} from '@react-types/shared';\nimport {filterDOMProps, handleLinkClick, mergeProps, useLinkProps, useRouter, useSlotId} from '@react-aria/utils';\nimport {getItemCount} from '@react-stately/collections';\nimport {isFocusVisible, useFocusable, useHover, useKeyboard, usePress} from '@react-aria/interactions';\nimport {menuData} from './utils';\nimport {MouseEvent, useRef} from 'react';\nimport {SelectionManager} from '@react-stately/selection';\nimport {TreeState} from '@react-stately/tree';\nimport {useSelectableItem} from '@react-aria/selection';\n\nexport interface MenuItemAria {\n /** Props for the menu item element. */\n menuItemProps: DOMAttributes,\n\n /** Props for the main text element inside the menu item. */\n labelProps: DOMAttributes,\n\n /** Props for the description text element inside the menu item, if any. */\n descriptionProps: DOMAttributes,\n\n /** Props for the keyboard shortcut text element inside the item, if any. */\n keyboardShortcutProps: DOMAttributes,\n\n /** Whether the item is currently focused. */\n isFocused: boolean,\n /** Whether the item is keyboard focused. */\n isFocusVisible: boolean,\n /** Whether the item is currently selected. */\n isSelected: boolean,\n /** Whether the item is currently in a pressed state. */\n isPressed: boolean,\n /** Whether the item is disabled. */\n isDisabled: boolean\n}\n\nexport interface AriaMenuItemProps extends DOMProps, PressEvents, HoverEvents, KeyboardEvents, FocusEvents {\n /**\n * Whether the menu item is disabled.\n * @deprecated - pass disabledKeys to useTreeState instead.\n */\n isDisabled?: boolean,\n\n /**\n * Whether the menu item is selected.\n * @deprecated - pass selectedKeys to useTreeState instead.\n */\n isSelected?: boolean,\n\n /** A screen reader only label for the menu item. */\n 'aria-label'?: string,\n\n /** The unique key for the menu item. */\n key: Key,\n\n /**\n * Handler that is called when the menu should close after selecting an item.\n * @deprecated - pass to the menu instead.\n */\n onClose?: () => void,\n\n /**\n * Whether the menu should close when the menu item is selected.\n * @deprecated - use shouldCloseOnSelect instead.\n */\n closeOnSelect?: boolean,\n\n /** Whether the menu should close when the menu item is selected. */\n shouldCloseOnSelect?: boolean,\n\n /** Whether the menu item is contained in a virtual scrolling menu. */\n isVirtualized?: boolean,\n\n /**\n * Handler that is called when the user activates the item.\n * @deprecated - pass to the menu instead.\n */\n onAction?: (key: Key) => void,\n\n /** What kind of popup the item opens. */\n 'aria-haspopup'?: 'menu' | 'dialog',\n\n /** Indicates whether the menu item's popup element is expanded or collapsed. */\n 'aria-expanded'?: boolean | 'true' | 'false',\n\n /** Identifies the menu item's popup element whose contents or presence is controlled by the menu item. */\n 'aria-controls'?: string,\n\n /** Override of the selection manager. By default, `state.selectionManager` is used. */\n selectionManager?: SelectionManager\n}\n\n/**\n * Provides the behavior and accessibility implementation for an item in a menu.\n * See `useMenu` for more details about menus.\n * @param props - Props for the item.\n * @param state - State for the menu, as returned by `useTreeState`.\n */\nexport function useMenuItem<T>(props: AriaMenuItemProps, state: TreeState<T>, ref: RefObject<FocusableElement | null>): MenuItemAria {\n let {\n id,\n key,\n closeOnSelect,\n shouldCloseOnSelect,\n isVirtualized,\n 'aria-haspopup': hasPopup,\n onPressStart,\n onPressUp: pressUpProp,\n onPress,\n onPressChange: pressChangeProp,\n onPressEnd,\n onClick: onClickProp,\n onHoverStart: hoverStartProp,\n onHoverChange,\n onHoverEnd,\n onKeyDown,\n onKeyUp,\n onFocus,\n onFocusChange,\n onBlur,\n selectionManager = state.selectionManager\n } = props;\n\n let isTrigger = !!hasPopup;\n let isTriggerExpanded = isTrigger && props['aria-expanded'] === 'true';\n let isDisabled = props.isDisabled ?? selectionManager.isDisabled(key);\n let isSelected = props.isSelected ?? selectionManager.isSelected(key);\n let data = menuData.get(state)!;\n let item = state.collection.getItem(key);\n let onClose = props.onClose || data.onClose;\n let router = useRouter();\n let performAction = () => {\n if (isTrigger) {\n return;\n }\n\n if (item?.props?.onAction) {\n item.props.onAction();\n } else if (props.onAction) {\n props.onAction(key);\n }\n\n if (data.onAction) {\n // Must reassign to variable otherwise `this` binding gets messed up. Something to do with WeakMap.\n let onAction = data.onAction;\n onAction(key);\n }\n };\n\n let role = 'menuitem';\n if (!isTrigger) {\n if (selectionManager.selectionMode === 'single') {\n role = 'menuitemradio';\n } else if (selectionManager.selectionMode === 'multiple') {\n role = 'menuitemcheckbox';\n }\n }\n\n let labelId = useSlotId();\n let descriptionId = useSlotId();\n let keyboardId = useSlotId();\n\n let ariaProps = {\n id,\n 'aria-disabled': isDisabled || undefined,\n role,\n 'aria-label': props['aria-label'],\n 'aria-labelledby': labelId,\n 'aria-describedby': [descriptionId, keyboardId].filter(Boolean).join(' ') || undefined,\n 'aria-controls': props['aria-controls'],\n 'aria-haspopup': hasPopup,\n 'aria-expanded': props['aria-expanded']\n };\n\n if (selectionManager.selectionMode !== 'none' && !isTrigger) {\n ariaProps['aria-checked'] = isSelected;\n }\n\n if (isVirtualized) {\n ariaProps['aria-posinset'] = item?.index;\n ariaProps['aria-setsize'] = getItemCount(state.collection);\n }\n\n let isPressedRef = useRef(false);\n let onPressChange = (isPressed: boolean) => {\n pressChangeProp?.(isPressed);\n isPressedRef.current = isPressed;\n };\n\n let interaction = useRef<{pointerType: string, key?: string} | null>(null);\n let onPressUp = (e: PressEvent) => {\n if (e.pointerType !== 'keyboard') {\n interaction.current = {pointerType: e.pointerType};\n }\n\n // If interacting with mouse, allow the user to mouse down on the trigger button,\n // drag, and release over an item (matching native behavior).\n if (e.pointerType === 'mouse') {\n if (!isPressedRef.current) {\n (e.target as HTMLElement).click();\n }\n }\n\n pressUpProp?.(e);\n };\n\n let onClick = (e: MouseEvent<FocusableElement>) => {\n onClickProp?.(e);\n performAction();\n handleLinkClick(e, router, item!.props.href, item?.props.routerOptions);\n\n let shouldClose = interaction.current?.pointerType === 'keyboard'\n // Always close when pressing Enter key, or if item is not selectable.\n ? interaction.current?.key === 'Enter' || selectionManager.selectionMode === 'none' || selectionManager.isLink(key)\n // Close except if multi-select is enabled.\n : selectionManager.selectionMode !== 'multiple' || selectionManager.isLink(key);\n\n\n shouldClose = shouldCloseOnSelect ?? closeOnSelect ?? shouldClose;\n\n if (onClose && !isTrigger && shouldClose) {\n onClose();\n }\n\n interaction.current = null;\n };\n\n let {itemProps, isFocused} = useSelectableItem({\n id,\n selectionManager: selectionManager,\n key,\n ref,\n shouldSelectOnPressUp: true,\n allowsDifferentPressOrigin: true,\n // Disable all handling of links in useSelectable item\n // because we handle it ourselves. The behavior of menus\n // is slightly different from other collections because\n // actions are performed on key down rather than key up.\n linkBehavior: 'none',\n shouldUseVirtualFocus: data.shouldUseVirtualFocus\n });\n\n let {pressProps, isPressed} = usePress({\n onPressStart,\n onPress,\n onPressUp,\n onPressChange,\n onPressEnd,\n isDisabled\n });\n let {hoverProps} = useHover({\n isDisabled,\n onHoverStart(e) {\n // Hovering over an already expanded sub dialog trigger should keep focus in the dialog.\n if (!isFocusVisible() && !(isTriggerExpanded && hasPopup)) {\n selectionManager.setFocused(true);\n selectionManager.setFocusedKey(key);\n }\n hoverStartProp?.(e);\n },\n onHoverChange,\n onHoverEnd\n });\n\n let {keyboardProps} = useKeyboard({\n onKeyDown: (e) => {\n // Ignore repeating events, which may have started on the menu trigger before moving\n // focus to the menu item. We want to wait for a second complete key press sequence.\n if (e.repeat) {\n e.continuePropagation();\n return;\n }\n\n switch (e.key) {\n case ' ':\n interaction.current = {pointerType: 'keyboard', key: ' '};\n (e.target as HTMLElement).click();\n break;\n case 'Enter':\n interaction.current = {pointerType: 'keyboard', key: 'Enter'};\n\n // Trigger click unless this is a link. Links trigger click natively.\n if ((e.target as HTMLElement).tagName !== 'A') {\n (e.target as HTMLElement).click();\n }\n break;\n default:\n if (!isTrigger) {\n e.continuePropagation();\n }\n\n onKeyDown?.(e);\n break;\n }\n },\n onKeyUp\n });\n\n let {focusableProps} = useFocusable({onBlur, onFocus, onFocusChange}, ref);\n let domProps = filterDOMProps(item?.props);\n delete domProps.id;\n let linkProps = useLinkProps(item?.props);\n\n return {\n menuItemProps: {\n ...ariaProps,\n ...mergeProps(\n domProps,\n linkProps,\n isTrigger\n ? {onFocus: itemProps.onFocus, 'data-collection': itemProps['data-collection'], 'data-key': itemProps['data-key']}\n : itemProps,\n pressProps,\n hoverProps,\n keyboardProps,\n focusableProps,\n // Prevent DOM focus from moving on mouse down when using virtual focus or this is a submenu/subdialog trigger.\n data.shouldUseVirtualFocus || isTrigger ? {onMouseDown: e => e.preventDefault()} : undefined,\n isDisabled ? undefined : {onClick}\n ),\n // If a submenu is expanded, set the tabIndex to -1 so that shift tabbing goes out of the menu instead of the parent menu item.\n tabIndex: itemProps.tabIndex != null && isTriggerExpanded && !data.shouldUseVirtualFocus ? -1 : itemProps.tabIndex\n },\n labelProps: {\n id: labelId\n },\n descriptionProps: {\n id: descriptionId\n },\n keyboardShortcutProps: {\n id: keyboardId\n },\n isFocused,\n isFocusVisible: isFocused && selectionManager.isFocused && isFocusVisible() && !isTriggerExpanded,\n isSelected,\n isPressed,\n isDisabled\n };\n}\n"],"names":[],"version":3,"file":"useMenuItem.module.js.map"}
@@ -1,5 +1,5 @@
1
- var $g3RPq$react = require("react");
2
1
  var $g3RPq$reactariautils = require("@react-aria/utils");
2
+ var $g3RPq$react = require("react");
3
3
  var $g3RPq$reactariainteractions = require("@react-aria/interactions");
4
4
 
5
5
 
@@ -53,7 +53,7 @@ function $62347d8c4183e713$export$85ec83e04c95f50a(options) {
53
53
  menuRef,
54
54
  preventPointerEvents
55
55
  ]);
56
- (0, $g3RPq$react.useEffect)(()=>{
56
+ (0, $g3RPq$reactariautils.useLayoutEffect)(()=>{
57
57
  let submenu = submenuRef.current;
58
58
  let menu = menuRef.current;
59
59
  if (isDisabled || !submenu || !isOpen || modality !== 'pointer' || !menu) {
@@ -111,7 +111,7 @@ function $62347d8c4183e713$export$85ec83e04c95f50a(options) {
111
111
  // Fire a pointerover event to trigger the menu to close.
112
112
  // Wait until pointer-events:none is no longer applied
113
113
  let target = document.elementFromPoint(mouseX, mouseY);
114
- if (target && menu.contains(target)) target.dispatchEvent(new PointerEvent('pointerover', {
114
+ if (target && (0, $g3RPq$reactariautils.nodeContains)(menu, target)) target.dispatchEvent(new PointerEvent('pointerover', {
115
115
  bubbles: true,
116
116
  cancelable: true
117
117
  }));
@@ -135,7 +135,6 @@ function $62347d8c4183e713$export$85ec83e04c95f50a(options) {
135
135
  menuRef,
136
136
  modality,
137
137
  setPreventPointerEvents,
138
- onPointerDown,
139
138
  submenuRef
140
139
  ]);
141
140
  }
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-aria/menu/src/useSafelyMouseToSubmenu.ts"],"sourcesContent":["\nimport {RefObject} from '@react-types/shared';\nimport {useEffect, useRef, useState} from 'react';\nimport {useEffectEvent, useResizeObserver} from '@react-aria/utils';\nimport {useInteractionModality} from '@react-aria/interactions';\n\ninterface SafelyMouseToSubmenuOptions {\n /** Ref for the parent menu. */\n menuRef: RefObject<Element | null>,\n /** Ref for the submenu. */\n submenuRef: RefObject<Element | null>,\n /** Whether the submenu is open. */\n isOpen: boolean,\n /** Whether this feature is disabled. */\n isDisabled?: boolean\n}\n\nconst ALLOWED_INVALID_MOVEMENTS = 2;\nconst THROTTLE_TIME = 50;\nconst TIMEOUT_TIME = 1000;\nconst ANGLE_PADDING = Math.PI / 12; // 15°\n\n/**\n * Allows the user to move their pointer to the submenu without it closing when their mouse leaves the trigger element.\n * Prevents pointer events from going to the underlying menu if the user is moving their pointer towards the sub-menu.\n */\nexport function useSafelyMouseToSubmenu(options: SafelyMouseToSubmenuOptions): void {\n let {menuRef, submenuRef, isOpen, isDisabled} = options;\n let prevPointerPos = useRef<{x: number, y: number} | undefined>(undefined);\n let submenuRect = useRef<DOMRect | undefined>(undefined);\n let lastProcessedTime = useRef<number>(0);\n let timeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let autoCloseTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let submenuSide = useRef<'left' | 'right' | undefined>(undefined);\n let movementsTowardsSubmenuCount = useRef<number>(2);\n let [preventPointerEvents, setPreventPointerEvents] = useState(false);\n\n let updateSubmenuRect = () => {\n if (submenuRef.current) {\n submenuRect.current = submenuRef.current.getBoundingClientRect();\n submenuSide.current = undefined;\n }\n };\n useResizeObserver({ref: submenuRef, onResize: updateSubmenuRect});\n\n let reset = () => {\n setPreventPointerEvents(false);\n movementsTowardsSubmenuCount.current = ALLOWED_INVALID_MOVEMENTS;\n prevPointerPos.current = undefined;\n };\n\n let modality = useInteractionModality();\n\n // Prevent mouse down over safe triangle. Clicking while pointer-events: none is applied\n // will cause focus to move unexpectedly since it will go to an element behind the menu.\n let onPointerDown = useEffectEvent((e: PointerEvent) => {\n if (preventPointerEvents) {\n e.preventDefault();\n }\n });\n\n useEffect(() => {\n if (preventPointerEvents && menuRef.current) {\n (menuRef.current as HTMLElement).style.pointerEvents = 'none';\n } else {\n (menuRef.current as HTMLElement).style.pointerEvents = '';\n }\n }, [menuRef, preventPointerEvents]);\n\n useEffect(() => {\n let submenu = submenuRef.current;\n let menu = menuRef.current;\n\n if (isDisabled || !submenu || !isOpen || modality !== 'pointer' || !menu) {\n reset();\n return;\n }\n submenuRect.current = submenu.getBoundingClientRect();\n\n let onPointerMove = (e: PointerEvent) => {\n if (e.pointerType === 'touch' || e.pointerType === 'pen') {\n return;\n }\n\n let currentTime = Date.now();\n\n // Throttle\n if (currentTime - lastProcessedTime.current < THROTTLE_TIME) {\n return;\n }\n clearTimeout(timeout.current);\n clearTimeout(autoCloseTimeout.current);\n\n let {clientX: mouseX, clientY: mouseY} = e;\n\n if (!prevPointerPos.current) {\n prevPointerPos.current = {x: mouseX, y: mouseY};\n return;\n }\n\n if (!submenuRect.current) {\n return;\n }\n\n if (!submenuSide.current) {\n submenuSide.current = mouseX > submenuRect.current.right ? 'left' : 'right';\n }\n\n // Pointer is outside of parent menu\n if (mouseX < menu.getBoundingClientRect().left || mouseX > menu.getBoundingClientRect().right || mouseY < menu.getBoundingClientRect().top || mouseY > menu.getBoundingClientRect().bottom) {\n reset();\n return;\n }\n\n /* Check if pointer is moving towards submenu.\n Uses the 2-argument arctangent (https://en.wikipedia.org/wiki/Atan2) to calculate:\n - angle between previous pointer and top of submenu\n - angle between previous pointer and bottom of submenu\n - angle between previous pointer and current pointer (delta)\n If the pointer delta angle value is between the top and bottom angle values, we know the pointer is moving towards the submenu.\n */\n let prevMouseX = prevPointerPos.current.x;\n let prevMouseY = prevPointerPos.current.y;\n let toSubmenuX = submenuSide.current === 'right' ? submenuRect.current.left - prevMouseX : prevMouseX - submenuRect.current.right;\n let angleTop = Math.atan2(prevMouseY - submenuRect.current.top, toSubmenuX) + ANGLE_PADDING;\n let angleBottom = Math.atan2(prevMouseY - submenuRect.current.bottom, toSubmenuX) - ANGLE_PADDING;\n let anglePointer = Math.atan2(prevMouseY - mouseY, (submenuSide.current === 'left' ? -(mouseX - prevMouseX) : mouseX - prevMouseX));\n let isMovingTowardsSubmenu = anglePointer < angleTop && anglePointer > angleBottom;\n\n movementsTowardsSubmenuCount.current = isMovingTowardsSubmenu ?\n Math.min(movementsTowardsSubmenuCount.current + 1, ALLOWED_INVALID_MOVEMENTS) :\n Math.max(movementsTowardsSubmenuCount.current - 1, 0);\n\n if (movementsTowardsSubmenuCount.current >= ALLOWED_INVALID_MOVEMENTS) {\n setPreventPointerEvents(true);\n } else {\n setPreventPointerEvents(false);\n }\n\n lastProcessedTime.current = currentTime;\n prevPointerPos.current = {x: mouseX, y: mouseY};\n\n // If the pointer is moving towards the submenu, start a timeout to close if no other movements are made after 500ms.\n if (isMovingTowardsSubmenu) {\n timeout.current = setTimeout(() => {\n reset();\n autoCloseTimeout.current = setTimeout(() => {\n // Fire a pointerover event to trigger the menu to close.\n // Wait until pointer-events:none is no longer applied\n let target = document.elementFromPoint(mouseX, mouseY);\n if (target && menu.contains(target)) {\n target.dispatchEvent(new PointerEvent('pointerover', {bubbles: true, cancelable: true}));\n }\n }, 100);\n }, TIMEOUT_TIME);\n }\n };\n\n window.addEventListener('pointermove', onPointerMove);\n\n // Prevent pointer down over the safe triangle. See above comment.\n // Do not enable in tests, because JSDom doesn't do hit testing.\n if (process.env.NODE_ENV !== 'test') {\n window.addEventListener('pointerdown', onPointerDown, true);\n }\n\n return () => {\n window.removeEventListener('pointermove', onPointerMove);\n if (process.env.NODE_ENV !== 'test') {\n window.removeEventListener('pointerdown', onPointerDown, true);\n }\n clearTimeout(timeout.current);\n clearTimeout(autoCloseTimeout.current);\n movementsTowardsSubmenuCount.current = ALLOWED_INVALID_MOVEMENTS;\n };\n\n }, [isDisabled, isOpen, menuRef, modality, setPreventPointerEvents, onPointerDown, submenuRef]);\n}\n"],"names":[],"version":3,"file":"useSafelyMouseToSubmenu.main.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-aria/menu/src/useSafelyMouseToSubmenu.ts"],"sourcesContent":["\nimport {nodeContains, useEffectEvent, useLayoutEffect, useResizeObserver} from '@react-aria/utils';\nimport {RefObject} from '@react-types/shared';\nimport {useEffect, useRef, useState} from 'react';\nimport {useInteractionModality} from '@react-aria/interactions';\n\ninterface SafelyMouseToSubmenuOptions {\n /** Ref for the parent menu. */\n menuRef: RefObject<Element | null>,\n /** Ref for the submenu. */\n submenuRef: RefObject<Element | null>,\n /** Whether the submenu is open. */\n isOpen: boolean,\n /** Whether this feature is disabled. */\n isDisabled?: boolean\n}\n\nconst ALLOWED_INVALID_MOVEMENTS = 2;\nconst THROTTLE_TIME = 50;\nconst TIMEOUT_TIME = 1000;\nconst ANGLE_PADDING = Math.PI / 12; // 15°\n\n/**\n * Allows the user to move their pointer to the submenu without it closing when their mouse leaves the trigger element.\n * Prevents pointer events from going to the underlying menu if the user is moving their pointer towards the sub-menu.\n */\nexport function useSafelyMouseToSubmenu(options: SafelyMouseToSubmenuOptions): void {\n let {menuRef, submenuRef, isOpen, isDisabled} = options;\n let prevPointerPos = useRef<{x: number, y: number} | undefined>(undefined);\n let submenuRect = useRef<DOMRect | undefined>(undefined);\n let lastProcessedTime = useRef<number>(0);\n let timeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let autoCloseTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let submenuSide = useRef<'left' | 'right' | undefined>(undefined);\n let movementsTowardsSubmenuCount = useRef<number>(2);\n let [preventPointerEvents, setPreventPointerEvents] = useState(false);\n\n let updateSubmenuRect = () => {\n if (submenuRef.current) {\n submenuRect.current = submenuRef.current.getBoundingClientRect();\n submenuSide.current = undefined;\n }\n };\n useResizeObserver({ref: submenuRef, onResize: updateSubmenuRect});\n\n let reset = () => {\n setPreventPointerEvents(false);\n movementsTowardsSubmenuCount.current = ALLOWED_INVALID_MOVEMENTS;\n prevPointerPos.current = undefined;\n };\n\n let modality = useInteractionModality();\n\n // Prevent mouse down over safe triangle. Clicking while pointer-events: none is applied\n // will cause focus to move unexpectedly since it will go to an element behind the menu.\n let onPointerDown = useEffectEvent((e: PointerEvent) => {\n if (preventPointerEvents) {\n e.preventDefault();\n }\n });\n\n useEffect(() => {\n if (preventPointerEvents && menuRef.current) {\n (menuRef.current as HTMLElement).style.pointerEvents = 'none';\n } else {\n (menuRef.current as HTMLElement).style.pointerEvents = '';\n }\n }, [menuRef, preventPointerEvents]);\n\n useLayoutEffect(() => {\n let submenu = submenuRef.current;\n let menu = menuRef.current;\n\n if (isDisabled || !submenu || !isOpen || modality !== 'pointer' || !menu) {\n reset();\n return;\n }\n submenuRect.current = submenu.getBoundingClientRect();\n\n let onPointerMove = (e: PointerEvent) => {\n if (e.pointerType === 'touch' || e.pointerType === 'pen') {\n return;\n }\n\n let currentTime = Date.now();\n\n // Throttle\n if (currentTime - lastProcessedTime.current < THROTTLE_TIME) {\n return;\n }\n clearTimeout(timeout.current);\n clearTimeout(autoCloseTimeout.current);\n\n let {clientX: mouseX, clientY: mouseY} = e;\n\n if (!prevPointerPos.current) {\n prevPointerPos.current = {x: mouseX, y: mouseY};\n return;\n }\n\n if (!submenuRect.current) {\n return;\n }\n\n if (!submenuSide.current) {\n submenuSide.current = mouseX > submenuRect.current.right ? 'left' : 'right';\n }\n\n // Pointer is outside of parent menu\n if (mouseX < menu.getBoundingClientRect().left || mouseX > menu.getBoundingClientRect().right || mouseY < menu.getBoundingClientRect().top || mouseY > menu.getBoundingClientRect().bottom) {\n reset();\n return;\n }\n\n /* Check if pointer is moving towards submenu.\n Uses the 2-argument arctangent (https://en.wikipedia.org/wiki/Atan2) to calculate:\n - angle between previous pointer and top of submenu\n - angle between previous pointer and bottom of submenu\n - angle between previous pointer and current pointer (delta)\n If the pointer delta angle value is between the top and bottom angle values, we know the pointer is moving towards the submenu.\n */\n let prevMouseX = prevPointerPos.current.x;\n let prevMouseY = prevPointerPos.current.y;\n let toSubmenuX = submenuSide.current === 'right' ? submenuRect.current.left - prevMouseX : prevMouseX - submenuRect.current.right;\n let angleTop = Math.atan2(prevMouseY - submenuRect.current.top, toSubmenuX) + ANGLE_PADDING;\n let angleBottom = Math.atan2(prevMouseY - submenuRect.current.bottom, toSubmenuX) - ANGLE_PADDING;\n let anglePointer = Math.atan2(prevMouseY - mouseY, (submenuSide.current === 'left' ? -(mouseX - prevMouseX) : mouseX - prevMouseX));\n let isMovingTowardsSubmenu = anglePointer < angleTop && anglePointer > angleBottom;\n\n movementsTowardsSubmenuCount.current = isMovingTowardsSubmenu ?\n Math.min(movementsTowardsSubmenuCount.current + 1, ALLOWED_INVALID_MOVEMENTS) :\n Math.max(movementsTowardsSubmenuCount.current - 1, 0);\n\n if (movementsTowardsSubmenuCount.current >= ALLOWED_INVALID_MOVEMENTS) {\n setPreventPointerEvents(true);\n } else {\n setPreventPointerEvents(false);\n }\n\n lastProcessedTime.current = currentTime;\n prevPointerPos.current = {x: mouseX, y: mouseY};\n\n // If the pointer is moving towards the submenu, start a timeout to close if no other movements are made after 500ms.\n if (isMovingTowardsSubmenu) {\n timeout.current = setTimeout(() => {\n reset();\n autoCloseTimeout.current = setTimeout(() => {\n // Fire a pointerover event to trigger the menu to close.\n // Wait until pointer-events:none is no longer applied\n let target = document.elementFromPoint(mouseX, mouseY);\n if (target && nodeContains(menu, target)) {\n target.dispatchEvent(new PointerEvent('pointerover', {bubbles: true, cancelable: true}));\n }\n }, 100);\n }, TIMEOUT_TIME);\n }\n };\n\n window.addEventListener('pointermove', onPointerMove);\n\n // Prevent pointer down over the safe triangle. See above comment.\n // Do not enable in tests, because JSDom doesn't do hit testing.\n if (process.env.NODE_ENV !== 'test') {\n window.addEventListener('pointerdown', onPointerDown, true);\n }\n\n return () => {\n window.removeEventListener('pointermove', onPointerMove);\n if (process.env.NODE_ENV !== 'test') {\n window.removeEventListener('pointerdown', onPointerDown, true);\n }\n clearTimeout(timeout.current);\n clearTimeout(autoCloseTimeout.current);\n movementsTowardsSubmenuCount.current = ALLOWED_INVALID_MOVEMENTS;\n };\n\n }, [isDisabled, isOpen, menuRef, modality, setPreventPointerEvents, submenuRef]);\n}\n"],"names":[],"version":3,"file":"useSafelyMouseToSubmenu.main.js.map"}
@@ -1,5 +1,5 @@
1
+ import {useResizeObserver as $fUfeP$useResizeObserver, useEffectEvent as $fUfeP$useEffectEvent, useLayoutEffect as $fUfeP$useLayoutEffect, nodeContains as $fUfeP$nodeContains} from "@react-aria/utils";
1
2
  import {useRef as $fUfeP$useRef, useState as $fUfeP$useState, useEffect as $fUfeP$useEffect} from "react";
2
- import {useResizeObserver as $fUfeP$useResizeObserver, useEffectEvent as $fUfeP$useEffectEvent} from "@react-aria/utils";
3
3
  import {useInteractionModality as $fUfeP$useInteractionModality} from "@react-aria/interactions";
4
4
 
5
5
 
@@ -47,7 +47,7 @@ function $d275435c250248f8$export$85ec83e04c95f50a(options) {
47
47
  menuRef,
48
48
  preventPointerEvents
49
49
  ]);
50
- (0, $fUfeP$useEffect)(()=>{
50
+ (0, $fUfeP$useLayoutEffect)(()=>{
51
51
  let submenu = submenuRef.current;
52
52
  let menu = menuRef.current;
53
53
  if (isDisabled || !submenu || !isOpen || modality !== 'pointer' || !menu) {
@@ -105,7 +105,7 @@ function $d275435c250248f8$export$85ec83e04c95f50a(options) {
105
105
  // Fire a pointerover event to trigger the menu to close.
106
106
  // Wait until pointer-events:none is no longer applied
107
107
  let target = document.elementFromPoint(mouseX, mouseY);
108
- if (target && menu.contains(target)) target.dispatchEvent(new PointerEvent('pointerover', {
108
+ if (target && (0, $fUfeP$nodeContains)(menu, target)) target.dispatchEvent(new PointerEvent('pointerover', {
109
109
  bubbles: true,
110
110
  cancelable: true
111
111
  }));
@@ -129,7 +129,6 @@ function $d275435c250248f8$export$85ec83e04c95f50a(options) {
129
129
  menuRef,
130
130
  modality,
131
131
  setPreventPointerEvents,
132
- onPointerDown,
133
132
  submenuRef
134
133
  ]);
135
134
  }
@@ -1,5 +1,5 @@
1
+ import {useResizeObserver as $fUfeP$useResizeObserver, useEffectEvent as $fUfeP$useEffectEvent, useLayoutEffect as $fUfeP$useLayoutEffect, nodeContains as $fUfeP$nodeContains} from "@react-aria/utils";
1
2
  import {useRef as $fUfeP$useRef, useState as $fUfeP$useState, useEffect as $fUfeP$useEffect} from "react";
2
- import {useResizeObserver as $fUfeP$useResizeObserver, useEffectEvent as $fUfeP$useEffectEvent} from "@react-aria/utils";
3
3
  import {useInteractionModality as $fUfeP$useInteractionModality} from "@react-aria/interactions";
4
4
 
5
5
 
@@ -47,7 +47,7 @@ function $d275435c250248f8$export$85ec83e04c95f50a(options) {
47
47
  menuRef,
48
48
  preventPointerEvents
49
49
  ]);
50
- (0, $fUfeP$useEffect)(()=>{
50
+ (0, $fUfeP$useLayoutEffect)(()=>{
51
51
  let submenu = submenuRef.current;
52
52
  let menu = menuRef.current;
53
53
  if (isDisabled || !submenu || !isOpen || modality !== 'pointer' || !menu) {
@@ -105,7 +105,7 @@ function $d275435c250248f8$export$85ec83e04c95f50a(options) {
105
105
  // Fire a pointerover event to trigger the menu to close.
106
106
  // Wait until pointer-events:none is no longer applied
107
107
  let target = document.elementFromPoint(mouseX, mouseY);
108
- if (target && menu.contains(target)) target.dispatchEvent(new PointerEvent('pointerover', {
108
+ if (target && (0, $fUfeP$nodeContains)(menu, target)) target.dispatchEvent(new PointerEvent('pointerover', {
109
109
  bubbles: true,
110
110
  cancelable: true
111
111
  }));
@@ -129,7 +129,6 @@ function $d275435c250248f8$export$85ec83e04c95f50a(options) {
129
129
  menuRef,
130
130
  modality,
131
131
  setPreventPointerEvents,
132
- onPointerDown,
133
132
  submenuRef
134
133
  ]);
135
134
  }
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-aria/menu/src/useSafelyMouseToSubmenu.ts"],"sourcesContent":["\nimport {RefObject} from '@react-types/shared';\nimport {useEffect, useRef, useState} from 'react';\nimport {useEffectEvent, useResizeObserver} from '@react-aria/utils';\nimport {useInteractionModality} from '@react-aria/interactions';\n\ninterface SafelyMouseToSubmenuOptions {\n /** Ref for the parent menu. */\n menuRef: RefObject<Element | null>,\n /** Ref for the submenu. */\n submenuRef: RefObject<Element | null>,\n /** Whether the submenu is open. */\n isOpen: boolean,\n /** Whether this feature is disabled. */\n isDisabled?: boolean\n}\n\nconst ALLOWED_INVALID_MOVEMENTS = 2;\nconst THROTTLE_TIME = 50;\nconst TIMEOUT_TIME = 1000;\nconst ANGLE_PADDING = Math.PI / 12; // 15°\n\n/**\n * Allows the user to move their pointer to the submenu without it closing when their mouse leaves the trigger element.\n * Prevents pointer events from going to the underlying menu if the user is moving their pointer towards the sub-menu.\n */\nexport function useSafelyMouseToSubmenu(options: SafelyMouseToSubmenuOptions): void {\n let {menuRef, submenuRef, isOpen, isDisabled} = options;\n let prevPointerPos = useRef<{x: number, y: number} | undefined>(undefined);\n let submenuRect = useRef<DOMRect | undefined>(undefined);\n let lastProcessedTime = useRef<number>(0);\n let timeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let autoCloseTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let submenuSide = useRef<'left' | 'right' | undefined>(undefined);\n let movementsTowardsSubmenuCount = useRef<number>(2);\n let [preventPointerEvents, setPreventPointerEvents] = useState(false);\n\n let updateSubmenuRect = () => {\n if (submenuRef.current) {\n submenuRect.current = submenuRef.current.getBoundingClientRect();\n submenuSide.current = undefined;\n }\n };\n useResizeObserver({ref: submenuRef, onResize: updateSubmenuRect});\n\n let reset = () => {\n setPreventPointerEvents(false);\n movementsTowardsSubmenuCount.current = ALLOWED_INVALID_MOVEMENTS;\n prevPointerPos.current = undefined;\n };\n\n let modality = useInteractionModality();\n\n // Prevent mouse down over safe triangle. Clicking while pointer-events: none is applied\n // will cause focus to move unexpectedly since it will go to an element behind the menu.\n let onPointerDown = useEffectEvent((e: PointerEvent) => {\n if (preventPointerEvents) {\n e.preventDefault();\n }\n });\n\n useEffect(() => {\n if (preventPointerEvents && menuRef.current) {\n (menuRef.current as HTMLElement).style.pointerEvents = 'none';\n } else {\n (menuRef.current as HTMLElement).style.pointerEvents = '';\n }\n }, [menuRef, preventPointerEvents]);\n\n useEffect(() => {\n let submenu = submenuRef.current;\n let menu = menuRef.current;\n\n if (isDisabled || !submenu || !isOpen || modality !== 'pointer' || !menu) {\n reset();\n return;\n }\n submenuRect.current = submenu.getBoundingClientRect();\n\n let onPointerMove = (e: PointerEvent) => {\n if (e.pointerType === 'touch' || e.pointerType === 'pen') {\n return;\n }\n\n let currentTime = Date.now();\n\n // Throttle\n if (currentTime - lastProcessedTime.current < THROTTLE_TIME) {\n return;\n }\n clearTimeout(timeout.current);\n clearTimeout(autoCloseTimeout.current);\n\n let {clientX: mouseX, clientY: mouseY} = e;\n\n if (!prevPointerPos.current) {\n prevPointerPos.current = {x: mouseX, y: mouseY};\n return;\n }\n\n if (!submenuRect.current) {\n return;\n }\n\n if (!submenuSide.current) {\n submenuSide.current = mouseX > submenuRect.current.right ? 'left' : 'right';\n }\n\n // Pointer is outside of parent menu\n if (mouseX < menu.getBoundingClientRect().left || mouseX > menu.getBoundingClientRect().right || mouseY < menu.getBoundingClientRect().top || mouseY > menu.getBoundingClientRect().bottom) {\n reset();\n return;\n }\n\n /* Check if pointer is moving towards submenu.\n Uses the 2-argument arctangent (https://en.wikipedia.org/wiki/Atan2) to calculate:\n - angle between previous pointer and top of submenu\n - angle between previous pointer and bottom of submenu\n - angle between previous pointer and current pointer (delta)\n If the pointer delta angle value is between the top and bottom angle values, we know the pointer is moving towards the submenu.\n */\n let prevMouseX = prevPointerPos.current.x;\n let prevMouseY = prevPointerPos.current.y;\n let toSubmenuX = submenuSide.current === 'right' ? submenuRect.current.left - prevMouseX : prevMouseX - submenuRect.current.right;\n let angleTop = Math.atan2(prevMouseY - submenuRect.current.top, toSubmenuX) + ANGLE_PADDING;\n let angleBottom = Math.atan2(prevMouseY - submenuRect.current.bottom, toSubmenuX) - ANGLE_PADDING;\n let anglePointer = Math.atan2(prevMouseY - mouseY, (submenuSide.current === 'left' ? -(mouseX - prevMouseX) : mouseX - prevMouseX));\n let isMovingTowardsSubmenu = anglePointer < angleTop && anglePointer > angleBottom;\n\n movementsTowardsSubmenuCount.current = isMovingTowardsSubmenu ?\n Math.min(movementsTowardsSubmenuCount.current + 1, ALLOWED_INVALID_MOVEMENTS) :\n Math.max(movementsTowardsSubmenuCount.current - 1, 0);\n\n if (movementsTowardsSubmenuCount.current >= ALLOWED_INVALID_MOVEMENTS) {\n setPreventPointerEvents(true);\n } else {\n setPreventPointerEvents(false);\n }\n\n lastProcessedTime.current = currentTime;\n prevPointerPos.current = {x: mouseX, y: mouseY};\n\n // If the pointer is moving towards the submenu, start a timeout to close if no other movements are made after 500ms.\n if (isMovingTowardsSubmenu) {\n timeout.current = setTimeout(() => {\n reset();\n autoCloseTimeout.current = setTimeout(() => {\n // Fire a pointerover event to trigger the menu to close.\n // Wait until pointer-events:none is no longer applied\n let target = document.elementFromPoint(mouseX, mouseY);\n if (target && menu.contains(target)) {\n target.dispatchEvent(new PointerEvent('pointerover', {bubbles: true, cancelable: true}));\n }\n }, 100);\n }, TIMEOUT_TIME);\n }\n };\n\n window.addEventListener('pointermove', onPointerMove);\n\n // Prevent pointer down over the safe triangle. See above comment.\n // Do not enable in tests, because JSDom doesn't do hit testing.\n if (process.env.NODE_ENV !== 'test') {\n window.addEventListener('pointerdown', onPointerDown, true);\n }\n\n return () => {\n window.removeEventListener('pointermove', onPointerMove);\n if (process.env.NODE_ENV !== 'test') {\n window.removeEventListener('pointerdown', onPointerDown, true);\n }\n clearTimeout(timeout.current);\n clearTimeout(autoCloseTimeout.current);\n movementsTowardsSubmenuCount.current = ALLOWED_INVALID_MOVEMENTS;\n };\n\n }, [isDisabled, isOpen, menuRef, modality, setPreventPointerEvents, onPointerDown, submenuRef]);\n}\n"],"names":[],"version":3,"file":"useSafelyMouseToSubmenu.module.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-aria/menu/src/useSafelyMouseToSubmenu.ts"],"sourcesContent":["\nimport {nodeContains, useEffectEvent, useLayoutEffect, useResizeObserver} from '@react-aria/utils';\nimport {RefObject} from '@react-types/shared';\nimport {useEffect, useRef, useState} from 'react';\nimport {useInteractionModality} from '@react-aria/interactions';\n\ninterface SafelyMouseToSubmenuOptions {\n /** Ref for the parent menu. */\n menuRef: RefObject<Element | null>,\n /** Ref for the submenu. */\n submenuRef: RefObject<Element | null>,\n /** Whether the submenu is open. */\n isOpen: boolean,\n /** Whether this feature is disabled. */\n isDisabled?: boolean\n}\n\nconst ALLOWED_INVALID_MOVEMENTS = 2;\nconst THROTTLE_TIME = 50;\nconst TIMEOUT_TIME = 1000;\nconst ANGLE_PADDING = Math.PI / 12; // 15°\n\n/**\n * Allows the user to move their pointer to the submenu without it closing when their mouse leaves the trigger element.\n * Prevents pointer events from going to the underlying menu if the user is moving their pointer towards the sub-menu.\n */\nexport function useSafelyMouseToSubmenu(options: SafelyMouseToSubmenuOptions): void {\n let {menuRef, submenuRef, isOpen, isDisabled} = options;\n let prevPointerPos = useRef<{x: number, y: number} | undefined>(undefined);\n let submenuRect = useRef<DOMRect | undefined>(undefined);\n let lastProcessedTime = useRef<number>(0);\n let timeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let autoCloseTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let submenuSide = useRef<'left' | 'right' | undefined>(undefined);\n let movementsTowardsSubmenuCount = useRef<number>(2);\n let [preventPointerEvents, setPreventPointerEvents] = useState(false);\n\n let updateSubmenuRect = () => {\n if (submenuRef.current) {\n submenuRect.current = submenuRef.current.getBoundingClientRect();\n submenuSide.current = undefined;\n }\n };\n useResizeObserver({ref: submenuRef, onResize: updateSubmenuRect});\n\n let reset = () => {\n setPreventPointerEvents(false);\n movementsTowardsSubmenuCount.current = ALLOWED_INVALID_MOVEMENTS;\n prevPointerPos.current = undefined;\n };\n\n let modality = useInteractionModality();\n\n // Prevent mouse down over safe triangle. Clicking while pointer-events: none is applied\n // will cause focus to move unexpectedly since it will go to an element behind the menu.\n let onPointerDown = useEffectEvent((e: PointerEvent) => {\n if (preventPointerEvents) {\n e.preventDefault();\n }\n });\n\n useEffect(() => {\n if (preventPointerEvents && menuRef.current) {\n (menuRef.current as HTMLElement).style.pointerEvents = 'none';\n } else {\n (menuRef.current as HTMLElement).style.pointerEvents = '';\n }\n }, [menuRef, preventPointerEvents]);\n\n useLayoutEffect(() => {\n let submenu = submenuRef.current;\n let menu = menuRef.current;\n\n if (isDisabled || !submenu || !isOpen || modality !== 'pointer' || !menu) {\n reset();\n return;\n }\n submenuRect.current = submenu.getBoundingClientRect();\n\n let onPointerMove = (e: PointerEvent) => {\n if (e.pointerType === 'touch' || e.pointerType === 'pen') {\n return;\n }\n\n let currentTime = Date.now();\n\n // Throttle\n if (currentTime - lastProcessedTime.current < THROTTLE_TIME) {\n return;\n }\n clearTimeout(timeout.current);\n clearTimeout(autoCloseTimeout.current);\n\n let {clientX: mouseX, clientY: mouseY} = e;\n\n if (!prevPointerPos.current) {\n prevPointerPos.current = {x: mouseX, y: mouseY};\n return;\n }\n\n if (!submenuRect.current) {\n return;\n }\n\n if (!submenuSide.current) {\n submenuSide.current = mouseX > submenuRect.current.right ? 'left' : 'right';\n }\n\n // Pointer is outside of parent menu\n if (mouseX < menu.getBoundingClientRect().left || mouseX > menu.getBoundingClientRect().right || mouseY < menu.getBoundingClientRect().top || mouseY > menu.getBoundingClientRect().bottom) {\n reset();\n return;\n }\n\n /* Check if pointer is moving towards submenu.\n Uses the 2-argument arctangent (https://en.wikipedia.org/wiki/Atan2) to calculate:\n - angle between previous pointer and top of submenu\n - angle between previous pointer and bottom of submenu\n - angle between previous pointer and current pointer (delta)\n If the pointer delta angle value is between the top and bottom angle values, we know the pointer is moving towards the submenu.\n */\n let prevMouseX = prevPointerPos.current.x;\n let prevMouseY = prevPointerPos.current.y;\n let toSubmenuX = submenuSide.current === 'right' ? submenuRect.current.left - prevMouseX : prevMouseX - submenuRect.current.right;\n let angleTop = Math.atan2(prevMouseY - submenuRect.current.top, toSubmenuX) + ANGLE_PADDING;\n let angleBottom = Math.atan2(prevMouseY - submenuRect.current.bottom, toSubmenuX) - ANGLE_PADDING;\n let anglePointer = Math.atan2(prevMouseY - mouseY, (submenuSide.current === 'left' ? -(mouseX - prevMouseX) : mouseX - prevMouseX));\n let isMovingTowardsSubmenu = anglePointer < angleTop && anglePointer > angleBottom;\n\n movementsTowardsSubmenuCount.current = isMovingTowardsSubmenu ?\n Math.min(movementsTowardsSubmenuCount.current + 1, ALLOWED_INVALID_MOVEMENTS) :\n Math.max(movementsTowardsSubmenuCount.current - 1, 0);\n\n if (movementsTowardsSubmenuCount.current >= ALLOWED_INVALID_MOVEMENTS) {\n setPreventPointerEvents(true);\n } else {\n setPreventPointerEvents(false);\n }\n\n lastProcessedTime.current = currentTime;\n prevPointerPos.current = {x: mouseX, y: mouseY};\n\n // If the pointer is moving towards the submenu, start a timeout to close if no other movements are made after 500ms.\n if (isMovingTowardsSubmenu) {\n timeout.current = setTimeout(() => {\n reset();\n autoCloseTimeout.current = setTimeout(() => {\n // Fire a pointerover event to trigger the menu to close.\n // Wait until pointer-events:none is no longer applied\n let target = document.elementFromPoint(mouseX, mouseY);\n if (target && nodeContains(menu, target)) {\n target.dispatchEvent(new PointerEvent('pointerover', {bubbles: true, cancelable: true}));\n }\n }, 100);\n }, TIMEOUT_TIME);\n }\n };\n\n window.addEventListener('pointermove', onPointerMove);\n\n // Prevent pointer down over the safe triangle. See above comment.\n // Do not enable in tests, because JSDom doesn't do hit testing.\n if (process.env.NODE_ENV !== 'test') {\n window.addEventListener('pointerdown', onPointerDown, true);\n }\n\n return () => {\n window.removeEventListener('pointermove', onPointerMove);\n if (process.env.NODE_ENV !== 'test') {\n window.removeEventListener('pointerdown', onPointerDown, true);\n }\n clearTimeout(timeout.current);\n clearTimeout(autoCloseTimeout.current);\n movementsTowardsSubmenuCount.current = ALLOWED_INVALID_MOVEMENTS;\n };\n\n }, [isDisabled, isOpen, menuRef, modality, setPreventPointerEvents, submenuRef]);\n}\n"],"names":[],"version":3,"file":"useSafelyMouseToSubmenu.module.js.map"}
@@ -37,14 +37,20 @@ function $5f4753043c9f6cdf$export$7138b0d059a6e743(props, state, ref) {
37
37
  }, [
38
38
  openTimeout
39
39
  ]);
40
- let onSubmenuOpen = (0, $23MMN$reactariautils.useEffectEvent)((focusStrategy)=>{
40
+ let onSubmenuOpen = (0, $23MMN$react.useCallback)((focusStrategy)=>{
41
41
  cancelOpenTimeout();
42
42
  state.open(focusStrategy);
43
- });
44
- let onSubmenuClose = (0, $23MMN$reactariautils.useEffectEvent)(()=>{
43
+ }, [
44
+ state,
45
+ cancelOpenTimeout
46
+ ]);
47
+ let onSubmenuClose = (0, $23MMN$react.useCallback)(()=>{
45
48
  cancelOpenTimeout();
46
49
  state.close();
47
- });
50
+ }, [
51
+ state,
52
+ cancelOpenTimeout
53
+ ]);
48
54
  (0, $23MMN$reactariautils.useLayoutEffect)(()=>{
49
55
  return ()=>{
50
56
  cancelOpenTimeout();
@@ -55,10 +61,10 @@ function $5f4753043c9f6cdf$export$7138b0d059a6e743(props, state, ref) {
55
61
  let submenuKeyDown = (e)=>{
56
62
  // If focus is not within the menu, assume virtual focus is being used.
57
63
  // This means some other input element is also within the popover, so we shouldn't close the menu.
58
- if (!e.currentTarget.contains(document.activeElement)) return;
64
+ if (!(0, $23MMN$reactariautils.nodeContains)(e.currentTarget, document.activeElement)) return;
59
65
  switch(e.key){
60
66
  case 'ArrowLeft':
61
- if (direction === 'ltr' && e.currentTarget.contains(e.target)) {
67
+ if (direction === 'ltr' && (0, $23MMN$reactariautils.nodeContains)(e.currentTarget, e.target)) {
62
68
  e.preventDefault();
63
69
  e.stopPropagation();
64
70
  onSubmenuClose();
@@ -66,7 +72,7 @@ function $5f4753043c9f6cdf$export$7138b0d059a6e743(props, state, ref) {
66
72
  }
67
73
  break;
68
74
  case 'ArrowRight':
69
- if (direction === 'rtl' && e.currentTarget.contains(e.target)) {
75
+ if (direction === 'rtl' && (0, $23MMN$reactariautils.nodeContains)(e.currentTarget, e.target)) {
70
76
  e.preventDefault();
71
77
  e.stopPropagation();
72
78
  onSubmenuClose();
@@ -74,9 +80,8 @@ function $5f4753043c9f6cdf$export$7138b0d059a6e743(props, state, ref) {
74
80
  }
75
81
  break;
76
82
  case 'Escape':
77
- var _submenuRef_current;
78
83
  // TODO: can remove this when we fix collection event leaks
79
- if ((_submenuRef_current = submenuRef.current) === null || _submenuRef_current === void 0 ? void 0 : _submenuRef_current.contains(e.target)) {
84
+ if ((0, $23MMN$reactariautils.nodeContains)(submenuRef.current, e.target)) {
80
85
  e.stopPropagation();
81
86
  onSubmenuClose();
82
87
  if (!shouldUseVirtualFocus && ref.current) (0, $23MMN$reactariautils.focusWithoutScrolling)(ref.current);
@@ -141,10 +146,9 @@ function $5f4753043c9f6cdf$export$7138b0d059a6e743(props, state, ref) {
141
146
  }
142
147
  };
143
148
  (0, $23MMN$reactariautils.useEvent)(parentMenuRef, 'focusin', (e)=>{
144
- var _parentMenuRef_current;
145
149
  // If we detect focus moved to a different item in the same menu that the currently open submenu trigger is in
146
150
  // then close the submenu. This is for a case where the user hovers a root menu item when multiple submenus are open
147
- if (state.isOpen && ((_parentMenuRef_current = parentMenuRef.current) === null || _parentMenuRef_current === void 0 ? void 0 : _parentMenuRef_current.contains(e.target)) && e.target !== ref.current) onSubmenuClose();
151
+ if (state.isOpen && (0, $23MMN$reactariautils.nodeContains)(parentMenuRef.current, e.target) && e.target !== ref.current) onSubmenuClose();
148
152
  });
149
153
  let shouldCloseOnInteractOutside = (target)=>{
150
154
  if (target !== ref.current) return true;
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-aria/menu/src/useSubmenuTrigger.ts"],"sourcesContent":["/*\n * Copyright 2023 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {AriaMenuItemProps} from './useMenuItem';\nimport {AriaMenuOptions} from './useMenu';\nimport type {AriaPopoverProps, OverlayProps} from '@react-aria/overlays';\nimport {FocusableElement, FocusStrategy, KeyboardEvent, Node, PressEvent, RefObject} from '@react-types/shared';\nimport {focusWithoutScrolling, useEffectEvent, useEvent, useId, useLayoutEffect} from '@react-aria/utils';\nimport type {SubmenuTriggerState} from '@react-stately/menu';\nimport {useCallback, useRef} from 'react';\nimport {useLocale} from '@react-aria/i18n';\nimport {useSafelyMouseToSubmenu} from './useSafelyMouseToSubmenu';\n\nexport interface AriaSubmenuTriggerProps {\n /**\n * An object representing the submenu trigger menu item. Contains all the relevant information that makes up the menu item.\n * @deprecated\n */\n node?: Node<unknown>,\n /** Whether the submenu trigger is disabled. */\n isDisabled?: boolean,\n /** The type of the contents that the submenu trigger opens. */\n type?: 'dialog' | 'menu',\n /** Ref of the menu that contains the submenu trigger. */\n parentMenuRef: RefObject<HTMLElement | null>,\n /** Ref of the submenu opened by the submenu trigger. */\n submenuRef: RefObject<HTMLElement | null>,\n /**\n * The delay time in milliseconds for the submenu to appear after hovering over the trigger.\n * @default 200\n */\n delay?: number,\n /** Whether the submenu trigger uses virtual focus. */\n shouldUseVirtualFocus?: boolean\n}\n\ninterface SubmenuTriggerProps extends Omit<AriaMenuItemProps, 'key'> {\n /** Whether the submenu trigger is in an expanded state. */\n isOpen: boolean\n}\n\ninterface SubmenuProps<T> extends AriaMenuOptions<T> {\n /** The level of the submenu. */\n submenuLevel: number\n}\n\nexport interface SubmenuTriggerAria<T> {\n /** Props for the submenu trigger menu item. */\n submenuTriggerProps: SubmenuTriggerProps,\n /** Props for the submenu controlled by the submenu trigger menu item. */\n submenuProps: SubmenuProps<T>,\n /** Props for the submenu's popover container. */\n popoverProps: Pick<AriaPopoverProps, 'isNonModal' | 'shouldCloseOnInteractOutside'> & Pick<OverlayProps, 'disableFocusManagement'>\n}\n\n/**\n * Provides the behavior and accessibility implementation for a submenu trigger and its associated submenu.\n * @param props - Props for the submenu trigger and refs attach to its submenu and parent menu.\n * @param state - State for the submenu trigger.\n * @param ref - Ref to the submenu trigger element.\n */\nexport function useSubmenuTrigger<T>(props: AriaSubmenuTriggerProps, state: SubmenuTriggerState, ref: RefObject<FocusableElement | null>): SubmenuTriggerAria<T> {\n let {parentMenuRef, submenuRef, type = 'menu', isDisabled, delay = 200, shouldUseVirtualFocus} = props;\n let submenuTriggerId = useId();\n let overlayId = useId();\n let {direction} = useLocale();\n let openTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let cancelOpenTimeout = useCallback(() => {\n if (openTimeout.current) {\n clearTimeout(openTimeout.current);\n openTimeout.current = undefined;\n }\n }, [openTimeout]);\n\n let onSubmenuOpen = useEffectEvent((focusStrategy?: FocusStrategy) => {\n cancelOpenTimeout();\n state.open(focusStrategy);\n });\n\n let onSubmenuClose = useEffectEvent(() => {\n cancelOpenTimeout();\n state.close();\n });\n\n useLayoutEffect(() => {\n return () => {\n cancelOpenTimeout();\n };\n }, [cancelOpenTimeout]);\n\n let submenuKeyDown = (e: KeyboardEvent) => {\n // If focus is not within the menu, assume virtual focus is being used.\n // This means some other input element is also within the popover, so we shouldn't close the menu.\n if (!e.currentTarget.contains(document.activeElement)) {\n return;\n }\n\n switch (e.key) {\n case 'ArrowLeft':\n if (direction === 'ltr' && e.currentTarget.contains(e.target as Element)) {\n e.preventDefault();\n e.stopPropagation();\n onSubmenuClose();\n if (!shouldUseVirtualFocus && ref.current) {\n focusWithoutScrolling(ref.current);\n }\n }\n break;\n case 'ArrowRight':\n if (direction === 'rtl' && e.currentTarget.contains(e.target as Element)) {\n e.preventDefault();\n e.stopPropagation();\n onSubmenuClose();\n if (!shouldUseVirtualFocus && ref.current) {\n focusWithoutScrolling(ref.current);\n }\n }\n break;\n case 'Escape':\n // TODO: can remove this when we fix collection event leaks\n if (submenuRef.current?.contains(e.target as Element)) {\n e.stopPropagation();\n onSubmenuClose();\n if (!shouldUseVirtualFocus && ref.current) {\n focusWithoutScrolling(ref.current);\n }\n }\n break;\n }\n };\n\n let submenuProps = {\n id: overlayId,\n 'aria-labelledby': submenuTriggerId,\n submenuLevel: state.submenuLevel,\n ...(type === 'menu' && {\n onClose: state.closeAll,\n autoFocus: state.focusStrategy ?? undefined,\n onKeyDown: submenuKeyDown\n })\n };\n\n let submenuTriggerKeyDown = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowRight':\n if (!isDisabled) {\n if (direction === 'ltr') {\n e.preventDefault();\n if (!state.isOpen) {\n onSubmenuOpen('first');\n }\n\n if (type === 'menu' && !!submenuRef?.current && document.activeElement === ref?.current) {\n focusWithoutScrolling(submenuRef.current);\n }\n } else if (state.isOpen) {\n onSubmenuClose();\n } else {\n e.continuePropagation();\n }\n }\n\n break;\n case 'ArrowLeft':\n if (!isDisabled) {\n if (direction === 'rtl') {\n e.preventDefault();\n if (!state.isOpen) {\n onSubmenuOpen('first');\n }\n\n if (type === 'menu' && !!submenuRef?.current && document.activeElement === ref?.current) {\n focusWithoutScrolling(submenuRef.current);\n }\n } else if (state.isOpen) {\n onSubmenuClose();\n } else {\n e.continuePropagation();\n }\n }\n break;\n default:\n e.continuePropagation();\n break;\n }\n };\n\n let onPressStart = (e: PressEvent) => {\n if (!isDisabled && (e.pointerType === 'virtual' || e.pointerType === 'keyboard')) {\n // If opened with a screen reader or keyboard, auto focus the first submenu item.\n onSubmenuOpen('first');\n }\n };\n\n let onPress = (e: PressEvent) => {\n if (!isDisabled && (e.pointerType === 'touch' || e.pointerType === 'mouse')) {\n // For touch or on a desktop device with a small screen open on press up to possible problems with\n // press up happening on the newly opened tray items\n onSubmenuOpen();\n }\n };\n\n let onHoverChange = (isHovered) => {\n if (!isDisabled) {\n if (isHovered && !state.isOpen) {\n if (!openTimeout.current) {\n openTimeout.current = setTimeout(() => {\n onSubmenuOpen();\n }, delay);\n }\n } else if (!isHovered) {\n cancelOpenTimeout();\n }\n }\n };\n\n useEvent(parentMenuRef, 'focusin', (e) => {\n // If we detect focus moved to a different item in the same menu that the currently open submenu trigger is in\n // then close the submenu. This is for a case where the user hovers a root menu item when multiple submenus are open\n if (state.isOpen && (parentMenuRef.current?.contains(e.target as HTMLElement) && e.target !== ref.current)) {\n onSubmenuClose();\n }\n });\n\n let shouldCloseOnInteractOutside = (target) => {\n if (target !== ref.current) {\n return true;\n }\n\n return false;\n };\n\n useSafelyMouseToSubmenu({menuRef: parentMenuRef, submenuRef, isOpen: state.isOpen, isDisabled: isDisabled});\n\n return {\n submenuTriggerProps: {\n id: submenuTriggerId,\n 'aria-controls': state.isOpen ? overlayId : undefined,\n 'aria-haspopup': !isDisabled ? type : undefined,\n 'aria-expanded': state.isOpen ? 'true' : 'false',\n onPressStart,\n onPress,\n onHoverChange,\n onKeyDown: submenuTriggerKeyDown,\n isOpen: state.isOpen\n },\n submenuProps,\n popoverProps: {\n isNonModal: true,\n shouldCloseOnInteractOutside\n }\n };\n}\n"],"names":[],"version":3,"file":"useSubmenuTrigger.main.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-aria/menu/src/useSubmenuTrigger.ts"],"sourcesContent":["/*\n * Copyright 2023 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {AriaMenuItemProps} from './useMenuItem';\nimport {AriaMenuOptions} from './useMenu';\nimport type {AriaPopoverProps, OverlayProps} from '@react-aria/overlays';\nimport {FocusableElement, FocusStrategy, KeyboardEvent, Node, PressEvent, RefObject} from '@react-types/shared';\nimport {focusWithoutScrolling, nodeContains, useEvent, useId, useLayoutEffect} from '@react-aria/utils';\nimport type {SubmenuTriggerState} from '@react-stately/menu';\nimport {useCallback, useRef} from 'react';\nimport {useLocale} from '@react-aria/i18n';\nimport {useSafelyMouseToSubmenu} from './useSafelyMouseToSubmenu';\n\nexport interface AriaSubmenuTriggerProps {\n /**\n * An object representing the submenu trigger menu item. Contains all the relevant information that makes up the menu item.\n * @deprecated\n */\n node?: Node<unknown>,\n /** Whether the submenu trigger is disabled. */\n isDisabled?: boolean,\n /** The type of the contents that the submenu trigger opens. */\n type?: 'dialog' | 'menu',\n /** Ref of the menu that contains the submenu trigger. */\n parentMenuRef: RefObject<HTMLElement | null>,\n /** Ref of the submenu opened by the submenu trigger. */\n submenuRef: RefObject<HTMLElement | null>,\n /**\n * The delay time in milliseconds for the submenu to appear after hovering over the trigger.\n * @default 200\n */\n delay?: number,\n /** Whether the submenu trigger uses virtual focus. */\n shouldUseVirtualFocus?: boolean\n}\n\ninterface SubmenuTriggerProps extends Omit<AriaMenuItemProps, 'key'> {\n /** Whether the submenu trigger is in an expanded state. */\n isOpen: boolean\n}\n\ninterface SubmenuProps<T> extends AriaMenuOptions<T> {\n /** The level of the submenu. */\n submenuLevel: number\n}\n\nexport interface SubmenuTriggerAria<T> {\n /** Props for the submenu trigger menu item. */\n submenuTriggerProps: SubmenuTriggerProps,\n /** Props for the submenu controlled by the submenu trigger menu item. */\n submenuProps: SubmenuProps<T>,\n /** Props for the submenu's popover container. */\n popoverProps: Pick<AriaPopoverProps, 'isNonModal' | 'shouldCloseOnInteractOutside'> & Pick<OverlayProps, 'disableFocusManagement'>\n}\n\n/**\n * Provides the behavior and accessibility implementation for a submenu trigger and its associated submenu.\n * @param props - Props for the submenu trigger and refs attach to its submenu and parent menu.\n * @param state - State for the submenu trigger.\n * @param ref - Ref to the submenu trigger element.\n */\nexport function useSubmenuTrigger<T>(props: AriaSubmenuTriggerProps, state: SubmenuTriggerState, ref: RefObject<FocusableElement | null>): SubmenuTriggerAria<T> {\n let {parentMenuRef, submenuRef, type = 'menu', isDisabled, delay = 200, shouldUseVirtualFocus} = props;\n let submenuTriggerId = useId();\n let overlayId = useId();\n let {direction} = useLocale();\n let openTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let cancelOpenTimeout = useCallback(() => {\n if (openTimeout.current) {\n clearTimeout(openTimeout.current);\n openTimeout.current = undefined;\n }\n }, [openTimeout]);\n\n let onSubmenuOpen = useCallback((focusStrategy?: FocusStrategy) => {\n cancelOpenTimeout();\n state.open(focusStrategy);\n }, [state, cancelOpenTimeout]);\n\n let onSubmenuClose = useCallback(() => {\n cancelOpenTimeout();\n state.close();\n }, [state, cancelOpenTimeout]);\n\n useLayoutEffect(() => {\n return () => {\n cancelOpenTimeout();\n };\n }, [cancelOpenTimeout]);\n\n let submenuKeyDown = (e: KeyboardEvent) => {\n // If focus is not within the menu, assume virtual focus is being used.\n // This means some other input element is also within the popover, so we shouldn't close the menu.\n if (!nodeContains(e.currentTarget, document.activeElement)) {\n return;\n }\n\n switch (e.key) {\n case 'ArrowLeft':\n if (direction === 'ltr' && nodeContains(e.currentTarget, e.target as Element)) {\n e.preventDefault();\n e.stopPropagation();\n onSubmenuClose();\n if (!shouldUseVirtualFocus && ref.current) {\n focusWithoutScrolling(ref.current);\n }\n }\n break;\n case 'ArrowRight':\n if (direction === 'rtl' && nodeContains(e.currentTarget, e.target as Element)) {\n e.preventDefault();\n e.stopPropagation();\n onSubmenuClose();\n if (!shouldUseVirtualFocus && ref.current) {\n focusWithoutScrolling(ref.current);\n }\n }\n break;\n case 'Escape':\n // TODO: can remove this when we fix collection event leaks\n if (nodeContains(submenuRef.current, e.target as Element)) {\n e.stopPropagation();\n onSubmenuClose();\n if (!shouldUseVirtualFocus && ref.current) {\n focusWithoutScrolling(ref.current);\n }\n }\n break;\n }\n };\n\n let submenuProps = {\n id: overlayId,\n 'aria-labelledby': submenuTriggerId,\n submenuLevel: state.submenuLevel,\n ...(type === 'menu' && {\n onClose: state.closeAll,\n autoFocus: state.focusStrategy ?? undefined,\n onKeyDown: submenuKeyDown\n })\n };\n\n let submenuTriggerKeyDown = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowRight':\n if (!isDisabled) {\n if (direction === 'ltr') {\n e.preventDefault();\n if (!state.isOpen) {\n onSubmenuOpen('first');\n }\n\n if (type === 'menu' && !!submenuRef?.current && document.activeElement === ref?.current) {\n focusWithoutScrolling(submenuRef.current);\n }\n } else if (state.isOpen) {\n onSubmenuClose();\n } else {\n e.continuePropagation();\n }\n }\n\n break;\n case 'ArrowLeft':\n if (!isDisabled) {\n if (direction === 'rtl') {\n e.preventDefault();\n if (!state.isOpen) {\n onSubmenuOpen('first');\n }\n\n if (type === 'menu' && !!submenuRef?.current && document.activeElement === ref?.current) {\n focusWithoutScrolling(submenuRef.current);\n }\n } else if (state.isOpen) {\n onSubmenuClose();\n } else {\n e.continuePropagation();\n }\n }\n break;\n default:\n e.continuePropagation();\n break;\n }\n };\n\n let onPressStart = (e: PressEvent) => {\n if (!isDisabled && (e.pointerType === 'virtual' || e.pointerType === 'keyboard')) {\n // If opened with a screen reader or keyboard, auto focus the first submenu item.\n onSubmenuOpen('first');\n }\n };\n\n let onPress = (e: PressEvent) => {\n if (!isDisabled && (e.pointerType === 'touch' || e.pointerType === 'mouse')) {\n // For touch or on a desktop device with a small screen open on press up to possible problems with\n // press up happening on the newly opened tray items\n onSubmenuOpen();\n }\n };\n\n let onHoverChange = (isHovered) => {\n if (!isDisabled) {\n if (isHovered && !state.isOpen) {\n if (!openTimeout.current) {\n openTimeout.current = setTimeout(() => {\n onSubmenuOpen();\n }, delay);\n }\n } else if (!isHovered) {\n cancelOpenTimeout();\n }\n }\n };\n\n useEvent(parentMenuRef, 'focusin', (e) => {\n // If we detect focus moved to a different item in the same menu that the currently open submenu trigger is in\n // then close the submenu. This is for a case where the user hovers a root menu item when multiple submenus are open\n if (state.isOpen && (nodeContains(parentMenuRef.current, e.target as HTMLElement) && e.target !== ref.current)) {\n onSubmenuClose();\n }\n });\n\n let shouldCloseOnInteractOutside = (target) => {\n if (target !== ref.current) {\n return true;\n }\n\n return false;\n };\n\n useSafelyMouseToSubmenu({menuRef: parentMenuRef, submenuRef, isOpen: state.isOpen, isDisabled: isDisabled});\n\n return {\n submenuTriggerProps: {\n id: submenuTriggerId,\n 'aria-controls': state.isOpen ? overlayId : undefined,\n 'aria-haspopup': !isDisabled ? type : undefined,\n 'aria-expanded': state.isOpen ? 'true' : 'false',\n onPressStart,\n onPress,\n onHoverChange,\n onKeyDown: submenuTriggerKeyDown,\n isOpen: state.isOpen\n },\n submenuProps,\n popoverProps: {\n isNonModal: true,\n shouldCloseOnInteractOutside\n }\n };\n}\n"],"names":[],"version":3,"file":"useSubmenuTrigger.main.js.map"}
@@ -1,5 +1,5 @@
1
1
  import {useSafelyMouseToSubmenu as $d275435c250248f8$export$85ec83e04c95f50a} from "./useSafelyMouseToSubmenu.mjs";
2
- import {useId as $dXlYe$useId, useEffectEvent as $dXlYe$useEffectEvent, useLayoutEffect as $dXlYe$useLayoutEffect, focusWithoutScrolling as $dXlYe$focusWithoutScrolling, useEvent as $dXlYe$useEvent} from "@react-aria/utils";
2
+ import {useId as $dXlYe$useId, useLayoutEffect as $dXlYe$useLayoutEffect, nodeContains as $dXlYe$nodeContains, focusWithoutScrolling as $dXlYe$focusWithoutScrolling, useEvent as $dXlYe$useEvent} from "@react-aria/utils";
3
3
  import {useRef as $dXlYe$useRef, useCallback as $dXlYe$useCallback} from "react";
4
4
  import {useLocale as $dXlYe$useLocale} from "@react-aria/i18n";
5
5
 
@@ -31,14 +31,20 @@ function $0065b146e7192841$export$7138b0d059a6e743(props, state, ref) {
31
31
  }, [
32
32
  openTimeout
33
33
  ]);
34
- let onSubmenuOpen = (0, $dXlYe$useEffectEvent)((focusStrategy)=>{
34
+ let onSubmenuOpen = (0, $dXlYe$useCallback)((focusStrategy)=>{
35
35
  cancelOpenTimeout();
36
36
  state.open(focusStrategy);
37
- });
38
- let onSubmenuClose = (0, $dXlYe$useEffectEvent)(()=>{
37
+ }, [
38
+ state,
39
+ cancelOpenTimeout
40
+ ]);
41
+ let onSubmenuClose = (0, $dXlYe$useCallback)(()=>{
39
42
  cancelOpenTimeout();
40
43
  state.close();
41
- });
44
+ }, [
45
+ state,
46
+ cancelOpenTimeout
47
+ ]);
42
48
  (0, $dXlYe$useLayoutEffect)(()=>{
43
49
  return ()=>{
44
50
  cancelOpenTimeout();
@@ -49,10 +55,10 @@ function $0065b146e7192841$export$7138b0d059a6e743(props, state, ref) {
49
55
  let submenuKeyDown = (e)=>{
50
56
  // If focus is not within the menu, assume virtual focus is being used.
51
57
  // This means some other input element is also within the popover, so we shouldn't close the menu.
52
- if (!e.currentTarget.contains(document.activeElement)) return;
58
+ if (!(0, $dXlYe$nodeContains)(e.currentTarget, document.activeElement)) return;
53
59
  switch(e.key){
54
60
  case 'ArrowLeft':
55
- if (direction === 'ltr' && e.currentTarget.contains(e.target)) {
61
+ if (direction === 'ltr' && (0, $dXlYe$nodeContains)(e.currentTarget, e.target)) {
56
62
  e.preventDefault();
57
63
  e.stopPropagation();
58
64
  onSubmenuClose();
@@ -60,7 +66,7 @@ function $0065b146e7192841$export$7138b0d059a6e743(props, state, ref) {
60
66
  }
61
67
  break;
62
68
  case 'ArrowRight':
63
- if (direction === 'rtl' && e.currentTarget.contains(e.target)) {
69
+ if (direction === 'rtl' && (0, $dXlYe$nodeContains)(e.currentTarget, e.target)) {
64
70
  e.preventDefault();
65
71
  e.stopPropagation();
66
72
  onSubmenuClose();
@@ -68,9 +74,8 @@ function $0065b146e7192841$export$7138b0d059a6e743(props, state, ref) {
68
74
  }
69
75
  break;
70
76
  case 'Escape':
71
- var _submenuRef_current;
72
77
  // TODO: can remove this when we fix collection event leaks
73
- if ((_submenuRef_current = submenuRef.current) === null || _submenuRef_current === void 0 ? void 0 : _submenuRef_current.contains(e.target)) {
78
+ if ((0, $dXlYe$nodeContains)(submenuRef.current, e.target)) {
74
79
  e.stopPropagation();
75
80
  onSubmenuClose();
76
81
  if (!shouldUseVirtualFocus && ref.current) (0, $dXlYe$focusWithoutScrolling)(ref.current);
@@ -135,10 +140,9 @@ function $0065b146e7192841$export$7138b0d059a6e743(props, state, ref) {
135
140
  }
136
141
  };
137
142
  (0, $dXlYe$useEvent)(parentMenuRef, 'focusin', (e)=>{
138
- var _parentMenuRef_current;
139
143
  // If we detect focus moved to a different item in the same menu that the currently open submenu trigger is in
140
144
  // then close the submenu. This is for a case where the user hovers a root menu item when multiple submenus are open
141
- if (state.isOpen && ((_parentMenuRef_current = parentMenuRef.current) === null || _parentMenuRef_current === void 0 ? void 0 : _parentMenuRef_current.contains(e.target)) && e.target !== ref.current) onSubmenuClose();
145
+ if (state.isOpen && (0, $dXlYe$nodeContains)(parentMenuRef.current, e.target) && e.target !== ref.current) onSubmenuClose();
142
146
  });
143
147
  let shouldCloseOnInteractOutside = (target)=>{
144
148
  if (target !== ref.current) return true;
@@ -1,5 +1,5 @@
1
1
  import {useSafelyMouseToSubmenu as $d275435c250248f8$export$85ec83e04c95f50a} from "./useSafelyMouseToSubmenu.module.js";
2
- import {useId as $dXlYe$useId, useEffectEvent as $dXlYe$useEffectEvent, useLayoutEffect as $dXlYe$useLayoutEffect, focusWithoutScrolling as $dXlYe$focusWithoutScrolling, useEvent as $dXlYe$useEvent} from "@react-aria/utils";
2
+ import {useId as $dXlYe$useId, useLayoutEffect as $dXlYe$useLayoutEffect, nodeContains as $dXlYe$nodeContains, focusWithoutScrolling as $dXlYe$focusWithoutScrolling, useEvent as $dXlYe$useEvent} from "@react-aria/utils";
3
3
  import {useRef as $dXlYe$useRef, useCallback as $dXlYe$useCallback} from "react";
4
4
  import {useLocale as $dXlYe$useLocale} from "@react-aria/i18n";
5
5
 
@@ -31,14 +31,20 @@ function $0065b146e7192841$export$7138b0d059a6e743(props, state, ref) {
31
31
  }, [
32
32
  openTimeout
33
33
  ]);
34
- let onSubmenuOpen = (0, $dXlYe$useEffectEvent)((focusStrategy)=>{
34
+ let onSubmenuOpen = (0, $dXlYe$useCallback)((focusStrategy)=>{
35
35
  cancelOpenTimeout();
36
36
  state.open(focusStrategy);
37
- });
38
- let onSubmenuClose = (0, $dXlYe$useEffectEvent)(()=>{
37
+ }, [
38
+ state,
39
+ cancelOpenTimeout
40
+ ]);
41
+ let onSubmenuClose = (0, $dXlYe$useCallback)(()=>{
39
42
  cancelOpenTimeout();
40
43
  state.close();
41
- });
44
+ }, [
45
+ state,
46
+ cancelOpenTimeout
47
+ ]);
42
48
  (0, $dXlYe$useLayoutEffect)(()=>{
43
49
  return ()=>{
44
50
  cancelOpenTimeout();
@@ -49,10 +55,10 @@ function $0065b146e7192841$export$7138b0d059a6e743(props, state, ref) {
49
55
  let submenuKeyDown = (e)=>{
50
56
  // If focus is not within the menu, assume virtual focus is being used.
51
57
  // This means some other input element is also within the popover, so we shouldn't close the menu.
52
- if (!e.currentTarget.contains(document.activeElement)) return;
58
+ if (!(0, $dXlYe$nodeContains)(e.currentTarget, document.activeElement)) return;
53
59
  switch(e.key){
54
60
  case 'ArrowLeft':
55
- if (direction === 'ltr' && e.currentTarget.contains(e.target)) {
61
+ if (direction === 'ltr' && (0, $dXlYe$nodeContains)(e.currentTarget, e.target)) {
56
62
  e.preventDefault();
57
63
  e.stopPropagation();
58
64
  onSubmenuClose();
@@ -60,7 +66,7 @@ function $0065b146e7192841$export$7138b0d059a6e743(props, state, ref) {
60
66
  }
61
67
  break;
62
68
  case 'ArrowRight':
63
- if (direction === 'rtl' && e.currentTarget.contains(e.target)) {
69
+ if (direction === 'rtl' && (0, $dXlYe$nodeContains)(e.currentTarget, e.target)) {
64
70
  e.preventDefault();
65
71
  e.stopPropagation();
66
72
  onSubmenuClose();
@@ -68,9 +74,8 @@ function $0065b146e7192841$export$7138b0d059a6e743(props, state, ref) {
68
74
  }
69
75
  break;
70
76
  case 'Escape':
71
- var _submenuRef_current;
72
77
  // TODO: can remove this when we fix collection event leaks
73
- if ((_submenuRef_current = submenuRef.current) === null || _submenuRef_current === void 0 ? void 0 : _submenuRef_current.contains(e.target)) {
78
+ if ((0, $dXlYe$nodeContains)(submenuRef.current, e.target)) {
74
79
  e.stopPropagation();
75
80
  onSubmenuClose();
76
81
  if (!shouldUseVirtualFocus && ref.current) (0, $dXlYe$focusWithoutScrolling)(ref.current);
@@ -135,10 +140,9 @@ function $0065b146e7192841$export$7138b0d059a6e743(props, state, ref) {
135
140
  }
136
141
  };
137
142
  (0, $dXlYe$useEvent)(parentMenuRef, 'focusin', (e)=>{
138
- var _parentMenuRef_current;
139
143
  // If we detect focus moved to a different item in the same menu that the currently open submenu trigger is in
140
144
  // then close the submenu. This is for a case where the user hovers a root menu item when multiple submenus are open
141
- if (state.isOpen && ((_parentMenuRef_current = parentMenuRef.current) === null || _parentMenuRef_current === void 0 ? void 0 : _parentMenuRef_current.contains(e.target)) && e.target !== ref.current) onSubmenuClose();
145
+ if (state.isOpen && (0, $dXlYe$nodeContains)(parentMenuRef.current, e.target) && e.target !== ref.current) onSubmenuClose();
142
146
  });
143
147
  let shouldCloseOnInteractOutside = (target)=>{
144
148
  if (target !== ref.current) return true;
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-aria/menu/src/useSubmenuTrigger.ts"],"sourcesContent":["/*\n * Copyright 2023 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {AriaMenuItemProps} from './useMenuItem';\nimport {AriaMenuOptions} from './useMenu';\nimport type {AriaPopoverProps, OverlayProps} from '@react-aria/overlays';\nimport {FocusableElement, FocusStrategy, KeyboardEvent, Node, PressEvent, RefObject} from '@react-types/shared';\nimport {focusWithoutScrolling, useEffectEvent, useEvent, useId, useLayoutEffect} from '@react-aria/utils';\nimport type {SubmenuTriggerState} from '@react-stately/menu';\nimport {useCallback, useRef} from 'react';\nimport {useLocale} from '@react-aria/i18n';\nimport {useSafelyMouseToSubmenu} from './useSafelyMouseToSubmenu';\n\nexport interface AriaSubmenuTriggerProps {\n /**\n * An object representing the submenu trigger menu item. Contains all the relevant information that makes up the menu item.\n * @deprecated\n */\n node?: Node<unknown>,\n /** Whether the submenu trigger is disabled. */\n isDisabled?: boolean,\n /** The type of the contents that the submenu trigger opens. */\n type?: 'dialog' | 'menu',\n /** Ref of the menu that contains the submenu trigger. */\n parentMenuRef: RefObject<HTMLElement | null>,\n /** Ref of the submenu opened by the submenu trigger. */\n submenuRef: RefObject<HTMLElement | null>,\n /**\n * The delay time in milliseconds for the submenu to appear after hovering over the trigger.\n * @default 200\n */\n delay?: number,\n /** Whether the submenu trigger uses virtual focus. */\n shouldUseVirtualFocus?: boolean\n}\n\ninterface SubmenuTriggerProps extends Omit<AriaMenuItemProps, 'key'> {\n /** Whether the submenu trigger is in an expanded state. */\n isOpen: boolean\n}\n\ninterface SubmenuProps<T> extends AriaMenuOptions<T> {\n /** The level of the submenu. */\n submenuLevel: number\n}\n\nexport interface SubmenuTriggerAria<T> {\n /** Props for the submenu trigger menu item. */\n submenuTriggerProps: SubmenuTriggerProps,\n /** Props for the submenu controlled by the submenu trigger menu item. */\n submenuProps: SubmenuProps<T>,\n /** Props for the submenu's popover container. */\n popoverProps: Pick<AriaPopoverProps, 'isNonModal' | 'shouldCloseOnInteractOutside'> & Pick<OverlayProps, 'disableFocusManagement'>\n}\n\n/**\n * Provides the behavior and accessibility implementation for a submenu trigger and its associated submenu.\n * @param props - Props for the submenu trigger and refs attach to its submenu and parent menu.\n * @param state - State for the submenu trigger.\n * @param ref - Ref to the submenu trigger element.\n */\nexport function useSubmenuTrigger<T>(props: AriaSubmenuTriggerProps, state: SubmenuTriggerState, ref: RefObject<FocusableElement | null>): SubmenuTriggerAria<T> {\n let {parentMenuRef, submenuRef, type = 'menu', isDisabled, delay = 200, shouldUseVirtualFocus} = props;\n let submenuTriggerId = useId();\n let overlayId = useId();\n let {direction} = useLocale();\n let openTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let cancelOpenTimeout = useCallback(() => {\n if (openTimeout.current) {\n clearTimeout(openTimeout.current);\n openTimeout.current = undefined;\n }\n }, [openTimeout]);\n\n let onSubmenuOpen = useEffectEvent((focusStrategy?: FocusStrategy) => {\n cancelOpenTimeout();\n state.open(focusStrategy);\n });\n\n let onSubmenuClose = useEffectEvent(() => {\n cancelOpenTimeout();\n state.close();\n });\n\n useLayoutEffect(() => {\n return () => {\n cancelOpenTimeout();\n };\n }, [cancelOpenTimeout]);\n\n let submenuKeyDown = (e: KeyboardEvent) => {\n // If focus is not within the menu, assume virtual focus is being used.\n // This means some other input element is also within the popover, so we shouldn't close the menu.\n if (!e.currentTarget.contains(document.activeElement)) {\n return;\n }\n\n switch (e.key) {\n case 'ArrowLeft':\n if (direction === 'ltr' && e.currentTarget.contains(e.target as Element)) {\n e.preventDefault();\n e.stopPropagation();\n onSubmenuClose();\n if (!shouldUseVirtualFocus && ref.current) {\n focusWithoutScrolling(ref.current);\n }\n }\n break;\n case 'ArrowRight':\n if (direction === 'rtl' && e.currentTarget.contains(e.target as Element)) {\n e.preventDefault();\n e.stopPropagation();\n onSubmenuClose();\n if (!shouldUseVirtualFocus && ref.current) {\n focusWithoutScrolling(ref.current);\n }\n }\n break;\n case 'Escape':\n // TODO: can remove this when we fix collection event leaks\n if (submenuRef.current?.contains(e.target as Element)) {\n e.stopPropagation();\n onSubmenuClose();\n if (!shouldUseVirtualFocus && ref.current) {\n focusWithoutScrolling(ref.current);\n }\n }\n break;\n }\n };\n\n let submenuProps = {\n id: overlayId,\n 'aria-labelledby': submenuTriggerId,\n submenuLevel: state.submenuLevel,\n ...(type === 'menu' && {\n onClose: state.closeAll,\n autoFocus: state.focusStrategy ?? undefined,\n onKeyDown: submenuKeyDown\n })\n };\n\n let submenuTriggerKeyDown = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowRight':\n if (!isDisabled) {\n if (direction === 'ltr') {\n e.preventDefault();\n if (!state.isOpen) {\n onSubmenuOpen('first');\n }\n\n if (type === 'menu' && !!submenuRef?.current && document.activeElement === ref?.current) {\n focusWithoutScrolling(submenuRef.current);\n }\n } else if (state.isOpen) {\n onSubmenuClose();\n } else {\n e.continuePropagation();\n }\n }\n\n break;\n case 'ArrowLeft':\n if (!isDisabled) {\n if (direction === 'rtl') {\n e.preventDefault();\n if (!state.isOpen) {\n onSubmenuOpen('first');\n }\n\n if (type === 'menu' && !!submenuRef?.current && document.activeElement === ref?.current) {\n focusWithoutScrolling(submenuRef.current);\n }\n } else if (state.isOpen) {\n onSubmenuClose();\n } else {\n e.continuePropagation();\n }\n }\n break;\n default:\n e.continuePropagation();\n break;\n }\n };\n\n let onPressStart = (e: PressEvent) => {\n if (!isDisabled && (e.pointerType === 'virtual' || e.pointerType === 'keyboard')) {\n // If opened with a screen reader or keyboard, auto focus the first submenu item.\n onSubmenuOpen('first');\n }\n };\n\n let onPress = (e: PressEvent) => {\n if (!isDisabled && (e.pointerType === 'touch' || e.pointerType === 'mouse')) {\n // For touch or on a desktop device with a small screen open on press up to possible problems with\n // press up happening on the newly opened tray items\n onSubmenuOpen();\n }\n };\n\n let onHoverChange = (isHovered) => {\n if (!isDisabled) {\n if (isHovered && !state.isOpen) {\n if (!openTimeout.current) {\n openTimeout.current = setTimeout(() => {\n onSubmenuOpen();\n }, delay);\n }\n } else if (!isHovered) {\n cancelOpenTimeout();\n }\n }\n };\n\n useEvent(parentMenuRef, 'focusin', (e) => {\n // If we detect focus moved to a different item in the same menu that the currently open submenu trigger is in\n // then close the submenu. This is for a case where the user hovers a root menu item when multiple submenus are open\n if (state.isOpen && (parentMenuRef.current?.contains(e.target as HTMLElement) && e.target !== ref.current)) {\n onSubmenuClose();\n }\n });\n\n let shouldCloseOnInteractOutside = (target) => {\n if (target !== ref.current) {\n return true;\n }\n\n return false;\n };\n\n useSafelyMouseToSubmenu({menuRef: parentMenuRef, submenuRef, isOpen: state.isOpen, isDisabled: isDisabled});\n\n return {\n submenuTriggerProps: {\n id: submenuTriggerId,\n 'aria-controls': state.isOpen ? overlayId : undefined,\n 'aria-haspopup': !isDisabled ? type : undefined,\n 'aria-expanded': state.isOpen ? 'true' : 'false',\n onPressStart,\n onPress,\n onHoverChange,\n onKeyDown: submenuTriggerKeyDown,\n isOpen: state.isOpen\n },\n submenuProps,\n popoverProps: {\n isNonModal: true,\n shouldCloseOnInteractOutside\n }\n };\n}\n"],"names":[],"version":3,"file":"useSubmenuTrigger.module.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-aria/menu/src/useSubmenuTrigger.ts"],"sourcesContent":["/*\n * Copyright 2023 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {AriaMenuItemProps} from './useMenuItem';\nimport {AriaMenuOptions} from './useMenu';\nimport type {AriaPopoverProps, OverlayProps} from '@react-aria/overlays';\nimport {FocusableElement, FocusStrategy, KeyboardEvent, Node, PressEvent, RefObject} from '@react-types/shared';\nimport {focusWithoutScrolling, nodeContains, useEvent, useId, useLayoutEffect} from '@react-aria/utils';\nimport type {SubmenuTriggerState} from '@react-stately/menu';\nimport {useCallback, useRef} from 'react';\nimport {useLocale} from '@react-aria/i18n';\nimport {useSafelyMouseToSubmenu} from './useSafelyMouseToSubmenu';\n\nexport interface AriaSubmenuTriggerProps {\n /**\n * An object representing the submenu trigger menu item. Contains all the relevant information that makes up the menu item.\n * @deprecated\n */\n node?: Node<unknown>,\n /** Whether the submenu trigger is disabled. */\n isDisabled?: boolean,\n /** The type of the contents that the submenu trigger opens. */\n type?: 'dialog' | 'menu',\n /** Ref of the menu that contains the submenu trigger. */\n parentMenuRef: RefObject<HTMLElement | null>,\n /** Ref of the submenu opened by the submenu trigger. */\n submenuRef: RefObject<HTMLElement | null>,\n /**\n * The delay time in milliseconds for the submenu to appear after hovering over the trigger.\n * @default 200\n */\n delay?: number,\n /** Whether the submenu trigger uses virtual focus. */\n shouldUseVirtualFocus?: boolean\n}\n\ninterface SubmenuTriggerProps extends Omit<AriaMenuItemProps, 'key'> {\n /** Whether the submenu trigger is in an expanded state. */\n isOpen: boolean\n}\n\ninterface SubmenuProps<T> extends AriaMenuOptions<T> {\n /** The level of the submenu. */\n submenuLevel: number\n}\n\nexport interface SubmenuTriggerAria<T> {\n /** Props for the submenu trigger menu item. */\n submenuTriggerProps: SubmenuTriggerProps,\n /** Props for the submenu controlled by the submenu trigger menu item. */\n submenuProps: SubmenuProps<T>,\n /** Props for the submenu's popover container. */\n popoverProps: Pick<AriaPopoverProps, 'isNonModal' | 'shouldCloseOnInteractOutside'> & Pick<OverlayProps, 'disableFocusManagement'>\n}\n\n/**\n * Provides the behavior and accessibility implementation for a submenu trigger and its associated submenu.\n * @param props - Props for the submenu trigger and refs attach to its submenu and parent menu.\n * @param state - State for the submenu trigger.\n * @param ref - Ref to the submenu trigger element.\n */\nexport function useSubmenuTrigger<T>(props: AriaSubmenuTriggerProps, state: SubmenuTriggerState, ref: RefObject<FocusableElement | null>): SubmenuTriggerAria<T> {\n let {parentMenuRef, submenuRef, type = 'menu', isDisabled, delay = 200, shouldUseVirtualFocus} = props;\n let submenuTriggerId = useId();\n let overlayId = useId();\n let {direction} = useLocale();\n let openTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n let cancelOpenTimeout = useCallback(() => {\n if (openTimeout.current) {\n clearTimeout(openTimeout.current);\n openTimeout.current = undefined;\n }\n }, [openTimeout]);\n\n let onSubmenuOpen = useCallback((focusStrategy?: FocusStrategy) => {\n cancelOpenTimeout();\n state.open(focusStrategy);\n }, [state, cancelOpenTimeout]);\n\n let onSubmenuClose = useCallback(() => {\n cancelOpenTimeout();\n state.close();\n }, [state, cancelOpenTimeout]);\n\n useLayoutEffect(() => {\n return () => {\n cancelOpenTimeout();\n };\n }, [cancelOpenTimeout]);\n\n let submenuKeyDown = (e: KeyboardEvent) => {\n // If focus is not within the menu, assume virtual focus is being used.\n // This means some other input element is also within the popover, so we shouldn't close the menu.\n if (!nodeContains(e.currentTarget, document.activeElement)) {\n return;\n }\n\n switch (e.key) {\n case 'ArrowLeft':\n if (direction === 'ltr' && nodeContains(e.currentTarget, e.target as Element)) {\n e.preventDefault();\n e.stopPropagation();\n onSubmenuClose();\n if (!shouldUseVirtualFocus && ref.current) {\n focusWithoutScrolling(ref.current);\n }\n }\n break;\n case 'ArrowRight':\n if (direction === 'rtl' && nodeContains(e.currentTarget, e.target as Element)) {\n e.preventDefault();\n e.stopPropagation();\n onSubmenuClose();\n if (!shouldUseVirtualFocus && ref.current) {\n focusWithoutScrolling(ref.current);\n }\n }\n break;\n case 'Escape':\n // TODO: can remove this when we fix collection event leaks\n if (nodeContains(submenuRef.current, e.target as Element)) {\n e.stopPropagation();\n onSubmenuClose();\n if (!shouldUseVirtualFocus && ref.current) {\n focusWithoutScrolling(ref.current);\n }\n }\n break;\n }\n };\n\n let submenuProps = {\n id: overlayId,\n 'aria-labelledby': submenuTriggerId,\n submenuLevel: state.submenuLevel,\n ...(type === 'menu' && {\n onClose: state.closeAll,\n autoFocus: state.focusStrategy ?? undefined,\n onKeyDown: submenuKeyDown\n })\n };\n\n let submenuTriggerKeyDown = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowRight':\n if (!isDisabled) {\n if (direction === 'ltr') {\n e.preventDefault();\n if (!state.isOpen) {\n onSubmenuOpen('first');\n }\n\n if (type === 'menu' && !!submenuRef?.current && document.activeElement === ref?.current) {\n focusWithoutScrolling(submenuRef.current);\n }\n } else if (state.isOpen) {\n onSubmenuClose();\n } else {\n e.continuePropagation();\n }\n }\n\n break;\n case 'ArrowLeft':\n if (!isDisabled) {\n if (direction === 'rtl') {\n e.preventDefault();\n if (!state.isOpen) {\n onSubmenuOpen('first');\n }\n\n if (type === 'menu' && !!submenuRef?.current && document.activeElement === ref?.current) {\n focusWithoutScrolling(submenuRef.current);\n }\n } else if (state.isOpen) {\n onSubmenuClose();\n } else {\n e.continuePropagation();\n }\n }\n break;\n default:\n e.continuePropagation();\n break;\n }\n };\n\n let onPressStart = (e: PressEvent) => {\n if (!isDisabled && (e.pointerType === 'virtual' || e.pointerType === 'keyboard')) {\n // If opened with a screen reader or keyboard, auto focus the first submenu item.\n onSubmenuOpen('first');\n }\n };\n\n let onPress = (e: PressEvent) => {\n if (!isDisabled && (e.pointerType === 'touch' || e.pointerType === 'mouse')) {\n // For touch or on a desktop device with a small screen open on press up to possible problems with\n // press up happening on the newly opened tray items\n onSubmenuOpen();\n }\n };\n\n let onHoverChange = (isHovered) => {\n if (!isDisabled) {\n if (isHovered && !state.isOpen) {\n if (!openTimeout.current) {\n openTimeout.current = setTimeout(() => {\n onSubmenuOpen();\n }, delay);\n }\n } else if (!isHovered) {\n cancelOpenTimeout();\n }\n }\n };\n\n useEvent(parentMenuRef, 'focusin', (e) => {\n // If we detect focus moved to a different item in the same menu that the currently open submenu trigger is in\n // then close the submenu. This is for a case where the user hovers a root menu item when multiple submenus are open\n if (state.isOpen && (nodeContains(parentMenuRef.current, e.target as HTMLElement) && e.target !== ref.current)) {\n onSubmenuClose();\n }\n });\n\n let shouldCloseOnInteractOutside = (target) => {\n if (target !== ref.current) {\n return true;\n }\n\n return false;\n };\n\n useSafelyMouseToSubmenu({menuRef: parentMenuRef, submenuRef, isOpen: state.isOpen, isDisabled: isDisabled});\n\n return {\n submenuTriggerProps: {\n id: submenuTriggerId,\n 'aria-controls': state.isOpen ? overlayId : undefined,\n 'aria-haspopup': !isDisabled ? type : undefined,\n 'aria-expanded': state.isOpen ? 'true' : 'false',\n onPressStart,\n onPress,\n onHoverChange,\n onKeyDown: submenuTriggerKeyDown,\n isOpen: state.isOpen\n },\n submenuProps,\n popoverProps: {\n isNonModal: true,\n shouldCloseOnInteractOutside\n }\n };\n}\n"],"names":[],"version":3,"file":"useSubmenuTrigger.module.js.map"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-aria/menu",
3
- "version": "3.19.3",
3
+ "version": "3.20.0",
4
4
  "description": "Spectrum UI components in React",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/main.js",
@@ -26,19 +26,19 @@
26
26
  "url": "https://github.com/adobe/react-spectrum"
27
27
  },
28
28
  "dependencies": {
29
- "@react-aria/focus": "^3.21.2",
30
- "@react-aria/i18n": "^3.12.13",
31
- "@react-aria/interactions": "^3.25.6",
32
- "@react-aria/overlays": "^3.30.0",
33
- "@react-aria/selection": "^3.26.0",
34
- "@react-aria/utils": "^3.31.0",
35
- "@react-stately/collections": "^3.12.8",
36
- "@react-stately/menu": "^3.9.8",
37
- "@react-stately/selection": "^3.20.6",
38
- "@react-stately/tree": "^3.9.3",
39
- "@react-types/button": "^3.14.1",
40
- "@react-types/menu": "^3.10.5",
41
- "@react-types/shared": "^3.32.1",
29
+ "@react-aria/focus": "^3.21.4",
30
+ "@react-aria/i18n": "^3.12.15",
31
+ "@react-aria/interactions": "^3.27.0",
32
+ "@react-aria/overlays": "^3.31.1",
33
+ "@react-aria/selection": "^3.27.1",
34
+ "@react-aria/utils": "^3.33.0",
35
+ "@react-stately/collections": "^3.12.9",
36
+ "@react-stately/menu": "^3.9.10",
37
+ "@react-stately/selection": "^3.20.8",
38
+ "@react-stately/tree": "^3.9.5",
39
+ "@react-types/button": "^3.15.0",
40
+ "@react-types/menu": "^3.10.6",
41
+ "@react-types/shared": "^3.33.0",
42
42
  "@swc/helpers": "^0.5.0"
43
43
  },
44
44
  "peerDependencies": {
@@ -48,5 +48,5 @@
48
48
  "publishConfig": {
49
49
  "access": "public"
50
50
  },
51
- "gitHead": "0bda51183baa23306342af32a82012ea0fe0f2dc"
51
+ "gitHead": "66e51757606b43a89ed02c574ca24517323a2ab9"
52
52
  }
@@ -13,7 +13,7 @@
13
13
  import {DOMAttributes, DOMProps, FocusableElement, FocusEvents, HoverEvents, Key, KeyboardEvents, PressEvent, PressEvents, RefObject} from '@react-types/shared';
14
14
  import {filterDOMProps, handleLinkClick, mergeProps, useLinkProps, useRouter, useSlotId} from '@react-aria/utils';
15
15
  import {getItemCount} from '@react-stately/collections';
16
- import {isFocusVisible, useFocus, useHover, useKeyboard, usePress} from '@react-aria/interactions';
16
+ import {isFocusVisible, useFocusable, useHover, useKeyboard, usePress} from '@react-aria/interactions';
17
17
  import {menuData} from './utils';
18
18
  import {MouseEvent, useRef} from 'react';
19
19
  import {SelectionManager} from '@react-stately/selection';
@@ -72,10 +72,13 @@ export interface AriaMenuItemProps extends DOMProps, PressEvents, HoverEvents, K
72
72
 
73
73
  /**
74
74
  * Whether the menu should close when the menu item is selected.
75
- * @default true
75
+ * @deprecated - use shouldCloseOnSelect instead.
76
76
  */
77
77
  closeOnSelect?: boolean,
78
78
 
79
+ /** Whether the menu should close when the menu item is selected. */
80
+ shouldCloseOnSelect?: boolean,
81
+
79
82
  /** Whether the menu item is contained in a virtual scrolling menu. */
80
83
  isVirtualized?: boolean,
81
84
 
@@ -109,6 +112,7 @@ export function useMenuItem<T>(props: AriaMenuItemProps, state: TreeState<T>, re
109
112
  id,
110
113
  key,
111
114
  closeOnSelect,
115
+ shouldCloseOnSelect,
112
116
  isVirtualized,
113
117
  'aria-haspopup': hasPopup,
114
118
  onPressStart,
@@ -221,8 +225,10 @@ export function useMenuItem<T>(props: AriaMenuItemProps, state: TreeState<T>, re
221
225
  ? interaction.current?.key === 'Enter' || selectionManager.selectionMode === 'none' || selectionManager.isLink(key)
222
226
  // Close except if multi-select is enabled.
223
227
  : selectionManager.selectionMode !== 'multiple' || selectionManager.isLink(key);
224
-
225
- shouldClose = closeOnSelect ?? shouldClose;
228
+
229
+
230
+ shouldClose = shouldCloseOnSelect ?? closeOnSelect ?? shouldClose;
231
+
226
232
  if (onClose && !isTrigger && shouldClose) {
227
233
  onClose();
228
234
  }
@@ -301,7 +307,7 @@ export function useMenuItem<T>(props: AriaMenuItemProps, state: TreeState<T>, re
301
307
  onKeyUp
302
308
  });
303
309
 
304
- let {focusProps} = useFocus({onBlur, onFocus, onFocusChange});
310
+ let {focusableProps} = useFocusable({onBlur, onFocus, onFocusChange}, ref);
305
311
  let domProps = filterDOMProps(item?.props);
306
312
  delete domProps.id;
307
313
  let linkProps = useLinkProps(item?.props);
@@ -312,13 +318,13 @@ export function useMenuItem<T>(props: AriaMenuItemProps, state: TreeState<T>, re
312
318
  ...mergeProps(
313
319
  domProps,
314
320
  linkProps,
315
- isTrigger
316
- ? {onFocus: itemProps.onFocus, 'data-collection': itemProps['data-collection'], 'data-key': itemProps['data-key']}
321
+ isTrigger
322
+ ? {onFocus: itemProps.onFocus, 'data-collection': itemProps['data-collection'], 'data-key': itemProps['data-key']}
317
323
  : itemProps,
318
324
  pressProps,
319
325
  hoverProps,
320
326
  keyboardProps,
321
- focusProps,
327
+ focusableProps,
322
328
  // Prevent DOM focus from moving on mouse down when using virtual focus or this is a submenu/subdialog trigger.
323
329
  data.shouldUseVirtualFocus || isTrigger ? {onMouseDown: e => e.preventDefault()} : undefined,
324
330
  isDisabled ? undefined : {onClick}
@@ -1,7 +1,7 @@
1
1
 
2
+ import {nodeContains, useEffectEvent, useLayoutEffect, useResizeObserver} from '@react-aria/utils';
2
3
  import {RefObject} from '@react-types/shared';
3
4
  import {useEffect, useRef, useState} from 'react';
4
- import {useEffectEvent, useResizeObserver} from '@react-aria/utils';
5
5
  import {useInteractionModality} from '@react-aria/interactions';
6
6
 
7
7
  interface SafelyMouseToSubmenuOptions {
@@ -67,7 +67,7 @@ export function useSafelyMouseToSubmenu(options: SafelyMouseToSubmenuOptions): v
67
67
  }
68
68
  }, [menuRef, preventPointerEvents]);
69
69
 
70
- useEffect(() => {
70
+ useLayoutEffect(() => {
71
71
  let submenu = submenuRef.current;
72
72
  let menu = menuRef.current;
73
73
 
@@ -148,7 +148,7 @@ export function useSafelyMouseToSubmenu(options: SafelyMouseToSubmenuOptions): v
148
148
  // Fire a pointerover event to trigger the menu to close.
149
149
  // Wait until pointer-events:none is no longer applied
150
150
  let target = document.elementFromPoint(mouseX, mouseY);
151
- if (target && menu.contains(target)) {
151
+ if (target && nodeContains(menu, target)) {
152
152
  target.dispatchEvent(new PointerEvent('pointerover', {bubbles: true, cancelable: true}));
153
153
  }
154
154
  }, 100);
@@ -174,5 +174,5 @@ export function useSafelyMouseToSubmenu(options: SafelyMouseToSubmenuOptions): v
174
174
  movementsTowardsSubmenuCount.current = ALLOWED_INVALID_MOVEMENTS;
175
175
  };
176
176
 
177
- }, [isDisabled, isOpen, menuRef, modality, setPreventPointerEvents, onPointerDown, submenuRef]);
177
+ }, [isDisabled, isOpen, menuRef, modality, setPreventPointerEvents, submenuRef]);
178
178
  }
@@ -14,7 +14,7 @@ import {AriaMenuItemProps} from './useMenuItem';
14
14
  import {AriaMenuOptions} from './useMenu';
15
15
  import type {AriaPopoverProps, OverlayProps} from '@react-aria/overlays';
16
16
  import {FocusableElement, FocusStrategy, KeyboardEvent, Node, PressEvent, RefObject} from '@react-types/shared';
17
- import {focusWithoutScrolling, useEffectEvent, useEvent, useId, useLayoutEffect} from '@react-aria/utils';
17
+ import {focusWithoutScrolling, nodeContains, useEvent, useId, useLayoutEffect} from '@react-aria/utils';
18
18
  import type {SubmenuTriggerState} from '@react-stately/menu';
19
19
  import {useCallback, useRef} from 'react';
20
20
  import {useLocale} from '@react-aria/i18n';
@@ -81,15 +81,15 @@ export function useSubmenuTrigger<T>(props: AriaSubmenuTriggerProps, state: Subm
81
81
  }
82
82
  }, [openTimeout]);
83
83
 
84
- let onSubmenuOpen = useEffectEvent((focusStrategy?: FocusStrategy) => {
84
+ let onSubmenuOpen = useCallback((focusStrategy?: FocusStrategy) => {
85
85
  cancelOpenTimeout();
86
86
  state.open(focusStrategy);
87
- });
87
+ }, [state, cancelOpenTimeout]);
88
88
 
89
- let onSubmenuClose = useEffectEvent(() => {
89
+ let onSubmenuClose = useCallback(() => {
90
90
  cancelOpenTimeout();
91
91
  state.close();
92
- });
92
+ }, [state, cancelOpenTimeout]);
93
93
 
94
94
  useLayoutEffect(() => {
95
95
  return () => {
@@ -100,13 +100,13 @@ export function useSubmenuTrigger<T>(props: AriaSubmenuTriggerProps, state: Subm
100
100
  let submenuKeyDown = (e: KeyboardEvent) => {
101
101
  // If focus is not within the menu, assume virtual focus is being used.
102
102
  // This means some other input element is also within the popover, so we shouldn't close the menu.
103
- if (!e.currentTarget.contains(document.activeElement)) {
103
+ if (!nodeContains(e.currentTarget, document.activeElement)) {
104
104
  return;
105
105
  }
106
106
 
107
107
  switch (e.key) {
108
108
  case 'ArrowLeft':
109
- if (direction === 'ltr' && e.currentTarget.contains(e.target as Element)) {
109
+ if (direction === 'ltr' && nodeContains(e.currentTarget, e.target as Element)) {
110
110
  e.preventDefault();
111
111
  e.stopPropagation();
112
112
  onSubmenuClose();
@@ -116,7 +116,7 @@ export function useSubmenuTrigger<T>(props: AriaSubmenuTriggerProps, state: Subm
116
116
  }
117
117
  break;
118
118
  case 'ArrowRight':
119
- if (direction === 'rtl' && e.currentTarget.contains(e.target as Element)) {
119
+ if (direction === 'rtl' && nodeContains(e.currentTarget, e.target as Element)) {
120
120
  e.preventDefault();
121
121
  e.stopPropagation();
122
122
  onSubmenuClose();
@@ -127,7 +127,7 @@ export function useSubmenuTrigger<T>(props: AriaSubmenuTriggerProps, state: Subm
127
127
  break;
128
128
  case 'Escape':
129
129
  // TODO: can remove this when we fix collection event leaks
130
- if (submenuRef.current?.contains(e.target as Element)) {
130
+ if (nodeContains(submenuRef.current, e.target as Element)) {
131
131
  e.stopPropagation();
132
132
  onSubmenuClose();
133
133
  if (!shouldUseVirtualFocus && ref.current) {
@@ -226,7 +226,7 @@ export function useSubmenuTrigger<T>(props: AriaSubmenuTriggerProps, state: Subm
226
226
  useEvent(parentMenuRef, 'focusin', (e) => {
227
227
  // If we detect focus moved to a different item in the same menu that the currently open submenu trigger is in
228
228
  // then close the submenu. This is for a case where the user hovers a root menu item when multiple submenus are open
229
- if (state.isOpen && (parentMenuRef.current?.contains(e.target as HTMLElement) && e.target !== ref.current)) {
229
+ if (state.isOpen && (nodeContains(parentMenuRef.current, e.target as HTMLElement) && e.target !== ref.current)) {
230
230
  onSubmenuClose();
231
231
  }
232
232
  });