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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) 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 +33 -15
  4. package/dist/cjs/config/useSplitInherithedProps.js.map +2 -2
  5. package/dist/cjs/parts/DSFlyoutMenu/DSFlyoutMenu.js +36 -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/useAdvancedValidation.js +4 -4
  10. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useAdvancedValidation.js.map +1 -1
  11. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js +40 -30
  12. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js.map +2 -2
  13. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js +1 -1
  14. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js.map +2 -2
  15. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js +7 -7
  16. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js.map +1 -1
  17. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.js +3 -0
  18. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.js.map +2 -2
  19. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/utils/multipleSelectionHelpers.js +14 -14
  20. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/utils/multipleSelectionHelpers.js.map +1 -1
  21. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/utils/singleSelectionHelpers.js +2 -2
  22. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/utils/singleSelectionHelpers.js.map +1 -1
  23. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableMenuItem.js +4 -5
  24. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableMenuItem.js.map +2 -2
  25. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js +4 -5
  26. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js.map +2 -2
  27. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js +6 -7
  28. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js.map +2 -2
  29. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js +7 -8
  30. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js.map +2 -2
  31. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js +6 -7
  32. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js.map +2 -2
  33. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js +6 -7
  34. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js.map +2 -2
  35. package/dist/cjs/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js +4 -5
  36. package/dist/cjs/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js.map +2 -2
  37. package/dist/cjs/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js +1 -1
  38. package/dist/cjs/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js.map +2 -2
  39. package/dist/cjs/parts/DSMenuItemRendererFactory/focusNodeRacingConditionSolved.js +43 -0
  40. package/dist/cjs/parts/DSMenuItemRendererFactory/focusNodeRacingConditionSolved.js.map +7 -0
  41. package/dist/cjs/parts/DSMenuItemRendererFactory/react-desc-prop-types.js.map +2 -2
  42. package/dist/cjs/parts/DSOpinionatedButton/react-desc-prop-types.js.map +2 -2
  43. package/dist/cjs/react-desc-prop-types.js +10 -11
  44. package/dist/cjs/react-desc-prop-types.js.map +2 -2
  45. package/dist/cjs/utils/nodesTypeguardsAndGetters.js +18 -56
  46. package/dist/cjs/utils/nodesTypeguardsAndGetters.js.map +2 -2
  47. package/dist/cjs/utils/useOptionsArrayToDsTree.js +10 -3
  48. package/dist/cjs/utils/useOptionsArrayToDsTree.js.map +2 -2
  49. package/dist/esm/config/useMenuButton.js +7 -3
  50. package/dist/esm/config/useMenuButton.js.map +2 -2
  51. package/dist/esm/config/useSplitInherithedProps.js +33 -15
  52. package/dist/esm/config/useSplitInherithedProps.js.map +2 -2
  53. package/dist/esm/parts/DSFlyoutMenu/DSFlyoutMenu.js +34 -10
  54. package/dist/esm/parts/DSFlyoutMenu/DSFlyoutMenu.js.map +2 -2
  55. package/dist/esm/parts/DSFlyoutMenu/react-desc-prop-types.js +1 -4
  56. package/dist/esm/parts/DSFlyoutMenu/react-desc-prop-types.js.map +2 -2
  57. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useAdvancedValidation.js +4 -4
  58. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useAdvancedValidation.js.map +1 -1
  59. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js +40 -30
  60. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js.map +2 -2
  61. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js +1 -1
  62. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js.map +2 -2
  63. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js +7 -7
  64. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js.map +1 -1
  65. package/dist/esm/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.js +3 -0
  66. package/dist/esm/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.js.map +2 -2
  67. package/dist/esm/parts/DSMenuBehaviouralContextProvider/utils/multipleSelectionHelpers.js +14 -14
  68. package/dist/esm/parts/DSMenuBehaviouralContextProvider/utils/multipleSelectionHelpers.js.map +1 -1
  69. package/dist/esm/parts/DSMenuBehaviouralContextProvider/utils/singleSelectionHelpers.js +2 -2
  70. package/dist/esm/parts/DSMenuBehaviouralContextProvider/utils/singleSelectionHelpers.js.map +1 -1
  71. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableMenuItem.js +4 -5
  72. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableMenuItem.js.map +2 -2
  73. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js +4 -5
  74. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js.map +2 -2
  75. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js +6 -7
  76. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js.map +2 -2
  77. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js +7 -8
  78. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js.map +2 -2
  79. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js +6 -7
  80. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js.map +2 -2
  81. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js +6 -7
  82. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js.map +2 -2
  83. package/dist/esm/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js +4 -5
  84. package/dist/esm/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js.map +2 -2
  85. package/dist/esm/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js +1 -1
  86. package/dist/esm/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js.map +2 -2
  87. package/dist/esm/parts/DSMenuItemRendererFactory/focusNodeRacingConditionSolved.js +13 -0
  88. package/dist/esm/parts/DSMenuItemRendererFactory/focusNodeRacingConditionSolved.js.map +7 -0
  89. package/dist/esm/parts/DSMenuItemRendererFactory/react-desc-prop-types.js.map +2 -2
  90. package/dist/esm/parts/DSOpinionatedButton/react-desc-prop-types.js +1 -1
  91. package/dist/esm/parts/DSOpinionatedButton/react-desc-prop-types.js.map +2 -2
  92. package/dist/esm/react-desc-prop-types.js +10 -11
  93. package/dist/esm/react-desc-prop-types.js.map +2 -2
  94. package/dist/esm/utils/nodesTypeguardsAndGetters.js +18 -56
  95. package/dist/esm/utils/nodesTypeguardsAndGetters.js.map +2 -2
  96. package/dist/esm/utils/useOptionsArrayToDsTree.js +10 -3
  97. package/dist/esm/utils/useOptionsArrayToDsTree.js.map +2 -2
  98. package/dist/types/config/useSplitInherithedProps.d.ts +3 -4
  99. package/dist/types/parts/DSFlyoutMenu/react-desc-prop-types.d.ts +1 -1
  100. package/dist/types/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.d.ts +6 -6
  101. package/dist/types/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.d.ts +1 -0
  102. package/dist/types/parts/DSMenuBehaviouralContextProvider/utils/multipleSelectionHelpers.d.ts +3 -3
  103. package/dist/types/parts/DSMenuBehaviouralContextProvider/utils/singleSelectionHelpers.d.ts +2 -2
  104. package/dist/types/parts/DSMenuItemRendererFactory/focusNodeRacingConditionSolved.d.ts +2 -0
  105. package/dist/types/parts/DSMenuItemRendererFactory/react-desc-prop-types.d.ts +2 -2
  106. package/dist/types/parts/DSOpinionatedButton/react-desc-prop-types.d.ts +1 -1
  107. package/dist/types/react-desc-prop-types.d.ts +10 -4
  108. package/dist/types/utils/nodesTypeguardsAndGetters.d.ts +113 -1
  109. package/dist/types/utils/useOptionsArrayToDsTree.d.ts +2 -1
  110. package/package.json +12 -13
@@ -41,7 +41,10 @@ var import_useOptionsArrayToDsTree = require("../utils/useOptionsArrayToDsTree.j
41
41
  var import_useSplitInherithedProps = require("./useSplitInherithedProps.js");
42
42
  var import_useValidateProps = require("./useValidateProps.js");
43
43
  const useMenuButton = (propsFromUser) => {
44
- const propsWithDefault = (0, import_ds_props_helpers.useMemoMergePropsWithDefault)(propsFromUser, import_react_desc_prop_types.defaultProps);
44
+ const propsWithDefault = (0, import_ds_props_helpers.useMemoMergePropsWithDefault)(
45
+ propsFromUser,
46
+ import_react_desc_prop_types.menuSpecificDefaultProps
47
+ );
45
48
  (0, import_useValidateProps.useValidateProps)(propsWithDefault, import_react_desc_prop_types.DSMenuButtonPropTypes);
46
49
  const xstyledProps = (0, import_ds_props_helpers.useGetXstyledProps)(propsWithDefault);
47
50
  const instanceUid = import_react.default.useMemo(() => `menu-button${(0, import_uid.uid)(5)}`, []);
@@ -49,7 +52,8 @@ const useMenuButton = (propsFromUser) => {
49
52
  const optionsArray = Array.isArray(appOptions) ? appOptions : [];
50
53
  const treeRootNodeFromOptionsArrayIfArray = (0, import_useOptionsArrayToDsTree.useOptionsArrayToDsTree)({
51
54
  options: optionsArray,
52
- instanceUid
55
+ instanceUid,
56
+ propsWithDefault
53
57
  // this typecast is a safe type reconciliation, typescript checks they are compatible
54
58
  // this typecast let us avoid to have to do the ` | OtherCompatibleType` dance
55
59
  }).getRoot();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/config/useMenuButton.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable max-statements */\nimport { useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport React from 'react';\nimport { uid } from 'uid';\nimport { DSMenuButtonPropTypes, defaultProps, type DSMenuButtonT } from '../react-desc-prop-types.js';\nimport { getFocusableNodes } from '../utils/nodesTypeguardsAndGetters.js';\nimport { useOptionsArrayToDsTree } from '../utils/useOptionsArrayToDsTree.js';\nimport { useSplitInherithedProps } from './useSplitInherithedProps.js';\nimport { useValidateProps } from './useValidateProps.js';\nexport interface MenuButtonCTX extends ReturnType<typeof useSplitInherithedProps> {\n propsWithDefault: DSMenuButtonT.InternalProps;\n xstyledProps: ReturnType<typeof useGetXstyledProps>;\n instanceUid: string;\n}\n\nexport const useMenuButton = (propsFromUser: DSMenuButtonT.Props) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<DSMenuButtonT.InternalProps>(propsFromUser, defaultProps);\n useValidateProps(propsWithDefault, DSMenuButtonPropTypes);\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(() => `menu-button${uid(5)}`, []);\n // =============================================================================\n // HELPERS HOOKS CONFIGS\n // =============================================================================\n\n // =============================================================================\n // React hooks can't be invoked conditionally...\n // =============================================================================\n const { options: appOptions } = propsWithDefault;\n const optionsArray: DSMenuButtonT.MenuItemInterface[] = Array.isArray(appOptions) ? appOptions : [];\n\n const treeRootNodeFromOptionsArrayIfArray = useOptionsArrayToDsTree({\n options: optionsArray,\n instanceUid,\n // this typecast is a safe type reconciliation, typescript checks they are compatible\n // this typecast let us avoid to have to do the ` | OtherCompatibleType` dance\n }).getRoot() as DSMenuButtonT.MenuNode;\n const treeRootNode = React.useMemo(\n () => (Array.isArray(appOptions) ? treeRootNodeFromOptionsArrayIfArray : appOptions),\n [appOptions, treeRootNodeFromOptionsArrayIfArray],\n );\n\n // =============================================================================\n // We calculate the focusableNodes from the treeRootNode.plainChildren via getFocusableNodes\n // =============================================================================\n const focusableNodes = React.useMemo(() => getFocusableNodes(treeRootNode), [treeRootNode]);\n const splitInherithedProps = useSplitInherithedProps({\n propsWithDefault,\n focusableNodes,\n treeRootNode,\n });\n\n return React.useMemo<MenuButtonCTX>(\n () => ({\n propsWithDefault,\n xstyledProps,\n instanceUid,\n ...splitInherithedProps,\n }),\n [propsWithDefault, xstyledProps, instanceUid, splitInherithedProps],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADCvB,8BAAiE;AACjE,mBAAkB;AAClB,iBAAoB;AACpB,mCAAwE;AACxE,uCAAkC;AAClC,qCAAwC;AACxC,qCAAwC;AACxC,8BAAiC;AAO1B,MAAM,gBAAgB,CAAC,kBAAuC;AAInE,QAAM,uBAAmB,sDAA0D,eAAe,yCAAY;AAC9G,gDAAiB,kBAAkB,kDAAqB;AAIxD,QAAM,mBAAe,4CAAmB,gBAAgB;AAKxD,QAAM,cAAc,aAAAA,QAAM,QAAQ,MAAM,kBAAc,gBAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAQlE,QAAM,EAAE,SAAS,WAAW,IAAI;AAChC,QAAM,eAAkD,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC;AAElG,QAAM,0CAAsC,wDAAwB;AAAA,IAClE,SAAS;AAAA,IACT;AAAA;AAAA;AAAA,EAGF,CAAC,EAAE,QAAQ;AACX,QAAM,eAAe,aAAAA,QAAM;AAAA,IACzB,MAAO,MAAM,QAAQ,UAAU,IAAI,sCAAsC;AAAA,IACzE,CAAC,YAAY,mCAAmC;AAAA,EAClD;AAKA,QAAM,iBAAiB,aAAAA,QAAM,QAAQ,UAAM,oDAAkB,YAAY,GAAG,CAAC,YAAY,CAAC;AAC1F,QAAM,2BAAuB,wDAAwB;AAAA,IACnD;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO,aAAAA,QAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL;AAAA,IACA,CAAC,kBAAkB,cAAc,aAAa,oBAAoB;AAAA,EACpE;AACF;",
4
+ "sourcesContent": ["/* eslint-disable max-statements */\nimport { useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport React from 'react';\nimport { uid } from 'uid';\nimport { DSMenuButtonPropTypes, menuSpecificDefaultProps, type DSMenuButtonT } from '../react-desc-prop-types.js';\nimport { getFocusableNodes } from '../utils/nodesTypeguardsAndGetters.js';\nimport { useOptionsArrayToDsTree } from '../utils/useOptionsArrayToDsTree.js';\nimport { useSplitInherithedProps } from './useSplitInherithedProps.js';\nimport { useValidateProps } from './useValidateProps.js';\nexport interface MenuButtonCTX extends ReturnType<typeof useSplitInherithedProps> {\n propsWithDefault: DSMenuButtonT.InternalProps;\n xstyledProps: ReturnType<typeof useGetXstyledProps>;\n instanceUid: string;\n}\n\nexport const useMenuButton = (propsFromUser: DSMenuButtonT.Props) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<DSMenuButtonT.InternalProps>(\n propsFromUser,\n menuSpecificDefaultProps,\n );\n useValidateProps(propsWithDefault, DSMenuButtonPropTypes);\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(() => `menu-button${uid(5)}`, []);\n // =============================================================================\n // HELPERS HOOKS CONFIGS\n // =============================================================================\n\n // =============================================================================\n // React hooks can't be invoked conditionally...\n // =============================================================================\n\n // As per intended WIDGET API, user can provide options as an array of \"items\" or an array of \"nodes\"\n // we do the conversion from \"items\" to \"nodes\" here,\n // because the `parts` require the \"nodes\" extra properties to handle the logic and rendering\n const { options: appOptions } = propsWithDefault;\n const optionsArray: DSMenuButtonT.MenuItemInterface[] = Array.isArray(appOptions) ? appOptions : [];\n\n const treeRootNodeFromOptionsArrayIfArray = useOptionsArrayToDsTree({\n options: optionsArray,\n instanceUid,\n propsWithDefault,\n // this typecast is a safe type reconciliation, typescript checks they are compatible\n // this typecast let us avoid to have to do the ` | OtherCompatibleType` dance\n }).getRoot() as DSMenuButtonT.MenuNode;\n const treeRootNode = React.useMemo(\n () => (Array.isArray(appOptions) ? treeRootNodeFromOptionsArrayIfArray : appOptions),\n [appOptions, treeRootNodeFromOptionsArrayIfArray],\n );\n\n // =============================================================================\n // We calculate the focusableNodes from the treeRootNode.plainChildren via getFocusableNodes\n // =============================================================================\n const focusableNodes = React.useMemo(() => getFocusableNodes(treeRootNode), [treeRootNode]);\n const splitInherithedProps = useSplitInherithedProps({\n propsWithDefault,\n focusableNodes,\n treeRootNode,\n });\n\n return React.useMemo<MenuButtonCTX>(\n () => ({\n propsWithDefault,\n xstyledProps,\n instanceUid,\n ...splitInherithedProps,\n }),\n [propsWithDefault, xstyledProps, instanceUid, splitInherithedProps],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADCvB,8BAAiE;AACjE,mBAAkB;AAClB,iBAAoB;AACpB,mCAAoF;AACpF,uCAAkC;AAClC,qCAAwC;AACxC,qCAAwC;AACxC,8BAAiC;AAO1B,MAAM,gBAAgB,CAAC,kBAAuC;AAInE,QAAM,uBAAmB;AAAA,IACvB;AAAA,IACA;AAAA,EACF;AACA,gDAAiB,kBAAkB,kDAAqB;AAIxD,QAAM,mBAAe,4CAAmB,gBAAgB;AAKxD,QAAM,cAAc,aAAAA,QAAM,QAAQ,MAAM,kBAAc,gBAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAYlE,QAAM,EAAE,SAAS,WAAW,IAAI;AAChC,QAAM,eAAkD,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC;AAElG,QAAM,0CAAsC,wDAAwB;AAAA,IAClE,SAAS;AAAA,IACT;AAAA,IACA;AAAA;AAAA;AAAA,EAGF,CAAC,EAAE,QAAQ;AACX,QAAM,eAAe,aAAAA,QAAM;AAAA,IACzB,MAAO,MAAM,QAAQ,UAAU,IAAI,sCAAsC;AAAA,IACzE,CAAC,YAAY,mCAAmC;AAAA,EAClD;AAKA,QAAM,iBAAiB,aAAAA,QAAM,QAAQ,UAAM,oDAAkB,YAAY,GAAG,CAAC,YAAY,CAAC;AAC1F,QAAM,2BAAuB,wDAAwB;AAAA,IACnD;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO,aAAAA,QAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL;AAAA,IACA,CAAC,kBAAkB,cAAc,aAAa,oBAAoB;AAAA,EACpE;AACF;",
6
6
  "names": ["React"]
7
7
  }
@@ -33,7 +33,29 @@ __export(useSplitInherithedProps_exports, {
33
33
  module.exports = __toCommonJS(useSplitInherithedProps_exports);
34
34
  var React = __toESM(require("react"));
35
35
  var import_react = __toESM(require("react"));
36
+ var import_nodesTypeguardsAndGetters = require("../utils/nodesTypeguardsAndGetters.js");
36
37
  var import_resolveRef = require("../utils/resolveRef.js");
38
+ const convertSelectedOptionsToNodes = (selectedItems, treeRootNode) => {
39
+ const convertedSelection = [];
40
+ selectedItems.forEach((selectedItem) => {
41
+ const needsConversion = !(0, import_nodesTypeguardsAndGetters.isObjectAMenuNode)(selectedItem);
42
+ if (!needsConversion) {
43
+ convertedSelection.push(selectedItem);
44
+ return;
45
+ }
46
+ const { dsId } = selectedItem;
47
+ const selectedNode = treeRootNode.findNode((node) => node.dsId === dsId);
48
+ if (!selectedNode) {
49
+ throw new Error(`Selected option with dsId ${dsId} not found in the menu tree.`);
50
+ }
51
+ if (!(0, import_nodesTypeguardsAndGetters.isSelectionableNode)(selectedNode)) {
52
+ console.warn(`Selected option with dsId ${dsId} is not a selectionable node and will be ignored.`);
53
+ return;
54
+ }
55
+ convertedSelection.push(selectedNode);
56
+ });
57
+ return convertedSelection;
58
+ };
37
59
  const useSplitInherithedProps = ({
38
60
  propsWithDefault,
39
61
  focusableNodes,
@@ -48,7 +70,6 @@ const useSplitInherithedProps = ({
48
70
  onSubmenuToggle,
49
71
  isLoading,
50
72
  isSkeleton,
51
- selectedOptions,
52
73
  ItemRenderer,
53
74
  innerRef,
54
75
  selectedItems,
@@ -57,6 +78,8 @@ const useSplitInherithedProps = ({
57
78
  onActivateItem,
58
79
  onOpen,
59
80
  onClose,
81
+ maxHeight,
82
+ // this is not shared with anything at all, it's instead a property of the "root" node, each node (with a submenu) can have its own maxHeight
60
83
  ...buttonInheritedProps
61
84
  } = propsWithDefault;
62
85
  const innerRefSnatchingNode = import_react.default.useCallback(
@@ -68,6 +91,12 @@ const useSplitInherithedProps = ({
68
91
  },
69
92
  [innerRef]
70
93
  );
94
+ const selectedNodesMap = import_react.default.useMemo(() => {
95
+ if (selectedItems) {
96
+ return convertSelectedOptionsToNodes(selectedItems, treeRootNode);
97
+ }
98
+ return [];
99
+ }, [selectedItems, treeRootNode]);
71
100
  const menuSpecificProps = import_react.default.useMemo(
72
101
  () => ({
73
102
  options,
@@ -77,26 +106,15 @@ const useSplitInherithedProps = ({
77
106
  onSubmenuToggle,
78
107
  isLoading,
79
108
  isSkeleton,
80
- selectedOptions,
81
109
  ItemRenderer
82
110
  }),
83
- [
84
- options,
85
- onClickOutside,
86
- onOptionClick,
87
- openedSubmenus,
88
- onSubmenuToggle,
89
- isLoading,
90
- isSkeleton,
91
- selectedOptions,
92
- ItemRenderer
93
- ]
111
+ [options, onClickOutside, onOptionClick, openedSubmenus, onSubmenuToggle, isLoading, isSkeleton, ItemRenderer]
94
112
  );
95
113
  return import_react.default.useMemo(
96
114
  () => ({
97
115
  menuBehaviouralLayerProps: {
98
116
  buttonDOMNodeRef,
99
- selectedItems,
117
+ selectedNodes: selectedNodesMap,
100
118
  focusableNodes,
101
119
  optionsTree: treeRootNode,
102
120
  onDisplayedSubmenuChange,
@@ -112,7 +130,7 @@ const useSplitInherithedProps = ({
112
130
  }
113
131
  }),
114
132
  [
115
- selectedItems,
133
+ selectedNodesMap,
116
134
  focusableNodes,
117
135
  treeRootNode,
118
136
  onDisplayedSubmenuChange,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/config/useSplitInherithedProps.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* *******************************************************\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 * this hooks is meant to take all the DSMenuButtonT.InternalProps with default already merged\n * and spit out menuSpecificProps & buttonInheritedProps\n ******************************************************* */\nimport {} from '@elliemae/ds-system';\nimport React from 'react';\nimport { type DSMenuButtonT } from '../react-desc-prop-types.js';\nimport { resolveRef } from '../utils/resolveRef.js';\n\ntype UseSplitInherithedPropsConfig = {\n propsWithDefault: DSMenuButtonT.InternalProps;\n focusableNodes: DSMenuButtonT.PseudoFocusableMenuNodes[];\n treeRootNode: DSMenuButtonT.MenuNode;\n};\nexport const useSplitInherithedProps = ({\n propsWithDefault,\n focusableNodes,\n treeRootNode,\n}: UseSplitInherithedPropsConfig) => {\n const buttonDOMNodeRef = React.useRef<HTMLElement | null>(null);\n // when this component has been wrote\n // =============================================================================\n // MENU BUTTON props are:\n // Required\n // optionsTree, menuSpecificProps\n // Default (we already have a value because props for this hook are already merged with default props)\n // onClickOutside, onOptionClick, openedSubmenus, onSubmenuToggle, isLoading, isSkeleton, selectedOptions\n // Optional (may or may not be present)\n // ItemRenderer\n // =============================================================================\n // Props for the DSMenuBehaviouralContextProvider\n // =============================================================================\n // Required\n // selectedItems, onItemSelected, onActivateItem,\n // Optional\n // onDisplayedSubmenuChange, onOpen, onClose\n\n const {\n options,\n onClickOutside,\n onOptionClick,\n openedSubmenus,\n onSubmenuToggle,\n isLoading,\n isSkeleton,\n selectedOptions,\n ItemRenderer,\n innerRef,\n selectedItems,\n onDisplayedSubmenuChange,\n onItemSelected,\n onActivateItem,\n onOpen,\n onClose,\n ...buttonInheritedProps\n } = propsWithDefault;\n\n // the button is allowed to receive innerRef, but we also need to invoke the setButtonDOMNode to store the button node\n // so we create a functional ref to do both\n const innerRefSnatchingNode: Required<DSMenuButtonT.Props>['innerRef'] = React.useCallback(\n (node: HTMLButtonElement) => {\n buttonDOMNodeRef.current = node;\n if (innerRef) {\n resolveRef(innerRef, node);\n }\n },\n [innerRef],\n );\n const menuSpecificProps = React.useMemo(\n () => ({\n options,\n onClickOutside,\n onOptionClick,\n openedSubmenus,\n onSubmenuToggle,\n isLoading,\n isSkeleton,\n selectedOptions,\n ItemRenderer,\n }),\n [\n options,\n onClickOutside,\n onOptionClick,\n openedSubmenus,\n onSubmenuToggle,\n isLoading,\n isSkeleton,\n selectedOptions,\n ItemRenderer,\n ],\n );\n\n return React.useMemo(\n () => ({\n menuBehaviouralLayerProps: {\n buttonDOMNodeRef,\n selectedItems,\n focusableNodes,\n optionsTree: treeRootNode,\n onDisplayedSubmenuChange,\n onItemSelected,\n onActivateItem,\n onOpen,\n onClose,\n },\n opinionatedButtonProps: {\n ...(buttonInheritedProps as DSMenuButtonT.ButtonInheritedProps),\n innerRef: innerRefSnatchingNode,\n menuSpecificProps,\n },\n }),\n [\n selectedItems,\n focusableNodes,\n treeRootNode,\n onDisplayedSubmenuChange,\n onItemSelected,\n onActivateItem,\n onOpen,\n onClose,\n buttonInheritedProps,\n innerRefSnatchingNode,\n menuSpecificProps,\n ],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADqBvB,mBAAkB;AAElB,wBAA2B;AAOpB,MAAM,0BAA0B,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,MAAqC;AACnC,QAAM,mBAAmB,aAAAA,QAAM,OAA2B,IAAI;AAkB9D,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AAIJ,QAAM,wBAAmE,aAAAA,QAAM;AAAA,IAC7E,CAAC,SAA4B;AAC3B,uBAAiB,UAAU;AAC3B,UAAI,UAAU;AACZ,0CAAW,UAAU,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,oBAAoB,aAAAA,QAAM;AAAA,IAC9B,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,aAAAA,QAAM;AAAA,IACX,OAAO;AAAA,MACL,2BAA2B;AAAA,QACzB;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,wBAAwB;AAAA,QACtB,GAAI;AAAA,QACJ,UAAU;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["/* *******************************************************\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 * this hooks is meant to take all the DSMenuButtonT.InternalProps with default already merged\n * and spit out menuSpecificProps & buttonInheritedProps\n ******************************************************* */\nimport {} from '@elliemae/ds-system';\nimport React from 'react';\nimport { type DSMenuButtonT } from '../react-desc-prop-types.js';\nimport { isSelectionableNode, isObjectAMenuNode } from '../utils/nodesTypeguardsAndGetters.js';\nimport { resolveRef } from '../utils/resolveRef.js';\n\n/**\n * Converts selected options to a map of selected nodes.\n * @param {DSMenuButtonT.SelectionableMenuNodes[]} selectedItems - The selected options, as provided by the user (either items or nodes).\n * @param {DSMenuButtonT.MenuNode} treeRootNode - The root node of the menu tree.\n * @returns {DSMenuButtonT.SelectionableMenuNodes[]} - The map of selected nodes.\n * @throws Will throw an error if a selected option is not found in the tree.\n */\nconst convertSelectedOptionsToNodes = (\n selectedItems: DSMenuButtonT.SelectionableMenuNodes[] | DSMenuButtonT.SelectionableMenuItemInterface[],\n treeRootNode: DSMenuButtonT.MenuNode,\n): DSMenuButtonT.SelectionableMenuNodes[] => {\n const convertedSelection: DSMenuButtonT.SelectionableMenuNodes[] = [];\n\n selectedItems.forEach((selectedItem) => {\n const needsConversion = !isObjectAMenuNode(selectedItem);\n if (!needsConversion) {\n convertedSelection.push(selectedItem);\n return;\n }\n\n const { dsId } = selectedItem;\n const selectedNode = treeRootNode.findNode((node: DSMenuButtonT.MenuNode) => node.dsId === dsId);\n if (!selectedNode) {\n throw new Error(`Selected option with dsId ${dsId} not found in the menu tree.`);\n }\n if (!isSelectionableNode(selectedNode)) {\n // eslint-disable-next-line no-console\n console.warn(`Selected option with dsId ${dsId} is not a selectionable node and will be ignored.`);\n return;\n }\n convertedSelection.push(selectedNode);\n });\n\n return convertedSelection;\n};\n\ntype UseSplitInherithedPropsConfig = {\n propsWithDefault: DSMenuButtonT.InternalProps;\n focusableNodes: DSMenuButtonT.PseudoFocusableMenuNodes[];\n treeRootNode: DSMenuButtonT.MenuNode;\n};\nexport const useSplitInherithedProps = ({\n propsWithDefault,\n focusableNodes,\n treeRootNode,\n}: UseSplitInherithedPropsConfig) => {\n const buttonDOMNodeRef = React.useRef<HTMLElement | null>(null);\n // when this component has been wrote\n // =============================================================================\n // MENU BUTTON props are:\n // Required\n // optionsTree, menuSpecificProps\n // Default (we already have a value because props for this hook are already merged with default props)\n // onClickOutside, onOptionClick, openedSubmenus, onSubmenuToggle, isLoading, isSkeleton, selectedOptions\n // Optional (may or may not be present)\n // ItemRenderer\n // =============================================================================\n // Props for the DSMenuBehaviouralContextProvider\n // =============================================================================\n // Required\n // selectedItems, onItemSelected, onActivateItem,\n // Optional\n // onDisplayedSubmenuChange, onOpen, onClose\n\n const {\n options,\n onClickOutside,\n onOptionClick,\n openedSubmenus,\n onSubmenuToggle,\n isLoading,\n isSkeleton,\n ItemRenderer,\n innerRef,\n selectedItems,\n onDisplayedSubmenuChange,\n onItemSelected,\n onActivateItem,\n onOpen,\n onClose,\n maxHeight, // this is not shared with anything at all, it's instead a property of the \"root\" node, each node (with a submenu) can have its own maxHeight\n ...buttonInheritedProps\n } = propsWithDefault;\n\n // the button is allowed to receive innerRef, but we also need to invoke the setButtonDOMNode to store the button node\n // so we create a functional ref to do both\n const innerRefSnatchingNode: Required<DSMenuButtonT.Props>['innerRef'] = React.useCallback(\n (node: HTMLButtonElement) => {\n buttonDOMNodeRef.current = node;\n if (innerRef) {\n resolveRef(innerRef, node);\n }\n },\n [innerRef],\n );\n // in the WIDGET API, the user can provide selectedItems as an array of \"items\" or an array of \"nodes\"\n // the component needs the \"nodes\" to handle the logic and rendering & accessibility\n // if the user provides \"items\", we convert them to \"nodes\" here\n const selectedNodesMap = React.useMemo(() => {\n if (selectedItems) {\n return convertSelectedOptionsToNodes(selectedItems, treeRootNode);\n }\n return [];\n }, [selectedItems, treeRootNode]);\n\n const menuSpecificProps = React.useMemo(\n () => ({\n options,\n onClickOutside,\n onOptionClick,\n openedSubmenus,\n onSubmenuToggle,\n isLoading,\n isSkeleton,\n ItemRenderer,\n }),\n [options, onClickOutside, onOptionClick, openedSubmenus, onSubmenuToggle, isLoading, isSkeleton, ItemRenderer],\n );\n\n return React.useMemo(\n () => ({\n menuBehaviouralLayerProps: {\n buttonDOMNodeRef,\n selectedNodes: selectedNodesMap,\n focusableNodes,\n optionsTree: treeRootNode,\n onDisplayedSubmenuChange,\n onItemSelected,\n onActivateItem,\n onOpen,\n onClose,\n },\n opinionatedButtonProps: {\n ...(buttonInheritedProps as DSMenuButtonT.ButtonInheritedProps),\n innerRef: innerRefSnatchingNode,\n menuSpecificProps,\n },\n }),\n [\n selectedNodesMap,\n focusableNodes,\n treeRootNode,\n onDisplayedSubmenuChange,\n onItemSelected,\n onActivateItem,\n onOpen,\n onClose,\n buttonInheritedProps,\n innerRefSnatchingNode,\n menuSpecificProps,\n ],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADqBvB,mBAAkB;AAElB,uCAAuD;AACvD,wBAA2B;AAS3B,MAAM,gCAAgC,CACpC,eACA,iBAC2C;AAC3C,QAAM,qBAA6D,CAAC;AAEpE,gBAAc,QAAQ,CAAC,iBAAiB;AACtC,UAAM,kBAAkB,KAAC,oDAAkB,YAAY;AACvD,QAAI,CAAC,iBAAiB;AACpB,yBAAmB,KAAK,YAAY;AACpC;AAAA,IACF;AAEA,UAAM,EAAE,KAAK,IAAI;AACjB,UAAM,eAAe,aAAa,SAAS,CAAC,SAAiC,KAAK,SAAS,IAAI;AAC/F,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI,MAAM,6BAA6B,IAAI,8BAA8B;AAAA,IACjF;AACA,QAAI,KAAC,sDAAoB,YAAY,GAAG;AAEtC,cAAQ,KAAK,6BAA6B,IAAI,mDAAmD;AACjG;AAAA,IACF;AACA,uBAAmB,KAAK,YAAY;AAAA,EACtC,CAAC;AAED,SAAO;AACT;AAOO,MAAM,0BAA0B,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,MAAqC;AACnC,QAAM,mBAAmB,aAAAA,QAAM,OAA2B,IAAI;AAkB9D,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AAIJ,QAAM,wBAAmE,aAAAA,QAAM;AAAA,IAC7E,CAAC,SAA4B;AAC3B,uBAAiB,UAAU;AAC3B,UAAI,UAAU;AACZ,0CAAW,UAAU,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAIA,QAAM,mBAAmB,aAAAA,QAAM,QAAQ,MAAM;AAC3C,QAAI,eAAe;AACjB,aAAO,8BAA8B,eAAe,YAAY;AAAA,IAClE;AACA,WAAO,CAAC;AAAA,EACV,GAAG,CAAC,eAAe,YAAY,CAAC;AAEhC,QAAM,oBAAoB,aAAAA,QAAM;AAAA,IAC9B,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,SAAS,gBAAgB,eAAe,gBAAgB,iBAAiB,WAAW,YAAY,YAAY;AAAA,EAC/G;AAEA,SAAO,aAAAA,QAAM;AAAA,IACX,OAAO;AAAA,MACL,2BAA2B;AAAA,QACzB;AAAA,QACA,eAAe;AAAA,QACf;AAAA,QACA,aAAa;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,wBAAwB;AAAA,QACtB,GAAI;AAAA,QACJ,UAAU;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;",
6
6
  "names": ["React"]
7
7
  }
@@ -39,28 +39,36 @@ var import_ds_grid = require("@elliemae/ds-grid");
39
39
  var import_ds_props_helpers = require("@elliemae/ds-props-helpers");
40
40
  var import_ds_system = require("@elliemae/ds-system");
41
41
  var import_react = __toESM(require("react"));
42
+ var import_react_desc_prop_types = require("../../react-desc-prop-types.js");
42
43
  var import_MenuBehaviouralContextProviderCTX = require("../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js");
43
44
  var import_DSMenuItemRendererFactory = require("../DSMenuItemRendererFactory/index.js");
44
45
  var import_useFlyoutMenu = require("./config/useFlyoutMenu.js");
45
46
  var import_constants = require("./constants/index.js");
46
- var import_react_desc_prop_types = require("./react-desc-prop-types.js");
47
+ var import_react_desc_prop_types2 = require("./react-desc-prop-types.js");
47
48
  var import_nodesTypeguardsAndGetters = require("../../utils/nodesTypeguardsAndGetters.js");
48
- const StyledWrapper = (0, import_ds_system.styled)(import_ds_grid.Grid, { name: import_constants.DSFlyoutMenuName, slot: import_constants.FLYOUT_MENU_SLOTS.ROOT })`
49
- min-width: 150px;
49
+ const StyledWrapper = (0, import_ds_system.styled)(import_ds_grid.Grid, {
50
+ name: import_constants.DSFlyoutMenuName,
51
+ slot: import_constants.FLYOUT_MENU_SLOTS.ROOT
52
+ })`
53
+ min-width: 1px;
50
54
  background-color: white;
51
55
  padding: ${({ theme }) => theme.space.xxxs} 0;
52
56
  ${import_ds_system.xStyledCommonProps}
53
57
  `;
54
58
  const StyledMenu = (0, import_ds_system.styled)("div", { name: import_constants.DSFlyoutMenuName, slot: import_constants.FLYOUT_MENU_SLOTS.LIST_WRAPPER })`
59
+ max-height: ${({ $maxHeight }) => typeof $maxHeight === "number" ? `${$maxHeight}px` : $maxHeight};
60
+ overflow-y: auto;
55
61
  padding: 0;
56
62
  margin: 0;
57
63
  `;
64
+ const NoComponentPlaceholder = () => null;
58
65
  const DSFlyoutMenu = (props) => {
59
66
  const { propsWithDefault, xstyledProps } = (0, import_useFlyoutMenu.useFlyoutMenu)(props);
60
67
  const {
61
68
  instanceUid,
62
69
  globalEventsHelpers: { mainMenuRef, handleSubmenusRefChange }
63
70
  } = import_react.default.useContext(import_MenuBehaviouralContextProviderCTX.MenuBehaviouralContextProviderContext);
71
+ const [didAnimationEnd, setDidAnimationEnd] = import_react.default.useState(false);
64
72
  const { setFloatingRef, floatingStyles, floatingContext, ItemRenderer, isMenuOpen, itemNode } = propsWithDefault;
65
73
  const handleRefChange = import_react.default.useCallback(
66
74
  (node) => {
@@ -72,6 +80,12 @@ const DSFlyoutMenu = (props) => {
72
80
  },
73
81
  [handleSubmenusRefChange, itemNode, mainMenuRef]
74
82
  );
83
+ const handleAnimationStartTrigger = import_react.default.useCallback(() => {
84
+ setDidAnimationEnd(false);
85
+ }, []);
86
+ const handleAnimationEnd = import_react.default.useCallback(() => {
87
+ setDidAnimationEnd(true);
88
+ }, []);
75
89
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
76
90
  import_ds_floating_context.FloatingWrapper,
77
91
  {
@@ -79,19 +93,29 @@ const DSFlyoutMenu = (props) => {
79
93
  floatingStyles,
80
94
  isOpen: isMenuOpen,
81
95
  context: floatingContext,
82
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StyledWrapper, { getOwnerProps: () => propsWithDefault, getOwnerPropsArguments: () => ({}), ...xstyledProps, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StyledMenu, { role: "menu", innerRef: handleRefChange, children: itemNode.children.map((optionNode) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
83
- import_DSMenuItemRendererFactory.DSMenuItemRendererFactory,
96
+ onAnimationStartTriggered: handleAnimationStartTrigger,
97
+ onAnimationEnd: handleAnimationEnd,
98
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StyledWrapper, { getOwnerProps: () => propsWithDefault, getOwnerPropsArguments: () => ({}), ...xstyledProps, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
99
+ StyledMenu,
84
100
  {
85
- itemNode: optionNode,
86
- ItemRenderer,
87
- FlyoutMenuCircularDepInject: DSFlyoutMenu
88
- },
89
- `flyout-menu-item-${optionNode.dsId}-${instanceUid}`
90
- )) }) })
101
+ role: "menu",
102
+ innerRef: handleRefChange,
103
+ $maxHeight: itemNode.plainItem.maxHeight ?? import_react_desc_prop_types.menuSpecificDefaultProps.maxHeight,
104
+ children: itemNode.children.map((optionNode) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
105
+ import_DSMenuItemRendererFactory.DSMenuItemRendererFactory,
106
+ {
107
+ itemNode: optionNode,
108
+ ItemRenderer,
109
+ FlyoutMenuCircularDepInject: didAnimationEnd ? DSFlyoutMenu : NoComponentPlaceholder
110
+ },
111
+ `flyout-menu-item-${optionNode.dsId}-${instanceUid}`
112
+ ))
113
+ }
114
+ ) })
91
115
  }
92
116
  );
93
117
  };
94
118
  DSFlyoutMenu.displayName = import_constants.DSFlyoutMenuName;
95
119
  const DSFlyoutMenuWithSchema = (0, import_ds_props_helpers.describe)(DSFlyoutMenu);
96
- DSFlyoutMenuWithSchema.propTypes = import_react_desc_prop_types.DSFlyoutMenuPropTypesSchema;
120
+ DSFlyoutMenuWithSchema.propTypes = import_react_desc_prop_types2.DSFlyoutMenuPropTypesSchema;
97
121
  //# sourceMappingURL=DSFlyoutMenu.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/parts/DSFlyoutMenu/DSFlyoutMenu.tsx", "../../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import { FloatingWrapper } from '@elliemae/ds-floating-context';\nimport { Grid } from '@elliemae/ds-grid';\nimport { describe } from '@elliemae/ds-props-helpers';\nimport { styled, xStyledCommonProps } from '@elliemae/ds-system';\nimport React from 'react';\nimport type { DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { MenuBehaviouralContextProviderContext } from '../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js';\nimport { DSMenuItemRendererFactory } from '../DSMenuItemRendererFactory/index.js';\nimport { useFlyoutMenu } from './config/useFlyoutMenu.js';\nimport { DSFlyoutMenuName, FLYOUT_MENU_SLOTS } from './constants/index.js';\nimport { DSFlyoutMenuPropTypesSchema, type DSFlyoutMenuT } from './react-desc-prop-types.js';\nimport { isRootNode } from '../../utils/nodesTypeguardsAndGetters.js';\n\nconst StyledWrapper = styled(Grid, { name: DSFlyoutMenuName, slot: FLYOUT_MENU_SLOTS.ROOT })`\n min-width: 150px;\n background-color: white;\n padding: ${({ theme }) => theme.space.xxxs} 0;\n ${xStyledCommonProps}\n`;\n\nconst StyledMenu = styled('div', { name: DSFlyoutMenuName, slot: FLYOUT_MENU_SLOTS.LIST_WRAPPER })`\n padding: 0;\n margin: 0;\n`;\n\nconst DSFlyoutMenu: React.ComponentType<DSFlyoutMenuT.Props> = (props) => {\n const { propsWithDefault, xstyledProps } = useFlyoutMenu(props);\n const {\n instanceUid,\n globalEventsHelpers: { mainMenuRef, handleSubmenusRefChange },\n } = React.useContext(MenuBehaviouralContextProviderContext);\n\n const { setFloatingRef, floatingStyles, floatingContext, ItemRenderer, isMenuOpen, itemNode } = propsWithDefault;\n\n const handleRefChange = React.useCallback(\n (node: HTMLDivElement) => {\n if (isRootNode(itemNode)) {\n mainMenuRef.current = node;\n return;\n }\n handleSubmenusRefChange(node, itemNode.dsId);\n },\n [handleSubmenusRefChange, itemNode, mainMenuRef],\n );\n\n return (\n <FloatingWrapper\n innerRef={setFloatingRef}\n floatingStyles={floatingStyles}\n isOpen={isMenuOpen}\n context={floatingContext}\n >\n <StyledWrapper getOwnerProps={() => propsWithDefault} getOwnerPropsArguments={() => ({})} {...xstyledProps}>\n <StyledMenu role=\"menu\" innerRef={handleRefChange}>\n {itemNode.children.map((optionNode) => (\n <DSMenuItemRendererFactory\n key={`flyout-menu-item-${optionNode.dsId}-${instanceUid}`}\n // DSTree doesn't support children having a polymorphic type, so we need to cast it manually\n itemNode={optionNode as DSMenuButtonT.MenuNode}\n ItemRenderer={ItemRenderer}\n // we are passing the DSFlyoutMenu component as a prop to the DSMenuItemRendererFactory\n // this solves the circular-ish dependency\n FlyoutMenuCircularDepInject={DSFlyoutMenu}\n />\n ))}\n </StyledMenu>\n </StyledWrapper>\n </FloatingWrapper>\n );\n};\n\nDSFlyoutMenu.displayName = DSFlyoutMenuName;\nconst DSFlyoutMenuWithSchema = describe(DSFlyoutMenu);\nDSFlyoutMenuWithSchema.propTypes = DSFlyoutMenuPropTypesSchema;\n\nexport { DSFlyoutMenu, DSFlyoutMenuWithSchema };\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADuDX;AAvDZ,iCAAgC;AAChC,qBAAqB;AACrB,8BAAyB;AACzB,uBAA2C;AAC3C,mBAAkB;AAElB,+CAAsD;AACtD,uCAA0C;AAC1C,2BAA8B;AAC9B,uBAAoD;AACpD,mCAAgE;AAChE,uCAA2B;AAE3B,MAAM,oBAAgB,yBAAO,qBAAM,EAAE,MAAM,mCAAkB,MAAM,mCAAkB,KAAK,CAAC;AAAA;AAAA;AAAA,aAG9E,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,IAAI;AAAA,IACxC,mCAAkB;AAAA;AAGtB,MAAM,iBAAa,yBAAO,OAAO,EAAE,MAAM,mCAAkB,MAAM,mCAAkB,aAAa,CAAC;AAAA;AAAA;AAAA;AAKjG,MAAM,eAAyD,CAAC,UAAU;AACxE,QAAM,EAAE,kBAAkB,aAAa,QAAI,oCAAc,KAAK;AAC9D,QAAM;AAAA,IACJ;AAAA,IACA,qBAAqB,EAAE,aAAa,wBAAwB;AAAA,EAC9D,IAAI,aAAAA,QAAM,WAAW,8EAAqC;AAE1D,QAAM,EAAE,gBAAgB,gBAAgB,iBAAiB,cAAc,YAAY,SAAS,IAAI;AAEhG,QAAM,kBAAkB,aAAAA,QAAM;AAAA,IAC5B,CAAC,SAAyB;AACxB,cAAI,6CAAW,QAAQ,GAAG;AACxB,oBAAY,UAAU;AACtB;AAAA,MACF;AACA,8BAAwB,MAAM,SAAS,IAAI;AAAA,IAC7C;AAAA,IACA,CAAC,yBAAyB,UAAU,WAAW;AAAA,EACjD;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,MAET,sDAAC,iBAAc,eAAe,MAAM,kBAAkB,wBAAwB,OAAO,CAAC,IAAK,GAAG,cAC5F,sDAAC,cAAW,MAAK,QAAO,UAAU,iBAC/B,mBAAS,SAAS,IAAI,CAAC,eACtB;AAAA,QAAC;AAAA;AAAA,UAGC,UAAU;AAAA,UACV;AAAA,UAGA,6BAA6B;AAAA;AAAA,QANxB,oBAAoB,WAAW,IAAI,IAAI,WAAW;AAAA,MAOzD,CACD,GACH,GACF;AAAA;AAAA,EACF;AAEJ;AAEA,aAAa,cAAc;AAC3B,MAAM,6BAAyB,kCAAS,YAAY;AACpD,uBAAuB,YAAY;",
6
- "names": ["React"]
4
+ "sourcesContent": ["import { FloatingWrapper } from '@elliemae/ds-floating-context';\nimport { Grid } from '@elliemae/ds-grid';\nimport { describe } from '@elliemae/ds-props-helpers';\nimport { styled, xStyledCommonProps } from '@elliemae/ds-system';\nimport React from 'react';\nimport { type DSMenuButtonT, menuSpecificDefaultProps } from '../../react-desc-prop-types.js';\nimport { MenuBehaviouralContextProviderContext } from '../DSMenuBehaviouralContextProvider/MenuBehaviouralContextProviderCTX.js';\nimport { DSMenuItemRendererFactory } from '../DSMenuItemRendererFactory/index.js';\nimport { useFlyoutMenu } from './config/useFlyoutMenu.js';\nimport { DSFlyoutMenuName, FLYOUT_MENU_SLOTS } from './constants/index.js';\nimport { DSFlyoutMenuPropTypesSchema, type DSFlyoutMenuT } from './react-desc-prop-types.js';\nimport { isRootNode } from '../../utils/nodesTypeguardsAndGetters.js';\n\nconst StyledWrapper = styled(Grid, {\n name: DSFlyoutMenuName,\n slot: FLYOUT_MENU_SLOTS.ROOT,\n})`\n min-width: 1px;\n background-color: white;\n padding: ${({ theme }) => theme.space.xxxs} 0;\n ${xStyledCommonProps}\n`;\n\nconst StyledMenu = styled('div', { name: DSFlyoutMenuName, slot: FLYOUT_MENU_SLOTS.LIST_WRAPPER })<{\n $maxHeight: string | number;\n}>`\n max-height: ${({ $maxHeight }) => (typeof $maxHeight === 'number' ? `${$maxHeight}px` : $maxHeight)};\n overflow-y: auto;\n padding: 0;\n margin: 0;\n`;\n\nconst NoComponentPlaceholder = () => null;\n\nconst DSFlyoutMenu: React.ComponentType<DSFlyoutMenuT.Props> = (props) => {\n const { propsWithDefault, xstyledProps } = useFlyoutMenu(props);\n const {\n instanceUid,\n globalEventsHelpers: { mainMenuRef, handleSubmenusRefChange },\n } = React.useContext(MenuBehaviouralContextProviderContext);\n const [didAnimationEnd, setDidAnimationEnd] = React.useState(false);\n\n const { setFloatingRef, floatingStyles, floatingContext, ItemRenderer, isMenuOpen, itemNode } = propsWithDefault;\n\n const handleRefChange = React.useCallback(\n (node: HTMLDivElement) => {\n if (isRootNode(itemNode)) {\n mainMenuRef.current = node;\n return;\n }\n handleSubmenusRefChange(node, itemNode.dsId);\n },\n [handleSubmenusRefChange, itemNode, mainMenuRef],\n );\n\n const handleAnimationStartTrigger = React.useCallback(() => {\n setDidAnimationEnd(false);\n }, []);\n const handleAnimationEnd = React.useCallback(() => {\n setDidAnimationEnd(true);\n }, []);\n\n return (\n <FloatingWrapper\n innerRef={setFloatingRef}\n floatingStyles={floatingStyles}\n isOpen={isMenuOpen}\n context={floatingContext}\n onAnimationStartTriggered={handleAnimationStartTrigger}\n onAnimationEnd={handleAnimationEnd}\n >\n <StyledWrapper getOwnerProps={() => propsWithDefault} getOwnerPropsArguments={() => ({})} {...xstyledProps}>\n <StyledMenu\n role=\"menu\"\n innerRef={handleRefChange}\n $maxHeight={itemNode.plainItem.maxHeight ?? menuSpecificDefaultProps.maxHeight}\n >\n {itemNode.children.map((optionNode) => (\n <DSMenuItemRendererFactory\n key={`flyout-menu-item-${optionNode.dsId}-${instanceUid}`}\n // DSTree doesn't support children having a polymorphic type, so we need to cast it manually\n itemNode={optionNode as DSMenuButtonT.MenuNode}\n ItemRenderer={ItemRenderer}\n // we are passing the DSFlyoutMenu component as a prop to the DSMenuItemRendererFactory\n // this solves the circular-ish dependency\n // the conditional `didAnimationEnd` solves the visual artefact of nested FloatingWrapper wrongly positioned due to animation\n FlyoutMenuCircularDepInject={didAnimationEnd ? DSFlyoutMenu : NoComponentPlaceholder}\n />\n ))}\n </StyledMenu>\n </StyledWrapper>\n </FloatingWrapper>\n );\n};\n\nDSFlyoutMenu.displayName = DSFlyoutMenuName;\nconst DSFlyoutMenuWithSchema = describe(DSFlyoutMenu);\nDSFlyoutMenuWithSchema.propTypes = DSFlyoutMenuPropTypesSchema;\n\nexport { DSFlyoutMenu, DSFlyoutMenuWithSchema };\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;AD8EX;AA9EZ,iCAAgC;AAChC,qBAAqB;AACrB,8BAAyB;AACzB,uBAA2C;AAC3C,mBAAkB;AAClB,mCAA6D;AAC7D,+CAAsD;AACtD,uCAA0C;AAC1C,2BAA8B;AAC9B,uBAAoD;AACpD,IAAAA,gCAAgE;AAChE,uCAA2B;AAE3B,MAAM,oBAAgB,yBAAO,qBAAM;AAAA,EACjC,MAAM;AAAA,EACN,MAAM,mCAAkB;AAC1B,CAAC;AAAA;AAAA;AAAA,aAGY,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,IAAI;AAAA,IACxC,mCAAkB;AAAA;AAGtB,MAAM,iBAAa,yBAAO,OAAO,EAAE,MAAM,mCAAkB,MAAM,mCAAkB,aAAa,CAAC;AAAA,gBAGjF,CAAC,EAAE,WAAW,MAAO,OAAO,eAAe,WAAW,GAAG,UAAU,OAAO,UAAW;AAAA;AAAA;AAAA;AAAA;AAMrG,MAAM,yBAAyB,MAAM;AAErC,MAAM,eAAyD,CAAC,UAAU;AACxE,QAAM,EAAE,kBAAkB,aAAa,QAAI,oCAAc,KAAK;AAC9D,QAAM;AAAA,IACJ;AAAA,IACA,qBAAqB,EAAE,aAAa,wBAAwB;AAAA,EAC9D,IAAI,aAAAC,QAAM,WAAW,8EAAqC;AAC1D,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,aAAAA,QAAM,SAAS,KAAK;AAElE,QAAM,EAAE,gBAAgB,gBAAgB,iBAAiB,cAAc,YAAY,SAAS,IAAI;AAEhG,QAAM,kBAAkB,aAAAA,QAAM;AAAA,IAC5B,CAAC,SAAyB;AACxB,cAAI,6CAAW,QAAQ,GAAG;AACxB,oBAAY,UAAU;AACtB;AAAA,MACF;AACA,8BAAwB,MAAM,SAAS,IAAI;AAAA,IAC7C;AAAA,IACA,CAAC,yBAAyB,UAAU,WAAW;AAAA,EACjD;AAEA,QAAM,8BAA8B,aAAAA,QAAM,YAAY,MAAM;AAC1D,uBAAmB,KAAK;AAAA,EAC1B,GAAG,CAAC,CAAC;AACL,QAAM,qBAAqB,aAAAA,QAAM,YAAY,MAAM;AACjD,uBAAmB,IAAI;AAAA,EACzB,GAAG,CAAC,CAAC;AAEL,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,2BAA2B;AAAA,MAC3B,gBAAgB;AAAA,MAEhB,sDAAC,iBAAc,eAAe,MAAM,kBAAkB,wBAAwB,OAAO,CAAC,IAAK,GAAG,cAC5F;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU;AAAA,UACV,YAAY,SAAS,UAAU,aAAa,sDAAyB;AAAA,UAEpE,mBAAS,SAAS,IAAI,CAAC,eACtB;AAAA,YAAC;AAAA;AAAA,cAGC,UAAU;AAAA,cACV;AAAA,cAIA,6BAA6B,kBAAkB,eAAe;AAAA;AAAA,YAPzD,oBAAoB,WAAW,IAAI,IAAI,WAAW;AAAA,UAQzD,CACD;AAAA;AAAA,MACH,GACF;AAAA;AAAA,EACF;AAEJ;AAEA,aAAa,cAAc;AAC3B,MAAM,6BAAyB,kCAAS,YAAY;AACpD,uBAAuB,YAAY;",
6
+ "names": ["import_react_desc_prop_types", "React"]
7
7
  }
@@ -37,7 +37,7 @@ var React = __toESM(require("react"));
37
37
  var import_ds_props_helpers = require("@elliemae/ds-props-helpers");
38
38
  var import_react_desc_prop_types = require("../../react-desc-prop-types.js");
39
39
  var import_constants = require("./constants/index.js");
40
- const defaultProps = { ...import_react_desc_prop_types.defaultProps };
40
+ const defaultProps = { ...import_react_desc_prop_types.menuSpecificDefaultProps };
41
41
  const DSFlyoutMenuPropTypes = {
42
42
  itemNode: import_ds_props_helpers.PropTypes.object.description("The parent menu node to render the menu from").isRequired,
43
43
  setFloatingRef: import_ds_props_helpers.PropTypes.func.description(
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/parts/DSFlyoutMenu/react-desc-prop-types.ts", "../../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { 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 { type useFloatingContext } from '@elliemae/ds-floating-context';\nimport {\n DSMenuSpecificPropTypes,\n defaultProps as menuSpecificDefaultProps,\n type DSMenuButtonT,\n} from '../../react-desc-prop-types.js';\nimport { DSFlyoutMenuName, FLYOUT_MENU_SLOTS } from './constants/index.js';\n\nexport declare namespace DSFlyoutMenuT {\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.MenuSpecificRequiredProps {\n isMenuOpen: boolean;\n itemNode:\n | DSMenuButtonT.MenuNodeWithSubmenuItem\n | DSMenuButtonT.MenuNodeSingleSelectWithSubmenuItem\n | DSMenuButtonT.MenuNodeMultipleSelectWithSubmenuItem\n | DSMenuButtonT.MenuNodeActivableWithSubmenuItem\n | DSMenuButtonT.MenuNodeRootItem;\n setFloatingRef: ReturnType<typeof useFloatingContext>['refs']['setFloating'];\n floatingStyles: ReturnType<typeof useFloatingContext>['floatingStyles'];\n floatingContext: ReturnType<typeof useFloatingContext>['context'];\n }\n\n export interface DefaultProps extends DSMenuButtonT.MenuSpecifiDefaultProps {}\n\n export interface OptionalProps\n extends TypescriptHelpersT.PropsForGlobalOnSlots<typeof DSFlyoutMenuName, typeof FLYOUT_MENU_SLOTS>,\n DSMenuButtonT.MenuSpecificOptionalProps {}\n\n export interface Props extends RequiredProps, Partial<DefaultProps>, OptionalProps {}\n\n export interface InternalProps extends RequiredProps, DefaultProps, OptionalProps {}\n}\n\nexport const defaultProps: DSFlyoutMenuT.DefaultProps = { ...menuSpecificDefaultProps };\n\nexport const DSFlyoutMenuPropTypes: DSPropTypesSchema<DSFlyoutMenuT.Props> = {\n itemNode: PropTypes.object.description('The parent menu node to render the menu from').isRequired,\n setFloatingRef: PropTypes.func.description(\n 'The function to set the ref of the floating element (from useFloatingContext.refs.setFloating)',\n ).isRequired,\n floatingStyles: PropTypes.object.description(\n 'The styles to apply to the floating element to correctly position it (from useFloatingContext.floatingStyles)',\n ).isRequired,\n floatingContext: PropTypes.object.description(\n 'The context object from useFloatingContext, used to allow FloatingWrapper correct functionality',\n ).isRequired,\n // anchorNode: PropTypes.instanceOf(HTMLElement).isRequired,\n isMenuOpen: PropTypes.bool.description('Wheter or not this particular instance of the flyout menu is open')\n .isRequired,\n ...getPropsPerSlotPropTypes(DSFlyoutMenuName, FLYOUT_MENU_SLOTS),\n ...globalAttributesPropTypes,\n // this component is meant to be used from a ds-menu-button compliant API,\n // for this reason we want to inherit the DSMenuButton props interface that relates to the menu and not the button...\n ...DSMenuSpecificPropTypes,\n ...xstyledPropTypes,\n};\n\nexport const DSFlyoutMenuPropTypesSchema = DSFlyoutMenuPropTypes as unknown as ValidationMap<DSFlyoutMenuT.Props>;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADEvB,8BAKO;AAGP,mCAIO;AACP,uBAAoD;AAkC7C,MAAM,eAA2C,EAAE,GAAG,6BAAAA,aAAyB;AAE/E,MAAM,wBAAgE;AAAA,EAC3E,UAAU,kCAAU,OAAO,YAAY,8CAA8C,EAAE;AAAA,EACvF,gBAAgB,kCAAU,KAAK;AAAA,IAC7B;AAAA,EACF,EAAE;AAAA,EACF,gBAAgB,kCAAU,OAAO;AAAA,IAC/B;AAAA,EACF,EAAE;AAAA,EACF,iBAAiB,kCAAU,OAAO;AAAA,IAChC;AAAA,EACF,EAAE;AAAA;AAAA,EAEF,YAAY,kCAAU,KAAK,YAAY,mEAAmE,EACvG;AAAA,EACH,OAAG,kDAAyB,mCAAkB,kCAAiB;AAAA,EAC/D,GAAG;AAAA;AAAA;AAAA,EAGH,GAAG;AAAA,EACH,GAAG;AACL;AAEO,MAAM,8BAA8B;",
6
- "names": ["menuSpecificDefaultProps"]
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-empty-interface */\nimport { type useFloatingContext } from '@elliemae/ds-floating-context';\nimport type { 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 { DSMenuSpecificPropTypes, menuSpecificDefaultProps, type DSMenuButtonT } from '../../react-desc-prop-types.js';\nimport { DSFlyoutMenuName, FLYOUT_MENU_SLOTS } from './constants/index.js';\n\nexport declare namespace DSFlyoutMenuT {\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.MenuSpecificRequiredProps {\n isMenuOpen: boolean;\n itemNode:\n | DSMenuButtonT.MenuNodeWithSubmenuItem\n | DSMenuButtonT.MenuNodeSingleSelectWithSubmenuItem\n | DSMenuButtonT.MenuNodeMultipleSelectWithSubmenuItem\n | DSMenuButtonT.MenuNodeActivableWithSubmenuItem\n | DSMenuButtonT.MenuNodeRootItem;\n setFloatingRef: ReturnType<typeof useFloatingContext>['refs']['setFloating'];\n floatingStyles: ReturnType<typeof useFloatingContext>['floatingStyles'];\n floatingContext: ReturnType<typeof useFloatingContext>['context'];\n }\n\n export interface DefaultProps extends DSMenuButtonT.MenuSpecifiDefaultProps {}\n\n export interface OptionalProps\n extends TypescriptHelpersT.PropsForGlobalOnSlots<typeof DSFlyoutMenuName, typeof FLYOUT_MENU_SLOTS>,\n DSMenuButtonT.MenuSpecificOptionalProps {}\n\n export interface Props extends RequiredProps, Partial<DefaultProps>, OptionalProps {}\n\n export interface InternalProps extends RequiredProps, DefaultProps, OptionalProps {}\n}\n\nexport const defaultProps: DSFlyoutMenuT.DefaultProps = { ...menuSpecificDefaultProps };\n\nexport const DSFlyoutMenuPropTypes: DSPropTypesSchema<DSFlyoutMenuT.Props> = {\n itemNode: PropTypes.object.description('The parent menu node to render the menu from').isRequired,\n setFloatingRef: PropTypes.func.description(\n 'The function to set the ref of the floating element (from useFloatingContext.refs.setFloating)',\n ).isRequired,\n floatingStyles: PropTypes.object.description(\n 'The styles to apply to the floating element to correctly position it (from useFloatingContext.floatingStyles)',\n ).isRequired,\n floatingContext: PropTypes.object.description(\n 'The context object from useFloatingContext, used to allow FloatingWrapper correct functionality',\n ).isRequired,\n // anchorNode: PropTypes.instanceOf(HTMLElement).isRequired,\n isMenuOpen: PropTypes.bool.description('Wheter or not this particular instance of the flyout menu is open')\n .isRequired,\n ...getPropsPerSlotPropTypes(DSFlyoutMenuName, FLYOUT_MENU_SLOTS),\n ...globalAttributesPropTypes,\n // this component is meant to be used from a ds-menu-button compliant API,\n // for this reason we want to inherit the DSMenuButton props interface that relates to the menu and not the button...\n ...DSMenuSpecificPropTypes,\n ...xstyledPropTypes,\n};\n\nexport const DSFlyoutMenuPropTypesSchema = DSFlyoutMenuPropTypes as unknown as ValidationMap<DSFlyoutMenuT.Props>;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADGvB,8BAKO;AAEP,mCAAsF;AACtF,uBAAoD;AAkC7C,MAAM,eAA2C,EAAE,GAAG,sDAAyB;AAE/E,MAAM,wBAAgE;AAAA,EAC3E,UAAU,kCAAU,OAAO,YAAY,8CAA8C,EAAE;AAAA,EACvF,gBAAgB,kCAAU,KAAK;AAAA,IAC7B;AAAA,EACF,EAAE;AAAA,EACF,gBAAgB,kCAAU,OAAO;AAAA,IAC/B;AAAA,EACF,EAAE;AAAA,EACF,iBAAiB,kCAAU,OAAO;AAAA,IAChC;AAAA,EACF,EAAE;AAAA;AAAA,EAEF,YAAY,kCAAU,KAAK,YAAY,mEAAmE,EACvG;AAAA,EACH,OAAG,kDAAyB,mCAAkB,kCAAiB;AAAA,EAC/D,GAAG;AAAA;AAAA;AAAA,EAGH,GAAG;AAAA,EACH,GAAG;AACL;AAEO,MAAM,8BAA8B;",
6
+ "names": []
7
7
  }
@@ -35,7 +35,7 @@ var React = __toESM(require("react"));
35
35
  var import_react = require("react");
36
36
  var import_nodesTypeguardsAndGetters = require("../../../utils/nodesTypeguardsAndGetters.js");
37
37
  const useAdvancedValidation = ({ propsWithDefault }) => {
38
- const { onActivateItem, onItemSelected, selectedItems, optionsTree } = propsWithDefault;
38
+ const { onActivateItem, onItemSelected, selectedNodes, optionsTree } = propsWithDefault;
39
39
  (0, import_react.useEffect)(() => {
40
40
  const allNodes = optionsTree.flatten();
41
41
  const nodesByDsId = {};
@@ -76,11 +76,11 @@ The dsId must be unique.`
76
76
  "DSMenuButton:\nSome items are activable, but onActivateItem is not provided.\n\nYou must provide onActivateItem to handle activation."
77
77
  );
78
78
  }
79
- if (hasSelection && (!onItemSelected || !selectedItems)) {
79
+ if (hasSelection && (!onItemSelected || !selectedNodes)) {
80
80
  throw new Error(
81
- "DSMenuButton:\nSome items are selectionable, but onItemSelected or selectedItems are not provided.\n\nYou must provide onItemSelected and selectedItems to handle selection."
81
+ "DSMenuButton:\nSome items are selectionable, but onItemSelected or selectedNodes are not provided.\n\nYou must provide onItemSelected and selectedNodes to handle selection."
82
82
  );
83
83
  }
84
- }, [onActivateItem, onItemSelected, selectedItems, optionsTree]);
84
+ }, [onActivateItem, onItemSelected, selectedNodes, optionsTree]);
85
85
  };
86
86
  //# sourceMappingURL=useAdvancedValidation.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/parts/DSMenuBehaviouralContextProvider/config/useAdvancedValidation.ts", "../../../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import { useEffect } from 'react';\nimport { type DSMenuButtonT } from '../../../react-desc-prop-types.js';\nimport { type DSMenuBehaviouralContextProviderT } from '../react-desc-prop-types.js';\nimport { isActivableNode, isSelectionableNode } from '../../../utils/nodesTypeguardsAndGetters.js';\n\ntype UseAdvancedValidationConfigT = {\n propsWithDefault: DSMenuBehaviouralContextProviderT.InternalProps;\n};\nexport const useAdvancedValidation = ({ propsWithDefault }: UseAdvancedValidationConfigT): void => {\n const { onActivateItem, onItemSelected, selectedItems, optionsTree } = propsWithDefault;\n // =============================================================================\n // SPECIAL VALIDATIONS\n // =============================================================================\n // We iterate onces, validate everything in one go for performance reasons\n // =============================================================================\n // - No repeated dsId\n // (only validating focusableNodes may work, but to avoid complexity we validate the whole tree)\n // - if any item is \"selectionable\", selection IoC props must be provided\n // - if any item is \"activable\", activation IoC props must be provided\n // =============================================================================\n // we want to validate only when dependencies change, should improve performance if app is using memoization\n // and be virtually a free overhead if the app is not using memoization\n // =============================================================================\n useEffect(() => {\n const allNodes = optionsTree.flatten();\n const nodesByDsId: { [key: DSMenuButtonT.MenuNode['dsId']]: DSMenuButtonT.MenuNode[] } = {};\n const duplicatedIdsNodes: { [key: DSMenuButtonT.MenuNode['dsId']]: DSMenuButtonT.MenuNode[] } = {};\n let hasActivation = false;\n let hasSelection = false;\n let hasDuplicateDsId = false;\n allNodes.forEach((node) => {\n const { dsId } = node;\n if (!Array.isArray(nodesByDsId[dsId])) {\n nodesByDsId[dsId] = [node];\n } else {\n nodesByDsId[dsId].push(node);\n hasDuplicateDsId = true;\n duplicatedIdsNodes[dsId] = nodesByDsId[dsId];\n }\n\n if (isActivableNode(node)) {\n hasActivation = true;\n }\n if (isSelectionableNode(node)) {\n hasSelection = true;\n }\n });\n if (hasDuplicateDsId) {\n // eslint-disable-next-line no-console\n console.log('duplicatedIdsNodes', duplicatedIdsNodes);\n throw new Error(\n `DSMenuButton:\\nThe following dsId are repeated:\\n${Object.keys(duplicatedIdsNodes).join(\n '\\n',\n )}\\n\\nThe dsId must be unique.`,\n );\n }\n if (hasActivation && !onActivateItem) {\n throw new Error(\n 'DSMenuButton:\\nSome items are activable, but onActivateItem is not provided.\\n\\nYou must provide onActivateItem to handle activation.',\n );\n }\n if (hasSelection && (!onItemSelected || !selectedItems)) {\n throw new Error(\n 'DSMenuButton:\\nSome items are selectionable, but onItemSelected or selectedItems are not provided.\\n\\nYou must provide onItemSelected and selectedItems to handle selection.',\n );\n }\n }, [onActivateItem, onItemSelected, selectedItems, optionsTree]);\n};\n", "import * as React from 'react';\nexport { React };\n"],
4
+ "sourcesContent": ["import { useEffect } from 'react';\nimport { type DSMenuButtonT } from '../../../react-desc-prop-types.js';\nimport { type DSMenuBehaviouralContextProviderT } from '../react-desc-prop-types.js';\nimport { isActivableNode, isSelectionableNode } from '../../../utils/nodesTypeguardsAndGetters.js';\n\ntype UseAdvancedValidationConfigT = {\n propsWithDefault: DSMenuBehaviouralContextProviderT.InternalProps;\n};\nexport const useAdvancedValidation = ({ propsWithDefault }: UseAdvancedValidationConfigT): void => {\n const { onActivateItem, onItemSelected, selectedNodes, optionsTree } = propsWithDefault;\n // =============================================================================\n // SPECIAL VALIDATIONS\n // =============================================================================\n // We iterate onces, validate everything in one go for performance reasons\n // =============================================================================\n // - No repeated dsId\n // (only validating focusableNodes may work, but to avoid complexity we validate the whole tree)\n // - if any item is \"selectionable\", selection IoC props must be provided\n // - if any item is \"activable\", activation IoC props must be provided\n // =============================================================================\n // we want to validate only when dependencies change, should improve performance if app is using memoization\n // and be virtually a free overhead if the app is not using memoization\n // =============================================================================\n useEffect(() => {\n const allNodes = optionsTree.flatten();\n const nodesByDsId: { [key: DSMenuButtonT.MenuNode['dsId']]: DSMenuButtonT.MenuNode[] } = {};\n const duplicatedIdsNodes: { [key: DSMenuButtonT.MenuNode['dsId']]: DSMenuButtonT.MenuNode[] } = {};\n let hasActivation = false;\n let hasSelection = false;\n let hasDuplicateDsId = false;\n allNodes.forEach((node) => {\n const { dsId } = node;\n if (!Array.isArray(nodesByDsId[dsId])) {\n nodesByDsId[dsId] = [node];\n } else {\n nodesByDsId[dsId].push(node);\n hasDuplicateDsId = true;\n duplicatedIdsNodes[dsId] = nodesByDsId[dsId];\n }\n\n if (isActivableNode(node)) {\n hasActivation = true;\n }\n if (isSelectionableNode(node)) {\n hasSelection = true;\n }\n });\n if (hasDuplicateDsId) {\n // eslint-disable-next-line no-console\n console.log('duplicatedIdsNodes', duplicatedIdsNodes);\n throw new Error(\n `DSMenuButton:\\nThe following dsId are repeated:\\n${Object.keys(duplicatedIdsNodes).join(\n '\\n',\n )}\\n\\nThe dsId must be unique.`,\n );\n }\n if (hasActivation && !onActivateItem) {\n throw new Error(\n 'DSMenuButton:\\nSome items are activable, but onActivateItem is not provided.\\n\\nYou must provide onActivateItem to handle activation.',\n );\n }\n if (hasSelection && (!onItemSelected || !selectedNodes)) {\n throw new Error(\n 'DSMenuButton:\\nSome items are selectionable, but onItemSelected or selectedNodes are not provided.\\n\\nYou must provide onItemSelected and selectedNodes to handle selection.',\n );\n }\n }, [onActivateItem, onItemSelected, selectedNodes, optionsTree]);\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAA0B;AAG1B,uCAAqD;AAK9C,MAAM,wBAAwB,CAAC,EAAE,iBAAiB,MAA0C;AACjG,QAAM,EAAE,gBAAgB,gBAAgB,eAAe,YAAY,IAAI;AAcvE,8BAAU,MAAM;AACd,UAAM,WAAW,YAAY,QAAQ;AACrC,UAAM,cAAmF,CAAC;AAC1F,UAAM,qBAA0F,CAAC;AACjG,QAAI,gBAAgB;AACpB,QAAI,eAAe;AACnB,QAAI,mBAAmB;AACvB,aAAS,QAAQ,CAAC,SAAS;AACzB,YAAM,EAAE,KAAK,IAAI;AACjB,UAAI,CAAC,MAAM,QAAQ,YAAY,IAAI,CAAC,GAAG;AACrC,oBAAY,IAAI,IAAI,CAAC,IAAI;AAAA,MAC3B,OAAO;AACL,oBAAY,IAAI,EAAE,KAAK,IAAI;AAC3B,2BAAmB;AACnB,2BAAmB,IAAI,IAAI,YAAY,IAAI;AAAA,MAC7C;AAEA,cAAI,kDAAgB,IAAI,GAAG;AACzB,wBAAgB;AAAA,MAClB;AACA,cAAI,sDAAoB,IAAI,GAAG;AAC7B,uBAAe;AAAA,MACjB;AAAA,IACF,CAAC;AACD,QAAI,kBAAkB;AAEpB,cAAQ,IAAI,sBAAsB,kBAAkB;AACpD,YAAM,IAAI;AAAA,QACR;AAAA;AAAA,EAAoD,OAAO,KAAK,kBAAkB,EAAE;AAAA,UAClF;AAAA,QACF,CAAC;AAAA;AAAA;AAAA,MACH;AAAA,IACF;AACA,QAAI,iBAAiB,CAAC,gBAAgB;AACpC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,QAAI,iBAAiB,CAAC,kBAAkB,CAAC,gBAAgB;AACvD,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,gBAAgB,gBAAgB,eAAe,WAAW,CAAC;AACjE;",
6
6
  "names": []
7
7
  }
@@ -32,6 +32,7 @@ __export(useFocusTracker_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(useFocusTracker_exports);
34
34
  var React = __toESM(require("react"));
35
+ var import_lodash = require("lodash");
35
36
  var import_react = __toESM(require("react"));
36
37
  var import_nodesTypeguardsAndGetters = require("../../../utils/nodesTypeguardsAndGetters.js");
37
38
  var import_Errors = require("../constants/Errors.js");
@@ -44,24 +45,34 @@ const useFocusTracker = () => {
44
45
  const focusedElementItemNode = import_react.default.useRef(
45
46
  null
46
47
  );
47
- const trackFocusTrigger = import_react.default.useCallback(() => {
48
- setFocusRegion(import_constants.MENU_FOCUS_REGIONS.TRIGGER);
49
- focusedRegionPerformanceHelper.current = import_constants.MENU_FOCUS_REGIONS.TRIGGER;
50
- focusedElementItemNode.current = null;
51
- return null;
52
- }, []);
53
- const trackFocusNode = import_react.default.useCallback((nodeToFocus) => {
54
- const newFocusRegion = import_constants.MENU_FOCUS_REGIONS.ITEM_BY_DSID(nodeToFocus.dsId);
55
- setFocusRegion(newFocusRegion);
56
- focusedRegionPerformanceHelper.current = newFocusRegion;
57
- focusedElementItemNode.current = nodeToFocus;
58
- }, []);
59
- const trackFocusRegionReset = import_react.default.useCallback(() => {
60
- setFocusRegion(import_constants.MENU_FOCUS_REGIONS.RESET);
61
- focusedRegionPerformanceHelper.current = import_constants.MENU_FOCUS_REGIONS.RESET;
62
- focusedElementItemNode.current = null;
63
- return null;
64
- }, []);
48
+ const racingConditionDebounceTrackFocus = import_react.default.useCallback(
49
+ (0, import_lodash.throttle)(
50
+ (newFocusRegion, focusNode) => {
51
+ setFocusRegion(newFocusRegion);
52
+ focusedRegionPerformanceHelper.current = newFocusRegion;
53
+ focusedElementItemNode.current = focusNode;
54
+ return focusNode;
55
+ },
56
+ 50,
57
+ { leading: true, trailing: true }
58
+ ),
59
+ []
60
+ );
61
+ const trackFocusTrigger = import_react.default.useCallback(
62
+ () => racingConditionDebounceTrackFocus(import_constants.MENU_FOCUS_REGIONS.TRIGGER, null),
63
+ [racingConditionDebounceTrackFocus]
64
+ );
65
+ const trackFocusNode = import_react.default.useCallback(
66
+ (nodeToFocus) => {
67
+ const newFocusRegion = import_constants.MENU_FOCUS_REGIONS.ITEM_BY_DSID(nodeToFocus.dsId);
68
+ racingConditionDebounceTrackFocus(newFocusRegion, nodeToFocus);
69
+ },
70
+ [racingConditionDebounceTrackFocus]
71
+ );
72
+ const trackFocusRegionReset = import_react.default.useCallback(
73
+ () => racingConditionDebounceTrackFocus(import_constants.MENU_FOCUS_REGIONS.RESET, null),
74
+ [racingConditionDebounceTrackFocus]
75
+ );
65
76
  const trackFocusFirstChildItem = import_react.default.useCallback(
66
77
  (itemNode) => {
67
78
  if (!(0, import_nodesTypeguardsAndGetters.isMenuNodeAllowedToHaveChildren)(itemNode)) {
@@ -78,10 +89,9 @@ const useFocusTracker = () => {
78
89
  throw new Error("No focusable nodes found in the children of the item node");
79
90
  }
80
91
  const newFocusedNode = focusableChildrenNodes[0];
81
- trackFocusNode(newFocusedNode);
82
- return newFocusedNode;
92
+ return racingConditionDebounceTrackFocus(import_constants.MENU_FOCUS_REGIONS.ITEM_BY_DSID(newFocusedNode.dsId), newFocusedNode);
83
93
  },
84
- [trackFocusNode]
94
+ [racingConditionDebounceTrackFocus]
85
95
  );
86
96
  const trackFocusLastChildItem = import_react.default.useCallback(
87
97
  (itemNode) => {
@@ -98,10 +108,12 @@ const useFocusTracker = () => {
98
108
  console.log("focus last child item > itemNode", itemNode);
99
109
  throw new Error("No focusable nodes found in the children of the item node");
100
110
  }
101
- trackFocusNode(focusableChildrenNodes[focusableChildrenNodes.length - 1]);
102
- return focusableChildrenNodes[focusableChildrenNodes.length - 1];
111
+ return racingConditionDebounceTrackFocus(
112
+ import_constants.MENU_FOCUS_REGIONS.ITEM_BY_DSID(focusableChildrenNodes[focusableChildrenNodes.length - 1].dsId),
113
+ focusableChildrenNodes[focusableChildrenNodes.length - 1]
114
+ );
103
115
  },
104
- [trackFocusNode]
116
+ [racingConditionDebounceTrackFocus]
105
117
  );
106
118
  const trackFocusNextItem = import_react.default.useCallback(
107
119
  (itemNode) => {
@@ -109,10 +121,9 @@ const useFocusTracker = () => {
109
121
  const currIndex = focusableSiblingsNodes.findIndex((node) => node.dsId === itemNode.dsId);
110
122
  const nextIndex = currIndex + 1 < focusableSiblingsNodes.length ? currIndex + 1 : 0;
111
123
  const newFocusedNode = focusableSiblingsNodes[nextIndex];
112
- trackFocusNode(newFocusedNode);
113
- return newFocusedNode;
124
+ return racingConditionDebounceTrackFocus(import_constants.MENU_FOCUS_REGIONS.ITEM_BY_DSID(newFocusedNode.dsId), newFocusedNode);
114
125
  },
115
- [trackFocusNode]
126
+ [racingConditionDebounceTrackFocus]
116
127
  );
117
128
  const trackFocusPreviousItem = import_react.default.useCallback(
118
129
  (itemNode) => {
@@ -120,10 +131,9 @@ const useFocusTracker = () => {
120
131
  const currIndex = focusableSiblingsNodes.findIndex((node) => node.dsId === itemNode.dsId);
121
132
  const previousIndex = currIndex - 1 >= 0 ? currIndex - 1 : focusableSiblingsNodes.length - 1;
122
133
  const newFocusNode = focusableSiblingsNodes[previousIndex];
123
- trackFocusNode(newFocusNode);
124
- return newFocusNode;
134
+ return racingConditionDebounceTrackFocus(import_constants.MENU_FOCUS_REGIONS.ITEM_BY_DSID(newFocusNode.dsId), newFocusNode);
125
135
  },
126
- [trackFocusNode]
136
+ [racingConditionDebounceTrackFocus]
127
137
  );
128
138
  const trackFocusParentItem = import_react.default.useCallback(
129
139
  (itemNode) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.ts", "../../../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable no-console */\n/* eslint-disable max-lines */\n/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport React from 'react';\nimport type { DSMenuButtonT } from '../../../react-desc-prop-types.js';\nimport {\n isFocusableNode,\n isGroup,\n isMenuNodeAllowedToHaveChildren,\n isRootNode,\n} from '../../../utils/nodesTypeguardsAndGetters.js';\nimport { TREE_STRUCTURE_ERRORS } from '../constants/Errors.js';\nimport { MENU_FOCUS_REGIONS } from '../constants/index.js';\nimport { getFocusableSiblingsList } from '../utils/nodeGettersByCriterias.js';\n\ntype MenuFocusRegionsValues = (typeof MENU_FOCUS_REGIONS)[keyof typeof MENU_FOCUS_REGIONS];\n// if MenuFocusRegionsValues may be a string or a function that returns a string, we want only the resolved strings\ntype ValidRegionsValues<T extends MenuFocusRegionsValues = MenuFocusRegionsValues> = T extends string\n ? T\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends (...args: any) => any\n ? ReturnType<T>\n : never;\n\nexport const useFocusTracker = () => {\n const [focusRegion, setFocusRegion] = React.useState<ValidRegionsValues>('');\n // we want to keep the focus region trackers as stable as possible to avoid unnecessary re-renders\n // there is no need to change the trackers reference when the focus region changes,\n // since changing the focus region is always triggered by a final user interaction (so after reacts reconciliation)\n const focusedRegionPerformanceHelper = React.useRef('') as React.MutableRefObject<ValidRegionsValues>;\n const preventBlurReset = React.useRef(false);\n\n const focusedElementItemNode = React.useRef(\n null,\n ) as React.MutableRefObject<DSMenuButtonT.PseudoFocusableMenuNodes | null>;\n const trackFocusTrigger = React.useCallback(() => {\n setFocusRegion(MENU_FOCUS_REGIONS.TRIGGER);\n focusedRegionPerformanceHelper.current = MENU_FOCUS_REGIONS.TRIGGER;\n focusedElementItemNode.current = null;\n\n return null;\n }, []);\n const trackFocusNode = React.useCallback((nodeToFocus: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n const newFocusRegion = MENU_FOCUS_REGIONS.ITEM_BY_DSID(nodeToFocus.dsId);\n setFocusRegion(newFocusRegion);\n focusedRegionPerformanceHelper.current = newFocusRegion;\n // eslint-disable-next-line prefer-destructuring\n focusedElementItemNode.current = nodeToFocus;\n }, []);\n\n const trackFocusRegionReset = React.useCallback(() => {\n setFocusRegion(MENU_FOCUS_REGIONS.RESET);\n focusedRegionPerformanceHelper.current = MENU_FOCUS_REGIONS.RESET;\n focusedElementItemNode.current = null;\n return null;\n }, []);\n\n const trackFocusFirstChildItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n if (!isMenuNodeAllowedToHaveChildren(itemNode)) {\n console.log('focus first child item > itemNode', itemNode);\n throw TREE_STRUCTURE_ERRORS.NODE_CANNOT_HAVE_CHILDREN;\n }\n if (itemNode.children.length === 0) {\n console.log(itemNode);\n throw new Error('No children found in the item node');\n }\n const focusableChildrenNodes = getFocusableSiblingsList(itemNode.children[0]);\n if (focusableChildrenNodes.length === 0) {\n console.log('focus first child item > itemNode', itemNode);\n throw new Error('No focusable nodes found in the children of the item node');\n }\n\n const newFocusedNode = focusableChildrenNodes[0];\n trackFocusNode(newFocusedNode);\n return newFocusedNode;\n },\n [trackFocusNode],\n );\n\n const trackFocusLastChildItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n if (!isMenuNodeAllowedToHaveChildren(itemNode)) {\n console.log('focus last child item > itemNode', itemNode);\n throw new Error('Item node is not allowed to have children');\n }\n if (itemNode.children.length === 0) {\n console.log(itemNode);\n throw new Error('No children found in the item node');\n }\n const focusableChildrenNodes = getFocusableSiblingsList(itemNode.children[0]);\n if (focusableChildrenNodes.length === 0) {\n console.log('focus last child item > itemNode', itemNode);\n throw new Error('No focusable nodes found in the children of the item node');\n }\n trackFocusNode(focusableChildrenNodes[focusableChildrenNodes.length - 1]);\n return focusableChildrenNodes[focusableChildrenNodes.length - 1];\n },\n [trackFocusNode],\n );\n\n const trackFocusNextItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n const focusableSiblingsNodes = getFocusableSiblingsList(itemNode);\n // we find the current item node index in the focusableSiblingsNodes array\n const currIndex = focusableSiblingsNodes.findIndex((node) => node.dsId === itemNode.dsId);\n\n const nextIndex = currIndex + 1 < focusableSiblingsNodes.length ? currIndex + 1 : 0;\n const newFocusedNode = focusableSiblingsNodes[nextIndex];\n trackFocusNode(newFocusedNode);\n\n return newFocusedNode;\n },\n [trackFocusNode],\n );\n\n const trackFocusPreviousItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n const focusableSiblingsNodes = getFocusableSiblingsList(itemNode);\n // we find the current item node index in the focusableSiblingsNodes array\n const currIndex = focusableSiblingsNodes.findIndex((node) => node.dsId === itemNode.dsId);\n\n const previousIndex = currIndex - 1 >= 0 ? currIndex - 1 : focusableSiblingsNodes.length - 1;\n const newFocusNode = focusableSiblingsNodes[previousIndex];\n trackFocusNode(newFocusNode);\n return newFocusNode;\n },\n [trackFocusNode],\n );\n\n const trackFocusParentItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n const { parent } = itemNode;\n // this typecast is required because we are reading the parent property from the itemNode\n // while this function can receive any PseudoFocusableMenuNodes,\n // the parent property may be a non-pseudo focusable node (specifically when the parent property is group node)\n const parentNode = parent;\n if (!parentNode) {\n console.log('focus parent item', { itemNode, parentNode });\n throw new Error(`No parent node found for the item node`);\n }\n\n let nodeToFocus: DSMenuButtonT.PseudoFocusableMenuNodes | null = parentNode;\n // if parent is SingleSelectGroupNode then we can't focus it\n if (isGroup(parentNode)) {\n const groupParent = parentNode.parent;\n if (!isFocusableNode(groupParent) && !isRootNode(groupParent)) {\n console.log('focus parent item', { itemNode, parentNode, groupParent });\n throw new Error('No focusable parent node found for the item node');\n }\n nodeToFocus = groupParent;\n }\n\n const focusableNode = isRootNode(nodeToFocus) ? null : nodeToFocus;\n const newFocusNode = focusableNode;\n if (!newFocusNode) trackFocusTrigger();\n else trackFocusNode(newFocusNode);\n\n return focusableNode;\n },\n [trackFocusNode, trackFocusTrigger],\n );\n\n return React.useMemo(\n () => ({\n preventBlurReset,\n focusRegion,\n focusedElementItemNode,\n trackFocusTrigger,\n trackFocusNode,\n trackFocusRegionReset,\n trackFocusFirstChildItem,\n trackFocusLastChildItem,\n trackFocusNextItem,\n trackFocusPreviousItem,\n trackFocusParentItem,\n }),\n [\n focusRegion,\n trackFocusFirstChildItem,\n trackFocusLastChildItem,\n trackFocusNextItem,\n trackFocusNode,\n trackFocusParentItem,\n trackFocusPreviousItem,\n trackFocusRegionReset,\n trackFocusTrigger,\n ],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable no-console */\n/* eslint-disable max-lines */\n/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport { throttle } from 'lodash';\nimport React from 'react';\nimport type { DSMenuButtonT } from '../../../react-desc-prop-types.js';\nimport {\n isFocusableNode,\n isGroup,\n isMenuNodeAllowedToHaveChildren,\n isRootNode,\n} from '../../../utils/nodesTypeguardsAndGetters.js';\nimport { TREE_STRUCTURE_ERRORS } from '../constants/Errors.js';\nimport { MENU_FOCUS_REGIONS } from '../constants/index.js';\nimport { getFocusableSiblingsList } from '../utils/nodeGettersByCriterias.js';\n\ntype MenuFocusRegionsValues = (typeof MENU_FOCUS_REGIONS)[keyof typeof MENU_FOCUS_REGIONS];\n// if MenuFocusRegionsValues may be a string or a function that returns a string, we want only the resolved strings\ntype ValidRegionsValues<T extends MenuFocusRegionsValues = MenuFocusRegionsValues> = T extends string\n ? T\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends (...args: any) => any\n ? ReturnType<T>\n : never;\n\nexport const useFocusTracker = () => {\n const [focusRegion, setFocusRegion] = React.useState<ValidRegionsValues>('');\n // we want to keep the focus region trackers as stable as possible to avoid unnecessary re-renders\n // there is no need to change the trackers reference when the focus region changes,\n // since changing the focus region is always triggered by a final user interaction (so after reacts reconciliation)\n const focusedRegionPerformanceHelper = React.useRef('') as React.MutableRefObject<ValidRegionsValues>;\n const preventBlurReset = React.useRef(false);\n\n const focusedElementItemNode = React.useRef(\n null,\n ) as React.MutableRefObject<DSMenuButtonT.PseudoFocusableMenuNodes | null>;\n\n // typescript with debounce doesn't work well, so we need to disable the exhaustive deps rule here\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const racingConditionDebounceTrackFocus = React.useCallback(\n throttle(\n (newFocusRegion: ValidRegionsValues, focusNode: DSMenuButtonT.PseudoFocusableMenuNodes | null) => {\n setFocusRegion(newFocusRegion);\n focusedRegionPerformanceHelper.current = newFocusRegion;\n focusedElementItemNode.current = focusNode;\n\n return focusNode;\n },\n 50,\n { leading: true, trailing: true },\n ),\n [],\n );\n\n const trackFocusTrigger = React.useCallback(\n () => racingConditionDebounceTrackFocus(MENU_FOCUS_REGIONS.TRIGGER, null),\n [racingConditionDebounceTrackFocus],\n );\n\n const trackFocusNode = React.useCallback(\n (nodeToFocus: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n const newFocusRegion = MENU_FOCUS_REGIONS.ITEM_BY_DSID(nodeToFocus.dsId);\n racingConditionDebounceTrackFocus(newFocusRegion, nodeToFocus);\n },\n [racingConditionDebounceTrackFocus],\n );\n\n const trackFocusRegionReset = React.useCallback(\n () => racingConditionDebounceTrackFocus(MENU_FOCUS_REGIONS.RESET, null),\n [racingConditionDebounceTrackFocus],\n );\n\n const trackFocusFirstChildItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n if (!isMenuNodeAllowedToHaveChildren(itemNode)) {\n console.log('focus first child item > itemNode', itemNode);\n throw TREE_STRUCTURE_ERRORS.NODE_CANNOT_HAVE_CHILDREN;\n }\n if (itemNode.children.length === 0) {\n console.log(itemNode);\n throw new Error('No children found in the item node');\n }\n const focusableChildrenNodes = getFocusableSiblingsList(itemNode.children[0]);\n if (focusableChildrenNodes.length === 0) {\n console.log('focus first child item > itemNode', itemNode);\n throw new Error('No focusable nodes found in the children of the item node');\n }\n\n const newFocusedNode = focusableChildrenNodes[0];\n return racingConditionDebounceTrackFocus(MENU_FOCUS_REGIONS.ITEM_BY_DSID(newFocusedNode.dsId), newFocusedNode);\n },\n [racingConditionDebounceTrackFocus],\n );\n\n const trackFocusLastChildItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n if (!isMenuNodeAllowedToHaveChildren(itemNode)) {\n console.log('focus last child item > itemNode', itemNode);\n throw new Error('Item node is not allowed to have children');\n }\n if (itemNode.children.length === 0) {\n console.log(itemNode);\n throw new Error('No children found in the item node');\n }\n const focusableChildrenNodes = getFocusableSiblingsList(itemNode.children[0]);\n if (focusableChildrenNodes.length === 0) {\n console.log('focus last child item > itemNode', itemNode);\n throw new Error('No focusable nodes found in the children of the item node');\n }\n return racingConditionDebounceTrackFocus(\n MENU_FOCUS_REGIONS.ITEM_BY_DSID(focusableChildrenNodes[focusableChildrenNodes.length - 1].dsId),\n focusableChildrenNodes[focusableChildrenNodes.length - 1],\n );\n },\n [racingConditionDebounceTrackFocus],\n );\n\n const trackFocusNextItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n const focusableSiblingsNodes = getFocusableSiblingsList(itemNode);\n // we find the current item node index in the focusableSiblingsNodes array\n const currIndex = focusableSiblingsNodes.findIndex((node) => node.dsId === itemNode.dsId);\n\n const nextIndex = currIndex + 1 < focusableSiblingsNodes.length ? currIndex + 1 : 0;\n const newFocusedNode = focusableSiblingsNodes[nextIndex];\n return racingConditionDebounceTrackFocus(MENU_FOCUS_REGIONS.ITEM_BY_DSID(newFocusedNode.dsId), newFocusedNode);\n },\n [racingConditionDebounceTrackFocus],\n );\n\n const trackFocusPreviousItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n const focusableSiblingsNodes = getFocusableSiblingsList(itemNode);\n // we find the current item node index in the focusableSiblingsNodes array\n const currIndex = focusableSiblingsNodes.findIndex((node) => node.dsId === itemNode.dsId);\n\n const previousIndex = currIndex - 1 >= 0 ? currIndex - 1 : focusableSiblingsNodes.length - 1;\n const newFocusNode = focusableSiblingsNodes[previousIndex];\n return racingConditionDebounceTrackFocus(MENU_FOCUS_REGIONS.ITEM_BY_DSID(newFocusNode.dsId), newFocusNode);\n },\n [racingConditionDebounceTrackFocus],\n );\n\n const trackFocusParentItem = React.useCallback(\n (itemNode: DSMenuButtonT.PseudoFocusableMenuNodes) => {\n const { parent } = itemNode;\n // this typecast is required because we are reading the parent property from the itemNode\n // while this function can receive any PseudoFocusableMenuNodes,\n // the parent property may be a non-pseudo focusable node (specifically when the parent property is group node)\n const parentNode = parent;\n if (!parentNode) {\n console.log('focus parent item', { itemNode, parentNode });\n throw new Error(`No parent node found for the item node`);\n }\n\n let nodeToFocus: DSMenuButtonT.PseudoFocusableMenuNodes | null = parentNode;\n // if parent is SingleSelectGroupNode then we can't focus it\n if (isGroup(parentNode)) {\n const groupParent = parentNode.parent;\n if (!isFocusableNode(groupParent) && !isRootNode(groupParent)) {\n console.log('focus parent item', { itemNode, parentNode, groupParent });\n throw new Error('No focusable parent node found for the item node');\n }\n nodeToFocus = groupParent;\n }\n\n const focusableNode = isRootNode(nodeToFocus) ? null : nodeToFocus;\n const newFocusNode = focusableNode;\n if (!newFocusNode) trackFocusTrigger();\n else trackFocusNode(newFocusNode);\n\n return focusableNode;\n },\n [trackFocusNode, trackFocusTrigger],\n );\n\n return React.useMemo(\n () => ({\n preventBlurReset,\n focusRegion,\n focusedElementItemNode,\n trackFocusTrigger,\n trackFocusNode,\n trackFocusRegionReset,\n trackFocusFirstChildItem,\n trackFocusLastChildItem,\n trackFocusNextItem,\n trackFocusPreviousItem,\n trackFocusParentItem,\n }),\n [\n focusRegion,\n trackFocusFirstChildItem,\n trackFocusLastChildItem,\n trackFocusNextItem,\n trackFocusNode,\n trackFocusParentItem,\n trackFocusPreviousItem,\n trackFocusRegionReset,\n trackFocusTrigger,\n ],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADIvB,oBAAyB;AACzB,mBAAkB;AAElB,uCAKO;AACP,oBAAsC;AACtC,uBAAmC;AACnC,oCAAyC;AAWlC,MAAM,kBAAkB,MAAM;AACnC,QAAM,CAAC,aAAa,cAAc,IAAI,aAAAA,QAAM,SAA6B,EAAE;AAI3E,QAAM,iCAAiC,aAAAA,QAAM,OAAO,EAAE;AACtD,QAAM,mBAAmB,aAAAA,QAAM,OAAO,KAAK;AAE3C,QAAM,yBAAyB,aAAAA,QAAM;AAAA,IACnC;AAAA,EACF;AAIA,QAAM,oCAAoC,aAAAA,QAAM;AAAA,QAC9C;AAAA,MACE,CAAC,gBAAoC,cAA6D;AAChG,uBAAe,cAAc;AAC7B,uCAA+B,UAAU;AACzC,+BAAuB,UAAU;AAEjC,eAAO;AAAA,MACT;AAAA,MACA;AAAA,MACA,EAAE,SAAS,MAAM,UAAU,KAAK;AAAA,IAClC;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,oBAAoB,aAAAA,QAAM;AAAA,IAC9B,MAAM,kCAAkC,oCAAmB,SAAS,IAAI;AAAA,IACxE,CAAC,iCAAiC;AAAA,EACpC;AAEA,QAAM,iBAAiB,aAAAA,QAAM;AAAA,IAC3B,CAAC,gBAAwD;AACvD,YAAM,iBAAiB,oCAAmB,aAAa,YAAY,IAAI;AACvE,wCAAkC,gBAAgB,WAAW;AAAA,IAC/D;AAAA,IACA,CAAC,iCAAiC;AAAA,EACpC;AAEA,QAAM,wBAAwB,aAAAA,QAAM;AAAA,IAClC,MAAM,kCAAkC,oCAAmB,OAAO,IAAI;AAAA,IACtE,CAAC,iCAAiC;AAAA,EACpC;AAEA,QAAM,2BAA2B,aAAAA,QAAM;AAAA,IACrC,CAAC,aAAqD;AACpD,UAAI,KAAC,kEAAgC,QAAQ,GAAG;AAC9C,gBAAQ,IAAI,qCAAqC,QAAQ;AACzD,cAAM,oCAAsB;AAAA,MAC9B;AACA,UAAI,SAAS,SAAS,WAAW,GAAG;AAClC,gBAAQ,IAAI,QAAQ;AACpB,cAAM,IAAI,MAAM,oCAAoC;AAAA,MACtD;AACA,YAAM,6BAAyB,wDAAyB,SAAS,SAAS,CAAC,CAAC;AAC5E,UAAI,uBAAuB,WAAW,GAAG;AACvC,gBAAQ,IAAI,qCAAqC,QAAQ;AACzD,cAAM,IAAI,MAAM,2DAA2D;AAAA,MAC7E;AAEA,YAAM,iBAAiB,uBAAuB,CAAC;AAC/C,aAAO,kCAAkC,oCAAmB,aAAa,eAAe,IAAI,GAAG,cAAc;AAAA,IAC/G;AAAA,IACA,CAAC,iCAAiC;AAAA,EACpC;AAEA,QAAM,0BAA0B,aAAAA,QAAM;AAAA,IACpC,CAAC,aAAqD;AACpD,UAAI,KAAC,kEAAgC,QAAQ,GAAG;AAC9C,gBAAQ,IAAI,oCAAoC,QAAQ;AACxD,cAAM,IAAI,MAAM,2CAA2C;AAAA,MAC7D;AACA,UAAI,SAAS,SAAS,WAAW,GAAG;AAClC,gBAAQ,IAAI,QAAQ;AACpB,cAAM,IAAI,MAAM,oCAAoC;AAAA,MACtD;AACA,YAAM,6BAAyB,wDAAyB,SAAS,SAAS,CAAC,CAAC;AAC5E,UAAI,uBAAuB,WAAW,GAAG;AACvC,gBAAQ,IAAI,oCAAoC,QAAQ;AACxD,cAAM,IAAI,MAAM,2DAA2D;AAAA,MAC7E;AACA,aAAO;AAAA,QACL,oCAAmB,aAAa,uBAAuB,uBAAuB,SAAS,CAAC,EAAE,IAAI;AAAA,QAC9F,uBAAuB,uBAAuB,SAAS,CAAC;AAAA,MAC1D;AAAA,IACF;AAAA,IACA,CAAC,iCAAiC;AAAA,EACpC;AAEA,QAAM,qBAAqB,aAAAA,QAAM;AAAA,IAC/B,CAAC,aAAqD;AACpD,YAAM,6BAAyB,wDAAyB,QAAQ;AAEhE,YAAM,YAAY,uBAAuB,UAAU,CAAC,SAAS,KAAK,SAAS,SAAS,IAAI;AAExF,YAAM,YAAY,YAAY,IAAI,uBAAuB,SAAS,YAAY,IAAI;AAClF,YAAM,iBAAiB,uBAAuB,SAAS;AACvD,aAAO,kCAAkC,oCAAmB,aAAa,eAAe,IAAI,GAAG,cAAc;AAAA,IAC/G;AAAA,IACA,CAAC,iCAAiC;AAAA,EACpC;AAEA,QAAM,yBAAyB,aAAAA,QAAM;AAAA,IACnC,CAAC,aAAqD;AACpD,YAAM,6BAAyB,wDAAyB,QAAQ;AAEhE,YAAM,YAAY,uBAAuB,UAAU,CAAC,SAAS,KAAK,SAAS,SAAS,IAAI;AAExF,YAAM,gBAAgB,YAAY,KAAK,IAAI,YAAY,IAAI,uBAAuB,SAAS;AAC3F,YAAM,eAAe,uBAAuB,aAAa;AACzD,aAAO,kCAAkC,oCAAmB,aAAa,aAAa,IAAI,GAAG,YAAY;AAAA,IAC3G;AAAA,IACA,CAAC,iCAAiC;AAAA,EACpC;AAEA,QAAM,uBAAuB,aAAAA,QAAM;AAAA,IACjC,CAAC,aAAqD;AACpD,YAAM,EAAE,OAAO,IAAI;AAInB,YAAM,aAAa;AACnB,UAAI,CAAC,YAAY;AACf,gBAAQ,IAAI,qBAAqB,EAAE,UAAU,WAAW,CAAC;AACzD,cAAM,IAAI,MAAM,wCAAwC;AAAA,MAC1D;AAEA,UAAI,cAA6D;AAEjE,cAAI,0CAAQ,UAAU,GAAG;AACvB,cAAM,cAAc,WAAW;AAC/B,YAAI,KAAC,kDAAgB,WAAW,KAAK,KAAC,6CAAW,WAAW,GAAG;AAC7D,kBAAQ,IAAI,qBAAqB,EAAE,UAAU,YAAY,YAAY,CAAC;AACtE,gBAAM,IAAI,MAAM,kDAAkD;AAAA,QACpE;AACA,sBAAc;AAAA,MAChB;AAEA,YAAM,oBAAgB,6CAAW,WAAW,IAAI,OAAO;AACvD,YAAM,eAAe;AACrB,UAAI,CAAC,aAAc,mBAAkB;AAAA,UAChC,gBAAe,YAAY;AAEhC,aAAO;AAAA,IACT;AAAA,IACA,CAAC,gBAAgB,iBAAiB;AAAA,EACpC;AAEA,SAAO,aAAAA,QAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;",
6
6
  "names": ["React"]
7
7
  }