@elliemae/ds-menu-button 3.39.0-rc.3 → 3.39.0-rc.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. package/dist/cjs/DSMenuButtonCTX.js.map +2 -2
  2. package/dist/cjs/config/useMenuButton.js +8 -2
  3. package/dist/cjs/config/useMenuButton.js.map +2 -2
  4. package/dist/cjs/parts/{SubMenu.js → Menu.js} +6 -7
  5. package/dist/cjs/parts/Menu.js.map +7 -0
  6. package/dist/cjs/parts/MenuButtonContent.js +9 -15
  7. package/dist/cjs/parts/MenuButtonContent.js.map +2 -2
  8. package/dist/cjs/parts/MenuItem.js +14 -5
  9. package/dist/cjs/parts/MenuItem.js.map +2 -2
  10. package/dist/cjs/react-desc-prop-types.js.map +2 -2
  11. package/dist/cjs/styled.js +13 -1
  12. package/dist/cjs/styled.js.map +2 -2
  13. package/dist/esm/DSMenuButtonCTX.js.map +2 -2
  14. package/dist/esm/config/useMenuButton.js +8 -2
  15. package/dist/esm/config/useMenuButton.js.map +2 -2
  16. package/dist/esm/parts/{SubMenu.js → Menu.js} +3 -4
  17. package/dist/esm/parts/Menu.js.map +7 -0
  18. package/dist/esm/parts/MenuButtonContent.js +10 -16
  19. package/dist/esm/parts/MenuButtonContent.js.map +2 -2
  20. package/dist/esm/parts/MenuItem.js +14 -5
  21. package/dist/esm/parts/MenuItem.js.map +2 -2
  22. package/dist/esm/react-desc-prop-types.js.map +2 -2
  23. package/dist/esm/styled.js +14 -2
  24. package/dist/esm/styled.js.map +2 -2
  25. package/dist/types/DSMenuButtonCTX.d.ts +4 -0
  26. package/dist/types/config/useMenuButton.d.ts +5 -1
  27. package/dist/types/parts/{SubMenu.d.ts → Menu.d.ts} +1 -1
  28. package/dist/types/react-desc-prop-types.d.ts +18 -16
  29. package/dist/types/styled.d.ts +1 -0
  30. package/package.json +10 -10
  31. package/dist/cjs/parts/SubMenu.js.map +0 -7
  32. package/dist/esm/parts/SubMenu.js.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/DSMenuButtonCTX.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import React from 'react';\nimport type { MenuButtonT } from './react-desc-prop-types.js';\ninterface MenuButtonContextProps<T extends object = object> {\n focusedOption: string | null;\n setFocusedOption: React.Dispatch<React.SetStateAction<string | null>>;\n selectedKeys: string[];\n onSelectionChange: (selectedKeys: string[], parentId: string, item: MenuButtonT.Item) => void;\n propsWithDefault: MenuButtonT.InternalProps<T>;\n}\n\nconst defaultContext = {} as MenuButtonContextProps<object>;\n\nexport const MenuButtonContext = React.createContext(defaultContext);\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAkB;AAUlB,MAAM,iBAAiB,CAAC;AAEjB,MAAM,oBAAoB,aAAAA,QAAM,cAAc,cAAc;",
4
+ "sourcesContent": ["import React from 'react';\nimport type { MenuButtonT } from './react-desc-prop-types.js';\ninterface MenuButtonContextProps<T extends object = object> {\n focusedOption: string | null;\n setFocusedOption: React.Dispatch<React.SetStateAction<string | null>>;\n selectedKeys: string[];\n onSelectionChange: (selectedKeys: string[], parentId: string, item: MenuButtonT.Item) => void;\n triggerElementRef: HTMLElement | null;\n setTriggerElementRef: React.Dispatch<React.SetStateAction<HTMLElement | null>>;\n isOpen: boolean;\n setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n propsWithDefault: MenuButtonT.InternalProps<T>;\n}\n\nconst defaultContext = {} as MenuButtonContextProps<object>;\n\nexport const MenuButtonContext = React.createContext(defaultContext);\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAkB;AAclB,MAAM,iBAAiB,CAAC;AAEjB,MAAM,oBAAoB,aAAAA,QAAM,cAAc,cAAc;",
6
6
  "names": ["React"]
7
7
  }
@@ -41,15 +41,21 @@ const useDSMenuButton = (propsFromUser) => {
41
41
  (0, import_useValidateProps.useValidateProps)(propsWithDefault, import_react_desc_prop_types.DSDMenuButtonPropTypes);
42
42
  const { selectedKeys, onSelectionChange } = propsWithDefault;
43
43
  const [focusedOption, setFocusedOption] = (0, import_react.useState)(null);
44
+ const [triggerElementRef, setTriggerElementRef] = (0, import_react.useState)(null);
45
+ const [isOpen, setIsOpen] = (0, import_react.useState)(false);
44
46
  return (0, import_react.useMemo)(
45
47
  () => ({
46
48
  propsWithDefault,
47
49
  focusedOption,
48
50
  setFocusedOption,
49
51
  selectedKeys,
50
- onSelectionChange
52
+ onSelectionChange,
53
+ triggerElementRef,
54
+ setTriggerElementRef,
55
+ isOpen,
56
+ setIsOpen
51
57
  }),
52
- [focusedOption, propsWithDefault, selectedKeys, onSelectionChange]
58
+ [propsWithDefault, focusedOption, selectedKeys, onSelectionChange, triggerElementRef, isOpen]
53
59
  );
54
60
  };
55
61
  //# sourceMappingURL=useMenuButton.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/config/useMenuButton.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import { useMemo, useState } from 'react';\nimport { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { type MenuButtonT, DSDMenuButtonPropTypes, defaultProps } from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nexport const useDSMenuButton = <T extends object = object>(propsFromUser: MenuButtonT.Props<T>) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<MenuButtonT.InternalProps<T>>(propsFromUser, defaultProps);\n useValidateProps(propsWithDefault, DSDMenuButtonPropTypes);\n\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n\n const { selectedKeys, onSelectionChange } = propsWithDefault;\n const [focusedOption, setFocusedOption] = useState<string | null>(null);\n\n return useMemo(\n () => ({\n propsWithDefault,\n focusedOption,\n setFocusedOption,\n selectedKeys,\n onSelectionChange,\n }),\n [focusedOption, propsWithDefault, selectedKeys, onSelectionChange],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAkC;AAClC,8BAA6C;AAC7C,mCAAuE;AACvE,8BAAiC;AAE1B,MAAM,kBAAkB,CAA4B,kBAAwC;AAIjG,QAAM,uBAAmB,sDAA2D,eAAe,yCAAY;AAC/G,gDAAiB,kBAAkB,mDAAsB;AAMzD,QAAM,EAAE,cAAc,kBAAkB,IAAI;AAC5C,QAAM,CAAC,eAAe,gBAAgB,QAAI,uBAAwB,IAAI;AAEtE,aAAO;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,eAAe,kBAAkB,cAAc,iBAAiB;AAAA,EACnE;AACF;",
4
+ "sourcesContent": ["import { useMemo, useState } from 'react';\nimport { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { type MenuButtonT, DSDMenuButtonPropTypes, defaultProps } from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nexport const useDSMenuButton = <T extends object = object>(propsFromUser: MenuButtonT.Props<T>) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<MenuButtonT.InternalProps<T>>(propsFromUser, defaultProps);\n useValidateProps(propsWithDefault, DSDMenuButtonPropTypes);\n\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n\n const { selectedKeys, onSelectionChange } = propsWithDefault;\n const [focusedOption, setFocusedOption] = useState<string | null>(null);\n const [triggerElementRef, setTriggerElementRef] = useState<HTMLElement | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n\n return useMemo(\n () => ({\n propsWithDefault,\n focusedOption,\n setFocusedOption,\n selectedKeys,\n onSelectionChange,\n triggerElementRef,\n setTriggerElementRef,\n isOpen,\n setIsOpen,\n }),\n [propsWithDefault, focusedOption, selectedKeys, onSelectionChange, triggerElementRef, isOpen],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAkC;AAClC,8BAA6C;AAC7C,mCAAuE;AACvE,8BAAiC;AAE1B,MAAM,kBAAkB,CAA4B,kBAAwC;AAIjG,QAAM,uBAAmB,sDAA2D,eAAe,yCAAY;AAC/G,gDAAiB,kBAAkB,mDAAsB;AAMzD,QAAM,EAAE,cAAc,kBAAkB,IAAI;AAC5C,QAAM,CAAC,eAAe,gBAAgB,QAAI,uBAAwB,IAAI;AACtE,QAAM,CAAC,mBAAmB,oBAAoB,QAAI,uBAA6B,IAAI;AACnF,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,KAAK;AAE1C,aAAO;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,eAAe,cAAc,mBAAmB,mBAAmB,MAAM;AAAA,EAC9F;AACF;",
6
6
  "names": []
7
7
  }
@@ -26,11 +26,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var SubMenu_exports = {};
30
- __export(SubMenu_exports, {
31
- SubMenu: () => SubMenu
29
+ var Menu_exports = {};
30
+ __export(Menu_exports, {
31
+ Menu: () => Menu
32
32
  });
33
- module.exports = __toCommonJS(SubMenu_exports);
33
+ module.exports = __toCommonJS(Menu_exports);
34
34
  var React = __toESM(require("react"));
35
35
  var import_jsx_runtime = require("react/jsx-runtime");
36
36
  var import_react = __toESM(require("react"));
@@ -38,7 +38,7 @@ var import_ds_hooks_keyboard_navigation = require("@elliemae/ds-hooks-keyboard-n
38
38
  var import_DSMenuButtonCTX = require("../DSMenuButtonCTX.js");
39
39
  var import_styled = require("../styled.js");
40
40
  var import_ItemFactory = require("./ItemFactory.js");
41
- const SubMenu = (props) => {
41
+ const Menu = (props) => {
42
42
  const { referenceElement, showSubMenu, selectionMode, setShowSubMenu, parentId, level, items, minWidth } = props;
43
43
  const { focusedOption, setFocusedOption } = (0, import_react.useContext)(import_DSMenuButtonCTX.MenuButtonContext);
44
44
  const listRef = import_react.default.useRef(null);
@@ -89,7 +89,6 @@ const SubMenu = (props) => {
89
89
  },
90
90
  [onBlur, setShowSubMenu]
91
91
  );
92
- console.log(minWidth, "minWidth");
93
92
  const subMenuStyles = (0, import_react.useMemo)(
94
93
  () => ({
95
94
  position: "absolute",
@@ -123,4 +122,4 @@ const SubMenu = (props) => {
123
122
  }
124
123
  );
125
124
  };
126
- //# sourceMappingURL=SubMenu.js.map
125
+ //# sourceMappingURL=Menu.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/parts/Menu.tsx", "../../../../../../scripts/build/transpile/react-shim.js"],
4
+ "sourcesContent": ["/* eslint-disable import/no-cycle */\nimport React, { useState, useMemo, useCallback, useContext } from 'react';\nimport { useKeyboardNavigation, DIRECTIONS } from '@elliemae/ds-hooks-keyboard-navigation';\nimport { MenuButtonContext } from '../DSMenuButtonCTX.js';\nimport type { MenuButtonT } from '../react-desc-prop-types.js';\nimport { StyledMenu } from '../styled.js';\nimport { ItemFactory } from './ItemFactory.js';\n\ninterface SubMenuProps {\n referenceElement: HTMLElement | null;\n showSubMenu: boolean;\n selectionMode?: 'single' | 'multiple';\n setShowSubMenu: React.Dispatch<React.SetStateAction<boolean>>;\n parentId?: string;\n level: number;\n items: MenuButtonT.Item[];\n minWidth?: string | number;\n}\n\nexport const Menu: React.FC<SubMenuProps> = (props) => {\n const { referenceElement, showSubMenu, selectionMode, setShowSubMenu, parentId, level, items, minWidth } = props;\n const { focusedOption, setFocusedOption } = useContext(MenuButtonContext);\n const listRef = React.useRef<HTMLDivElement>(null);\n const rect = referenceElement?.getBoundingClientRect();\n const [coords, setCoords] = useState<{ x: number; y: number }>({ x: rect?.width ?? 0, y: 0 });\n\n // this logic will be part of the new popper custom hook\n React.useLayoutEffect(() => {\n const listRect = listRef?.current?.getBoundingClientRect();\n if (!listRect) return;\n if (level === 1) {\n if (listRect.bottom < window.innerHeight) {\n setCoords({ x: 0, y: rect?.height || 0 });\n } else {\n setCoords({ x: 0, y: -listRect.height });\n }\n return;\n }\n if (listRect.right > window.innerWidth) {\n setCoords({ x: -(rect?.width || 0), y: 0 });\n } else {\n setCoords({ x: rect?.width || 0, y: 0 });\n }\n }, [level, rect?.height, rect?.width, referenceElement]);\n\n const config = {\n options: items.filter((item) => item.type !== 'separator' && item.type !== 'section').map((item) => item.dsId),\n direction: DIRECTIONS.VERTICAL,\n focusedOption,\n setFocusedOption,\n };\n\n const { getWrapperProps, getItemProps } = useKeyboardNavigation(config);\n\n const { onKeyDown, onBlur } = getWrapperProps();\n\n const handleOnMenuKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.stopPropagation();\n }\n onKeyDown(event);\n },\n [onKeyDown],\n );\n\n const handleOnBlur: React.FocusEventHandler<HTMLDivElement> = useCallback(\n (e) => {\n setTimeout(() => {\n if (!listRef.current?.contains(document.activeElement)) {\n setShowSubMenu(false);\n }\n });\n onBlur(e);\n },\n [onBlur, setShowSubMenu],\n );\n\n const subMenuStyles = useMemo(\n () => ({\n position: 'absolute',\n top: coords.y,\n left: coords.x,\n zIndex: 1001 + level,\n minWidth,\n }),\n [coords, level, minWidth],\n );\n\n if (!referenceElement || !showSubMenu) return null;\n\n return (\n <StyledMenu\n innerRef={listRef}\n role=\"menu\"\n onKeyDown={handleOnMenuKeyDown}\n onBlur={handleOnBlur}\n style={subMenuStyles}\n >\n {items.map((item) => (\n <ItemFactory\n key={item.dsId}\n item={item}\n selectionMode={selectionMode}\n level={level}\n parentId={parentId}\n {...getItemProps(item.dsId)}\n />\n ))}\n </StyledMenu>\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": "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",
6
+ "names": ["React"]
7
+ }
@@ -35,7 +35,7 @@ var React = __toESM(require("react"));
35
35
  var import_jsx_runtime = require("react/jsx-runtime");
36
36
  var import_react = __toESM(require("react"));
37
37
  var import_ds_props_helpers = require("@elliemae/ds-props-helpers");
38
- var import_SubMenu = require("./SubMenu.js");
38
+ var import_Menu = require("./Menu.js");
39
39
  var import_DSMenuButtonCTX = require("../DSMenuButtonCTX.js");
40
40
  var import_styled = require("../styled.js");
41
41
  function useOnClickOutside(ref, cb) {
@@ -55,9 +55,7 @@ function useOnClickOutside(ref, cb) {
55
55
  }, [ref, cb]);
56
56
  }
57
57
  const MenuButtonContent = () => {
58
- const [referenceElement, setReferenceElement] = (0, import_react.useState)(null);
59
- const [isOpen, setIsOpen] = (0, import_react.useState)(false);
60
- const { setFocusedOption, propsWithDefault } = (0, import_react.useContext)(import_DSMenuButtonCTX.MenuButtonContext);
58
+ const { setFocusedOption, triggerElementRef, setTriggerElementRef, isOpen, setIsOpen, propsWithDefault } = (0, import_react.useContext)(import_DSMenuButtonCTX.MenuButtonContext);
61
59
  const { items, TriggerElement, selectionMode, triggerElementProps, menuMinWidth } = propsWithDefault;
62
60
  const globalProps = (0, import_ds_props_helpers.useGetGlobalAttributes)(propsWithDefault);
63
61
  const xstyledProps = (0, import_ds_props_helpers.useGetXstyledProps)(propsWithDefault);
@@ -71,7 +69,7 @@ const MenuButtonContent = () => {
71
69
  const handleOnKeyDown = (0, import_react.useCallback)(
72
70
  (event) => {
73
71
  if (event.key === "Escape") {
74
- referenceElement?.focus();
72
+ triggerElementRef?.focus();
75
73
  }
76
74
  if (event.key === "ArrowDown" && isOpen) {
77
75
  event.preventDefault();
@@ -81,15 +79,11 @@ const MenuButtonContent = () => {
81
79
  event.preventDefault();
82
80
  setFocusedOption(items[items.length - 1].dsId);
83
81
  }
84
- if (event.key === "Enter" && isOpen) {
85
- event.preventDefault();
86
- setIsOpen(false);
87
- referenceElement?.focus();
88
- } else if ((event.key === "Enter" || event.key === " ") && !isOpen && firstItem) {
82
+ if ((event.key === "Enter" || event.key === " ") && !isOpen && firstItem) {
89
83
  setFocusedOption(firstItem?.dsId);
90
84
  }
91
85
  },
92
- [firstItem, items, isOpen, referenceElement, setFocusedOption]
86
+ [isOpen, firstItem, triggerElementRef, setFocusedOption, items]
93
87
  );
94
88
  const handleOnTriggerOnKeyDown = (0, import_react.useCallback)(
95
89
  (e) => {
@@ -102,7 +96,7 @@ const MenuButtonContent = () => {
102
96
  );
103
97
  const handleOnClick = (0, import_react.useCallback)(() => {
104
98
  setIsOpen(!isOpen);
105
- }, [isOpen]);
99
+ }, [isOpen, setIsOpen]);
106
100
  const attributes = (0, import_react.useMemo)(
107
101
  () => ({
108
102
  "aria-haspopup": "true",
@@ -131,7 +125,7 @@ const MenuButtonContent = () => {
131
125
  TriggerElement,
132
126
  {
133
127
  isOpen,
134
- innerRef: setReferenceElement,
128
+ innerRef: setTriggerElementRef,
135
129
  setIsOpen,
136
130
  attributes,
137
131
  listeners,
@@ -139,13 +133,13 @@ const MenuButtonContent = () => {
139
133
  }
140
134
  ),
141
135
  isOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
142
- import_SubMenu.SubMenu,
136
+ import_Menu.Menu,
143
137
  {
144
138
  level: 1,
145
139
  items,
146
140
  showSubMenu: isOpen,
147
141
  setShowSubMenu: setIsOpen,
148
- referenceElement,
142
+ referenceElement: triggerElementRef,
149
143
  selectionMode,
150
144
  minWidth: menuMinWidth
151
145
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/parts/MenuButtonContent.tsx", "../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable complexity */\nimport React, { useState, useMemo, useCallback, useContext, useRef } from 'react';\nimport { useGetGlobalAttributes, useGetXstyledProps } from '@elliemae/ds-props-helpers';\nimport { SubMenu } from './SubMenu.js';\nimport { MenuButtonContext } from '../DSMenuButtonCTX.js';\n\nimport { StyledMenuButtonWrapper } from '../styled.js';\nfunction useOnClickOutside(ref: React.RefObject<HTMLElement>, cb: (event: MouseEvent | TouchEvent) => void) {\n React.useEffect(() => {\n const listener = (event: MouseEvent | TouchEvent) => {\n // Do nothing if clicking ref's element or descendent elements\n if (!ref?.current || ref?.current?.contains?.(event.target as Node)) {\n return;\n }\n cb(event);\n };\n document.addEventListener('mousedown', listener);\n document.addEventListener('touchstart', listener);\n return () => {\n document.removeEventListener('mousedown', listener);\n document.removeEventListener('touchstart', listener);\n };\n }, [ref, cb]);\n}\n\nexport const MenuButtonContent = () => {\n const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const { setFocusedOption, propsWithDefault } = useContext(MenuButtonContext);\n\n const { items, TriggerElement, selectionMode, triggerElementProps, menuMinWidth } = propsWithDefault;\n const globalProps = useGetGlobalAttributes(propsWithDefault);\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n\n const firstItem = useMemo(() => {\n const first = items.find((item) => item.type !== 'separator');\n if (first && first.type === 'section') {\n return first.childrens?.find((item) => item.type !== 'separator');\n }\n return first;\n }, [items]);\n\n const handleOnKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'Escape') {\n referenceElement?.focus();\n }\n if (event.key === 'ArrowDown' && isOpen) {\n event.preventDefault();\n setFocusedOption(firstItem?.dsId || '');\n }\n if (event.key === 'ArrowUp' && isOpen) {\n event.preventDefault();\n setFocusedOption(items[items.length - 1].dsId);\n }\n\n // Enter to close the menu and focus the trigger element\n if (event.key === 'Enter' && isOpen) {\n event.preventDefault();\n setIsOpen(false);\n referenceElement?.focus();\n } else if ((event.key === 'Enter' || event.key === ' ') && !isOpen && firstItem) {\n setFocusedOption(firstItem?.dsId);\n }\n },\n [firstItem, items, isOpen, referenceElement, setFocusedOption],\n );\n\n const handleOnTriggerOnKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setFocusedOption(items[0]?.dsId);\n }\n },\n [items, setFocusedOption],\n );\n\n const handleOnClick = useCallback(() => {\n setIsOpen(!isOpen);\n }, [isOpen]);\n\n const attributes = useMemo(\n () => ({\n 'aria-haspopup': 'true',\n 'aria-expanded': isOpen,\n }),\n [isOpen],\n );\n\n const listeners = useMemo(\n () => ({\n onKeyDown: handleOnTriggerOnKeyDown,\n }),\n [handleOnTriggerOnKeyDown],\n );\n\n const containerRef = useRef<HTMLDivElement | null>(null);\n useOnClickOutside(containerRef, () => setIsOpen(false));\n\n return (\n <StyledMenuButtonWrapper\n onClick={handleOnClick}\n onKeyDown={handleOnKeyDown}\n innerRef={containerRef}\n {...globalProps}\n {...xstyledProps}\n >\n <TriggerElement\n isOpen={isOpen}\n innerRef={setReferenceElement}\n setIsOpen={setIsOpen}\n attributes={attributes}\n listeners={listeners}\n triggerElementProps={triggerElementProps}\n />\n {isOpen && (\n <SubMenu\n level={1}\n items={items}\n showSubMenu={isOpen}\n setShowSubMenu={setIsOpen}\n referenceElement={referenceElement}\n selectionMode={selectionMode}\n minWidth={menuMinWidth}\n />\n )}\n </StyledMenuButtonWrapper>\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable complexity */\nimport React, { useMemo, useCallback, useContext, useRef } from 'react';\nimport { useGetGlobalAttributes, useGetXstyledProps } from '@elliemae/ds-props-helpers';\nimport { Menu } from './Menu.js';\nimport { MenuButtonContext } from '../DSMenuButtonCTX.js';\n\nimport { StyledMenuButtonWrapper } from '../styled.js';\nfunction useOnClickOutside(ref: React.RefObject<HTMLElement>, cb: (event: MouseEvent | TouchEvent) => void) {\n React.useEffect(() => {\n const listener = (event: MouseEvent | TouchEvent) => {\n // Do nothing if clicking ref's element or descendent elements\n if (!ref?.current || ref?.current?.contains?.(event.target as Node)) {\n return;\n }\n cb(event);\n };\n document.addEventListener('mousedown', listener);\n document.addEventListener('touchstart', listener);\n return () => {\n document.removeEventListener('mousedown', listener);\n document.removeEventListener('touchstart', listener);\n };\n }, [ref, cb]);\n}\n\nexport const MenuButtonContent = () => {\n const { setFocusedOption, triggerElementRef, setTriggerElementRef, isOpen, setIsOpen, propsWithDefault } =\n useContext(MenuButtonContext);\n\n const { items, TriggerElement, selectionMode, triggerElementProps, menuMinWidth } = propsWithDefault;\n const globalProps = useGetGlobalAttributes(propsWithDefault);\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n\n const firstItem = useMemo(() => {\n const first = items.find((item) => item.type !== 'separator');\n if (first && first.type === 'section') {\n return first.childrens?.find((item) => item.type !== 'separator');\n }\n return first;\n }, [items]);\n\n const handleOnKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'Escape') {\n triggerElementRef?.focus();\n }\n if (event.key === 'ArrowDown' && isOpen) {\n event.preventDefault();\n setFocusedOption(firstItem?.dsId || '');\n }\n if (event.key === 'ArrowUp' && isOpen) {\n event.preventDefault();\n setFocusedOption(items[items.length - 1].dsId);\n }\n\n if ((event.key === 'Enter' || event.key === ' ') && !isOpen && firstItem) {\n setFocusedOption(firstItem?.dsId);\n }\n },\n [isOpen, firstItem, triggerElementRef, setFocusedOption, items],\n );\n\n const handleOnTriggerOnKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setFocusedOption(items[0]?.dsId);\n }\n },\n [items, setFocusedOption],\n );\n\n const handleOnClick = useCallback(() => {\n setIsOpen(!isOpen);\n }, [isOpen, setIsOpen]);\n\n const attributes = useMemo(\n () => ({\n 'aria-haspopup': 'true',\n 'aria-expanded': isOpen,\n }),\n [isOpen],\n );\n\n const listeners = useMemo(\n () => ({\n onKeyDown: handleOnTriggerOnKeyDown,\n }),\n [handleOnTriggerOnKeyDown],\n );\n\n const containerRef = useRef<HTMLDivElement | null>(null);\n useOnClickOutside(containerRef, () => setIsOpen(false));\n\n return (\n <StyledMenuButtonWrapper\n onClick={handleOnClick}\n onKeyDown={handleOnKeyDown}\n innerRef={containerRef}\n {...globalProps}\n {...xstyledProps}\n >\n <TriggerElement\n isOpen={isOpen}\n innerRef={setTriggerElementRef}\n setIsOpen={setIsOpen}\n attributes={attributes}\n listeners={listeners}\n triggerElementProps={triggerElementProps}\n />\n {isOpen && (\n <Menu\n level={1}\n items={items}\n showSubMenu={isOpen}\n setShowSubMenu={setIsOpen}\n referenceElement={triggerElementRef}\n selectionMode={selectionMode}\n minWidth={menuMinWidth}\n />\n )}\n </StyledMenuButtonWrapper>\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -42,7 +42,7 @@ var import_ds_system = require("@elliemae/ds-system");
42
42
  var import_ds_grid = require("@elliemae/ds-grid");
43
43
  var import_DSMenuButtonCTX = require("../DSMenuButtonCTX.js");
44
44
  var import_styled = require("../styled.js");
45
- var import_SubMenu = require("./SubMenu.js");
45
+ var import_Menu = require("./Menu.js");
46
46
  const MenuItemAddon = import_react.default.memo(({ level, isOpen }) => {
47
47
  if (level === 0)
48
48
  return isOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ds_icons.TriangleUpSmall, { color: ["brand-primary", "600"] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ds_icons.TriangleDownSmall, { color: ["brand-primary", "600"] });
@@ -63,6 +63,8 @@ const MenuItem = ({
63
63
  focusedOption,
64
64
  selectedKeys,
65
65
  onSelectionChange,
66
+ triggerElementRef,
67
+ setIsOpen,
66
68
  propsWithDefault: { ItemRenderer }
67
69
  } = import_react.default.useContext(import_DSMenuButtonCTX.MenuButtonContext);
68
70
  const listRef = import_react.default.useRef(null);
@@ -78,6 +80,7 @@ const MenuItem = ({
78
80
  [focusedOption, item.dsId]
79
81
  );
80
82
  const selectionLogic = (0, import_react.useCallback)(() => {
83
+ if (item.disabled) return;
81
84
  if (selectionMode === "single") {
82
85
  const newValue = item.dsId === selectedKeys[0] ? [] : [item.dsId];
83
86
  onSelectionChange(newValue, parentId || "root", item);
@@ -89,15 +92,19 @@ const MenuItem = ({
89
92
  }, [item, onSelectionChange, parentId, selectedKeys, selectionMode]);
90
93
  const handleOnClick = (0, import_react.useCallback)(
91
94
  (e) => {
92
- if (selectionMode === "multiple") {
95
+ if (selectionMode === "multiple" || item.disabled) {
93
96
  e.stopPropagation();
94
97
  }
95
98
  selectionLogic();
96
99
  },
97
- [selectionLogic, selectionMode]
100
+ [item.disabled, selectionLogic, selectionMode]
98
101
  );
99
102
  const onItemKeyDown = (0, import_react.useCallback)(
100
103
  (event) => {
104
+ if (event.key === "Enter" && !item.disabled) {
105
+ setIsOpen(false);
106
+ triggerElementRef?.focus();
107
+ }
101
108
  if (event.key === "Enter" || event.key === " ") {
102
109
  event.preventDefault();
103
110
  selectionLogic();
@@ -119,7 +126,7 @@ const MenuItem = ({
119
126
  }
120
127
  }
121
128
  },
122
- [level, item.subitems, selectionLogic, setFocusedOption, parentId]
129
+ [item.disabled, item.subitems, level, setIsOpen, triggerElementRef, selectionLogic, setFocusedOption, parentId]
123
130
  );
124
131
  const handleOnLIKeyDown = (0, import_react.useCallback)(
125
132
  (e) => {
@@ -171,6 +178,7 @@ const MenuItem = ({
171
178
  isOpen: showSubMenu,
172
179
  level,
173
180
  isVertical,
181
+ disabled: item.disabled,
174
182
  children: [
175
183
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
176
184
  import_styled.StyledMenuItemContent,
@@ -185,6 +193,7 @@ const MenuItem = ({
185
193
  hasChildren: item.subitems !== void 0,
186
194
  onFocus,
187
195
  tabIndex,
196
+ "aria-disabled": item.disabled ? "true" : "false",
188
197
  children: ItemRenderer ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ItemRenderer, { item, isSelected: selectedKeys.includes(item.dsId) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
189
198
  MenuItemContent,
190
199
  {
@@ -198,7 +207,7 @@ const MenuItem = ({
198
207
  }
199
208
  ),
200
209
  item.subitems && showSubMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
201
- import_SubMenu.SubMenu,
210
+ import_Menu.Menu,
202
211
  {
203
212
  level: level + 1,
204
213
  items: item.subitems,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/parts/MenuItem.tsx", "../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable import/no-cycle */\n/* eslint-disable @typescript-eslint/no-use-before-define */\n/* eslint-disable complexity */\n/* eslint-disable max-lines */\nimport React, { useState, useCallback, useMemo } from 'react';\nimport {\n TriangleUpSmall,\n CheckmarkXsmall,\n TriangleDownSmall,\n ChevronSmallDown,\n ChevronSmallRight,\n} from '@elliemae/ds-icons';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport { mergeRefs } from '@elliemae/ds-system';\nimport { Grid } from '@elliemae/ds-grid';\nimport { MenuButtonContext } from '../DSMenuButtonCTX.js';\nimport {\n StyledMenuItem,\n StyledMenuItemContent,\n StyledLeftContent,\n StyledRightContent,\n StyledSeparator,\n StyledSection,\n} from '../styled.js';\nimport { SubMenu } from './SubMenu.js';\nimport type { MenuButtonT } from '../react-desc-prop-types.js';\n\nexport const MenuItemAddon = React.memo(({ level, isOpen }: { level: number; isOpen: boolean }) => {\n if (level === 0)\n return isOpen ? (\n <TriangleUpSmall color={['brand-primary', '600']} />\n ) : (\n <TriangleDownSmall color={['brand-primary', '600']} />\n );\n return isOpen ? (\n <ChevronSmallDown size=\"m\" color={['brand-primary', '600']} />\n ) : (\n <ChevronSmallRight size=\"m\" color={['brand-primary', '600']} />\n );\n});\n\nexport const MenuItem = ({\n innerRef,\n tabIndex,\n onFocus,\n selectionMode,\n item,\n level,\n parentId,\n isVertical,\n}: {\n selectionMode?: 'single' | 'multiple';\n item: MenuButtonT.Item;\n level: number;\n parentId: string | undefined;\n isVertical?: boolean;\n tabIndex: number;\n onFocus: React.FocusEventHandler;\n innerRef: TypescriptHelpersT.AnyRef<HTMLElement>;\n}) => {\n const {\n setFocusedOption,\n focusedOption,\n selectedKeys,\n onSelectionChange,\n propsWithDefault: { ItemRenderer },\n } = React.useContext(MenuButtonContext);\n const listRef = React.useRef(null);\n const [showSubMenu, setShowSubMenu] = useState(false);\n const [referenceElement, setReferenceElement] = React.useState<HTMLElement | null>(null);\n const itemRef = useCallback(\n (node: HTMLElement | null) => {\n if (node !== null) {\n if (focusedOption === item.dsId) node.focus();\n }\n return node;\n },\n [focusedOption, item.dsId],\n );\n\n const selectionLogic = useCallback(() => {\n if (selectionMode === 'single') {\n const newValue = item.dsId === selectedKeys[0] ? [] : [item.dsId];\n onSelectionChange(newValue, parentId || 'root', item);\n }\n if (selectionMode === 'multiple') {\n const newValue = selectedKeys.includes(item.dsId)\n ? selectedKeys.filter((key: string) => key !== item.dsId)\n : [...selectedKeys, item.dsId];\n onSelectionChange(newValue, parentId || 'root', item);\n }\n }, [item, onSelectionChange, parentId, selectedKeys, selectionMode]);\n\n const handleOnClick: React.MouseEventHandler = useCallback(\n (e) => {\n if (selectionMode === 'multiple') {\n e.stopPropagation();\n }\n selectionLogic();\n },\n [selectionLogic, selectionMode],\n );\n const onItemKeyDown: React.KeyboardEventHandler = useCallback(\n (event) => {\n // selection\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n selectionLogic();\n }\n // open submenu logic\n if (\n ((event.key === 'ArrowDown' && level === 0) || (event.key === 'ArrowRight' && level !== 0)) &&\n item.subitems\n ) {\n event.preventDefault();\n event.stopPropagation();\n setShowSubMenu(true);\n setFocusedOption(item.subitems[0].dsId);\n }\n\n // close submenu logic\n if (event.key === 'ArrowLeft' && level >= 2) {\n event.preventDefault();\n event.stopPropagation();\n if (parentId) setFocusedOption(parentId);\n }\n if (event.key === 'Escape' && level > 0) {\n if (parentId !== undefined) {\n setFocusedOption(parentId);\n }\n }\n },\n [level, item.subitems, selectionLogic, setFocusedOption, parentId],\n );\n\n const handleOnLIKeyDown: React.KeyboardEventHandler = useCallback(\n (e) => {\n // logic to close all submenus and focus on parent\n if (e.key === 'Enter') {\n setShowSubMenu(false);\n if (level === 0) {\n setFocusedOption(item.dsId);\n }\n }\n },\n [item.dsId, level, setFocusedOption],\n );\n\n const handleOnMouseEnter = useCallback(() => {\n setShowSubMenu(true);\n setFocusedOption(item.dsId);\n }, [item.dsId, setFocusedOption]);\n\n const handleOnMouseLeave = useCallback(() => {\n setShowSubMenu(false);\n }, []);\n\n const ariaExpanded = useMemo(() => {\n if (item.subitems) {\n return showSubMenu ? 'true' : 'false';\n }\n return undefined;\n }, [item.subitems, showSubMenu]);\n\n const role = useMemo(() => {\n if (selectionMode === 'single') {\n return 'menuitemradio';\n }\n if (selectionMode === 'multiple') {\n return 'menuitemcheckbox';\n }\n return 'menuitem';\n }, [selectionMode]);\n\n const ariaChecked = useMemo(() => {\n if (selectionMode === 'multiple' || selectionMode === 'single') {\n return selectedKeys.includes(item.dsId) ? 'true' : 'false';\n }\n return undefined;\n }, [item.dsId, selectionMode, selectedKeys]);\n\n return (\n <StyledMenuItem\n role=\"none\"\n innerRef={listRef}\n onMouseEnter={handleOnMouseEnter}\n onMouseLeave={handleOnMouseLeave}\n onKeyDown={handleOnLIKeyDown}\n isOpen={showSubMenu}\n level={level}\n isVertical={isVertical}\n >\n <StyledMenuItemContent\n role={role}\n aria-checked={ariaChecked}\n aria-haspopup={item.subitems ? 'true' : 'false'}\n aria-expanded={ariaExpanded}\n innerRef={mergeRefs(innerRef, itemRef, setReferenceElement)}\n onKeyDown={onItemKeyDown}\n onClick={handleOnClick}\n hasChildren={item.subitems !== undefined}\n onFocus={onFocus}\n tabIndex={tabIndex}\n >\n {ItemRenderer ? (\n <ItemRenderer item={item} isSelected={selectedKeys.includes(item.dsId)} />\n ) : (\n <MenuItemContent\n item={item}\n selectionMode={selectionMode}\n selectedKeys={selectedKeys}\n showSubMenu={showSubMenu}\n level={level}\n />\n )}\n </StyledMenuItemContent>\n {item.subitems && showSubMenu && (\n <SubMenu\n level={level + 1}\n items={item.subitems}\n showSubMenu={showSubMenu}\n setShowSubMenu={setShowSubMenu}\n referenceElement={referenceElement}\n parentId={item.dsId}\n selectionMode={item.selectionMode}\n minWidth={item.minWidth}\n />\n )}\n </StyledMenuItem>\n );\n};\n\nconst MenuItemContent = React.memo(\n ({\n item,\n selectionMode,\n selectedKeys,\n showSubMenu,\n level,\n }: {\n item: MenuButtonT.Item;\n selectionMode?: 'single' | 'multiple';\n selectedKeys: string[];\n showSubMenu: boolean;\n level: number;\n }) => (\n <>\n <StyledLeftContent>\n <SelectionAddon selectionMode={selectionMode} item={item} selectedKeys={selectedKeys} />\n <span style={{ lineHeight: 1.15 }}>{item.label}</span>\n </StyledLeftContent>\n <StyledRightContent>\n {item.subitems ? <MenuItemAddon isOpen={showSubMenu} level={level} /> : null}\n </StyledRightContent>\n </>\n ),\n);\n\nconst SelectionAddon = ({\n item,\n selectedKeys,\n selectionMode,\n}: {\n item: MenuButtonT.Item;\n selectedKeys: string[];\n selectionMode?: 'single' | 'multiple';\n}) => {\n if (selectionMode) {\n return selectedKeys.includes(item.dsId) ? (\n <Grid>\n <CheckmarkXsmall size=\"m\" color={['brand-primary', '600']} />\n </Grid>\n ) : (\n <div style={{ width: '24px' }} />\n );\n }\n return null;\n};\n\nexport const Separator = () => (\n <li role=\"none\" style={{ padding: '0px 16px' }}>\n <StyledSeparator role=\"separator\" />\n </li>\n);\n\nexport const Section = ({ item }: { item: MenuButtonT.Item }) => (\n <li role=\"none\" style={{ padding: '0px 16px', minHeight: 24, display: 'flex', alignItems: 'center' }}>\n <StyledSection role=\"presentation\">{item.label}</StyledSection>\n </li>\n);\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable import/no-cycle */\n/* eslint-disable @typescript-eslint/no-use-before-define */\n/* eslint-disable complexity */\n/* eslint-disable max-lines */\nimport React, { useState, useCallback, useMemo } from 'react';\nimport {\n TriangleUpSmall,\n CheckmarkXsmall,\n TriangleDownSmall,\n ChevronSmallDown,\n ChevronSmallRight,\n} from '@elliemae/ds-icons';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport { mergeRefs } from '@elliemae/ds-system';\nimport { Grid } from '@elliemae/ds-grid';\nimport { MenuButtonContext } from '../DSMenuButtonCTX.js';\nimport {\n StyledMenuItem,\n StyledMenuItemContent,\n StyledLeftContent,\n StyledRightContent,\n StyledSeparator,\n StyledSection,\n} from '../styled.js';\nimport { Menu } from './Menu.js';\nimport type { MenuButtonT } from '../react-desc-prop-types.js';\n\nexport const MenuItemAddon = React.memo(({ level, isOpen }: { level: number; isOpen: boolean }) => {\n if (level === 0)\n return isOpen ? (\n <TriangleUpSmall color={['brand-primary', '600']} />\n ) : (\n <TriangleDownSmall color={['brand-primary', '600']} />\n );\n return isOpen ? (\n <ChevronSmallDown size=\"m\" color={['brand-primary', '600']} />\n ) : (\n <ChevronSmallRight size=\"m\" color={['brand-primary', '600']} />\n );\n});\n\nexport const MenuItem = ({\n innerRef,\n tabIndex,\n onFocus,\n selectionMode,\n item,\n level,\n parentId,\n isVertical,\n}: {\n selectionMode?: 'single' | 'multiple';\n item: MenuButtonT.Item;\n level: number;\n parentId: string | undefined;\n isVertical?: boolean;\n tabIndex: number;\n onFocus: React.FocusEventHandler;\n innerRef: TypescriptHelpersT.AnyRef<HTMLElement>;\n}) => {\n const {\n setFocusedOption,\n focusedOption,\n selectedKeys,\n onSelectionChange,\n triggerElementRef,\n setIsOpen,\n propsWithDefault: { ItemRenderer },\n } = React.useContext(MenuButtonContext);\n const listRef = React.useRef(null);\n const [showSubMenu, setShowSubMenu] = useState(false);\n const [referenceElement, setReferenceElement] = React.useState<HTMLElement | null>(null);\n const itemRef = useCallback(\n (node: HTMLElement | null) => {\n if (node !== null) {\n if (focusedOption === item.dsId) node.focus();\n }\n return node;\n },\n [focusedOption, item.dsId],\n );\n\n const selectionLogic = useCallback(() => {\n if (item.disabled) return;\n if (selectionMode === 'single') {\n const newValue = item.dsId === selectedKeys[0] ? [] : [item.dsId];\n onSelectionChange(newValue, parentId || 'root', item);\n }\n if (selectionMode === 'multiple') {\n const newValue = selectedKeys.includes(item.dsId)\n ? selectedKeys.filter((key: string) => key !== item.dsId)\n : [...selectedKeys, item.dsId];\n onSelectionChange(newValue, parentId || 'root', item);\n }\n }, [item, onSelectionChange, parentId, selectedKeys, selectionMode]);\n\n const handleOnClick: React.MouseEventHandler = useCallback(\n (e) => {\n if (selectionMode === 'multiple' || item.disabled) {\n e.stopPropagation();\n }\n selectionLogic();\n },\n [item.disabled, selectionLogic, selectionMode],\n );\n const onItemKeyDown: React.KeyboardEventHandler = useCallback(\n (event) => {\n // Enter to close the menu and focus the trigger element\n if (event.key === 'Enter' && !item.disabled) {\n setIsOpen(false);\n triggerElementRef?.focus();\n }\n // selection\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n selectionLogic();\n }\n // open submenu logic\n if (\n ((event.key === 'ArrowDown' && level === 0) || (event.key === 'ArrowRight' && level !== 0)) &&\n item.subitems\n ) {\n event.preventDefault();\n event.stopPropagation();\n setShowSubMenu(true);\n setFocusedOption(item.subitems[0].dsId);\n }\n\n // close submenu logic\n if (event.key === 'ArrowLeft' && level >= 2) {\n event.preventDefault();\n event.stopPropagation();\n if (parentId) setFocusedOption(parentId);\n }\n if (event.key === 'Escape' && level > 0) {\n if (parentId !== undefined) {\n setFocusedOption(parentId);\n }\n }\n },\n [item.disabled, item.subitems, level, setIsOpen, triggerElementRef, selectionLogic, setFocusedOption, parentId],\n );\n\n const handleOnLIKeyDown: React.KeyboardEventHandler = useCallback(\n (e) => {\n // logic to close all submenus and focus on parent\n if (e.key === 'Enter') {\n setShowSubMenu(false);\n if (level === 0) {\n setFocusedOption(item.dsId);\n }\n }\n },\n [item.dsId, level, setFocusedOption],\n );\n\n const handleOnMouseEnter = useCallback(() => {\n setShowSubMenu(true);\n setFocusedOption(item.dsId);\n }, [item.dsId, setFocusedOption]);\n\n const handleOnMouseLeave = useCallback(() => {\n setShowSubMenu(false);\n }, []);\n\n const ariaExpanded = useMemo(() => {\n if (item.subitems) {\n return showSubMenu ? 'true' : 'false';\n }\n return undefined;\n }, [item.subitems, showSubMenu]);\n\n const role = useMemo(() => {\n if (selectionMode === 'single') {\n return 'menuitemradio';\n }\n if (selectionMode === 'multiple') {\n return 'menuitemcheckbox';\n }\n return 'menuitem';\n }, [selectionMode]);\n\n const ariaChecked = useMemo(() => {\n if (selectionMode === 'multiple' || selectionMode === 'single') {\n return selectedKeys.includes(item.dsId) ? 'true' : 'false';\n }\n return undefined;\n }, [item.dsId, selectionMode, selectedKeys]);\n\n return (\n <StyledMenuItem\n role=\"none\"\n innerRef={listRef}\n onMouseEnter={handleOnMouseEnter}\n onMouseLeave={handleOnMouseLeave}\n onKeyDown={handleOnLIKeyDown}\n isOpen={showSubMenu}\n level={level}\n isVertical={isVertical}\n disabled={item.disabled}\n >\n <StyledMenuItemContent\n role={role}\n aria-checked={ariaChecked}\n aria-haspopup={item.subitems ? 'true' : 'false'}\n aria-expanded={ariaExpanded}\n innerRef={mergeRefs(innerRef, itemRef, setReferenceElement)}\n onKeyDown={onItemKeyDown}\n onClick={handleOnClick}\n hasChildren={item.subitems !== undefined}\n onFocus={onFocus}\n tabIndex={tabIndex}\n aria-disabled={item.disabled ? 'true' : 'false'}\n >\n {ItemRenderer ? (\n <ItemRenderer item={item} isSelected={selectedKeys.includes(item.dsId)} />\n ) : (\n <MenuItemContent\n item={item}\n selectionMode={selectionMode}\n selectedKeys={selectedKeys}\n showSubMenu={showSubMenu}\n level={level}\n />\n )}\n </StyledMenuItemContent>\n {item.subitems && showSubMenu && (\n <Menu\n level={level + 1}\n items={item.subitems}\n showSubMenu={showSubMenu}\n setShowSubMenu={setShowSubMenu}\n referenceElement={referenceElement}\n parentId={item.dsId}\n selectionMode={item.selectionMode}\n minWidth={item.minWidth}\n />\n )}\n </StyledMenuItem>\n );\n};\n\nconst MenuItemContent = React.memo(\n ({\n item,\n selectionMode,\n selectedKeys,\n showSubMenu,\n level,\n }: {\n item: MenuButtonT.Item;\n selectionMode?: 'single' | 'multiple';\n selectedKeys: string[];\n showSubMenu: boolean;\n level: number;\n }) => (\n <>\n <StyledLeftContent>\n <SelectionAddon selectionMode={selectionMode} item={item} selectedKeys={selectedKeys} />\n <span style={{ lineHeight: 1.15 }}>{item.label}</span>\n </StyledLeftContent>\n <StyledRightContent>\n {item.subitems ? <MenuItemAddon isOpen={showSubMenu} level={level} /> : null}\n </StyledRightContent>\n </>\n ),\n);\n\nconst SelectionAddon = ({\n item,\n selectedKeys,\n selectionMode,\n}: {\n item: MenuButtonT.Item;\n selectedKeys: string[];\n selectionMode?: 'single' | 'multiple';\n}) => {\n if (selectionMode) {\n return selectedKeys.includes(item.dsId) ? (\n <Grid>\n <CheckmarkXsmall size=\"m\" color={['brand-primary', '600']} />\n </Grid>\n ) : (\n <div style={{ width: '24px' }} />\n );\n }\n return null;\n};\n\nexport const Separator = () => (\n <li role=\"none\" style={{ padding: '0px 16px' }}>\n <StyledSeparator role=\"separator\" />\n </li>\n);\n\nexport const Section = ({ item }: { item: MenuButtonT.Item }) => (\n <li role=\"none\" style={{ padding: '0px 16px', minHeight: 24, display: 'flex', alignItems: 'center' }}>\n <StyledSection role=\"presentation\">{item.label}</StyledSection>\n </li>\n);\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/react-desc-prop-types.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { GlobalAttributesT, XstyledProps, DSPropTypesSchema } from '@elliemae/ds-props-helpers';\nimport { PropTypes, globalAttributesPropTypes, xstyledPropTypes } from '@elliemae/ds-props-helpers';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type { WeakValidationMap } from 'react';\n\nexport declare namespace MenuButtonT {\n export interface RequiredProps {\n items: Item[];\n TriggerElement: React.ComponentType<TriggerElementProps>;\n }\n\n export interface DefaultProps {\n selectedKeys: string[];\n onSelectionChange: (selectedKeys: string[]) => void;\n }\n\n export interface OptionalProps<T extends object = object> {\n triggerElementProps?: T;\n selectionMode?: 'single' | 'multiple';\n menuMinWidth?: string | number;\n ItemRenderer?: React.ComponentType<{ item: Item; isSelected: boolean }>;\n }\n\n export interface Props<T extends object = object>\n extends Partial<DefaultProps>,\n OptionalProps<T>,\n Omit<GlobalAttributesT<HTMLButtonElement>, keyof OptionalProps<T> | keyof XstyledProps>,\n XstyledProps,\n RequiredProps {}\n\n export interface InternalProps<T extends object = object>\n extends DefaultProps,\n OptionalProps<T>,\n Omit<GlobalAttributesT<HTMLButtonElement>, keyof OptionalProps<T> | keyof XstyledProps>,\n XstyledProps,\n RequiredProps {}\n\n export type Item = {\n dsId: string;\n label: string;\n type?: 'separator' | 'section';\n childrens?: Item[];\n subitems: Item[];\n selectionMode?: 'single' | 'multiple';\n minWidth?: string;\n };\n\n export interface TriggerElementProps {\n isOpen: boolean;\n innerRef: TypescriptHelpersT.AnyRef<HTMLElement>;\n setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n attributes: {\n 'aria-haspopup': string;\n 'aria-expanded': boolean;\n };\n listeners: {\n onKeyDown: (e: React.KeyboardEvent) => void;\n };\n triggerElementProps?: OptionalProps['triggerElementProps'];\n }\n}\n\nexport const defaultProps: MenuButtonT.DefaultProps = {\n selectedKeys: [],\n onSelectionChange: () => {},\n};\n\nexport const DSDMenuButtonPropTypes: DSPropTypesSchema<MenuButtonT.Props<object>> = {\n ...globalAttributesPropTypes,\n ...xstyledPropTypes,\n items: PropTypes.arrayOf(\n PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n label: PropTypes.string,\n type: PropTypes.oneOf(['separator', 'section', 'single', 'multiple', undefined]),\n }),\n ).description('Array of items to be displayed in the dropdown').isRequired,\n TriggerElement: PropTypes.node.description('Component to be used as the trigger element').isRequired,\n selectedKeys: PropTypes.arrayOf(PropTypes.string).description('Array of selected keys'),\n onSelectionChange: PropTypes.func.description('Function to be called when selection changes'),\n triggerElementProps: PropTypes.object.description('Props to be passed to the trigger element'),\n selectionMode: PropTypes.oneOf(['single', 'multiple']).description('Selection mode'),\n menuMinWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).description(\n 'Minimum width of the main dropdown',\n ),\n ItemRenderer: PropTypes.node.description('Component to be used to render the items'),\n};\n\nexport const DSDMenuButtonPropTypesSchema = DSDMenuButtonPropTypes as unknown as WeakValidationMap<\n MenuButtonT.Props<object>\n>;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADEvB,8BAAuE;AA6DhE,MAAM,eAAyC;AAAA,EACpD,cAAc,CAAC;AAAA,EACf,mBAAmB,MAAM;AAAA,EAAC;AAC5B;AAEO,MAAM,yBAAuE;AAAA,EAClF,GAAG;AAAA,EACH,GAAG;AAAA,EACH,OAAO,kCAAU;AAAA,IACf,kCAAU,MAAM;AAAA,MACd,MAAM,kCAAU,OAAO;AAAA,MACvB,OAAO,kCAAU;AAAA,MACjB,MAAM,kCAAU,MAAM,CAAC,aAAa,WAAW,UAAU,YAAY,MAAS,CAAC;AAAA,IACjF,CAAC;AAAA,EACH,EAAE,YAAY,gDAAgD,EAAE;AAAA,EAChE,gBAAgB,kCAAU,KAAK,YAAY,6CAA6C,EAAE;AAAA,EAC1F,cAAc,kCAAU,QAAQ,kCAAU,MAAM,EAAE,YAAY,wBAAwB;AAAA,EACtF,mBAAmB,kCAAU,KAAK,YAAY,8CAA8C;AAAA,EAC5F,qBAAqB,kCAAU,OAAO,YAAY,2CAA2C;AAAA,EAC7F,eAAe,kCAAU,MAAM,CAAC,UAAU,UAAU,CAAC,EAAE,YAAY,gBAAgB;AAAA,EACnF,cAAc,kCAAU,UAAU,CAAC,kCAAU,QAAQ,kCAAU,MAAM,CAAC,EAAE;AAAA,IACtE;AAAA,EACF;AAAA,EACA,cAAc,kCAAU,KAAK,YAAY,0CAA0C;AACrF;AAEO,MAAM,+BAA+B;",
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { GlobalAttributesT, XstyledProps, DSPropTypesSchema } from '@elliemae/ds-props-helpers';\nimport { PropTypes, globalAttributesPropTypes, xstyledPropTypes } from '@elliemae/ds-props-helpers';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type { WeakValidationMap } from 'react';\n\nexport declare namespace MenuButtonT {\n export interface RequiredProps<T> {\n items: Item[];\n TriggerElement: React.ComponentType<TriggerElementProps<T>>;\n }\n\n export interface DefaultProps {\n selectedKeys: string[];\n onSelectionChange: (selectedKeys: string[], parentId: string, item: MenuButtonT.Item) => void;\n }\n\n export interface OptionalProps<T extends object> {\n triggerElementProps?: T;\n selectionMode?: 'single' | 'multiple';\n menuMinWidth?: string | number;\n ItemRenderer?: ItemRendererT;\n }\n\n export interface Props<T extends object = object>\n extends Partial<DefaultProps>,\n OptionalProps<T>,\n Omit<GlobalAttributesT<HTMLButtonElement>, keyof OptionalProps<T> | keyof XstyledProps>,\n XstyledProps,\n RequiredProps<T> {}\n\n export interface InternalProps<T extends object = object>\n extends DefaultProps,\n OptionalProps<T>,\n Omit<GlobalAttributesT<HTMLButtonElement>, keyof OptionalProps<T> | keyof XstyledProps>,\n XstyledProps,\n RequiredProps<T> {}\n\n export type Item = {\n dsId: string;\n label: string;\n type?: 'separator' | 'section';\n childrens?: Item[];\n subitems?: Item[];\n selectionMode?: 'single' | 'multiple';\n minWidth?: string | number;\n disabled?: boolean;\n };\n\n export interface TriggerElementProps<T2> {\n isOpen: boolean;\n innerRef: TypescriptHelpersT.AnyRef<HTMLButtonElement | null>;\n setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n attributes: {\n 'aria-haspopup'?: boolean | 'true' | 'false' | 'dialog' | 'grid' | 'listbox' | 'menu' | 'tree';\n 'aria-expanded': boolean;\n };\n listeners: {\n onKeyDown: (e: React.KeyboardEvent) => void;\n };\n triggerElementProps: T2;\n }\n\n export type ItemRendererT = React.ComponentType<{ item: Item; isSelected: boolean }>;\n}\n\nexport const defaultProps: MenuButtonT.DefaultProps = {\n selectedKeys: [],\n onSelectionChange: () => {},\n};\n\nexport const DSDMenuButtonPropTypes: DSPropTypesSchema<MenuButtonT.Props<object>> = {\n ...globalAttributesPropTypes,\n ...xstyledPropTypes,\n items: PropTypes.arrayOf(\n PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n label: PropTypes.string,\n type: PropTypes.oneOf(['separator', 'section', 'single', 'multiple', undefined]),\n }),\n ).description('Array of items to be displayed in the dropdown').isRequired,\n TriggerElement: PropTypes.node.description('Component to be used as the trigger element').isRequired,\n selectedKeys: PropTypes.arrayOf(PropTypes.string).description('Array of selected keys'),\n onSelectionChange: PropTypes.func.description('Function to be called when selection changes'),\n triggerElementProps: PropTypes.object.description('Props to be passed to the trigger element'),\n selectionMode: PropTypes.oneOf(['single', 'multiple']).description('Selection mode'),\n menuMinWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).description(\n 'Minimum width of the main dropdown',\n ),\n ItemRenderer: PropTypes.node.description('Component to be used to render the items'),\n};\n\nexport const DSDMenuButtonPropTypesSchema = DSDMenuButtonPropTypes as unknown as WeakValidationMap<\n MenuButtonT.Props<object>\n>;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADEvB,8BAAuE;AAgEhE,MAAM,eAAyC;AAAA,EACpD,cAAc,CAAC;AAAA,EACf,mBAAmB,MAAM;AAAA,EAAC;AAC5B;AAEO,MAAM,yBAAuE;AAAA,EAClF,GAAG;AAAA,EACH,GAAG;AAAA,EACH,OAAO,kCAAU;AAAA,IACf,kCAAU,MAAM;AAAA,MACd,MAAM,kCAAU,OAAO;AAAA,MACvB,OAAO,kCAAU;AAAA,MACjB,MAAM,kCAAU,MAAM,CAAC,aAAa,WAAW,UAAU,YAAY,MAAS,CAAC;AAAA,IACjF,CAAC;AAAA,EACH,EAAE,YAAY,gDAAgD,EAAE;AAAA,EAChE,gBAAgB,kCAAU,KAAK,YAAY,6CAA6C,EAAE;AAAA,EAC1F,cAAc,kCAAU,QAAQ,kCAAU,MAAM,EAAE,YAAY,wBAAwB;AAAA,EACtF,mBAAmB,kCAAU,KAAK,YAAY,8CAA8C;AAAA,EAC5F,qBAAqB,kCAAU,OAAO,YAAY,2CAA2C;AAAA,EAC7F,eAAe,kCAAU,MAAM,CAAC,UAAU,UAAU,CAAC,EAAE,YAAY,gBAAgB;AAAA,EACnF,cAAc,kCAAU,UAAU,CAAC,kCAAU,QAAQ,kCAAU,MAAM,CAAC,EAAE;AAAA,IACtE;AAAA,EACF;AAAA,EACA,cAAc,kCAAU,KAAK,YAAY,0CAA0C;AACrF;AAEO,MAAM,+BAA+B;",
6
6
  "names": []
7
7
  }
@@ -41,6 +41,16 @@ __export(styled_exports, {
41
41
  module.exports = __toCommonJS(styled_exports);
42
42
  var React = __toESM(require("react"));
43
43
  var import_ds_system = require("@elliemae/ds-system");
44
+ const disabledOption = () => import_ds_system.css`
45
+ a {
46
+ color: ${({ theme }) => theme.colors.neutral[500]};
47
+ }
48
+ background-color: ${({ theme }) => theme.colors.neutral["000"]};
49
+ cursor: not-allowed;
50
+ * {
51
+ cursor: not-allowed;
52
+ }
53
+ `;
44
54
  const StyledMenuButtonWrapper = (0, import_ds_system.styled)("div")`
45
55
  position: relative;
46
56
  `;
@@ -81,6 +91,8 @@ const StyledMenuItem = (0, import_ds_system.styled)("li")`
81
91
  }
82
92
 
83
93
  ${({ isOpen, theme }) => isOpen ? `background-color: ${theme.colors.brand["200"]}` : ""}
94
+
95
+ ${({ disabled }) => disabled ? disabledOption() : ""}
84
96
  `;
85
97
  const StyledMenuItemContent = (0, import_ds_system.styled)("a")`
86
98
  display: flex;
@@ -88,7 +100,7 @@ const StyledMenuItemContent = (0, import_ds_system.styled)("a")`
88
100
  justify-content: space-between;
89
101
  width: 100%;
90
102
  text-decoration: none;
91
- color: black;
103
+ color: inherit;
92
104
  &:focus {
93
105
  outline: none;
94
106
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/styled.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import { xStyledCommonProps, styled } from '@elliemae/ds-system';\n\nexport const StyledMenuButtonWrapper = styled('div')`\n position: relative;\n`;\n\nexport const StyledMenu = styled('ul')`\n display: flex;\n flex-direction: column;\n gap: 1px;\n list-style-type: none;\n padding: 0;\n margin: 0;\n background-color: white;\n /* height: 100%; */\n ${xStyledCommonProps}\n box-shadow: 0 0 0 1px rgba(16, 22, 26, 0.1),\n 0 2px 4px rgba(16, 22, 26, 0.2),\n 0 8px 24px rgba(16, 22, 26, 0.2);\n`;\n\nexport const StyledMenuItem = styled('li')<{ isVertical?: boolean; level?: number; isOpen?: boolean }>`\n position: relative;\n background-color: white;\n display: flex;\n margin: 0;\n min-height: 32px;\n width: ${({ isVertical, level }) => (!isVertical && level === 0 ? 'auto' : '100%')};\n cursor: pointer;\n\n ul li {\n min-width: 200px;\n }\n\n &:hover {\n background-color: brand-200;\n }\n\n a:focus {\n outline: 1px solid brand-500;\n background-color: brand-200;\n }\n\n ${({ isOpen, theme }) => (isOpen ? `background-color: ${theme.colors.brand['200']}` : '')}\n`;\n\nexport const StyledMenuItemContent = styled('a')<{ hasChildren?: boolean }>`\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n text-decoration: none;\n color: black;\n &:focus {\n outline: none;\n }\n ${({ hasChildren }) => (hasChildren ? 'padding-left: 16px;' : 'padding: 0 16px;')}\n ${xStyledCommonProps}\n`;\n\nexport const StyledLeftContent = styled('div')`\n display: flex;\n align-items: center;\n gap: 4px;\n height: 100%;\n`;\n\nexport const StyledRightContent = styled('div')`\n display: flex;\n align-items: center;\n`;\n\nexport const StyledSeparator = styled('hr')`\n border: 0;\n border-top: 1px solid #697489;\n margin: 4px 0px;\n padding: 0;\n`;\n\nexport const StyledSectionLabel = styled('div')`\n color: neutral-500;\n display: flex;\n flex-direction: column;\n gap: 1px;\n padding: 0 16px;\n min-height: 24px;\n justify-content: center;\n`;\n\nexport const StyledSection = styled('div')`\n display: flex;\n flex-direction: column;\n gap: 1px;\n`;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,uBAA2C;AAEpC,MAAM,8BAA0B,yBAAO,KAAK;AAAA;AAAA;AAI5C,MAAM,iBAAa,yBAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASjC,mCAAkB;AAAA;AAAA;AAAA;AAAA;AAMf,MAAM,qBAAiB,yBAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAM9B,CAAC,EAAE,YAAY,MAAM,MAAO,CAAC,cAAc,UAAU,IAAI,SAAS,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgBhF,CAAC,EAAE,QAAQ,MAAM,MAAO,SAAS,qBAAqB,MAAM,OAAO,MAAM,KAAK,CAAC,KAAK,EAAG;AAAA;AAGpF,MAAM,4BAAwB,yBAAO,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAU3C,CAAC,EAAE,YAAY,MAAO,cAAc,wBAAwB,kBAAmB;AAAA,IAC/E,mCAAkB;AAAA;AAGf,MAAM,wBAAoB,yBAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAOtC,MAAM,yBAAqB,yBAAO,KAAK;AAAA;AAAA;AAAA;AAKvC,MAAM,sBAAkB,yBAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAOnC,MAAM,yBAAqB,yBAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUvC,MAAM,oBAAgB,yBAAO,KAAK;AAAA;AAAA;AAAA;AAAA;",
4
+ "sourcesContent": ["import { xStyledCommonProps, styled, css } from '@elliemae/ds-system';\n\nconst disabledOption = () => css`\n a {\n color: ${({ theme }) => theme.colors.neutral[500]};\n }\n background-color: ${({ theme }) => theme.colors.neutral['000']};\n cursor: not-allowed;\n * {\n cursor: not-allowed;\n }\n`;\n\nexport const StyledMenuButtonWrapper = styled('div')`\n position: relative;\n`;\n\nexport const StyledMenu = styled('ul')`\n display: flex;\n flex-direction: column;\n gap: 1px;\n list-style-type: none;\n padding: 0;\n margin: 0;\n background-color: white;\n /* height: 100%; */\n ${xStyledCommonProps}\n box-shadow: 0 0 0 1px rgba(16, 22, 26, 0.1),\n 0 2px 4px rgba(16, 22, 26, 0.2),\n 0 8px 24px rgba(16, 22, 26, 0.2);\n`;\n\nexport const StyledMenuItem = styled('li')<{\n isVertical?: boolean;\n level?: number;\n isOpen?: boolean;\n disabled?: boolean;\n}>`\n position: relative;\n background-color: white;\n display: flex;\n margin: 0;\n min-height: 32px;\n width: ${({ isVertical, level }) => (!isVertical && level === 0 ? 'auto' : '100%')};\n cursor: pointer;\n\n ul li {\n min-width: 200px;\n }\n\n &:hover {\n background-color: brand-200;\n }\n\n a:focus {\n outline: 1px solid brand-500;\n background-color: brand-200;\n }\n\n ${({ isOpen, theme }) => (isOpen ? `background-color: ${theme.colors.brand['200']}` : '')}\n\n ${({ disabled }) => (disabled ? disabledOption() : '')}\n`;\n\nexport const StyledMenuItemContent = styled('a')<{ hasChildren?: boolean }>`\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n text-decoration: none;\n color: inherit;\n &:focus {\n outline: none;\n }\n ${({ hasChildren }) => (hasChildren ? 'padding-left: 16px;' : 'padding: 0 16px;')}\n ${xStyledCommonProps}\n`;\n\nexport const StyledLeftContent = styled('div')`\n display: flex;\n align-items: center;\n gap: 4px;\n height: 100%;\n`;\n\nexport const StyledRightContent = styled('div')`\n display: flex;\n align-items: center;\n`;\n\nexport const StyledSeparator = styled('hr')`\n border: 0;\n border-top: 1px solid #697489;\n margin: 4px 0px;\n padding: 0;\n`;\n\nexport const StyledSectionLabel = styled('div')`\n color: neutral-500;\n display: flex;\n flex-direction: column;\n gap: 1px;\n padding: 0 16px;\n min-height: 24px;\n justify-content: center;\n`;\n\nexport const StyledSection = styled('div')`\n display: flex;\n flex-direction: column;\n gap: 1px;\n`;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,uBAAgD;AAEhD,MAAM,iBAAiB,MAAM;AAAA;AAAA,aAEhB,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,QAAQ,GAAG,CAAC;AAAA;AAAA,sBAE/B,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,QAAQ,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAOzD,MAAM,8BAA0B,yBAAO,KAAK;AAAA;AAAA;AAI5C,MAAM,iBAAa,yBAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASjC,mCAAkB;AAAA;AAAA;AAAA;AAAA;AAMf,MAAM,qBAAiB,yBAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAW9B,CAAC,EAAE,YAAY,MAAM,MAAO,CAAC,cAAc,UAAU,IAAI,SAAS,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgBhF,CAAC,EAAE,QAAQ,MAAM,MAAO,SAAS,qBAAqB,MAAM,OAAO,MAAM,KAAK,CAAC,KAAK,EAAG;AAAA;AAAA,IAEvF,CAAC,EAAE,SAAS,MAAO,WAAW,eAAe,IAAI,EAAG;AAAA;AAGjD,MAAM,4BAAwB,yBAAO,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAU3C,CAAC,EAAE,YAAY,MAAO,cAAc,wBAAwB,kBAAmB;AAAA,IAC/E,mCAAkB;AAAA;AAGf,MAAM,wBAAoB,yBAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAOtC,MAAM,yBAAqB,yBAAO,KAAK;AAAA;AAAA;AAAA;AAKvC,MAAM,sBAAkB,yBAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAOnC,MAAM,yBAAqB,yBAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUvC,MAAM,oBAAgB,yBAAO,KAAK;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/DSMenuButtonCTX.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport type { MenuButtonT } from './react-desc-prop-types.js';\ninterface MenuButtonContextProps<T extends object = object> {\n focusedOption: string | null;\n setFocusedOption: React.Dispatch<React.SetStateAction<string | null>>;\n selectedKeys: string[];\n onSelectionChange: (selectedKeys: string[], parentId: string, item: MenuButtonT.Item) => void;\n propsWithDefault: MenuButtonT.InternalProps<T>;\n}\n\nconst defaultContext = {} as MenuButtonContextProps<object>;\n\nexport const MenuButtonContext = React.createContext(defaultContext);\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,YAAW;AAUlB,MAAM,iBAAiB,CAAC;AAEjB,MAAM,oBAAoBA,OAAM,cAAc,cAAc;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport type { MenuButtonT } from './react-desc-prop-types.js';\ninterface MenuButtonContextProps<T extends object = object> {\n focusedOption: string | null;\n setFocusedOption: React.Dispatch<React.SetStateAction<string | null>>;\n selectedKeys: string[];\n onSelectionChange: (selectedKeys: string[], parentId: string, item: MenuButtonT.Item) => void;\n triggerElementRef: HTMLElement | null;\n setTriggerElementRef: React.Dispatch<React.SetStateAction<HTMLElement | null>>;\n isOpen: boolean;\n setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n propsWithDefault: MenuButtonT.InternalProps<T>;\n}\n\nconst defaultContext = {} as MenuButtonContextProps<object>;\n\nexport const MenuButtonContext = React.createContext(defaultContext);\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,YAAW;AAclB,MAAM,iBAAiB,CAAC;AAEjB,MAAM,oBAAoBA,OAAM,cAAc,cAAc;",
6
6
  "names": ["React"]
7
7
  }
@@ -8,15 +8,21 @@ const useDSMenuButton = (propsFromUser) => {
8
8
  useValidateProps(propsWithDefault, DSDMenuButtonPropTypes);
9
9
  const { selectedKeys, onSelectionChange } = propsWithDefault;
10
10
  const [focusedOption, setFocusedOption] = useState(null);
11
+ const [triggerElementRef, setTriggerElementRef] = useState(null);
12
+ const [isOpen, setIsOpen] = useState(false);
11
13
  return useMemo(
12
14
  () => ({
13
15
  propsWithDefault,
14
16
  focusedOption,
15
17
  setFocusedOption,
16
18
  selectedKeys,
17
- onSelectionChange
19
+ onSelectionChange,
20
+ triggerElementRef,
21
+ setTriggerElementRef,
22
+ isOpen,
23
+ setIsOpen
18
24
  }),
19
- [focusedOption, propsWithDefault, selectedKeys, onSelectionChange]
25
+ [propsWithDefault, focusedOption, selectedKeys, onSelectionChange, triggerElementRef, isOpen]
20
26
  );
21
27
  };
22
28
  export {
@@ -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 { useMemo, useState } from 'react';\nimport { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { type MenuButtonT, DSDMenuButtonPropTypes, defaultProps } from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nexport const useDSMenuButton = <T extends object = object>(propsFromUser: MenuButtonT.Props<T>) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<MenuButtonT.InternalProps<T>>(propsFromUser, defaultProps);\n useValidateProps(propsWithDefault, DSDMenuButtonPropTypes);\n\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n\n const { selectedKeys, onSelectionChange } = propsWithDefault;\n const [focusedOption, setFocusedOption] = useState<string | null>(null);\n\n return useMemo(\n () => ({\n propsWithDefault,\n focusedOption,\n setFocusedOption,\n selectedKeys,\n onSelectionChange,\n }),\n [focusedOption, propsWithDefault, selectedKeys, onSelectionChange],\n );\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,SAAS,gBAAgB;AAClC,SAAS,oCAAoC;AAC7C,SAA2B,wBAAwB,oBAAoB;AACvE,SAAS,wBAAwB;AAE1B,MAAM,kBAAkB,CAA4B,kBAAwC;AAIjG,QAAM,mBAAmB,6BAA2D,eAAe,YAAY;AAC/G,mBAAiB,kBAAkB,sBAAsB;AAMzD,QAAM,EAAE,cAAc,kBAAkB,IAAI;AAC5C,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAwB,IAAI;AAEtE,SAAO;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,eAAe,kBAAkB,cAAc,iBAAiB;AAAA,EACnE;AACF;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useMemo, useState } from 'react';\nimport { useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { type MenuButtonT, DSDMenuButtonPropTypes, defaultProps } from '../react-desc-prop-types.js';\nimport { useValidateProps } from './useValidateProps.js';\n\nexport const useDSMenuButton = <T extends object = object>(propsFromUser: MenuButtonT.Props<T>) => {\n // =============================================================================\n // MERGE WITH DEFAULT AND VALIDATE PROPS\n // =============================================================================\n const propsWithDefault = useMemoMergePropsWithDefault<MenuButtonT.InternalProps<T>>(propsFromUser, defaultProps);\n useValidateProps(propsWithDefault, DSDMenuButtonPropTypes);\n\n // =============================================================================\n // AD HOC PER COMPONENT LOGIC\n // =============================================================================\n\n const { selectedKeys, onSelectionChange } = propsWithDefault;\n const [focusedOption, setFocusedOption] = useState<string | null>(null);\n const [triggerElementRef, setTriggerElementRef] = useState<HTMLElement | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n\n return useMemo(\n () => ({\n propsWithDefault,\n focusedOption,\n setFocusedOption,\n selectedKeys,\n onSelectionChange,\n triggerElementRef,\n setTriggerElementRef,\n isOpen,\n setIsOpen,\n }),\n [propsWithDefault, focusedOption, selectedKeys, onSelectionChange, triggerElementRef, isOpen],\n );\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,SAAS,gBAAgB;AAClC,SAAS,oCAAoC;AAC7C,SAA2B,wBAAwB,oBAAoB;AACvE,SAAS,wBAAwB;AAE1B,MAAM,kBAAkB,CAA4B,kBAAwC;AAIjG,QAAM,mBAAmB,6BAA2D,eAAe,YAAY;AAC/G,mBAAiB,kBAAkB,sBAAsB;AAMzD,QAAM,EAAE,cAAc,kBAAkB,IAAI;AAC5C,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAwB,IAAI;AACtE,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAA6B,IAAI;AACnF,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,SAAO;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,eAAe,cAAc,mBAAmB,mBAAmB,MAAM;AAAA,EAC9F;AACF;",
6
6
  "names": []
7
7
  }
@@ -5,7 +5,7 @@ import { useKeyboardNavigation, DIRECTIONS } from "@elliemae/ds-hooks-keyboard-n
5
5
  import { MenuButtonContext } from "../DSMenuButtonCTX.js";
6
6
  import { StyledMenu } from "../styled.js";
7
7
  import { ItemFactory } from "./ItemFactory.js";
8
- const SubMenu = (props) => {
8
+ const Menu = (props) => {
9
9
  const { referenceElement, showSubMenu, selectionMode, setShowSubMenu, parentId, level, items, minWidth } = props;
10
10
  const { focusedOption, setFocusedOption } = useContext(MenuButtonContext);
11
11
  const listRef = React2.useRef(null);
@@ -56,7 +56,6 @@ const SubMenu = (props) => {
56
56
  },
57
57
  [onBlur, setShowSubMenu]
58
58
  );
59
- console.log(minWidth, "minWidth");
60
59
  const subMenuStyles = useMemo(
61
60
  () => ({
62
61
  position: "absolute",
@@ -91,6 +90,6 @@ const SubMenu = (props) => {
91
90
  );
92
91
  };
93
92
  export {
94
- SubMenu
93
+ Menu
95
94
  };
96
- //# sourceMappingURL=SubMenu.js.map
95
+ //# sourceMappingURL=Menu.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/parts/Menu.tsx"],
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable import/no-cycle */\nimport React, { useState, useMemo, useCallback, useContext } from 'react';\nimport { useKeyboardNavigation, DIRECTIONS } from '@elliemae/ds-hooks-keyboard-navigation';\nimport { MenuButtonContext } from '../DSMenuButtonCTX.js';\nimport type { MenuButtonT } from '../react-desc-prop-types.js';\nimport { StyledMenu } from '../styled.js';\nimport { ItemFactory } from './ItemFactory.js';\n\ninterface SubMenuProps {\n referenceElement: HTMLElement | null;\n showSubMenu: boolean;\n selectionMode?: 'single' | 'multiple';\n setShowSubMenu: React.Dispatch<React.SetStateAction<boolean>>;\n parentId?: string;\n level: number;\n items: MenuButtonT.Item[];\n minWidth?: string | number;\n}\n\nexport const Menu: React.FC<SubMenuProps> = (props) => {\n const { referenceElement, showSubMenu, selectionMode, setShowSubMenu, parentId, level, items, minWidth } = props;\n const { focusedOption, setFocusedOption } = useContext(MenuButtonContext);\n const listRef = React.useRef<HTMLDivElement>(null);\n const rect = referenceElement?.getBoundingClientRect();\n const [coords, setCoords] = useState<{ x: number; y: number }>({ x: rect?.width ?? 0, y: 0 });\n\n // this logic will be part of the new popper custom hook\n React.useLayoutEffect(() => {\n const listRect = listRef?.current?.getBoundingClientRect();\n if (!listRect) return;\n if (level === 1) {\n if (listRect.bottom < window.innerHeight) {\n setCoords({ x: 0, y: rect?.height || 0 });\n } else {\n setCoords({ x: 0, y: -listRect.height });\n }\n return;\n }\n if (listRect.right > window.innerWidth) {\n setCoords({ x: -(rect?.width || 0), y: 0 });\n } else {\n setCoords({ x: rect?.width || 0, y: 0 });\n }\n }, [level, rect?.height, rect?.width, referenceElement]);\n\n const config = {\n options: items.filter((item) => item.type !== 'separator' && item.type !== 'section').map((item) => item.dsId),\n direction: DIRECTIONS.VERTICAL,\n focusedOption,\n setFocusedOption,\n };\n\n const { getWrapperProps, getItemProps } = useKeyboardNavigation(config);\n\n const { onKeyDown, onBlur } = getWrapperProps();\n\n const handleOnMenuKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.stopPropagation();\n }\n onKeyDown(event);\n },\n [onKeyDown],\n );\n\n const handleOnBlur: React.FocusEventHandler<HTMLDivElement> = useCallback(\n (e) => {\n setTimeout(() => {\n if (!listRef.current?.contains(document.activeElement)) {\n setShowSubMenu(false);\n }\n });\n onBlur(e);\n },\n [onBlur, setShowSubMenu],\n );\n\n const subMenuStyles = useMemo(\n () => ({\n position: 'absolute',\n top: coords.y,\n left: coords.x,\n zIndex: 1001 + level,\n minWidth,\n }),\n [coords, level, minWidth],\n );\n\n if (!referenceElement || !showSubMenu) return null;\n\n return (\n <StyledMenu\n innerRef={listRef}\n role=\"menu\"\n onKeyDown={handleOnMenuKeyDown}\n onBlur={handleOnBlur}\n style={subMenuStyles}\n >\n {items.map((item) => (\n <ItemFactory\n key={item.dsId}\n item={item}\n selectionMode={selectionMode}\n level={level}\n parentId={parentId}\n {...getItemProps(item.dsId)}\n />\n ))}\n </StyledMenu>\n );\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACoGf;AAnGR,OAAOA,UAAS,UAAU,SAAS,aAAa,kBAAkB;AAClE,SAAS,uBAAuB,kBAAkB;AAClD,SAAS,yBAAyB;AAElC,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAarB,MAAM,OAA+B,CAAC,UAAU;AACrD,QAAM,EAAE,kBAAkB,aAAa,eAAe,gBAAgB,UAAU,OAAO,OAAO,SAAS,IAAI;AAC3G,QAAM,EAAE,eAAe,iBAAiB,IAAI,WAAW,iBAAiB;AACxE,QAAM,UAAUA,OAAM,OAAuB,IAAI;AACjD,QAAM,OAAO,kBAAkB,sBAAsB;AACrD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAmC,EAAE,GAAG,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;AAG5F,EAAAA,OAAM,gBAAgB,MAAM;AAC1B,UAAM,WAAW,SAAS,SAAS,sBAAsB;AACzD,QAAI,CAAC,SAAU;AACf,QAAI,UAAU,GAAG;AACf,UAAI,SAAS,SAAS,OAAO,aAAa;AACxC,kBAAU,EAAE,GAAG,GAAG,GAAG,MAAM,UAAU,EAAE,CAAC;AAAA,MAC1C,OAAO;AACL,kBAAU,EAAE,GAAG,GAAG,GAAG,CAAC,SAAS,OAAO,CAAC;AAAA,MACzC;AACA;AAAA,IACF;AACA,QAAI,SAAS,QAAQ,OAAO,YAAY;AACtC,gBAAU,EAAE,GAAG,EAAE,MAAM,SAAS,IAAI,GAAG,EAAE,CAAC;AAAA,IAC5C,OAAO;AACL,gBAAU,EAAE,GAAG,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;AAAA,IACzC;AAAA,EACF,GAAG,CAAC,OAAO,MAAM,QAAQ,MAAM,OAAO,gBAAgB,CAAC;AAEvD,QAAM,SAAS;AAAA,IACb,SAAS,MAAM,OAAO,CAAC,SAAS,KAAK,SAAS,eAAe,KAAK,SAAS,SAAS,EAAE,IAAI,CAAC,SAAS,KAAK,IAAI;AAAA,IAC7G,WAAW,WAAW;AAAA,IACtB;AAAA,IACA;AAAA,EACF;AAEA,QAAM,EAAE,iBAAiB,aAAa,IAAI,sBAAsB,MAAM;AAEtE,QAAM,EAAE,WAAW,OAAO,IAAI,gBAAgB;AAE9C,QAAM,sBAAsB;AAAA,IAC1B,CAAC,UAA+B;AAC9B,UAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,WAAW;AACxD,cAAM,gBAAgB;AAAA,MACxB;AACA,gBAAU,KAAK;AAAA,IACjB;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,eAAwD;AAAA,IAC5D,CAAC,MAAM;AACL,iBAAW,MAAM;AACf,YAAI,CAAC,QAAQ,SAAS,SAAS,SAAS,aAAa,GAAG;AACtD,yBAAe,KAAK;AAAA,QACtB;AAAA,MACF,CAAC;AACD,aAAO,CAAC;AAAA,IACV;AAAA,IACA,CAAC,QAAQ,cAAc;AAAA,EACzB;AAEA,QAAM,gBAAgB;AAAA,IACpB,OAAO;AAAA,MACL,UAAU;AAAA,MACV,KAAK,OAAO;AAAA,MACZ,MAAM,OAAO;AAAA,MACb,QAAQ,OAAO;AAAA,MACf;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,OAAO,QAAQ;AAAA,EAC1B;AAEA,MAAI,CAAC,oBAAoB,CAAC,YAAa,QAAO;AAE9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,MAAK;AAAA,MACL,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,OAAO;AAAA,MAEN,gBAAM,IAAI,CAAC,SACV;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACC,GAAG,aAAa,KAAK,IAAI;AAAA;AAAA,QALrB,KAAK;AAAA,MAMZ,CACD;AAAA;AAAA,EACH;AAEJ;",
6
+ "names": ["React"]
7
+ }
@@ -1,8 +1,8 @@
1
1
  import * as React from "react";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import React2, { useState, useMemo, useCallback, useContext, useRef } from "react";
3
+ import React2, { useMemo, useCallback, useContext, useRef } from "react";
4
4
  import { useGetGlobalAttributes, useGetXstyledProps } from "@elliemae/ds-props-helpers";
5
- import { SubMenu } from "./SubMenu.js";
5
+ import { Menu } from "./Menu.js";
6
6
  import { MenuButtonContext } from "../DSMenuButtonCTX.js";
7
7
  import { StyledMenuButtonWrapper } from "../styled.js";
8
8
  function useOnClickOutside(ref, cb) {
@@ -22,9 +22,7 @@ function useOnClickOutside(ref, cb) {
22
22
  }, [ref, cb]);
23
23
  }
24
24
  const MenuButtonContent = () => {
25
- const [referenceElement, setReferenceElement] = useState(null);
26
- const [isOpen, setIsOpen] = useState(false);
27
- const { setFocusedOption, propsWithDefault } = useContext(MenuButtonContext);
25
+ const { setFocusedOption, triggerElementRef, setTriggerElementRef, isOpen, setIsOpen, propsWithDefault } = useContext(MenuButtonContext);
28
26
  const { items, TriggerElement, selectionMode, triggerElementProps, menuMinWidth } = propsWithDefault;
29
27
  const globalProps = useGetGlobalAttributes(propsWithDefault);
30
28
  const xstyledProps = useGetXstyledProps(propsWithDefault);
@@ -38,7 +36,7 @@ const MenuButtonContent = () => {
38
36
  const handleOnKeyDown = useCallback(
39
37
  (event) => {
40
38
  if (event.key === "Escape") {
41
- referenceElement?.focus();
39
+ triggerElementRef?.focus();
42
40
  }
43
41
  if (event.key === "ArrowDown" && isOpen) {
44
42
  event.preventDefault();
@@ -48,15 +46,11 @@ const MenuButtonContent = () => {
48
46
  event.preventDefault();
49
47
  setFocusedOption(items[items.length - 1].dsId);
50
48
  }
51
- if (event.key === "Enter" && isOpen) {
52
- event.preventDefault();
53
- setIsOpen(false);
54
- referenceElement?.focus();
55
- } else if ((event.key === "Enter" || event.key === " ") && !isOpen && firstItem) {
49
+ if ((event.key === "Enter" || event.key === " ") && !isOpen && firstItem) {
56
50
  setFocusedOption(firstItem?.dsId);
57
51
  }
58
52
  },
59
- [firstItem, items, isOpen, referenceElement, setFocusedOption]
53
+ [isOpen, firstItem, triggerElementRef, setFocusedOption, items]
60
54
  );
61
55
  const handleOnTriggerOnKeyDown = useCallback(
62
56
  (e) => {
@@ -69,7 +63,7 @@ const MenuButtonContent = () => {
69
63
  );
70
64
  const handleOnClick = useCallback(() => {
71
65
  setIsOpen(!isOpen);
72
- }, [isOpen]);
66
+ }, [isOpen, setIsOpen]);
73
67
  const attributes = useMemo(
74
68
  () => ({
75
69
  "aria-haspopup": "true",
@@ -98,7 +92,7 @@ const MenuButtonContent = () => {
98
92
  TriggerElement,
99
93
  {
100
94
  isOpen,
101
- innerRef: setReferenceElement,
95
+ innerRef: setTriggerElementRef,
102
96
  setIsOpen,
103
97
  attributes,
104
98
  listeners,
@@ -106,13 +100,13 @@ const MenuButtonContent = () => {
106
100
  }
107
101
  ),
108
102
  isOpen && /* @__PURE__ */ jsx(
109
- SubMenu,
103
+ Menu,
110
104
  {
111
105
  level: 1,
112
106
  items,
113
107
  showSubMenu: isOpen,
114
108
  setShowSubMenu: setIsOpen,
115
- referenceElement,
109
+ referenceElement: triggerElementRef,
116
110
  selectionMode,
117
111
  minWidth: menuMinWidth
118
112
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/parts/MenuButtonContent.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable complexity */\nimport React, { useState, useMemo, useCallback, useContext, useRef } from 'react';\nimport { useGetGlobalAttributes, useGetXstyledProps } from '@elliemae/ds-props-helpers';\nimport { SubMenu } from './SubMenu.js';\nimport { MenuButtonContext } from '../DSMenuButtonCTX.js';\n\nimport { StyledMenuButtonWrapper } from '../styled.js';\nfunction useOnClickOutside(ref: React.RefObject<HTMLElement>, cb: (event: MouseEvent | TouchEvent) => void) {\n React.useEffect(() => {\n const listener = (event: MouseEvent | TouchEvent) => {\n // Do nothing if clicking ref's element or descendent elements\n if (!ref?.current || ref?.current?.contains?.(event.target as Node)) {\n return;\n }\n cb(event);\n };\n document.addEventListener('mousedown', listener);\n document.addEventListener('touchstart', listener);\n return () => {\n document.removeEventListener('mousedown', listener);\n document.removeEventListener('touchstart', listener);\n };\n }, [ref, cb]);\n}\n\nexport const MenuButtonContent = () => {\n const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const { setFocusedOption, propsWithDefault } = useContext(MenuButtonContext);\n\n const { items, TriggerElement, selectionMode, triggerElementProps, menuMinWidth } = propsWithDefault;\n const globalProps = useGetGlobalAttributes(propsWithDefault);\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n\n const firstItem = useMemo(() => {\n const first = items.find((item) => item.type !== 'separator');\n if (first && first.type === 'section') {\n return first.childrens?.find((item) => item.type !== 'separator');\n }\n return first;\n }, [items]);\n\n const handleOnKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'Escape') {\n referenceElement?.focus();\n }\n if (event.key === 'ArrowDown' && isOpen) {\n event.preventDefault();\n setFocusedOption(firstItem?.dsId || '');\n }\n if (event.key === 'ArrowUp' && isOpen) {\n event.preventDefault();\n setFocusedOption(items[items.length - 1].dsId);\n }\n\n // Enter to close the menu and focus the trigger element\n if (event.key === 'Enter' && isOpen) {\n event.preventDefault();\n setIsOpen(false);\n referenceElement?.focus();\n } else if ((event.key === 'Enter' || event.key === ' ') && !isOpen && firstItem) {\n setFocusedOption(firstItem?.dsId);\n }\n },\n [firstItem, items, isOpen, referenceElement, setFocusedOption],\n );\n\n const handleOnTriggerOnKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setFocusedOption(items[0]?.dsId);\n }\n },\n [items, setFocusedOption],\n );\n\n const handleOnClick = useCallback(() => {\n setIsOpen(!isOpen);\n }, [isOpen]);\n\n const attributes = useMemo(\n () => ({\n 'aria-haspopup': 'true',\n 'aria-expanded': isOpen,\n }),\n [isOpen],\n );\n\n const listeners = useMemo(\n () => ({\n onKeyDown: handleOnTriggerOnKeyDown,\n }),\n [handleOnTriggerOnKeyDown],\n );\n\n const containerRef = useRef<HTMLDivElement | null>(null);\n useOnClickOutside(containerRef, () => setIsOpen(false));\n\n return (\n <StyledMenuButtonWrapper\n onClick={handleOnClick}\n onKeyDown={handleOnKeyDown}\n innerRef={containerRef}\n {...globalProps}\n {...xstyledProps}\n >\n <TriggerElement\n isOpen={isOpen}\n innerRef={setReferenceElement}\n setIsOpen={setIsOpen}\n attributes={attributes}\n listeners={listeners}\n triggerElementProps={triggerElementProps}\n />\n {isOpen && (\n <SubMenu\n level={1}\n items={items}\n showSubMenu={isOpen}\n setShowSubMenu={setIsOpen}\n referenceElement={referenceElement}\n selectionMode={selectionMode}\n minWidth={menuMinWidth}\n />\n )}\n </StyledMenuButtonWrapper>\n );\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable complexity */\nimport React, { useMemo, useCallback, useContext, useRef } from 'react';\nimport { useGetGlobalAttributes, useGetXstyledProps } from '@elliemae/ds-props-helpers';\nimport { Menu } from './Menu.js';\nimport { MenuButtonContext } from '../DSMenuButtonCTX.js';\n\nimport { StyledMenuButtonWrapper } from '../styled.js';\nfunction useOnClickOutside(ref: React.RefObject<HTMLElement>, cb: (event: MouseEvent | TouchEvent) => void) {\n React.useEffect(() => {\n const listener = (event: MouseEvent | TouchEvent) => {\n // Do nothing if clicking ref's element or descendent elements\n if (!ref?.current || ref?.current?.contains?.(event.target as Node)) {\n return;\n }\n cb(event);\n };\n document.addEventListener('mousedown', listener);\n document.addEventListener('touchstart', listener);\n return () => {\n document.removeEventListener('mousedown', listener);\n document.removeEventListener('touchstart', listener);\n };\n }, [ref, cb]);\n}\n\nexport const MenuButtonContent = () => {\n const { setFocusedOption, triggerElementRef, setTriggerElementRef, isOpen, setIsOpen, propsWithDefault } =\n useContext(MenuButtonContext);\n\n const { items, TriggerElement, selectionMode, triggerElementProps, menuMinWidth } = propsWithDefault;\n const globalProps = useGetGlobalAttributes(propsWithDefault);\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n\n const firstItem = useMemo(() => {\n const first = items.find((item) => item.type !== 'separator');\n if (first && first.type === 'section') {\n return first.childrens?.find((item) => item.type !== 'separator');\n }\n return first;\n }, [items]);\n\n const handleOnKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'Escape') {\n triggerElementRef?.focus();\n }\n if (event.key === 'ArrowDown' && isOpen) {\n event.preventDefault();\n setFocusedOption(firstItem?.dsId || '');\n }\n if (event.key === 'ArrowUp' && isOpen) {\n event.preventDefault();\n setFocusedOption(items[items.length - 1].dsId);\n }\n\n if ((event.key === 'Enter' || event.key === ' ') && !isOpen && firstItem) {\n setFocusedOption(firstItem?.dsId);\n }\n },\n [isOpen, firstItem, triggerElementRef, setFocusedOption, items],\n );\n\n const handleOnTriggerOnKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setFocusedOption(items[0]?.dsId);\n }\n },\n [items, setFocusedOption],\n );\n\n const handleOnClick = useCallback(() => {\n setIsOpen(!isOpen);\n }, [isOpen, setIsOpen]);\n\n const attributes = useMemo(\n () => ({\n 'aria-haspopup': 'true',\n 'aria-expanded': isOpen,\n }),\n [isOpen],\n );\n\n const listeners = useMemo(\n () => ({\n onKeyDown: handleOnTriggerOnKeyDown,\n }),\n [handleOnTriggerOnKeyDown],\n );\n\n const containerRef = useRef<HTMLDivElement | null>(null);\n useOnClickOutside(containerRef, () => setIsOpen(false));\n\n return (\n <StyledMenuButtonWrapper\n onClick={handleOnClick}\n onKeyDown={handleOnKeyDown}\n innerRef={containerRef}\n {...globalProps}\n {...xstyledProps}\n >\n <TriggerElement\n isOpen={isOpen}\n innerRef={setTriggerElementRef}\n setIsOpen={setIsOpen}\n attributes={attributes}\n listeners={listeners}\n triggerElementProps={triggerElementProps}\n />\n {isOpen && (\n <Menu\n level={1}\n items={items}\n showSubMenu={isOpen}\n setShowSubMenu={setIsOpen}\n referenceElement={triggerElementRef}\n selectionMode={selectionMode}\n minWidth={menuMinWidth}\n />\n )}\n </StyledMenuButtonWrapper>\n );\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -19,7 +19,7 @@ import {
19
19
  StyledSeparator,
20
20
  StyledSection
21
21
  } from "../styled.js";
22
- import { SubMenu } from "./SubMenu.js";
22
+ import { Menu } from "./Menu.js";
23
23
  const MenuItemAddon = React2.memo(({ level, isOpen }) => {
24
24
  if (level === 0)
25
25
  return isOpen ? /* @__PURE__ */ jsx(TriangleUpSmall, { color: ["brand-primary", "600"] }) : /* @__PURE__ */ jsx(TriangleDownSmall, { color: ["brand-primary", "600"] });
@@ -40,6 +40,8 @@ const MenuItem = ({
40
40
  focusedOption,
41
41
  selectedKeys,
42
42
  onSelectionChange,
43
+ triggerElementRef,
44
+ setIsOpen,
43
45
  propsWithDefault: { ItemRenderer }
44
46
  } = React2.useContext(MenuButtonContext);
45
47
  const listRef = React2.useRef(null);
@@ -55,6 +57,7 @@ const MenuItem = ({
55
57
  [focusedOption, item.dsId]
56
58
  );
57
59
  const selectionLogic = useCallback(() => {
60
+ if (item.disabled) return;
58
61
  if (selectionMode === "single") {
59
62
  const newValue = item.dsId === selectedKeys[0] ? [] : [item.dsId];
60
63
  onSelectionChange(newValue, parentId || "root", item);
@@ -66,15 +69,19 @@ const MenuItem = ({
66
69
  }, [item, onSelectionChange, parentId, selectedKeys, selectionMode]);
67
70
  const handleOnClick = useCallback(
68
71
  (e) => {
69
- if (selectionMode === "multiple") {
72
+ if (selectionMode === "multiple" || item.disabled) {
70
73
  e.stopPropagation();
71
74
  }
72
75
  selectionLogic();
73
76
  },
74
- [selectionLogic, selectionMode]
77
+ [item.disabled, selectionLogic, selectionMode]
75
78
  );
76
79
  const onItemKeyDown = useCallback(
77
80
  (event) => {
81
+ if (event.key === "Enter" && !item.disabled) {
82
+ setIsOpen(false);
83
+ triggerElementRef?.focus();
84
+ }
78
85
  if (event.key === "Enter" || event.key === " ") {
79
86
  event.preventDefault();
80
87
  selectionLogic();
@@ -96,7 +103,7 @@ const MenuItem = ({
96
103
  }
97
104
  }
98
105
  },
99
- [level, item.subitems, selectionLogic, setFocusedOption, parentId]
106
+ [item.disabled, item.subitems, level, setIsOpen, triggerElementRef, selectionLogic, setFocusedOption, parentId]
100
107
  );
101
108
  const handleOnLIKeyDown = useCallback(
102
109
  (e) => {
@@ -148,6 +155,7 @@ const MenuItem = ({
148
155
  isOpen: showSubMenu,
149
156
  level,
150
157
  isVertical,
158
+ disabled: item.disabled,
151
159
  children: [
152
160
  /* @__PURE__ */ jsx(
153
161
  StyledMenuItemContent,
@@ -162,6 +170,7 @@ const MenuItem = ({
162
170
  hasChildren: item.subitems !== void 0,
163
171
  onFocus,
164
172
  tabIndex,
173
+ "aria-disabled": item.disabled ? "true" : "false",
165
174
  children: ItemRenderer ? /* @__PURE__ */ jsx(ItemRenderer, { item, isSelected: selectedKeys.includes(item.dsId) }) : /* @__PURE__ */ jsx(
166
175
  MenuItemContent,
167
176
  {
@@ -175,7 +184,7 @@ const MenuItem = ({
175
184
  }
176
185
  ),
177
186
  item.subitems && showSubMenu && /* @__PURE__ */ jsx(
178
- SubMenu,
187
+ Menu,
179
188
  {
180
189
  level: level + 1,
181
190
  items: item.subitems,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/parts/MenuItem.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable import/no-cycle */\n/* eslint-disable @typescript-eslint/no-use-before-define */\n/* eslint-disable complexity */\n/* eslint-disable max-lines */\nimport React, { useState, useCallback, useMemo } from 'react';\nimport {\n TriangleUpSmall,\n CheckmarkXsmall,\n TriangleDownSmall,\n ChevronSmallDown,\n ChevronSmallRight,\n} from '@elliemae/ds-icons';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport { mergeRefs } from '@elliemae/ds-system';\nimport { Grid } from '@elliemae/ds-grid';\nimport { MenuButtonContext } from '../DSMenuButtonCTX.js';\nimport {\n StyledMenuItem,\n StyledMenuItemContent,\n StyledLeftContent,\n StyledRightContent,\n StyledSeparator,\n StyledSection,\n} from '../styled.js';\nimport { SubMenu } from './SubMenu.js';\nimport type { MenuButtonT } from '../react-desc-prop-types.js';\n\nexport const MenuItemAddon = React.memo(({ level, isOpen }: { level: number; isOpen: boolean }) => {\n if (level === 0)\n return isOpen ? (\n <TriangleUpSmall color={['brand-primary', '600']} />\n ) : (\n <TriangleDownSmall color={['brand-primary', '600']} />\n );\n return isOpen ? (\n <ChevronSmallDown size=\"m\" color={['brand-primary', '600']} />\n ) : (\n <ChevronSmallRight size=\"m\" color={['brand-primary', '600']} />\n );\n});\n\nexport const MenuItem = ({\n innerRef,\n tabIndex,\n onFocus,\n selectionMode,\n item,\n level,\n parentId,\n isVertical,\n}: {\n selectionMode?: 'single' | 'multiple';\n item: MenuButtonT.Item;\n level: number;\n parentId: string | undefined;\n isVertical?: boolean;\n tabIndex: number;\n onFocus: React.FocusEventHandler;\n innerRef: TypescriptHelpersT.AnyRef<HTMLElement>;\n}) => {\n const {\n setFocusedOption,\n focusedOption,\n selectedKeys,\n onSelectionChange,\n propsWithDefault: { ItemRenderer },\n } = React.useContext(MenuButtonContext);\n const listRef = React.useRef(null);\n const [showSubMenu, setShowSubMenu] = useState(false);\n const [referenceElement, setReferenceElement] = React.useState<HTMLElement | null>(null);\n const itemRef = useCallback(\n (node: HTMLElement | null) => {\n if (node !== null) {\n if (focusedOption === item.dsId) node.focus();\n }\n return node;\n },\n [focusedOption, item.dsId],\n );\n\n const selectionLogic = useCallback(() => {\n if (selectionMode === 'single') {\n const newValue = item.dsId === selectedKeys[0] ? [] : [item.dsId];\n onSelectionChange(newValue, parentId || 'root', item);\n }\n if (selectionMode === 'multiple') {\n const newValue = selectedKeys.includes(item.dsId)\n ? selectedKeys.filter((key: string) => key !== item.dsId)\n : [...selectedKeys, item.dsId];\n onSelectionChange(newValue, parentId || 'root', item);\n }\n }, [item, onSelectionChange, parentId, selectedKeys, selectionMode]);\n\n const handleOnClick: React.MouseEventHandler = useCallback(\n (e) => {\n if (selectionMode === 'multiple') {\n e.stopPropagation();\n }\n selectionLogic();\n },\n [selectionLogic, selectionMode],\n );\n const onItemKeyDown: React.KeyboardEventHandler = useCallback(\n (event) => {\n // selection\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n selectionLogic();\n }\n // open submenu logic\n if (\n ((event.key === 'ArrowDown' && level === 0) || (event.key === 'ArrowRight' && level !== 0)) &&\n item.subitems\n ) {\n event.preventDefault();\n event.stopPropagation();\n setShowSubMenu(true);\n setFocusedOption(item.subitems[0].dsId);\n }\n\n // close submenu logic\n if (event.key === 'ArrowLeft' && level >= 2) {\n event.preventDefault();\n event.stopPropagation();\n if (parentId) setFocusedOption(parentId);\n }\n if (event.key === 'Escape' && level > 0) {\n if (parentId !== undefined) {\n setFocusedOption(parentId);\n }\n }\n },\n [level, item.subitems, selectionLogic, setFocusedOption, parentId],\n );\n\n const handleOnLIKeyDown: React.KeyboardEventHandler = useCallback(\n (e) => {\n // logic to close all submenus and focus on parent\n if (e.key === 'Enter') {\n setShowSubMenu(false);\n if (level === 0) {\n setFocusedOption(item.dsId);\n }\n }\n },\n [item.dsId, level, setFocusedOption],\n );\n\n const handleOnMouseEnter = useCallback(() => {\n setShowSubMenu(true);\n setFocusedOption(item.dsId);\n }, [item.dsId, setFocusedOption]);\n\n const handleOnMouseLeave = useCallback(() => {\n setShowSubMenu(false);\n }, []);\n\n const ariaExpanded = useMemo(() => {\n if (item.subitems) {\n return showSubMenu ? 'true' : 'false';\n }\n return undefined;\n }, [item.subitems, showSubMenu]);\n\n const role = useMemo(() => {\n if (selectionMode === 'single') {\n return 'menuitemradio';\n }\n if (selectionMode === 'multiple') {\n return 'menuitemcheckbox';\n }\n return 'menuitem';\n }, [selectionMode]);\n\n const ariaChecked = useMemo(() => {\n if (selectionMode === 'multiple' || selectionMode === 'single') {\n return selectedKeys.includes(item.dsId) ? 'true' : 'false';\n }\n return undefined;\n }, [item.dsId, selectionMode, selectedKeys]);\n\n return (\n <StyledMenuItem\n role=\"none\"\n innerRef={listRef}\n onMouseEnter={handleOnMouseEnter}\n onMouseLeave={handleOnMouseLeave}\n onKeyDown={handleOnLIKeyDown}\n isOpen={showSubMenu}\n level={level}\n isVertical={isVertical}\n >\n <StyledMenuItemContent\n role={role}\n aria-checked={ariaChecked}\n aria-haspopup={item.subitems ? 'true' : 'false'}\n aria-expanded={ariaExpanded}\n innerRef={mergeRefs(innerRef, itemRef, setReferenceElement)}\n onKeyDown={onItemKeyDown}\n onClick={handleOnClick}\n hasChildren={item.subitems !== undefined}\n onFocus={onFocus}\n tabIndex={tabIndex}\n >\n {ItemRenderer ? (\n <ItemRenderer item={item} isSelected={selectedKeys.includes(item.dsId)} />\n ) : (\n <MenuItemContent\n item={item}\n selectionMode={selectionMode}\n selectedKeys={selectedKeys}\n showSubMenu={showSubMenu}\n level={level}\n />\n )}\n </StyledMenuItemContent>\n {item.subitems && showSubMenu && (\n <SubMenu\n level={level + 1}\n items={item.subitems}\n showSubMenu={showSubMenu}\n setShowSubMenu={setShowSubMenu}\n referenceElement={referenceElement}\n parentId={item.dsId}\n selectionMode={item.selectionMode}\n minWidth={item.minWidth}\n />\n )}\n </StyledMenuItem>\n );\n};\n\nconst MenuItemContent = React.memo(\n ({\n item,\n selectionMode,\n selectedKeys,\n showSubMenu,\n level,\n }: {\n item: MenuButtonT.Item;\n selectionMode?: 'single' | 'multiple';\n selectedKeys: string[];\n showSubMenu: boolean;\n level: number;\n }) => (\n <>\n <StyledLeftContent>\n <SelectionAddon selectionMode={selectionMode} item={item} selectedKeys={selectedKeys} />\n <span style={{ lineHeight: 1.15 }}>{item.label}</span>\n </StyledLeftContent>\n <StyledRightContent>\n {item.subitems ? <MenuItemAddon isOpen={showSubMenu} level={level} /> : null}\n </StyledRightContent>\n </>\n ),\n);\n\nconst SelectionAddon = ({\n item,\n selectedKeys,\n selectionMode,\n}: {\n item: MenuButtonT.Item;\n selectedKeys: string[];\n selectionMode?: 'single' | 'multiple';\n}) => {\n if (selectionMode) {\n return selectedKeys.includes(item.dsId) ? (\n <Grid>\n <CheckmarkXsmall size=\"m\" color={['brand-primary', '600']} />\n </Grid>\n ) : (\n <div style={{ width: '24px' }} />\n );\n }\n return null;\n};\n\nexport const Separator = () => (\n <li role=\"none\" style={{ padding: '0px 16px' }}>\n <StyledSeparator role=\"separator\" />\n </li>\n);\n\nexport const Section = ({ item }: { item: MenuButtonT.Item }) => (\n <li role=\"none\" style={{ padding: '0px 16px', minHeight: 24, display: 'flex', alignItems: 'center' }}>\n <StyledSection role=\"presentation\">{item.label}</StyledSection>\n </li>\n);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable import/no-cycle */\n/* eslint-disable @typescript-eslint/no-use-before-define */\n/* eslint-disable complexity */\n/* eslint-disable max-lines */\nimport React, { useState, useCallback, useMemo } from 'react';\nimport {\n TriangleUpSmall,\n CheckmarkXsmall,\n TriangleDownSmall,\n ChevronSmallDown,\n ChevronSmallRight,\n} from '@elliemae/ds-icons';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport { mergeRefs } from '@elliemae/ds-system';\nimport { Grid } from '@elliemae/ds-grid';\nimport { MenuButtonContext } from '../DSMenuButtonCTX.js';\nimport {\n StyledMenuItem,\n StyledMenuItemContent,\n StyledLeftContent,\n StyledRightContent,\n StyledSeparator,\n StyledSection,\n} from '../styled.js';\nimport { Menu } from './Menu.js';\nimport type { MenuButtonT } from '../react-desc-prop-types.js';\n\nexport const MenuItemAddon = React.memo(({ level, isOpen }: { level: number; isOpen: boolean }) => {\n if (level === 0)\n return isOpen ? (\n <TriangleUpSmall color={['brand-primary', '600']} />\n ) : (\n <TriangleDownSmall color={['brand-primary', '600']} />\n );\n return isOpen ? (\n <ChevronSmallDown size=\"m\" color={['brand-primary', '600']} />\n ) : (\n <ChevronSmallRight size=\"m\" color={['brand-primary', '600']} />\n );\n});\n\nexport const MenuItem = ({\n innerRef,\n tabIndex,\n onFocus,\n selectionMode,\n item,\n level,\n parentId,\n isVertical,\n}: {\n selectionMode?: 'single' | 'multiple';\n item: MenuButtonT.Item;\n level: number;\n parentId: string | undefined;\n isVertical?: boolean;\n tabIndex: number;\n onFocus: React.FocusEventHandler;\n innerRef: TypescriptHelpersT.AnyRef<HTMLElement>;\n}) => {\n const {\n setFocusedOption,\n focusedOption,\n selectedKeys,\n onSelectionChange,\n triggerElementRef,\n setIsOpen,\n propsWithDefault: { ItemRenderer },\n } = React.useContext(MenuButtonContext);\n const listRef = React.useRef(null);\n const [showSubMenu, setShowSubMenu] = useState(false);\n const [referenceElement, setReferenceElement] = React.useState<HTMLElement | null>(null);\n const itemRef = useCallback(\n (node: HTMLElement | null) => {\n if (node !== null) {\n if (focusedOption === item.dsId) node.focus();\n }\n return node;\n },\n [focusedOption, item.dsId],\n );\n\n const selectionLogic = useCallback(() => {\n if (item.disabled) return;\n if (selectionMode === 'single') {\n const newValue = item.dsId === selectedKeys[0] ? [] : [item.dsId];\n onSelectionChange(newValue, parentId || 'root', item);\n }\n if (selectionMode === 'multiple') {\n const newValue = selectedKeys.includes(item.dsId)\n ? selectedKeys.filter((key: string) => key !== item.dsId)\n : [...selectedKeys, item.dsId];\n onSelectionChange(newValue, parentId || 'root', item);\n }\n }, [item, onSelectionChange, parentId, selectedKeys, selectionMode]);\n\n const handleOnClick: React.MouseEventHandler = useCallback(\n (e) => {\n if (selectionMode === 'multiple' || item.disabled) {\n e.stopPropagation();\n }\n selectionLogic();\n },\n [item.disabled, selectionLogic, selectionMode],\n );\n const onItemKeyDown: React.KeyboardEventHandler = useCallback(\n (event) => {\n // Enter to close the menu and focus the trigger element\n if (event.key === 'Enter' && !item.disabled) {\n setIsOpen(false);\n triggerElementRef?.focus();\n }\n // selection\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n selectionLogic();\n }\n // open submenu logic\n if (\n ((event.key === 'ArrowDown' && level === 0) || (event.key === 'ArrowRight' && level !== 0)) &&\n item.subitems\n ) {\n event.preventDefault();\n event.stopPropagation();\n setShowSubMenu(true);\n setFocusedOption(item.subitems[0].dsId);\n }\n\n // close submenu logic\n if (event.key === 'ArrowLeft' && level >= 2) {\n event.preventDefault();\n event.stopPropagation();\n if (parentId) setFocusedOption(parentId);\n }\n if (event.key === 'Escape' && level > 0) {\n if (parentId !== undefined) {\n setFocusedOption(parentId);\n }\n }\n },\n [item.disabled, item.subitems, level, setIsOpen, triggerElementRef, selectionLogic, setFocusedOption, parentId],\n );\n\n const handleOnLIKeyDown: React.KeyboardEventHandler = useCallback(\n (e) => {\n // logic to close all submenus and focus on parent\n if (e.key === 'Enter') {\n setShowSubMenu(false);\n if (level === 0) {\n setFocusedOption(item.dsId);\n }\n }\n },\n [item.dsId, level, setFocusedOption],\n );\n\n const handleOnMouseEnter = useCallback(() => {\n setShowSubMenu(true);\n setFocusedOption(item.dsId);\n }, [item.dsId, setFocusedOption]);\n\n const handleOnMouseLeave = useCallback(() => {\n setShowSubMenu(false);\n }, []);\n\n const ariaExpanded = useMemo(() => {\n if (item.subitems) {\n return showSubMenu ? 'true' : 'false';\n }\n return undefined;\n }, [item.subitems, showSubMenu]);\n\n const role = useMemo(() => {\n if (selectionMode === 'single') {\n return 'menuitemradio';\n }\n if (selectionMode === 'multiple') {\n return 'menuitemcheckbox';\n }\n return 'menuitem';\n }, [selectionMode]);\n\n const ariaChecked = useMemo(() => {\n if (selectionMode === 'multiple' || selectionMode === 'single') {\n return selectedKeys.includes(item.dsId) ? 'true' : 'false';\n }\n return undefined;\n }, [item.dsId, selectionMode, selectedKeys]);\n\n return (\n <StyledMenuItem\n role=\"none\"\n innerRef={listRef}\n onMouseEnter={handleOnMouseEnter}\n onMouseLeave={handleOnMouseLeave}\n onKeyDown={handleOnLIKeyDown}\n isOpen={showSubMenu}\n level={level}\n isVertical={isVertical}\n disabled={item.disabled}\n >\n <StyledMenuItemContent\n role={role}\n aria-checked={ariaChecked}\n aria-haspopup={item.subitems ? 'true' : 'false'}\n aria-expanded={ariaExpanded}\n innerRef={mergeRefs(innerRef, itemRef, setReferenceElement)}\n onKeyDown={onItemKeyDown}\n onClick={handleOnClick}\n hasChildren={item.subitems !== undefined}\n onFocus={onFocus}\n tabIndex={tabIndex}\n aria-disabled={item.disabled ? 'true' : 'false'}\n >\n {ItemRenderer ? (\n <ItemRenderer item={item} isSelected={selectedKeys.includes(item.dsId)} />\n ) : (\n <MenuItemContent\n item={item}\n selectionMode={selectionMode}\n selectedKeys={selectedKeys}\n showSubMenu={showSubMenu}\n level={level}\n />\n )}\n </StyledMenuItemContent>\n {item.subitems && showSubMenu && (\n <Menu\n level={level + 1}\n items={item.subitems}\n showSubMenu={showSubMenu}\n setShowSubMenu={setShowSubMenu}\n referenceElement={referenceElement}\n parentId={item.dsId}\n selectionMode={item.selectionMode}\n minWidth={item.minWidth}\n />\n )}\n </StyledMenuItem>\n );\n};\n\nconst MenuItemContent = React.memo(\n ({\n item,\n selectionMode,\n selectedKeys,\n showSubMenu,\n level,\n }: {\n item: MenuButtonT.Item;\n selectionMode?: 'single' | 'multiple';\n selectedKeys: string[];\n showSubMenu: boolean;\n level: number;\n }) => (\n <>\n <StyledLeftContent>\n <SelectionAddon selectionMode={selectionMode} item={item} selectedKeys={selectedKeys} />\n <span style={{ lineHeight: 1.15 }}>{item.label}</span>\n </StyledLeftContent>\n <StyledRightContent>\n {item.subitems ? <MenuItemAddon isOpen={showSubMenu} level={level} /> : null}\n </StyledRightContent>\n </>\n ),\n);\n\nconst SelectionAddon = ({\n item,\n selectedKeys,\n selectionMode,\n}: {\n item: MenuButtonT.Item;\n selectedKeys: string[];\n selectionMode?: 'single' | 'multiple';\n}) => {\n if (selectionMode) {\n return selectedKeys.includes(item.dsId) ? (\n <Grid>\n <CheckmarkXsmall size=\"m\" color={['brand-primary', '600']} />\n </Grid>\n ) : (\n <div style={{ width: '24px' }} />\n );\n }\n return null;\n};\n\nexport const Separator = () => (\n <li role=\"none\" style={{ padding: '0px 16px' }}>\n <StyledSeparator role=\"separator\" />\n </li>\n);\n\nexport const Section = ({ item }: { item: MenuButtonT.Item }) => (\n <li role=\"none\" style={{ padding: '0px 16px', minHeight: 24, display: 'flex', alignItems: 'center' }}>\n <StyledSection role=\"presentation\">{item.label}</StyledSection>\n </li>\n);\n"],
5
+ "mappings": "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",
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/react-desc-prop-types.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { GlobalAttributesT, XstyledProps, DSPropTypesSchema } from '@elliemae/ds-props-helpers';\nimport { PropTypes, globalAttributesPropTypes, xstyledPropTypes } from '@elliemae/ds-props-helpers';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type { WeakValidationMap } from 'react';\n\nexport declare namespace MenuButtonT {\n export interface RequiredProps {\n items: Item[];\n TriggerElement: React.ComponentType<TriggerElementProps>;\n }\n\n export interface DefaultProps {\n selectedKeys: string[];\n onSelectionChange: (selectedKeys: string[]) => void;\n }\n\n export interface OptionalProps<T extends object = object> {\n triggerElementProps?: T;\n selectionMode?: 'single' | 'multiple';\n menuMinWidth?: string | number;\n ItemRenderer?: React.ComponentType<{ item: Item; isSelected: boolean }>;\n }\n\n export interface Props<T extends object = object>\n extends Partial<DefaultProps>,\n OptionalProps<T>,\n Omit<GlobalAttributesT<HTMLButtonElement>, keyof OptionalProps<T> | keyof XstyledProps>,\n XstyledProps,\n RequiredProps {}\n\n export interface InternalProps<T extends object = object>\n extends DefaultProps,\n OptionalProps<T>,\n Omit<GlobalAttributesT<HTMLButtonElement>, keyof OptionalProps<T> | keyof XstyledProps>,\n XstyledProps,\n RequiredProps {}\n\n export type Item = {\n dsId: string;\n label: string;\n type?: 'separator' | 'section';\n childrens?: Item[];\n subitems: Item[];\n selectionMode?: 'single' | 'multiple';\n minWidth?: string;\n };\n\n export interface TriggerElementProps {\n isOpen: boolean;\n innerRef: TypescriptHelpersT.AnyRef<HTMLElement>;\n setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n attributes: {\n 'aria-haspopup': string;\n 'aria-expanded': boolean;\n };\n listeners: {\n onKeyDown: (e: React.KeyboardEvent) => void;\n };\n triggerElementProps?: OptionalProps['triggerElementProps'];\n }\n}\n\nexport const defaultProps: MenuButtonT.DefaultProps = {\n selectedKeys: [],\n onSelectionChange: () => {},\n};\n\nexport const DSDMenuButtonPropTypes: DSPropTypesSchema<MenuButtonT.Props<object>> = {\n ...globalAttributesPropTypes,\n ...xstyledPropTypes,\n items: PropTypes.arrayOf(\n PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n label: PropTypes.string,\n type: PropTypes.oneOf(['separator', 'section', 'single', 'multiple', undefined]),\n }),\n ).description('Array of items to be displayed in the dropdown').isRequired,\n TriggerElement: PropTypes.node.description('Component to be used as the trigger element').isRequired,\n selectedKeys: PropTypes.arrayOf(PropTypes.string).description('Array of selected keys'),\n onSelectionChange: PropTypes.func.description('Function to be called when selection changes'),\n triggerElementProps: PropTypes.object.description('Props to be passed to the trigger element'),\n selectionMode: PropTypes.oneOf(['single', 'multiple']).description('Selection mode'),\n menuMinWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).description(\n 'Minimum width of the main dropdown',\n ),\n ItemRenderer: PropTypes.node.description('Component to be used to render the items'),\n};\n\nexport const DSDMenuButtonPropTypesSchema = DSDMenuButtonPropTypes as unknown as WeakValidationMap<\n MenuButtonT.Props<object>\n>;\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACEvB,SAAS,WAAW,2BAA2B,wBAAwB;AA6DhE,MAAM,eAAyC;AAAA,EACpD,cAAc,CAAC;AAAA,EACf,mBAAmB,MAAM;AAAA,EAAC;AAC5B;AAEO,MAAM,yBAAuE;AAAA,EAClF,GAAG;AAAA,EACH,GAAG;AAAA,EACH,OAAO,UAAU;AAAA,IACf,UAAU,MAAM;AAAA,MACd,MAAM,UAAU,OAAO;AAAA,MACvB,OAAO,UAAU;AAAA,MACjB,MAAM,UAAU,MAAM,CAAC,aAAa,WAAW,UAAU,YAAY,MAAS,CAAC;AAAA,IACjF,CAAC;AAAA,EACH,EAAE,YAAY,gDAAgD,EAAE;AAAA,EAChE,gBAAgB,UAAU,KAAK,YAAY,6CAA6C,EAAE;AAAA,EAC1F,cAAc,UAAU,QAAQ,UAAU,MAAM,EAAE,YAAY,wBAAwB;AAAA,EACtF,mBAAmB,UAAU,KAAK,YAAY,8CAA8C;AAAA,EAC5F,qBAAqB,UAAU,OAAO,YAAY,2CAA2C;AAAA,EAC7F,eAAe,UAAU,MAAM,CAAC,UAAU,UAAU,CAAC,EAAE,YAAY,gBAAgB;AAAA,EACnF,cAAc,UAAU,UAAU,CAAC,UAAU,QAAQ,UAAU,MAAM,CAAC,EAAE;AAAA,IACtE;AAAA,EACF;AAAA,EACA,cAAc,UAAU,KAAK,YAAY,0CAA0C;AACrF;AAEO,MAAM,+BAA+B;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { GlobalAttributesT, XstyledProps, DSPropTypesSchema } from '@elliemae/ds-props-helpers';\nimport { PropTypes, globalAttributesPropTypes, xstyledPropTypes } from '@elliemae/ds-props-helpers';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type { WeakValidationMap } from 'react';\n\nexport declare namespace MenuButtonT {\n export interface RequiredProps<T> {\n items: Item[];\n TriggerElement: React.ComponentType<TriggerElementProps<T>>;\n }\n\n export interface DefaultProps {\n selectedKeys: string[];\n onSelectionChange: (selectedKeys: string[], parentId: string, item: MenuButtonT.Item) => void;\n }\n\n export interface OptionalProps<T extends object> {\n triggerElementProps?: T;\n selectionMode?: 'single' | 'multiple';\n menuMinWidth?: string | number;\n ItemRenderer?: ItemRendererT;\n }\n\n export interface Props<T extends object = object>\n extends Partial<DefaultProps>,\n OptionalProps<T>,\n Omit<GlobalAttributesT<HTMLButtonElement>, keyof OptionalProps<T> | keyof XstyledProps>,\n XstyledProps,\n RequiredProps<T> {}\n\n export interface InternalProps<T extends object = object>\n extends DefaultProps,\n OptionalProps<T>,\n Omit<GlobalAttributesT<HTMLButtonElement>, keyof OptionalProps<T> | keyof XstyledProps>,\n XstyledProps,\n RequiredProps<T> {}\n\n export type Item = {\n dsId: string;\n label: string;\n type?: 'separator' | 'section';\n childrens?: Item[];\n subitems?: Item[];\n selectionMode?: 'single' | 'multiple';\n minWidth?: string | number;\n disabled?: boolean;\n };\n\n export interface TriggerElementProps<T2> {\n isOpen: boolean;\n innerRef: TypescriptHelpersT.AnyRef<HTMLButtonElement | null>;\n setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n attributes: {\n 'aria-haspopup'?: boolean | 'true' | 'false' | 'dialog' | 'grid' | 'listbox' | 'menu' | 'tree';\n 'aria-expanded': boolean;\n };\n listeners: {\n onKeyDown: (e: React.KeyboardEvent) => void;\n };\n triggerElementProps: T2;\n }\n\n export type ItemRendererT = React.ComponentType<{ item: Item; isSelected: boolean }>;\n}\n\nexport const defaultProps: MenuButtonT.DefaultProps = {\n selectedKeys: [],\n onSelectionChange: () => {},\n};\n\nexport const DSDMenuButtonPropTypes: DSPropTypesSchema<MenuButtonT.Props<object>> = {\n ...globalAttributesPropTypes,\n ...xstyledPropTypes,\n items: PropTypes.arrayOf(\n PropTypes.shape({\n dsId: PropTypes.string.isRequired,\n label: PropTypes.string,\n type: PropTypes.oneOf(['separator', 'section', 'single', 'multiple', undefined]),\n }),\n ).description('Array of items to be displayed in the dropdown').isRequired,\n TriggerElement: PropTypes.node.description('Component to be used as the trigger element').isRequired,\n selectedKeys: PropTypes.arrayOf(PropTypes.string).description('Array of selected keys'),\n onSelectionChange: PropTypes.func.description('Function to be called when selection changes'),\n triggerElementProps: PropTypes.object.description('Props to be passed to the trigger element'),\n selectionMode: PropTypes.oneOf(['single', 'multiple']).description('Selection mode'),\n menuMinWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).description(\n 'Minimum width of the main dropdown',\n ),\n ItemRenderer: PropTypes.node.description('Component to be used to render the items'),\n};\n\nexport const DSDMenuButtonPropTypesSchema = DSDMenuButtonPropTypes as unknown as WeakValidationMap<\n MenuButtonT.Props<object>\n>;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACEvB,SAAS,WAAW,2BAA2B,wBAAwB;AAgEhE,MAAM,eAAyC;AAAA,EACpD,cAAc,CAAC;AAAA,EACf,mBAAmB,MAAM;AAAA,EAAC;AAC5B;AAEO,MAAM,yBAAuE;AAAA,EAClF,GAAG;AAAA,EACH,GAAG;AAAA,EACH,OAAO,UAAU;AAAA,IACf,UAAU,MAAM;AAAA,MACd,MAAM,UAAU,OAAO;AAAA,MACvB,OAAO,UAAU;AAAA,MACjB,MAAM,UAAU,MAAM,CAAC,aAAa,WAAW,UAAU,YAAY,MAAS,CAAC;AAAA,IACjF,CAAC;AAAA,EACH,EAAE,YAAY,gDAAgD,EAAE;AAAA,EAChE,gBAAgB,UAAU,KAAK,YAAY,6CAA6C,EAAE;AAAA,EAC1F,cAAc,UAAU,QAAQ,UAAU,MAAM,EAAE,YAAY,wBAAwB;AAAA,EACtF,mBAAmB,UAAU,KAAK,YAAY,8CAA8C;AAAA,EAC5F,qBAAqB,UAAU,OAAO,YAAY,2CAA2C;AAAA,EAC7F,eAAe,UAAU,MAAM,CAAC,UAAU,UAAU,CAAC,EAAE,YAAY,gBAAgB;AAAA,EACnF,cAAc,UAAU,UAAU,CAAC,UAAU,QAAQ,UAAU,MAAM,CAAC,EAAE;AAAA,IACtE;AAAA,EACF;AAAA,EACA,cAAc,UAAU,KAAK,YAAY,0CAA0C;AACrF;AAEO,MAAM,+BAA+B;",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,15 @@
1
1
  import * as React from "react";
2
- import { xStyledCommonProps, styled } from "@elliemae/ds-system";
2
+ import { xStyledCommonProps, styled, css } from "@elliemae/ds-system";
3
+ const disabledOption = () => css`
4
+ a {
5
+ color: ${({ theme }) => theme.colors.neutral[500]};
6
+ }
7
+ background-color: ${({ theme }) => theme.colors.neutral["000"]};
8
+ cursor: not-allowed;
9
+ * {
10
+ cursor: not-allowed;
11
+ }
12
+ `;
3
13
  const StyledMenuButtonWrapper = styled("div")`
4
14
  position: relative;
5
15
  `;
@@ -40,6 +50,8 @@ const StyledMenuItem = styled("li")`
40
50
  }
41
51
 
42
52
  ${({ isOpen, theme }) => isOpen ? `background-color: ${theme.colors.brand["200"]}` : ""}
53
+
54
+ ${({ disabled }) => disabled ? disabledOption() : ""}
43
55
  `;
44
56
  const StyledMenuItemContent = styled("a")`
45
57
  display: flex;
@@ -47,7 +59,7 @@ const StyledMenuItemContent = styled("a")`
47
59
  justify-content: space-between;
48
60
  width: 100%;
49
61
  text-decoration: none;
50
- color: black;
62
+ color: inherit;
51
63
  &:focus {
52
64
  outline: none;
53
65
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/styled.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { xStyledCommonProps, styled } from '@elliemae/ds-system';\n\nexport const StyledMenuButtonWrapper = styled('div')`\n position: relative;\n`;\n\nexport const StyledMenu = styled('ul')`\n display: flex;\n flex-direction: column;\n gap: 1px;\n list-style-type: none;\n padding: 0;\n margin: 0;\n background-color: white;\n /* height: 100%; */\n ${xStyledCommonProps}\n box-shadow: 0 0 0 1px rgba(16, 22, 26, 0.1),\n 0 2px 4px rgba(16, 22, 26, 0.2),\n 0 8px 24px rgba(16, 22, 26, 0.2);\n`;\n\nexport const StyledMenuItem = styled('li')<{ isVertical?: boolean; level?: number; isOpen?: boolean }>`\n position: relative;\n background-color: white;\n display: flex;\n margin: 0;\n min-height: 32px;\n width: ${({ isVertical, level }) => (!isVertical && level === 0 ? 'auto' : '100%')};\n cursor: pointer;\n\n ul li {\n min-width: 200px;\n }\n\n &:hover {\n background-color: brand-200;\n }\n\n a:focus {\n outline: 1px solid brand-500;\n background-color: brand-200;\n }\n\n ${({ isOpen, theme }) => (isOpen ? `background-color: ${theme.colors.brand['200']}` : '')}\n`;\n\nexport const StyledMenuItemContent = styled('a')<{ hasChildren?: boolean }>`\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n text-decoration: none;\n color: black;\n &:focus {\n outline: none;\n }\n ${({ hasChildren }) => (hasChildren ? 'padding-left: 16px;' : 'padding: 0 16px;')}\n ${xStyledCommonProps}\n`;\n\nexport const StyledLeftContent = styled('div')`\n display: flex;\n align-items: center;\n gap: 4px;\n height: 100%;\n`;\n\nexport const StyledRightContent = styled('div')`\n display: flex;\n align-items: center;\n`;\n\nexport const StyledSeparator = styled('hr')`\n border: 0;\n border-top: 1px solid #697489;\n margin: 4px 0px;\n padding: 0;\n`;\n\nexport const StyledSectionLabel = styled('div')`\n color: neutral-500;\n display: flex;\n flex-direction: column;\n gap: 1px;\n padding: 0 16px;\n min-height: 24px;\n justify-content: center;\n`;\n\nexport const StyledSection = styled('div')`\n display: flex;\n flex-direction: column;\n gap: 1px;\n`;\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,oBAAoB,cAAc;AAEpC,MAAM,0BAA0B,OAAO,KAAK;AAAA;AAAA;AAI5C,MAAM,aAAa,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASjC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAMf,MAAM,iBAAiB,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAM9B,CAAC,EAAE,YAAY,MAAM,MAAO,CAAC,cAAc,UAAU,IAAI,SAAS,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgBhF,CAAC,EAAE,QAAQ,MAAM,MAAO,SAAS,qBAAqB,MAAM,OAAO,MAAM,KAAK,CAAC,KAAK,EAAG;AAAA;AAGpF,MAAM,wBAAwB,OAAO,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAU3C,CAAC,EAAE,YAAY,MAAO,cAAc,wBAAwB,kBAAmB;AAAA,IAC/E,kBAAkB;AAAA;AAGf,MAAM,oBAAoB,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAOtC,MAAM,qBAAqB,OAAO,KAAK;AAAA;AAAA;AAAA;AAKvC,MAAM,kBAAkB,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAOnC,MAAM,qBAAqB,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUvC,MAAM,gBAAgB,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { xStyledCommonProps, styled, css } from '@elliemae/ds-system';\n\nconst disabledOption = () => css`\n a {\n color: ${({ theme }) => theme.colors.neutral[500]};\n }\n background-color: ${({ theme }) => theme.colors.neutral['000']};\n cursor: not-allowed;\n * {\n cursor: not-allowed;\n }\n`;\n\nexport const StyledMenuButtonWrapper = styled('div')`\n position: relative;\n`;\n\nexport const StyledMenu = styled('ul')`\n display: flex;\n flex-direction: column;\n gap: 1px;\n list-style-type: none;\n padding: 0;\n margin: 0;\n background-color: white;\n /* height: 100%; */\n ${xStyledCommonProps}\n box-shadow: 0 0 0 1px rgba(16, 22, 26, 0.1),\n 0 2px 4px rgba(16, 22, 26, 0.2),\n 0 8px 24px rgba(16, 22, 26, 0.2);\n`;\n\nexport const StyledMenuItem = styled('li')<{\n isVertical?: boolean;\n level?: number;\n isOpen?: boolean;\n disabled?: boolean;\n}>`\n position: relative;\n background-color: white;\n display: flex;\n margin: 0;\n min-height: 32px;\n width: ${({ isVertical, level }) => (!isVertical && level === 0 ? 'auto' : '100%')};\n cursor: pointer;\n\n ul li {\n min-width: 200px;\n }\n\n &:hover {\n background-color: brand-200;\n }\n\n a:focus {\n outline: 1px solid brand-500;\n background-color: brand-200;\n }\n\n ${({ isOpen, theme }) => (isOpen ? `background-color: ${theme.colors.brand['200']}` : '')}\n\n ${({ disabled }) => (disabled ? disabledOption() : '')}\n`;\n\nexport const StyledMenuItemContent = styled('a')<{ hasChildren?: boolean }>`\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n text-decoration: none;\n color: inherit;\n &:focus {\n outline: none;\n }\n ${({ hasChildren }) => (hasChildren ? 'padding-left: 16px;' : 'padding: 0 16px;')}\n ${xStyledCommonProps}\n`;\n\nexport const StyledLeftContent = styled('div')`\n display: flex;\n align-items: center;\n gap: 4px;\n height: 100%;\n`;\n\nexport const StyledRightContent = styled('div')`\n display: flex;\n align-items: center;\n`;\n\nexport const StyledSeparator = styled('hr')`\n border: 0;\n border-top: 1px solid #697489;\n margin: 4px 0px;\n padding: 0;\n`;\n\nexport const StyledSectionLabel = styled('div')`\n color: neutral-500;\n display: flex;\n flex-direction: column;\n gap: 1px;\n padding: 0 16px;\n min-height: 24px;\n justify-content: center;\n`;\n\nexport const StyledSection = styled('div')`\n display: flex;\n flex-direction: column;\n gap: 1px;\n`;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,oBAAoB,QAAQ,WAAW;AAEhD,MAAM,iBAAiB,MAAM;AAAA;AAAA,aAEhB,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,QAAQ,GAAG,CAAC;AAAA;AAAA,sBAE/B,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,QAAQ,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAOzD,MAAM,0BAA0B,OAAO,KAAK;AAAA;AAAA;AAI5C,MAAM,aAAa,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASjC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAMf,MAAM,iBAAiB,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAW9B,CAAC,EAAE,YAAY,MAAM,MAAO,CAAC,cAAc,UAAU,IAAI,SAAS,MAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgBhF,CAAC,EAAE,QAAQ,MAAM,MAAO,SAAS,qBAAqB,MAAM,OAAO,MAAM,KAAK,CAAC,KAAK,EAAG;AAAA;AAAA,IAEvF,CAAC,EAAE,SAAS,MAAO,WAAW,eAAe,IAAI,EAAG;AAAA;AAGjD,MAAM,wBAAwB,OAAO,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAU3C,CAAC,EAAE,YAAY,MAAO,cAAc,wBAAwB,kBAAmB;AAAA,IAC/E,kBAAkB;AAAA;AAGf,MAAM,oBAAoB,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAOtC,MAAM,qBAAqB,OAAO,KAAK;AAAA;AAAA;AAAA;AAKvC,MAAM,kBAAkB,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAOnC,MAAM,qBAAqB,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUvC,MAAM,gBAAgB,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -5,6 +5,10 @@ interface MenuButtonContextProps<T extends object = object> {
5
5
  setFocusedOption: React.Dispatch<React.SetStateAction<string | null>>;
6
6
  selectedKeys: string[];
7
7
  onSelectionChange: (selectedKeys: string[], parentId: string, item: MenuButtonT.Item) => void;
8
+ triggerElementRef: HTMLElement | null;
9
+ setTriggerElementRef: React.Dispatch<React.SetStateAction<HTMLElement | null>>;
10
+ isOpen: boolean;
11
+ setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
8
12
  propsWithDefault: MenuButtonT.InternalProps<T>;
9
13
  }
10
14
  export declare const MenuButtonContext: React.Context<MenuButtonContextProps<object>>;
@@ -5,5 +5,9 @@ export declare const useDSMenuButton: <T extends object = object>(propsFromUser:
5
5
  focusedOption: string | null;
6
6
  setFocusedOption: import("react").Dispatch<import("react").SetStateAction<string | null>>;
7
7
  selectedKeys: string[];
8
- onSelectionChange: (selectedKeys: string[]) => void;
8
+ onSelectionChange: (selectedKeys: string[], parentId: string, item: MenuButtonT.Item) => void;
9
+ triggerElementRef: HTMLElement | null;
10
+ setTriggerElementRef: import("react").Dispatch<import("react").SetStateAction<HTMLElement | null>>;
11
+ isOpen: boolean;
12
+ setIsOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
9
13
  };
@@ -10,5 +10,5 @@ interface SubMenuProps {
10
10
  items: MenuButtonT.Item[];
11
11
  minWidth?: string | number;
12
12
  }
13
- export declare const SubMenu: React.FC<SubMenuProps>;
13
+ export declare const Menu: React.FC<SubMenuProps>;
14
14
  export {};
@@ -2,49 +2,51 @@ import type { GlobalAttributesT, XstyledProps, DSPropTypesSchema } from '@elliem
2
2
  import { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';
3
3
  import type { WeakValidationMap } from 'react';
4
4
  export declare namespace MenuButtonT {
5
- interface RequiredProps {
5
+ interface RequiredProps<T> {
6
6
  items: Item[];
7
- TriggerElement: React.ComponentType<TriggerElementProps>;
7
+ TriggerElement: React.ComponentType<TriggerElementProps<T>>;
8
8
  }
9
9
  interface DefaultProps {
10
10
  selectedKeys: string[];
11
- onSelectionChange: (selectedKeys: string[]) => void;
11
+ onSelectionChange: (selectedKeys: string[], parentId: string, item: MenuButtonT.Item) => void;
12
12
  }
13
- interface OptionalProps<T extends object = object> {
13
+ interface OptionalProps<T extends object> {
14
14
  triggerElementProps?: T;
15
15
  selectionMode?: 'single' | 'multiple';
16
16
  menuMinWidth?: string | number;
17
- ItemRenderer?: React.ComponentType<{
18
- item: Item;
19
- isSelected: boolean;
20
- }>;
17
+ ItemRenderer?: ItemRendererT;
21
18
  }
22
- interface Props<T extends object = object> extends Partial<DefaultProps>, OptionalProps<T>, Omit<GlobalAttributesT<HTMLButtonElement>, keyof OptionalProps<T> | keyof XstyledProps>, XstyledProps, RequiredProps {
19
+ interface Props<T extends object = object> extends Partial<DefaultProps>, OptionalProps<T>, Omit<GlobalAttributesT<HTMLButtonElement>, keyof OptionalProps<T> | keyof XstyledProps>, XstyledProps, RequiredProps<T> {
23
20
  }
24
- interface InternalProps<T extends object = object> extends DefaultProps, OptionalProps<T>, Omit<GlobalAttributesT<HTMLButtonElement>, keyof OptionalProps<T> | keyof XstyledProps>, XstyledProps, RequiredProps {
21
+ interface InternalProps<T extends object = object> extends DefaultProps, OptionalProps<T>, Omit<GlobalAttributesT<HTMLButtonElement>, keyof OptionalProps<T> | keyof XstyledProps>, XstyledProps, RequiredProps<T> {
25
22
  }
26
23
  type Item = {
27
24
  dsId: string;
28
25
  label: string;
29
26
  type?: 'separator' | 'section';
30
27
  childrens?: Item[];
31
- subitems: Item[];
28
+ subitems?: Item[];
32
29
  selectionMode?: 'single' | 'multiple';
33
- minWidth?: string;
30
+ minWidth?: string | number;
31
+ disabled?: boolean;
34
32
  };
35
- interface TriggerElementProps {
33
+ interface TriggerElementProps<T2> {
36
34
  isOpen: boolean;
37
- innerRef: TypescriptHelpersT.AnyRef<HTMLElement>;
35
+ innerRef: TypescriptHelpersT.AnyRef<HTMLButtonElement | null>;
38
36
  setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
39
37
  attributes: {
40
- 'aria-haspopup': string;
38
+ 'aria-haspopup'?: boolean | 'true' | 'false' | 'dialog' | 'grid' | 'listbox' | 'menu' | 'tree';
41
39
  'aria-expanded': boolean;
42
40
  };
43
41
  listeners: {
44
42
  onKeyDown: (e: React.KeyboardEvent) => void;
45
43
  };
46
- triggerElementProps?: OptionalProps['triggerElementProps'];
44
+ triggerElementProps: T2;
47
45
  }
46
+ type ItemRendererT = React.ComponentType<{
47
+ item: Item;
48
+ isSelected: boolean;
49
+ }>;
48
50
  }
49
51
  export declare const defaultProps: MenuButtonT.DefaultProps;
50
52
  export declare const DSDMenuButtonPropTypes: DSPropTypesSchema<MenuButtonT.Props<object>>;
@@ -4,6 +4,7 @@ export declare const StyledMenuItem: import("styled-components").StyledComponent
4
4
  isVertical?: boolean | undefined;
5
5
  level?: number | undefined;
6
6
  isOpen?: boolean | undefined;
7
+ disabled?: boolean | undefined;
7
8
  } & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<"li">, never>;
8
9
  export declare const StyledMenuItemContent: import("styled-components").StyledComponent<"a", import("@elliemae/ds-system").Theme, {
9
10
  hasChildren?: boolean | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-menu-button",
3
- "version": "3.39.0-rc.3",
3
+ "version": "3.39.0-rc.4",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Menu Button",
6
6
  "files": [
@@ -38,21 +38,21 @@
38
38
  "dependencies": {
39
39
  "@xstyled/styled-components": "~3.6.0",
40
40
  "uid": "^2.0.2",
41
- "@elliemae/ds-button-v2": "3.39.0-rc.3",
42
- "@elliemae/ds-grid": "3.39.0-rc.3",
43
- "@elliemae/ds-hooks-keyboard-navigation": "3.39.0-rc.3",
44
- "@elliemae/ds-icons": "3.39.0-rc.3",
45
- "@elliemae/ds-props-helpers": "3.39.0-rc.3",
46
- "@elliemae/ds-system": "3.39.0-rc.3",
47
- "@elliemae/ds-typescript-helpers": "3.39.0-rc.3",
48
- "@elliemae/ds-typography": "3.39.0-rc.3"
41
+ "@elliemae/ds-button-v2": "3.39.0-rc.4",
42
+ "@elliemae/ds-props-helpers": "3.39.0-rc.4",
43
+ "@elliemae/ds-grid": "3.39.0-rc.4",
44
+ "@elliemae/ds-hooks-keyboard-navigation": "3.39.0-rc.4",
45
+ "@elliemae/ds-icons": "3.39.0-rc.4",
46
+ "@elliemae/ds-system": "3.39.0-rc.4",
47
+ "@elliemae/ds-typography": "3.39.0-rc.4",
48
+ "@elliemae/ds-typescript-helpers": "3.39.0-rc.4"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@elliemae/pui-cli": "9.0.0-next.50",
52
52
  "@xstyled/system": "3.7.0",
53
53
  "lodash": "^4.17.21",
54
54
  "styled-components": "~5.3.9",
55
- "@elliemae/ds-monorepo-devops": "3.39.0-rc.3"
55
+ "@elliemae/ds-monorepo-devops": "3.39.0-rc.4"
56
56
  },
57
57
  "peerDependencies": {
58
58
  "lodash": "^4.17.21",
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/parts/SubMenu.tsx", "../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable import/no-cycle */\nimport React, { useState, useMemo, useCallback, useContext } from 'react';\nimport { useKeyboardNavigation, DIRECTIONS } from '@elliemae/ds-hooks-keyboard-navigation';\nimport { MenuButtonContext } from '../DSMenuButtonCTX.js';\nimport type { MenuButtonT } from '../react-desc-prop-types.js';\nimport { StyledMenu } from '../styled.js';\nimport { ItemFactory } from './ItemFactory.js';\n\ninterface SubMenuProps {\n referenceElement: HTMLElement | null;\n showSubMenu: boolean;\n selectionMode?: 'single' | 'multiple';\n setShowSubMenu: React.Dispatch<React.SetStateAction<boolean>>;\n parentId?: string;\n level: number;\n items: MenuButtonT.Item[];\n minWidth?: string | number;\n}\n\nexport const SubMenu: React.FC<SubMenuProps> = (props) => {\n const { referenceElement, showSubMenu, selectionMode, setShowSubMenu, parentId, level, items, minWidth } = props;\n const { focusedOption, setFocusedOption } = useContext(MenuButtonContext);\n const listRef = React.useRef<HTMLDivElement>(null);\n const rect = referenceElement?.getBoundingClientRect();\n const [coords, setCoords] = useState<{ x: number; y: number }>({ x: rect?.width ?? 0, y: 0 });\n\n // this logic will be part of the new popper custom hook\n React.useLayoutEffect(() => {\n const listRect = listRef?.current?.getBoundingClientRect();\n if (!listRect) return;\n if (level === 1) {\n if (listRect.bottom < window.innerHeight) {\n setCoords({ x: 0, y: rect?.height || 0 });\n } else {\n setCoords({ x: 0, y: -listRect.height });\n }\n return;\n }\n if (listRect.right > window.innerWidth) {\n setCoords({ x: -(rect?.width || 0), y: 0 });\n } else {\n setCoords({ x: rect?.width || 0, y: 0 });\n }\n }, [level, rect?.height, rect?.width, referenceElement]);\n\n const config = {\n options: items.filter((item) => item.type !== 'separator' && item.type !== 'section').map((item) => item.dsId),\n direction: DIRECTIONS.VERTICAL,\n focusedOption,\n setFocusedOption,\n };\n\n const { getWrapperProps, getItemProps } = useKeyboardNavigation(config);\n\n const { onKeyDown, onBlur } = getWrapperProps();\n\n const handleOnMenuKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.stopPropagation();\n }\n onKeyDown(event);\n },\n [onKeyDown],\n );\n\n const handleOnBlur: React.FocusEventHandler<HTMLDivElement> = useCallback(\n (e) => {\n setTimeout(() => {\n if (!listRef.current?.contains(document.activeElement)) {\n setShowSubMenu(false);\n }\n });\n onBlur(e);\n },\n [onBlur, setShowSubMenu],\n );\n\n console.log(minWidth, 'minWidth');\n\n const subMenuStyles = useMemo(\n () => ({\n position: 'absolute',\n top: coords.y,\n left: coords.x,\n zIndex: 1001 + level,\n minWidth,\n }),\n [coords, level, minWidth],\n );\n\n if (!referenceElement || !showSubMenu) return null;\n\n return (\n <StyledMenu\n innerRef={listRef}\n role=\"menu\"\n onKeyDown={handleOnMenuKeyDown}\n onBlur={handleOnBlur}\n style={subMenuStyles}\n >\n {items.map((item) => (\n <ItemFactory\n key={item.dsId}\n item={item}\n selectionMode={selectionMode}\n level={level}\n parentId={parentId}\n {...getItemProps(item.dsId)}\n />\n ))}\n </StyledMenu>\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": "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",
6
- "names": ["React"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/parts/SubMenu.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable import/no-cycle */\nimport React, { useState, useMemo, useCallback, useContext } from 'react';\nimport { useKeyboardNavigation, DIRECTIONS } from '@elliemae/ds-hooks-keyboard-navigation';\nimport { MenuButtonContext } from '../DSMenuButtonCTX.js';\nimport type { MenuButtonT } from '../react-desc-prop-types.js';\nimport { StyledMenu } from '../styled.js';\nimport { ItemFactory } from './ItemFactory.js';\n\ninterface SubMenuProps {\n referenceElement: HTMLElement | null;\n showSubMenu: boolean;\n selectionMode?: 'single' | 'multiple';\n setShowSubMenu: React.Dispatch<React.SetStateAction<boolean>>;\n parentId?: string;\n level: number;\n items: MenuButtonT.Item[];\n minWidth?: string | number;\n}\n\nexport const SubMenu: React.FC<SubMenuProps> = (props) => {\n const { referenceElement, showSubMenu, selectionMode, setShowSubMenu, parentId, level, items, minWidth } = props;\n const { focusedOption, setFocusedOption } = useContext(MenuButtonContext);\n const listRef = React.useRef<HTMLDivElement>(null);\n const rect = referenceElement?.getBoundingClientRect();\n const [coords, setCoords] = useState<{ x: number; y: number }>({ x: rect?.width ?? 0, y: 0 });\n\n // this logic will be part of the new popper custom hook\n React.useLayoutEffect(() => {\n const listRect = listRef?.current?.getBoundingClientRect();\n if (!listRect) return;\n if (level === 1) {\n if (listRect.bottom < window.innerHeight) {\n setCoords({ x: 0, y: rect?.height || 0 });\n } else {\n setCoords({ x: 0, y: -listRect.height });\n }\n return;\n }\n if (listRect.right > window.innerWidth) {\n setCoords({ x: -(rect?.width || 0), y: 0 });\n } else {\n setCoords({ x: rect?.width || 0, y: 0 });\n }\n }, [level, rect?.height, rect?.width, referenceElement]);\n\n const config = {\n options: items.filter((item) => item.type !== 'separator' && item.type !== 'section').map((item) => item.dsId),\n direction: DIRECTIONS.VERTICAL,\n focusedOption,\n setFocusedOption,\n };\n\n const { getWrapperProps, getItemProps } = useKeyboardNavigation(config);\n\n const { onKeyDown, onBlur } = getWrapperProps();\n\n const handleOnMenuKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.stopPropagation();\n }\n onKeyDown(event);\n },\n [onKeyDown],\n );\n\n const handleOnBlur: React.FocusEventHandler<HTMLDivElement> = useCallback(\n (e) => {\n setTimeout(() => {\n if (!listRef.current?.contains(document.activeElement)) {\n setShowSubMenu(false);\n }\n });\n onBlur(e);\n },\n [onBlur, setShowSubMenu],\n );\n\n console.log(minWidth, 'minWidth');\n\n const subMenuStyles = useMemo(\n () => ({\n position: 'absolute',\n top: coords.y,\n left: coords.x,\n zIndex: 1001 + level,\n minWidth,\n }),\n [coords, level, minWidth],\n );\n\n if (!referenceElement || !showSubMenu) return null;\n\n return (\n <StyledMenu\n innerRef={listRef}\n role=\"menu\"\n onKeyDown={handleOnMenuKeyDown}\n onBlur={handleOnBlur}\n style={subMenuStyles}\n >\n {items.map((item) => (\n <ItemFactory\n key={item.dsId}\n item={item}\n selectionMode={selectionMode}\n level={level}\n parentId={parentId}\n {...getItemProps(item.dsId)}\n />\n ))}\n </StyledMenu>\n );\n};\n"],
5
- "mappings": "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",
6
- "names": ["React"]
7
- }