@elliemae/ds-menu-button 3.46.0-rc.0 → 3.46.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/cjs/config/useMenuButton.js +4 -17
  2. package/dist/cjs/config/useMenuButton.js.map +2 -2
  3. package/dist/cjs/index.js +2 -0
  4. package/dist/cjs/index.js.map +2 -2
  5. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useAdvancedValidation.js +86 -0
  6. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useAdvancedValidation.js.map +7 -0
  7. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js +2 -0
  8. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js.map +2 -2
  9. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js +49 -22
  10. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js.map +2 -2
  11. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableMenuItem.js +9 -4
  12. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableMenuItem.js.map +2 -2
  13. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js +9 -4
  14. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js.map +2 -2
  15. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js +9 -4
  16. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js.map +2 -2
  17. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js +11 -4
  18. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js.map +2 -2
  19. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js +9 -4
  20. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js.map +2 -2
  21. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js +9 -4
  22. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js.map +2 -2
  23. package/dist/cjs/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js +9 -4
  24. package/dist/cjs/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js.map +2 -2
  25. package/dist/cjs/react-desc-prop-types.js +8 -6
  26. package/dist/cjs/react-desc-prop-types.js.map +2 -2
  27. package/dist/esm/config/useMenuButton.js +4 -17
  28. package/dist/esm/config/useMenuButton.js.map +2 -2
  29. package/dist/esm/index.js +2 -0
  30. package/dist/esm/index.js.map +2 -2
  31. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useAdvancedValidation.js +56 -0
  32. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useAdvancedValidation.js.map +7 -0
  33. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js +2 -0
  34. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js.map +2 -2
  35. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js +49 -22
  36. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js.map +2 -2
  37. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableMenuItem.js +9 -4
  38. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableMenuItem.js.map +2 -2
  39. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js +9 -4
  40. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js.map +2 -2
  41. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js +9 -4
  42. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js.map +2 -2
  43. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js +11 -4
  44. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js.map +2 -2
  45. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js +9 -4
  46. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js.map +2 -2
  47. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js +9 -4
  48. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js.map +2 -2
  49. package/dist/esm/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js +9 -4
  50. package/dist/esm/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js.map +2 -2
  51. package/dist/esm/react-desc-prop-types.js +8 -6
  52. package/dist/esm/react-desc-prop-types.js.map +2 -2
  53. package/dist/types/config/useSplitInherithedProps.d.ts +6 -6
  54. package/dist/types/index.d.ts +1 -1
  55. package/dist/types/parts/DSMenuBehaviouralContextProvider/config/useAdvancedValidation.d.ts +6 -0
  56. package/dist/types/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.d.ts +2 -1
  57. package/dist/types/react-desc-prop-types.d.ts +14 -14
  58. package/package.json +13 -13
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../src/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable no-console */\n/* eslint-disable max-lines */\n// in this files the returns are not useless, they are used to clearly demark the intended behavior shortcircuit for the next developer that reads the code\n/* eslint-disable no-useless-return */\n/* eslint-disable complexity */\n/* eslint-disable max-statements */\nimport React from 'react';\nimport { type DSMenuButtonT } from '../../../react-desc-prop-types.js';\nimport {\n isFocusableNode,\n isMultipleSelectNode,\n isRootNode,\n isSingleSelectNode,\n isWithSubmenuNode,\n isWithSubmenuOnlyNode,\n} from '../../../utils/nodesTypeguardsAndGetters.js';\nimport { FORBIDDEN_BEHAVIOURS, UNEXPECTED_INTERNAL_ERRORS } from '../constants/Errors.js';\nimport { type DSMenuBehaviouralContextProviderT } from '../react-desc-prop-types.js';\nimport { getNewSelectionMultipleSelect } from '../utils/multipleSelectionHelpers.js';\nimport { getSubMenusPath } from '../utils/nodeGettersByCriterias.js';\nimport { getNewSelectionSingleSelect } from '../utils/singleSelectionHelpers.js';\nimport type { useFocusTracker } from './useFocusTracker.js';\nimport type { useMenuOpenStatus } from './useMenuOpenStatus.js';\n\ntype ItemKeydownHelpersArgs = {\n pseudoFocusedItemNode: DSMenuButtonT.PseudoFocusableMenuNodes;\n event?: React.KeyboardEvent | React.MouseEvent;\n};\ntype SubmenuChangeMetainfo = {\n itemNode: DSMenuButtonT.PseudoFocusableMenuNodes;\n event?: React.SyntheticEvent;\n};\n\ntype UseMenuItemEventsHandlersConfig = {\n propsWithDefault: DSMenuBehaviouralContextProviderT.InternalProps;\n focusTrackers: ReturnType<typeof useFocusTracker>;\n menuOpenStatus: ReturnType<typeof useMenuOpenStatus>;\n handleChangeOpenedSubItems: Required<DSMenuButtonT.MenuBehaviouralLayerOptionalProps>['onDisplayedSubmenuChange'];\n};\n\nexport const useMenuItemEventsHandlers = ({\n propsWithDefault,\n focusTrackers,\n menuOpenStatus,\n handleChangeOpenedSubItems,\n}: UseMenuItemEventsHandlersConfig) => {\n const { onItemSelected, onActivateItem, selectedItems } = propsWithDefault;\n const { onOpinionatedClose } = menuOpenStatus;\n const {\n trackFocusFirstChildItem,\n trackFocusLastChildItem,\n trackFocusNextItem,\n trackFocusPreviousItem,\n trackFocusParentItem,\n trackFocusNode,\n focusedElementItemNode,\n } = focusTrackers;\n\n const openSubmenu = React.useCallback(\n ({\n itemNode,\n event,\n }: {\n itemNode: DSMenuButtonT.WithSubmenuMenuNodes;\n event?: React.KeyboardEvent | React.MouseEvent;\n }) => {\n if (!isWithSubmenuNode(itemNode)) {\n console.log('openSubmenu -> itemNode:', itemNode);\n throw FORBIDDEN_BEHAVIOURS.TRYING_TO_OPEN_SUBMENU_OF_NODE_WITHOUT_SUBMENU;\n }\n const subMenuNodesPath = getSubMenusPath(itemNode);\n const metainfo: SubmenuChangeMetainfo = { itemNode, event };\n const newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[] = [...subMenuNodesPath, itemNode];\n handleChangeOpenedSubItems(newOpenedItems, metainfo);\n },\n [handleChangeOpenedSubItems],\n );\n const closeCurrentSubmenu = React.useCallback(\n ({\n itemNode,\n event,\n }: {\n itemNode: DSMenuButtonT.PseudoFocusableMenuNodes;\n event?: React.KeyboardEvent | React.MouseEvent;\n }) => {\n const metainfo: SubmenuChangeMetainfo = { itemNode, event };\n const subMenuNodesPath = getSubMenusPath(itemNode);\n // if length is 0, it means the parent is the root node, so we close all the submenus\n if (subMenuNodesPath.length === 0) {\n handleChangeOpenedSubItems([], metainfo);\n return { currentSubmenuWasMainMenu: true };\n }\n\n // we want to close current submenu, so we pop the last element\n // getSubMenusPath guarantees the order by walkParents + reverse at the end\n subMenuNodesPath.pop();\n handleChangeOpenedSubItems(subMenuNodesPath, metainfo);\n return { currentSubmenuWasMainMenu: false };\n },\n [handleChangeOpenedSubItems],\n );\n /*\n * 13th August 2024:\n * https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/\n * Additional roles, states, and properties needed for the menu element are described in the Menu and Menubar Pattern.\n * https://www.w3.org/WAI/ARIA/apg/patterns/menubar/\n * Because menubar and menu elements are composite widgets as described in the practice for Keyboard Navigation Inside Components,\n * Tab and Shift + Tab do not move focus among the items in the menu.\n * Instead, the keyboard commands described in this section enable users to move focus among the elements in a menubar or menu.\n * Tab and Shift + Tab:\n * - Move focus into a menubar <- Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n * - When focus is on a menuitem in a menu or menubar, move focus out of the menu or menubar, and close all menus and submenus.\n * ************************************************************************************************************************************\n * this will be implemented by not setting document.activeElement to the menuitem but keeping it on the trigger button\n * why? because there is no javascript API to trigger a \"tab\"/\"shift+tab\" navigation and any algorithm trying to do so is fragile\n * also, this is enforced by w3.org too as per:\n * ************************************************************************************************************************************\n * Note that Tab and Shift + Tab do not move focus into a menu.\n * Unlike a menubar, a menu is not visually persistent,\n * and authors are responsible for ensuring focus moves to an item inside of a menu when the menu opens.\n *\n */\n const handleMenuItemEnterKeyDown = React.useCallback(\n ({ pseudoFocusedItemNode, event }: ItemKeydownHelpersArgs) => {\n // Enter:\n // - When focus is on a menuitem that has a submenu, opens the submenu and places focus on its first item.\n // ...\n if (isWithSubmenuOnlyNode(pseudoFocusedItemNode)) {\n openSubmenu({ itemNode: pseudoFocusedItemNode, event });\n trackFocusFirstChildItem(pseudoFocusedItemNode);\n } else {\n // - Otherwise, activates the item...\n\n // ----------------------------------\n // 4. Although it is recommended that authors avoid doing so,\n // some implementations of navigation menubars may have menuitem elements that both perform a function and open a submenu.\n // In such implementations, Enter and Space perform a navigation function,\n // e.g., load new content, while Down Arrow, in a horizontal menubar, opens the submenu associated with that same menuitem.\n // ---------------------------------\n // Based on an investigation, the above statement is not specific to \"navigation\" nor to ONLY \"menubars\", it really is about \"menuitems\" in general\n // as long as the role=\"menuitem\" & aria-haspopup=\"${id-of-the-submenu}\" & aria-expanded=\"${true/false}\" (& aria-orientation=\"vertical/horizontal\" if non-default)\n // are set, the Screen Readers will provide the same announcement for the menuitem regardless of the parent role\n\n // \"activation\" is a concept,\n // WCAG here implies that for menuitemscheckbox and menuitemsradio this triggers the selection\n // for menuitems (that doesn't fit selection nor submenus) it triggers the action\n // this also triggers enter -> single-select-item-with-submenu as expected\n if (isMultipleSelectNode(pseudoFocusedItemNode)) {\n const newSelection = getNewSelectionMultipleSelect(selectedItems, pseudoFocusedItemNode);\n onItemSelected(newSelection, { itemNode: pseudoFocusedItemNode, event });\n } else if (isSingleSelectNode(pseudoFocusedItemNode)) {\n const newSelection = getNewSelectionSingleSelect(selectedItems, pseudoFocusedItemNode);\n onItemSelected(newSelection, { itemNode: pseudoFocusedItemNode, event });\n } else {\n onActivateItem(pseudoFocusedItemNode, { itemNode: pseudoFocusedItemNode, event });\n }\n // ... and closes the menu.\n const metainfo: SubmenuChangeMetainfo = { itemNode: pseudoFocusedItemNode, event };\n const newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[] = [];\n handleChangeOpenedSubItems(newOpenedItems, metainfo);\n onOpinionatedClose();\n }\n },\n [\n trackFocusFirstChildItem,\n openSubmenu,\n handleChangeOpenedSubItems,\n onOpinionatedClose,\n selectedItems,\n onItemSelected,\n onActivateItem,\n ],\n );\n const handleMenuItemSpaceKeyDown = React.useCallback(\n ({ pseudoFocusedItemNode, event }: ItemKeydownHelpersArgs) => {\n // Space:\n // [X] (Optional): When focus is on a menuitem that has a submenu, opens the submenu and places focus on its first item.\n // ----------------------------------\n // 4. Although it is recommended that authors avoid doing so,\n // some implementations of navigation menubars may have menuitem elements that both perform a function and open a submenu.\n // In such implementations, Enter and Space perform a navigation function,\n // e.g., load new content, while Down Arrow, in a horizontal menubar, opens the submenu associated with that same menuitem.\n // ---------------------------------\n // Based on an investigation, the above statement is not specific to \"navigation\" nor to ONLY \"menubars\", it really is about \"menuitems\" in general\n // as long as the role=\"menuitem\" & aria-haspopup=\"${id-of-the-submenu}\" & aria-expanded=\"${true/false}\" (& aria-orientation=\"vertical/horizontal\" if non-default)\n // are set, the Screen Readers will provide the same announcement for the menuitem regardless of the parent role\n if (isWithSubmenuOnlyNode(pseudoFocusedItemNode)) {\n openSubmenu({ itemNode: pseudoFocusedItemNode, event });\n trackFocusFirstChildItem(pseudoFocusedItemNode);\n return;\n }\n // [X] (Optional): When focus is on a menuitemcheckbox, changes the state without closing the menu.\n if (isMultipleSelectNode(pseudoFocusedItemNode)) {\n const newSelection = getNewSelectionMultipleSelect(selectedItems, pseudoFocusedItemNode);\n onItemSelected(newSelection, { itemNode: pseudoFocusedItemNode, event });\n return;\n }\n // [X] (Optional): When focus is on a menuitemradio that is not checked, without closing the menu,\n // checks the focused menuitemradio and unchecks any other checked menuitemradio element in the same group.\n if (isSingleSelectNode(pseudoFocusedItemNode)) {\n const newSelection = getNewSelectionSingleSelect(selectedItems, pseudoFocusedItemNode);\n onItemSelected(newSelection, { itemNode: pseudoFocusedItemNode, event });\n return;\n }\n // [X] (Optional): When focus is on a menuitem that does not have a submenu, activates the menuitem and closes the menu.\n onActivateItem(pseudoFocusedItemNode, { itemNode: pseudoFocusedItemNode, event });\n\n const metainfo: SubmenuChangeMetainfo = { itemNode: pseudoFocusedItemNode, event };\n const newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[] = [];\n handleChangeOpenedSubItems(newOpenedItems, metainfo);\n onOpinionatedClose();\n },\n [\n onActivateItem,\n handleChangeOpenedSubItems,\n onOpinionatedClose,\n trackFocusFirstChildItem,\n openSubmenu,\n selectedItems,\n onItemSelected,\n ],\n );\n const handleMenuItemRightArrowKeyDown = React.useCallback(\n ({ pseudoFocusedItemNode, event }: ItemKeydownHelpersArgs) => {\n // Right Arrow:\n // [N/A] When focus is in a menubar, moves focus to the next item, optionally wrapping from the last to the first.\n // /\\ Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n\n // [X] When focus is in a menu and on a menuitem that has a submenu, opens the submenu and places focus on its first item.\n // [N/A] When focus is in a menu and on an item that does not have a submenu, performs the following 3 actions:\n // [N/A] Closes the submenu and any parent menus.\n // [N/A] Moves focus to the next item in the menubar.\n // /\\ Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n\n // [X] If focus is now on a menuitem with a submenu, either:\n // [X] (Recommended) opens the submenu of that menuitem without moving focus into the submenu,\n // /\\ we choose the recommended option\n // OR\n // [N/A] opens the submenu of that menuitem and places focus on the first item in the submenu.\n // ***********************************************************\n // Dimsum implements IoC, if APP side for whatever reason wants to open the new sub sub menu,\n // it's up to them to listen to the pseudo focus event and open the sub sub menu\n // ***********************************************************\n if (isWithSubmenuNode(pseudoFocusedItemNode)) {\n openSubmenu({ itemNode: pseudoFocusedItemNode, event });\n trackFocusFirstChildItem(pseudoFocusedItemNode);\n return;\n }\n // Note that if the menubar were not present, e.g., the menus were opened from a menubutton,\n // Right Arrow would not do anything when focus is on an item that does not have a submenu.\n return;\n },\n [openSubmenu, trackFocusFirstChildItem],\n );\n\n const handleMenuItemLeftArrowKeyDown = React.useCallback(\n ({ pseudoFocusedItemNode, event }: ItemKeydownHelpersArgs) => {\n // Left Arrow:\n // [N/A] When focus is in a menubar, moves focus to the previous item, optionally wrapping from the first to the last.\n // /\\ Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n\n // [X] When focus is in a submenu of an item in a menu, closes the submenu and returns focus to the parent menuitem.\n const { currentSubmenuWasMainMenu } = closeCurrentSubmenu({ itemNode: pseudoFocusedItemNode, event });\n if (!currentSubmenuWasMainMenu) {\n trackFocusParentItem(pseudoFocusedItemNode);\n }\n\n // [N/A] When focus is in a submenu of an item in a menubar, performs the following 3 actions:\n // [N/A] Closes the submenu.\n // [N/A] Moves focus to the previous item in the menubar.\n // [N/A] If focus is now on a menuitem with a submenu, either:\n // (Recommended) opens the submenu of that menuitem without moving focus into the submenu,\n // or\n // opens the submenu of that menuitem and places focus on the first item in the submenu.\n // /\\ Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n },\n [closeCurrentSubmenu, trackFocusParentItem],\n );\n\n const handleFocusableMenuItemKeyDown = React.useCallback<React.KeyboardEventHandler<HTMLDivElement>>(\n (event) => {\n const pseudoFocusedItemNode = focusedElementItemNode.current;\n // if there is no focused item, we can't handle the logics\n if (pseudoFocusedItemNode === null) throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_NODE_NOT_SET;\n // if the item contains an `onKeyDown` prop, we trigger it\n if (pseudoFocusedItemNode.plainItem.onKeyDown) pseudoFocusedItemNode.plainItem.onKeyDown(event);\n\n // Down Arrow:\n // [N/A] When focus is on a menuitem in a menubar, and that menuitem has a submenu, opens the submenu and places focus on the first item in the submenu.\n // /\\ Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n // [X] When focus is in a menu, moves focus to the next item,\n // [X] optionally wrapping from the last to the first.\n if (event.key === 'ArrowDown') {\n event?.preventDefault(); // if scrollbar are present, this keydown event should not interact with the scrollbar\n trackFocusNextItem(pseudoFocusedItemNode);\n return;\n }\n // Up Arrow:\n // [X] When focus is in a menu, moves focus to the previous item,\n // [X] optionally wrapping from the first to the last.\n // [N/A] (Optional): When focus is on a menuitem in a menubar, and that menuitem has a submenu, opens the submenu and places focus on the last item in the submenu.\n // /\\ Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n if (event.key === 'ArrowUp') {\n event?.preventDefault(); // if scrollbar are present, this keydown event should not interact with the scrollbar\n trackFocusPreviousItem(pseudoFocusedItemNode);\n return;\n }\n // Left Arrow:\n if (event.key === 'ArrowLeft') {\n event?.preventDefault(); // if scrollbar are present, this keydown event should not interact with the scrollbar\n handleMenuItemLeftArrowKeyDown({ pseudoFocusedItemNode, event });\n return;\n }\n // Home: If arrow key wrapping is not supported, moves focus to the first item in the current menu or menubar.\n if (event.key === 'Home') {\n if (!pseudoFocusedItemNode.parent) {\n console.log('handleFocusableMenuItemKeyDown -> Home > focused item node', pseudoFocusedItemNode);\n // should be impossible, at most the .parent is the root node, which is not able to trigger this event\n throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_HAS_NO_PARENT;\n }\n trackFocusFirstChildItem(pseudoFocusedItemNode.parent);\n return;\n }\n // End: If arrow key wrapping is not supported, moves focus to the last item in the current menu or menubar.\n if (event.key === 'End') {\n if (!pseudoFocusedItemNode.parent) {\n console.log('handleFocusableMenuItemKeyDown -> Home > focused item node', pseudoFocusedItemNode);\n // should be impossible, at most the .parent is the root node, which is not able to trigger this event\n throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_HAS_NO_PARENT;\n }\n trackFocusLastChildItem(pseudoFocusedItemNode.parent);\n return;\n }\n // Escape: Close the menu that contains focus and return focus to the element or context, e.g., menu button or parent menuitem, from which the menu was opened\n if (event.key === 'Escape') {\n const { currentSubmenuWasMainMenu } = closeCurrentSubmenu({ itemNode: pseudoFocusedItemNode, event });\n trackFocusParentItem(pseudoFocusedItemNode);\n // if the menu we are trying to close is the main menu, we adittionally close the main menu itself\n if (currentSubmenuWasMainMenu) {\n // if parent is the root node, we close also the main menu\n onOpinionatedClose();\n }\n return;\n }\n /* ************************************************************************************\n * ******* ACTIVATION & SUBMENU keys doesn't apply if the item is \"disabled\" **********\n * ************************************************************************************ */\n if (pseudoFocusedItemNode.plainItem.disabled) return;\n // Enter:\n if (event.key === 'Enter') {\n handleMenuItemEnterKeyDown({ pseudoFocusedItemNode, event });\n return;\n }\n // Space:\n if (event.key === ' ') {\n event?.preventDefault(); // if scrollbar are present, this keydown event should not interact with the scrollbar\n handleMenuItemSpaceKeyDown({ pseudoFocusedItemNode, event });\n return;\n }\n // Right Arrow:\n if (event.key === 'ArrowRight') {\n event?.preventDefault(); // if scrollbar are present, this keydown event should not interact with the scrollbar\n handleMenuItemRightArrowKeyDown({ pseudoFocusedItemNode, event });\n return;\n }\n },\n [\n focusedElementItemNode,\n handleMenuItemEnterKeyDown,\n handleMenuItemSpaceKeyDown,\n trackFocusNextItem,\n trackFocusPreviousItem,\n handleMenuItemRightArrowKeyDown,\n handleMenuItemLeftArrowKeyDown,\n trackFocusFirstChildItem,\n trackFocusLastChildItem,\n closeCurrentSubmenu,\n trackFocusParentItem,\n onOpinionatedClose,\n ],\n );\n\n const handleFocusableMenuItemOnMouseEnter = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes, event: React.MouseEvent) => {\n if (!isFocusableNode(itemNode)) {\n console.log('handleFocusableMenuItemOnMouseEnter > itemNode:', itemNode);\n throw FORBIDDEN_BEHAVIOURS.TRYING_TO_FOCUS_NON_FOCUSABLE_NODE;\n }\n // on hover -> we track the hovered item as the focused one on top of which events should work on\n trackFocusNode(itemNode);\n if (!isWithSubmenuNode(itemNode)) {\n // if the item has nosubmenu we close all the siblings submenus\n const subMenuNodesPath = getSubMenusPath(itemNode);\n const metainfo: SubmenuChangeMetainfo = { itemNode, event };\n const newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[] = [...subMenuNodesPath];\n handleChangeOpenedSubItems(newOpenedItems, metainfo);\n return;\n }\n // if the item is disabled, we don't open the submenu\n if (itemNode.plainItem.disabled) return;\n // if not disabled and it has a submenu, we open it\n openSubmenu({ itemNode, event });\n },\n [handleChangeOpenedSubItems, openSubmenu, trackFocusNode],\n );\n\n const handleFocusableMenuItemClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n const pseudoFocusedItemNode = focusedElementItemNode.current;\n if (pseudoFocusedItemNode === null) throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_NODE_NOT_SET;\n // if the item is disabled, we don't do anything\n if (pseudoFocusedItemNode.plainItem.disabled) return;\n // we need to handle which submenu needs to close automagically based on the click\n // starting from the itemNode, we check:\n // - the parent of the itemNode is root?\n // - yes -> we close all the submenus\n const parentMenuNode = pseudoFocusedItemNode.parent;\n if (isRootNode(parentMenuNode)) {\n const metainfo: SubmenuChangeMetainfo = { itemNode: pseudoFocusedItemNode, event };\n const newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[] = [];\n handleChangeOpenedSubItems(newOpenedItems, metainfo);\n } else {\n // - no -> we close all the submenus that are not in the path to the root of the itemNode\n // this is necessary on click because the user can still interact with other (visual) depths of the menu\n // during keyboard navigation, the user is limited to the current (visual) depth\n const newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[] = [...getSubMenusPath(pseudoFocusedItemNode)];\n // - if the clicked node has a submenu, keep it open\n if (isWithSubmenuNode(pseudoFocusedItemNode)) {\n newOpenedItems.push(pseudoFocusedItemNode);\n }\n const metainfo: SubmenuChangeMetainfo = { itemNode: pseudoFocusedItemNode, event };\n handleChangeOpenedSubItems(newOpenedItems, metainfo);\n }\n\n // to all effects and purposes, the click event is the same as the space key\n // the main difference between enter and space is that\n // - enter ALWAYS closes the menu excepts for submenus\n // - space closes the menu if \"activable\", selections doesn't, submenus doesn't\n handleMenuItemSpaceKeyDown({ pseudoFocusedItemNode, event });\n // if the item contains an `onClick` prop, we trigger it\n if (pseudoFocusedItemNode.plainItem.onClick) pseudoFocusedItemNode.plainItem.onClick(event);\n },\n [focusedElementItemNode, handleMenuItemSpaceKeyDown, handleChangeOpenedSubItems],\n );\n\n return React.useMemo(\n () => ({\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemClick,\n handleFocusableMenuItemOnMouseEnter,\n }),\n [handleFocusableMenuItemClick, handleFocusableMenuItemKeyDown, handleFocusableMenuItemOnMouseEnter],\n );\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable no-console */\n/* eslint-disable max-lines */\n// in this files the returns are not useless, they are used to clearly demark the intended behavior shortcircuit for the next developer that reads the code\n/* eslint-disable no-useless-return */\n/* eslint-disable complexity */\n/* eslint-disable max-statements */\nimport React from 'react';\nimport { type DSMenuButtonT } from '../../../react-desc-prop-types.js';\nimport {\n isFocusableNode,\n isMultipleSelectNode,\n isRootNode,\n isSingleSelectNode,\n isWithSubmenuNode,\n isWithSubmenuOnlyNode,\n} from '../../../utils/nodesTypeguardsAndGetters.js';\nimport { FORBIDDEN_BEHAVIOURS, UNEXPECTED_INTERNAL_ERRORS } from '../constants/Errors.js';\nimport { type DSMenuBehaviouralContextProviderT } from '../react-desc-prop-types.js';\nimport { getNewSelectionMultipleSelect } from '../utils/multipleSelectionHelpers.js';\nimport { getSubMenusPath } from '../utils/nodeGettersByCriterias.js';\nimport { getNewSelectionSingleSelect } from '../utils/singleSelectionHelpers.js';\nimport type { useFocusTracker } from './useFocusTracker.js';\nimport type { useMenuOpenStatus } from './useMenuOpenStatus.js';\n\ntype ItemKeydownHelpersArgs = {\n pseudoFocusedItemNode: DSMenuButtonT.PseudoFocusableMenuNodes;\n event?: React.KeyboardEvent | React.MouseEvent;\n};\ntype SubmenuChangeMetainfo = {\n itemNode: DSMenuButtonT.PseudoFocusableMenuNodes;\n event?: React.SyntheticEvent;\n};\n\ntype UseMenuItemEventsHandlersConfig = {\n propsWithDefault: DSMenuBehaviouralContextProviderT.InternalProps;\n focusTrackers: ReturnType<typeof useFocusTracker>;\n menuOpenStatus: ReturnType<typeof useMenuOpenStatus>;\n handleChangeOpenedSubItems: Required<DSMenuButtonT.MenuBehaviouralLayerOptionalProps>['onDisplayedSubmenuChange'];\n};\n\nexport const useMenuItemEventsHandlers = ({\n propsWithDefault,\n focusTrackers,\n menuOpenStatus,\n handleChangeOpenedSubItems,\n}: UseMenuItemEventsHandlersConfig) => {\n const { onItemSelected, onActivateItem, selectedItems } = propsWithDefault;\n const { onOpinionatedClose } = menuOpenStatus;\n const {\n trackFocusFirstChildItem,\n trackFocusLastChildItem,\n trackFocusNextItem,\n trackFocusPreviousItem,\n trackFocusParentItem,\n trackFocusNode,\n focusedElementItemNode,\n } = focusTrackers;\n\n const openSubmenu = React.useCallback(\n ({\n itemNode,\n event,\n }: {\n itemNode: DSMenuButtonT.WithSubmenuMenuNodes;\n event?: React.KeyboardEvent | React.MouseEvent | React.FocusEvent;\n }) => {\n if (!isWithSubmenuNode(itemNode)) {\n console.log('openSubmenu -> itemNode:', itemNode);\n throw FORBIDDEN_BEHAVIOURS.TRYING_TO_OPEN_SUBMENU_OF_NODE_WITHOUT_SUBMENU;\n }\n const subMenuNodesPath = getSubMenusPath(itemNode);\n const metainfo: SubmenuChangeMetainfo = { itemNode, event };\n const newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[] = [...subMenuNodesPath, itemNode];\n handleChangeOpenedSubItems(newOpenedItems, metainfo);\n },\n [handleChangeOpenedSubItems],\n );\n const closeCurrentSubmenu = React.useCallback(\n ({\n itemNode,\n event,\n }: {\n itemNode: DSMenuButtonT.PseudoFocusableMenuNodes;\n event?: React.KeyboardEvent | React.MouseEvent;\n }) => {\n const metainfo: SubmenuChangeMetainfo = { itemNode, event };\n const subMenuNodesPath = getSubMenusPath(itemNode);\n // if length is 0, it means the parent is the root node, so we close all the submenus\n if (subMenuNodesPath.length === 0) {\n handleChangeOpenedSubItems([], metainfo);\n return { currentSubmenuWasMainMenu: true };\n }\n\n // we want to close current submenu, so we pop the last element\n // getSubMenusPath guarantees the order by walkParents + reverse at the end\n subMenuNodesPath.pop();\n handleChangeOpenedSubItems(subMenuNodesPath, metainfo);\n return { currentSubmenuWasMainMenu: false };\n },\n [handleChangeOpenedSubItems],\n );\n /*\n * 13th August 2024:\n * https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/\n * Additional roles, states, and properties needed for the menu element are described in the Menu and Menubar Pattern.\n * https://www.w3.org/WAI/ARIA/apg/patterns/menubar/\n * Because menubar and menu elements are composite widgets as described in the practice for Keyboard Navigation Inside Components,\n * Tab and Shift + Tab do not move focus among the items in the menu.\n * Instead, the keyboard commands described in this section enable users to move focus among the elements in a menubar or menu.\n * Tab and Shift + Tab:\n * - Move focus into a menubar <- Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n * - When focus is on a menuitem in a menu or menubar, move focus out of the menu or menubar, and close all menus and submenus.\n * ************************************************************************************************************************************\n * this will be implemented by not setting document.activeElement to the menuitem but keeping it on the trigger button\n * why? because there is no javascript API to trigger a \"tab\"/\"shift+tab\" navigation and any algorithm trying to do so is fragile\n * also, this is enforced by w3.org too as per:\n * ************************************************************************************************************************************\n * Note that Tab and Shift + Tab do not move focus into a menu.\n * Unlike a menubar, a menu is not visually persistent,\n * and authors are responsible for ensuring focus moves to an item inside of a menu when the menu opens.\n *\n */\n const handleMenuItemEnterKeyDown = React.useCallback(\n ({ pseudoFocusedItemNode, event }: ItemKeydownHelpersArgs) => {\n // Enter:\n // - When focus is on a menuitem that has a submenu, opens the submenu and places focus on its first item.\n // ...\n if (isWithSubmenuOnlyNode(pseudoFocusedItemNode)) {\n openSubmenu({ itemNode: pseudoFocusedItemNode, event });\n trackFocusFirstChildItem(pseudoFocusedItemNode);\n } else {\n // - Otherwise, activates the item...\n\n // ----------------------------------\n // 4. Although it is recommended that authors avoid doing so,\n // some implementations of navigation menubars may have menuitem elements that both perform a function and open a submenu.\n // In such implementations, Enter and Space perform a navigation function,\n // e.g., load new content, while Down Arrow, in a horizontal menubar, opens the submenu associated with that same menuitem.\n // ---------------------------------\n // Based on an investigation, the above statement is not specific to \"navigation\" nor to ONLY \"menubars\", it really is about \"menuitems\" in general\n // as long as the role=\"menuitem\" & aria-haspopup=\"${id-of-the-submenu}\" & aria-expanded=\"${true/false}\" (& aria-orientation=\"vertical/horizontal\" if non-default)\n // are set, the Screen Readers will provide the same announcement for the menuitem regardless of the parent role\n\n // \"activation\" is a concept,\n // WCAG here implies that for menuitemscheckbox and menuitemsradio this triggers the selection\n // for menuitems (that doesn't fit selection nor submenus) it triggers the action\n // this also triggers enter -> single-select-item-with-submenu as expected\n if (isMultipleSelectNode(pseudoFocusedItemNode)) {\n // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator\n // useAdvancedValidation guarantees the non-null in this \"if\" branch\n const newSelection = getNewSelectionMultipleSelect(selectedItems!, pseudoFocusedItemNode);\n onItemSelected!(newSelection, { itemNode: pseudoFocusedItemNode, event });\n } else if (isSingleSelectNode(pseudoFocusedItemNode)) {\n // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator\n // useAdvancedValidation guarantees the non-null in this \"if\" branch\n const newSelection = getNewSelectionSingleSelect(selectedItems!, pseudoFocusedItemNode);\n onItemSelected!(newSelection, { itemNode: pseudoFocusedItemNode, event });\n } else {\n // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator\n // useAdvancedValidation guarantees the non-null in this \"if\" branch\n onActivateItem!(pseudoFocusedItemNode, { itemNode: pseudoFocusedItemNode, event });\n }\n // ... and closes the menu.\n const metainfo: SubmenuChangeMetainfo = { itemNode: pseudoFocusedItemNode, event };\n const newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[] = [];\n handleChangeOpenedSubItems(newOpenedItems, metainfo);\n onOpinionatedClose();\n }\n },\n [\n trackFocusFirstChildItem,\n openSubmenu,\n handleChangeOpenedSubItems,\n onOpinionatedClose,\n selectedItems,\n onItemSelected,\n onActivateItem,\n ],\n );\n const handleMenuItemSpaceKeyDown = React.useCallback(\n ({ pseudoFocusedItemNode, event }: ItemKeydownHelpersArgs) => {\n // Space:\n // [X] (Optional): When focus is on a menuitem that has a submenu, opens the submenu and places focus on its first item.\n // ----------------------------------\n // 4. Although it is recommended that authors avoid doing so,\n // some implementations of navigation menubars may have menuitem elements that both perform a function and open a submenu.\n // In such implementations, Enter and Space perform a navigation function,\n // e.g., load new content, while Down Arrow, in a horizontal menubar, opens the submenu associated with that same menuitem.\n // ---------------------------------\n // Based on an investigation, the above statement is not specific to \"navigation\" nor to ONLY \"menubars\", it really is about \"menuitems\" in general\n // as long as the role=\"menuitem\" & aria-haspopup=\"${id-of-the-submenu}\" & aria-expanded=\"${true/false}\" (& aria-orientation=\"vertical/horizontal\" if non-default)\n // are set, the Screen Readers will provide the same announcement for the menuitem regardless of the parent role\n if (isWithSubmenuOnlyNode(pseudoFocusedItemNode)) {\n openSubmenu({ itemNode: pseudoFocusedItemNode, event });\n trackFocusFirstChildItem(pseudoFocusedItemNode);\n return;\n }\n // [X] (Optional): When focus is on a menuitemcheckbox, changes the state without closing the menu.\n if (isMultipleSelectNode(pseudoFocusedItemNode)) {\n // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator\n // useAdvancedValidation guarantees the non-null in this \"if\" branch\n const newSelection = getNewSelectionMultipleSelect(selectedItems!, pseudoFocusedItemNode);\n onItemSelected!(newSelection, { itemNode: pseudoFocusedItemNode, event });\n return;\n }\n // [X] (Optional): When focus is on a menuitemradio that is not checked, without closing the menu,\n // checks the focused menuitemradio and unchecks any other checked menuitemradio element in the same group.\n if (isSingleSelectNode(pseudoFocusedItemNode)) {\n // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator\n // useAdvancedValidation guarantees the non-null in this \"if\" branch\n const newSelection = getNewSelectionSingleSelect(selectedItems!, pseudoFocusedItemNode);\n onItemSelected!(newSelection, { itemNode: pseudoFocusedItemNode, event });\n return;\n }\n // [X] (Optional): When focus is on a menuitem that does not have a submenu, activates the menuitem and closes the menu.\n onActivateItem?.(pseudoFocusedItemNode, { itemNode: pseudoFocusedItemNode, event });\n\n const metainfo: SubmenuChangeMetainfo = { itemNode: pseudoFocusedItemNode, event };\n const newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[] = [];\n handleChangeOpenedSubItems(newOpenedItems, metainfo);\n onOpinionatedClose();\n },\n [\n onActivateItem,\n handleChangeOpenedSubItems,\n onOpinionatedClose,\n trackFocusFirstChildItem,\n openSubmenu,\n selectedItems,\n onItemSelected,\n ],\n );\n const handleMenuItemRightArrowKeyDown = React.useCallback(\n ({ pseudoFocusedItemNode, event }: ItemKeydownHelpersArgs) => {\n // Right Arrow:\n // [N/A] When focus is in a menubar, moves focus to the next item, optionally wrapping from the last to the first.\n // /\\ Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n\n // [X] When focus is in a menu and on a menuitem that has a submenu, opens the submenu and places focus on its first item.\n // [N/A] When focus is in a menu and on an item that does not have a submenu, performs the following 3 actions:\n // [N/A] Closes the submenu and any parent menus.\n // [N/A] Moves focus to the next item in the menubar.\n // /\\ Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n\n // [X] If focus is now on a menuitem with a submenu, either:\n // [X] (Recommended) opens the submenu of that menuitem without moving focus into the submenu,\n // /\\ we choose the recommended option\n // OR\n // [N/A] opens the submenu of that menuitem and places focus on the first item in the submenu.\n // ***********************************************************\n // Dimsum implements IoC, if APP side for whatever reason wants to open the new sub sub menu,\n // it's up to them to listen to the pseudo focus event and open the sub sub menu\n // ***********************************************************\n if (isWithSubmenuNode(pseudoFocusedItemNode)) {\n openSubmenu({ itemNode: pseudoFocusedItemNode, event });\n trackFocusFirstChildItem(pseudoFocusedItemNode);\n return;\n }\n // Note that if the menubar were not present, e.g., the menus were opened from a menubutton,\n // Right Arrow would not do anything when focus is on an item that does not have a submenu.\n return;\n },\n [openSubmenu, trackFocusFirstChildItem],\n );\n\n const handleMenuItemLeftArrowKeyDown = React.useCallback(\n ({ pseudoFocusedItemNode, event }: ItemKeydownHelpersArgs) => {\n // Left Arrow:\n // [N/A] When focus is in a menubar, moves focus to the previous item, optionally wrapping from the first to the last.\n // /\\ Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n\n // [X] When focus is in a submenu of an item in a menu, closes the submenu and returns focus to the parent menuitem.\n const { currentSubmenuWasMainMenu } = closeCurrentSubmenu({ itemNode: pseudoFocusedItemNode, event });\n if (!currentSubmenuWasMainMenu) {\n trackFocusParentItem(pseudoFocusedItemNode);\n }\n\n // [N/A] When focus is in a submenu of an item in a menubar, performs the following 3 actions:\n // [N/A] Closes the submenu.\n // [N/A] Moves focus to the previous item in the menubar.\n // [N/A] If focus is now on a menuitem with a submenu, either:\n // (Recommended) opens the submenu of that menuitem without moving focus into the submenu,\n // or\n // opens the submenu of that menuitem and places focus on the first item in the submenu.\n // /\\ Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n },\n [closeCurrentSubmenu, trackFocusParentItem],\n );\n\n const handleFocusableMenuItemKeyDown = React.useCallback<React.KeyboardEventHandler<HTMLDivElement>>(\n (event) => {\n const pseudoFocusedItemNode = focusedElementItemNode.current;\n // if there is no focused item, we can't handle the logics\n if (pseudoFocusedItemNode === null) throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_NODE_NOT_SET;\n // if the item contains an `onKeyDown` prop, we trigger it\n if (pseudoFocusedItemNode.plainItem.onKeyDown) pseudoFocusedItemNode.plainItem.onKeyDown(event);\n\n // Down Arrow:\n // [N/A] When focus is on a menuitem in a menubar, and that menuitem has a submenu, opens the submenu and places focus on the first item in the submenu.\n // /\\ Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n // [X] When focus is in a menu, moves focus to the next item,\n // [X] optionally wrapping from the last to the first.\n if (event.key === 'ArrowDown') {\n event?.preventDefault(); // if scrollbar are present, this keydown event should not interact with the scrollbar\n trackFocusNextItem(pseudoFocusedItemNode);\n return;\n }\n // Up Arrow:\n // [X] When focus is in a menu, moves focus to the previous item,\n // [X] optionally wrapping from the first to the last.\n // [N/A] (Optional): When focus is on a menuitem in a menubar, and that menuitem has a submenu, opens the submenu and places focus on the last item in the submenu.\n // /\\ Not relevant for this component, this is ONLY FOR MENU, not for MENUBARS\n if (event.key === 'ArrowUp') {\n event?.preventDefault(); // if scrollbar are present, this keydown event should not interact with the scrollbar\n trackFocusPreviousItem(pseudoFocusedItemNode);\n return;\n }\n // Left Arrow:\n if (event.key === 'ArrowLeft') {\n event?.preventDefault(); // if scrollbar are present, this keydown event should not interact with the scrollbar\n handleMenuItemLeftArrowKeyDown({ pseudoFocusedItemNode, event });\n return;\n }\n // Home: If arrow key wrapping is not supported, moves focus to the first item in the current menu or menubar.\n if (event.key === 'Home') {\n if (!pseudoFocusedItemNode.parent) {\n console.log('handleFocusableMenuItemKeyDown -> Home > focused item node', pseudoFocusedItemNode);\n // should be impossible, at most the .parent is the root node, which is not able to trigger this event\n throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_HAS_NO_PARENT;\n }\n trackFocusFirstChildItem(pseudoFocusedItemNode.parent);\n return;\n }\n // End: If arrow key wrapping is not supported, moves focus to the last item in the current menu or menubar.\n if (event.key === 'End') {\n if (!pseudoFocusedItemNode.parent) {\n console.log('handleFocusableMenuItemKeyDown -> Home > focused item node', pseudoFocusedItemNode);\n // should be impossible, at most the .parent is the root node, which is not able to trigger this event\n throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_HAS_NO_PARENT;\n }\n trackFocusLastChildItem(pseudoFocusedItemNode.parent);\n return;\n }\n // Escape: Close the menu that contains focus and return focus to the element or context, e.g., menu button or parent menuitem, from which the menu was opened\n if (event.key === 'Escape') {\n const { currentSubmenuWasMainMenu } = closeCurrentSubmenu({ itemNode: pseudoFocusedItemNode, event });\n trackFocusParentItem(pseudoFocusedItemNode);\n // if the menu we are trying to close is the main menu, we adittionally close the main menu itself\n if (currentSubmenuWasMainMenu) {\n // if parent is the root node, we close also the main menu\n onOpinionatedClose();\n }\n return;\n }\n /* ************************************************************************************\n * ******* ACTIVATION & SUBMENU keys doesn't apply if the item is \"disabled\" **********\n * ************************************************************************************ */\n if (pseudoFocusedItemNode.plainItem.disabled) return;\n // Enter:\n if (event.key === 'Enter') {\n handleMenuItemEnterKeyDown({ pseudoFocusedItemNode, event });\n return;\n }\n // Space:\n if (event.key === ' ') {\n event?.preventDefault(); // if scrollbar are present, this keydown event should not interact with the scrollbar\n handleMenuItemSpaceKeyDown({ pseudoFocusedItemNode, event });\n return;\n }\n // Right Arrow:\n if (event.key === 'ArrowRight') {\n event?.preventDefault(); // if scrollbar are present, this keydown event should not interact with the scrollbar\n handleMenuItemRightArrowKeyDown({ pseudoFocusedItemNode, event });\n return;\n }\n },\n [\n focusedElementItemNode,\n handleMenuItemEnterKeyDown,\n handleMenuItemSpaceKeyDown,\n trackFocusNextItem,\n trackFocusPreviousItem,\n handleMenuItemRightArrowKeyDown,\n handleMenuItemLeftArrowKeyDown,\n trackFocusFirstChildItem,\n trackFocusLastChildItem,\n closeCurrentSubmenu,\n trackFocusParentItem,\n onOpinionatedClose,\n ],\n );\n const handleFocusableMenuItemClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n const pseudoFocusedItemNode = focusedElementItemNode.current;\n if (pseudoFocusedItemNode === null) throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_NODE_NOT_SET;\n // if the item is disabled, we don't do anything\n if (pseudoFocusedItemNode.plainItem.disabled) return;\n // we need to handle which submenu needs to close automagically based on the click\n // starting from the itemNode, we check:\n // - the parent of the itemNode is root?\n // - yes -> we close all the submenus\n const parentMenuNode = pseudoFocusedItemNode.parent;\n if (isRootNode(parentMenuNode)) {\n const metainfo: SubmenuChangeMetainfo = { itemNode: pseudoFocusedItemNode, event };\n const newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[] = [];\n handleChangeOpenedSubItems(newOpenedItems, metainfo);\n } else {\n // - no -> we close all the submenus that are not in the path to the root of the itemNode\n // this is necessary on click because the user can still interact with other (visual) depths of the menu\n // during keyboard navigation, the user is limited to the current (visual) depth\n const newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[] = [...getSubMenusPath(pseudoFocusedItemNode)];\n // - if the clicked node has a submenu, keep it open\n if (isWithSubmenuNode(pseudoFocusedItemNode)) {\n newOpenedItems.push(pseudoFocusedItemNode);\n }\n const metainfo: SubmenuChangeMetainfo = { itemNode: pseudoFocusedItemNode, event };\n handleChangeOpenedSubItems(newOpenedItems, metainfo);\n }\n\n // to all effects and purposes, the click event is the same as the space key\n // the main difference between enter and space is that\n // - enter ALWAYS closes the menu excepts for submenus\n // - space closes the menu if \"activable\", selections doesn't, submenus doesn't\n handleMenuItemSpaceKeyDown({ pseudoFocusedItemNode, event });\n // if the item contains an `onClick` prop, we trigger it\n if (pseudoFocusedItemNode.plainItem.onClick) pseudoFocusedItemNode.plainItem.onClick(event);\n },\n [focusedElementItemNode, handleMenuItemSpaceKeyDown, handleChangeOpenedSubItems],\n );\n\n // the \"menu-button\" widget is an opinionated widget with a specific behaviour to follow when a focusable item is \"focused\"\n // this function achieve the opinionated \"focus an item\" opinionated behaviour (regardless of why the item is focused)\n const opinionatedFocusBehaviour = React.useCallback(\n // we currently know only one \"event\" that can trigger this opinionated behaviour\n // - focus => React.FocusEvent <-- triggered by ATs \"focus mode\" or \"virtual cursor\" navigation\n // NOTE:\n // mouseEnter => React.MouseEvent\n // still ends up calling this function, but as a side effect of mouse-enter focusing the item, not as the main event\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes, event: React.FocusEvent) => {\n if (!isFocusableNode(itemNode)) {\n console.log('handleFocusableMenuItemOnMouseEnter > itemNode:', itemNode);\n throw FORBIDDEN_BEHAVIOURS.TRYING_TO_FOCUS_NON_FOCUSABLE_NODE;\n }\n // on hover -> we track the hovered item as the focused one on top of which events should work on\n trackFocusNode(itemNode);\n if (!isWithSubmenuNode(itemNode)) {\n // if the item has nosubmenu we close all the siblings submenus\n const subMenuNodesPath = getSubMenusPath(itemNode);\n const metainfo: SubmenuChangeMetainfo = { itemNode, event };\n const newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[] = [...subMenuNodesPath];\n handleChangeOpenedSubItems(newOpenedItems, metainfo);\n return;\n }\n // if the item is disabled, we don't open the submenu, and there is nothing else to do\n if (itemNode.plainItem.disabled) return;\n // if not disabled and it has a submenu, we open it, and there is nothing else to do\n openSubmenu({ itemNode, event });\n },\n [handleChangeOpenedSubItems, openSubmenu, trackFocusNode],\n );\n\n // when an item is hovered, we focus it\n // this effectively achieves:\n // - the item is focused (it trigger the handleFocusableMenuItemNativeFocusEvent function because render runs node.focus())\n // - if the user presses a keyboard key, the interaction will work starting from the (hovered hence focused) item\n const handleFocusableMenuItemOnMouseEnter = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n if (!isFocusableNode(itemNode)) {\n console.log('handleFocusableMenuItemOnMouseEnter > itemNode:', itemNode);\n throw FORBIDDEN_BEHAVIOURS.TRYING_TO_FOCUS_NON_FOCUSABLE_NODE;\n }\n // on hover -> we track the hovered item as the focused one on top of which events should work on\n trackFocusNode(itemNode);\n },\n [trackFocusNode],\n );\n\n const handleFocusableMenuItemNativeFocusEvent = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes, event: React.FocusEvent) => {\n opinionatedFocusBehaviour(itemNode, event);\n },\n [opinionatedFocusBehaviour],\n );\n\n return React.useMemo(\n () => ({\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemClick,\n handleFocusableMenuItemOnMouseEnter,\n handleFocusableMenuItemNativeFocusEvent,\n }),\n [\n handleFocusableMenuItemClick,\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemNativeFocusEvent,\n handleFocusableMenuItemOnMouseEnter,\n ],\n );\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -19,7 +19,8 @@ const ActivableMenuItem = ({
19
19
  menuItemEventsHandlers: {
20
20
  handleFocusableMenuItemKeyDown,
21
21
  handleFocusableMenuItemClick,
22
- handleFocusableMenuItemOnMouseEnter
22
+ handleFocusableMenuItemOnMouseEnter,
23
+ handleFocusableMenuItemNativeFocusEvent
23
24
  }
24
25
  } = React2.useContext(MenuBehaviouralContextProviderContext);
25
26
  const gridLayout = React2.useMemo(() => {
@@ -44,11 +45,14 @@ const ActivableMenuItem = ({
44
45
  // the logic here actually receives a ref to a HTMLDivElement,
45
46
  // but the component must think this is a HTMLLIElement ref callback
46
47
  );
47
- const handleOnMouseEnter = React2.useCallback(
48
+ const handleOnMouseEnter = React2.useCallback(() => {
49
+ handleFocusableMenuItemOnMouseEnter(itemNode);
50
+ }, [handleFocusableMenuItemOnMouseEnter, itemNode]);
51
+ const handleOnFocus = React2.useCallback(
48
52
  (e) => {
49
- handleFocusableMenuItemOnMouseEnter(itemNode, e);
53
+ handleFocusableMenuItemNativeFocusEvent(itemNode, e);
50
54
  },
51
- [handleFocusableMenuItemOnMouseEnter, itemNode]
55
+ [handleFocusableMenuItemNativeFocusEvent, itemNode]
52
56
  );
53
57
  const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\s/g, "")}`;
54
58
  return /* @__PURE__ */ jsx(
@@ -58,6 +62,7 @@ const ActivableMenuItem = ({
58
62
  onKeyDown: handleFocusableMenuItemKeyDown,
59
63
  onClick: handleFocusableMenuItemClick,
60
64
  onMouseEnter: handleOnMouseEnter,
65
+ onFocus: handleOnFocus,
61
66
  as: "div",
62
67
  id: `${spacelessDsIdForDom}`,
63
68
  role: "menuitem",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/DSMenuItemRendererFactory/ActivableMenuItem.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\nimport {\n StyleMenuItemLabel,\n StyleMenuItemSecondaryLabel,\n StyledContentWrapper,\n StyledGlobalMenuItemWrapper,\n} from '@elliemae/ds-menu-items-commons';\nimport React from 'react';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { MenuBehaviouralContextProviderContext } from '../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js';\nimport { MENU_FOCUS_REGIONS } from '../DSMenuBehaviouralContextProvider/constants/index.js';\n\nexport const ActivableMenuItem: React.ComponentType<{ itemNode: DSMenuButtonT.MenuNodeActivableItem }> = ({\n itemNode,\n}) => {\n const { dsId, plainItem } = itemNode;\n const { label, secondaryLabel, leftDecoration: LeftDecComponent, minWidth, disabled } = plainItem;\n\n const {\n focusRegion,\n menuItemEventsHandlers: {\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemClick,\n handleFocusableMenuItemOnMouseEnter,\n },\n } = React.useContext(MenuBehaviouralContextProviderContext);\n\n const gridLayout = React.useMemo(() => {\n const cols = LeftDecComponent ? ['min-content', 'auto'] : ['auto'];\n if (secondaryLabel) cols.push('auto');\n return cols;\n }, [LeftDecComponent, secondaryLabel]);\n\n const focusedRegionPerformanceHelper = React.useRef(focusRegion);\n focusedRegionPerformanceHelper.current = focusRegion;\n\n const isFocused = focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId);\n\n const handleFocusOnRender = React.useCallback(\n (node: HTMLDivElement) => {\n setTimeout(() => {\n if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {\n node.focus();\n }\n });\n },\n // we need to change the callback reference every time the focusRegion changes or else the focus will not be set\n [dsId, focusRegion],\n // we are using the \"as='div'\", typescript is not able to infer the correct type\n // the logic here actually receives a ref to a HTMLDivElement,\n // but the component must think this is a HTMLLIElement ref callback\n ) as unknown as React.RefCallback<HTMLLIElement>;\n const handleOnMouseEnter = React.useCallback<React.MouseEventHandler<HTMLDivElement>>(\n (e) => {\n handleFocusableMenuItemOnMouseEnter(itemNode, e);\n },\n [handleFocusableMenuItemOnMouseEnter, itemNode],\n );\n\n const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\\s/g, '')}`;\n\n return (\n <StyledGlobalMenuItemWrapper\n innerRef={handleFocusOnRender}\n onKeyDown={handleFocusableMenuItemKeyDown}\n onClick={handleFocusableMenuItemClick}\n onMouseEnter={handleOnMouseEnter}\n as=\"div\"\n id={`${spacelessDsIdForDom}`}\n role=\"menuitem\"\n tabIndex={isFocused ? 0 : -1}\n aria-disabled={disabled}\n applyAriaDisabled={disabled}\n >\n <StyledContentWrapper\n cols={gridLayout}\n minHeight=\"16px\"\n gutter=\"xxs\"\n alignItems=\"center\"\n minWidth={minWidth ?? undefined}\n >\n {LeftDecComponent ? <LeftDecComponent /> : null}\n <StyleMenuItemLabel>{label}</StyleMenuItemLabel>\n {secondaryLabel !== undefined && (\n <StyleMenuItemSecondaryLabel disabled={disabled}>{secondaryLabel}</StyleMenuItemSecondaryLabel>\n )}\n </StyledContentWrapper>\n </StyledGlobalMenuItemWrapper>\n );\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;AC0EjB,SAOsB,KAPtB;AAzEN;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,OAAOA,YAAW;AAElB,SAAS,6CAA6C;AACtD,SAAS,0BAA0B;AAE5B,MAAM,oBAA4F,CAAC;AAAA,EACxG;AACF,MAAM;AACJ,QAAM,EAAE,MAAM,UAAU,IAAI;AAC5B,QAAM,EAAE,OAAO,gBAAgB,gBAAgB,kBAAkB,UAAU,SAAS,IAAI;AAExF,QAAM;AAAA,IACJ;AAAA,IACA,wBAAwB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,IAAIA,OAAM,WAAW,qCAAqC;AAE1D,QAAM,aAAaA,OAAM,QAAQ,MAAM;AACrC,UAAM,OAAO,mBAAmB,CAAC,eAAe,MAAM,IAAI,CAAC,MAAM;AACjE,QAAI,eAAgB,MAAK,KAAK,MAAM;AACpC,WAAO;AAAA,EACT,GAAG,CAAC,kBAAkB,cAAc,CAAC;AAErC,QAAM,iCAAiCA,OAAM,OAAO,WAAW;AAC/D,iCAA+B,UAAU;AAEzC,QAAM,YAAY,gBAAgB,mBAAmB,aAAa,IAAI;AAEtE,QAAM,sBAAsBA,OAAM;AAAA,IAChC,CAAC,SAAyB;AACxB,iBAAW,MAAM;AACf,YAAI,QAAQ,gBAAgB,mBAAmB,aAAa,IAAI,GAAG;AACjE,eAAK,MAAM;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH;AAAA;AAAA,IAEA,CAAC,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA,EAIpB;AACA,QAAM,qBAAqBA,OAAM;AAAA,IAC/B,CAAC,MAAM;AACL,0CAAoC,UAAU,CAAC;AAAA,IACjD;AAAA,IACA,CAAC,qCAAqC,QAAQ;AAAA,EAChD;AAEA,QAAM,sBAAsB,gBAAgB,GAAG,IAAI,GAAG,QAAQ,OAAO,EAAE,CAAC;AAExE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,WAAW;AAAA,MACX,SAAS;AAAA,MACT,cAAc;AAAA,MACd,IAAG;AAAA,MACH,IAAI,GAAG,mBAAmB;AAAA,MAC1B,MAAK;AAAA,MACL,UAAU,YAAY,IAAI;AAAA,MAC1B,iBAAe;AAAA,MACf,mBAAmB;AAAA,MAEnB;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,WAAU;AAAA,UACV,QAAO;AAAA,UACP,YAAW;AAAA,UACX,UAAU,YAAY;AAAA,UAErB;AAAA,+BAAmB,oBAAC,oBAAiB,IAAK;AAAA,YAC3C,oBAAC,sBAAoB,iBAAM;AAAA,YAC1B,mBAAmB,UAClB,oBAAC,+BAA4B,UAAqB,0BAAe;AAAA;AAAA;AAAA,MAErE;AAAA;AAAA,EACF;AAEJ;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\nimport {\n StyleMenuItemLabel,\n StyleMenuItemSecondaryLabel,\n StyledContentWrapper,\n StyledGlobalMenuItemWrapper,\n} from '@elliemae/ds-menu-items-commons';\nimport React from 'react';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { MenuBehaviouralContextProviderContext } from '../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js';\nimport { MENU_FOCUS_REGIONS } from '../DSMenuBehaviouralContextProvider/constants/index.js';\n\nexport const ActivableMenuItem: React.ComponentType<{ itemNode: DSMenuButtonT.MenuNodeActivableItem }> = ({\n itemNode,\n}) => {\n const { dsId, plainItem } = itemNode;\n const { label, secondaryLabel, leftDecoration: LeftDecComponent, minWidth, disabled } = plainItem;\n\n const {\n focusRegion,\n menuItemEventsHandlers: {\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemClick,\n handleFocusableMenuItemOnMouseEnter,\n handleFocusableMenuItemNativeFocusEvent,\n },\n } = React.useContext(MenuBehaviouralContextProviderContext);\n\n const gridLayout = React.useMemo(() => {\n const cols = LeftDecComponent ? ['min-content', 'auto'] : ['auto'];\n if (secondaryLabel) cols.push('auto');\n return cols;\n }, [LeftDecComponent, secondaryLabel]);\n\n const focusedRegionPerformanceHelper = React.useRef(focusRegion);\n focusedRegionPerformanceHelper.current = focusRegion;\n\n const isFocused = focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId);\n\n const handleFocusOnRender = React.useCallback(\n (node: HTMLDivElement) => {\n setTimeout(() => {\n if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {\n node.focus();\n }\n });\n },\n // we need to change the callback reference every time the focusRegion changes or else the focus will not be set\n [dsId, focusRegion],\n // we are using the \"as='div'\", typescript is not able to infer the correct type\n // the logic here actually receives a ref to a HTMLDivElement,\n // but the component must think this is a HTMLLIElement ref callback\n ) as unknown as React.RefCallback<HTMLLIElement>;\n const handleOnMouseEnter = React.useCallback<React.MouseEventHandler<HTMLDivElement>>(() => {\n handleFocusableMenuItemOnMouseEnter(itemNode);\n }, [handleFocusableMenuItemOnMouseEnter, itemNode]);\n const handleOnFocus = React.useCallback<React.FocusEventHandler<HTMLDivElement>>(\n (e) => {\n handleFocusableMenuItemNativeFocusEvent(itemNode, e);\n },\n [handleFocusableMenuItemNativeFocusEvent, itemNode],\n );\n\n const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\\s/g, '')}`;\n\n return (\n <StyledGlobalMenuItemWrapper\n innerRef={handleFocusOnRender}\n onKeyDown={handleFocusableMenuItemKeyDown}\n onClick={handleFocusableMenuItemClick}\n onMouseEnter={handleOnMouseEnter}\n onFocus={handleOnFocus}\n as=\"div\"\n id={`${spacelessDsIdForDom}`}\n role=\"menuitem\"\n tabIndex={isFocused ? 0 : -1}\n aria-disabled={disabled}\n applyAriaDisabled={disabled}\n >\n <StyledContentWrapper\n cols={gridLayout}\n minHeight=\"16px\"\n gutter=\"xxs\"\n alignItems=\"center\"\n minWidth={minWidth ?? undefined}\n >\n {LeftDecComponent ? <LeftDecComponent /> : null}\n <StyleMenuItemLabel>{label}</StyleMenuItemLabel>\n {secondaryLabel !== undefined && (\n <StyleMenuItemSecondaryLabel disabled={disabled}>{secondaryLabel}</StyleMenuItemSecondaryLabel>\n )}\n </StyledContentWrapper>\n </StyledGlobalMenuItemWrapper>\n );\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;AC+EjB,SAOsB,KAPtB;AA9EN;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,OAAOA,YAAW;AAElB,SAAS,6CAA6C;AACtD,SAAS,0BAA0B;AAE5B,MAAM,oBAA4F,CAAC;AAAA,EACxG;AACF,MAAM;AACJ,QAAM,EAAE,MAAM,UAAU,IAAI;AAC5B,QAAM,EAAE,OAAO,gBAAgB,gBAAgB,kBAAkB,UAAU,SAAS,IAAI;AAExF,QAAM;AAAA,IACJ;AAAA,IACA,wBAAwB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,IAAIA,OAAM,WAAW,qCAAqC;AAE1D,QAAM,aAAaA,OAAM,QAAQ,MAAM;AACrC,UAAM,OAAO,mBAAmB,CAAC,eAAe,MAAM,IAAI,CAAC,MAAM;AACjE,QAAI,eAAgB,MAAK,KAAK,MAAM;AACpC,WAAO;AAAA,EACT,GAAG,CAAC,kBAAkB,cAAc,CAAC;AAErC,QAAM,iCAAiCA,OAAM,OAAO,WAAW;AAC/D,iCAA+B,UAAU;AAEzC,QAAM,YAAY,gBAAgB,mBAAmB,aAAa,IAAI;AAEtE,QAAM,sBAAsBA,OAAM;AAAA,IAChC,CAAC,SAAyB;AACxB,iBAAW,MAAM;AACf,YAAI,QAAQ,gBAAgB,mBAAmB,aAAa,IAAI,GAAG;AACjE,eAAK,MAAM;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH;AAAA;AAAA,IAEA,CAAC,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA,EAIpB;AACA,QAAM,qBAAqBA,OAAM,YAAqD,MAAM;AAC1F,wCAAoC,QAAQ;AAAA,EAC9C,GAAG,CAAC,qCAAqC,QAAQ,CAAC;AAClD,QAAM,gBAAgBA,OAAM;AAAA,IAC1B,CAAC,MAAM;AACL,8CAAwC,UAAU,CAAC;AAAA,IACrD;AAAA,IACA,CAAC,yCAAyC,QAAQ;AAAA,EACpD;AAEA,QAAM,sBAAsB,gBAAgB,GAAG,IAAI,GAAG,QAAQ,OAAO,EAAE,CAAC;AAExE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,WAAW;AAAA,MACX,SAAS;AAAA,MACT,cAAc;AAAA,MACd,SAAS;AAAA,MACT,IAAG;AAAA,MACH,IAAI,GAAG,mBAAmB;AAAA,MAC1B,MAAK;AAAA,MACL,UAAU,YAAY,IAAI;AAAA,MAC1B,iBAAe;AAAA,MACf,mBAAmB;AAAA,MAEnB;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,WAAU;AAAA,UACV,QAAO;AAAA,UACP,YAAW;AAAA,UACX,UAAU,YAAY;AAAA,UAErB;AAAA,+BAAmB,oBAAC,oBAAiB,IAAK;AAAA,YAC3C,oBAAC,sBAAoB,iBAAM;AAAA,YAC1B,mBAAmB,UAClB,oBAAC,+BAA4B,UAAqB,0BAAe;AAAA;AAAA;AAAA,MAErE;AAAA;AAAA,EACF;AAEJ;",
6
6
  "names": ["React"]
7
7
  }
@@ -36,7 +36,8 @@ const ActivableWithSubmenuMenuItem = ({ itemNode, FlyoutMenuCircularDepInject })
36
36
  menuItemEventsHandlers: {
37
37
  handleFocusableMenuItemKeyDown,
38
38
  handleFocusableMenuItemClick,
39
- handleFocusableMenuItemOnMouseEnter
39
+ handleFocusableMenuItemOnMouseEnter,
40
+ handleFocusableMenuItemNativeFocusEvent
40
41
  }
41
42
  } = React2.useContext(MenuBehaviouralContextProviderContext);
42
43
  const gridLayout = React2.useMemo(() => {
@@ -63,11 +64,14 @@ const ActivableWithSubmenuMenuItem = ({ itemNode, FlyoutMenuCircularDepInject })
63
64
  // the logic here actually receives a ref to a HTMLDivElement,
64
65
  // but the component must think this is a HTMLLIElement ref callback
65
66
  );
66
- const handleOnMouseEnter = React2.useCallback(
67
+ const handleOnMouseEnter = React2.useCallback(() => {
68
+ handleFocusableMenuItemOnMouseEnter(itemNode);
69
+ }, [handleFocusableMenuItemOnMouseEnter, itemNode]);
70
+ const handleOnFocus = React2.useCallback(
67
71
  (e) => {
68
- handleFocusableMenuItemOnMouseEnter(itemNode, e);
72
+ handleFocusableMenuItemNativeFocusEvent(itemNode, e);
69
73
  },
70
- [handleFocusableMenuItemOnMouseEnter, itemNode]
74
+ [handleFocusableMenuItemNativeFocusEvent, itemNode]
71
75
  );
72
76
  const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\s/g, "")}`;
73
77
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -78,6 +82,7 @@ const ActivableWithSubmenuMenuItem = ({ itemNode, FlyoutMenuCircularDepInject })
78
82
  onKeyDown: handleFocusableMenuItemKeyDown,
79
83
  onClick: handleFocusableMenuItemClick,
80
84
  onMouseEnter: handleOnMouseEnter,
85
+ onFocus: handleOnFocus,
81
86
  as: "div",
82
87
  id: `${spacelessDsIdForDom}`,
83
88
  tabIndex: isFocused ? 0 : -1,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\nimport {\n StyleMenuItemLabel,\n StyleMenuItemSecondaryLabel,\n StyledContentWrapper,\n StyledGlobalMenuItemWrapper,\n} from '@elliemae/ds-menu-items-commons';\nimport React from 'react';\nimport { useFloatingContext, type DSHookFloatingContextT } from '@elliemae/ds-floating-context';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { MenuBehaviouralContextProviderContext } from '../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js';\nimport { MENU_FOCUS_REGIONS } from '../DSMenuBehaviouralContextProvider/constants/index.js';\nimport { type DSMenuItemRendererFactoryT } from './react-desc-prop-types.js';\nconst placementOrderPreference: Required<DSHookFloatingContextT.Props>['placementOrderPreference'] = [\n 'right-start',\n 'right-start',\n 'right',\n 'left-start',\n 'left-end',\n 'left',\n];\nexport const ActivableWithSubmenuMenuItem: React.ComponentType<{\n itemNode: DSMenuButtonT.MenuNodeActivableWithSubmenuItem;\n FlyoutMenuCircularDepInject: DSMenuItemRendererFactoryT.RequiredProps['FlyoutMenuCircularDepInject'];\n}> = ({ itemNode, FlyoutMenuCircularDepInject }) => {\n const { dsId, plainItem } = itemNode;\n const { label, secondaryLabel, leftDecoration: LeftDecComponent, minWidth, disabled } = plainItem;\n const floatingContext = useFloatingContext({\n placement: placementOrderPreference[0],\n placementOrderPreference,\n animationDuration: 100,\n customOffset: [0, 0],\n });\n const {\n refs: { setReference },\n } = floatingContext;\n\n const {\n focusRegion,\n openedSubItems,\n menuItemEventsHandlers: {\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemClick,\n handleFocusableMenuItemOnMouseEnter,\n },\n } = React.useContext(MenuBehaviouralContextProviderContext);\n\n const gridLayout = React.useMemo(() => {\n const cols = LeftDecComponent ? ['min-content', 'auto'] : ['auto'];\n if (secondaryLabel) cols.push('auto');\n return cols;\n }, [LeftDecComponent, secondaryLabel]);\n\n const focusedRegionPerformanceHelper = React.useRef(focusRegion);\n focusedRegionPerformanceHelper.current = focusRegion;\n\n const isExpanded = openedSubItems.some((itemWithOpenSubmenu) => itemWithOpenSubmenu.dsId === dsId);\n const isFocused = focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId);\n\n const handleFocusOnRender = React.useCallback(\n (node: HTMLDivElement) => {\n setReference(node);\n setTimeout(() => {\n if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {\n node.focus();\n }\n });\n },\n // we need to change the callback reference every time the focusRegion changes or else the focus will not be set\n [dsId, focusRegion, setReference],\n // we are using the \"as='div'\", typescript is not able to infer the correct type\n // the logic here actually receives a ref to a HTMLDivElement,\n // but the component must think this is a HTMLLIElement ref callback\n ) as unknown as React.RefCallback<HTMLLIElement>;\n\n const handleOnMouseEnter = React.useCallback<React.MouseEventHandler<HTMLDivElement>>(\n (e) => {\n handleFocusableMenuItemOnMouseEnter(itemNode, e);\n },\n [handleFocusableMenuItemOnMouseEnter, itemNode],\n );\n\n const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\\s/g, '')}`;\n return (\n <>\n <StyledGlobalMenuItemWrapper\n innerRef={handleFocusOnRender}\n onKeyDown={handleFocusableMenuItemKeyDown}\n onClick={handleFocusableMenuItemClick}\n onMouseEnter={handleOnMouseEnter}\n as=\"div\"\n id={`${spacelessDsIdForDom}`}\n tabIndex={isFocused ? 0 : -1}\n role=\"menuitem\"\n aria-controls={\n /* ********************************************************************************************************************\n * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-controls\n * The aria-controls only needs to be set when the popup is visible, but it is valid and easier to program to reference an element that is not visible.\n * ********************************************************************************************************************\n * ^^^ some automated tools will mark an error if the aria-controls references an element that does (yet) exist in the DOM\n * so, while technically valid to not check if expanded, we are doing it to avoid automated tools marking an error\n * ******************************************************************************************************************** */\n isExpanded\n ? itemNode.plainChildren.map((child) => `ds-menu-item-${`${child.dsId}`.replace(/\\s/g, '')}`).join(' ')\n : undefined\n }\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n aria-disabled={disabled}\n applyAriaDisabled={disabled}\n >\n <StyledContentWrapper\n cols={gridLayout}\n minHeight=\"16px\"\n gutter=\"xxs\"\n alignItems=\"center\"\n minWidth={minWidth ?? undefined}\n >\n {LeftDecComponent ? <LeftDecComponent /> : null}\n <StyleMenuItemLabel>{label}</StyleMenuItemLabel>\n {secondaryLabel !== undefined && (\n <StyleMenuItemSecondaryLabel disabled={disabled}>{secondaryLabel}</StyleMenuItemSecondaryLabel>\n )}\n </StyledContentWrapper>\n </StyledGlobalMenuItemWrapper>\n <FlyoutMenuCircularDepInject\n isMenuOpen={isExpanded}\n floatingContext={floatingContext.context}\n floatingStyles={floatingContext.floatingStyles}\n setFloatingRef={floatingContext.refs.setFloating}\n itemNode={itemNode}\n />\n </>\n );\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\nimport {\n StyleMenuItemLabel,\n StyleMenuItemSecondaryLabel,\n StyledContentWrapper,\n StyledGlobalMenuItemWrapper,\n} from '@elliemae/ds-menu-items-commons';\nimport React from 'react';\nimport { useFloatingContext, type DSHookFloatingContextT } from '@elliemae/ds-floating-context';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { MenuBehaviouralContextProviderContext } from '../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js';\nimport { MENU_FOCUS_REGIONS } from '../DSMenuBehaviouralContextProvider/constants/index.js';\nimport { type DSMenuItemRendererFactoryT } from './react-desc-prop-types.js';\nconst placementOrderPreference: Required<DSHookFloatingContextT.Props>['placementOrderPreference'] = [\n 'right-start',\n 'right-start',\n 'right',\n 'left-start',\n 'left-end',\n 'left',\n];\nexport const ActivableWithSubmenuMenuItem: React.ComponentType<{\n itemNode: DSMenuButtonT.MenuNodeActivableWithSubmenuItem;\n FlyoutMenuCircularDepInject: DSMenuItemRendererFactoryT.RequiredProps['FlyoutMenuCircularDepInject'];\n}> = ({ itemNode, FlyoutMenuCircularDepInject }) => {\n const { dsId, plainItem } = itemNode;\n const { label, secondaryLabel, leftDecoration: LeftDecComponent, minWidth, disabled } = plainItem;\n const floatingContext = useFloatingContext({\n placement: placementOrderPreference[0],\n placementOrderPreference,\n animationDuration: 100,\n customOffset: [0, 0],\n });\n const {\n refs: { setReference },\n } = floatingContext;\n\n const {\n focusRegion,\n openedSubItems,\n menuItemEventsHandlers: {\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemClick,\n handleFocusableMenuItemOnMouseEnter,\n handleFocusableMenuItemNativeFocusEvent,\n },\n } = React.useContext(MenuBehaviouralContextProviderContext);\n\n const gridLayout = React.useMemo(() => {\n const cols = LeftDecComponent ? ['min-content', 'auto'] : ['auto'];\n if (secondaryLabel) cols.push('auto');\n return cols;\n }, [LeftDecComponent, secondaryLabel]);\n\n const focusedRegionPerformanceHelper = React.useRef(focusRegion);\n focusedRegionPerformanceHelper.current = focusRegion;\n\n const isExpanded = openedSubItems.some((itemWithOpenSubmenu) => itemWithOpenSubmenu.dsId === dsId);\n const isFocused = focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId);\n\n const handleFocusOnRender = React.useCallback(\n (node: HTMLDivElement) => {\n setReference(node);\n setTimeout(() => {\n if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {\n node.focus();\n }\n });\n },\n // we need to change the callback reference every time the focusRegion changes or else the focus will not be set\n [dsId, focusRegion, setReference],\n // we are using the \"as='div'\", typescript is not able to infer the correct type\n // the logic here actually receives a ref to a HTMLDivElement,\n // but the component must think this is a HTMLLIElement ref callback\n ) as unknown as React.RefCallback<HTMLLIElement>;\n\n const handleOnMouseEnter = React.useCallback<React.MouseEventHandler<HTMLDivElement>>(() => {\n handleFocusableMenuItemOnMouseEnter(itemNode);\n }, [handleFocusableMenuItemOnMouseEnter, itemNode]);\n const handleOnFocus = React.useCallback<React.FocusEventHandler<HTMLDivElement>>(\n (e) => {\n handleFocusableMenuItemNativeFocusEvent(itemNode, e);\n },\n [handleFocusableMenuItemNativeFocusEvent, itemNode],\n );\n\n const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\\s/g, '')}`;\n return (\n <>\n <StyledGlobalMenuItemWrapper\n innerRef={handleFocusOnRender}\n onKeyDown={handleFocusableMenuItemKeyDown}\n onClick={handleFocusableMenuItemClick}\n onMouseEnter={handleOnMouseEnter}\n onFocus={handleOnFocus}\n as=\"div\"\n id={`${spacelessDsIdForDom}`}\n tabIndex={isFocused ? 0 : -1}\n role=\"menuitem\"\n aria-controls={\n /* ********************************************************************************************************************\n * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-controls\n * The aria-controls only needs to be set when the popup is visible, but it is valid and easier to program to reference an element that is not visible.\n * ********************************************************************************************************************\n * ^^^ some automated tools will mark an error if the aria-controls references an element that does (yet) exist in the DOM\n * so, while technically valid to not check if expanded, we are doing it to avoid automated tools marking an error\n * ******************************************************************************************************************** */\n isExpanded\n ? itemNode.plainChildren.map((child) => `ds-menu-item-${`${child.dsId}`.replace(/\\s/g, '')}`).join(' ')\n : undefined\n }\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n aria-disabled={disabled}\n applyAriaDisabled={disabled}\n >\n <StyledContentWrapper\n cols={gridLayout}\n minHeight=\"16px\"\n gutter=\"xxs\"\n alignItems=\"center\"\n minWidth={minWidth ?? undefined}\n >\n {LeftDecComponent ? <LeftDecComponent /> : null}\n <StyleMenuItemLabel>{label}</StyleMenuItemLabel>\n {secondaryLabel !== undefined && (\n <StyleMenuItemSecondaryLabel disabled={disabled}>{secondaryLabel}</StyleMenuItemSecondaryLabel>\n )}\n </StyledContentWrapper>\n </StyledGlobalMenuItemWrapper>\n <FlyoutMenuCircularDepInject\n isMenuOpen={isExpanded}\n floatingContext={floatingContext.context}\n floatingStyles={floatingContext.floatingStyles}\n setFloatingRef={floatingContext.refs.setFloating}\n itemNode={itemNode}\n />\n </>\n );\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -21,7 +21,8 @@ const MultipleSelectMenuItem = ({ itemNode }) => {
21
21
  menuItemEventsHandlers: {
22
22
  handleFocusableMenuItemKeyDown,
23
23
  handleFocusableMenuItemClick,
24
- handleFocusableMenuItemOnMouseEnter
24
+ handleFocusableMenuItemOnMouseEnter,
25
+ handleFocusableMenuItemNativeFocusEvent
25
26
  }
26
27
  } = React2.useContext(MenuBehaviouralContextProviderContext);
27
28
  const { selectedItems } = propsWithDefault;
@@ -48,11 +49,14 @@ const MultipleSelectMenuItem = ({ itemNode }) => {
48
49
  // the logic here actually receives a ref to a HTMLDivElement,
49
50
  // but the component must think this is a HTMLLIElement ref callback
50
51
  );
51
- const handleOnMouseEnter = React2.useCallback(
52
+ const handleOnMouseEnter = React2.useCallback(() => {
53
+ handleFocusableMenuItemOnMouseEnter(itemNode);
54
+ }, [handleFocusableMenuItemOnMouseEnter, itemNode]);
55
+ const handleOnFocus = React2.useCallback(
52
56
  (e) => {
53
- handleFocusableMenuItemOnMouseEnter(itemNode, e);
57
+ handleFocusableMenuItemNativeFocusEvent(itemNode, e);
54
58
  },
55
- [handleFocusableMenuItemOnMouseEnter, itemNode]
59
+ [handleFocusableMenuItemNativeFocusEvent, itemNode]
56
60
  );
57
61
  const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\s/g, "")}`;
58
62
  return /* @__PURE__ */ jsx(
@@ -62,6 +66,7 @@ const MultipleSelectMenuItem = ({ itemNode }) => {
62
66
  onKeyDown: handleFocusableMenuItemKeyDown,
63
67
  onClick: handleFocusableMenuItemClick,
64
68
  onMouseEnter: handleOnMouseEnter,
69
+ onFocus: handleOnFocus,
65
70
  as: "div",
66
71
  id: `${spacelessDsIdForDom}`,
67
72
  tabIndex: isFocused ? 0 : -1,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { Grid } from '@elliemae/ds-grid';\nimport { Checkmark } from '@elliemae/ds-icons';\nimport {\n StyleMenuItemLabel,\n StyleMenuItemSecondaryLabel,\n StyledContentWrapper,\n StyledGlobalMenuItemWrapper,\n} from '@elliemae/ds-menu-items-commons';\nimport React from 'react';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { MenuBehaviouralContextProviderContext } from '../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js';\nimport { MENU_FOCUS_REGIONS } from '../DSMenuBehaviouralContextProvider/constants/index.js';\n\nconst LeftBoxlessCheckbox = React.memo(({ isSelected }: { isSelected: boolean }) => (\n <Grid width=\"16px\">{isSelected ? <Checkmark size=\"s\" color={['brand-primary', '600']} /> : <div />}</Grid>\n));\nexport const MultipleSelectMenuItem: React.ComponentType<{\n itemNode: DSMenuButtonT.MenuNodeMultipleSelectItem;\n}> = ({ itemNode }) => {\n const { dsId, plainItem } = itemNode;\n const { label, secondaryLabel, leftDecoration: LeftDecComponent, minWidth, disabled } = plainItem;\n const {\n focusRegion,\n propsWithDefault,\n menuItemEventsHandlers: {\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemClick,\n handleFocusableMenuItemOnMouseEnter,\n },\n } = React.useContext(MenuBehaviouralContextProviderContext);\n const { selectedItems } = propsWithDefault;\n\n const gridLayout = React.useMemo(() => {\n const cols = LeftDecComponent ? ['min-content', 'min-content', 'auto'] : ['min-content', 'auto'];\n if (secondaryLabel) cols.push('auto');\n return cols;\n }, [LeftDecComponent, secondaryLabel]);\n\n const focusedRegionPerformanceHelper = React.useRef(focusRegion);\n focusedRegionPerformanceHelper.current = focusRegion;\n\n const isFocused = focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId);\n const isSelected = selectedItems.some((itemMarkesAsSelected) => itemMarkesAsSelected.dsId === dsId);\n\n const handleFocusOnRender = React.useCallback(\n (node: HTMLDivElement) => {\n setTimeout(() => {\n if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {\n node.focus();\n }\n });\n },\n // we need to change the callback reference every time the focusRegion changes or else the focus will not be set\n [dsId, focusRegion],\n // we are using the \"as='div'\", typescript is not able to infer the correct type\n // the logic here actually receives a ref to a HTMLDivElement,\n // but the component must think this is a HTMLLIElement ref callback\n ) as unknown as React.RefCallback<HTMLLIElement>;\n\n const handleOnMouseEnter = React.useCallback<React.MouseEventHandler<HTMLDivElement>>(\n (e) => {\n handleFocusableMenuItemOnMouseEnter(itemNode, e);\n },\n [handleFocusableMenuItemOnMouseEnter, itemNode],\n );\n\n const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\\s/g, '')}`;\n return (\n <StyledGlobalMenuItemWrapper\n innerRef={handleFocusOnRender}\n onKeyDown={handleFocusableMenuItemKeyDown}\n onClick={handleFocusableMenuItemClick}\n onMouseEnter={handleOnMouseEnter}\n as=\"div\"\n id={`${spacelessDsIdForDom}`}\n tabIndex={isFocused ? 0 : -1}\n role=\"menuitemcheckbox\"\n aria-checked={isSelected}\n aria-disabled={disabled}\n applyAriaDisabled={disabled}\n >\n <StyledContentWrapper\n cols={gridLayout}\n minHeight=\"16px\"\n gutter=\"xxs\"\n alignItems=\"center\"\n minWidth={minWidth ?? undefined}\n >\n <LeftBoxlessCheckbox isSelected={isSelected} />\n {LeftDecComponent ? <LeftDecComponent /> : null}\n <StyleMenuItemLabel>{label}</StyleMenuItemLabel>\n {secondaryLabel !== undefined && (\n <StyleMenuItemSecondaryLabel disabled={disabled}>{secondaryLabel}</StyleMenuItemSecondaryLabel>\n )}\n </StyledContentWrapper>\n </StyledGlobalMenuItemWrapper>\n );\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACcY,cAmE7B,YAnE6B;AAdnC,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,OAAOA,YAAW;AAElB,SAAS,6CAA6C;AACtD,SAAS,0BAA0B;AAEnC,MAAM,sBAAsBA,OAAM,KAAK,CAAC,EAAE,WAAW,MACnD,oBAAC,QAAK,OAAM,QAAQ,uBAAa,oBAAC,aAAU,MAAK,KAAI,OAAO,CAAC,iBAAiB,KAAK,GAAG,IAAK,oBAAC,SAAI,GAAG,CACpG;AACM,MAAM,yBAER,CAAC,EAAE,SAAS,MAAM;AACrB,QAAM,EAAE,MAAM,UAAU,IAAI;AAC5B,QAAM,EAAE,OAAO,gBAAgB,gBAAgB,kBAAkB,UAAU,SAAS,IAAI;AACxF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,wBAAwB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,IAAIA,OAAM,WAAW,qCAAqC;AAC1D,QAAM,EAAE,cAAc,IAAI;AAE1B,QAAM,aAAaA,OAAM,QAAQ,MAAM;AACrC,UAAM,OAAO,mBAAmB,CAAC,eAAe,eAAe,MAAM,IAAI,CAAC,eAAe,MAAM;AAC/F,QAAI,eAAgB,MAAK,KAAK,MAAM;AACpC,WAAO;AAAA,EACT,GAAG,CAAC,kBAAkB,cAAc,CAAC;AAErC,QAAM,iCAAiCA,OAAM,OAAO,WAAW;AAC/D,iCAA+B,UAAU;AAEzC,QAAM,YAAY,gBAAgB,mBAAmB,aAAa,IAAI;AACtE,QAAM,aAAa,cAAc,KAAK,CAAC,yBAAyB,qBAAqB,SAAS,IAAI;AAElG,QAAM,sBAAsBA,OAAM;AAAA,IAChC,CAAC,SAAyB;AACxB,iBAAW,MAAM;AACf,YAAI,QAAQ,gBAAgB,mBAAmB,aAAa,IAAI,GAAG;AACjE,eAAK,MAAM;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH;AAAA;AAAA,IAEA,CAAC,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA,EAIpB;AAEA,QAAM,qBAAqBA,OAAM;AAAA,IAC/B,CAAC,MAAM;AACL,0CAAoC,UAAU,CAAC;AAAA,IACjD;AAAA,IACA,CAAC,qCAAqC,QAAQ;AAAA,EAChD;AAEA,QAAM,sBAAsB,gBAAgB,GAAG,IAAI,GAAG,QAAQ,OAAO,EAAE,CAAC;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,WAAW;AAAA,MACX,SAAS;AAAA,MACT,cAAc;AAAA,MACd,IAAG;AAAA,MACH,IAAI,GAAG,mBAAmB;AAAA,MAC1B,UAAU,YAAY,IAAI;AAAA,MAC1B,MAAK;AAAA,MACL,gBAAc;AAAA,MACd,iBAAe;AAAA,MACf,mBAAmB;AAAA,MAEnB;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,WAAU;AAAA,UACV,QAAO;AAAA,UACP,YAAW;AAAA,UACX,UAAU,YAAY;AAAA,UAEtB;AAAA,gCAAC,uBAAoB,YAAwB;AAAA,YAC5C,mBAAmB,oBAAC,oBAAiB,IAAK;AAAA,YAC3C,oBAAC,sBAAoB,iBAAM;AAAA,YAC1B,mBAAmB,UAClB,oBAAC,+BAA4B,UAAqB,0BAAe;AAAA;AAAA;AAAA,MAErE;AAAA;AAAA,EACF;AAEJ;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { Grid } from '@elliemae/ds-grid';\nimport { Checkmark } from '@elliemae/ds-icons';\nimport {\n StyleMenuItemLabel,\n StyleMenuItemSecondaryLabel,\n StyledContentWrapper,\n StyledGlobalMenuItemWrapper,\n} from '@elliemae/ds-menu-items-commons';\nimport React from 'react';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { MenuBehaviouralContextProviderContext } from '../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js';\nimport { MENU_FOCUS_REGIONS } from '../DSMenuBehaviouralContextProvider/constants/index.js';\n\nconst LeftBoxlessCheckbox = React.memo(({ isSelected }: { isSelected: boolean }) => (\n <Grid width=\"16px\">{isSelected ? <Checkmark size=\"s\" color={['brand-primary', '600']} /> : <div />}</Grid>\n));\nexport const MultipleSelectMenuItem: React.ComponentType<{\n itemNode: DSMenuButtonT.MenuNodeMultipleSelectItem;\n}> = ({ itemNode }) => {\n const { dsId, plainItem } = itemNode;\n const { label, secondaryLabel, leftDecoration: LeftDecComponent, minWidth, disabled } = plainItem;\n const {\n focusRegion,\n propsWithDefault,\n menuItemEventsHandlers: {\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemClick,\n handleFocusableMenuItemOnMouseEnter,\n handleFocusableMenuItemNativeFocusEvent,\n },\n } = React.useContext(MenuBehaviouralContextProviderContext);\n const { selectedItems } = propsWithDefault;\n\n const gridLayout = React.useMemo(() => {\n const cols = LeftDecComponent ? ['min-content', 'min-content', 'auto'] : ['min-content', 'auto'];\n if (secondaryLabel) cols.push('auto');\n return cols;\n }, [LeftDecComponent, secondaryLabel]);\n\n const focusedRegionPerformanceHelper = React.useRef(focusRegion);\n focusedRegionPerformanceHelper.current = focusRegion;\n\n const isFocused = focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId);\n\n // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator\n // useAdvancedValidation guarantees the non-null in this component\n const isSelected = selectedItems!.some((itemMarkesAsSelected) => itemMarkesAsSelected.dsId === dsId);\n\n const handleFocusOnRender = React.useCallback(\n (node: HTMLDivElement) => {\n setTimeout(() => {\n if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {\n node.focus();\n }\n });\n },\n // we need to change the callback reference every time the focusRegion changes or else the focus will not be set\n [dsId, focusRegion],\n // we are using the \"as='div'\", typescript is not able to infer the correct type\n // the logic here actually receives a ref to a HTMLDivElement,\n // but the component must think this is a HTMLLIElement ref callback\n ) as unknown as React.RefCallback<HTMLLIElement>;\n\n const handleOnMouseEnter = React.useCallback<React.MouseEventHandler<HTMLDivElement>>(() => {\n handleFocusableMenuItemOnMouseEnter(itemNode);\n }, [handleFocusableMenuItemOnMouseEnter, itemNode]);\n const handleOnFocus = React.useCallback<React.FocusEventHandler<HTMLDivElement>>(\n (e) => {\n handleFocusableMenuItemNativeFocusEvent(itemNode, e);\n },\n [handleFocusableMenuItemNativeFocusEvent, itemNode],\n );\n\n const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\\s/g, '')}`;\n return (\n <StyledGlobalMenuItemWrapper\n innerRef={handleFocusOnRender}\n onKeyDown={handleFocusableMenuItemKeyDown}\n onClick={handleFocusableMenuItemClick}\n onMouseEnter={handleOnMouseEnter}\n onFocus={handleOnFocus}\n as=\"div\"\n id={`${spacelessDsIdForDom}`}\n tabIndex={isFocused ? 0 : -1}\n role=\"menuitemcheckbox\"\n aria-checked={isSelected}\n aria-disabled={disabled}\n applyAriaDisabled={disabled}\n >\n <StyledContentWrapper\n cols={gridLayout}\n minHeight=\"16px\"\n gutter=\"xxs\"\n alignItems=\"center\"\n minWidth={minWidth ?? undefined}\n >\n <LeftBoxlessCheckbox isSelected={isSelected} />\n {LeftDecComponent ? <LeftDecComponent /> : null}\n <StyleMenuItemLabel>{label}</StyleMenuItemLabel>\n {secondaryLabel !== undefined && (\n <StyleMenuItemSecondaryLabel disabled={disabled}>{secondaryLabel}</StyleMenuItemSecondaryLabel>\n )}\n </StyledContentWrapper>\n </StyledGlobalMenuItemWrapper>\n );\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACcY,cA2E7B,YA3E6B;AAdnC,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,OAAOA,YAAW;AAElB,SAAS,6CAA6C;AACtD,SAAS,0BAA0B;AAEnC,MAAM,sBAAsBA,OAAM,KAAK,CAAC,EAAE,WAAW,MACnD,oBAAC,QAAK,OAAM,QAAQ,uBAAa,oBAAC,aAAU,MAAK,KAAI,OAAO,CAAC,iBAAiB,KAAK,GAAG,IAAK,oBAAC,SAAI,GAAG,CACpG;AACM,MAAM,yBAER,CAAC,EAAE,SAAS,MAAM;AACrB,QAAM,EAAE,MAAM,UAAU,IAAI;AAC5B,QAAM,EAAE,OAAO,gBAAgB,gBAAgB,kBAAkB,UAAU,SAAS,IAAI;AACxF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,wBAAwB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,IAAIA,OAAM,WAAW,qCAAqC;AAC1D,QAAM,EAAE,cAAc,IAAI;AAE1B,QAAM,aAAaA,OAAM,QAAQ,MAAM;AACrC,UAAM,OAAO,mBAAmB,CAAC,eAAe,eAAe,MAAM,IAAI,CAAC,eAAe,MAAM;AAC/F,QAAI,eAAgB,MAAK,KAAK,MAAM;AACpC,WAAO;AAAA,EACT,GAAG,CAAC,kBAAkB,cAAc,CAAC;AAErC,QAAM,iCAAiCA,OAAM,OAAO,WAAW;AAC/D,iCAA+B,UAAU;AAEzC,QAAM,YAAY,gBAAgB,mBAAmB,aAAa,IAAI;AAItE,QAAM,aAAa,cAAe,KAAK,CAAC,yBAAyB,qBAAqB,SAAS,IAAI;AAEnG,QAAM,sBAAsBA,OAAM;AAAA,IAChC,CAAC,SAAyB;AACxB,iBAAW,MAAM;AACf,YAAI,QAAQ,gBAAgB,mBAAmB,aAAa,IAAI,GAAG;AACjE,eAAK,MAAM;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH;AAAA;AAAA,IAEA,CAAC,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA,EAIpB;AAEA,QAAM,qBAAqBA,OAAM,YAAqD,MAAM;AAC1F,wCAAoC,QAAQ;AAAA,EAC9C,GAAG,CAAC,qCAAqC,QAAQ,CAAC;AAClD,QAAM,gBAAgBA,OAAM;AAAA,IAC1B,CAAC,MAAM;AACL,8CAAwC,UAAU,CAAC;AAAA,IACrD;AAAA,IACA,CAAC,yCAAyC,QAAQ;AAAA,EACpD;AAEA,QAAM,sBAAsB,gBAAgB,GAAG,IAAI,GAAG,QAAQ,OAAO,EAAE,CAAC;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,WAAW;AAAA,MACX,SAAS;AAAA,MACT,cAAc;AAAA,MACd,SAAS;AAAA,MACT,IAAG;AAAA,MACH,IAAI,GAAG,mBAAmB;AAAA,MAC1B,UAAU,YAAY,IAAI;AAAA,MAC1B,MAAK;AAAA,MACL,gBAAc;AAAA,MACd,iBAAe;AAAA,MACf,mBAAmB;AAAA,MAEnB;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,WAAU;AAAA,UACV,QAAO;AAAA,UACP,YAAW;AAAA,UACX,UAAU,YAAY;AAAA,UAEtB;AAAA,gCAAC,uBAAoB,YAAwB;AAAA,YAC5C,mBAAmB,oBAAC,oBAAiB,IAAK;AAAA,YAC3C,oBAAC,sBAAoB,iBAAM;AAAA,YAC1B,mBAAmB,UAClB,oBAAC,+BAA4B,UAAqB,0BAAe;AAAA;AAAA;AAAA,MAErE;AAAA;AAAA,EACF;AAEJ;",
6
6
  "names": ["React"]
7
7
  }
@@ -41,7 +41,8 @@ const MultipleSelectWithSubmenuMenuItem = ({ itemNode, FlyoutMenuCircularDepInje
41
41
  menuItemEventsHandlers: {
42
42
  handleFocusableMenuItemKeyDown,
43
43
  handleFocusableMenuItemClick,
44
- handleFocusableMenuItemOnMouseEnter
44
+ handleFocusableMenuItemOnMouseEnter,
45
+ handleFocusableMenuItemNativeFocusEvent
45
46
  }
46
47
  } = React2.useContext(MenuBehaviouralContextProviderContext);
47
48
  const { selectedItems } = propsWithDefault;
@@ -56,6 +57,8 @@ const MultipleSelectWithSubmenuMenuItem = ({ itemNode, FlyoutMenuCircularDepInje
56
57
  const isExpanded = openedSubItems.some((itemWithOpenSubmenu) => itemWithOpenSubmenu.dsId === dsId);
57
58
  const isFocused = focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId);
58
59
  const isSelected = React2.useMemo(
60
+ // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator
61
+ // useAdvancedValidation guarantees the non-null in this component
59
62
  () => getIsMultipleSelectNodeWithSubmenuSelected({ itemNode, selectedItems }),
60
63
  [itemNode, selectedItems]
61
64
  );
@@ -74,11 +77,14 @@ const MultipleSelectWithSubmenuMenuItem = ({ itemNode, FlyoutMenuCircularDepInje
74
77
  // the logic here actually receives a ref to a HTMLDivElement,
75
78
  // but the component must think this is a HTMLLIElement ref callback
76
79
  );
77
- const handleOnMouseEnter = React2.useCallback(
80
+ const handleOnMouseEnter = React2.useCallback(() => {
81
+ handleFocusableMenuItemOnMouseEnter(itemNode);
82
+ }, [handleFocusableMenuItemOnMouseEnter, itemNode]);
83
+ const handleOnFocus = React2.useCallback(
78
84
  (e) => {
79
- handleFocusableMenuItemOnMouseEnter(itemNode, e);
85
+ handleFocusableMenuItemNativeFocusEvent(itemNode, e);
80
86
  },
81
- [handleFocusableMenuItemOnMouseEnter, itemNode]
87
+ [handleFocusableMenuItemNativeFocusEvent, itemNode]
82
88
  );
83
89
  const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\s/g, "")}`;
84
90
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -89,6 +95,7 @@ const MultipleSelectWithSubmenuMenuItem = ({ itemNode, FlyoutMenuCircularDepInje
89
95
  onKeyDown: handleFocusableMenuItemKeyDown,
90
96
  onClick: handleFocusableMenuItemClick,
91
97
  onMouseEnter: handleOnMouseEnter,
98
+ onFocus: handleOnFocus,
92
99
  as: "div",
93
100
  id: `${spacelessDsIdForDom}`,
94
101
  tabIndex: isFocused ? 0 : -1,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable no-nested-ternary */\n/* eslint-disable max-lines */\nimport { useFloatingContext, type DSHookFloatingContextT } from '@elliemae/ds-floating-context';\nimport { Grid } from '@elliemae/ds-grid';\nimport { Checkmark, ChevronSmallRight, ParenthesisRemove } from '@elliemae/ds-icons';\nimport {\n StyleMenuItemLabel,\n StyleMenuItemSecondaryLabel,\n StyledContentWrapper,\n StyledGlobalMenuItemWrapper,\n} from '@elliemae/ds-menu-items-commons';\nimport React from 'react';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { MenuBehaviouralContextProviderContext } from '../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js';\nimport { MENU_FOCUS_REGIONS } from '../DSMenuBehaviouralContextProvider/constants/index.js';\nimport { type DSMenuItemRendererFactoryT } from './react-desc-prop-types.js';\nimport { getIsMultipleSelectNodeWithSubmenuSelected } from '../DSMenuBehaviouralContextProvider/utils/multipleSelectionHelpers.js';\n\nconst placementOrderPreference: Required<DSHookFloatingContextT.Props>['placementOrderPreference'] = [\n 'right-start',\n 'right-start',\n 'right',\n 'left-start',\n 'left-end',\n 'left',\n];\nconst LeftBoxlessCheckbox = React.memo(({ isSelected }: { isSelected: boolean | 'mixed' }) => (\n <Grid width=\"16px\">\n {isSelected ? (\n isSelected === 'mixed' ? (\n <ParenthesisRemove size=\"s\" color={['brand-primary', '600']} />\n ) : (\n <Checkmark size=\"s\" color={['brand-primary', '600']} />\n )\n ) : (\n <div />\n )}\n </Grid>\n));\nexport const MultipleSelectWithSubmenuMenuItem: React.ComponentType<{\n itemNode: DSMenuButtonT.MenuNodeMultipleSelectWithSubmenuItem;\n FlyoutMenuCircularDepInject: DSMenuItemRendererFactoryT.RequiredProps['FlyoutMenuCircularDepInject'];\n}> = ({ itemNode, FlyoutMenuCircularDepInject }) => {\n const { dsId, plainItem } = itemNode;\n const { label, secondaryLabel, leftDecoration: LeftDecComponent, minWidth, disabled } = plainItem;\n const floatingContext = useFloatingContext({\n placement: placementOrderPreference[0],\n placementOrderPreference,\n animationDuration: 100,\n customOffset: [0, 0],\n });\n const {\n refs: { setReference },\n } = floatingContext;\n\n const {\n focusRegion,\n propsWithDefault,\n openedSubItems,\n menuItemEventsHandlers: {\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemClick,\n handleFocusableMenuItemOnMouseEnter,\n },\n } = React.useContext(MenuBehaviouralContextProviderContext);\n const { selectedItems } = propsWithDefault;\n\n const gridLayout = React.useMemo(() => {\n const cols = LeftDecComponent ? ['min-content', 'min-content', 'auto'] : ['min-content', 'auto'];\n if (secondaryLabel) cols.push('auto');\n cols.push('min-content');\n return cols;\n }, [LeftDecComponent, secondaryLabel]);\n\n const focusedRegionPerformanceHelper = React.useRef(focusRegion);\n focusedRegionPerformanceHelper.current = focusRegion;\n\n const isExpanded = openedSubItems.some((itemWithOpenSubmenu) => itemWithOpenSubmenu.dsId === dsId);\n const isFocused = focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId);\n const isSelected = React.useMemo<'mixed' | boolean>(\n () => getIsMultipleSelectNodeWithSubmenuSelected({ itemNode, selectedItems }),\n [itemNode, selectedItems],\n );\n const handleFocusOnRender = React.useCallback(\n (node: HTMLDivElement) => {\n setReference(node);\n setTimeout(() => {\n if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {\n node.focus();\n }\n });\n },\n // we need to change the callback reference every time the focusRegion changes or else the focus will not be set\n [dsId, focusRegion, setReference],\n // we are using the \"as='div'\", typescript is not able to infer the correct type\n // the logic here actually receives a ref to a HTMLDivElement,\n // but the component must think this is a HTMLLIElement ref callback\n ) as unknown as React.RefCallback<HTMLLIElement>;\n\n const handleOnMouseEnter = React.useCallback<React.MouseEventHandler<HTMLDivElement>>(\n (e) => {\n handleFocusableMenuItemOnMouseEnter(itemNode, e);\n },\n [handleFocusableMenuItemOnMouseEnter, itemNode],\n );\n\n const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\\s/g, '')}`;\n return (\n <>\n <StyledGlobalMenuItemWrapper\n innerRef={handleFocusOnRender}\n onKeyDown={handleFocusableMenuItemKeyDown}\n onClick={handleFocusableMenuItemClick}\n onMouseEnter={handleOnMouseEnter}\n as=\"div\"\n id={`${spacelessDsIdForDom}`}\n tabIndex={isFocused ? 0 : -1}\n role=\"menuitemcheckbox\"\n aria-checked={isSelected}\n aria-controls={\n /* ********************************************************************************************************************\n * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-controls\n * The aria-controls only needs to be set when the popup is visible, but it is valid and easier to program to reference an element that is not visible.\n * ********************************************************************************************************************\n * ^^^ some automated tools will mark an error if the aria-controls references an element that does (yet) exist in the DOM\n * so, while technically valid to not check if expanded, we are doing it to avoid automated tools marking an error\n * ******************************************************************************************************************** */\n isExpanded\n ? itemNode.plainChildren.map((child) => `ds-menu-item-${`${child.dsId}`.replace(/\\s/g, '')}`).join(' ')\n : undefined\n }\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n aria-disabled={disabled}\n applyAriaDisabled={disabled}\n >\n <StyledContentWrapper\n cols={gridLayout}\n minHeight=\"16px\"\n gutter=\"xxs\"\n alignItems=\"center\"\n minWidth={minWidth ?? undefined}\n >\n <LeftBoxlessCheckbox isSelected={isSelected} />\n {LeftDecComponent ? <LeftDecComponent /> : null}\n <StyleMenuItemLabel>{label}</StyleMenuItemLabel>\n {secondaryLabel !== undefined && (\n <StyleMenuItemSecondaryLabel disabled={disabled}>{secondaryLabel}</StyleMenuItemSecondaryLabel>\n )}\n <ChevronSmallRight />\n </StyledContentWrapper>\n </StyledGlobalMenuItemWrapper>\n <FlyoutMenuCircularDepInject\n isMenuOpen={isExpanded}\n floatingContext={floatingContext.context}\n floatingStyles={floatingContext.floatingStyles}\n setFloatingRef={floatingContext.refs.setFloating}\n itemNode={itemNode}\n />\n </>\n );\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable no-nested-ternary */\n/* eslint-disable max-lines */\nimport { useFloatingContext, type DSHookFloatingContextT } from '@elliemae/ds-floating-context';\nimport { Grid } from '@elliemae/ds-grid';\nimport { Checkmark, ChevronSmallRight, ParenthesisRemove } from '@elliemae/ds-icons';\nimport {\n StyleMenuItemLabel,\n StyleMenuItemSecondaryLabel,\n StyledContentWrapper,\n StyledGlobalMenuItemWrapper,\n} from '@elliemae/ds-menu-items-commons';\nimport React from 'react';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { MenuBehaviouralContextProviderContext } from '../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js';\nimport { MENU_FOCUS_REGIONS } from '../DSMenuBehaviouralContextProvider/constants/index.js';\nimport { type DSMenuItemRendererFactoryT } from './react-desc-prop-types.js';\nimport { getIsMultipleSelectNodeWithSubmenuSelected } from '../DSMenuBehaviouralContextProvider/utils/multipleSelectionHelpers.js';\n\nconst placementOrderPreference: Required<DSHookFloatingContextT.Props>['placementOrderPreference'] = [\n 'right-start',\n 'right-start',\n 'right',\n 'left-start',\n 'left-end',\n 'left',\n];\nconst LeftBoxlessCheckbox = React.memo(({ isSelected }: { isSelected: boolean | 'mixed' }) => (\n <Grid width=\"16px\">\n {isSelected ? (\n isSelected === 'mixed' ? (\n <ParenthesisRemove size=\"s\" color={['brand-primary', '600']} />\n ) : (\n <Checkmark size=\"s\" color={['brand-primary', '600']} />\n )\n ) : (\n <div />\n )}\n </Grid>\n));\nexport const MultipleSelectWithSubmenuMenuItem: React.ComponentType<{\n itemNode: DSMenuButtonT.MenuNodeMultipleSelectWithSubmenuItem;\n FlyoutMenuCircularDepInject: DSMenuItemRendererFactoryT.RequiredProps['FlyoutMenuCircularDepInject'];\n}> = ({ itemNode, FlyoutMenuCircularDepInject }) => {\n const { dsId, plainItem } = itemNode;\n const { label, secondaryLabel, leftDecoration: LeftDecComponent, minWidth, disabled } = plainItem;\n const floatingContext = useFloatingContext({\n placement: placementOrderPreference[0],\n placementOrderPreference,\n animationDuration: 100,\n customOffset: [0, 0],\n });\n const {\n refs: { setReference },\n } = floatingContext;\n\n const {\n focusRegion,\n propsWithDefault,\n openedSubItems,\n menuItemEventsHandlers: {\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemClick,\n handleFocusableMenuItemOnMouseEnter,\n handleFocusableMenuItemNativeFocusEvent,\n },\n } = React.useContext(MenuBehaviouralContextProviderContext);\n const { selectedItems } = propsWithDefault;\n\n const gridLayout = React.useMemo(() => {\n const cols = LeftDecComponent ? ['min-content', 'min-content', 'auto'] : ['min-content', 'auto'];\n if (secondaryLabel) cols.push('auto');\n cols.push('min-content');\n return cols;\n }, [LeftDecComponent, secondaryLabel]);\n\n const focusedRegionPerformanceHelper = React.useRef(focusRegion);\n focusedRegionPerformanceHelper.current = focusRegion;\n\n const isExpanded = openedSubItems.some((itemWithOpenSubmenu) => itemWithOpenSubmenu.dsId === dsId);\n const isFocused = focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId);\n const isSelected = React.useMemo<'mixed' | boolean>(\n // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator\n // useAdvancedValidation guarantees the non-null in this component\n () => getIsMultipleSelectNodeWithSubmenuSelected({ itemNode, selectedItems: selectedItems! }),\n [itemNode, selectedItems],\n );\n const handleFocusOnRender = React.useCallback(\n (node: HTMLDivElement) => {\n setReference(node);\n setTimeout(() => {\n if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {\n node.focus();\n }\n });\n },\n // we need to change the callback reference every time the focusRegion changes or else the focus will not be set\n [dsId, focusRegion, setReference],\n // we are using the \"as='div'\", typescript is not able to infer the correct type\n // the logic here actually receives a ref to a HTMLDivElement,\n // but the component must think this is a HTMLLIElement ref callback\n ) as unknown as React.RefCallback<HTMLLIElement>;\n\n const handleOnMouseEnter = React.useCallback<React.MouseEventHandler<HTMLDivElement>>(() => {\n handleFocusableMenuItemOnMouseEnter(itemNode);\n }, [handleFocusableMenuItemOnMouseEnter, itemNode]);\n const handleOnFocus = React.useCallback<React.FocusEventHandler<HTMLDivElement>>(\n (e) => {\n handleFocusableMenuItemNativeFocusEvent(itemNode, e);\n },\n [handleFocusableMenuItemNativeFocusEvent, itemNode],\n );\n\n const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\\s/g, '')}`;\n return (\n <>\n <StyledGlobalMenuItemWrapper\n innerRef={handleFocusOnRender}\n onKeyDown={handleFocusableMenuItemKeyDown}\n onClick={handleFocusableMenuItemClick}\n onMouseEnter={handleOnMouseEnter}\n onFocus={handleOnFocus}\n as=\"div\"\n id={`${spacelessDsIdForDom}`}\n tabIndex={isFocused ? 0 : -1}\n role=\"menuitemcheckbox\"\n aria-checked={isSelected}\n aria-controls={\n /* ********************************************************************************************************************\n * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-controls\n * The aria-controls only needs to be set when the popup is visible, but it is valid and easier to program to reference an element that is not visible.\n * ********************************************************************************************************************\n * ^^^ some automated tools will mark an error if the aria-controls references an element that does (yet) exist in the DOM\n * so, while technically valid to not check if expanded, we are doing it to avoid automated tools marking an error\n * ******************************************************************************************************************** */\n isExpanded\n ? itemNode.plainChildren.map((child) => `ds-menu-item-${`${child.dsId}`.replace(/\\s/g, '')}`).join(' ')\n : undefined\n }\n aria-haspopup=\"menu\"\n aria-expanded={isExpanded}\n aria-disabled={disabled}\n applyAriaDisabled={disabled}\n >\n <StyledContentWrapper\n cols={gridLayout}\n minHeight=\"16px\"\n gutter=\"xxs\"\n alignItems=\"center\"\n minWidth={minWidth ?? undefined}\n >\n <LeftBoxlessCheckbox isSelected={isSelected} />\n {LeftDecComponent ? <LeftDecComponent /> : null}\n <StyleMenuItemLabel>{label}</StyleMenuItemLabel>\n {secondaryLabel !== undefined && (\n <StyleMenuItemSecondaryLabel disabled={disabled}>{secondaryLabel}</StyleMenuItemSecondaryLabel>\n )}\n <ChevronSmallRight />\n </StyledContentWrapper>\n </StyledGlobalMenuItemWrapper>\n <FlyoutMenuCircularDepInject\n isMenuOpen={isExpanded}\n floatingContext={floatingContext.context}\n floatingStyles={floatingContext.floatingStyles}\n setFloatingRef={floatingContext.refs.setFloating}\n itemNode={itemNode}\n />\n </>\n );\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -29,7 +29,8 @@ const SingleSelectMenuItem = ({
29
29
  menuItemEventsHandlers: {
30
30
  handleFocusableMenuItemKeyDown,
31
31
  handleFocusableMenuItemClick,
32
- handleFocusableMenuItemOnMouseEnter
32
+ handleFocusableMenuItemOnMouseEnter,
33
+ handleFocusableMenuItemNativeFocusEvent
33
34
  }
34
35
  } = React2.useContext(MenuBehaviouralContextProviderContext);
35
36
  const { selectedItems } = propsWithDefault;
@@ -56,11 +57,14 @@ const SingleSelectMenuItem = ({
56
57
  // the logic here actually receives a ref to a HTMLDivElement,
57
58
  // but the component must think this is a HTMLLIElement ref callback
58
59
  );
59
- const handleOnMouseEnter = React2.useCallback(
60
+ const handleOnMouseEnter = React2.useCallback(() => {
61
+ handleFocusableMenuItemOnMouseEnter(itemNode);
62
+ }, [handleFocusableMenuItemOnMouseEnter, itemNode]);
63
+ const handleOnFocus = React2.useCallback(
60
64
  (e) => {
61
- handleFocusableMenuItemOnMouseEnter(itemNode, e);
65
+ handleFocusableMenuItemNativeFocusEvent(itemNode, e);
62
66
  },
63
- [handleFocusableMenuItemOnMouseEnter, itemNode]
67
+ [handleFocusableMenuItemNativeFocusEvent, itemNode]
64
68
  );
65
69
  const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\s/g, "")}`;
66
70
  return /* @__PURE__ */ jsx(
@@ -70,6 +74,7 @@ const SingleSelectMenuItem = ({
70
74
  onKeyDown: handleFocusableMenuItemKeyDown,
71
75
  onClick: handleFocusableMenuItemClick,
72
76
  onMouseEnter: handleOnMouseEnter,
77
+ onFocus: handleOnFocus,
73
78
  as: "div",
74
79
  id: `${spacelessDsIdForDom}`,
75
80
  tabIndex: isFocused ? 0 : -1,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\nimport { Grid } from '@elliemae/ds-grid';\nimport {\n StyleMenuItemLabel,\n StyleMenuItemSecondaryLabel,\n StyledContentWrapper,\n StyledGlobalMenuItemWrapper,\n} from '@elliemae/ds-menu-items-commons';\nimport { styled } from '@elliemae/ds-system';\nimport React from 'react';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { MenuBehaviouralContextProviderContext } from '../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js';\nimport { MENU_FOCUS_REGIONS } from '../DSMenuBehaviouralContextProvider/constants/index.js';\n\nconst StyledRadioDotIndicator = styled('div')`\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background-color: #005ea2;\n`;\n\nconst LeftBoxlessRadio = React.memo(({ isSelected }: { isSelected: boolean }) => (\n <Grid width=\"16px\">{isSelected ? <StyledRadioDotIndicator /> : <div />}</Grid>\n));\nexport const SingleSelectMenuItem: React.ComponentType<{ itemNode: DSMenuButtonT.MenuNodeSingleSelectItem }> = ({\n itemNode,\n}) => {\n const { dsId, plainItem } = itemNode;\n const { label, secondaryLabel, leftDecoration: LeftDecComponent, minWidth, disabled } = plainItem;\n\n const {\n focusRegion,\n propsWithDefault,\n menuItemEventsHandlers: {\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemClick,\n handleFocusableMenuItemOnMouseEnter,\n },\n } = React.useContext(MenuBehaviouralContextProviderContext);\n const { selectedItems } = propsWithDefault;\n\n const gridLayout = React.useMemo(() => {\n const cols = LeftDecComponent ? ['min-content', 'min-content', 'auto'] : ['min-content', 'auto'];\n if (secondaryLabel) cols.push('auto');\n return cols;\n }, [LeftDecComponent, secondaryLabel]);\n\n const focusedRegionPerformanceHelper = React.useRef(focusRegion);\n focusedRegionPerformanceHelper.current = focusRegion;\n\n const isFocused = focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId);\n const isSelected = selectedItems.some((itemMarkesAsSelected) => itemMarkesAsSelected.dsId === dsId);\n\n const handleFocusOnRender = React.useCallback(\n (node: HTMLDivElement) => {\n setTimeout(() => {\n if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {\n node.focus();\n }\n });\n },\n // we need to change the callback reference every time the focusRegion changes or else the focus will not be set\n [dsId, focusRegion],\n // we are using the \"as='div'\", typescript is not able to infer the correct type\n // the logic here actually receives a ref to a HTMLDivElement,\n // but the component must think this is a HTMLLIElement ref callback\n ) as unknown as React.RefCallback<HTMLLIElement>;\n\n const handleOnMouseEnter = React.useCallback<React.MouseEventHandler<HTMLDivElement>>(\n (e) => {\n handleFocusableMenuItemOnMouseEnter(itemNode, e);\n },\n [handleFocusableMenuItemOnMouseEnter, itemNode],\n );\n\n const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\\s/g, '')}`;\n return (\n <StyledGlobalMenuItemWrapper\n innerRef={handleFocusOnRender}\n onKeyDown={handleFocusableMenuItemKeyDown}\n onClick={handleFocusableMenuItemClick}\n onMouseEnter={handleOnMouseEnter}\n as=\"div\"\n id={`${spacelessDsIdForDom}`}\n tabIndex={isFocused ? 0 : -1}\n role=\"menuitemradio\"\n aria-checked={isSelected}\n aria-disabled={disabled}\n applyAriaDisabled={disabled}\n >\n <StyledContentWrapper\n cols={gridLayout}\n minHeight=\"16px\"\n gutter=\"xxs\"\n alignItems=\"center\"\n minWidth={minWidth ?? undefined}\n >\n <LeftBoxlessRadio isSelected={isSelected} />\n {LeftDecComponent ? <LeftDecComponent /> : null}\n <StyleMenuItemLabel>{label}</StyleMenuItemLabel>\n {secondaryLabel !== undefined && (\n <StyleMenuItemSecondaryLabel disabled={disabled}>{secondaryLabel}</StyleMenuItemSecondaryLabel>\n )}\n </StyledContentWrapper>\n </StyledGlobalMenuItemWrapper>\n );\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACsBY,cAoE7B,YApE6B;AArBnC,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AACvB,OAAOA,YAAW;AAElB,SAAS,6CAA6C;AACtD,SAAS,0BAA0B;AAEnC,MAAM,0BAA0B,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAO5C,MAAM,mBAAmBA,OAAM,KAAK,CAAC,EAAE,WAAW,MAChD,oBAAC,QAAK,OAAM,QAAQ,uBAAa,oBAAC,2BAAwB,IAAK,oBAAC,SAAI,GAAG,CACxE;AACM,MAAM,uBAAkG,CAAC;AAAA,EAC9G;AACF,MAAM;AACJ,QAAM,EAAE,MAAM,UAAU,IAAI;AAC5B,QAAM,EAAE,OAAO,gBAAgB,gBAAgB,kBAAkB,UAAU,SAAS,IAAI;AAExF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,wBAAwB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,IAAIA,OAAM,WAAW,qCAAqC;AAC1D,QAAM,EAAE,cAAc,IAAI;AAE1B,QAAM,aAAaA,OAAM,QAAQ,MAAM;AACrC,UAAM,OAAO,mBAAmB,CAAC,eAAe,eAAe,MAAM,IAAI,CAAC,eAAe,MAAM;AAC/F,QAAI,eAAgB,MAAK,KAAK,MAAM;AACpC,WAAO;AAAA,EACT,GAAG,CAAC,kBAAkB,cAAc,CAAC;AAErC,QAAM,iCAAiCA,OAAM,OAAO,WAAW;AAC/D,iCAA+B,UAAU;AAEzC,QAAM,YAAY,gBAAgB,mBAAmB,aAAa,IAAI;AACtE,QAAM,aAAa,cAAc,KAAK,CAAC,yBAAyB,qBAAqB,SAAS,IAAI;AAElG,QAAM,sBAAsBA,OAAM;AAAA,IAChC,CAAC,SAAyB;AACxB,iBAAW,MAAM;AACf,YAAI,QAAQ,gBAAgB,mBAAmB,aAAa,IAAI,GAAG;AACjE,eAAK,MAAM;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH;AAAA;AAAA,IAEA,CAAC,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA,EAIpB;AAEA,QAAM,qBAAqBA,OAAM;AAAA,IAC/B,CAAC,MAAM;AACL,0CAAoC,UAAU,CAAC;AAAA,IACjD;AAAA,IACA,CAAC,qCAAqC,QAAQ;AAAA,EAChD;AAEA,QAAM,sBAAsB,gBAAgB,GAAG,IAAI,GAAG,QAAQ,OAAO,EAAE,CAAC;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,WAAW;AAAA,MACX,SAAS;AAAA,MACT,cAAc;AAAA,MACd,IAAG;AAAA,MACH,IAAI,GAAG,mBAAmB;AAAA,MAC1B,UAAU,YAAY,IAAI;AAAA,MAC1B,MAAK;AAAA,MACL,gBAAc;AAAA,MACd,iBAAe;AAAA,MACf,mBAAmB;AAAA,MAEnB;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,WAAU;AAAA,UACV,QAAO;AAAA,UACP,YAAW;AAAA,UACX,UAAU,YAAY;AAAA,UAEtB;AAAA,gCAAC,oBAAiB,YAAwB;AAAA,YACzC,mBAAmB,oBAAC,oBAAiB,IAAK;AAAA,YAC3C,oBAAC,sBAAoB,iBAAM;AAAA,YAC1B,mBAAmB,UAClB,oBAAC,+BAA4B,UAAqB,0BAAe;AAAA;AAAA;AAAA,MAErE;AAAA;AAAA,EACF;AAEJ;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\nimport { Grid } from '@elliemae/ds-grid';\nimport {\n StyleMenuItemLabel,\n StyleMenuItemSecondaryLabel,\n StyledContentWrapper,\n StyledGlobalMenuItemWrapper,\n} from '@elliemae/ds-menu-items-commons';\nimport { styled } from '@elliemae/ds-system';\nimport React from 'react';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { MenuBehaviouralContextProviderContext } from '../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js';\nimport { MENU_FOCUS_REGIONS } from '../DSMenuBehaviouralContextProvider/constants/index.js';\n\nconst StyledRadioDotIndicator = styled('div')`\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background-color: #005ea2;\n`;\n\nconst LeftBoxlessRadio = React.memo(({ isSelected }: { isSelected: boolean }) => (\n <Grid width=\"16px\">{isSelected ? <StyledRadioDotIndicator /> : <div />}</Grid>\n));\nexport const SingleSelectMenuItem: React.ComponentType<{ itemNode: DSMenuButtonT.MenuNodeSingleSelectItem }> = ({\n itemNode,\n}) => {\n const { dsId, plainItem } = itemNode;\n const { label, secondaryLabel, leftDecoration: LeftDecComponent, minWidth, disabled } = plainItem;\n\n const {\n focusRegion,\n propsWithDefault,\n menuItemEventsHandlers: {\n handleFocusableMenuItemKeyDown,\n handleFocusableMenuItemClick,\n handleFocusableMenuItemOnMouseEnter,\n handleFocusableMenuItemNativeFocusEvent,\n },\n } = React.useContext(MenuBehaviouralContextProviderContext);\n const { selectedItems } = propsWithDefault;\n\n const gridLayout = React.useMemo(() => {\n const cols = LeftDecComponent ? ['min-content', 'min-content', 'auto'] : ['min-content', 'auto'];\n if (secondaryLabel) cols.push('auto');\n return cols;\n }, [LeftDecComponent, secondaryLabel]);\n\n const focusedRegionPerformanceHelper = React.useRef(focusRegion);\n focusedRegionPerformanceHelper.current = focusRegion;\n\n const isFocused = focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId);\n // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator\n // useAdvancedValidation guarantees the non-null in this component\n const isSelected = selectedItems!.some((itemMarkesAsSelected) => itemMarkesAsSelected.dsId === dsId);\n\n const handleFocusOnRender = React.useCallback(\n (node: HTMLDivElement) => {\n setTimeout(() => {\n if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {\n node.focus();\n }\n });\n },\n // we need to change the callback reference every time the focusRegion changes or else the focus will not be set\n [dsId, focusRegion],\n // we are using the \"as='div'\", typescript is not able to infer the correct type\n // the logic here actually receives a ref to a HTMLDivElement,\n // but the component must think this is a HTMLLIElement ref callback\n ) as unknown as React.RefCallback<HTMLLIElement>;\n\n const handleOnMouseEnter = React.useCallback<React.MouseEventHandler<HTMLDivElement>>(() => {\n handleFocusableMenuItemOnMouseEnter(itemNode);\n }, [handleFocusableMenuItemOnMouseEnter, itemNode]);\n const handleOnFocus = React.useCallback<React.FocusEventHandler<HTMLDivElement>>(\n (e) => {\n handleFocusableMenuItemNativeFocusEvent(itemNode, e);\n },\n [handleFocusableMenuItemNativeFocusEvent, itemNode],\n );\n\n const spacelessDsIdForDom = `ds-menu-item-${`${dsId}`.replace(/\\s/g, '')}`;\n return (\n <StyledGlobalMenuItemWrapper\n innerRef={handleFocusOnRender}\n onKeyDown={handleFocusableMenuItemKeyDown}\n onClick={handleFocusableMenuItemClick}\n onMouseEnter={handleOnMouseEnter}\n onFocus={handleOnFocus}\n as=\"div\"\n id={`${spacelessDsIdForDom}`}\n tabIndex={isFocused ? 0 : -1}\n role=\"menuitemradio\"\n aria-checked={isSelected}\n aria-disabled={disabled}\n applyAriaDisabled={disabled}\n >\n <StyledContentWrapper\n cols={gridLayout}\n minHeight=\"16px\"\n gutter=\"xxs\"\n alignItems=\"center\"\n minWidth={minWidth ?? undefined}\n >\n <LeftBoxlessRadio isSelected={isSelected} />\n {LeftDecComponent ? <LeftDecComponent /> : null}\n <StyleMenuItemLabel>{label}</StyleMenuItemLabel>\n {secondaryLabel !== undefined && (\n <StyleMenuItemSecondaryLabel disabled={disabled}>{secondaryLabel}</StyleMenuItemSecondaryLabel>\n )}\n </StyledContentWrapper>\n </StyledGlobalMenuItemWrapper>\n );\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACsBY,cA2E7B,YA3E6B;AArBnC,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AACvB,OAAOA,YAAW;AAElB,SAAS,6CAA6C;AACtD,SAAS,0BAA0B;AAEnC,MAAM,0BAA0B,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAO5C,MAAM,mBAAmBA,OAAM,KAAK,CAAC,EAAE,WAAW,MAChD,oBAAC,QAAK,OAAM,QAAQ,uBAAa,oBAAC,2BAAwB,IAAK,oBAAC,SAAI,GAAG,CACxE;AACM,MAAM,uBAAkG,CAAC;AAAA,EAC9G;AACF,MAAM;AACJ,QAAM,EAAE,MAAM,UAAU,IAAI;AAC5B,QAAM,EAAE,OAAO,gBAAgB,gBAAgB,kBAAkB,UAAU,SAAS,IAAI;AAExF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,wBAAwB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,IAAIA,OAAM,WAAW,qCAAqC;AAC1D,QAAM,EAAE,cAAc,IAAI;AAE1B,QAAM,aAAaA,OAAM,QAAQ,MAAM;AACrC,UAAM,OAAO,mBAAmB,CAAC,eAAe,eAAe,MAAM,IAAI,CAAC,eAAe,MAAM;AAC/F,QAAI,eAAgB,MAAK,KAAK,MAAM;AACpC,WAAO;AAAA,EACT,GAAG,CAAC,kBAAkB,cAAc,CAAC;AAErC,QAAM,iCAAiCA,OAAM,OAAO,WAAW;AAC/D,iCAA+B,UAAU;AAEzC,QAAM,YAAY,gBAAgB,mBAAmB,aAAa,IAAI;AAGtE,QAAM,aAAa,cAAe,KAAK,CAAC,yBAAyB,qBAAqB,SAAS,IAAI;AAEnG,QAAM,sBAAsBA,OAAM;AAAA,IAChC,CAAC,SAAyB;AACxB,iBAAW,MAAM;AACf,YAAI,QAAQ,gBAAgB,mBAAmB,aAAa,IAAI,GAAG;AACjE,eAAK,MAAM;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH;AAAA;AAAA,IAEA,CAAC,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA,EAIpB;AAEA,QAAM,qBAAqBA,OAAM,YAAqD,MAAM;AAC1F,wCAAoC,QAAQ;AAAA,EAC9C,GAAG,CAAC,qCAAqC,QAAQ,CAAC;AAClD,QAAM,gBAAgBA,OAAM;AAAA,IAC1B,CAAC,MAAM;AACL,8CAAwC,UAAU,CAAC;AAAA,IACrD;AAAA,IACA,CAAC,yCAAyC,QAAQ;AAAA,EACpD;AAEA,QAAM,sBAAsB,gBAAgB,GAAG,IAAI,GAAG,QAAQ,OAAO,EAAE,CAAC;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,WAAW;AAAA,MACX,SAAS;AAAA,MACT,cAAc;AAAA,MACd,SAAS;AAAA,MACT,IAAG;AAAA,MACH,IAAI,GAAG,mBAAmB;AAAA,MAC1B,UAAU,YAAY,IAAI;AAAA,MAC1B,MAAK;AAAA,MACL,gBAAc;AAAA,MACd,iBAAe;AAAA,MACf,mBAAmB;AAAA,MAEnB;AAAA,QAAC;AAAA;AAAA,UACC,MAAM;AAAA,UACN,WAAU;AAAA,UACV,QAAO;AAAA,UACP,YAAW;AAAA,UACX,UAAU,YAAY;AAAA,UAEtB;AAAA,gCAAC,oBAAiB,YAAwB;AAAA,YACzC,mBAAmB,oBAAC,oBAAiB,IAAK;AAAA,YAC3C,oBAAC,sBAAoB,iBAAM;AAAA,YAC1B,mBAAmB,UAClB,oBAAC,+BAA4B,UAAqB,0BAAe;AAAA;AAAA;AAAA,MAErE;AAAA;AAAA,EACF;AAEJ;",
6
6
  "names": ["React"]
7
7
  }