@elliemae/ds-global-header 3.70.0-next.61 → 3.70.0-next.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/cjs/DSGlobalHeader.js +16 -2
  2. package/dist/cjs/DSGlobalHeader.js.map +2 -2
  3. package/dist/cjs/DSGlobalHeaderContext.js.map +2 -2
  4. package/dist/cjs/config/useGlobalHeader.js +13 -2
  5. package/dist/cjs/config/useGlobalHeader.js.map +2 -2
  6. package/dist/cjs/constants/index.js +4 -3
  7. package/dist/cjs/constants/index.js.map +2 -2
  8. package/dist/cjs/index.js +3 -6
  9. package/dist/cjs/index.js.map +3 -3
  10. package/dist/cjs/parts/Breadcrumb/useGlobalHeaderBreadcrumb.js +33 -1
  11. package/dist/cjs/parts/Breadcrumb/useGlobalHeaderBreadcrumb.js.map +2 -2
  12. package/dist/cjs/parts/Logo/GlobalHeaderLogo.js +16 -2
  13. package/dist/cjs/parts/Logo/GlobalHeaderLogo.js.map +2 -2
  14. package/dist/cjs/parts/Toolbar/GlobalHeaderToolbar.js +54 -16
  15. package/dist/cjs/parts/Toolbar/GlobalHeaderToolbar.js.map +2 -2
  16. package/dist/cjs/{utils/useCallbackAfterRender.js → parts/Toolbar/outOfTheBox/AppPicker/AppPickerCTX.js} +7 -16
  17. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/AppPickerCTX.js.map +7 -0
  18. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/AppPickerCTXRenderer.js +43 -0
  19. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/AppPickerCTXRenderer.js.map +7 -0
  20. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/AppPickerRenderer.js +52 -0
  21. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/AppPickerRenderer.js.map +7 -0
  22. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/TriggerDefaultComponent.js +84 -0
  23. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/TriggerDefaultComponent.js.map +7 -0
  24. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/react-desc-prop-types.js +50 -0
  25. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/react-desc-prop-types.js.map +7 -0
  26. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/useAppPickerCTX.js +64 -0
  27. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/useAppPickerCTX.js.map +7 -0
  28. package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/PopupMenu.js +106 -55
  29. package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/PopupMenu.js.map +3 -3
  30. package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/PopupMenuContent.js +27 -11
  31. package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/PopupMenuContent.js.map +2 -2
  32. package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/react-desc-prop-types.js +52 -0
  33. package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/react-desc-prop-types.js.map +7 -0
  34. package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/usePopupMenuContent.js +23 -15
  35. package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/usePopupMenuContent.js.map +2 -2
  36. package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/react-desc-prop-types.js +54 -0
  37. package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/react-desc-prop-types.js.map +7 -0
  38. package/dist/cjs/parts/Toolbar/outOfTheBox/SearchToggle/SearchToggle.js +26 -16
  39. package/dist/cjs/parts/Toolbar/outOfTheBox/SearchToggle/SearchToggle.js.map +2 -2
  40. package/dist/cjs/parts/Toolbar/outOfTheBox/SearchToggle/SearchToggleSpinButton.js +60 -50
  41. package/dist/cjs/parts/Toolbar/outOfTheBox/SearchToggle/SearchToggleSpinButton.js.map +2 -2
  42. package/dist/cjs/parts/Toolbar/outOfTheBox/SearchToggle/react-desc-prop-types.js +58 -0
  43. package/dist/cjs/parts/Toolbar/outOfTheBox/SearchToggle/react-desc-prop-types.js.map +7 -0
  44. package/dist/cjs/parts/Toolbar/outOfTheBox/SearchToggle/useSearchToggle.js +33 -25
  45. package/dist/cjs/parts/Toolbar/outOfTheBox/SearchToggle/useSearchToggle.js.map +2 -2
  46. package/dist/cjs/parts/Toolbar/outOfTheBox/index.js +12 -4
  47. package/dist/cjs/parts/Toolbar/outOfTheBox/index.js.map +2 -2
  48. package/dist/cjs/parts/Toolbar/styles.js +6 -1
  49. package/dist/cjs/parts/Toolbar/styles.js.map +2 -2
  50. package/dist/cjs/react-desc-prop-types.js.map +2 -2
  51. package/dist/cjs/sharedTypes.js.map +1 -1
  52. package/dist/cjs/typescript-testing/typescript-global-header-toolbar-types.js +52 -0
  53. package/dist/cjs/typescript-testing/typescript-global-header-toolbar-types.js.map +2 -2
  54. package/dist/esm/DSGlobalHeader.js +16 -2
  55. package/dist/esm/DSGlobalHeader.js.map +2 -2
  56. package/dist/esm/DSGlobalHeaderContext.js.map +2 -2
  57. package/dist/esm/config/useGlobalHeader.js +13 -2
  58. package/dist/esm/config/useGlobalHeader.js.map +2 -2
  59. package/dist/esm/constants/index.js +4 -3
  60. package/dist/esm/constants/index.js.map +2 -2
  61. package/dist/esm/index.js +3 -6
  62. package/dist/esm/index.js.map +3 -3
  63. package/dist/esm/parts/Breadcrumb/useGlobalHeaderBreadcrumb.js +34 -2
  64. package/dist/esm/parts/Breadcrumb/useGlobalHeaderBreadcrumb.js.map +2 -2
  65. package/dist/esm/parts/Logo/GlobalHeaderLogo.js +16 -2
  66. package/dist/esm/parts/Logo/GlobalHeaderLogo.js.map +2 -2
  67. package/dist/esm/parts/Toolbar/GlobalHeaderToolbar.js +55 -17
  68. package/dist/esm/parts/Toolbar/GlobalHeaderToolbar.js.map +2 -2
  69. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/AppPickerCTX.js +8 -0
  70. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/AppPickerCTX.js.map +7 -0
  71. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/AppPickerCTXRenderer.js +13 -0
  72. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/AppPickerCTXRenderer.js.map +7 -0
  73. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/AppPickerRenderer.js +22 -0
  74. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/AppPickerRenderer.js.map +7 -0
  75. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/TriggerDefaultComponent.js +54 -0
  76. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/TriggerDefaultComponent.js.map +7 -0
  77. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/react-desc-prop-types.js +20 -0
  78. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/react-desc-prop-types.js.map +7 -0
  79. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/useAppPickerCTX.js +34 -0
  80. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/useAppPickerCTX.js.map +7 -0
  81. package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/PopupMenu.js +108 -57
  82. package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/PopupMenu.js.map +2 -2
  83. package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/PopupMenuContent.js +28 -12
  84. package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/PopupMenuContent.js.map +2 -2
  85. package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/react-desc-prop-types.js +22 -0
  86. package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/react-desc-prop-types.js.map +7 -0
  87. package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/usePopupMenuContent.js +24 -16
  88. package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/usePopupMenuContent.js.map +2 -2
  89. package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/react-desc-prop-types.js +24 -0
  90. package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/react-desc-prop-types.js.map +7 -0
  91. package/dist/esm/parts/Toolbar/outOfTheBox/SearchToggle/SearchToggle.js +26 -16
  92. package/dist/esm/parts/Toolbar/outOfTheBox/SearchToggle/SearchToggle.js.map +2 -2
  93. package/dist/esm/parts/Toolbar/outOfTheBox/SearchToggle/SearchToggleSpinButton.js +60 -50
  94. package/dist/esm/parts/Toolbar/outOfTheBox/SearchToggle/SearchToggleSpinButton.js.map +2 -2
  95. package/dist/esm/parts/Toolbar/outOfTheBox/SearchToggle/react-desc-prop-types.js +28 -0
  96. package/dist/esm/parts/Toolbar/outOfTheBox/SearchToggle/react-desc-prop-types.js.map +7 -0
  97. package/dist/esm/parts/Toolbar/outOfTheBox/SearchToggle/useSearchToggle.js +33 -25
  98. package/dist/esm/parts/Toolbar/outOfTheBox/SearchToggle/useSearchToggle.js.map +2 -2
  99. package/dist/esm/parts/Toolbar/outOfTheBox/index.js +8 -3
  100. package/dist/esm/parts/Toolbar/outOfTheBox/index.js.map +2 -2
  101. package/dist/esm/parts/Toolbar/styles.js +6 -1
  102. package/dist/esm/parts/Toolbar/styles.js.map +2 -2
  103. package/dist/esm/react-desc-prop-types.js.map +2 -2
  104. package/dist/esm/typescript-testing/typescript-global-header-toolbar-types.js +52 -0
  105. package/dist/esm/typescript-testing/typescript-global-header-toolbar-types.js.map +2 -2
  106. package/dist/types/DSGlobalHeaderContext.d.ts +10 -2
  107. package/dist/types/config/useGlobalHeader.d.ts +3 -4
  108. package/dist/types/constants/index.d.ts +3 -3
  109. package/dist/types/index.d.ts +0 -2
  110. package/dist/types/parts/Toolbar/outOfTheBox/AppPicker/AppPickerCTX.d.ts +4 -0
  111. package/dist/types/parts/Toolbar/outOfTheBox/AppPicker/AppPickerCTXRenderer.d.ts +2 -0
  112. package/dist/types/parts/Toolbar/outOfTheBox/AppPicker/AppPickerRenderer.d.ts +1 -0
  113. package/dist/types/parts/Toolbar/outOfTheBox/AppPicker/TriggerDefaultComponent.d.ts +2 -0
  114. package/dist/types/parts/Toolbar/outOfTheBox/AppPicker/react-desc-prop-types.d.ts +23 -0
  115. package/dist/types/parts/Toolbar/outOfTheBox/AppPicker/useAppPickerCTX.d.ts +456 -0
  116. package/dist/types/parts/Toolbar/outOfTheBox/PopupMenu/PopupMenu.d.ts +2 -2
  117. package/dist/types/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/PopupMenuContent.d.ts +2 -2
  118. package/dist/types/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/react-desc-prop-types.d.ts +28 -0
  119. package/dist/types/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/usePopupMenuContent.d.ts +9 -1
  120. package/dist/types/parts/Toolbar/outOfTheBox/PopupMenu/react-desc-prop-types.d.ts +26 -0
  121. package/dist/types/parts/Toolbar/outOfTheBox/SearchToggle/SearchToggle.d.ts +2 -2
  122. package/dist/types/parts/Toolbar/outOfTheBox/SearchToggle/SearchToggleSpinButton.d.ts +2 -0
  123. package/dist/types/parts/Toolbar/outOfTheBox/SearchToggle/react-desc-prop-types.d.ts +26 -0
  124. package/dist/types/parts/Toolbar/outOfTheBox/SearchToggle/useSearchToggle.d.ts +2 -3
  125. package/dist/types/parts/Toolbar/outOfTheBox/index.d.ts +3 -3
  126. package/dist/types/parts/Toolbar/styles.d.ts +1 -0
  127. package/dist/types/react-desc-prop-types.d.ts +63 -72
  128. package/dist/types/sharedTypes.d.ts +16 -6
  129. package/package.json +16 -13
  130. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/AppPicker.js +0 -127
  131. package/dist/cjs/parts/Toolbar/outOfTheBox/AppPicker/AppPicker.js.map +0 -7
  132. package/dist/cjs/utils/useCallbackAfterRender.js.map +0 -7
  133. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/AppPicker.js +0 -97
  134. package/dist/esm/parts/Toolbar/outOfTheBox/AppPicker/AppPicker.js.map +0 -7
  135. package/dist/esm/utils/useCallbackAfterRender.js +0 -17
  136. package/dist/esm/utils/useCallbackAfterRender.js.map +0 -7
  137. package/dist/types/parts/Toolbar/outOfTheBox/AppPicker/AppPicker.d.ts +0 -6
  138. package/dist/types/utils/useCallbackAfterRender.d.ts +0 -3
@@ -1,17 +1,18 @@
1
1
  import * as React from "react";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useFloatingContext, PopoverArrow, FloatingWrapper } from "@elliemae/ds-floating-context";
4
- import { useGetGlobalAttributes } from "@elliemae/ds-props-helpers";
5
- import { useCallback } from "react";
4
+ import { useGetGlobalAttributes, useGetXstyledProps } from "@elliemae/ds-props-helpers";
5
+ import { useCallback, useRef } from "react";
6
6
  import { GLOBAL_HEADER_DATA_TESTID } from "../../../../constants/index.js";
7
7
  import { StyledButton } from "../../../styles.js";
8
+ import { StyledPopupMenuContainer } from "../../styles.js";
8
9
  import { PopupMenuContent } from "./menuContent/PopupMenuContent.js";
9
10
  const PopupMenu = ({
10
11
  Icon,
11
12
  onClick,
12
13
  setRef,
13
14
  componentProps,
14
- ownerProps,
15
+ getOwnerPropsAwareOfPropsPassedToGlobalHeader,
15
16
  ...otherProps
16
17
  }) => {
17
18
  const {
@@ -20,7 +21,9 @@ const PopupMenu = ({
20
21
  popupOnKeyPress,
21
22
  isOpen: userIsOpen,
22
23
  options,
23
- closeOnClick
24
+ closeOnClick,
25
+ onOpen,
26
+ onClose
24
27
  } = componentProps;
25
28
  const { arrowStyles, floatingStyles, isOpen, refs, context, showTooltip, hideTooltip } = useFloatingContext({
26
29
  externallyControlledIsOpen: componentProps.isOpen,
@@ -32,29 +35,66 @@ const PopupMenu = ({
32
35
  // Gated internally on `isOpen`, so it only fires while open.
33
36
  onClickOutside: (event) => {
34
37
  onClickOutside(event);
35
- if (userIsOpen === void 0) {
36
- hideTooltip();
37
- refs.reference?.focus();
38
- }
39
- }
38
+ if (userIsOpen === void 0) hideTooltip();
39
+ },
40
+ /*
41
+ * Passive notification, straight through from the floating context. Handed over rather than
42
+ * reimplemented because the hook is the only place that sees every transition: the trigger click and
43
+ * ArrowDown both go through `showTooltip`, and click-outside, Escape inside the menu and a
44
+ * closeOnClick item all go through `hideTooltip` — plus a controlled flip of `isOpen`, which no
45
+ * handler in this file observes at all.
46
+ *
47
+ * Notifying does NOT make the consumer responsible for the transition: this stays uncontrolled unless
48
+ * they also supply `isOpen`.
49
+ *
50
+ * The scoped-Escape caveat in the hook's docs does not apply here. A scoped Escape would route to
51
+ * `onEscape` instead of `onClose`, but that path needs `closeOnEscape`, which defaults to false and is
52
+ * not passed — Escape is handled inside PopupMenuContent and closes via `hideTooltip`, so it surfaces
53
+ * as a normal 'interaction' close. Passing `closeOnEscape` here later would silently punch a hole in
54
+ * `onClose` unless `onEscape` is wired at the same time.
55
+ */
56
+ /*
57
+ * Escape is the floating context's, not this part's. `closeOnEscape` closes the menu and
58
+ * `returnFocusToReference` puts focus back on the trigger — both were hand-rolled here before, in
59
+ * PopupMenuContent's per-item keydown and in a manual `.focus()`.
60
+ *
61
+ * Gated on being UNCONTROLLED, and that gate is load-bearing rather than tidy: the hook applies
62
+ * `returnFocusToReference` on a scoped Escape whichever side owns the open state. For a controlled
63
+ * consumer the close below is inert, so leaving it on would move focus to the trigger while their
64
+ * menu is still open — focus outside an open menu. A controlled consumer owns the close, so they own
65
+ * the Escape and the refocus with it.
66
+ */
67
+ closeOnEscape: userIsOpen === void 0,
68
+ returnFocusToReference: true,
69
+ /*
70
+ * A scoped Escape routes HERE and not to `onClose`, so the consumer's close notification has to be
71
+ * re-emitted or it silently stops reporting the most common keyboard close.
72
+ */
73
+ onEscape: (event) => {
74
+ hideTooltip();
75
+ onClose?.({ reason: "interaction", event, isControlled: userIsOpen !== void 0 });
76
+ },
77
+ onOpen,
78
+ onClose
40
79
  });
80
+ const openIntentRef = useRef("first");
41
81
  const handleOnKeyDown = useCallback(
42
82
  (e) => {
43
- if (e.code === "ArrowDown") {
44
- showTooltip();
83
+ if (e.code === "ArrowDown" || e.code === "ArrowUp") {
84
+ e.preventDefault();
85
+ openIntentRef.current = e.code === "ArrowUp" ? "last" : "first";
86
+ if (userIsOpen === void 0) showTooltip();
45
87
  }
46
88
  if (onKeyPress) onKeyPress(e);
47
89
  },
48
- [onKeyPress, showTooltip]
90
+ [onKeyPress, showTooltip, userIsOpen]
49
91
  );
50
92
  const handleOnClose = useCallback(() => {
51
- if (userIsOpen === void 0) {
52
- hideTooltip();
53
- }
54
- refs.reference?.focus();
55
- }, [hideTooltip, refs.reference, userIsOpen]);
93
+ if (userIsOpen === void 0) hideTooltip();
94
+ }, [hideTooltip, userIsOpen]);
56
95
  const handleTriggerOnClick = useCallback(
57
96
  (e) => {
97
+ openIntentRef.current = "first";
58
98
  if (userIsOpen === void 0) showTooltip(e);
59
99
  if (onClick) onClick(e);
60
100
  },
@@ -70,46 +110,57 @@ const PopupMenu = ({
70
110
  },
71
111
  [refs, setRef]
72
112
  );
73
- return /* @__PURE__ */ jsxs("div", { children: [
74
- /* @__PURE__ */ jsx(
75
- StyledButton,
76
- {
77
- onClick: handleTriggerOnClick,
78
- onKeyDown: handleOnKeyDown,
79
- innerRef: handleRefs,
80
- "data-testid": GLOBAL_HEADER_DATA_TESTID.MENUBAR_ITEM_BUTTON,
81
- "aria-haspopup": true,
82
- "aria-expanded": userIsOpen ?? isOpen,
83
- ...useGetGlobalAttributes(otherProps),
84
- type: "button",
85
- ...ownerProps,
86
- children: Icon && /* @__PURE__ */ jsx(Icon, { size: "m" })
87
- }
88
- ),
89
- refs.reference ? /* @__PURE__ */ jsxs(
90
- FloatingWrapper,
91
- {
92
- innerRef: refs.setFloating,
93
- isOpen: userIsOpen ?? isOpen,
94
- floatingStyles,
95
- context,
96
- children: [
97
- /* @__PURE__ */ jsx(
98
- PopupMenuContent,
99
- {
100
- options,
101
- onItemClick: handleItemClick,
102
- onClose: handleOnClose,
103
- setIsOpen: hideTooltip,
104
- popupOnKeyPress,
105
- ownerProps
106
- }
107
- ),
108
- /* @__PURE__ */ jsx(PopoverArrow, { ...arrowStyles })
109
- ]
110
- }
111
- ) : null
112
- ] });
113
+ const noSlotArguments = useCallback(() => ({}), []);
114
+ return /* @__PURE__ */ jsxs(
115
+ StyledPopupMenuContainer,
116
+ {
117
+ "data-testid": GLOBAL_HEADER_DATA_TESTID.MENUBAR_ITEM_POPUPMENU_CONTAINER,
118
+ getOwnerProps: getOwnerPropsAwareOfPropsPassedToGlobalHeader,
119
+ getOwnerPropsArguments: noSlotArguments,
120
+ ...useGetXstyledProps(otherProps),
121
+ children: [
122
+ /* @__PURE__ */ jsx(
123
+ StyledButton,
124
+ {
125
+ onClick: handleTriggerOnClick,
126
+ onKeyDown: handleOnKeyDown,
127
+ innerRef: handleRefs,
128
+ "data-testid": GLOBAL_HEADER_DATA_TESTID.MENUBAR_ITEM_BUTTON,
129
+ "aria-haspopup": true,
130
+ "aria-expanded": userIsOpen ?? isOpen,
131
+ ...useGetGlobalAttributes(otherProps),
132
+ type: "button",
133
+ getOwnerProps: getOwnerPropsAwareOfPropsPassedToGlobalHeader,
134
+ getOwnerPropsArguments: noSlotArguments,
135
+ children: Icon && /* @__PURE__ */ jsx(Icon, { size: "m" })
136
+ }
137
+ ),
138
+ refs.reference ? /* @__PURE__ */ jsxs(
139
+ FloatingWrapper,
140
+ {
141
+ innerRef: refs.setFloating,
142
+ isOpen: userIsOpen ?? isOpen,
143
+ floatingStyles,
144
+ context,
145
+ children: [
146
+ /* @__PURE__ */ jsx(
147
+ PopupMenuContent,
148
+ {
149
+ options,
150
+ onItemClick: handleItemClick,
151
+ openIntent: openIntentRef.current,
152
+ setIsOpen: hideTooltip,
153
+ popupOnKeyPress,
154
+ getOwnerPropsAwareOfPropsPassedToGlobalHeader
155
+ }
156
+ ),
157
+ /* @__PURE__ */ jsx(PopoverArrow, { ...arrowStyles })
158
+ ]
159
+ }
160
+ ) : null
161
+ ]
162
+ }
163
+ );
113
164
  };
114
165
  export {
115
166
  PopupMenu
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../../src/parts/Toolbar/outOfTheBox/PopupMenu/PopupMenu.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useFloatingContext, PopoverArrow, FloatingWrapper } from '@elliemae/ds-floating-context';\nimport { useGetGlobalAttributes } from '@elliemae/ds-props-helpers';\nimport React, { useCallback } from 'react';\nimport { GLOBAL_HEADER_DATA_TESTID } from '../../../../constants/index.js';\nimport type { DSGlobalHeaderT } from '../../../../react-desc-prop-types.js';\nimport { StyledButton } from '../../../styles.js';\nimport { PopupMenuContent } from './menuContent/PopupMenuContent.js';\n\nexport const PopupMenu = ({\n Icon,\n onClick,\n setRef,\n componentProps,\n ownerProps,\n ...otherProps\n}: DSGlobalHeaderT.PopupProps): JSX.Element => {\n const {\n onClickOutside = () => null,\n onKeyPress,\n popupOnKeyPress,\n isOpen: userIsOpen,\n options,\n closeOnClick,\n } = componentProps;\n\n // We need to declare the floating context before we can reference its hideTooltip in\n // handleOutside; but handleOutside is passed into the same hook call. We resolve this by\n // pulling hideTooltip / refs.reference via the latest-ref pattern of the hook itself \u2014\n // see comments on `onClickOutside` below.\n const { arrowStyles, floatingStyles, isOpen, refs, context, showTooltip, hideTooltip } = useFloatingContext({\n externallyControlledIsOpen: componentProps.isOpen,\n placement: 'bottom',\n withoutAnimation: true,\n withoutPortal: true,\n // The hook auto-excludes clicks inside the floating element and the reference, so the\n // outside boundary is now { reference, floating } \u2014 no boundary <div> needed.\n // Gated internally on `isOpen`, so it only fires while open.\n onClickOutside: (event) => {\n onClickOutside(event);\n if (userIsOpen === undefined) {\n hideTooltip();\n (refs.reference as HTMLElement)?.focus();\n }\n },\n });\n\n const handleOnKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.code === 'ArrowDown') {\n showTooltip();\n }\n if (onKeyPress) onKeyPress(e);\n },\n [onKeyPress, showTooltip],\n );\n\n const handleOnClose = useCallback(() => {\n if (userIsOpen === undefined) {\n hideTooltip();\n }\n (refs.reference as HTMLElement)?.focus();\n }, [hideTooltip, refs.reference, userIsOpen]);\n\n const handleTriggerOnClick = useCallback(\n (e: React.MouseEvent) => {\n if (userIsOpen === undefined) showTooltip(e);\n if (onClick) onClick(e);\n },\n [onClick, userIsOpen, showTooltip],\n );\n\n const handleItemClick = useCallback(() => {\n if (closeOnClick && userIsOpen === undefined) handleOnClose();\n }, [closeOnClick, handleOnClose, userIsOpen]);\n\n const handleRefs = useCallback(\n (ref: HTMLButtonElement) => {\n setRef(ref);\n refs.setReference(ref);\n },\n [refs, setRef],\n );\n return (\n <div>\n <StyledButton\n onClick={handleTriggerOnClick}\n onKeyDown={handleOnKeyDown}\n innerRef={handleRefs}\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_ITEM_BUTTON}\n aria-haspopup\n aria-expanded={userIsOpen ?? isOpen}\n {...useGetGlobalAttributes(otherProps)}\n type=\"button\"\n {...ownerProps}\n >\n {Icon && <Icon size=\"m\" />}\n </StyledButton>\n\n {refs.reference ? (\n <FloatingWrapper\n innerRef={refs.setFloating}\n isOpen={userIsOpen ?? isOpen}\n floatingStyles={floatingStyles}\n context={context}\n >\n <PopupMenuContent\n options={options}\n onItemClick={handleItemClick}\n onClose={handleOnClose}\n setIsOpen={hideTooltip}\n popupOnKeyPress={popupOnKeyPress}\n ownerProps={ownerProps}\n />\n <PopoverArrow {...arrowStyles} />\n </FloatingWrapper>\n ) : null}\n </div>\n );\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;AC+FN,cAIT,YAJS;AA/FjB,SAAS,oBAAoB,cAAc,uBAAuB;AAClE,SAAS,8BAA8B;AACvC,SAAgB,mBAAmB;AACnC,SAAS,iCAAiC;AAE1C,SAAS,oBAAoB;AAC7B,SAAS,wBAAwB;AAE1B,MAAM,YAAY,CAAC;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA+C;AAC7C,QAAM;AAAA,IACJ,iBAAiB,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,EACF,IAAI;AAMJ,QAAM,EAAE,aAAa,gBAAgB,QAAQ,MAAM,SAAS,aAAa,YAAY,IAAI,mBAAmB;AAAA,IAC1G,4BAA4B,eAAe;AAAA,IAC3C,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,eAAe;AAAA;AAAA;AAAA;AAAA,IAIf,gBAAgB,CAAC,UAAU;AACzB,qBAAe,KAAK;AACpB,UAAI,eAAe,QAAW;AAC5B,oBAAY;AACZ,QAAC,KAAK,WAA2B,MAAM;AAAA,MACzC;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,kBAAkB;AAAA,IACtB,CAAC,MAA2B;AAC1B,UAAI,EAAE,SAAS,aAAa;AAC1B,oBAAY;AAAA,MACd;AACA,UAAI,WAAY,YAAW,CAAC;AAAA,IAC9B;AAAA,IACA,CAAC,YAAY,WAAW;AAAA,EAC1B;AAEA,QAAM,gBAAgB,YAAY,MAAM;AACtC,QAAI,eAAe,QAAW;AAC5B,kBAAY;AAAA,IACd;AACA,IAAC,KAAK,WAA2B,MAAM;AAAA,EACzC,GAAG,CAAC,aAAa,KAAK,WAAW,UAAU,CAAC;AAE5C,QAAM,uBAAuB;AAAA,IAC3B,CAAC,MAAwB;AACvB,UAAI,eAAe,OAAW,aAAY,CAAC;AAC3C,UAAI,QAAS,SAAQ,CAAC;AAAA,IACxB;AAAA,IACA,CAAC,SAAS,YAAY,WAAW;AAAA,EACnC;AAEA,QAAM,kBAAkB,YAAY,MAAM;AACxC,QAAI,gBAAgB,eAAe,OAAW,eAAc;AAAA,EAC9D,GAAG,CAAC,cAAc,eAAe,UAAU,CAAC;AAE5C,QAAM,aAAa;AAAA,IACjB,CAAC,QAA2B;AAC1B,aAAO,GAAG;AACV,WAAK,aAAa,GAAG;AAAA,IACvB;AAAA,IACA,CAAC,MAAM,MAAM;AAAA,EACf;AACA,SACE,qBAAC,SACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,QACV,eAAa,0BAA0B;AAAA,QACvC,iBAAa;AAAA,QACb,iBAAe,cAAc;AAAA,QAC5B,GAAG,uBAAuB,UAAU;AAAA,QACrC,MAAK;AAAA,QACJ,GAAG;AAAA,QAEH,kBAAQ,oBAAC,QAAK,MAAK,KAAI;AAAA;AAAA,IAC1B;AAAA,IAEC,KAAK,YACJ;AAAA,MAAC;AAAA;AAAA,QACC,UAAU,KAAK;AAAA,QACf,QAAQ,cAAc;AAAA,QACtB;AAAA,QACA;AAAA,QAEA;AAAA;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA,aAAa;AAAA,cACb,SAAS;AAAA,cACT,WAAW;AAAA,cACX;AAAA,cACA;AAAA;AAAA,UACF;AAAA,UACA,oBAAC,gBAAc,GAAG,aAAa;AAAA;AAAA;AAAA,IACjC,IACE;AAAA,KACN;AAEJ;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useFloatingContext, PopoverArrow, FloatingWrapper } from '@elliemae/ds-floating-context';\nimport { useGetGlobalAttributes, useGetXstyledProps } from '@elliemae/ds-props-helpers';\nimport React, { useCallback, useRef } from 'react';\nimport { GLOBAL_HEADER_DATA_TESTID } from '../../../../constants/index.js';\nimport { StyledButton } from '../../../styles.js';\nimport { StyledPopupMenuContainer } from '../../styles.js';\nimport { PopupMenuContent } from './menuContent/PopupMenuContent.js';\nimport type { PopupMenuT } from './react-desc-prop-types.js';\n\nexport const PopupMenu = ({\n Icon,\n onClick,\n setRef,\n componentProps,\n getOwnerPropsAwareOfPropsPassedToGlobalHeader,\n ...otherProps\n}: PopupMenuT.Props): JSX.Element => {\n const {\n onClickOutside = () => null,\n onKeyPress,\n popupOnKeyPress,\n isOpen: userIsOpen,\n options,\n closeOnClick,\n onOpen,\n onClose,\n } = componentProps;\n\n // We need to declare the floating context before we can reference its hideTooltip in\n // handleOutside; but handleOutside is passed into the same hook call. We resolve this by\n // pulling hideTooltip / refs.reference via the latest-ref pattern of the hook itself \u2014\n // see comments on `onClickOutside` below.\n const { arrowStyles, floatingStyles, isOpen, refs, context, showTooltip, hideTooltip } = useFloatingContext({\n externallyControlledIsOpen: componentProps.isOpen,\n placement: 'bottom',\n withoutAnimation: true,\n withoutPortal: true,\n // The hook auto-excludes clicks inside the floating element and the reference, so the\n // outside boundary is now { reference, floating } \u2014 no boundary <div> needed.\n // Gated internally on `isOpen`, so it only fires while open.\n onClickOutside: (event) => {\n onClickOutside(event);\n // Closes but does NOT move focus. The user clicked somewhere else and the browser has already put\n // focus where they aimed; pulling it back to the trigger would undo that. Returning focus is a\n // scoped-Escape affordance only \u2014 the same line DSAppPicker and the floating context both draw.\n if (userIsOpen === undefined) hideTooltip();\n },\n /*\n * Passive notification, straight through from the floating context. Handed over rather than\n * reimplemented because the hook is the only place that sees every transition: the trigger click and\n * ArrowDown both go through `showTooltip`, and click-outside, Escape inside the menu and a\n * closeOnClick item all go through `hideTooltip` \u2014 plus a controlled flip of `isOpen`, which no\n * handler in this file observes at all.\n *\n * Notifying does NOT make the consumer responsible for the transition: this stays uncontrolled unless\n * they also supply `isOpen`.\n *\n * The scoped-Escape caveat in the hook's docs does not apply here. A scoped Escape would route to\n * `onEscape` instead of `onClose`, but that path needs `closeOnEscape`, which defaults to false and is\n * not passed \u2014 Escape is handled inside PopupMenuContent and closes via `hideTooltip`, so it surfaces\n * as a normal 'interaction' close. Passing `closeOnEscape` here later would silently punch a hole in\n * `onClose` unless `onEscape` is wired at the same time.\n */\n /*\n * Escape is the floating context's, not this part's. `closeOnEscape` closes the menu and\n * `returnFocusToReference` puts focus back on the trigger \u2014 both were hand-rolled here before, in\n * PopupMenuContent's per-item keydown and in a manual `.focus()`.\n *\n * Gated on being UNCONTROLLED, and that gate is load-bearing rather than tidy: the hook applies\n * `returnFocusToReference` on a scoped Escape whichever side owns the open state. For a controlled\n * consumer the close below is inert, so leaving it on would move focus to the trigger while their\n * menu is still open \u2014 focus outside an open menu. A controlled consumer owns the close, so they own\n * the Escape and the refocus with it.\n */\n closeOnEscape: userIsOpen === undefined,\n returnFocusToReference: true,\n /*\n * A scoped Escape routes HERE and not to `onClose`, so the consumer's close notification has to be\n * re-emitted or it silently stops reporting the most common keyboard close.\n */\n onEscape: (event) => {\n hideTooltip();\n onClose?.({ reason: 'interaction', event, isControlled: userIsOpen !== undefined });\n },\n onOpen,\n onClose,\n });\n\n /*\n * WHICH end of the menu the pending open lands on. Same mechanism as DSAppPicker's `openIntentRef`,\n * scoped to this part: the trigger is the only place that knows which key was pressed, and the seeding\n * happens later, in PopupMenuContent's ref callback. A ref rather than state because nothing renders\n * from it and it must not cause a render of its own between the key and the open.\n */\n const openIntentRef = useRef<'first' | 'last'>('first');\n\n /*\n * ArrowDown opens onto the first item, ArrowUp onto the last \u2014 the menubar convention, and the same\n * split DSAppPicker makes.\n *\n * Enter and Space are absent on purpose: this is a native <button>, so the browser turns them into a\n * click that arrives at handleTriggerOnClick. Handling them here too would open twice.\n *\n * `preventDefault` stops the page scrolling on a key being used to open a widget.\n */\n const handleOnKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.code === 'ArrowDown' || e.code === 'ArrowUp') {\n e.preventDefault();\n openIntentRef.current = e.code === 'ArrowUp' ? 'last' : 'first';\n if (userIsOpen === undefined) showTooltip();\n }\n if (onKeyPress) onKeyPress(e);\n },\n [onKeyPress, showTooltip, userIsOpen],\n );\n\n /*\n * Closes after an item click. No `.focus()` here: returning focus to the trigger is the floating\n * context's job on a scoped Escape, and an item click is not one \u2014 the clicked item is usually\n * navigating away, so yanking focus back to the trigger would fight the user.\n */\n const handleOnClose = useCallback(() => {\n if (userIsOpen === undefined) hideTooltip();\n }, [hideTooltip, userIsOpen]);\n\n const handleTriggerOnClick = useCallback(\n (e: React.MouseEvent) => {\n // Click, Enter and Space all land on the first item; only ArrowUp asks for the other end.\n openIntentRef.current = 'first';\n if (userIsOpen === undefined) showTooltip(e);\n if (onClick) onClick(e);\n },\n [onClick, userIsOpen, showTooltip],\n );\n\n const handleItemClick = useCallback(() => {\n if (closeOnClick && userIsOpen === undefined) handleOnClose();\n }, [closeOnClick, handleOnClose, userIsOpen]);\n\n const handleRefs = useCallback(\n (ref: HTMLButtonElement) => {\n setRef(ref);\n refs.setReference(ref);\n },\n [refs, setRef],\n );\n\n // Explicit and empty, shared by this part's slot render sites: `getOwnerPropsArguments` hydrates\n // function-form slot props and nothing else, and none of these elements have render-time values worth\n // passing. Stated rather than omitted so the answer is always visible at the call site.\n const noSlotArguments = useCallback(() => ({}), []);\n return (\n <StyledPopupMenuContainer\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_ITEM_POPUPMENU_CONTAINER}\n getOwnerProps={getOwnerPropsAwareOfPropsPassedToGlobalHeader}\n // Explicit and empty: this root has no render-time values to hand a function-form slot prop.\n getOwnerPropsArguments={noSlotArguments}\n // The part-level xstyled layer. This root is the only element in the part that can receive it, so it\n // must stay a styled component \u2014 a plain <div> here silently drops every xstyled prop the contract\n // advertises.\n {...useGetXstyledProps(otherProps)}\n >\n <StyledButton\n onClick={handleTriggerOnClick}\n onKeyDown={handleOnKeyDown}\n innerRef={handleRefs}\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_ITEM_BUTTON}\n aria-haspopup\n aria-expanded={userIsOpen ?? isOpen}\n {...useGetGlobalAttributes(otherProps)}\n type=\"button\"\n getOwnerProps={getOwnerPropsAwareOfPropsPassedToGlobalHeader}\n getOwnerPropsArguments={noSlotArguments}\n >\n {Icon && <Icon size=\"m\" />}\n </StyledButton>\n\n {refs.reference ? (\n <FloatingWrapper\n innerRef={refs.setFloating}\n isOpen={userIsOpen ?? isOpen}\n floatingStyles={floatingStyles}\n context={context}\n >\n <PopupMenuContent\n options={options}\n onItemClick={handleItemClick}\n openIntent={openIntentRef.current}\n setIsOpen={hideTooltip}\n popupOnKeyPress={popupOnKeyPress}\n getOwnerPropsAwareOfPropsPassedToGlobalHeader={getOwnerPropsAwareOfPropsPassedToGlobalHeader}\n />\n <PopoverArrow {...arrowStyles} />\n </FloatingWrapper>\n ) : null}\n </StyledPopupMenuContainer>\n );\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { getGlobalAttributes } from "@elliemae/ds-props-helpers";
3
+ import { getGlobalAttributes, getXstyledProps } from "@elliemae/ds-props-helpers";
4
4
  import React2, { useContext } from "react";
5
5
  import { DSGlobalHeaderContext } from "../../../../../DSGlobalHeaderContext.js";
6
6
  import { GLOBAL_HEADER_DATA_TESTID } from "../../../../../constants/index.js";
@@ -10,20 +10,31 @@ const PopupMenuContent = React2.memo(
10
10
  ({
11
11
  options,
12
12
  onItemClick,
13
- onClose,
13
+ openIntent,
14
14
  popupOnKeyPress,
15
15
  setIsOpen,
16
- ownerProps
16
+ getOwnerPropsAwareOfPropsPassedToGlobalHeader,
17
+ // The part-level global attribute + xstyled layers, forwarded onto the list root below.
18
+ ...restGlobalAndXstyled
17
19
  }) => {
18
20
  const { instanceUID } = useContext(DSGlobalHeaderContext);
19
- const { menuRef, setRef, keyboardNavigation } = usePopupMenuContent({ setIsOpen });
21
+ const focusableItemsCount = options.filter((option) => option.type !== "separator").length;
22
+ const { menuRef, setRef, keyboardNavigation } = usePopupMenuContent({
23
+ setIsOpen,
24
+ openIntent,
25
+ focusableItemsCount
26
+ });
27
+ const noSlotArguments = () => ({});
20
28
  return /* @__PURE__ */ jsx(
21
29
  StyledList,
22
30
  {
23
31
  innerRef: menuRef,
24
32
  role: "menu",
25
33
  "data-testid": GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_LIST,
26
- ...ownerProps,
34
+ getOwnerProps: getOwnerPropsAwareOfPropsPassedToGlobalHeader,
35
+ getOwnerPropsArguments: noSlotArguments,
36
+ ...getGlobalAttributes(restGlobalAndXstyled),
37
+ ...getXstyledProps(restGlobalAndXstyled),
27
38
  children: options.map((option) => {
28
39
  const { type, Icon, label = "", onClick, Content, ...rest } = option;
29
40
  const globalAttrs = getGlobalAttributes(rest);
@@ -33,7 +44,6 @@ const PopupMenuContent = React2.memo(
33
44
  };
34
45
  const handleKeyDown = (e) => {
35
46
  keyboardNavigation(e);
36
- if (e.code === "Escape") onClose();
37
47
  if (popupOnKeyPress) popupOnKeyPress(e);
38
48
  };
39
49
  switch (type) {
@@ -44,7 +54,8 @@ const PopupMenuContent = React2.memo(
44
54
  role: "none",
45
55
  "data-testid": GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_SEPARATOR,
46
56
  ...globalAttrs,
47
- ...ownerProps
57
+ getOwnerProps: getOwnerPropsAwareOfPropsPassedToGlobalHeader,
58
+ getOwnerPropsArguments: noSlotArguments
48
59
  },
49
60
  `${instanceUID}-separator-${label}`
50
61
  );
@@ -54,7 +65,8 @@ const PopupMenuContent = React2.memo(
54
65
  {
55
66
  role: "menuitem",
56
67
  "data-testid": GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM,
57
- ...ownerProps,
68
+ getOwnerProps: getOwnerPropsAwareOfPropsPassedToGlobalHeader,
69
+ getOwnerPropsArguments: noSlotArguments,
58
70
  children: /* @__PURE__ */ jsx(
59
71
  StyledItemButton,
60
72
  {
@@ -64,7 +76,8 @@ const PopupMenuContent = React2.memo(
64
76
  "data-testid": GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM_BUTTON,
65
77
  ...globalAttrs,
66
78
  type: "button",
67
- ...ownerProps,
79
+ getOwnerProps: getOwnerPropsAwareOfPropsPassedToGlobalHeader,
80
+ getOwnerPropsArguments: noSlotArguments,
68
81
  children: Content && /* @__PURE__ */ jsx(Content, {})
69
82
  }
70
83
  )
@@ -77,7 +90,8 @@ const PopupMenuContent = React2.memo(
77
90
  {
78
91
  role: "menuitem",
79
92
  "data-testid": GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM,
80
- ...ownerProps,
93
+ getOwnerProps: getOwnerPropsAwareOfPropsPassedToGlobalHeader,
94
+ getOwnerPropsArguments: noSlotArguments,
81
95
  children: /* @__PURE__ */ jsxs(
82
96
  StyledItemButton,
83
97
  {
@@ -87,14 +101,16 @@ const PopupMenuContent = React2.memo(
87
101
  "data-testid": GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM_BUTTON,
88
102
  ...globalAttrs,
89
103
  type: "button",
90
- ...ownerProps,
104
+ getOwnerProps: getOwnerPropsAwareOfPropsPassedToGlobalHeader,
105
+ getOwnerPropsArguments: noSlotArguments,
91
106
  children: [
92
107
  Icon && /* @__PURE__ */ jsx(Icon, {}),
93
108
  label && /* @__PURE__ */ jsx(
94
109
  StyledLabel,
95
110
  {
96
111
  "data-testid": GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM_BUTTON_LABEL,
97
- ...ownerProps,
112
+ getOwnerProps: getOwnerPropsAwareOfPropsPassedToGlobalHeader,
113
+ getOwnerPropsArguments: noSlotArguments,
98
114
  children: label
99
115
  }
100
116
  )
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../../../src/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/PopupMenuContent.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { getGlobalAttributes } from '@elliemae/ds-props-helpers';\nimport React, { useContext } from 'react';\nimport { DSGlobalHeaderContext } from '../../../../../DSGlobalHeaderContext.js';\nimport { GLOBAL_HEADER_DATA_TESTID } from '../../../../../constants/index.js';\nimport type { DSGlobalHeaderT } from '../../../../../react-desc-prop-types.js';\nimport { StyledItemButton, StyledItemContainer, StyledLabel, StyledList, StyledSeparator } from './styles.js';\nimport { usePopupMenuContent } from './usePopupMenuContent.js';\n\nexport const PopupMenuContent = React.memo(\n ({\n options,\n onItemClick,\n onClose,\n popupOnKeyPress,\n setIsOpen,\n ownerProps,\n }: DSGlobalHeaderT.PopupMenuContentProps): JSX.Element => {\n const { instanceUID } = useContext(DSGlobalHeaderContext);\n\n const { menuRef, setRef, keyboardNavigation } = usePopupMenuContent({ setIsOpen });\n\n return (\n <StyledList\n innerRef={menuRef}\n role=\"menu\"\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_LIST}\n {...ownerProps}\n >\n {options.map((option) => {\n const { type, Icon, label = '', onClick, Content, ...rest } = option;\n\n const globalAttrs = getGlobalAttributes(rest);\n\n const handleClick = (e: React.MouseEvent) => {\n onItemClick();\n if (onClick) onClick(e);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n keyboardNavigation(e);\n if (e.code === 'Escape') onClose();\n if (popupOnKeyPress) popupOnKeyPress(e);\n };\n\n switch (type) {\n case 'separator':\n return (\n <StyledSeparator\n key={`${instanceUID}-separator-${label}`}\n role=\"none\"\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_SEPARATOR}\n {...globalAttrs}\n {...ownerProps}\n />\n );\n case 'custom':\n return (\n <StyledItemContainer\n key={`${instanceUID}-popup-${label}`}\n role=\"menuitem\"\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM}\n {...ownerProps}\n >\n <StyledItemButton\n innerRef={setRef}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM_BUTTON}\n {...globalAttrs}\n type=\"button\"\n {...ownerProps}\n >\n {Content && <Content />}\n </StyledItemButton>\n </StyledItemContainer>\n );\n default:\n return (\n <StyledItemContainer\n key={`${instanceUID}-popup-${label}`}\n role=\"menuitem\"\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM}\n {...ownerProps}\n >\n <StyledItemButton\n innerRef={setRef}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM_BUTTON}\n {...globalAttrs}\n type=\"button\"\n {...ownerProps}\n >\n {Icon && <Icon />}\n {label && (\n <StyledLabel\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM_BUTTON_LABEL}\n {...ownerProps}\n >\n {label}\n </StyledLabel>\n )}\n </StyledItemButton>\n </StyledItemContainer>\n );\n }\n })}\n </StyledList>\n );\n },\n);\n"],
5
- "mappings": "AAAA,YAAY,WAAW;AC+CP,cAqCE,YArCF;AA/ChB,SAAS,2BAA2B;AACpC,OAAOA,UAAS,kBAAkB;AAClC,SAAS,6BAA6B;AACtC,SAAS,iCAAiC;AAE1C,SAAS,kBAAkB,qBAAqB,aAAa,YAAY,uBAAuB;AAChG,SAAS,2BAA2B;AAE7B,MAAM,mBAAmBA,OAAM;AAAA,EACpC,CAAC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAA0D;AACxD,UAAM,EAAE,YAAY,IAAI,WAAW,qBAAqB;AAExD,UAAM,EAAE,SAAS,QAAQ,mBAAmB,IAAI,oBAAoB,EAAE,UAAU,CAAC;AAEjF,WACE;AAAA,MAAC;AAAA;AAAA,QACC,UAAU;AAAA,QACV,MAAK;AAAA,QACL,eAAa,0BAA0B;AAAA,QACtC,GAAG;AAAA,QAEH,kBAAQ,IAAI,CAAC,WAAW;AACvB,gBAAM,EAAE,MAAM,MAAM,QAAQ,IAAI,SAAS,SAAS,GAAG,KAAK,IAAI;AAE9D,gBAAM,cAAc,oBAAoB,IAAI;AAE5C,gBAAM,cAAc,CAAC,MAAwB;AAC3C,wBAAY;AACZ,gBAAI,QAAS,SAAQ,CAAC;AAAA,UACxB;AAEA,gBAAM,gBAAgB,CAAC,MAA2B;AAChD,+BAAmB,CAAC;AACpB,gBAAI,EAAE,SAAS,SAAU,SAAQ;AACjC,gBAAI,gBAAiB,iBAAgB,CAAC;AAAA,UACxC;AAEA,kBAAQ,MAAM;AAAA,YACZ,KAAK;AACH,qBACE;AAAA,gBAAC;AAAA;AAAA,kBAEC,MAAK;AAAA,kBACL,eAAa,0BAA0B;AAAA,kBACtC,GAAG;AAAA,kBACH,GAAG;AAAA;AAAA,gBAJC,GAAG,WAAW,cAAc,KAAK;AAAA,cAKxC;AAAA,YAEJ,KAAK;AACH,qBACE;AAAA,gBAAC;AAAA;AAAA,kBAEC,MAAK;AAAA,kBACL,eAAa,0BAA0B;AAAA,kBACtC,GAAG;AAAA,kBAEJ;AAAA,oBAAC;AAAA;AAAA,sBACC,UAAU;AAAA,sBACV,SAAS;AAAA,sBACT,WAAW;AAAA,sBACX,eAAa,0BAA0B;AAAA,sBACtC,GAAG;AAAA,sBACJ,MAAK;AAAA,sBACJ,GAAG;AAAA,sBAEH,qBAAW,oBAAC,WAAQ;AAAA;AAAA,kBACvB;AAAA;AAAA,gBAfK,GAAG,WAAW,UAAU,KAAK;AAAA,cAgBpC;AAAA,YAEJ;AACE,qBACE;AAAA,gBAAC;AAAA;AAAA,kBAEC,MAAK;AAAA,kBACL,eAAa,0BAA0B;AAAA,kBACtC,GAAG;AAAA,kBAEJ;AAAA,oBAAC;AAAA;AAAA,sBACC,UAAU;AAAA,sBACV,SAAS;AAAA,sBACT,WAAW;AAAA,sBACX,eAAa,0BAA0B;AAAA,sBACtC,GAAG;AAAA,sBACJ,MAAK;AAAA,sBACJ,GAAG;AAAA,sBAEH;AAAA,gCAAQ,oBAAC,QAAK;AAAA,wBACd,SACC;AAAA,0BAAC;AAAA;AAAA,4BACC,eAAa,0BAA0B;AAAA,4BACtC,GAAG;AAAA,4BAEH;AAAA;AAAA,wBACH;AAAA;AAAA;AAAA,kBAEJ;AAAA;AAAA,gBAvBK,GAAG,WAAW,UAAU,KAAK;AAAA,cAwBpC;AAAA,UAEN;AAAA,QACF,CAAC;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { getGlobalAttributes, getXstyledProps } from '@elliemae/ds-props-helpers';\nimport React, { useContext } from 'react';\nimport { DSGlobalHeaderContext } from '../../../../../DSGlobalHeaderContext.js';\nimport { GLOBAL_HEADER_DATA_TESTID } from '../../../../../constants/index.js';\nimport { StyledItemButton, StyledItemContainer, StyledLabel, StyledList, StyledSeparator } from './styles.js';\nimport type { PopupMenuContentT } from './react-desc-prop-types.js';\nimport { usePopupMenuContent } from './usePopupMenuContent.js';\n\nexport const PopupMenuContent = React.memo(\n ({\n options,\n onItemClick,\n openIntent,\n popupOnKeyPress,\n setIsOpen,\n getOwnerPropsAwareOfPropsPassedToGlobalHeader,\n // The part-level global attribute + xstyled layers, forwarded onto the list root below.\n ...restGlobalAndXstyled\n }: PopupMenuContentT.Props): JSX.Element => {\n const { instanceUID } = useContext(DSGlobalHeaderContext);\n\n // Separators are rendered as `role=\"none\"` and carry no ref, so they are excluded from the count the\n // seeding compares against.\n const focusableItemsCount = options.filter((option) => option.type !== 'separator').length;\n\n const { menuRef, setRef, keyboardNavigation } = usePopupMenuContent({\n setIsOpen,\n openIntent,\n focusableItemsCount,\n });\n\n /*\n * Explicit and empty at every slot render site below. `getOwnerPropsArguments` hydrates function-form\n * slot props and nothing else, so \"no arguments\" is worth stating rather than leaving to inference.\n *\n * The per-option sites (item container, item button, label, separator) are where a real payload would\n * go \u2014 ds-fast-list hands its rows `{ index: getId(index) }` for exactly this. What a per-option payload\n * should contain is a consumer-facing contract decision, so adding one is a deliberate API change, not\n * a fill-in-the-blank.\n */\n const noSlotArguments = () => ({});\n\n return (\n <StyledList\n innerRef={menuRef}\n role=\"menu\"\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_LIST}\n getOwnerProps={getOwnerPropsAwareOfPropsPassedToGlobalHeader}\n getOwnerPropsArguments={noSlotArguments}\n {...getGlobalAttributes(restGlobalAndXstyled)}\n {...getXstyledProps(restGlobalAndXstyled)}\n >\n {options.map((option) => {\n const { type, Icon, label = '', onClick, Content, ...rest } = option;\n\n const globalAttrs = getGlobalAttributes(rest);\n\n const handleClick = (e: React.MouseEvent) => {\n onItemClick();\n if (onClick) onClick(e);\n };\n\n /*\n * No Escape branch here on purpose. Escape is the floating context's, via `closeOnEscape` +\n * `returnFocusToReference` \u2014 it closes the menu AND returns focus to the trigger, which this\n * part used to hand-roll. Re-adding a local Escape would close it twice and fight that focus\n * return.\n */\n const handleKeyDown = (e: React.KeyboardEvent) => {\n keyboardNavigation(e);\n if (popupOnKeyPress) popupOnKeyPress(e);\n };\n\n switch (type) {\n case 'separator':\n return (\n <StyledSeparator\n key={`${instanceUID}-separator-${label}`}\n role=\"none\"\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_SEPARATOR}\n {...globalAttrs}\n getOwnerProps={getOwnerPropsAwareOfPropsPassedToGlobalHeader}\n getOwnerPropsArguments={noSlotArguments}\n />\n );\n case 'custom':\n return (\n <StyledItemContainer\n key={`${instanceUID}-popup-${label}`}\n role=\"menuitem\"\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM}\n getOwnerProps={getOwnerPropsAwareOfPropsPassedToGlobalHeader}\n getOwnerPropsArguments={noSlotArguments}\n >\n <StyledItemButton\n innerRef={setRef}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM_BUTTON}\n {...globalAttrs}\n type=\"button\"\n getOwnerProps={getOwnerPropsAwareOfPropsPassedToGlobalHeader}\n getOwnerPropsArguments={noSlotArguments}\n >\n {Content && <Content />}\n </StyledItemButton>\n </StyledItemContainer>\n );\n default:\n return (\n <StyledItemContainer\n key={`${instanceUID}-popup-${label}`}\n role=\"menuitem\"\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM}\n getOwnerProps={getOwnerPropsAwareOfPropsPassedToGlobalHeader}\n getOwnerPropsArguments={noSlotArguments}\n >\n <StyledItemButton\n innerRef={setRef}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM_BUTTON}\n {...globalAttrs}\n type=\"button\"\n getOwnerProps={getOwnerPropsAwareOfPropsPassedToGlobalHeader}\n getOwnerPropsArguments={noSlotArguments}\n >\n {Icon && <Icon />}\n {label && (\n <StyledLabel\n data-testid={GLOBAL_HEADER_DATA_TESTID.MENUBAR_POPUP_MENU_ITEM_BUTTON_LABEL}\n getOwnerProps={getOwnerPropsAwareOfPropsPassedToGlobalHeader}\n getOwnerPropsArguments={noSlotArguments}\n >\n {label}\n </StyledLabel>\n )}\n </StyledItemButton>\n </StyledItemContainer>\n );\n }\n })}\n </StyledList>\n );\n },\n);\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -0,0 +1,22 @@
1
+ import * as React from "react";
2
+ import { PropTypes, globalAttributesPropTypes, xstyledPropTypes } from "@elliemae/ds-props-helpers";
3
+ const PopupMenuContentPropTypes = {
4
+ ...globalAttributesPropTypes,
5
+ ...xstyledPropTypes,
6
+ options: PropTypes.array.description(
7
+ "Consumer-authored menu entries. Format: [{ type?, Icon?, label?, onClick?, Content?, ...globalAttributes }]"
8
+ ).isRequired,
9
+ onItemClick: PropTypes.func.description("Invoked after a menu item click so the wrapper can apply its closeOnClick policy").signature("(() => void )").isRequired,
10
+ openIntent: PropTypes.string.description('Which end of the menu this open lands on: "first" or "last"').isRequired,
11
+ setIsOpen: PropTypes.func.description("The floating context's hide function").signature("(() => void )").isRequired,
12
+ getOwnerPropsAwareOfPropsPassedToGlobalHeader: PropTypes.func.description(
13
+ "Returns the props passed to DSGlobalHeader, so getPartProps can look up this slot consumer-supplied props. Must come from DSGlobalHeader; the function-form hydrator is supplied per slot render site instead"
14
+ ).signature("(() => Partial<DSGlobalHeaderT.DefaultProps> )").isRequired,
15
+ popupOnKeyPress: PropTypes.func.description("Consumer key handler, invoked on menu items alongside the internal keyboard navigation").signature("(( event: React.KeyboardEvent ) => void )")
16
+ };
17
+ const PopupMenuContentPropTypesSchema = PopupMenuContentPropTypes;
18
+ export {
19
+ PopupMenuContentPropTypes,
20
+ PopupMenuContentPropTypesSchema
21
+ };
22
+ //# sourceMappingURL=react-desc-prop-types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../../../src/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/react-desc-prop-types.ts"],
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { DSPropTypesSchema, GlobalAttributesT, ValidationMap, XstyledProps } from '@elliemae/ds-props-helpers';\nimport { PropTypes, globalAttributesPropTypes, xstyledPropTypes } from '@elliemae/ds-props-helpers';\nimport type React from 'react';\nimport type { DSGlobalHeaderT } from '../../../../../react-desc-prop-types.js';\n\n/*\n * Relocated here from DSGlobalHeaderT.PopupMenuContentProps, per the convention every other part in the\n * repo follows. Consumed by PopupMenuContent.tsx.\n *\n * This is the innermost of the three Popup* contracts and the one least likely to be a consumer's\n * business: it is what the PopupMenu wrapper hands to its own menu-content renderer. Every prop except\n * `options` is machinery the wrapper generated. `options` is the one consumer-authored value on it,\n * and it arrives already unwrapped from DSGlobalHeaderT.PopupMenuComponentProps \u2014 which is exactly why\n * having both `PopupMenuComponentProps` and `PopupMenuContentProps` visible side by side in the public\n * namespace was misleading: they look like a pair a developer chooses between, and they are not.\n *\n * IoC layers: the slot layer via `getOwnerPropsAwareOfPropsPassedToGlobalHeader` (fully wired \u2014 this part\n * passes it to the list, items, item buttons, labels and separators, each with its own explicit empty\n * hydrator), per-entry global attributes via `options` items, and the part-level global attribute /\n * xstyled layer below.\n *\n * KNOWN GAP \u2014 the part-level global attribute + xstyled layer is the one thing in this file that was an\n * addition rather than a transcription: the old DSGlobalHeaderT.PopupMenuContentProps did not extend\n * GlobalAttributesT at all, which made this the only out-of-the-box part missing that layer and left its\n * PropTypes unable to spread globalAttributesPropTypes coherently. Nothing forwards either to the root\n * list yet, so for this part both remain a statement of the intended contract rather than of behaviour.\n * Per-entry attributes on `options` items DO reach the DOM and are covered by the pillar tests.\n *\n * No slots of its own \u2014 see the AppPicker sibling file for why.\n */\nexport declare namespace PopupMenuContentT {\n export interface RequiredProps {\n /** The consumer-authored menu entries, unwrapped from componentProps by the PopupMenu wrapper. */\n options: DSGlobalHeaderT.PopupMenuContentItem[];\n /** Wrapper callback: applies the item's closeOnClick policy after a menu item is clicked. */\n onItemClick: () => void;\n /** Wrapper callback: closes the menu and returns focus to the trigger. */\n /** Which end of the menu this open lands on \u2014 see usePopupMenuContent. */\n openIntent: 'first' | 'last';\n /** Wrapper callback: the floating context's hide function. */\n setIsOpen: () => void;\n /*\n * The slot lookup table, and the only half of the slot IoC layer that may be drilled down \u2014 the\n * function-form hydrator is supplied per slot render site instead. See the AppPicker sibling for the\n * full reasoning and the getPartProps mechanics behind the name.\n */\n getOwnerPropsAwareOfPropsPassedToGlobalHeader: () => Partial<DSGlobalHeaderT.DefaultProps>;\n }\n\n /*\n * Intentionally empty, and intentionally still declared \u2014 \"this part has no default props, do not\n * expect them\". See the AppPicker sibling for the full reasoning.\n */\n export interface DefaultProps {}\n\n export interface OptionalProps {\n /*\n * Optional, matching the runtime: PopupMenuContent guards it (`if (popupOnKeyPress)`) and consumers\n * routinely omit it. It was declared required, which was simply wrong \u2014 the type claimed a guarantee\n * the code never relied on, and every consumer omitting it was type-lying to satisfy the compiler.\n */\n popupOnKeyPress?: (event: React.KeyboardEvent) => void;\n }\n\n export interface Props\n extends\n Partial<DefaultProps>,\n OptionalProps,\n Omit<\n GlobalAttributesT<HTMLUListElement>,\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n keyof RequiredProps | keyof DefaultProps | keyof XstyledProps\n >,\n XstyledProps,\n RequiredProps {}\n\n export interface InternalProps\n extends\n DefaultProps,\n OptionalProps,\n Omit<\n GlobalAttributesT<HTMLUListElement>,\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n keyof RequiredProps | keyof DefaultProps | keyof XstyledProps\n >,\n XstyledProps,\n RequiredProps {}\n}\n\nexport const PopupMenuContentPropTypes: DSPropTypesSchema<PopupMenuContentT.Props> = {\n ...globalAttributesPropTypes,\n ...xstyledPropTypes,\n options: PropTypes.array.description(\n 'Consumer-authored menu entries. Format: [{ type?, Icon?, label?, onClick?, Content?, ...globalAttributes }]',\n ).isRequired,\n onItemClick: PropTypes.func\n .description('Invoked after a menu item click so the wrapper can apply its closeOnClick policy')\n .signature('(() => void )').isRequired,\n openIntent: PropTypes.string.description('Which end of the menu this open lands on: \"first\" or \"last\"').isRequired,\n setIsOpen: PropTypes.func.description(\"The floating context's hide function\").signature('(() => void )').isRequired,\n getOwnerPropsAwareOfPropsPassedToGlobalHeader: PropTypes.func\n .description(\n 'Returns the props passed to DSGlobalHeader, so getPartProps can look up this slot consumer-supplied props. Must come from DSGlobalHeader; the function-form hydrator is supplied per slot render site instead',\n )\n .signature('(() => Partial<DSGlobalHeaderT.DefaultProps> )').isRequired,\n popupOnKeyPress: PropTypes.func\n .description('Consumer key handler, invoked on menu items alongside the internal keyboard navigation')\n .signature('(( event: React.KeyboardEvent ) => void )'),\n};\n\nexport const PopupMenuContentPropTypesSchema =\n PopupMenuContentPropTypes as unknown as ValidationMap<PopupMenuContentT.Props>;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACEvB,SAAS,WAAW,2BAA2B,wBAAwB;AAwFhE,MAAM,4BAAwE;AAAA,EACnF,GAAG;AAAA,EACH,GAAG;AAAA,EACH,SAAS,UAAU,MAAM;AAAA,IACvB;AAAA,EACF,EAAE;AAAA,EACF,aAAa,UAAU,KACpB,YAAY,kFAAkF,EAC9F,UAAU,eAAe,EAAE;AAAA,EAC9B,YAAY,UAAU,OAAO,YAAY,6DAA6D,EAAE;AAAA,EACxG,WAAW,UAAU,KAAK,YAAY,sCAAsC,EAAE,UAAU,eAAe,EAAE;AAAA,EACzG,+CAA+C,UAAU,KACtD;AAAA,IACC;AAAA,EACF,EACC,UAAU,gDAAgD,EAAE;AAAA,EAC/D,iBAAiB,UAAU,KACxB,YAAY,wFAAwF,EACpG,UAAU,2CAA2C;AAC1D;AAEO,MAAM,kCACX;",
6
+ "names": []
7
+ }
@@ -1,23 +1,31 @@
1
1
  import * as React from "react";
2
- import { useRef, useCallback, useEffect } from "react";
3
- const usePopupMenuContent = ({ setIsOpen }) => {
2
+ import { useRef, useCallback } from "react";
3
+ const usePopupMenuContent = ({ setIsOpen, openIntent, focusableItemsCount }) => {
4
4
  const menuRef = useRef(null);
5
5
  const allMenuItemsRef = useRef([]);
6
- const setRef = useCallback((ref) => {
7
- if (ref && !allMenuItemsRef.current.includes(ref)) {
8
- allMenuItemsRef.current.push(ref);
9
- }
10
- allMenuItemsRef.current.forEach((item, index) => {
11
- if (index === 0) {
12
- item?.setAttribute?.("tabindex", "0");
13
- } else {
14
- item?.setAttribute?.("tabindex", "-1");
6
+ const hasSeededFocusRef = useRef(false);
7
+ const setRef = useCallback(
8
+ (ref) => {
9
+ if (ref && !allMenuItemsRef.current.includes(ref)) {
10
+ allMenuItemsRef.current.push(ref);
11
+ }
12
+ allMenuItemsRef.current.forEach((item, index) => {
13
+ if (index === 0) {
14
+ item?.setAttribute?.("tabindex", "0");
15
+ } else {
16
+ item?.setAttribute?.("tabindex", "-1");
17
+ }
18
+ });
19
+ if (!ref || hasSeededFocusRef.current) return;
20
+ const hasReachedSeedTarget = openIntent === "last" ? allMenuItemsRef.current.length === focusableItemsCount : allMenuItemsRef.current[0] === ref;
21
+ if (hasReachedSeedTarget) {
22
+ hasSeededFocusRef.current = true;
23
+ const target = openIntent === "last" ? allMenuItemsRef.current[focusableItemsCount - 1] : ref;
24
+ target?.focus();
15
25
  }
16
- });
17
- }, []);
18
- useEffect(() => {
19
- setTimeout(() => allMenuItemsRef.current?.[0]?.focus(), 0);
20
- }, []);
26
+ },
27
+ [openIntent, focusableItemsCount]
28
+ );
21
29
  const keyboardNavigation = useCallback(
22
30
  (e) => {
23
31
  if (e.code === "Tab") {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../../../src/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/usePopupMenuContent.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useRef, useCallback, useEffect } from 'react';\n\ninterface UsePopupMenuContentT {\n setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\nexport const usePopupMenuContent = ({ setIsOpen }: UsePopupMenuContentT) => {\n const menuRef = useRef<HTMLUListElement>(null);\n const allMenuItemsRef = useRef<HTMLButtonElement[]>([]);\n\n const setRef = useCallback((ref: HTMLButtonElement) => {\n if (ref && !allMenuItemsRef.current.includes(ref)) {\n allMenuItemsRef.current.push(ref);\n }\n\n allMenuItemsRef.current.forEach((item, index) => {\n if (index === 0) {\n item?.setAttribute?.('tabindex', '0');\n } else {\n item?.setAttribute?.('tabindex', '-1');\n }\n });\n }, []);\n\n useEffect(() => {\n setTimeout(() => allMenuItemsRef.current?.[0]?.focus(), 0);\n }, []);\n\n const keyboardNavigation = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.code === 'Tab') {\n setIsOpen(false);\n } else {\n const currentIndex = allMenuItemsRef.current.indexOf(e.target as HTMLButtonElement);\n const allRefsLength = allMenuItemsRef.current.length;\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (currentIndex < allRefsLength - 1) {\n allMenuItemsRef.current[currentIndex + 1]?.focus?.();\n } else {\n allMenuItemsRef.current[0]?.focus?.();\n }\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n if (currentIndex === 0) {\n allMenuItemsRef.current[allRefsLength - 1]?.focus?.();\n } else {\n allMenuItemsRef.current[currentIndex - 1]?.focus?.();\n }\n }\n }\n },\n [setIsOpen],\n );\n\n return {\n menuRef,\n setRef,\n keyboardNavigation,\n };\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,QAAQ,aAAa,iBAAiB;AAMxC,MAAM,sBAAsB,CAAC,EAAE,UAAU,MAA4B;AAC1E,QAAM,UAAU,OAAyB,IAAI;AAC7C,QAAM,kBAAkB,OAA4B,CAAC,CAAC;AAEtD,QAAM,SAAS,YAAY,CAAC,QAA2B;AACrD,QAAI,OAAO,CAAC,gBAAgB,QAAQ,SAAS,GAAG,GAAG;AACjD,sBAAgB,QAAQ,KAAK,GAAG;AAAA,IAClC;AAEA,oBAAgB,QAAQ,QAAQ,CAAC,MAAM,UAAU;AAC/C,UAAI,UAAU,GAAG;AACf,cAAM,eAAe,YAAY,GAAG;AAAA,MACtC,OAAO;AACL,cAAM,eAAe,YAAY,IAAI;AAAA,MACvC;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,eAAW,MAAM,gBAAgB,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC;AAAA,EAC3D,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAqB;AAAA,IACzB,CAAC,MAA2B;AAC1B,UAAI,EAAE,SAAS,OAAO;AACpB,kBAAU,KAAK;AAAA,MACjB,OAAO;AACL,cAAM,eAAe,gBAAgB,QAAQ,QAAQ,EAAE,MAA2B;AAClF,cAAM,gBAAgB,gBAAgB,QAAQ;AAC9C,YAAI,EAAE,QAAQ,aAAa;AACzB,YAAE,eAAe;AACjB,cAAI,eAAe,gBAAgB,GAAG;AACpC,4BAAgB,QAAQ,eAAe,CAAC,GAAG,QAAQ;AAAA,UACrD,OAAO;AACL,4BAAgB,QAAQ,CAAC,GAAG,QAAQ;AAAA,UACtC;AAAA,QACF;AACA,YAAI,EAAE,QAAQ,WAAW;AACvB,YAAE,eAAe;AACjB,cAAI,iBAAiB,GAAG;AACtB,4BAAgB,QAAQ,gBAAgB,CAAC,GAAG,QAAQ;AAAA,UACtD,OAAO;AACL,4BAAgB,QAAQ,eAAe,CAAC,GAAG,QAAQ;AAAA,UACrD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useRef, useCallback } from 'react';\n\ninterface UsePopupMenuContentT {\n setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n /**\n * Which end of the menu this open should land on. Mirrors DSAppPicker's open-intent mechanism, scoped\n * to this part: the trigger records WHICH key opened the menu and the seeding below reads it \u2014 ArrowUp\n * lands on the last item, everything else on the first.\n */\n openIntent: 'first' | 'last';\n /** How many focusable items the menu mounts. Separators are not focusable and are excluded. */\n focusableItemsCount: number;\n}\n\nexport const usePopupMenuContent = ({ setIsOpen, openIntent, focusableItemsCount }: UsePopupMenuContentT) => {\n const menuRef = useRef<HTMLUListElement>(null);\n const allMenuItemsRef = useRef<HTMLButtonElement[]>([]);\n // Seeded once per mount of the menu content. A ref rather than state because nothing renders from it.\n const hasSeededFocusRef = useRef(false);\n\n const setRef = useCallback(\n (ref: HTMLButtonElement) => {\n if (ref && !allMenuItemsRef.current.includes(ref)) {\n allMenuItemsRef.current.push(ref);\n }\n\n allMenuItemsRef.current.forEach((item, index) => {\n if (index === 0) {\n item?.setAttribute?.('tabindex', '0');\n } else {\n item?.setAttribute?.('tabindex', '-1');\n }\n });\n\n /*\n * Initial focus, seeded from this ref callback \u2014 the correct place for it, because the callback is\n * guaranteed to run once the node exists. Do not move this into an effect or wrap it in a timer; per\n * antipattern_focus_management.md there is nothing left to wait for, and both reintroduce a race this\n * has no need for.\n *\n * `first` can seed the moment item 0 attaches. `last` cannot: the ref callbacks fire one per item and\n * nothing else here knows when the set is complete, which is why the count is passed in rather than\n * inferred. Comparing against it keeps the decision inside the callback instead of deferring it.\n *\n * Seeds once per mount of the menu content, which is why the guard ref exists.\n */\n if (!ref || hasSeededFocusRef.current) return;\n\n const hasReachedSeedTarget =\n openIntent === 'last'\n ? allMenuItemsRef.current.length === focusableItemsCount\n : allMenuItemsRef.current[0] === ref;\n\n if (hasReachedSeedTarget) {\n hasSeededFocusRef.current = true;\n const target = openIntent === 'last' ? allMenuItemsRef.current[focusableItemsCount - 1] : ref;\n target?.focus();\n }\n },\n [openIntent, focusableItemsCount],\n );\n\n const keyboardNavigation = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.code === 'Tab') {\n setIsOpen(false);\n } else {\n const currentIndex = allMenuItemsRef.current.indexOf(e.target as HTMLButtonElement);\n const allRefsLength = allMenuItemsRef.current.length;\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (currentIndex < allRefsLength - 1) {\n allMenuItemsRef.current[currentIndex + 1]?.focus?.();\n } else {\n allMenuItemsRef.current[0]?.focus?.();\n }\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n if (currentIndex === 0) {\n allMenuItemsRef.current[allRefsLength - 1]?.focus?.();\n } else {\n allMenuItemsRef.current[currentIndex - 1]?.focus?.();\n }\n }\n }\n },\n [setIsOpen],\n );\n\n return {\n menuRef,\n setRef,\n keyboardNavigation,\n };\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,QAAQ,mBAAmB;AAc7B,MAAM,sBAAsB,CAAC,EAAE,WAAW,YAAY,oBAAoB,MAA4B;AAC3G,QAAM,UAAU,OAAyB,IAAI;AAC7C,QAAM,kBAAkB,OAA4B,CAAC,CAAC;AAEtD,QAAM,oBAAoB,OAAO,KAAK;AAEtC,QAAM,SAAS;AAAA,IACb,CAAC,QAA2B;AAC1B,UAAI,OAAO,CAAC,gBAAgB,QAAQ,SAAS,GAAG,GAAG;AACjD,wBAAgB,QAAQ,KAAK,GAAG;AAAA,MAClC;AAEA,sBAAgB,QAAQ,QAAQ,CAAC,MAAM,UAAU;AAC/C,YAAI,UAAU,GAAG;AACf,gBAAM,eAAe,YAAY,GAAG;AAAA,QACtC,OAAO;AACL,gBAAM,eAAe,YAAY,IAAI;AAAA,QACvC;AAAA,MACF,CAAC;AAcD,UAAI,CAAC,OAAO,kBAAkB,QAAS;AAEvC,YAAM,uBACJ,eAAe,SACX,gBAAgB,QAAQ,WAAW,sBACnC,gBAAgB,QAAQ,CAAC,MAAM;AAErC,UAAI,sBAAsB;AACxB,0BAAkB,UAAU;AAC5B,cAAM,SAAS,eAAe,SAAS,gBAAgB,QAAQ,sBAAsB,CAAC,IAAI;AAC1F,gBAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AAAA,IACA,CAAC,YAAY,mBAAmB;AAAA,EAClC;AAEA,QAAM,qBAAqB;AAAA,IACzB,CAAC,MAA2B;AAC1B,UAAI,EAAE,SAAS,OAAO;AACpB,kBAAU,KAAK;AAAA,MACjB,OAAO;AACL,cAAM,eAAe,gBAAgB,QAAQ,QAAQ,EAAE,MAA2B;AAClF,cAAM,gBAAgB,gBAAgB,QAAQ;AAC9C,YAAI,EAAE,QAAQ,aAAa;AACzB,YAAE,eAAe;AACjB,cAAI,eAAe,gBAAgB,GAAG;AACpC,4BAAgB,QAAQ,eAAe,CAAC,GAAG,QAAQ;AAAA,UACrD,OAAO;AACL,4BAAgB,QAAQ,CAAC,GAAG,QAAQ;AAAA,UACtC;AAAA,QACF;AACA,YAAI,EAAE,QAAQ,WAAW;AACvB,YAAE,eAAe;AACjB,cAAI,iBAAiB,GAAG;AACtB,4BAAgB,QAAQ,gBAAgB,CAAC,GAAG,QAAQ;AAAA,UACtD,OAAO;AACL,4BAAgB,QAAQ,eAAe,CAAC,GAAG,QAAQ;AAAA,UACrD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,24 @@
1
+ import * as React from "react";
2
+ import { PropTypes, globalAttributesPropTypes, xstyledPropTypes } from "@elliemae/ds-props-helpers";
3
+ const PopupMenuPropTypes = {
4
+ ...globalAttributesPropTypes,
5
+ ...xstyledPropTypes,
6
+ componentProps: PropTypes.object.description(
7
+ "The consumer-authored popup menu configuration: options, isOpen, closeOnClick and the key handlers"
8
+ ).isRequired,
9
+ getOwnerPropsAwareOfPropsPassedToGlobalHeader: PropTypes.func.description(
10
+ "Returns the props passed to DSGlobalHeader, so getPartProps can look up this slot consumer-supplied props. Must come from DSGlobalHeader; the function-form hydrator is supplied per slot render site instead"
11
+ ).signature("(() => Partial<DSGlobalHeaderT.DefaultProps> )").isRequired,
12
+ setRef: PropTypes.func.description("Registers the trigger node with the toolbar focus management for arrow-key navigation").signature("(( ref: HTMLElement ) => void )").isRequired,
13
+ Icon: PropTypes.func.description("Icon rendered inside the trigger button"),
14
+ onClick: PropTypes.func.description("Consumer click handler for the trigger, invoked alongside the internal open/close toggle").signature("(( event: React.MouseEvent ) => void )"),
15
+ title: PropTypes.string.description(
16
+ "Receives the toolbar item label; printed as the HTML title attribute on the trigger"
17
+ )
18
+ };
19
+ const PopupMenuPropTypesSchema = PopupMenuPropTypes;
20
+ export {
21
+ PopupMenuPropTypes,
22
+ PopupMenuPropTypesSchema
23
+ };
24
+ //# sourceMappingURL=react-desc-prop-types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../../../scripts/build/transpile/react-shim.js", "../../../../../../src/parts/Toolbar/outOfTheBox/PopupMenu/react-desc-prop-types.ts"],
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { DSPropTypesSchema, GlobalAttributesT, ValidationMap, XstyledProps } from '@elliemae/ds-props-helpers';\nimport { PropTypes, globalAttributesPropTypes, xstyledPropTypes } from '@elliemae/ds-props-helpers';\nimport type { SvgIconT } from '@elliemae/ds-icons';\nimport type React from 'react';\nimport type { DSGlobalHeaderT } from '../../../../react-desc-prop-types.js';\n\n/*\n * Relocated here from DSGlobalHeaderT.PopupProps, per the convention every other part in the repo\n * follows. Consumed by PopupMenu.tsx.\n *\n * This namespace describes what DSGlobalHeader passes DOWN to its own out-of-the-box Popup Menu\n * wrapper. It is NOT the shape an application developer authors \u2014 that is\n * DSGlobalHeaderT.PopupMenuItem (the toolbar config entry) and, inside it,\n * DSGlobalHeaderT.PopupMenuComponentProps. `setRef` and\n * `getOwnerPropsAwareOfPropsPassedToGlobalHeader` are generated by the widget and the developer is not\n * meant to know about them.\n *\n * The old name is worth losing on the way: `PopupProps` sat a word away from `PopupMenuItem`,\n * `PopupMenuComponentProps` and `PopupMenuContentProps` in the same namespace \u2014 the first two of which\n * ARE consumer-authored, while the third was internal and has been relocated to menuContent/ alongside\n * this one. `PopupMenuT.Props`, scoped to this directory, cannot be mistaken for any of them.\n *\n * All three IoC layers present: item-level global attributes onto the trigger, the slot layer via\n * `getOwnerPropsAwareOfPropsPassedToGlobalHeader`, and `componentProps` for the menu's own contract.\n *\n * No slots of its own \u2014 see the AppPicker sibling file for why (published slot surface stays under the\n * parent's name).\n *\n * KNOWN GAP \u2014 xstyled props are declared and not forwarded, as in every sibling part. See the AppPicker\n * file for the full statement; this part is additionally the one with no styled root to forward them to,\n * because PopupMenu.tsx's outermost element is a bare <div>.\n */\nexport declare namespace PopupMenuT {\n export interface RequiredProps {\n /** The consumer-authored configuration object for this toolbar item. */\n componentProps: DSGlobalHeaderT.PopupMenuComponentProps;\n /*\n * The slot lookup table, and the only half of the slot IoC layer that may be drilled down \u2014 the\n * function-form hydrator is supplied per slot render site instead. See the AppPicker sibling for the\n * full reasoning and the getPartProps mechanics behind the name.\n */\n getOwnerPropsAwareOfPropsPassedToGlobalHeader: () => Partial<DSGlobalHeaderT.DefaultProps>;\n /** Focus-management registration, supplied by useGlobalHeaderToolbar for arrow-key navigation. */\n setRef: (ref: HTMLElement) => void;\n }\n\n /*\n * Intentionally empty, and intentionally still declared \u2014 \"this part has no default props, do not\n * expect them\". See the AppPicker sibling for the full reasoning.\n */\n export interface DefaultProps {}\n\n export interface OptionalProps {\n Icon?: React.ComponentType<SvgIconT.Props>;\n onClick?: (event: React.MouseEvent) => void;\n /*\n * Carries the toolbar item's `label`: GlobalHeaderToolbar renders <PopupMenu title={label} .../>.\n * Faithful to the current declaration, including its standing note that landing this in the HTML\n * `title` attribute was probably not intended but is kept to avoid a breaking change.\n */\n title?: string;\n }\n\n export interface Props\n extends\n Partial<DefaultProps>,\n OptionalProps,\n Omit<\n GlobalAttributesT<HTMLButtonElement>,\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n keyof RequiredProps | keyof DefaultProps | keyof OptionalProps | keyof XstyledProps\n >,\n XstyledProps,\n RequiredProps {}\n\n export interface InternalProps\n extends\n DefaultProps,\n OptionalProps,\n Omit<\n GlobalAttributesT<HTMLButtonElement>,\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n keyof RequiredProps | keyof DefaultProps | keyof OptionalProps | keyof XstyledProps\n >,\n XstyledProps,\n RequiredProps {}\n}\n\nexport const PopupMenuPropTypes: DSPropTypesSchema<PopupMenuT.Props> = {\n ...globalAttributesPropTypes,\n ...xstyledPropTypes,\n componentProps: PropTypes.object.description(\n 'The consumer-authored popup menu configuration: options, isOpen, closeOnClick and the key handlers',\n ).isRequired,\n getOwnerPropsAwareOfPropsPassedToGlobalHeader: PropTypes.func\n .description(\n 'Returns the props passed to DSGlobalHeader, so getPartProps can look up this slot consumer-supplied props. Must come from DSGlobalHeader; the function-form hydrator is supplied per slot render site instead',\n )\n .signature('(() => Partial<DSGlobalHeaderT.DefaultProps> )').isRequired,\n setRef: PropTypes.func\n .description('Registers the trigger node with the toolbar focus management for arrow-key navigation')\n .signature('(( ref: HTMLElement ) => void )').isRequired,\n Icon: PropTypes.func.description('Icon rendered inside the trigger button'),\n onClick: PropTypes.func\n .description('Consumer click handler for the trigger, invoked alongside the internal open/close toggle')\n .signature('(( event: React.MouseEvent ) => void )'),\n title: PropTypes.string.description(\n 'Receives the toolbar item label; printed as the HTML title attribute on the trigger',\n ),\n};\n\nexport const PopupMenuPropTypesSchema = PopupMenuPropTypes as unknown as ValidationMap<PopupMenuT.Props>;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACEvB,SAAS,WAAW,2BAA2B,wBAAwB;AAuFhE,MAAM,qBAA0D;AAAA,EACrE,GAAG;AAAA,EACH,GAAG;AAAA,EACH,gBAAgB,UAAU,OAAO;AAAA,IAC/B;AAAA,EACF,EAAE;AAAA,EACF,+CAA+C,UAAU,KACtD;AAAA,IACC;AAAA,EACF,EACC,UAAU,gDAAgD,EAAE;AAAA,EAC/D,QAAQ,UAAU,KACf,YAAY,uFAAuF,EACnG,UAAU,iCAAiC,EAAE;AAAA,EAChD,MAAM,UAAU,KAAK,YAAY,yCAAyC;AAAA,EAC1E,SAAS,UAAU,KAChB,YAAY,0FAA0F,EACtG,UAAU,wCAAwC;AAAA,EACrD,OAAO,UAAU,OAAO;AAAA,IACtB;AAAA,EACF;AACF;AAEO,MAAM,2BAA2B;",
6
+ "names": []
7
+ }