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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/cjs/config/useMenuButton.js +0 -3
  2. package/dist/cjs/config/useMenuButton.js.map +2 -2
  3. package/dist/cjs/config/useSplitInherithedProps.js +3 -15
  4. package/dist/cjs/config/useSplitInherithedProps.js.map +2 -2
  5. package/dist/cjs/parts/DSFlyoutMenu/DSFlyoutMenu.js +1 -0
  6. package/dist/cjs/parts/DSFlyoutMenu/DSFlyoutMenu.js.map +2 -2
  7. package/dist/cjs/parts/DSFlyoutMenu/config/useFlyoutMenu.js +8 -2
  8. package/dist/cjs/parts/DSFlyoutMenu/config/useFlyoutMenu.js.map +2 -2
  9. package/dist/cjs/parts/DSFlyoutMenu/react-desc-prop-types.js.map +2 -2
  10. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js +9 -15
  11. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js.map +2 -2
  12. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js +7 -5
  13. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js.map +2 -2
  14. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js +7 -21
  15. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js.map +3 -3
  16. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.js +0 -1
  17. package/dist/cjs/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.js.map +2 -2
  18. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableMenuItem.js +7 -10
  19. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableMenuItem.js.map +2 -2
  20. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js +7 -10
  21. package/dist/cjs/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js.map +2 -2
  22. package/dist/cjs/parts/DSMenuItemRendererFactory/DSMenuItemRendererFactory.js +17 -3
  23. package/dist/cjs/parts/DSMenuItemRendererFactory/DSMenuItemRendererFactory.js.map +2 -2
  24. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js +7 -10
  25. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js.map +2 -2
  26. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js +7 -10
  27. package/dist/cjs/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js.map +2 -2
  28. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js +7 -10
  29. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js.map +2 -2
  30. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js +7 -10
  31. package/dist/cjs/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js.map +2 -2
  32. package/dist/cjs/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js +7 -10
  33. package/dist/cjs/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js.map +2 -2
  34. package/dist/cjs/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js +6 -3
  35. package/dist/cjs/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js.map +2 -2
  36. package/dist/cjs/parts/DSMenuItemRendererFactory/constants/index.js +3 -1
  37. package/dist/cjs/parts/DSMenuItemRendererFactory/constants/index.js.map +2 -2
  38. package/dist/cjs/parts/DSOpinionatedButton/config/useOpinionatedButton.js +6 -4
  39. package/dist/cjs/parts/DSOpinionatedButton/config/useOpinionatedButton.js.map +2 -2
  40. package/dist/cjs/parts/DSOpinionatedButton/config/useTriggerEventsHandlers.js +8 -5
  41. package/dist/cjs/parts/DSOpinionatedButton/config/useTriggerEventsHandlers.js.map +2 -2
  42. package/dist/cjs/utils/resolveRef.js +43 -0
  43. package/dist/cjs/utils/resolveRef.js.map +7 -0
  44. package/dist/esm/config/useMenuButton.js +0 -3
  45. package/dist/esm/config/useMenuButton.js.map +2 -2
  46. package/dist/esm/config/useSplitInherithedProps.js +2 -14
  47. package/dist/esm/config/useSplitInherithedProps.js.map +2 -2
  48. package/dist/esm/parts/DSFlyoutMenu/DSFlyoutMenu.js +1 -0
  49. package/dist/esm/parts/DSFlyoutMenu/DSFlyoutMenu.js.map +2 -2
  50. package/dist/esm/parts/DSFlyoutMenu/config/useFlyoutMenu.js +8 -2
  51. package/dist/esm/parts/DSFlyoutMenu/config/useFlyoutMenu.js.map +2 -2
  52. package/dist/esm/parts/DSFlyoutMenu/react-desc-prop-types.js.map +2 -2
  53. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js +9 -15
  54. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.js.map +2 -2
  55. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js +7 -5
  56. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.js.map +2 -2
  57. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js +7 -21
  58. package/dist/esm/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.js.map +2 -2
  59. package/dist/esm/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.js +0 -1
  60. package/dist/esm/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.js.map +2 -2
  61. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableMenuItem.js +7 -10
  62. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableMenuItem.js.map +2 -2
  63. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js +7 -10
  64. package/dist/esm/parts/DSMenuItemRendererFactory/ActivableWithSubmenuMenuItem.js.map +2 -2
  65. package/dist/esm/parts/DSMenuItemRendererFactory/DSMenuItemRendererFactory.js +19 -5
  66. package/dist/esm/parts/DSMenuItemRendererFactory/DSMenuItemRendererFactory.js.map +2 -2
  67. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js +7 -10
  68. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectMenuItem.js.map +2 -2
  69. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js +7 -10
  70. package/dist/esm/parts/DSMenuItemRendererFactory/MultipleSelectWithSubmenuMenuItem.js.map +2 -2
  71. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js +7 -10
  72. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectMenuItem.js.map +2 -2
  73. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js +7 -10
  74. package/dist/esm/parts/DSMenuItemRendererFactory/SingleSelectWithSubmenuMenuItem.js.map +2 -2
  75. package/dist/esm/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js +7 -10
  76. package/dist/esm/parts/DSMenuItemRendererFactory/WithSubmenuMenuItem.js.map +2 -2
  77. package/dist/esm/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js +7 -4
  78. package/dist/esm/parts/DSMenuItemRendererFactory/config/useMenuItemRendererFactory.js.map +2 -2
  79. package/dist/esm/parts/DSMenuItemRendererFactory/constants/index.js +3 -1
  80. package/dist/esm/parts/DSMenuItemRendererFactory/constants/index.js.map +2 -2
  81. package/dist/esm/parts/DSOpinionatedButton/config/useOpinionatedButton.js +6 -4
  82. package/dist/esm/parts/DSOpinionatedButton/config/useOpinionatedButton.js.map +2 -2
  83. package/dist/esm/parts/DSOpinionatedButton/config/useTriggerEventsHandlers.js +8 -5
  84. package/dist/esm/parts/DSOpinionatedButton/config/useTriggerEventsHandlers.js.map +2 -2
  85. package/dist/esm/utils/resolveRef.js +13 -0
  86. package/dist/esm/utils/resolveRef.js.map +7 -0
  87. package/dist/types/config/useSplitInherithedProps.d.ts +3 -7
  88. package/dist/types/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.d.ts +1 -1
  89. package/dist/types/parts/DSMenuBehaviouralContextProvider/config/useMenuItemEventsHandlers.d.ts +0 -1
  90. package/dist/types/parts/DSMenuBehaviouralContextProvider/react-desc-prop-types.d.ts +0 -1
  91. package/dist/types/parts/DSMenuItemRendererFactory/constants/index.d.ts +2 -0
  92. package/dist/types/utils/resolveRef.d.ts +2 -0
  93. package/package.json +13 -13
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var resolveRef_exports = {};
30
+ __export(resolveRef_exports, {
31
+ resolveRef: () => resolveRef
32
+ });
33
+ module.exports = __toCommonJS(resolveRef_exports);
34
+ var React = __toESM(require("react"));
35
+ const resolveRef = (ref, node) => {
36
+ if (typeof ref === "function") {
37
+ ref(node);
38
+ }
39
+ if ("current" in ref) {
40
+ ref.current = node;
41
+ }
42
+ };
43
+ //# sourceMappingURL=resolveRef.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/utils/resolveRef.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
4
+ "sourcesContent": ["import type React from 'react';\n\n// react references may be functions or objects, this helpers identify the type and act accordingly\nexport const resolveRef = (\n ref: React.MutableRefObject<HTMLElement | null> | React.RefCallback<HTMLElement>,\n node: HTMLElement | null,\n) => {\n if (typeof ref === 'function') {\n ref(node);\n }\n if ('current' in ref) {\n ref.current = node;\n }\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADGhB,MAAM,aAAa,CACxB,KACA,SACG;AACH,MAAI,OAAO,QAAQ,YAAY;AAC7B,QAAI,IAAI;AAAA,EACV;AACA,MAAI,aAAa,KAAK;AACpB,QAAI,UAAU;AAAA,EAChB;AACF;",
6
+ "names": []
7
+ }
@@ -12,7 +12,6 @@ const useMenuButton = (propsFromUser) => {
12
12
  useValidateProps(propsWithDefault, DSMenuButtonPropTypes);
13
13
  const xstyledProps = useGetXstyledProps(propsWithDefault);
14
14
  const instanceUid = React2.useMemo(() => `menu-button${uid(5)}`, []);
15
- const [buttonDOMNode, setButtonDOMNode] = React2.useState(null);
16
15
  const { options: appOptions } = propsWithDefault;
17
16
  const optionsArray = Array.isArray(appOptions) ? appOptions : [];
18
17
  const treeRootNodeFromOptionsArrayIfArray = useOptionsArrayToDsTree({
@@ -28,8 +27,6 @@ const useMenuButton = (propsFromUser) => {
28
27
  const focusableNodes = React2.useMemo(() => getFocusableNodes(treeRootNode), [treeRootNode]);
29
28
  const splitInherithedProps = useSplitInherithedProps({
30
29
  propsWithDefault,
31
- setButtonDOMNode,
32
- buttonDOMNode,
33
30
  focusableNodes,
34
31
  treeRootNode
35
32
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/config/useMenuButton.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport { useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { uid } from 'uid';\nimport { type DSMenuButtonT, DSMenuButtonPropTypes, defaultProps } from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\nimport { useSplitInherithedProps } from './useSplitInherithedProps.js';\nimport { useOptionsArrayToDsTree } from '../utils/useOptionsArrayToDsTree.js';\nimport { getFocusableNodes } from '../utils/nodesTypeguardsAndGetters.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 const [buttonDOMNode, setButtonDOMNode] = React.useState<HTMLElement | null>(null);\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 setButtonDOMNode,\n buttonDOMNode,\n focusableNodes,\n treeRootNode,\n });\n\n // =============================================================================\n // if any item as a repeated dsId, we must throw an error,\n // the component will not work properly if the dsId is not guaranteed to be unique\n // (only validating focusableNodes may work, but as a good practice it's better to validate the whole tree)\n // =============================================================================\n const allNodes = treeRootNode.flatten();\n const nodesWithRepeatedDsId = allNodes.filter(\n (node, index, self) => self.findIndex((n) => n.dsId === node.dsId) !== index,\n );\n if (nodesWithRepeatedDsId.length > 0) {\n throw new Error(\n `DSMenuButton:\\nThe following dsId are repeated:\\n${nodesWithRepeatedDsId\n .map((n) => n.dsId)\n .join('\\n ')}\\n\\nThe dsId must be unique.`,\n );\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"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,YAAW;AAClB,SAAS,oBAAoB,oCAAoC;AACjE,SAAS,WAAW;AACpB,SAA6B,uBAAuB,oBAAoB;AACxE,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,+BAA+B;AACxC,SAAS,yBAAyB;AAO3B,MAAM,gBAAgB,CAAC,kBAAuC;AAInE,QAAM,mBAAmB,6BAA0D,eAAe,YAAY;AAC9G,mBAAiB,kBAAkB,qBAAqB;AAIxD,QAAM,eAAe,mBAAmB,gBAAgB;AAKxD,QAAM,cAAcA,OAAM,QAAQ,MAAM,cAAc,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAClE,QAAM,CAAC,eAAe,gBAAgB,IAAIA,OAAM,SAA6B,IAAI;AAQjF,QAAM,EAAE,SAAS,WAAW,IAAI;AAChC,QAAM,eAAkD,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC;AAElG,QAAM,sCAAsC,wBAAwB;AAAA,IAClE,SAAS;AAAA,IACT;AAAA;AAAA;AAAA,EAGF,CAAC,EAAE,QAAQ;AACX,QAAM,eAAeA,OAAM;AAAA,IACzB,MAAO,MAAM,QAAQ,UAAU,IAAI,sCAAsC;AAAA,IACzE,CAAC,YAAY,mCAAmC;AAAA,EAClD;AAKA,QAAM,iBAAiBA,OAAM,QAAQ,MAAM,kBAAkB,YAAY,GAAG,CAAC,YAAY,CAAC;AAC1F,QAAM,uBAAuB,wBAAwB;AAAA,IACnD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAOD,QAAM,WAAW,aAAa,QAAQ;AACtC,QAAM,wBAAwB,SAAS;AAAA,IACrC,CAAC,MAAM,OAAO,SAAS,KAAK,UAAU,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,MAAM;AAAA,EACzE;AACA,MAAI,sBAAsB,SAAS,GAAG;AACpC,UAAM,IAAI;AAAA,MACR;AAAA;AAAA,EAAoD,sBACjD,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,KAAK,CAAC;AAAA;AAAA;AAAA,IAChB;AAAA,EACF;AAEA,SAAOA,OAAM;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": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport { useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { uid } from 'uid';\nimport { type DSMenuButtonT, DSMenuButtonPropTypes, defaultProps } from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\nimport { useSplitInherithedProps } from './useSplitInherithedProps.js';\nimport { useOptionsArrayToDsTree } from '../utils/useOptionsArrayToDsTree.js';\nimport { getFocusableNodes } from '../utils/nodesTypeguardsAndGetters.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 // =============================================================================\n // if any item as a repeated dsId, we must throw an error,\n // the component will not work properly if the dsId is not guaranteed to be unique\n // (only validating focusableNodes may work, but as a good practice it's better to validate the whole tree)\n // =============================================================================\n const allNodes = treeRootNode.flatten();\n const nodesWithRepeatedDsId = allNodes.filter(\n (node, index, self) => self.findIndex((n) => n.dsId === node.dsId) !== index,\n );\n if (nodesWithRepeatedDsId.length > 0) {\n throw new Error(\n `DSMenuButton:\\nThe following dsId are repeated:\\n${nodesWithRepeatedDsId\n .map((n) => n.dsId)\n .join('\\n ')}\\n\\nThe dsId must be unique.`,\n );\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"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,YAAW;AAClB,SAAS,oBAAoB,oCAAoC;AACjE,SAAS,WAAW;AACpB,SAA6B,uBAAuB,oBAAoB;AACxE,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,+BAA+B;AACxC,SAAS,yBAAyB;AAO3B,MAAM,gBAAgB,CAAC,kBAAuC;AAInE,QAAM,mBAAmB,6BAA0D,eAAe,YAAY;AAC9G,mBAAiB,kBAAkB,qBAAqB;AAIxD,QAAM,eAAe,mBAAmB,gBAAgB;AAKxD,QAAM,cAAcA,OAAM,QAAQ,MAAM,cAAc,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAQlE,QAAM,EAAE,SAAS,WAAW,IAAI;AAChC,QAAM,eAAkD,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC;AAElG,QAAM,sCAAsC,wBAAwB;AAAA,IAClE,SAAS;AAAA,IACT;AAAA;AAAA;AAAA,EAGF,CAAC,EAAE,QAAQ;AACX,QAAM,eAAeA,OAAM;AAAA,IACzB,MAAO,MAAM,QAAQ,UAAU,IAAI,sCAAsC;AAAA,IACzE,CAAC,YAAY,mCAAmC;AAAA,EAClD;AAKA,QAAM,iBAAiBA,OAAM,QAAQ,MAAM,kBAAkB,YAAY,GAAG,CAAC,YAAY,CAAC;AAC1F,QAAM,uBAAuB,wBAAwB;AAAA,IACnD;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAOD,QAAM,WAAW,aAAa,QAAQ;AACtC,QAAM,wBAAwB,SAAS;AAAA,IACrC,CAAC,MAAM,OAAO,SAAS,KAAK,UAAU,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,MAAM;AAAA,EACzE;AACA,MAAI,sBAAsB,SAAS,GAAG;AACpC,UAAM,IAAI;AAAA,MACR;AAAA;AAAA,EAAoD,sBACjD,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,KAAK,CAAC;AAAA;AAAA;AAAA,IAChB;AAAA,EACF;AAEA,SAAOA,OAAM;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
  }
@@ -1,17 +1,8 @@
1
1
  import * as React from "react";
2
2
  import React2 from "react";
3
- const resolveRef = (ref, node) => {
4
- if (typeof ref === "function") {
5
- ref(node);
6
- }
7
- if ("current" in ref) {
8
- ref.current = node;
9
- }
10
- };
3
+ import { resolveRef } from "../utils/resolveRef.js";
11
4
  const useSplitInherithedProps = ({
12
5
  propsWithDefault,
13
- setButtonDOMNode,
14
- buttonDOMNode,
15
6
  focusableNodes,
16
7
  treeRootNode
17
8
  }) => {
@@ -37,13 +28,12 @@ const useSplitInherithedProps = ({
37
28
  } = propsWithDefault;
38
29
  const innerRefSnatchingNode = React2.useCallback(
39
30
  (node) => {
40
- setButtonDOMNode(node);
41
31
  buttonDOMNodeRef.current = node;
42
32
  if (innerRef) {
43
33
  resolveRef(innerRef, node);
44
34
  }
45
35
  },
46
- [innerRef, setButtonDOMNode]
36
+ [innerRef]
47
37
  );
48
38
  const menuSpecificProps = React2.useMemo(
49
39
  () => ({
@@ -72,7 +62,6 @@ const useSplitInherithedProps = ({
72
62
  return React2.useMemo(
73
63
  () => ({
74
64
  menuBehaviouralLayerProps: {
75
- buttonDOMNode,
76
65
  buttonDOMNodeRef,
77
66
  selectedItems,
78
67
  focusableNodes,
@@ -90,7 +79,6 @@ const useSplitInherithedProps = ({
90
79
  }
91
80
  }),
92
81
  [
93
- buttonDOMNode,
94
82
  selectedItems,
95
83
  focusableNodes,
96
84
  treeRootNode,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/config/useSplitInherithedProps.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* *******************************************************\n * From official source definition\n *\n * Menu Button Pattern\n * About This Pattern:\n * A menu button is a button\n * that opens a menu\n * (as described in the Menu and Menubar Pattern).\n *\n * Since the menu button is a button, it inherits all the props from the Button component.\n * Since the menu button MUST have a menu, it also have a set of specific props used to handle the menu.\n * Because we build with atomic composition in mind, the \"logic layer\" is separated and has a yet another set of props.\n *\n * This is effectively an OOP \"extension\" of the Button component,\n * so it has the same props,\n * BUT also a few more to handle the specific behavior of the menu.\n *\n * 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 { TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport { type DSMenuButtonT } from '../react-desc-prop-types.js';\n\n// react references may be functions or objects, this helpers identify the type and act accordingly\nconst resolveRef = (\n ref: React.MutableRefObject<HTMLElement | null> | React.RefCallback<HTMLElement>,\n node: HTMLElement,\n) => {\n if (typeof ref === 'function') {\n ref(node);\n }\n if ('current' in ref) {\n ref.current = node;\n }\n};\n\ntype UseSplitInherithedPropsConfig = {\n propsWithDefault: DSMenuButtonT.InternalProps;\n buttonDOMNode: HTMLElement | null;\n setButtonDOMNode: TypescriptHelpersT.StateSetter<HTMLElement | null>;\n focusableNodes: DSMenuButtonT.PseudoFocusableMenuNodes[];\n treeRootNode: DSMenuButtonT.MenuNode;\n};\nexport const useSplitInherithedProps = ({\n propsWithDefault,\n setButtonDOMNode,\n buttonDOMNode,\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 setButtonDOMNode(node);\n buttonDOMNodeRef.current = node;\n if (innerRef) {\n resolveRef(innerRef, node);\n }\n },\n [innerRef, setButtonDOMNode],\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 buttonDOMNode,\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 buttonDOMNode,\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"],
5
- "mappings": "AAAA,YAAY,WAAW;ACqBvB,OAAOA,YAAW;AAKlB,MAAM,aAAa,CACjB,KACA,SACG;AACH,MAAI,OAAO,QAAQ,YAAY;AAC7B,QAAI,IAAI;AAAA,EACV;AACA,MAAI,aAAa,KAAK;AACpB,QAAI,UAAU;AAAA,EAChB;AACF;AASO,MAAM,0BAA0B,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAqC;AACnC,QAAM,mBAAmBA,OAAM,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,wBAAmEA,OAAM;AAAA,IAC7E,CAAC,SAA4B;AAC3B,uBAAiB,IAAI;AACrB,uBAAiB,UAAU;AAC3B,UAAI,UAAU;AACZ,mBAAW,UAAU,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,IACA,CAAC,UAAU,gBAAgB;AAAA,EAC7B;AACA,QAAM,oBAAoBA,OAAM;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,SAAOA,OAAM;AAAA,IACX,OAAO;AAAA,MACL,2BAA2B;AAAA,QACzB;AAAA,QACA;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,MACA;AAAA,IACF;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* *******************************************************\n * From official source definition\n *\n * Menu Button Pattern\n * About This Pattern:\n * A menu button is a button\n * that opens a menu\n * (as described in the Menu and Menubar Pattern).\n *\n * Since the menu button is a button, it inherits all the props from the Button component.\n * Since the menu button MUST have a menu, it also have a set of specific props used to handle the menu.\n * Because we build with atomic composition in mind, the \"logic layer\" is separated and has a yet another set of props.\n *\n * This is effectively an OOP \"extension\" of the Button component,\n * so it has the same props,\n * BUT also a few more to handle the specific behavior of the menu.\n *\n * 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"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACqBvB,OAAOA,YAAW;AAElB,SAAS,kBAAkB;AAOpB,MAAM,0BAA0B,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,MAAqC;AACnC,QAAM,mBAAmBA,OAAM,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,wBAAmEA,OAAM;AAAA,IAC7E,CAAC,SAA4B;AAC3B,uBAAiB,UAAU;AAC3B,UAAI,UAAU;AACZ,mBAAW,UAAU,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,oBAAoBA,OAAM;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,SAAOA,OAAM;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;",
6
6
  "names": ["React"]
7
7
  }
@@ -14,6 +14,7 @@ import { isRootNode } from "../../utils/nodesTypeguardsAndGetters.js";
14
14
  const StyledWrapper = styled(Grid, { name: DSFlyoutMenuName, slot: FLYOUT_MENU_SLOTS.ROOT })`
15
15
  min-width: 150px;
16
16
  background-color: white;
17
+ padding: ${({ theme }) => theme.space.xxxs} 0;
17
18
  ${xStyledCommonProps}
18
19
  `;
19
20
  const StyledMenu = styled("div", { name: DSFlyoutMenuName, slot: FLYOUT_MENU_SLOTS.LIST_WRAPPER })`
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/DSFlyoutMenu/DSFlyoutMenu.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "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 ${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"],
5
- "mappings": "AAAA,YAAY,WAAW;ACsDX;AAtDZ,SAAS,uBAAuB;AAChC,SAAS,YAAY;AACrB,SAAS,gBAAgB;AACzB,SAAS,QAAQ,0BAA0B;AAC3C,OAAOA,YAAW;AAElB,SAAS,6CAA6C;AACtD,SAAS,iCAAiC;AAC1C,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB,yBAAyB;AACpD,SAAS,mCAAuD;AAChE,SAAS,kBAAkB;AAE3B,MAAM,gBAAgB,OAAO,MAAM,EAAE,MAAM,kBAAkB,MAAM,kBAAkB,KAAK,CAAC;AAAA;AAAA;AAAA,IAGvF,kBAAkB;AAAA;AAGtB,MAAM,aAAa,OAAO,OAAO,EAAE,MAAM,kBAAkB,MAAM,kBAAkB,aAAa,CAAC;AAAA;AAAA;AAAA;AAKjG,MAAM,eAAyD,CAAC,UAAU;AACxE,QAAM,EAAE,kBAAkB,aAAa,IAAI,cAAc,KAAK;AAC9D,QAAM;AAAA,IACJ;AAAA,IACA,qBAAqB,EAAE,aAAa,wBAAwB;AAAA,EAC9D,IAAIA,OAAM,WAAW,qCAAqC;AAE1D,QAAM,EAAE,gBAAgB,gBAAgB,iBAAiB,cAAc,YAAY,SAAS,IAAI;AAEhG,QAAM,kBAAkBA,OAAM;AAAA,IAC5B,CAAC,SAAyB;AACxB,UAAI,WAAW,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,8BAAC,iBAAc,eAAe,MAAM,kBAAkB,wBAAwB,OAAO,CAAC,IAAK,GAAG,cAC5F,8BAAC,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,yBAAyB,SAAS,YAAY;AACpD,uBAAuB,YAAY;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "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"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACuDX;AAvDZ,SAAS,uBAAuB;AAChC,SAAS,YAAY;AACrB,SAAS,gBAAgB;AACzB,SAAS,QAAQ,0BAA0B;AAC3C,OAAOA,YAAW;AAElB,SAAS,6CAA6C;AACtD,SAAS,iCAAiC;AAC1C,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB,yBAAyB;AACpD,SAAS,mCAAuD;AAChE,SAAS,kBAAkB;AAE3B,MAAM,gBAAgB,OAAO,MAAM,EAAE,MAAM,kBAAkB,MAAM,kBAAkB,KAAK,CAAC;AAAA;AAAA;AAAA,aAG9E,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,IAAI;AAAA,IACxC,kBAAkB;AAAA;AAGtB,MAAM,aAAa,OAAO,OAAO,EAAE,MAAM,kBAAkB,MAAM,kBAAkB,aAAa,CAAC;AAAA;AAAA;AAAA;AAKjG,MAAM,eAAyD,CAAC,UAAU;AACxE,QAAM,EAAE,kBAAkB,aAAa,IAAI,cAAc,KAAK;AAC9D,QAAM;AAAA,IACJ;AAAA,IACA,qBAAqB,EAAE,aAAa,wBAAwB;AAAA,EAC9D,IAAIA,OAAM,WAAW,qCAAqC;AAE1D,QAAM,EAAE,gBAAgB,gBAAgB,iBAAiB,cAAc,YAAY,SAAS,IAAI;AAEhG,QAAM,kBAAkBA,OAAM;AAAA,IAC5B,CAAC,SAAyB;AACxB,UAAI,WAAW,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,8BAAC,iBAAc,eAAe,MAAM,kBAAkB,wBAAwB,OAAO,CAAC,IAAK,GAAG,cAC5F,8BAAC,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,yBAAyB,SAAS,YAAY;AACpD,uBAAuB,YAAY;",
6
6
  "names": ["React"]
7
7
  }
@@ -1,11 +1,17 @@
1
1
  import * as React from "react";
2
+ import { useGetXstyledProps } from "@elliemae/ds-props-helpers";
2
3
  import React2 from "react";
3
- import { useGetXstyledProps, useMemoMergePropsWithDefault } from "@elliemae/ds-props-helpers";
4
4
  import { uid } from "uid";
5
5
  import { DSFlyoutMenuPropTypesSchema, defaultProps } from "../react-desc-prop-types.js";
6
6
  import { useValidateProps } from "./useValidateProps.js";
7
7
  const useFlyoutMenu = (propsFromUser) => {
8
- const propsWithDefault = useMemoMergePropsWithDefault(propsFromUser, defaultProps);
8
+ const propsWithDefault = React2.useMemo(
9
+ () => ({
10
+ ...defaultProps,
11
+ ...propsFromUser
12
+ }),
13
+ [propsFromUser]
14
+ );
9
15
  useValidateProps(propsWithDefault, DSFlyoutMenuPropTypesSchema);
10
16
  const xstyledProps = useGetXstyledProps(propsWithDefault);
11
17
  const instanceUid = React2.useMemo(() => `ds-flyout-menu-${uid(5)}`, []);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../src/parts/DSFlyoutMenu/config/useFlyoutMenu.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport { useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { uid } from 'uid';\nimport { type DSFlyoutMenuT, DSFlyoutMenuPropTypesSchema, defaultProps } from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nexport interface FlyoutMenuReturnedType {\n propsWithDefault: DSFlyoutMenuT.InternalProps;\n xstyledProps: ReturnType<typeof useGetXstyledProps>;\n instanceUid: string;\n}\n\nexport const useFlyoutMenu = (propsFromUser: DSFlyoutMenuT.Props) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<DSFlyoutMenuT.InternalProps>(propsFromUser, defaultProps);\n useValidateProps(propsWithDefault, DSFlyoutMenuPropTypesSchema);\n // =============================================================================\n // XSTYLED PROPS\n // =============================================================================\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n // custom code goes here, this is an example\n const instanceUid = React.useMemo(() => `ds-flyout-menu-${uid(5)}`, []);\n\n // =============================================================================\n // HELPERS HOOKS CONFIGS\n // =============================================================================\n\n return React.useMemo<FlyoutMenuReturnedType>(\n () => ({\n propsWithDefault,\n xstyledProps,\n instanceUid,\n }),\n [propsWithDefault, xstyledProps, instanceUid],\n );\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,YAAW;AAClB,SAAS,oBAAoB,oCAAoC;AACjE,SAAS,WAAW;AACpB,SAA6B,6BAA6B,oBAAoB;AAC9E,SAAS,wBAAwB;AAQ1B,MAAM,gBAAgB,CAAC,kBAAuC;AAInE,QAAM,mBAAmB,6BAA0D,eAAe,YAAY;AAC9G,mBAAiB,kBAAkB,2BAA2B;AAI9D,QAAM,eAAe,mBAAmB,gBAAgB;AAKxD,QAAM,cAAcA,OAAM,QAAQ,MAAM,kBAAkB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAMtE,SAAOA,OAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,cAAc,WAAW;AAAA,EAC9C;AACF;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useGetXstyledProps } from '@elliemae/ds-props-helpers';\nimport React from 'react';\nimport { uid } from 'uid';\nimport { DSFlyoutMenuPropTypesSchema, defaultProps, type DSFlyoutMenuT } from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nexport interface FlyoutMenuReturnedType {\n propsWithDefault: DSFlyoutMenuT.InternalProps;\n xstyledProps: ReturnType<typeof useGetXstyledProps>;\n instanceUid: string;\n}\n\nexport const useFlyoutMenu = (propsFromUser: DSFlyoutMenuT.Props) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n // the component deals with HTML DOM elements\n // Deep compare of HTML DOM elements is pointless and extremely costly\n // for this specific case, we are better of not using `useMemoMergePropsWithDefault`\n const propsWithDefault = React.useMemo(\n () => ({\n ...defaultProps,\n ...propsFromUser,\n }),\n [propsFromUser],\n ) as DSFlyoutMenuT.InternalProps;\n useValidateProps(propsWithDefault, DSFlyoutMenuPropTypesSchema);\n // =============================================================================\n // XSTYLED PROPS\n // =============================================================================\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n // custom code goes here, this is an example\n const instanceUid = React.useMemo(() => `ds-flyout-menu-${uid(5)}`, []);\n\n // =============================================================================\n // HELPERS HOOKS CONFIGS\n // =============================================================================\n\n return React.useMemo<FlyoutMenuReturnedType>(\n () => ({\n propsWithDefault,\n xstyledProps,\n instanceUid,\n }),\n [propsWithDefault, xstyledProps, instanceUid],\n );\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,0BAA0B;AACnC,OAAOA,YAAW;AAClB,SAAS,WAAW;AACpB,SAAS,6BAA6B,oBAAwC;AAC9E,SAAS,wBAAwB;AAQ1B,MAAM,gBAAgB,CAAC,kBAAuC;AAOnE,QAAM,mBAAmBA,OAAM;AAAA,IAC7B,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AACA,mBAAiB,kBAAkB,2BAA2B;AAI9D,QAAM,eAAe,mBAAmB,gBAAgB;AAKxD,QAAM,cAAcA,OAAM,QAAQ,MAAM,kBAAkB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAMtE,SAAOA,OAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,cAAc,WAAW;AAAA,EAC9C;AACF;",
6
6
  "names": ["React"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../scripts/build/transpile/react-shim.js", "../../../../src/parts/DSFlyoutMenu/react-desc-prop-types.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* 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 // anchorNode: HTMLElement | null;\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"],
5
- "mappings": "AAAA,YAAY,WAAW;ACEvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP;AAAA,EACE;AAAA,EACA,gBAAgB;AAAA,OAEX;AACP,SAAS,kBAAkB,yBAAyB;AAmC7C,MAAM,eAA2C,EAAE,GAAG,yBAAyB;AAE/E,MAAM,wBAAgE;AAAA,EAC3E,UAAU,UAAU,OAAO,YAAY,8CAA8C,EAAE;AAAA,EACvF,gBAAgB,UAAU,KAAK;AAAA,IAC7B;AAAA,EACF,EAAE;AAAA,EACF,gBAAgB,UAAU,OAAO;AAAA,IAC/B;AAAA,EACF,EAAE;AAAA,EACF,iBAAiB,UAAU,OAAO;AAAA,IAChC;AAAA,EACF,EAAE;AAAA;AAAA,EAEF,YAAY,UAAU,KAAK,YAAY,mEAAmE,EACvG;AAAA,EACH,GAAG,yBAAyB,kBAAkB,iBAAiB;AAAA,EAC/D,GAAG;AAAA;AAAA;AAAA,EAGH,GAAG;AAAA,EACH,GAAG;AACL;AAEO,MAAM,8BAA8B;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* 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"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACEvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP;AAAA,EACE;AAAA,EACA,gBAAgB;AAAA,OAEX;AACP,SAAS,kBAAkB,yBAAyB;AAkC7C,MAAM,eAA2C,EAAE,GAAG,yBAAyB;AAE/E,MAAM,wBAAgE;AAAA,EAC3E,UAAU,UAAU,OAAO,YAAY,8CAA8C,EAAE;AAAA,EACvF,gBAAgB,UAAU,KAAK;AAAA,IAC7B;AAAA,EACF,EAAE;AAAA,EACF,gBAAgB,UAAU,OAAO;AAAA,IAC/B;AAAA,EACF,EAAE;AAAA,EACF,iBAAiB,UAAU,OAAO;AAAA,IAChC;AAAA,EACF,EAAE;AAAA;AAAA,EAEF,YAAY,UAAU,KAAK,YAAY,mEAAmE,EACvG;AAAA,EACH,GAAG,yBAAyB,kBAAkB,iBAAiB;AAAA,EAC/D,GAAG;AAAA;AAAA;AAAA,EAGH,GAAG;AAAA,EACH,GAAG;AACL;AAEO,MAAM,8BAA8B;",
6
6
  "names": []
7
7
  }
@@ -17,27 +17,21 @@ const useFocusTracker = () => {
17
17
  null
18
18
  );
19
19
  const trackFocusTrigger = React2.useCallback(() => {
20
- setTimeout(() => {
21
- setFocusRegion(MENU_FOCUS_REGIONS.TRIGGER);
22
- focusedRegionPerformanceHelper.current = MENU_FOCUS_REGIONS.TRIGGER;
23
- focusedElementItemNode.current = null;
24
- });
20
+ setFocusRegion(MENU_FOCUS_REGIONS.TRIGGER);
21
+ focusedRegionPerformanceHelper.current = MENU_FOCUS_REGIONS.TRIGGER;
22
+ focusedElementItemNode.current = null;
25
23
  return null;
26
24
  }, []);
27
25
  const trackFocusNode = React2.useCallback((nodeToFocus) => {
28
26
  const newFocusRegion = MENU_FOCUS_REGIONS.ITEM_BY_DSID(nodeToFocus.dsId);
29
- setTimeout(() => {
30
- setFocusRegion(newFocusRegion);
31
- focusedRegionPerformanceHelper.current = newFocusRegion;
32
- focusedElementItemNode.current = nodeToFocus;
33
- });
27
+ setFocusRegion(newFocusRegion);
28
+ focusedRegionPerformanceHelper.current = newFocusRegion;
29
+ focusedElementItemNode.current = nodeToFocus;
34
30
  }, []);
35
31
  const trackFocusRegionReset = React2.useCallback(() => {
36
- setTimeout(() => {
37
- setFocusRegion(MENU_FOCUS_REGIONS.RESET);
38
- focusedRegionPerformanceHelper.current = MENU_FOCUS_REGIONS.RESET;
39
- focusedElementItemNode.current = null;
40
- });
32
+ setFocusRegion(MENU_FOCUS_REGIONS.RESET);
33
+ focusedRegionPerformanceHelper.current = MENU_FOCUS_REGIONS.RESET;
34
+ focusedElementItemNode.current = null;
41
35
  return null;
42
36
  }, []);
43
37
  const trackFocusFirstChildItem = React2.useCallback(
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../src/parts/DSMenuBehaviouralContextProvider/config/useFocusTracker.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* 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 // we need to guarantee that the focus is set after the current event loop or else bubbling events will trigger on the new focused element\n setTimeout(() => {\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 // we need to guarantee that the focus is set after the current event loop or else bubbling events will trigger on the new focused element\n setTimeout(() => {\n setFocusRegion(newFocusRegion);\n focusedRegionPerformanceHelper.current = newFocusRegion;\n // eslint-disable-next-line prefer-destructuring\n focusedElementItemNode.current = nodeToFocus;\n });\n }, []);\n\n const trackFocusRegionReset = React.useCallback(() => {\n // we need to guarantee that the focus is set after the current event loop or else bubbling events will trigger on the new focused element\n setTimeout(() => {\n setFocusRegion(MENU_FOCUS_REGIONS.RESET);\n focusedRegionPerformanceHelper.current = MENU_FOCUS_REGIONS.RESET;\n focusedElementItemNode.current = null;\n });\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"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable no-console */\n/* eslint-disable max-lines */\n/* 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"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -1,5 +1,4 @@
1
1
  import * as React from "react";
2
- import { useMemoMergePropsWithDefault } from "@elliemae/ds-props-helpers";
3
2
  import React2 from "react";
4
3
  import { uid } from "uid";
5
4
  import {
@@ -7,14 +6,17 @@ import {
7
6
  defaultProps
8
7
  } from "../react-desc-prop-types.js";
9
8
  import { useFocusTracker } from "./useFocusTracker.js";
9
+ import { useGlobalEvents } from "./useGlobalEvents.js";
10
10
  import { useMenuItemEventsHandlers } from "./useMenuItemEventsHandlers.js";
11
11
  import { useMenuOpenStatus } from "./useMenuOpenStatus.js";
12
12
  import { useValidateProps } from "./useValidateProps.js";
13
- import { useGlobalEvents } from "./useGlobalEvents.js";
14
13
  const useMenuBehaviouralContextProvider = (propsFromUser) => {
15
- const propsWithDefault = useMemoMergePropsWithDefault(
16
- propsFromUser,
17
- defaultProps
14
+ const propsWithDefault = React2.useMemo(
15
+ () => ({
16
+ ...defaultProps,
17
+ ...propsFromUser
18
+ }),
19
+ [propsFromUser]
18
20
  );
19
21
  useValidateProps(propsWithDefault, DSMenuBehaviouralContextProviderPropTypesSchema);
20
22
  const { onDisplayedSubmenuChange } = propsWithDefault;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../src/parts/DSMenuBehaviouralContextProvider/config/useMenuBehaviouralContextProvider.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport React from 'react';\nimport { uid } from 'uid';\nimport type { DSMenuButtonT } from '../../../react-desc-prop-types.js';\nimport {\n DSMenuBehaviouralContextProviderPropTypesSchema,\n defaultProps,\n type DSMenuBehaviouralContextProviderT,\n} from '../react-desc-prop-types.js';\nimport { useFocusTracker } from './useFocusTracker.js';\nimport { useMenuItemEventsHandlers } from './useMenuItemEventsHandlers.js';\nimport { useMenuOpenStatus } from './useMenuOpenStatus.js';\nimport { useValidateProps } from './useValidateProps.js';\nimport { useGlobalEvents } from './useGlobalEvents.js';\n\nexport interface MenuBehaviouralContextProviderCTX\n extends ReturnType<typeof useFocusTracker>,\n ReturnType<typeof useMenuOpenStatus> {\n propsWithDefault: DSMenuBehaviouralContextProviderT.InternalProps;\n instanceUid: string;\n menuItemEventsHandlers: ReturnType<typeof useMenuItemEventsHandlers>;\n openedSubItems: DSMenuButtonT.WithSubmenuMenuNodes[];\n handleChangeOpenedSubItems: Required<DSMenuButtonT.MenuBehaviouralLayerOptionalProps>['onDisplayedSubmenuChange'];\n globalEventsHelpers: ReturnType<typeof useGlobalEvents>;\n}\n\nexport const useMenuBehaviouralContextProvider = (propsFromUser: DSMenuBehaviouralContextProviderT.Props) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<DSMenuBehaviouralContextProviderT.InternalProps>(\n propsFromUser,\n defaultProps,\n );\n useValidateProps(propsWithDefault, DSMenuBehaviouralContextProviderPropTypesSchema);\n // =============================================================================\n // XSTYLED PROPS\n // =============================================================================\n // NO XSTYLED PROPS\n // this is 100% a pure logic context provider, it's not a visual component\n\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n // custom code goes here, this is an example\n const { onDisplayedSubmenuChange } = propsWithDefault;\n const instanceUid = React.useMemo(() => `ds-menu-behavioural-context-provider-${uid(5)}`, []);\n const [openedSubItems, setOpenedSubItems] = React.useState<DSMenuButtonT.WithSubmenuMenuNodes[]>([]);\n\n const handleChangeOpenedSubItems = React.useCallback<\n Required<DSMenuButtonT.MenuBehaviouralLayerOptionalProps>['onDisplayedSubmenuChange']\n >(\n (newOpenedItems, metainfo) => {\n setOpenedSubItems(newOpenedItems);\n onDisplayedSubmenuChange?.(newOpenedItems, metainfo);\n },\n [onDisplayedSubmenuChange],\n );\n\n // =============================================================================\n // HELPERS HOOKS CONFIGS\n // =============================================================================\n const focusTrackers = useFocusTracker();\n const menuOpenStatus = useMenuOpenStatus({ propsWithDefault, focusTrackers });\n\n // why item events handlers declared in the menu behaviour context provider and not in the menu item itself?\n // 1 - each menu item depending on it's own type (single select, multiple select, with submenu) will have different behaviours\n // having each menu item to declare it's own events handlers would make the single event handler way easier to create per se\n // BUT we would lose the big picture of how the menu items are interacting with each other\n // 2 - having each item to declare it's own event handler repeatdly is a waste of resources (even if it's a useless micro-optimization, it hurts me)\n const menuItemEventsHandlers = useMenuItemEventsHandlers({\n propsWithDefault,\n focusTrackers,\n menuOpenStatus,\n handleChangeOpenedSubItems,\n });\n\n // handle \"onClickOutside\" + on window blur...\n // the helpers contain a way to register the submenu refs/mainmenu refs, used in checking \"if click is outside\"\n const globalEventsHelpers = useGlobalEvents({ menuOpenStatus, handleChangeOpenedSubItems, propsWithDefault });\n\n return React.useMemo<MenuBehaviouralContextProviderCTX>(\n () => ({\n propsWithDefault,\n instanceUid,\n ...focusTrackers,\n ...menuOpenStatus,\n menuItemEventsHandlers,\n openedSubItems,\n handleChangeOpenedSubItems,\n globalEventsHelpers,\n }),\n [\n propsWithDefault,\n instanceUid,\n focusTrackers,\n menuOpenStatus,\n menuItemEventsHandlers,\n openedSubItems,\n handleChangeOpenedSubItems,\n globalEventsHelpers,\n ],\n );\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,oCAAoC;AAC7C,OAAOA,YAAW;AAClB,SAAS,WAAW;AAEpB;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,uBAAuB;AAChC,SAAS,iCAAiC;AAC1C,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAazB,MAAM,oCAAoC,CAAC,kBAA2D;AAI3G,QAAM,mBAAmB;AAAA,IACvB;AAAA,IACA;AAAA,EACF;AACA,mBAAiB,kBAAkB,+CAA+C;AAWlF,QAAM,EAAE,yBAAyB,IAAI;AACrC,QAAM,cAAcA,OAAM,QAAQ,MAAM,wCAAwC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5F,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,OAAM,SAA+C,CAAC,CAAC;AAEnG,QAAM,6BAA6BA,OAAM;AAAA,IAGvC,CAAC,gBAAgB,aAAa;AAC5B,wBAAkB,cAAc;AAChC,iCAA2B,gBAAgB,QAAQ;AAAA,IACrD;AAAA,IACA,CAAC,wBAAwB;AAAA,EAC3B;AAKA,QAAM,gBAAgB,gBAAgB;AACtC,QAAM,iBAAiB,kBAAkB,EAAE,kBAAkB,cAAc,CAAC;AAO5E,QAAM,yBAAyB,0BAA0B;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAID,QAAM,sBAAsB,gBAAgB,EAAE,gBAAgB,4BAA4B,iBAAiB,CAAC;AAE5G,SAAOA,OAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,GAAG;AAAA,MACH,GAAG;AAAA,MACH;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,IACF;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport { uid } from 'uid';\nimport type { DSMenuButtonT } from '../../../react-desc-prop-types.js';\nimport {\n DSMenuBehaviouralContextProviderPropTypesSchema,\n defaultProps,\n type DSMenuBehaviouralContextProviderT,\n} from '../react-desc-prop-types.js';\nimport { useFocusTracker } from './useFocusTracker.js';\nimport { useGlobalEvents } from './useGlobalEvents.js';\nimport { useMenuItemEventsHandlers } from './useMenuItemEventsHandlers.js';\nimport { useMenuOpenStatus } from './useMenuOpenStatus.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nexport interface MenuBehaviouralContextProviderCTX\n extends ReturnType<typeof useFocusTracker>,\n ReturnType<typeof useMenuOpenStatus> {\n propsWithDefault: DSMenuBehaviouralContextProviderT.InternalProps;\n instanceUid: string;\n menuItemEventsHandlers: ReturnType<typeof useMenuItemEventsHandlers>;\n openedSubItems: DSMenuButtonT.WithSubmenuMenuNodes[];\n handleChangeOpenedSubItems: Required<DSMenuButtonT.MenuBehaviouralLayerOptionalProps>['onDisplayedSubmenuChange'];\n globalEventsHelpers: ReturnType<typeof useGlobalEvents>;\n}\n\nexport const useMenuBehaviouralContextProvider = (propsFromUser: DSMenuBehaviouralContextProviderT.Props) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n // the component deals with HTML DOM elements,\n // Deep compare of HTML DOM elements is pointless and extremely costly\n // for this specific case, we are better of not using `useMemoMergePropsWithDefault`\n const propsWithDefault = React.useMemo(\n () => ({\n ...defaultProps,\n ...propsFromUser,\n }),\n [propsFromUser],\n ) as DSMenuBehaviouralContextProviderT.InternalProps;\n useValidateProps(propsWithDefault, DSMenuBehaviouralContextProviderPropTypesSchema);\n // =============================================================================\n // XSTYLED PROPS\n // =============================================================================\n // NO XSTYLED PROPS\n // this is 100% a pure logic context provider, it's not a visual component\n\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n // custom code goes here, this is an example\n const { onDisplayedSubmenuChange } = propsWithDefault;\n const instanceUid = React.useMemo(() => `ds-menu-behavioural-context-provider-${uid(5)}`, []);\n const [openedSubItems, setOpenedSubItems] = React.useState<DSMenuButtonT.WithSubmenuMenuNodes[]>([]);\n\n const handleChangeOpenedSubItems = React.useCallback<\n Required<DSMenuButtonT.MenuBehaviouralLayerOptionalProps>['onDisplayedSubmenuChange']\n >(\n (newOpenedItems, metainfo) => {\n setOpenedSubItems(newOpenedItems);\n onDisplayedSubmenuChange?.(newOpenedItems, metainfo);\n },\n [onDisplayedSubmenuChange],\n );\n\n // =============================================================================\n // HELPERS HOOKS CONFIGS\n // =============================================================================\n const focusTrackers = useFocusTracker();\n const menuOpenStatus = useMenuOpenStatus({ propsWithDefault, focusTrackers });\n\n // why item events handlers declared in the menu behaviour context provider and not in the menu item itself?\n // 1 - each menu item depending on it's own type (single select, multiple select, with submenu) will have different behaviours\n // having each menu item to declare it's own events handlers would make the single event handler way easier to create per se\n // BUT we would lose the big picture of how the menu items are interacting with each other\n // 2 - having each item to declare it's own event handler repeatdly is a waste of resources (even if it's a useless micro-optimization, it hurts me)\n const menuItemEventsHandlers = useMenuItemEventsHandlers({\n propsWithDefault,\n focusTrackers,\n menuOpenStatus,\n handleChangeOpenedSubItems,\n });\n\n // handle \"onClickOutside\" + on window blur...\n // the helpers contain a way to register the submenu refs/mainmenu refs, used in checking \"if click is outside\"\n const globalEventsHelpers = useGlobalEvents({ menuOpenStatus, handleChangeOpenedSubItems, propsWithDefault });\n\n return React.useMemo<MenuBehaviouralContextProviderCTX>(\n () => ({\n propsWithDefault,\n instanceUid,\n ...focusTrackers,\n ...menuOpenStatus,\n menuItemEventsHandlers,\n openedSubItems,\n handleChangeOpenedSubItems,\n globalEventsHelpers,\n }),\n [\n propsWithDefault,\n instanceUid,\n focusTrackers,\n menuOpenStatus,\n menuItemEventsHandlers,\n openedSubItems,\n handleChangeOpenedSubItems,\n globalEventsHelpers,\n ],\n );\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,YAAW;AAClB,SAAS,WAAW;AAEpB;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAChC,SAAS,iCAAiC;AAC1C,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;AAa1B,MAAM,oCAAoC,CAAC,kBAA2D;AAO3G,QAAM,mBAAmBA,OAAM;AAAA,IAC7B,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AACA,mBAAiB,kBAAkB,+CAA+C;AAWlF,QAAM,EAAE,yBAAyB,IAAI;AACrC,QAAM,cAAcA,OAAM,QAAQ,MAAM,wCAAwC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5F,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,OAAM,SAA+C,CAAC,CAAC;AAEnG,QAAM,6BAA6BA,OAAM;AAAA,IAGvC,CAAC,gBAAgB,aAAa;AAC5B,wBAAkB,cAAc;AAChC,iCAA2B,gBAAgB,QAAQ;AAAA,IACrD;AAAA,IACA,CAAC,wBAAwB;AAAA,EAC3B;AAKA,QAAM,gBAAgB,gBAAgB;AACtC,QAAM,iBAAiB,kBAAkB,EAAE,kBAAkB,cAAc,CAAC;AAO5E,QAAM,yBAAyB,0BAA0B;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAID,QAAM,sBAAsB,gBAAgB,EAAE,gBAAgB,4BAA4B,iBAAiB,CAAC;AAE5G,SAAOA,OAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,GAAG;AAAA,MACH,GAAG;AAAA,MACH;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,IACF;AAAA,EACF;AACF;",
6
6
  "names": ["React"]
7
7
  }
@@ -1,5 +1,4 @@
1
1
  import * as React from "react";
2
- import debounce from "lodash/debounce";
3
2
  import React2 from "react";
4
3
  import {
5
4
  isFocusableNode,
@@ -153,14 +152,17 @@ const useMenuItemEventsHandlers = ({
153
152
  if (pseudoFocusedItemNode === null) throw UNEXPECTED_INTERNAL_ERRORS.FOCUSED_ITEM_NODE_NOT_SET;
154
153
  if (pseudoFocusedItemNode.plainItem.onKeyDown) pseudoFocusedItemNode.plainItem.onKeyDown(event);
155
154
  if (event.key === "ArrowDown") {
155
+ event?.preventDefault();
156
156
  trackFocusNextItem(pseudoFocusedItemNode);
157
157
  return;
158
158
  }
159
159
  if (event.key === "ArrowUp") {
160
+ event?.preventDefault();
160
161
  trackFocusPreviousItem(pseudoFocusedItemNode);
161
162
  return;
162
163
  }
163
164
  if (event.key === "ArrowLeft") {
165
+ event?.preventDefault();
164
166
  handleMenuItemLeftArrowKeyDown({ pseudoFocusedItemNode, event });
165
167
  return;
166
168
  }
@@ -194,10 +196,12 @@ const useMenuItemEventsHandlers = ({
194
196
  return;
195
197
  }
196
198
  if (event.key === " ") {
199
+ event?.preventDefault();
197
200
  handleMenuItemSpaceKeyDown({ pseudoFocusedItemNode, event });
198
201
  return;
199
202
  }
200
203
  if (event.key === "ArrowRight") {
204
+ event?.preventDefault();
201
205
  handleMenuItemRightArrowKeyDown({ pseudoFocusedItemNode, event });
202
206
  return;
203
207
  }
@@ -259,31 +263,13 @@ const useMenuItemEventsHandlers = ({
259
263
  },
260
264
  [focusedElementItemNode, handleMenuItemSpaceKeyDown, handleChangeOpenedSubItems]
261
265
  );
262
- const handleMenuItemFocusReconciliation = React2.useCallback(
263
- (itemNode) => {
264
- debounce(
265
- () => {
266
- if (focusedElementItemNode.current?.dsId !== itemNode.dsId) trackFocusNode(itemNode);
267
- },
268
- 10,
269
- { leading: false, trailing: true }
270
- );
271
- },
272
- [focusedElementItemNode, trackFocusNode]
273
- );
274
266
  return React2.useMemo(
275
267
  () => ({
276
268
  handleFocusableMenuItemKeyDown,
277
269
  handleFocusableMenuItemClick,
278
- handleFocusableMenuItemOnMouseEnter,
279
- handleMenuItemFocusReconciliation
270
+ handleFocusableMenuItemOnMouseEnter
280
271
  }),
281
- [
282
- handleFocusableMenuItemClick,
283
- handleFocusableMenuItemKeyDown,
284
- handleFocusableMenuItemOnMouseEnter,
285
- handleMenuItemFocusReconciliation
286
- ]
272
+ [handleFocusableMenuItemClick, handleFocusableMenuItemKeyDown, handleFocusableMenuItemOnMouseEnter]
287
273
  );
288
274
  };
289
275
  export {