@elliemae/ds-menu-button 3.46.0-rc.3 → 3.46.0-rc.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. package/dist/cjs/config/useMenuButton.js +6 -2
  2. package/dist/cjs/config/useMenuButton.js.map +2 -2
  3. package/dist/cjs/config/useSplitInherithedProps.js +2 -0
  4. package/dist/cjs/config/useSplitInherithedProps.js.map +2 -2
  5. package/dist/cjs/parts/DSFlyoutMenu/DSFlyoutMenu.js +26 -12
  6. package/dist/cjs/parts/DSFlyoutMenu/DSFlyoutMenu.js.map +3 -3
  7. package/dist/cjs/parts/DSFlyoutMenu/react-desc-prop-types.js +1 -1
  8. package/dist/cjs/parts/DSFlyoutMenu/react-desc-prop-types.js.map +3 -3
  9. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js +40 -30
  10. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js.map +2 -2
  11. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js +1 -1
  12. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js.map +2 -2
  13. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js +21 -4
  14. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js.map +2 -2
  15. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableMenuItem.js +4 -5
  16. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableMenuItem.js.map +2 -2
  17. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js +4 -5
  18. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js.map +2 -2
  19. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js +4 -5
  20. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js.map +2 -2
  21. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js +4 -5
  22. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js.map +2 -2
  23. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js +4 -5
  24. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js.map +2 -2
  25. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js +4 -5
  26. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js.map +2 -2
  27. package/dist/cjs/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js +4 -5
  28. package/dist/cjs/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js.map +2 -2
  29. package/dist/cjs/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js +1 -1
  30. package/dist/cjs/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js.map +2 -2
  31. package/dist/cjs/parts/DSMenuItemRendererFactory/focusNodeRacingConditionSolved.js +43 -0
  32. package/dist/cjs/parts/DSMenuItemRendererFactory/focusNodeRacingConditionSolved.js.map +7 -0
  33. package/dist/cjs/parts/DSMenuItemRendererFactory/react-desc-prop-types.js.map +2 -2
  34. package/dist/cjs/parts/DSOpinionatedButton/react-desc-prop-types.js.map +2 -2
  35. package/dist/cjs/react-desc-prop-types.js +7 -4
  36. package/dist/cjs/react-desc-prop-types.js.map +2 -2
  37. package/dist/cjs/utils/useOptionsArrayToDsTree.js +10 -3
  38. package/dist/cjs/utils/useOptionsArrayToDsTree.js.map +2 -2
  39. package/dist/esm/config/useMenuButton.js +7 -3
  40. package/dist/esm/config/useMenuButton.js.map +2 -2
  41. package/dist/esm/config/useSplitInherithedProps.js +2 -0
  42. package/dist/esm/config/useSplitInherithedProps.js.map +2 -2
  43. package/dist/esm/parts/DSFlyoutMenu/DSFlyoutMenu.js +24 -10
  44. package/dist/esm/parts/DSFlyoutMenu/DSFlyoutMenu.js.map +2 -2
  45. package/dist/esm/parts/DSFlyoutMenu/react-desc-prop-types.js +1 -4
  46. package/dist/esm/parts/DSFlyoutMenu/react-desc-prop-types.js.map +2 -2
  47. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js +40 -30
  48. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js.map +2 -2
  49. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js +1 -1
  50. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js.map +2 -2
  51. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js +21 -4
  52. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js.map +2 -2
  53. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableMenuItem.js +4 -5
  54. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableMenuItem.js.map +2 -2
  55. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js +4 -5
  56. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js.map +2 -2
  57. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js +4 -5
  58. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js.map +2 -2
  59. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js +4 -5
  60. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js.map +2 -2
  61. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js +4 -5
  62. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js.map +2 -2
  63. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js +4 -5
  64. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js.map +2 -2
  65. package/dist/esm/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js +4 -5
  66. package/dist/esm/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js.map +2 -2
  67. package/dist/esm/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js +1 -1
  68. package/dist/esm/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js.map +2 -2
  69. package/dist/esm/parts/DSMenuItemRendererFactory/focusNodeRacingConditionSolved.js +13 -0
  70. package/dist/esm/parts/DSMenuItemRendererFactory/focusNodeRacingConditionSolved.js.map +7 -0
  71. package/dist/esm/parts/DSMenuItemRendererFactory/react-desc-prop-types.js.map +2 -2
  72. package/dist/esm/parts/DSOpinionatedButton/react-desc-prop-types.js +1 -1
  73. package/dist/esm/parts/DSOpinionatedButton/react-desc-prop-types.js.map +2 -2
  74. package/dist/esm/react-desc-prop-types.js +7 -4
  75. package/dist/esm/react-desc-prop-types.js.map +2 -2
  76. package/dist/esm/utils/useOptionsArrayToDsTree.js +10 -3
  77. package/dist/esm/utils/useOptionsArrayToDsTree.js.map +2 -2
  78. package/dist/types/config/useSplitInherithedProps.d.ts +0 -1
  79. package/dist/types/parts/DSFlyoutMenu/react-desc-prop-types.d.ts +1 -1
  80. package/dist/types/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.d.ts +6 -6
  81. package/dist/types/parts/DSMenuItemRendererFactory/focusNodeRacingConditionSolved.d.ts +2 -0
  82. package/dist/types/parts/DSMenuItemRendererFactory/react-desc-prop-types.d.ts +2 -2
  83. package/dist/types/parts/DSOpinionatedButton/react-desc-prop-types.d.ts +1 -1
  84. package/dist/types/react-desc-prop-types.d.ts +8 -2
  85. package/dist/types/utils/useOptionsArrayToDsTree.d.ts +2 -1
  86. package/package.json +12 -13
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\nimport { Grid } from '@elliemae/ds-grid';\nimport { ChevronSmallRight } from '@elliemae/ds-icons';\nimport { useFloatingContext, type DSHookFloatingContextT } from '@elliemae/ds-floating-context';\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';\nimport { type DSMenuItemRendererFactoryT } from './react-desc-prop-types.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 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 SingleSelectWithSubmenuMenuItem: React.ComponentType<{\n itemNode: DSMenuButtonT.MenuNodeSingleSelectWithSubmenuItem;\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 { selectedNodes } = 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 // 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 = selectedNodes!.some((itemMarkesAsSelected) => itemMarkesAsSelected.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=\"menuitemradio\"\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 <LeftBoxlessRadio 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 max-lines */\nimport { Grid } from '@elliemae/ds-grid';\nimport { ChevronSmallRight } from '@elliemae/ds-icons';\nimport { useFloatingContext, type DSHookFloatingContextT } from '@elliemae/ds-floating-context';\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';\nimport { type DSMenuItemRendererFactoryT } from './react-desc-prop-types.js';\nimport { focusNodeRacingConditionSolved } from './focusNodeRacingConditionSolved.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 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 SingleSelectWithSubmenuMenuItem: React.ComponentType<{\n itemNode: DSMenuButtonT.MenuNodeSingleSelectWithSubmenuItem;\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 { selectedNodes } = 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 // 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 = selectedNodes!.some((itemMarkesAsSelected) => itemMarkesAsSelected.dsId === dsId);\n\n const handleFocusOnRender = React.useCallback(\n (node: HTMLDivElement) => {\n setReference(node);\n if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {\n focusNodeRacingConditionSolved(node);\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=\"menuitemradio\"\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 <LeftBoxlessRadio 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
  }
@@ -11,6 +11,7 @@ import { useFloatingContext } from "@elliemae/ds-floating-context";
11
11
  import React2 from "react";
12
12
  import { MenuBehaviouralContextProviderContext } from "../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js";
13
13
  import { MENU_FOCUS_REGIONS } from "../DSMenuBehaviouralContextProvider/constants/index.js";
14
+ import { focusNodeRacingConditionSolved } from "./focusNodeRacingConditionSolved.js";
14
15
  const placementOrderPreference = [
15
16
  "right-start",
16
17
  "right-start",
@@ -54,11 +55,9 @@ const WithSubmenuMenuItem = ({ itemNode, FlyoutMenuCircularDepInject }) => {
54
55
  const handleFocusOnRender = React2.useCallback(
55
56
  (node) => {
56
57
  setReference(node);
57
- setTimeout(() => {
58
- if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {
59
- node.focus();
60
- }
61
- });
58
+ if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {
59
+ focusNodeRacingConditionSolved(node);
60
+ }
62
61
  },
63
62
  // we need to change the callback reference every time the focusRegion changes or else the focus will not be set
64
63
  [dsId, focusRegion, setReference]
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { ChevronSmallRight } from '@elliemae/ds-icons';\nimport {\n StyleMenuItemLabel,\n StyleMenuItemSecondaryLabel,\n StyledContentWrapper,\n StyledGlobalMenuItemWrapper,\n} from '@elliemae/ds-menu-items-commons';\nimport { useFloatingContext, type DSHookFloatingContextT } from '@elliemae/ds-floating-context';\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';\n\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 WithSubmenuMenuItem: React.ComponentType<{\n itemNode: DSMenuButtonT.MenuNodeWithSubmenuItem;\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 cols.push('min-content');\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 isExpanded = openedSubItems.some((itemWithOpenSubmenu) => itemWithOpenSubmenu.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-haspopup=\"menu\"\n aria-expanded={isExpanded}\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-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 <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", "import { ChevronSmallRight } from '@elliemae/ds-icons';\nimport {\n StyleMenuItemLabel,\n StyleMenuItemSecondaryLabel,\n StyledContentWrapper,\n StyledGlobalMenuItemWrapper,\n} from '@elliemae/ds-menu-items-commons';\nimport { useFloatingContext, type DSHookFloatingContextT } from '@elliemae/ds-floating-context';\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 { focusNodeRacingConditionSolved } from './focusNodeRacingConditionSolved.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];\nexport const WithSubmenuMenuItem: React.ComponentType<{\n itemNode: DSMenuButtonT.MenuNodeWithSubmenuItem;\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 cols.push('min-content');\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 isExpanded = openedSubItems.some((itemWithOpenSubmenu) => itemWithOpenSubmenu.dsId === dsId);\n\n const handleFocusOnRender = React.useCallback(\n (node: HTMLDivElement) => {\n setReference(node);\n if (node && focusRegion === MENU_FOCUS_REGIONS.ITEM_BY_DSID(dsId)) {\n focusNodeRacingConditionSolved(node);\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-haspopup=\"menu\"\n aria-expanded={isExpanded}\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-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 <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
  }
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
- import React2 from "react";
3
2
  import { useGetXstyledProps } from "@elliemae/ds-props-helpers";
3
+ import React2 from "react";
4
4
  import { uid } from "uid";
5
5
  import {
6
6
  DSMenuItemRendererFactoryPropTypesSchema,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../src/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport { useGetXstyledProps } from '@elliemae/ds-props-helpers';\nimport { uid } from 'uid';\nimport {\n type DSMenuItemRendererFactoryT,\n DSMenuItemRendererFactoryPropTypesSchema,\n defaultProps,\n} from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nexport const useMenuItemRendererFactory = (propsFromUser: DSMenuItemRendererFactoryT.Props) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n // the component deals with HTML DOM elements,\n // Deep compare of HTML DOM elements is pointless and extremely costly\n // for this specific case, we are better of not using `useMemoMergePropsWithDefault`\n const propsWithDefault = React.useMemo(\n () => ({\n ...defaultProps,\n ...propsFromUser,\n }),\n [propsFromUser],\n ) as DSMenuItemRendererFactoryT.InternalProps;\n useValidateProps(propsWithDefault, DSMenuItemRendererFactoryPropTypesSchema);\n // =============================================================================\n // XSTYLED PROPS\n // =============================================================================\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n // custom code goes here, this is an example\n const instanceUid = React.useMemo(() => `ds-menu-item-renderer-factory-${uid(5)}`, []);\n\n return React.useMemo(\n () => ({\n propsWithDefault,\n xstyledProps,\n instanceUid,\n }),\n [propsWithDefault, xstyledProps, instanceUid],\n );\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,YAAW;AAClB,SAAS,0BAA0B;AACnC,SAAS,WAAW;AACpB;AAAA,EAEE;AAAA,EACA;AAAA,OACK;AACP,SAAS,wBAAwB;AAE1B,MAAM,6BAA6B,CAAC,kBAAoD;AAO7F,QAAM,mBAAmBA,OAAM;AAAA,IAC7B,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AACA,mBAAiB,kBAAkB,wCAAwC;AAI3E,QAAM,eAAe,mBAAmB,gBAAgB;AAKxD,QAAM,cAAcA,OAAM,QAAQ,MAAM,iCAAiC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAErF,SAAOA,OAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,cAAc,WAAW;AAAA,EAC9C;AACF;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useGetXstyledProps } from '@elliemae/ds-props-helpers';\nimport React from 'react';\nimport { uid } from 'uid';\nimport {\n DSMenuItemRendererFactoryPropTypesSchema,\n defaultProps,\n type DSMenuItemRendererFactoryT,\n} from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nexport const useMenuItemRendererFactory = (propsFromUser: DSMenuItemRendererFactoryT.Props) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n // the component deals with HTML DOM elements,\n // Deep compare of HTML DOM elements is pointless and extremely costly\n // for this specific case, we are better of not using `useMemoMergePropsWithDefault`\n const propsWithDefault = React.useMemo(\n () => ({\n ...defaultProps,\n ...propsFromUser,\n }),\n [propsFromUser],\n ) as DSMenuItemRendererFactoryT.InternalProps;\n useValidateProps(propsWithDefault, DSMenuItemRendererFactoryPropTypesSchema);\n // =============================================================================\n // XSTYLED PROPS\n // =============================================================================\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n // custom code goes here, this is an example\n const instanceUid = React.useMemo(() => `ds-menu-item-renderer-factory-${uid(5)}`, []);\n\n return React.useMemo(\n () => ({\n propsWithDefault,\n xstyledProps,\n instanceUid,\n }),\n [propsWithDefault, xstyledProps, instanceUid],\n );\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,0BAA0B;AACnC,OAAOA,YAAW;AAClB,SAAS,WAAW;AACpB;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,wBAAwB;AAE1B,MAAM,6BAA6B,CAAC,kBAAoD;AAO7F,QAAM,mBAAmBA,OAAM;AAAA,IAC7B,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AACA,mBAAiB,kBAAkB,wCAAwC;AAI3E,QAAM,eAAe,mBAAmB,gBAAgB;AAKxD,QAAM,cAAcA,OAAM,QAAQ,MAAM,iCAAiC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAErF,SAAOA,OAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,cAAc,WAAW;AAAA,EAC9C;AACF;",
6
6
  "names": ["React"]
7
7
  }
@@ -0,0 +1,13 @@
1
+ import * as React from "react";
2
+ import { throttle } from "lodash";
3
+ const focusNodeRacingConditionSolved = throttle(
4
+ (node) => {
5
+ node.focus();
6
+ },
7
+ 10,
8
+ { leading: false, trailing: true }
9
+ );
10
+ export {
11
+ focusNodeRacingConditionSolved
12
+ };
13
+ //# sourceMappingURL=focusNodeRacingConditionSolved.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/DSMenuItemRendererFactory/focusNodeRacingConditionSolved.tsx"],
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { throttle } from 'lodash';\n\nexport const focusNodeRacingConditionSolved = throttle(\n (node: HTMLDivElement) => {\n node.focus();\n },\n 10,\n { leading: false, trailing: true },\n);\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,gBAAgB;AAElB,MAAM,iCAAiC;AAAA,EAC5C,CAAC,SAAyB;AACxB,SAAK,MAAM;AAAA,EACb;AAAA,EACA;AAAA,EACA,EAAE,SAAS,OAAO,UAAU,KAAK;AACnC;",
6
+ "names": []
7
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/DSMenuItemRendererFactory/react-desc-prop-types.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { GlobalAttributesT, XstyledProps, DSPropTypesSchema, ValidationMap } from '@elliemae/ds-props-helpers';\nimport {\n PropTypes,\n getPropsPerSlotPropTypes,\n globalAttributesPropTypes,\n xstyledPropTypes,\n} from '@elliemae/ds-props-helpers';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport { DSMenuItemRendererFactoryName, MENU_ITEM_RENDERER_FACTORY_SLOTS } from './constants/index.js';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport type { DSFlyoutMenuT } from '../DSFlyoutMenu/react-desc-prop-types.js';\n\nexport declare namespace DSMenuItemRendererFactoryT {\n /*\n * everything that is specifically added in this namespace declaration and is not part of the original component\n * is because the original component is an \"opinionated widget\" that offloads a chunk of responsibilities from dev to dimsum\n * as such, the widget generates those interfaces,\n * but the app developer is not supposed to know about them\n * untill they go atomic composition (this namespace)\n */\n export interface RequiredProps {\n itemNode: DSMenuButtonT.MenuNode;\n FlyoutMenuCircularDepInject: React.ComponentType<DSFlyoutMenuT.Props>;\n }\n\n export interface DefaultProps {}\n\n export interface OptionalProps\n extends TypescriptHelpersT.PropsForGlobalOnSlots<\n typeof DSMenuItemRendererFactoryName,\n typeof MENU_ITEM_RENDERER_FACTORY_SLOTS\n > {\n ItemRenderer?: DSMenuButtonT.ItemRendererT;\n }\n export interface Props\n extends Partial<DefaultProps>,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLLIElement>, keyof OptionalProps | keyof XstyledProps>,\n XstyledProps,\n RequiredProps {}\n\n export interface InternalProps\n extends DefaultProps,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLLIElement>, keyof OptionalProps | keyof XstyledProps>,\n XstyledProps,\n RequiredProps {}\n}\n\nexport const defaultProps: DSMenuItemRendererFactoryT.DefaultProps = {};\n\nexport const DSMenuItemRendererFactoryPropTypes: DSPropTypesSchema<DSMenuItemRendererFactoryT.Props> = {\n ...getPropsPerSlotPropTypes(DSMenuItemRendererFactoryName, MENU_ITEM_RENDERER_FACTORY_SLOTS),\n ...globalAttributesPropTypes,\n ...xstyledPropTypes,\n itemNode: PropTypes.object.description('The polymorphic item to render').isRequired,\n ItemRenderer: PropTypes.func.description('The custom item renderer'),\n FlyoutMenuCircularDepInject: PropTypes.func.description(\n 'Flyout menu component, passed to the factory to avoid circular dependency',\n ),\n};\n\nexport const DSMenuItemRendererFactoryPropTypesSchema =\n DSMenuItemRendererFactoryPropTypes as unknown as ValidationMap<DSMenuItemRendererFactoryT.Props>;\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACEvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,+BAA+B,wCAAwC;AAyCzE,MAAM,eAAwD,CAAC;AAE/D,MAAM,qCAA0F;AAAA,EACrG,GAAG,yBAAyB,+BAA+B,gCAAgC;AAAA,EAC3F,GAAG;AAAA,EACH,GAAG;AAAA,EACH,UAAU,UAAU,OAAO,YAAY,gCAAgC,EAAE;AAAA,EACzE,cAAc,UAAU,KAAK,YAAY,0BAA0B;AAAA,EACnE,6BAA6B,UAAU,KAAK;AAAA,IAC1C;AAAA,EACF;AACF;AAEO,MAAM,2CACX;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { DSPropTypesSchema, GlobalAttributesT, ValidationMap, XstyledProps } from '@elliemae/ds-props-helpers';\nimport {\n PropTypes,\n getPropsPerSlotPropTypes,\n globalAttributesPropTypes,\n xstyledPropTypes,\n} from '@elliemae/ds-props-helpers';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport type { DSFlyoutMenuT } from '../DSFlyoutMenu/react-desc-prop-types.js';\nimport { DSMenuItemRendererFactoryName, MENU_ITEM_RENDERER_FACTORY_SLOTS } from './constants/index.js';\n\nexport declare namespace DSMenuItemRendererFactoryT {\n /*\n * everything that is specifically added in this namespace declaration and is not part of the original component\n * is because the original component is an \"opinionated widget\" that offloads a chunk of responsibilities from dev to dimsum\n * as such, the widget generates those interfaces,\n * but the app developer is not supposed to know about them\n * untill they go atomic composition (this namespace)\n */\n export interface RequiredProps {\n itemNode: DSMenuButtonT.MenuNode;\n FlyoutMenuCircularDepInject: React.ComponentType<DSFlyoutMenuT.Props>;\n }\n\n export interface DefaultProps {}\n\n export interface OptionalProps\n extends TypescriptHelpersT.PropsForGlobalOnSlots<\n typeof DSMenuItemRendererFactoryName,\n typeof MENU_ITEM_RENDERER_FACTORY_SLOTS\n > {\n ItemRenderer?: DSMenuButtonT.ItemRendererT;\n }\n export interface Props\n extends Partial<DefaultProps>,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLLIElement>, keyof OptionalProps | keyof XstyledProps>,\n XstyledProps,\n RequiredProps {}\n\n export interface InternalProps\n extends DefaultProps,\n OptionalProps,\n Omit<GlobalAttributesT<HTMLLIElement>, keyof OptionalProps | keyof XstyledProps>,\n XstyledProps,\n RequiredProps {}\n}\n\nexport const defaultProps: DSMenuItemRendererFactoryT.DefaultProps = {};\n\nexport const DSMenuItemRendererFactoryPropTypes: DSPropTypesSchema<DSMenuItemRendererFactoryT.Props> = {\n ...getPropsPerSlotPropTypes(DSMenuItemRendererFactoryName, MENU_ITEM_RENDERER_FACTORY_SLOTS),\n ...globalAttributesPropTypes,\n ...xstyledPropTypes,\n itemNode: PropTypes.object.description('The polymorphic item to render').isRequired,\n ItemRenderer: PropTypes.func.description('The custom item renderer'),\n FlyoutMenuCircularDepInject: PropTypes.func.description(\n 'Flyout menu component, passed to the factory to avoid circular dependency',\n ),\n};\n\nexport const DSMenuItemRendererFactoryPropTypesSchema =\n DSMenuItemRendererFactoryPropTypes as unknown as ValidationMap<DSMenuItemRendererFactoryT.Props>;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACEvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIP,SAAS,+BAA+B,wCAAwC;AAuCzE,MAAM,eAAwD,CAAC;AAE/D,MAAM,qCAA0F;AAAA,EACrG,GAAG,yBAAyB,+BAA+B,gCAAgC;AAAA,EAC3F,GAAG;AAAA,EACH,GAAG;AAAA,EACH,UAAU,UAAU,OAAO,YAAY,gCAAgC,EAAE;AAAA,EACzE,cAAc,UAAU,KAAK,YAAY,0BAA0B;AAAA,EACnE,6BAA6B,UAAU,KAAK;AAAA,IAC1C;AAAA,EACF;AACF;AAEO,MAAM,2CACX;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { DSButtonV3DefaultProps, DSButtonV3PropTypes } from "@elliemae/ds-button-v2";
3
- import { getPropsPerSlotPropTypes, PropTypes } from "@elliemae/ds-props-helpers";
3
+ import { PropTypes, getPropsPerSlotPropTypes } from "@elliemae/ds-props-helpers";
4
4
  import { DSMenuSpecificPropTypes } from "../../react-desc-prop-types.js";
5
5
  import { DSOpinionatedButtonName, OPINIONATED_BUTTON_SLOTS } from "./constants/index.js";
6
6
  const defaultProps = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/DSOpinionatedButton/react-desc-prop-types.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-empty-interface */\nimport React from 'react';\nimport { DSButtonV3DefaultProps, DSButtonV3PropTypes } from '@elliemae/ds-button-v2';\nimport type { DSPropTypesSchema, ValidationMap } from '@elliemae/ds-props-helpers';\nimport { getPropsPerSlotPropTypes, PropTypes } from '@elliemae/ds-props-helpers';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport { type DSMenuButtonT, DSMenuSpecificPropTypes } from '../../react-desc-prop-types.js';\nimport { DSOpinionatedButtonName, OPINIONATED_BUTTON_SLOTS } from './constants/index.js';\n\nexport declare namespace DSOpinionatedButtonT {\n /*\n * everything that is specifically added in this namespace declaration and is not part of the original component\n * is because the original component is an \"opinionated widget\" that offloads a chunk of responsibilities from dev to dimsum\n * as such, the widget generates those interfaces,\n * but the app developer is not supposed to know about them\n * untill they go atomic composition (this namespace)\n */\n export interface RequiredProps extends DSMenuButtonT.ButtonInheritedRequiredProps {\n menuSpecificProps: DSMenuButtonT.MenuSpecificProps;\n }\n\n export interface DefaultProps extends DSMenuButtonT.ButtonInheiredDefaultProps {}\n\n export interface OptionalProps\n extends TypescriptHelpersT.PropsForGlobalOnSlots<typeof DSOpinionatedButtonName, typeof OPINIONATED_BUTTON_SLOTS>,\n DSMenuButtonT.ButtonInheritedOptionalProps {}\n\n export interface Props\n extends RequiredProps,\n Partial<DefaultProps>,\n OptionalProps,\n // this is where global/xstyled props are inherited from DSButtonV3\n DSMenuButtonT.ButtonInheritedProps {\n innerRef: React.RefCallback<HTMLButtonElement>;\n }\n\n export interface InternalProps\n extends RequiredProps,\n DefaultProps,\n OptionalProps,\n // this is where global/xstyled props are inherited from DSButtonV3\n DSMenuButtonT.ButtonInheritedInternalProps {\n innerRef: React.RefCallback<HTMLButtonElement>;\n }\n}\n\nexport const defaultProps: DSOpinionatedButtonT.DefaultProps = {\n ...DSButtonV3DefaultProps,\n};\n\nexport const DSOpinionatedButtonPropTypes: DSPropTypesSchema<DSOpinionatedButtonT.Props> = {\n ...getPropsPerSlotPropTypes(DSOpinionatedButtonName, OPINIONATED_BUTTON_SLOTS),\n ...DSButtonV3PropTypes,\n menuSpecificProps: PropTypes.shape(DSMenuSpecificPropTypes).description('Props for the main flyout menu').isRequired,\n innerRef: PropTypes.func.description(\n 'Ref callback for the button, if not provided how is the flyout menu being positioned?',\n ).isRequired,\n};\n\nexport const DSOpinionatedButtonPropTypesSchema =\n DSOpinionatedButtonPropTypes as unknown as ValidationMap<DSOpinionatedButtonT.Props>;\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACEvB,SAAS,wBAAwB,2BAA2B;AAE5D,SAAS,0BAA0B,iBAAiB;AAEpD,SAA6B,+BAA+B;AAC5D,SAAS,yBAAyB,gCAAgC;AAuC3D,MAAM,eAAkD;AAAA,EAC7D,GAAG;AACL;AAEO,MAAM,+BAA8E;AAAA,EACzF,GAAG,yBAAyB,yBAAyB,wBAAwB;AAAA,EAC7E,GAAG;AAAA,EACH,mBAAmB,UAAU,MAAM,uBAAuB,EAAE,YAAY,gCAAgC,EAAE;AAAA,EAC1G,UAAU,UAAU,KAAK;AAAA,IACvB;AAAA,EACF,EAAE;AACJ;AAEO,MAAM,qCACX;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-empty-interface */\nimport { DSButtonV3DefaultProps, DSButtonV3PropTypes } from '@elliemae/ds-button-v2';\nimport type { DSPropTypesSchema, ValidationMap } from '@elliemae/ds-props-helpers';\nimport { PropTypes, getPropsPerSlotPropTypes } from '@elliemae/ds-props-helpers';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type React from 'react';\nimport { DSMenuSpecificPropTypes, type DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { DSOpinionatedButtonName, OPINIONATED_BUTTON_SLOTS } from './constants/index.js';\n\nexport declare namespace DSOpinionatedButtonT {\n /*\n * everything that is specifically added in this namespace declaration and is not part of the original component\n * is because the original component is an \"opinionated widget\" that offloads a chunk of responsibilities from dev to dimsum\n * as such, the widget generates those interfaces,\n * but the app developer is not supposed to know about them\n * untill they go atomic composition (this namespace)\n */\n export interface RequiredProps extends DSMenuButtonT.ButtonInheritedRequiredProps {\n menuSpecificProps: DSMenuButtonT.MenuSpecificProps;\n }\n\n export interface DefaultProps extends DSMenuButtonT.ButtonInheiredDefaultProps {}\n\n export interface OptionalProps\n extends TypescriptHelpersT.PropsForGlobalOnSlots<typeof DSOpinionatedButtonName, typeof OPINIONATED_BUTTON_SLOTS>,\n DSMenuButtonT.ButtonInheritedOptionalProps {}\n\n export interface Props\n extends RequiredProps,\n Partial<DefaultProps>,\n OptionalProps,\n // this is where global/xstyled props are inherited from DSButtonV3\n DSMenuButtonT.ButtonInheritedProps {\n innerRef: React.RefCallback<HTMLButtonElement>;\n }\n\n export interface InternalProps\n extends RequiredProps,\n DefaultProps,\n OptionalProps,\n // this is where global/xstyled props are inherited from DSButtonV3\n DSMenuButtonT.ButtonInheritedInternalProps {\n innerRef: React.RefCallback<HTMLButtonElement>;\n }\n}\n\nexport const defaultProps: DSOpinionatedButtonT.DefaultProps = {\n ...DSButtonV3DefaultProps,\n};\n\nexport const DSOpinionatedButtonPropTypes: DSPropTypesSchema<DSOpinionatedButtonT.Props> = {\n ...getPropsPerSlotPropTypes(DSOpinionatedButtonName, OPINIONATED_BUTTON_SLOTS),\n ...DSButtonV3PropTypes,\n menuSpecificProps: PropTypes.shape(DSMenuSpecificPropTypes).description('Props for the main flyout menu').isRequired,\n innerRef: PropTypes.func.description(\n 'Ref callback for the button, if not provided how is the flyout menu being positioned?',\n ).isRequired,\n};\n\nexport const DSOpinionatedButtonPropTypesSchema =\n DSOpinionatedButtonPropTypes as unknown as ValidationMap<DSOpinionatedButtonT.Props>;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACCvB,SAAS,wBAAwB,2BAA2B;AAE5D,SAAS,WAAW,gCAAgC;AAGpD,SAAS,+BAAmD;AAC5D,SAAS,yBAAyB,gCAAgC;AAuC3D,MAAM,eAAkD;AAAA,EAC7D,GAAG;AACL;AAEO,MAAM,+BAA8E;AAAA,EACzF,GAAG,yBAAyB,yBAAyB,wBAAwB;AAAA,EAC7E,GAAG;AAAA,EACH,mBAAmB,UAAU,MAAM,uBAAuB,EAAE,YAAY,gCAAgC,EAAE;AAAA,EAC1G,UAAU,UAAU,KAAK;AAAA,IACvB;AAAA,EACF,EAAE;AACJ;AAEO,MAAM,qCACX;",
6
6
  "names": []
7
7
  }
@@ -2,13 +2,15 @@ import * as React from "react";
2
2
  import { PropTypes, getPropsPerSlotPropTypes } from "@elliemae/ds-props-helpers";
3
3
  import { DSButtonV3PropTypes } from "@elliemae/ds-button-v2";
4
4
  import { DSMenuButtonName, MENU_BUTTON_SLOTS } from "./constants/index.js";
5
- const defaultProps = {
5
+ const menuSpecificDefaultProps = {
6
6
  onClickOutside: () => null,
7
7
  onOptionClick: () => null,
8
8
  openedSubmenus: {},
9
9
  onSubmenuToggle: () => null,
10
10
  isLoading: false,
11
- isSkeleton: false
11
+ isSkeleton: false,
12
+ maxHeight: "256px"
13
+ // was available in dropdownmenu-v2, have to provide for retrocompatibility
12
14
  };
13
15
  const MenuBehaviouralLayerPropTypes = {
14
16
  onItemSelected: PropTypes.func.description(
@@ -43,7 +45,8 @@ const DSMenuSpecificPropTypes = {
43
45
  "((nextOpenedSubmenus: Record<string, boolean>, submenu: Item, e: React.MouseEvent | React.KeyboardEvent) => void)"
44
46
  ).defaultValue(() => null),
45
47
  isLoading: PropTypes.bool.description("Whether the flyout menu should render the loading indicator").defaultValue(false),
46
- isSkeleton: PropTypes.bool.description("Whether the flyout menu should render the skeleton").defaultValue(false)
48
+ isSkeleton: PropTypes.bool.description("Whether the flyout menu should render the skeleton").defaultValue(false),
49
+ maxHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).description("The maximum height of the flyout menu").defaultValue("256px")
47
50
  };
48
51
  const DSMenuButtonPropTypes = {
49
52
  options: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).description(
@@ -63,6 +66,6 @@ export {
63
66
  DSMenuButtonPropTypesSchema,
64
67
  DSMenuSpecificPropTypes,
65
68
  MenuBehaviouralLayerPropTypes,
66
- defaultProps
69
+ menuSpecificDefaultProps
67
70
  };
68
71
  //# sourceMappingURL=react-desc-prop-types.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/react-desc-prop-types.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/no-empty-interface */\nimport { PropTypes, getPropsPerSlotPropTypes } from '@elliemae/ds-props-helpers';\nimport { DSButtonV3PropTypes } from '@elliemae/ds-button-v2';\nimport type { DSPropTypesSchema, ValidationMap } from '@elliemae/ds-props-helpers';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type { DSButtonV3T } from '@elliemae/ds-button-v2';\nimport type { UseDSTreeT } from '@elliemae/ds-tree-model';\n\nimport { DSMenuButtonName, MENU_BUTTON_SLOTS, type MENU_ITEMS_TYPES } from './constants/index.js';\nexport declare namespace DSMenuButtonT {\n /* *******************************************************\n * YURI's NOTE:\n *\n * This polymorphic interface \"looks similar\" between the diffent types\n * but it's actually different upon closer inspection\n *\n * If you are smarter then me, you can probably find a way to make this more DRY\n * but I prefeer AHA (Avoid Hasty Abstractions) that gives me an easier to mantain code\n * ESPECIALLY when the types are so similar but not the same & in typescript (polymorphism is hard in TS)\n *\n * So I'm going to keep them separate and explicit\n * key difference is what's required to exist and what is required to explicitly NOT exist\n *\n * If someone's review this and make this DRY, I'm NOT going to mantain this code moving forward\n * whoever makes this TS DRY will be responsible for it and own it.\n ******************************************************* */\n\n /* **************************************************************************************************************\n *********************************** POLYMORPHIC INTERFACES FOR MENU ITEMS *************************************\n ************************************************************************************************************** */\n export interface RootItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: 'ROOT_ITEM'; // HARDCODED BECAUSE THIS IS NOT A MENU ITEM, IT'S EXCLUSIVE TO THE ROOT NODE\n dsId: string;\n label?: undefined;\n secondaryLabel?: undefined;\n leftDecoration?: undefined;\n minWidth?: undefined;\n disabled?: undefined;\n onClick?: undefined;\n onKeyDown?: undefined;\n }\n export interface SeparatorItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['SEPARATOR'];\n dsId: string;\n label?: undefined;\n secondaryLabel?: undefined;\n leftDecoration?: undefined;\n minWidth?: undefined;\n disabled?: undefined;\n onClick?: undefined;\n onKeyDown?: undefined;\n }\n export interface ActivableItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['ACTIVABLE_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n export interface ActionableWithSubmenuItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['ACTIVABLE_WITH_SUBMENU_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n export interface SkeletonItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['SKELETON_ITEM'];\n dsId: string;\n minWidth?: string | number;\n label?: undefined;\n secondaryLabel?: undefined;\n leftDecoration?: undefined;\n disabled?: undefined;\n onClick?: undefined;\n onKeyDown?: undefined;\n }\n export interface MultipleSelectItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['MULTIPLE_SELECT_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n\n export interface MultiSelectWithSubmenuItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['MULTIPLE_SELECT_WITH_SUBMENU_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n export interface WithSubmenuItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['WITH_SUBMENU_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n export interface SingleSelectItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['SINGLE_SELECT_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n export interface SingleSelectWithSubmenuItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['SINGLE_SELECT_WITH_SUBMENU_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n\n export interface GroupItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['GROUP'];\n dsId: string;\n label?: string; // if present, add a title to the group\n leftDecoration?: React.ComponentType; // if present, a label must also be present\n minWidth?: string | number;\n }\n\n export type MenuItemInterface =\n | SeparatorItem\n | ActivableItem\n | ActionableWithSubmenuItem\n | SkeletonItem\n | MultipleSelectItem\n | MultiSelectWithSubmenuItem\n | WithSubmenuItem\n | GroupItem;\n\n export type PseudoFocusableItemInterface =\n | ActivableItem\n | ActionableWithSubmenuItem\n | SkeletonItem\n | MultipleSelectItem\n | MultiSelectWithSubmenuItem\n | WithSubmenuItem\n | SingleSelectItem\n | SingleSelectWithSubmenuItem;\n\n export type SelectionableMenuItemInterface =\n | MultipleSelectItem\n | MultiSelectWithSubmenuItem\n | SingleSelectItem\n | SingleSelectWithSubmenuItem;\n\n /* **************************************************************************************************************\n *************************** POLYMORPHIC INTERFACES FOR ITEMS USING DSTREE *************************************\n ************************************************************************************************************** */\n // Define MenuNode types directly\n export type MenuNodeRootItem = UseDSTreeT.TreeNode<RootItem>; // MenuNodesAllowedToHaveChildren is the only expected reference to this type\n export type MenuNodeSeparatorItem = UseDSTreeT.TreeNode<SeparatorItem>;\n export type MenuNodeActivableItem = UseDSTreeT.TreeNode<ActivableItem>;\n export type MenuNodeActivableWithSubmenuItem = UseDSTreeT.TreeNode<ActionableWithSubmenuItem>;\n export type MenuNodeSkeletonItem = UseDSTreeT.TreeNode<SkeletonItem>;\n export type MenuNodeMultipleSelectItem = UseDSTreeT.TreeNode<MultipleSelectItem>;\n export type MenuNodeMultipleSelectWithSubmenuItem = UseDSTreeT.TreeNode<MultiSelectWithSubmenuItem>;\n export type MenuNodeWithSubmenuItem = UseDSTreeT.TreeNode<WithSubmenuItem>;\n export type MenuNodeSingleSelectItem = UseDSTreeT.TreeNode<SingleSelectItem>;\n export type MenuNodeSingleSelectWithSubmenuItem = UseDSTreeT.TreeNode<SingleSelectWithSubmenuItem>;\n export type MenuNodeGroupItem = UseDSTreeT.TreeNode<GroupItem>;\n\n // in the future we want to better describe the polymorphic nature of the MenuNode\n // having each type be able to have it's own \"subitems\" type that isn't necessarily the same as the parent\n // but currenctly the DS tree model typescript definitions don't support this\n // will be addresssed via PUI-XXXX\n export type MenuNode =\n // DO NOT ADD MenuNodeRootItem HERE, WILL BREAK THE SUBTREES\n | MenuNodeSeparatorItem\n | MenuNodeActivableItem\n | MenuNodeActivableWithSubmenuItem\n | MenuNodeSkeletonItem\n | MenuNodeMultipleSelectItem\n | MenuNodeMultipleSelectWithSubmenuItem\n | MenuNodeWithSubmenuItem\n | MenuNodeSingleSelectItem\n | MenuNodeSingleSelectWithSubmenuItem\n | MenuNodeGroupItem;\n\n export type PseudoFocusableMenuNodes =\n | MenuNodeActivableItem\n | MenuNodeActivableWithSubmenuItem\n | MenuNodeSkeletonItem\n | MenuNodeSingleSelectItem\n | MenuNodeMultipleSelectItem\n | MenuNodeMultipleSelectWithSubmenuItem\n | MenuNodeWithSubmenuItem\n | MenuNodeSingleSelectWithSubmenuItem;\n\n export type MenuNodesAllowedToHaveChildren =\n | MenuNodeRootItem\n | MenuNodeWithSubmenuItem\n | MenuNodeGroupItem\n | MenuNodeActivableWithSubmenuItem\n | MenuNodeMultipleSelectWithSubmenuItem\n | MenuNodeSingleSelectWithSubmenuItem;\n\n export type SelectionableMenuNodes =\n | DSMenuButtonT.MenuNodeMultipleSelectItem\n | DSMenuButtonT.MenuNodeMultipleSelectWithSubmenuItem\n | DSMenuButtonT.MenuNodeSingleSelectItem\n | DSMenuButtonT.MenuNodeSingleSelectWithSubmenuItem;\n\n export type MultipleSelectionableMenuNodes =\n | DSMenuButtonT.MenuNodeMultipleSelectItem\n | DSMenuButtonT.MenuNodeMultipleSelectWithSubmenuItem;\n\n export type SingleSelectionableMenuNodes =\n | DSMenuButtonT.MenuNodeSingleSelectItem\n | DSMenuButtonT.MenuNodeSingleSelectWithSubmenuItem;\n\n export type WithSubmenuMenuNodes =\n | DSMenuButtonT.MenuNodeWithSubmenuItem\n | DSMenuButtonT.MenuNodeActivableWithSubmenuItem\n | DSMenuButtonT.MenuNodeMultipleSelectWithSubmenuItem\n | DSMenuButtonT.MenuNodeSingleSelectWithSubmenuItem;\n\n export type SelectionablesWithSubmenuMenuNodes =\n | DSMenuButtonT.MenuNodeMultipleSelectWithSubmenuItem\n | DSMenuButtonT.MenuNodeSingleSelectWithSubmenuItem;\n\n /* **************************************************************************************************************\n ********************************** PROPS/INTERNAL PROPS DEFINITIONS *******************************************\n ************************************************************************************************************** */\n\n export type ItemRendererT = React.ComponentType<{ itemNode: MenuNode }>;\n\n /* **************************************************************************************************************\n ******************************************* \"REQUIRED\" PROPS **************************************************\n ************************************************************************************************************** */\n /* *******************************************************\n * From official source definition\n *\n * Menu Button Pattern\n * About This Pattern:\n * A menu button is a button\n * that opens a menu\n * (as described in the Menu and Menubar Pattern).\n *\n * Since the menu button is a button, it inherits all the props from the Button component.\n * Since the menu button MUST have a menu, it also have a set of specific props used to handle the menu.\n * Because we build with atomic composition in mind, the \"logic layer\" is separated and has a yet another set of props.\n *\n * This is effectively an OOP \"extension\" of the Button component,\n * so it has the same props,\n * BUT also a few more to handle the specific behavior of the menu.\n ******************************************************* */\n export interface MenuBehaviouralLayerRequiredProps {}\n export interface MenuSpecificRequiredProps {}\n /* *******************************************************\n * Required Props + Inherited Required Props\n * - We inherit the required props from the button\n * - We add the required props for the menu\n *\n * - if a collision occurs, the menu specific are meant to be the most important and specific ones\n ******************************************************* */\n export interface ButtonInheritedRequiredProps\n // by using Omit, we remove the keys that are present in the MenuSpecificRequiredProps to ensure collision are handled as expected\n extends Omit<DSButtonV3T.RequiredProps, keyof MenuSpecificRequiredProps> {}\n // the final RequiredProps will be the combination of the two with proper collision handling\n export interface RequiredProps\n extends MenuSpecificRequiredProps,\n ButtonInheritedRequiredProps,\n MenuBehaviouralLayerRequiredProps {\n // it's the Menu Widget sole responsibility to receive the options and convert them to a tree\n options: MenuItemInterface[] | MenuNode;\n }\n\n /* **************************************************************************************************************\n ******************************************** \"DEFAULT\" PROPS **************************************************\n ************************************************************************************************************** */\n /* *******************************************************\n * Since the menu button is a button, it inherits all the props from the Button component.\n * Since the menu button MUST have a menu, it also have a set of specific props used to handle the menu.\n * Because we build with atomic composition in mind, the \"logic layer\" is separated and has a yet another set of props.\n ******************************************************* */\n export interface MenuBehaviouralLayerDefaultProps {}\n export interface MenuSpecifiDefaultProps {\n onClickOutside: (e: MouseEvent | React.KeyboardEvent | TouchEvent) => void;\n onOptionClick: (\n nextSelectedOptions: Record<string, boolean>,\n clickedOption: MenuItemInterface,\n e: React.MouseEvent | React.KeyboardEvent,\n ) => void;\n openedSubmenus: Record<string, boolean>;\n onSubmenuToggle: (\n nextOpenedSubmenus: Record<string, boolean>,\n submenu: MenuItemInterface,\n e: React.MouseEvent | React.KeyboardEvent,\n ) => void;\n isLoading: boolean;\n isSkeleton: boolean;\n }\n\n /* *******************************************************\n * Default Props + Inherited Default Props\n * - We inherit the default props from the button\n * - We add the default props for the menu\n *\n * - if a collision occurs, the menu specific are meant to be the most important and specific ones\n ******************************************************* */\n // by using Omit, we remove the keys that are present in the MenuSpecificDefaultProps to ensure collision are handled as expected\n export interface ButtonInheiredDefaultProps extends Omit<DSButtonV3T.DefaultProps, keyof MenuSpecifiDefaultProps> {}\n // the final DefaultProps will be the combination of the two with proper collision handling\n export interface DefaultProps\n extends MenuSpecifiDefaultProps,\n ButtonInheiredDefaultProps,\n MenuBehaviouralLayerDefaultProps {}\n\n /* **************************************************************************************************************\n ******************************************* \"OPTIONAL\" PROPS **************************************************\n ************************************************************************************************************** */\n /* *******************************************************\n * Since the menu button is a button, it inherits all the props from the Button component.\n * Since the menu button MUST have a menu, it also have a set of specific props used to handle the menu.\n * Because we build with atomic composition in mind, the \"logic layer\" is separated and has a yet another set of props.\n ******************************************************* */\n export interface MenuBehaviouralLayerOptionalProps {\n // **********************************************************************************************\n // IoC Pattern\n // - in scenarios where not \"selectionable\" items are present,\n // - the \"selectedItems\" prop is not required\n // - the \"onItemSelected\" prop is not required\n // - in scenarios where no \"activation\" items are present,\n // - the \"onActivateItem\" prop is not required\n // AFAIK Typescipt doesn't support this kind of \"conditional\" required props\n // so we will rely on javascript error throwing to handle this + documentation\n // **********************************************************************************************\n onItemSelected?: (\n newSelection: SelectionableMenuNodes[],\n metainfo: { itemNode: DSMenuButtonT.SelectionableMenuNodes; event?: React.SyntheticEvent },\n ) => void | TypescriptHelpersT.StateSetter<DSMenuButtonT.SelectionableMenuNodes[]>;\n onActivateItem?: (\n itemNode: DSMenuButtonT.PseudoFocusableMenuNodes,\n metainfo: { itemNode: DSMenuButtonT.PseudoFocusableMenuNodes; event?: React.SyntheticEvent },\n ) => void;\n // **********************************************************************************************\n onOpen?: () => void;\n onClose?: () => void;\n onDisplayedSubmenuChange?: (\n newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[],\n metainfo: {\n itemNode: DSMenuButtonT.PseudoFocusableMenuNodes | null;\n event?: React.SyntheticEvent | FocusEvent | TouchEvent;\n },\n ) => void | TypescriptHelpersT.StateSetter<DSMenuButtonT.WithSubmenuMenuNodes[]>;\n }\n export interface MenuSpecificOptionalProps {\n ItemRenderer?: ItemRendererT;\n }\n /* *******************************************************\n * Optional Props + Inherited Optional Props\n * - We inherit the optional props from the button\n * - We add the optional props for the menu\n *\n * - if a collision occurs, the menu specific are meant to be the most important and specific ones\n ******************************************************* */\n export interface ButtonInheritedOptionalProps\n // by using Omit, we remove the keys that are present in the MenuSpecificOptionalProps to ensure collision are handled as expected\n extends Omit<DSButtonV3T.OptionalProps, keyof MenuSpecificOptionalProps> {}\n export interface OptionalProps\n extends MenuSpecificOptionalProps,\n ButtonInheritedOptionalProps,\n // we convert the (selected) options to a Nodes as part of the widget's logic\n MenuBehaviouralLayerOptionalProps,\n TypescriptHelpersT.PropsForGlobalOnSlots<typeof DSMenuButtonName, typeof MENU_BUTTON_SLOTS> {\n // we convert the (selected) options to a Nodes as part of the widget's logic\n selectedItems?: SelectionableMenuNodes[] | SelectionableMenuItemInterface[];\n }\n\n /* **************************************************************************************************************\n ************************************************ PROPS *******************************************************\n ************************************************************************************************************** */\n /* *******************************************************\n * Since the menu button is a button, it inherits all the props from the Button component.\n * Since the menu button MUST have a menu, it also have a set of specific props used to handle the menu.\n * Because we build with atomic composition in mind, the \"logic layer\" is separated and has a yet another set of props.\n ******************************************************* */\n export interface MenuBehaviouralLayerProps\n extends Partial<MenuBehaviouralLayerDefaultProps>,\n MenuBehaviouralLayerOptionalProps,\n MenuBehaviouralLayerRequiredProps {}\n export interface MenuSpecificProps\n extends Partial<MenuSpecifiDefaultProps>,\n MenuSpecificOptionalProps,\n MenuSpecificRequiredProps {}\n /* *******************************************************\n * Props + Inherited Props\n * - We inherit the props from the button\n * - We add the props for the menu\n *\n * - if a collision occurs, the menu specific are meant to be the most important and specific ones\n ******************************************************* */\n // by using Omit, we remove the keys that are present in the MenuSpecificProps to ensure collision are handled as expected\n // THIS IS ALSO INHERITING THE GLOBAL ATTRIBUTES & XSTYLED PROPS FROM THE BUTTON!!!\n export interface ButtonInheritedProps extends Omit<DSButtonV3T.Props, keyof MenuSpecificProps> {}\n\n export interface Props\n extends RequiredProps,\n Partial<DefaultProps>,\n OptionalProps,\n // the global and xstyled props are only part of \"props\"/\"internalProps\" in our namespaces\n // to properly inherith button's global & xstyled props, we need to also include the following\n Omit<DSButtonV3T.Props, keyof RequiredProps | keyof DefaultProps | keyof OptionalProps> {}\n\n /* **************************************************************************************************************\n ******************************************** INTERNAL PROPS ***************************************************\n ************************************************************************************************************** */\n /* *******************************************************\n * Since the menu button is a button, it inherits all the props from the Button component.\n * Since the menu button MUST have a menu, it also have a set of specific props used to handle the menu.\n * Because we build with atomic composition in mind, the \"logic layer\" is separated and has a yet another set of props.\n ******************************************************* */\n export interface MenuBehaviouralLayerInternalProps\n extends MenuBehaviouralLayerDefaultProps,\n MenuBehaviouralLayerOptionalProps,\n MenuBehaviouralLayerRequiredProps {}\n export interface MenuSpecificInternalProps\n extends MenuSpecifiDefaultProps,\n MenuSpecificOptionalProps,\n MenuSpecificRequiredProps {}\n\n /* *******************************************************\n * Internal Props\n * - We inherit the internal props from the button\n * - We add the internal props for the menu\n *\n * - if a collision occurs, the menu specific are meant to be the most important and specific ones\n ******************************************************* */\n export interface ButtonInheritedInternalProps\n // by using Omit, we remove the keys that are present in the MenuSpecificInternalProps to ensure collision are handled as expected\n // THIS IS ALSO INHERITING THE GLOBAL ATTRIBUTES & XSTYLED PROPS FROM THE BUTTON!!!\n extends Omit<DSButtonV3T.InternalProps, keyof MenuSpecificInternalProps> {}\n export interface InternalProps\n extends RequiredProps,\n DefaultProps,\n OptionalProps,\n // the global and xstyled props are only part of \"props\"/\"internalProps\" in our namespaces\n // to properly inherith button's global & xstyled props, we need to also include the following\n Omit<DSButtonV3T.Props, keyof RequiredProps | keyof DefaultProps | keyof OptionalProps> {}\n}\n\nexport const defaultProps: DSMenuButtonT.MenuSpecifiDefaultProps = {\n onClickOutside: () => null,\n onOptionClick: () => null,\n openedSubmenus: {},\n onSubmenuToggle: () => null,\n isLoading: false,\n isSkeleton: false,\n};\n/* *******************************************************\n * We are building a widget composed of 3 ATOMIC composition components\n * - Button\n * - Menu\n * - Behavioural Layer\n * The final API facing the users is a sum of all 3 interfaces\n * THOSE INTERFACES ARE NOT EQUAL TO THE FINAL \"PARTS\" INTERFACES\n * The widget embeds \"assumptions\" (as all widgets do) that are AGNOSTIC to the \"parts\" interfaces\n * The \"Parts\" interfaces \"mostly\" inherit the following interfaces, but with meaningful meant and planned differences\n * (E.G. the widget accepts an array of options, but the Menu part accepts a DSTree only)\n ******************************************************* */\nexport const MenuBehaviouralLayerPropTypes: DSPropTypesSchema<DSMenuButtonT.MenuBehaviouralLayerProps> = {\n onItemSelected: PropTypes.func.description(\n 'IoC function in charge of handling the selection of a menu item, required if the menu has selectionable items',\n ).signature(`((\n newSelection: DSMenuButtonT.PseudoFocusableMenuNodes[],\n metainfo: { itemNode: DSMenuButtonT.PseudoFocusableMenuNodes; event?: React.SyntheticEvent },\n ) => void)`),\n\n onActivateItem: PropTypes.func.description(\n 'IoC function in charge of handling the activation (NOT INVOKED ON SELECTION) of a menu item, required if the menu has activable items',\n ).signature(`((\n itemNode: DSMenuButtonT.PseudoFocusableMenuNodes,\n metainfo: { itemNode: DSMenuButtonT.PseudoFocusableMenuNodes; event?: React.SyntheticEvent },\n ) => void)`),\n\n onOpen: PropTypes.func.description('function triggered when the widget opens the menu').signature(`(()=>void)`),\n onClose: PropTypes.func.description('function triggered when the widget closes the menu').signature(`(()=>void)`),\n onDisplayedSubmenuChange: PropTypes.func.description(\"function triggered when the widget's closes or opens a submenu\")\n .signature(`((\n newOpenedItems: DSMenuButtonT.PseudoFocusableMenuNodes[],\n metainfo: { itemNode: DSMenuButtonT.PseudoFocusableMenuNodes; event?: React.SyntheticEvent },\n ) => void)`),\n};\n\nexport const DSMenuSpecificPropTypes: DSPropTypesSchema<DSMenuButtonT.MenuSpecificProps> = {\n ItemRenderer: PropTypes.node.description('Component to be used to render the items'),\n onClickOutside: PropTypes.func\n .description('Callback executed when you click outside the dropdown menu, or press the Esc key')\n .defaultValue(() => null),\n onOptionClick: PropTypes.func\n .description(\n 'Callback triggered when an item is clicked or pressed. We provide the next selected options, the clicked option and the event, in that order',\n )\n .defaultValue(() => null),\n openedSubmenus: PropTypes.object\n .description(\n 'Object with the ids of the submenus as keys, and booleans as keys. Represents the state of the current opened submenus',\n )\n .defaultValue({}),\n onSubmenuToggle: PropTypes.func\n .description('Callback triggered when a submenu is opened or closed.')\n .signature(\n '((nextOpenedSubmenus: Record<string, boolean>, submenu: Item, e: React.MouseEvent | React.KeyboardEvent) => void)',\n )\n .defaultValue(() => null),\n isLoading: PropTypes.bool\n .description('Whether the flyout menu should render the loading indicator')\n .defaultValue(false),\n isSkeleton: PropTypes.bool.description('Whether the flyout menu should render the skeleton').defaultValue(false),\n};\n\nexport const DSMenuButtonPropTypes: DSPropTypesSchema<DSMenuButtonT.Props> = {\n options: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).description(\n 'Array of options to display in the menu or a DSTree node to build branches from',\n ).isRequired,\n selectedItems: PropTypes.arrayOf(PropTypes.object).description(\n 'an array of tree-nodes or tree-items that have to be marked as selected in the GUI, required if the menu has selectionable items',\n ),\n ...DSButtonV3PropTypes,\n ...MenuBehaviouralLayerPropTypes,\n ...DSMenuSpecificPropTypes,\n ...getPropsPerSlotPropTypes(DSMenuButtonName, MENU_BUTTON_SLOTS),\n};\n\nexport const DSMenuButtonPropTypesSchema = DSMenuButtonPropTypes as unknown as ValidationMap<DSMenuButtonT.Props>;\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACEvB,SAAS,WAAW,gCAAgC;AACpD,SAAS,2BAA2B;AAMpC,SAAS,kBAAkB,yBAAgD;AAgdpE,MAAM,eAAsD;AAAA,EACjE,gBAAgB,MAAM;AAAA,EACtB,eAAe,MAAM;AAAA,EACrB,gBAAgB,CAAC;AAAA,EACjB,iBAAiB,MAAM;AAAA,EACvB,WAAW;AAAA,EACX,YAAY;AACd;AAYO,MAAM,gCAA4F;AAAA,EACvG,gBAAgB,UAAU,KAAK;AAAA,IAC7B;AAAA,EACF,EAAE,UAAU;AAAA;AAAA;AAAA,eAGC;AAAA,EAEb,gBAAgB,UAAU,KAAK;AAAA,IAC7B;AAAA,EACF,EAAE,UAAU;AAAA;AAAA;AAAA,eAGC;AAAA,EAEb,QAAQ,UAAU,KAAK,YAAY,mDAAmD,EAAE,UAAU,YAAY;AAAA,EAC9G,SAAS,UAAU,KAAK,YAAY,oDAAoD,EAAE,UAAU,YAAY;AAAA,EAChH,0BAA0B,UAAU,KAAK,YAAY,gEAAgE,EAClH,UAAU;AAAA;AAAA;AAAA,eAGA;AACf;AAEO,MAAM,0BAA8E;AAAA,EACzF,cAAc,UAAU,KAAK,YAAY,0CAA0C;AAAA,EACnF,gBAAgB,UAAU,KACvB,YAAY,kFAAkF,EAC9F,aAAa,MAAM,IAAI;AAAA,EAC1B,eAAe,UAAU,KACtB;AAAA,IACC;AAAA,EACF,EACC,aAAa,MAAM,IAAI;AAAA,EAC1B,gBAAgB,UAAU,OACvB;AAAA,IACC;AAAA,EACF,EACC,aAAa,CAAC,CAAC;AAAA,EAClB,iBAAiB,UAAU,KACxB,YAAY,wDAAwD,EACpE;AAAA,IACC;AAAA,EACF,EACC,aAAa,MAAM,IAAI;AAAA,EAC1B,WAAW,UAAU,KAClB,YAAY,6DAA6D,EACzE,aAAa,KAAK;AAAA,EACrB,YAAY,UAAU,KAAK,YAAY,oDAAoD,EAAE,aAAa,KAAK;AACjH;AAEO,MAAM,wBAAgE;AAAA,EAC3E,SAAS,UAAU,UAAU,CAAC,UAAU,OAAO,UAAU,MAAM,CAAC,EAAE;AAAA,IAChE;AAAA,EACF,EAAE;AAAA,EACF,eAAe,UAAU,QAAQ,UAAU,MAAM,EAAE;AAAA,IACjD;AAAA,EACF;AAAA,EACA,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG,yBAAyB,kBAAkB,iBAAiB;AACjE;AAEO,MAAM,8BAA8B;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/no-empty-interface */\nimport { PropTypes, getPropsPerSlotPropTypes } from '@elliemae/ds-props-helpers';\nimport { DSButtonV3PropTypes } from '@elliemae/ds-button-v2';\nimport type { DSPropTypesSchema, ValidationMap } from '@elliemae/ds-props-helpers';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type { DSButtonV3T } from '@elliemae/ds-button-v2';\nimport type { UseDSTreeT } from '@elliemae/ds-tree-model';\n\nimport { DSMenuButtonName, MENU_BUTTON_SLOTS, type MENU_ITEMS_TYPES } from './constants/index.js';\nexport declare namespace DSMenuButtonT {\n /* *******************************************************\n * YURI's NOTE:\n *\n * This polymorphic interface \"looks similar\" between the diffent types\n * but it's actually different upon closer inspection\n *\n * If you are smarter then me, you can probably find a way to make this more DRY\n * but I prefeer AHA (Avoid Hasty Abstractions) that gives me an easier to mantain code\n * ESPECIALLY when the types are so similar but not the same & in typescript (polymorphism is hard in TS)\n *\n * So I'm going to keep them separate and explicit\n * key difference is what's required to exist and what is required to explicitly NOT exist\n *\n * If someone's review this and make this DRY, I'm NOT going to mantain this code moving forward\n * whoever makes this TS DRY will be responsible for it and own it.\n ******************************************************* */\n\n /* **************************************************************************************************************\n *********************************** POLYMORPHIC INTERFACES FOR MENU ITEMS *************************************\n ************************************************************************************************************** */\n export interface RootItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: 'ROOT_ITEM'; // HARDCODED BECAUSE THIS IS NOT A MENU ITEM, IT'S EXCLUSIVE TO THE ROOT NODE\n dsId: string;\n maxHeight?: string | number; // was available in dropdownmenu-v2, have to provide for retrocompatibility\n label?: undefined;\n secondaryLabel?: undefined;\n leftDecoration?: undefined;\n minWidth?: undefined;\n disabled?: undefined;\n onClick?: undefined;\n onKeyDown?: undefined;\n }\n export interface SeparatorItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['SEPARATOR'];\n dsId: string;\n label?: undefined;\n secondaryLabel?: undefined;\n leftDecoration?: undefined;\n minWidth?: undefined;\n disabled?: undefined;\n onClick?: undefined;\n onKeyDown?: undefined;\n }\n export interface ActivableItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['ACTIVABLE_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n export interface ActionableWithSubmenuItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['ACTIVABLE_WITH_SUBMENU_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n maxHeight?: string | number; // was available in dropdownmenu-v2, have to provide for retrocompatibility\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n export interface SkeletonItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['SKELETON_ITEM'];\n dsId: string;\n minWidth?: string | number;\n label?: undefined;\n secondaryLabel?: undefined;\n leftDecoration?: undefined;\n disabled?: undefined;\n onClick?: undefined;\n onKeyDown?: undefined;\n }\n export interface MultipleSelectItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['MULTIPLE_SELECT_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n\n export interface MultiSelectWithSubmenuItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['MULTIPLE_SELECT_WITH_SUBMENU_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n maxHeight?: string | number; // was available in dropdownmenu-v2, have to provide for retrocompatibility\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n export interface WithSubmenuItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['WITH_SUBMENU_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n maxHeight?: string | number; // was available in dropdownmenu-v2, have to provide for retrocompatibility\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n export interface SingleSelectItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['SINGLE_SELECT_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n export interface SingleSelectWithSubmenuItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['SINGLE_SELECT_WITH_SUBMENU_ITEM'];\n dsId: string;\n label: string;\n secondaryLabel?: string;\n leftDecoration?: React.ComponentType;\n minWidth?: string | number;\n maxHeight: string | number; // was available in dropdownmenu-v2, have to provide for retrocompatibility\n disabled?: boolean;\n onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;\n onKeyDown?: (e: React.KeyboardEvent) => null;\n }\n\n export interface GroupItem extends UseDSTreeT.AnyObjectWithoutReservedKeys {\n type: (typeof MENU_ITEMS_TYPES)['GROUP'];\n dsId: string;\n label?: string; // if present, add a title to the group\n leftDecoration?: React.ComponentType; // if present, a label must also be present\n minWidth?: string | number;\n }\n\n export type MenuItemInterface =\n | SeparatorItem\n | ActivableItem\n | ActionableWithSubmenuItem\n | SkeletonItem\n | MultipleSelectItem\n | MultiSelectWithSubmenuItem\n | WithSubmenuItem\n | GroupItem\n | SingleSelectItem\n | SingleSelectWithSubmenuItem;\n\n export type PseudoFocusableItemInterface =\n | ActivableItem\n | ActionableWithSubmenuItem\n | SkeletonItem\n | MultipleSelectItem\n | MultiSelectWithSubmenuItem\n | WithSubmenuItem\n | SingleSelectItem\n | SingleSelectWithSubmenuItem;\n\n export type SelectionableMenuItemInterface =\n | MultipleSelectItem\n | MultiSelectWithSubmenuItem\n | SingleSelectItem\n | SingleSelectWithSubmenuItem;\n\n /* **************************************************************************************************************\n *************************** POLYMORPHIC INTERFACES FOR ITEMS USING DSTREE *************************************\n ************************************************************************************************************** */\n // Define MenuNode types directly\n export type MenuNodeRootItem = UseDSTreeT.TreeNode<RootItem>; // MenuNodesAllowedToHaveChildren is the only expected reference to this type\n export type MenuNodeSeparatorItem = UseDSTreeT.TreeNode<SeparatorItem>;\n export type MenuNodeActivableItem = UseDSTreeT.TreeNode<ActivableItem>;\n export type MenuNodeActivableWithSubmenuItem = UseDSTreeT.TreeNode<ActionableWithSubmenuItem>;\n export type MenuNodeSkeletonItem = UseDSTreeT.TreeNode<SkeletonItem>;\n export type MenuNodeMultipleSelectItem = UseDSTreeT.TreeNode<MultipleSelectItem>;\n export type MenuNodeMultipleSelectWithSubmenuItem = UseDSTreeT.TreeNode<MultiSelectWithSubmenuItem>;\n export type MenuNodeWithSubmenuItem = UseDSTreeT.TreeNode<WithSubmenuItem>;\n export type MenuNodeSingleSelectItem = UseDSTreeT.TreeNode<SingleSelectItem>;\n export type MenuNodeSingleSelectWithSubmenuItem = UseDSTreeT.TreeNode<SingleSelectWithSubmenuItem>;\n export type MenuNodeGroupItem = UseDSTreeT.TreeNode<GroupItem>;\n\n // in the future we want to better describe the polymorphic nature of the MenuNode\n // having each type be able to have it's own \"subitems\" type that isn't necessarily the same as the parent\n // but currenctly the DS tree model typescript definitions don't support this\n // will be addresssed via PUI-XXXX\n export type MenuNode =\n // DO NOT ADD MenuNodeRootItem HERE, WILL BREAK THE SUBTREES\n | MenuNodeSeparatorItem\n | MenuNodeActivableItem\n | MenuNodeActivableWithSubmenuItem\n | MenuNodeSkeletonItem\n | MenuNodeMultipleSelectItem\n | MenuNodeMultipleSelectWithSubmenuItem\n | MenuNodeWithSubmenuItem\n | MenuNodeSingleSelectItem\n | MenuNodeSingleSelectWithSubmenuItem\n | MenuNodeGroupItem;\n\n export type PseudoFocusableMenuNodes =\n | MenuNodeActivableItem\n | MenuNodeActivableWithSubmenuItem\n | MenuNodeSkeletonItem\n | MenuNodeSingleSelectItem\n | MenuNodeMultipleSelectItem\n | MenuNodeMultipleSelectWithSubmenuItem\n | MenuNodeWithSubmenuItem\n | MenuNodeSingleSelectWithSubmenuItem;\n\n export type MenuNodesAllowedToHaveChildren =\n | MenuNodeRootItem\n | MenuNodeWithSubmenuItem\n | MenuNodeGroupItem\n | MenuNodeActivableWithSubmenuItem\n | MenuNodeMultipleSelectWithSubmenuItem\n | MenuNodeSingleSelectWithSubmenuItem;\n\n export type SelectionableMenuNodes =\n | DSMenuButtonT.MenuNodeMultipleSelectItem\n | DSMenuButtonT.MenuNodeMultipleSelectWithSubmenuItem\n | DSMenuButtonT.MenuNodeSingleSelectItem\n | DSMenuButtonT.MenuNodeSingleSelectWithSubmenuItem;\n\n export type MultipleSelectionableMenuNodes =\n | DSMenuButtonT.MenuNodeMultipleSelectItem\n | DSMenuButtonT.MenuNodeMultipleSelectWithSubmenuItem;\n\n export type SingleSelectionableMenuNodes =\n | DSMenuButtonT.MenuNodeSingleSelectItem\n | DSMenuButtonT.MenuNodeSingleSelectWithSubmenuItem;\n\n export type WithSubmenuMenuNodes =\n | DSMenuButtonT.MenuNodeWithSubmenuItem\n | DSMenuButtonT.MenuNodeActivableWithSubmenuItem\n | DSMenuButtonT.MenuNodeMultipleSelectWithSubmenuItem\n | DSMenuButtonT.MenuNodeSingleSelectWithSubmenuItem;\n\n export type SelectionablesWithSubmenuMenuNodes =\n | DSMenuButtonT.MenuNodeMultipleSelectWithSubmenuItem\n | DSMenuButtonT.MenuNodeSingleSelectWithSubmenuItem;\n\n /* **************************************************************************************************************\n ********************************** PROPS/INTERNAL PROPS DEFINITIONS *******************************************\n ************************************************************************************************************** */\n\n export type ItemRendererT = React.ComponentType<{ itemNode: MenuNode }>;\n\n /* **************************************************************************************************************\n ******************************************* \"REQUIRED\" PROPS **************************************************\n ************************************************************************************************************** */\n /* *******************************************************\n * From official source definition\n *\n * Menu Button Pattern\n * About This Pattern:\n * A menu button is a button\n * that opens a menu\n * (as described in the Menu and Menubar Pattern).\n *\n * Since the menu button is a button, it inherits all the props from the Button component.\n * Since the menu button MUST have a menu, it also have a set of specific props used to handle the menu.\n * Because we build with atomic composition in mind, the \"logic layer\" is separated and has a yet another set of props.\n *\n * This is effectively an OOP \"extension\" of the Button component,\n * so it has the same props,\n * BUT also a few more to handle the specific behavior of the menu.\n ******************************************************* */\n export interface MenuBehaviouralLayerRequiredProps {}\n export interface MenuSpecificRequiredProps {}\n /* *******************************************************\n * Required Props + Inherited Required Props\n * - We inherit the required props from the button\n * - We add the required props for the menu\n *\n * - if a collision occurs, the menu specific are meant to be the most important and specific ones\n ******************************************************* */\n export interface ButtonInheritedRequiredProps\n // by using Omit, we remove the keys that are present in the MenuSpecificRequiredProps to ensure collision are handled as expected\n extends Omit<DSButtonV3T.RequiredProps, keyof MenuSpecificRequiredProps> {}\n // the final RequiredProps will be the combination of the two with proper collision handling\n export interface RequiredProps\n extends MenuSpecificRequiredProps,\n ButtonInheritedRequiredProps,\n MenuBehaviouralLayerRequiredProps {\n // it's the Menu Widget sole responsibility to receive the options and convert them to a tree\n options: MenuItemInterface[] | MenuNode;\n }\n\n /* **************************************************************************************************************\n ******************************************** \"DEFAULT\" PROPS **************************************************\n ************************************************************************************************************** */\n /* *******************************************************\n * Since the menu button is a button, it inherits all the props from the Button component.\n * Since the menu button MUST have a menu, it also have a set of specific props used to handle the menu.\n * Because we build with atomic composition in mind, the \"logic layer\" is separated and has a yet another set of props.\n ******************************************************* */\n export interface MenuBehaviouralLayerDefaultProps {}\n export interface MenuSpecifiDefaultProps {\n onClickOutside: (e: MouseEvent | React.KeyboardEvent | TouchEvent) => void;\n onOptionClick: (\n nextSelectedOptions: Record<string, boolean>,\n clickedOption: MenuItemInterface,\n e: React.MouseEvent | React.KeyboardEvent,\n ) => void;\n openedSubmenus: Record<string, boolean>;\n onSubmenuToggle: (\n nextOpenedSubmenus: Record<string, boolean>,\n submenu: MenuItemInterface,\n e: React.MouseEvent | React.KeyboardEvent,\n ) => void;\n isLoading: boolean;\n isSkeleton: boolean;\n maxHeight: string | number; // was available in dropdownmenu-v2, have to provide for retrocompatibility\n }\n\n /* *******************************************************\n * Default Props + Inherited Default Props\n * - We inherit the default props from the button\n * - We add the default props for the menu\n *\n * - if a collision occurs, the menu specific are meant to be the most important and specific ones\n ******************************************************* */\n // by using Omit, we remove the keys that are present in the MenuSpecificDefaultProps to ensure collision are handled as expected\n export interface ButtonInheiredDefaultProps extends Omit<DSButtonV3T.DefaultProps, keyof MenuSpecifiDefaultProps> {}\n // the final DefaultProps will be the combination of the two with proper collision handling\n export interface DefaultProps\n extends MenuSpecifiDefaultProps,\n ButtonInheiredDefaultProps,\n MenuBehaviouralLayerDefaultProps {}\n\n /* **************************************************************************************************************\n ******************************************* \"OPTIONAL\" PROPS **************************************************\n ************************************************************************************************************** */\n /* *******************************************************\n * Since the menu button is a button, it inherits all the props from the Button component.\n * Since the menu button MUST have a menu, it also have a set of specific props used to handle the menu.\n * Because we build with atomic composition in mind, the \"logic layer\" is separated and has a yet another set of props.\n ******************************************************* */\n export interface MenuBehaviouralLayerOptionalProps {\n // **********************************************************************************************\n // IoC Pattern\n // - in scenarios where not \"selectionable\" items are present,\n // - the \"selectedItems\" prop is not required\n // - the \"onItemSelected\" prop is not required\n // - in scenarios where no \"activation\" items are present,\n // - the \"onActivateItem\" prop is not required\n // AFAIK Typescipt doesn't support this kind of \"conditional\" required props\n // so we will rely on javascript error throwing to handle this + documentation\n // **********************************************************************************************\n onItemSelected?: (\n newSelection: SelectionableMenuNodes[],\n metainfo: { itemNode: DSMenuButtonT.SelectionableMenuNodes; event?: React.SyntheticEvent },\n ) => void | TypescriptHelpersT.StateSetter<DSMenuButtonT.SelectionableMenuNodes[]>;\n onActivateItem?: (\n itemNode: DSMenuButtonT.PseudoFocusableMenuNodes,\n metainfo: { itemNode: DSMenuButtonT.PseudoFocusableMenuNodes; event?: React.SyntheticEvent },\n ) => void;\n // **********************************************************************************************\n onOpen?: () => void;\n onClose?: () => void;\n onDisplayedSubmenuChange?: (\n newOpenedItems: DSMenuButtonT.WithSubmenuMenuNodes[],\n metainfo: {\n itemNode: DSMenuButtonT.PseudoFocusableMenuNodes | null;\n event?: React.SyntheticEvent | FocusEvent | TouchEvent;\n },\n ) => void | TypescriptHelpersT.StateSetter<DSMenuButtonT.WithSubmenuMenuNodes[]>;\n }\n export interface MenuSpecificOptionalProps {\n ItemRenderer?: ItemRendererT;\n }\n /* *******************************************************\n * Optional Props + Inherited Optional Props\n * - We inherit the optional props from the button\n * - We add the optional props for the menu\n *\n * - if a collision occurs, the menu specific are meant to be the most important and specific ones\n ******************************************************* */\n export interface ButtonInheritedOptionalProps\n // by using Omit, we remove the keys that are present in the MenuSpecificOptionalProps to ensure collision are handled as expected\n extends Omit<DSButtonV3T.OptionalProps, keyof MenuSpecificOptionalProps> {}\n export interface OptionalProps\n extends MenuSpecificOptionalProps,\n ButtonInheritedOptionalProps,\n // we convert the (selected) options to a Nodes as part of the widget's logic\n MenuBehaviouralLayerOptionalProps,\n TypescriptHelpersT.PropsForGlobalOnSlots<typeof DSMenuButtonName, typeof MENU_BUTTON_SLOTS> {\n // we convert the (selected) options to a Nodes as part of the widget's logic\n selectedItems?: SelectionableMenuNodes[] | SelectionableMenuItemInterface[];\n }\n\n /* **************************************************************************************************************\n ************************************************ PROPS *******************************************************\n ************************************************************************************************************** */\n /* *******************************************************\n * Since the menu button is a button, it inherits all the props from the Button component.\n * Since the menu button MUST have a menu, it also have a set of specific props used to handle the menu.\n * Because we build with atomic composition in mind, the \"logic layer\" is separated and has a yet another set of props.\n ******************************************************* */\n export interface MenuBehaviouralLayerProps\n extends Partial<MenuBehaviouralLayerDefaultProps>,\n MenuBehaviouralLayerOptionalProps,\n MenuBehaviouralLayerRequiredProps {}\n export interface MenuSpecificProps\n extends Partial<MenuSpecifiDefaultProps>,\n MenuSpecificOptionalProps,\n MenuSpecificRequiredProps {}\n /* *******************************************************\n * Props + Inherited Props\n * - We inherit the props from the button\n * - We add the props for the menu\n *\n * - if a collision occurs, the menu specific are meant to be the most important and specific ones\n ******************************************************* */\n // by using Omit, we remove the keys that are present in the MenuSpecificProps to ensure collision are handled as expected\n // THIS IS ALSO INHERITING THE GLOBAL ATTRIBUTES & XSTYLED PROPS FROM THE BUTTON!!!\n export interface ButtonInheritedProps extends Omit<DSButtonV3T.Props, keyof MenuSpecificProps> {}\n\n export interface Props\n extends RequiredProps,\n Partial<DefaultProps>,\n OptionalProps,\n // the global and xstyled props are only part of \"props\"/\"internalProps\" in our namespaces\n // to properly inherith button's global & xstyled props, we need to also include the following\n Omit<DSButtonV3T.Props, keyof RequiredProps | keyof DefaultProps | keyof OptionalProps> {}\n\n /* **************************************************************************************************************\n ******************************************** INTERNAL PROPS ***************************************************\n ************************************************************************************************************** */\n /* *******************************************************\n * Since the menu button is a button, it inherits all the props from the Button component.\n * Since the menu button MUST have a menu, it also have a set of specific props used to handle the menu.\n * Because we build with atomic composition in mind, the \"logic layer\" is separated and has a yet another set of props.\n ******************************************************* */\n export interface MenuBehaviouralLayerInternalProps\n extends MenuBehaviouralLayerDefaultProps,\n MenuBehaviouralLayerOptionalProps,\n MenuBehaviouralLayerRequiredProps {}\n export interface MenuSpecificInternalProps\n extends MenuSpecifiDefaultProps,\n MenuSpecificOptionalProps,\n MenuSpecificRequiredProps {}\n\n /* *******************************************************\n * Internal Props\n * - We inherit the internal props from the button\n * - We add the internal props for the menu\n *\n * - if a collision occurs, the menu specific are meant to be the most important and specific ones\n ******************************************************* */\n export interface ButtonInheritedInternalProps\n // by using Omit, we remove the keys that are present in the MenuSpecificInternalProps to ensure collision are handled as expected\n // THIS IS ALSO INHERITING THE GLOBAL ATTRIBUTES & XSTYLED PROPS FROM THE BUTTON!!!\n extends Omit<DSButtonV3T.InternalProps, keyof MenuSpecificInternalProps> {}\n export interface InternalProps\n extends RequiredProps,\n DefaultProps,\n OptionalProps,\n // the global and xstyled props are only part of \"props\"/\"internalProps\" in our namespaces\n // to properly inherith button's global & xstyled props, we need to also include the following\n Omit<DSButtonV3T.Props, keyof RequiredProps | keyof DefaultProps | keyof OptionalProps> {}\n}\n\nexport const menuSpecificDefaultProps: DSMenuButtonT.MenuSpecifiDefaultProps = {\n onClickOutside: () => null,\n onOptionClick: () => null,\n openedSubmenus: {},\n onSubmenuToggle: () => null,\n isLoading: false,\n isSkeleton: false,\n maxHeight: '256px', // was available in dropdownmenu-v2, have to provide for retrocompatibility\n};\n/* *******************************************************\n * We are building a widget composed of 3 ATOMIC composition components\n * - Button\n * - Menu\n * - Behavioural Layer\n * The final API facing the users is a sum of all 3 interfaces\n * THOSE INTERFACES ARE NOT EQUAL TO THE FINAL \"PARTS\" INTERFACES\n * The widget embeds \"assumptions\" (as all widgets do) that are AGNOSTIC to the \"parts\" interfaces\n * The \"Parts\" interfaces \"mostly\" inherit the following interfaces, but with meaningful meant and planned differences\n * (E.G. the widget accepts an array of options, but the Menu part accepts a DSTree only)\n ******************************************************* */\nexport const MenuBehaviouralLayerPropTypes: DSPropTypesSchema<DSMenuButtonT.MenuBehaviouralLayerProps> = {\n onItemSelected: PropTypes.func.description(\n 'IoC function in charge of handling the selection of a menu item, required if the menu has selectionable items',\n ).signature(`((\n newSelection: DSMenuButtonT.PseudoFocusableMenuNodes[],\n metainfo: { itemNode: DSMenuButtonT.PseudoFocusableMenuNodes; event?: React.SyntheticEvent },\n ) => void)`),\n\n onActivateItem: PropTypes.func.description(\n 'IoC function in charge of handling the activation (NOT INVOKED ON SELECTION) of a menu item, required if the menu has activable items',\n ).signature(`((\n itemNode: DSMenuButtonT.PseudoFocusableMenuNodes,\n metainfo: { itemNode: DSMenuButtonT.PseudoFocusableMenuNodes; event?: React.SyntheticEvent },\n ) => void)`),\n\n onOpen: PropTypes.func.description('function triggered when the widget opens the menu').signature(`(()=>void)`),\n onClose: PropTypes.func.description('function triggered when the widget closes the menu').signature(`(()=>void)`),\n onDisplayedSubmenuChange: PropTypes.func.description(\"function triggered when the widget's closes or opens a submenu\")\n .signature(`((\n newOpenedItems: DSMenuButtonT.PseudoFocusableMenuNodes[],\n metainfo: { itemNode: DSMenuButtonT.PseudoFocusableMenuNodes; event?: React.SyntheticEvent },\n ) => void)`),\n};\n\nexport const DSMenuSpecificPropTypes: DSPropTypesSchema<DSMenuButtonT.MenuSpecificProps> = {\n ItemRenderer: PropTypes.node.description('Component to be used to render the items'),\n onClickOutside: PropTypes.func\n .description('Callback executed when you click outside the dropdown menu, or press the Esc key')\n .defaultValue(() => null),\n onOptionClick: PropTypes.func\n .description(\n 'Callback triggered when an item is clicked or pressed. We provide the next selected options, the clicked option and the event, in that order',\n )\n .defaultValue(() => null),\n openedSubmenus: PropTypes.object\n .description(\n 'Object with the ids of the submenus as keys, and booleans as keys. Represents the state of the current opened submenus',\n )\n .defaultValue({}),\n onSubmenuToggle: PropTypes.func\n .description('Callback triggered when a submenu is opened or closed.')\n .signature(\n '((nextOpenedSubmenus: Record<string, boolean>, submenu: Item, e: React.MouseEvent | React.KeyboardEvent) => void)',\n )\n .defaultValue(() => null),\n isLoading: PropTypes.bool\n .description('Whether the flyout menu should render the loading indicator')\n .defaultValue(false),\n isSkeleton: PropTypes.bool.description('Whether the flyout menu should render the skeleton').defaultValue(false),\n maxHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number])\n .description('The maximum height of the flyout menu')\n .defaultValue('256px'),\n};\n\nexport const DSMenuButtonPropTypes: DSPropTypesSchema<DSMenuButtonT.Props> = {\n options: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).description(\n 'Array of options to display in the menu or a DSTree node to build branches from',\n ).isRequired,\n selectedItems: PropTypes.arrayOf(PropTypes.object).description(\n 'an array of tree-nodes or tree-items that have to be marked as selected in the GUI, required if the menu has selectionable items',\n ),\n ...DSButtonV3PropTypes,\n ...MenuBehaviouralLayerPropTypes,\n ...DSMenuSpecificPropTypes,\n ...getPropsPerSlotPropTypes(DSMenuButtonName, MENU_BUTTON_SLOTS),\n};\n\nexport const DSMenuButtonPropTypesSchema = DSMenuButtonPropTypes as unknown as ValidationMap<DSMenuButtonT.Props>;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACEvB,SAAS,WAAW,gCAAgC;AACpD,SAAS,2BAA2B;AAMpC,SAAS,kBAAkB,yBAAgD;AAwdpE,MAAM,2BAAkE;AAAA,EAC7E,gBAAgB,MAAM;AAAA,EACtB,eAAe,MAAM;AAAA,EACrB,gBAAgB,CAAC;AAAA,EACjB,iBAAiB,MAAM;AAAA,EACvB,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,WAAW;AAAA;AACb;AAYO,MAAM,gCAA4F;AAAA,EACvG,gBAAgB,UAAU,KAAK;AAAA,IAC7B;AAAA,EACF,EAAE,UAAU;AAAA;AAAA;AAAA,eAGC;AAAA,EAEb,gBAAgB,UAAU,KAAK;AAAA,IAC7B;AAAA,EACF,EAAE,UAAU;AAAA;AAAA;AAAA,eAGC;AAAA,EAEb,QAAQ,UAAU,KAAK,YAAY,mDAAmD,EAAE,UAAU,YAAY;AAAA,EAC9G,SAAS,UAAU,KAAK,YAAY,oDAAoD,EAAE,UAAU,YAAY;AAAA,EAChH,0BAA0B,UAAU,KAAK,YAAY,gEAAgE,EAClH,UAAU;AAAA;AAAA;AAAA,eAGA;AACf;AAEO,MAAM,0BAA8E;AAAA,EACzF,cAAc,UAAU,KAAK,YAAY,0CAA0C;AAAA,EACnF,gBAAgB,UAAU,KACvB,YAAY,kFAAkF,EAC9F,aAAa,MAAM,IAAI;AAAA,EAC1B,eAAe,UAAU,KACtB;AAAA,IACC;AAAA,EACF,EACC,aAAa,MAAM,IAAI;AAAA,EAC1B,gBAAgB,UAAU,OACvB;AAAA,IACC;AAAA,EACF,EACC,aAAa,CAAC,CAAC;AAAA,EAClB,iBAAiB,UAAU,KACxB,YAAY,wDAAwD,EACpE;AAAA,IACC;AAAA,EACF,EACC,aAAa,MAAM,IAAI;AAAA,EAC1B,WAAW,UAAU,KAClB,YAAY,6DAA6D,EACzE,aAAa,KAAK;AAAA,EACrB,YAAY,UAAU,KAAK,YAAY,oDAAoD,EAAE,aAAa,KAAK;AAAA,EAC/G,WAAW,UAAU,UAAU,CAAC,UAAU,QAAQ,UAAU,MAAM,CAAC,EAChE,YAAY,uCAAuC,EACnD,aAAa,OAAO;AACzB;AAEO,MAAM,wBAAgE;AAAA,EAC3E,SAAS,UAAU,UAAU,CAAC,UAAU,OAAO,UAAU,MAAM,CAAC,EAAE;AAAA,IAChE;AAAA,EACF,EAAE;AAAA,EACF,eAAe,UAAU,QAAQ,UAAU,MAAM,EAAE;AAAA,IACjD;AAAA,EACF;AAAA,EACA,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG,yBAAyB,kBAAkB,iBAAiB;AACjE;AAEO,MAAM,8BAA8B;",
6
6
  "names": []
7
7
  }
@@ -1,21 +1,28 @@
1
1
  import * as React from "react";
2
2
  import React2 from "react";
3
3
  import { useDSTree } from "@elliemae/ds-tree-model";
4
+ import { menuSpecificDefaultProps } from "../react-desc-prop-types.js";
4
5
  const useDsTreeOpts = {
5
6
  getUniqueId: (item) => item.dsId
6
7
  };
7
- const useOptionsArrayToDsTree = ({ options, instanceUid }) => {
8
+ const useOptionsArrayToDsTree = ({
9
+ options,
10
+ instanceUid,
11
+ propsWithDefault
12
+ }) => {
13
+ const { maxHeight } = propsWithDefault || menuSpecificDefaultProps;
8
14
  const rootNode = React2.useMemo(
9
15
  () => ({
10
16
  dsId: `root-${instanceUid}`,
11
17
  type: "ROOT_ITEM",
12
- subitems: options
18
+ subitems: options,
19
+ maxHeight
13
20
  // as unknown as RootNodeType is because currently
14
21
  // the DS tree model doesn't support the type of the root node being different from the subitems
15
22
  // in practice, this is fine because the root node is never rendered & the subitems are the only thing that matters
16
23
  // will be addresssed via PUI-XXXX
17
24
  }),
18
- [instanceUid, options]
25
+ [instanceUid, maxHeight, options]
19
26
  );
20
27
  return useDSTree(rootNode, useDsTreeOpts);
21
28
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/utils/useOptionsArrayToDsTree.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport { useDSTree } from '@elliemae/ds-tree-model';\nimport type { UseDSTreeT } from '@elliemae/ds-tree-model';\nimport { type DSMenuButtonT } from '../react-desc-prop-types.js';\n\nconst useDsTreeOpts: UseDSTreeT.SecondParameter<DSMenuButtonT.MenuItemInterface> = {\n getUniqueId: (item) => item.dsId,\n};\n\ntype UseOptionsArrayToDsTreeRootNodeConfig = {\n options: DSMenuButtonT.MenuItemInterface[];\n instanceUid: string;\n};\n\ntype RootNodeType = UseDSTreeT.Item<DSMenuButtonT.MenuItemInterface>;\n\nexport const useOptionsArrayToDsTree = ({ options, instanceUid }: UseOptionsArrayToDsTreeRootNodeConfig) => {\n // we need to create the root node that the app dev doesn't need to worry about\n const rootNode = React.useMemo<RootNodeType>(\n () =>\n ({\n dsId: `root-${instanceUid}`,\n type: 'ROOT_ITEM',\n subitems: options,\n // as unknown as RootNodeType is because currently\n // the DS tree model doesn't support the type of the root node being different from the subitems\n // in practice, this is fine because the root node is never rendered & the subitems are the only thing that matters\n // will be addresssed via PUI-XXXX\n }) as unknown as RootNodeType,\n [instanceUid, options],\n );\n return useDSTree<DSMenuButtonT.MenuItemInterface>(rootNode, useDsTreeOpts);\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,YAAW;AAClB,SAAS,iBAAiB;AAI1B,MAAM,gBAA6E;AAAA,EACjF,aAAa,CAAC,SAAS,KAAK;AAC9B;AASO,MAAM,0BAA0B,CAAC,EAAE,SAAS,YAAY,MAA6C;AAE1G,QAAM,WAAWA,OAAM;AAAA,IACrB,OACG;AAAA,MACC,MAAM,QAAQ,WAAW;AAAA,MACzB,MAAM;AAAA,MACN,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,IAKZ;AAAA,IACF,CAAC,aAAa,OAAO;AAAA,EACvB;AACA,SAAO,UAA2C,UAAU,aAAa;AAC3E;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport { useDSTree } from '@elliemae/ds-tree-model';\nimport type { UseDSTreeT } from '@elliemae/ds-tree-model';\nimport { type DSMenuButtonT, menuSpecificDefaultProps } from '../react-desc-prop-types.js';\n\nconst useDsTreeOpts: UseDSTreeT.SecondParameter<DSMenuButtonT.MenuItemInterface> = {\n getUniqueId: (item) => item.dsId,\n};\n\ntype UseOptionsArrayToDsTreeRootNodeConfig = {\n options: DSMenuButtonT.MenuItemInterface[];\n instanceUid: string;\n propsWithDefault?: DSMenuButtonT.MenuSpecifiDefaultProps;\n};\n\ntype RootNodeType = UseDSTreeT.Item<DSMenuButtonT.MenuItemInterface>;\n\nexport const useOptionsArrayToDsTree = ({\n options,\n instanceUid,\n propsWithDefault,\n}: UseOptionsArrayToDsTreeRootNodeConfig) => {\n const { maxHeight } = propsWithDefault || menuSpecificDefaultProps;\n // we need to create the root node that the app dev doesn't need to worry about\n const rootNode = React.useMemo<RootNodeType>(\n () =>\n ({\n dsId: `root-${instanceUid}`,\n type: 'ROOT_ITEM',\n subitems: options,\n maxHeight,\n // as unknown as RootNodeType is because currently\n // the DS tree model doesn't support the type of the root node being different from the subitems\n // in practice, this is fine because the root node is never rendered & the subitems are the only thing that matters\n // will be addresssed via PUI-XXXX\n }) as unknown as RootNodeType,\n [instanceUid, maxHeight, options],\n );\n return useDSTree<DSMenuButtonT.MenuItemInterface>(rootNode, useDsTreeOpts);\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,YAAW;AAClB,SAAS,iBAAiB;AAE1B,SAA6B,gCAAgC;AAE7D,MAAM,gBAA6E;AAAA,EACjF,aAAa,CAAC,SAAS,KAAK;AAC9B;AAUO,MAAM,0BAA0B,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,MAA6C;AAC3C,QAAM,EAAE,UAAU,IAAI,oBAAoB;AAE1C,QAAM,WAAWA,OAAM;AAAA,IACrB,OACG;AAAA,MACC,MAAM,QAAQ,WAAW;AAAA,MACzB,MAAM;AAAA,MACN,UAAU;AAAA,MACV;AAAA;AAAA;AAAA;AAAA;AAAA,IAKF;AAAA,IACF,CAAC,aAAa,WAAW,OAAO;AAAA,EAClC;AACA,SAAO,UAA2C,UAAU,aAAa;AAC3E;",
6
6
  "names": ["React"]
7
7
  }
@@ -439,7 +439,6 @@ export declare const useSplitInherithedProps: ({ propsWithDefault, focusableNode
439
439
  h?: import("@xstyled/system").SystemProp<string | number | true | symbol | {} | (string & {}), import("@xstyled/system").Theme> | undefined;
440
440
  maxWidth?: (string | number | true | symbol | {} | (string & {}) | import("@xstyled/system").ThemeProp<string | number | true | symbol | {} | (string & {}), import("@xstyled/system").Theme>) | undefined;
441
441
  maxW?: (string | number | true | symbol | {} | (string & {}) | import("@xstyled/system").ThemeProp<string | number | true | symbol | {} | (string & {}), import("@xstyled/system").Theme>) | undefined;
442
- maxHeight?: (string | number | true | symbol | {} | (string & {}) | import("@xstyled/system").ThemeProp<string | number | true | symbol | {} | (string & {}), import("@xstyled/system").Theme>) | undefined;
443
442
  maxH?: (string | number | true | symbol | {} | (string & {}) | import("@xstyled/system").ThemeProp<string | number | true | symbol | {} | (string & {}), import("@xstyled/system").Theme>) | undefined;
444
443
  minHeight?: (string | number | true | symbol | {} | (string & {}) | import("@xstyled/system").ThemeProp<string | number | true | symbol | {} | (string & {}), import("@xstyled/system").Theme>) | undefined;
445
444
  minH?: (string | number | true | symbol | {} | (string & {}) | import("@xstyled/system").ThemeProp<string | number | true | symbol | {} | (string & {}), import("@xstyled/system").Theme>) | undefined;
@@ -1,6 +1,6 @@
1
+ import { type useFloatingContext } from '@elliemae/ds-floating-context';
1
2
  import type { DSPropTypesSchema, ValidationMap } from '@elliemae/ds-props-helpers';
2
3
  import { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';
3
- import { type useFloatingContext } from '@elliemae/ds-floating-context';
4
4
  import { type DSMenuButtonT } from '../../react-desc-prop-types.js';
5
5
  import { DSFlyoutMenuName, FLYOUT_MENU_SLOTS } from './constants/index.js';
6
6
  export declare namespace DSFlyoutMenuT {
@@ -4,12 +4,12 @@ export declare const useFocusTracker: () => {
4
4
  preventBlurReset: React.MutableRefObject<boolean>;
5
5
  focusRegion: "" | "trigger" | `item-dsid-${string}` | `item-dsid-${number}`;
6
6
  focusedElementItemNode: React.MutableRefObject<DSMenuButtonT.PseudoFocusableMenuNodes | null>;
7
- trackFocusTrigger: () => null;
7
+ trackFocusTrigger: () => DSMenuButtonT.PseudoFocusableMenuNodes | null;
8
8
  trackFocusNode: (nodeToFocus: DSMenuButtonT.PseudoFocusableMenuNodes) => void;
9
- trackFocusRegionReset: () => null;
10
- trackFocusFirstChildItem: (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => DSMenuButtonT.PseudoFocusableMenuNodes;
11
- trackFocusLastChildItem: (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => DSMenuButtonT.PseudoFocusableMenuNodes;
12
- trackFocusNextItem: (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => DSMenuButtonT.PseudoFocusableMenuNodes;
13
- trackFocusPreviousItem: (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => DSMenuButtonT.PseudoFocusableMenuNodes;
9
+ trackFocusRegionReset: () => DSMenuButtonT.PseudoFocusableMenuNodes | null;
10
+ trackFocusFirstChildItem: (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => DSMenuButtonT.PseudoFocusableMenuNodes | null;
11
+ trackFocusLastChildItem: (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => DSMenuButtonT.PseudoFocusableMenuNodes | null;
12
+ trackFocusNextItem: (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => DSMenuButtonT.PseudoFocusableMenuNodes | null;
13
+ trackFocusPreviousItem: (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => DSMenuButtonT.PseudoFocusableMenuNodes | null;
14
14
  trackFocusParentItem: (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => DSMenuButtonT.PseudoFocusableMenuNodes | null;
15
15
  };
@@ -0,0 +1,2 @@
1
+ /// <reference types="lodash" />
2
+ export declare const focusNodeRacingConditionSolved: import("lodash").DebouncedFunc<(node: HTMLDivElement) => void>;
@@ -1,9 +1,9 @@
1
1
  /// <reference types="react" />
2
- import type { GlobalAttributesT, XstyledProps, DSPropTypesSchema, ValidationMap } from '@elliemae/ds-props-helpers';
2
+ import type { DSPropTypesSchema, GlobalAttributesT, ValidationMap, XstyledProps } from '@elliemae/ds-props-helpers';
3
3
  import { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';
4
- import { DSMenuItemRendererFactoryName, MENU_ITEM_RENDERER_FACTORY_SLOTS } from './constants/index.js';
5
4
  import type { DSMenuButtonT } from '../../react-desc-prop-types.js';
6
5
  import type { DSFlyoutMenuT } from '../DSFlyoutMenu/react-desc-prop-types.js';
6
+ import { DSMenuItemRendererFactoryName, MENU_ITEM_RENDERER_FACTORY_SLOTS } from './constants/index.js';
7
7
  export declare namespace DSMenuItemRendererFactoryT {
8
8
  interface RequiredProps {
9
9
  itemNode: DSMenuButtonT.MenuNode;
@@ -1,6 +1,6 @@
1
- import React from 'react';
2
1
  import type { DSPropTypesSchema, ValidationMap } from '@elliemae/ds-props-helpers';
3
2
  import { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';
3
+ import type React from 'react';
4
4
  import { type DSMenuButtonT } from '../../react-desc-prop-types.js';
5
5
  import { DSOpinionatedButtonName, OPINIONATED_BUTTON_SLOTS } from './constants/index.js';
6
6
  export declare namespace DSOpinionatedButtonT {