@elliemae/ds-global-header 3.60.0-next.13 → 3.60.0-next.15
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.
- package/dist/cjs/hooks/useOnClickOutside.js +60 -0
- package/dist/cjs/hooks/useOnClickOutside.js.map +7 -0
- package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/PopupMenu.js +50 -30
- package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/PopupMenu.js.map +2 -2
- package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/usePopupMenuContent.js +3 -1
- package/dist/cjs/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/usePopupMenuContent.js.map +2 -2
- package/dist/esm/hooks/useOnClickOutside.js +30 -0
- package/dist/esm/hooks/useOnClickOutside.js.map +7 -0
- package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/PopupMenu.js +52 -32
- package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/PopupMenu.js.map +2 -2
- package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/usePopupMenuContent.js +3 -1
- package/dist/esm/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/usePopupMenuContent.js.map +2 -2
- package/dist/types/hooks/useOnClickOutside.d.ts +1 -0
- package/package.json +12 -13
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var useOnClickOutside_exports = {};
|
|
30
|
+
__export(useOnClickOutside_exports, {
|
|
31
|
+
useOnClickOutside: () => useOnClickOutside
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(useOnClickOutside_exports);
|
|
34
|
+
var React = __toESM(require("react"));
|
|
35
|
+
var import_react = __toESM(require("react"));
|
|
36
|
+
function useOnClickOutside(ref, cb) {
|
|
37
|
+
const cbRef = import_react.default.useRef(cb);
|
|
38
|
+
(0, import_react.useEffect)(() => {
|
|
39
|
+
cbRef.current = cb;
|
|
40
|
+
}, [cb]);
|
|
41
|
+
(0, import_react.useEffect)(() => {
|
|
42
|
+
if (!ref) {
|
|
43
|
+
return () => {
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const listener = (event) => {
|
|
47
|
+
const target = event.target;
|
|
48
|
+
if (!target) return;
|
|
49
|
+
if (ref.contains(target)) return;
|
|
50
|
+
cbRef.current(event);
|
|
51
|
+
};
|
|
52
|
+
document.addEventListener("mousedown", listener, true);
|
|
53
|
+
document.addEventListener("touchstart", listener, true);
|
|
54
|
+
return () => {
|
|
55
|
+
document.removeEventListener("mousedown", listener, true);
|
|
56
|
+
document.removeEventListener("touchstart", listener, true);
|
|
57
|
+
};
|
|
58
|
+
}, [ref]);
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=useOnClickOutside.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/useOnClickOutside.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["import React, { useEffect } from 'react';\n\nexport function useOnClickOutside<T extends Node>(ref: T | null, cb: (event: Event) => void): void {\n const cbRef = React.useRef(cb);\n\n useEffect(() => {\n cbRef.current = cb;\n }, [cb]);\n\n useEffect(() => {\n if (!ref) {\n return () => {};\n }\n\n const listener = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n\n if (ref.contains(target)) return;\n\n cbRef.current(event);\n };\n\n document.addEventListener('mousedown', listener, true);\n document.addEventListener('touchstart', listener, true);\n\n return () => {\n document.removeEventListener('mousedown', listener, true);\n document.removeEventListener('touchstart', listener, true);\n };\n }, [ref]);\n}\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAiC;AAE1B,SAAS,kBAAkC,KAAe,IAAkC;AACjG,QAAM,QAAQ,aAAAA,QAAM,OAAO,EAAE;AAE7B,8BAAU,MAAM;AACd,UAAM,UAAU;AAAA,EAClB,GAAG,CAAC,EAAE,CAAC;AAEP,8BAAU,MAAM;AACd,QAAI,CAAC,KAAK;AACR,aAAO,MAAM;AAAA,MAAC;AAAA,IAChB;AAEA,UAAM,WAAW,CAAC,UAAmC;AACnD,YAAM,SAAS,MAAM;AACrB,UAAI,CAAC,OAAQ;AAEb,UAAI,IAAI,SAAS,MAAM,EAAG;AAE1B,YAAM,QAAQ,KAAK;AAAA,IACrB;AAEA,aAAS,iBAAiB,aAAa,UAAU,IAAI;AACrD,aAAS,iBAAiB,cAAc,UAAU,IAAI;AAEtD,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,UAAU,IAAI;AACxD,eAAS,oBAAoB,cAAc,UAAU,IAAI;AAAA,IAC3D;AAAA,EACF,GAAG,CAAC,GAAG,CAAC;AACV;",
|
|
6
|
+
"names": ["React"]
|
|
7
|
+
}
|
|
@@ -33,12 +33,13 @@ __export(PopupMenu_exports, {
|
|
|
33
33
|
module.exports = __toCommonJS(PopupMenu_exports);
|
|
34
34
|
var React = __toESM(require("react"));
|
|
35
35
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
36
|
-
var
|
|
36
|
+
var import_ds_floating_context = require("@elliemae/ds-floating-context");
|
|
37
37
|
var import_ds_props_helpers = require("@elliemae/ds-props-helpers");
|
|
38
38
|
var import_react = require("react");
|
|
39
39
|
var import_exported_related = require("../../../../exported-related/index.js");
|
|
40
40
|
var import_styles = require("../../../styles.js");
|
|
41
41
|
var import_PopupMenuContent = require("./menuContent/PopupMenuContent.js");
|
|
42
|
+
var import_useOnClickOutside = require("../../../../hooks/useOnClickOutside.js");
|
|
42
43
|
const PopupMenu = ({
|
|
43
44
|
Icon,
|
|
44
45
|
onClick,
|
|
@@ -46,8 +47,12 @@ const PopupMenu = ({
|
|
|
46
47
|
componentProps,
|
|
47
48
|
...otherProps
|
|
48
49
|
}) => {
|
|
49
|
-
const
|
|
50
|
-
|
|
50
|
+
const { arrowStyles, floatingStyles, isOpen, refs, context, showTooltip, hideTooltip } = (0, import_ds_floating_context.useFloatingContext)({
|
|
51
|
+
externallyControlledIsOpen: componentProps.isOpen,
|
|
52
|
+
placement: "bottom",
|
|
53
|
+
withoutAnimation: true,
|
|
54
|
+
withoutPortal: true
|
|
55
|
+
});
|
|
51
56
|
const {
|
|
52
57
|
onClickOutside = () => null,
|
|
53
58
|
onKeyPress,
|
|
@@ -56,39 +61,52 @@ const PopupMenu = ({
|
|
|
56
61
|
options,
|
|
57
62
|
closeOnClick
|
|
58
63
|
} = componentProps;
|
|
64
|
+
const boundaryRef = (0, import_react.useRef)(null);
|
|
59
65
|
const handleOnKeyDown = (0, import_react.useCallback)(
|
|
60
66
|
(e) => {
|
|
61
67
|
if (e.code === "ArrowDown") {
|
|
62
|
-
|
|
68
|
+
showTooltip();
|
|
63
69
|
}
|
|
64
70
|
if (onKeyPress) onKeyPress(e);
|
|
65
71
|
},
|
|
66
|
-
[onKeyPress]
|
|
72
|
+
[onKeyPress, showTooltip]
|
|
67
73
|
);
|
|
68
74
|
const handleOnClose = (0, import_react.useCallback)(() => {
|
|
69
75
|
if (userIsOpen === void 0) {
|
|
70
|
-
|
|
76
|
+
hideTooltip();
|
|
71
77
|
}
|
|
72
|
-
|
|
73
|
-
}, [
|
|
78
|
+
refs.reference?.focus();
|
|
79
|
+
}, [hideTooltip, refs.reference, userIsOpen]);
|
|
74
80
|
const handleTriggerOnClick = (0, import_react.useCallback)(
|
|
75
81
|
(e) => {
|
|
76
|
-
if (userIsOpen === void 0)
|
|
82
|
+
if (userIsOpen === void 0) showTooltip();
|
|
77
83
|
if (onClick) onClick(e);
|
|
78
84
|
},
|
|
79
|
-
[onClick, userIsOpen]
|
|
85
|
+
[onClick, userIsOpen, showTooltip]
|
|
80
86
|
);
|
|
81
87
|
const handleItemClick = (0, import_react.useCallback)(() => {
|
|
82
88
|
if (closeOnClick && userIsOpen === void 0) handleOnClose();
|
|
83
89
|
}, [closeOnClick, handleOnClose, userIsOpen]);
|
|
90
|
+
const handleOutside = (0, import_react.useCallback)(
|
|
91
|
+
(event) => {
|
|
92
|
+
onClickOutside(event);
|
|
93
|
+
const actuallyOpen = userIsOpen ?? isOpen;
|
|
94
|
+
if (!actuallyOpen) return;
|
|
95
|
+
if (userIsOpen === void 0) {
|
|
96
|
+
handleOnClose();
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
[handleOnClose, isOpen, onClickOutside, userIsOpen]
|
|
100
|
+
);
|
|
101
|
+
(0, import_useOnClickOutside.useOnClickOutside)(userIsOpen ?? isOpen ? boundaryRef.current : null, handleOutside);
|
|
84
102
|
const handleRefs = (0, import_react.useCallback)(
|
|
85
103
|
(ref) => {
|
|
86
104
|
setRef(ref);
|
|
87
|
-
|
|
105
|
+
refs.setReference(ref);
|
|
88
106
|
},
|
|
89
|
-
[setRef]
|
|
107
|
+
[refs, setRef]
|
|
90
108
|
);
|
|
91
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
109
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ref: boundaryRef, children: [
|
|
92
110
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
93
111
|
import_styles.StyledButton,
|
|
94
112
|
{
|
|
@@ -103,24 +121,26 @@ const PopupMenu = ({
|
|
|
103
121
|
children: Icon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { size: "m" })
|
|
104
122
|
}
|
|
105
123
|
),
|
|
106
|
-
|
|
107
|
-
|
|
124
|
+
refs.reference ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
125
|
+
import_ds_floating_context.FloatingWrapper,
|
|
108
126
|
{
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
127
|
+
innerRef: refs.setFloating,
|
|
128
|
+
isOpen: userIsOpen ?? isOpen,
|
|
129
|
+
floatingStyles,
|
|
130
|
+
context,
|
|
131
|
+
children: [
|
|
132
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
133
|
+
import_PopupMenuContent.PopupMenuContent,
|
|
134
|
+
{
|
|
135
|
+
options,
|
|
136
|
+
onItemClick: handleItemClick,
|
|
137
|
+
onClose: handleOnClose,
|
|
138
|
+
setIsOpen: hideTooltip,
|
|
139
|
+
popupOnKeyPress
|
|
140
|
+
}
|
|
141
|
+
),
|
|
142
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ds_floating_context.PopoverArrow, { ...arrowStyles })
|
|
143
|
+
]
|
|
124
144
|
}
|
|
125
145
|
) : null
|
|
126
146
|
] });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/parts/Toolbar/outOfTheBox/PopupMenu/PopupMenu.tsx", "../../../../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;
|
|
4
|
+
"sourcesContent": ["import { useFloatingContext, PopoverArrow, FloatingWrapper } from '@elliemae/ds-floating-context';\nimport { useGetGlobalAttributes } from '@elliemae/ds-props-helpers';\nimport React, { useCallback, useRef } from 'react';\nimport { DSGlobalHeaderDatatestid } from '../../../../exported-related/index.js';\nimport type { DSGlobalHeaderT } from '../../../../react-desc-prop-types.js';\nimport { StyledButton } from '../../../styles.js';\nimport { PopupMenuContent } from './menuContent/PopupMenuContent.js';\nimport { useOnClickOutside } from '../../../../hooks/useOnClickOutside.js';\nexport const PopupMenu = ({\n Icon,\n onClick,\n setRef,\n componentProps,\n ...otherProps\n}: DSGlobalHeaderT.PopupProps): JSX.Element => {\n const { arrowStyles, floatingStyles, isOpen, refs, context, showTooltip, hideTooltip } = useFloatingContext({\n externallyControlledIsOpen: componentProps.isOpen,\n placement: 'bottom',\n withoutAnimation: true,\n withoutPortal: true,\n });\n\n const {\n onClickOutside = () => null,\n onKeyPress,\n popupOnKeyPress,\n isOpen: userIsOpen,\n options,\n closeOnClick,\n } = componentProps;\n\n /**\n * We want \"outside\" to mean: outside BOTH the trigger and the floating panel.\n * So wrap them in a single DOM node and use that as the boundary.\n */\n const boundaryRef = useRef<HTMLDivElement | null>(null);\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();\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 // Close on outside click, but:\n // - always notify consumer via onClickOutside\n // - only actually close when uncontrolled (userIsOpen === undefined)\n // - only run while open\n const handleOutside = useCallback(\n (event: Event) => {\n onClickOutside(event as MouseEvent | TouchEvent);\n\n const actuallyOpen = userIsOpen ?? isOpen;\n if (!actuallyOpen) return;\n\n if (userIsOpen === undefined) {\n handleOnClose();\n }\n },\n [handleOnClose, isOpen, onClickOutside, userIsOpen],\n );\n\n // If you only want to listen when open, pass `null` when closed\n useOnClickOutside((userIsOpen ?? isOpen) ? boundaryRef.current : null, handleOutside);\n\n const handleRefs = useCallback(\n (ref: HTMLButtonElement) => {\n setRef(ref);\n refs.setReference(ref);\n },\n [refs, setRef],\n );\n return (\n <div ref={boundaryRef}>\n <StyledButton\n onClick={handleTriggerOnClick}\n onKeyDown={handleOnKeyDown}\n innerRef={handleRefs}\n data-testid={DSGlobalHeaderDatatestid.MENUBAR.ITEM_BUTTON}\n aria-haspopup\n aria-expanded={userIsOpen ?? isOpen}\n {...useGetGlobalAttributes(otherProps)}\n type=\"button\"\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 />\n <PopoverArrow {...arrowStyles} />\n </FloatingWrapper>\n ) : null}\n </div>\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;AD0GN;AA1GjB,iCAAkE;AAClE,8BAAuC;AACvC,mBAA2C;AAC3C,8BAAyC;AAEzC,oBAA6B;AAC7B,8BAAiC;AACjC,+BAAkC;AAC3B,MAAM,YAAY,CAAC;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA+C;AAC7C,QAAM,EAAE,aAAa,gBAAgB,QAAQ,MAAM,SAAS,aAAa,YAAY,QAAI,+CAAmB;AAAA,IAC1G,4BAA4B,eAAe;AAAA,IAC3C,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,eAAe;AAAA,EACjB,CAAC;AAED,QAAM;AAAA,IACJ,iBAAiB,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,EACF,IAAI;AAMJ,QAAM,kBAAc,qBAA8B,IAAI;AAEtD,QAAM,sBAAkB;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,oBAAgB,0BAAY,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,2BAAuB;AAAA,IAC3B,CAAC,MAAwB;AACvB,UAAI,eAAe,OAAW,aAAY;AAC1C,UAAI,QAAS,SAAQ,CAAC;AAAA,IACxB;AAAA,IACA,CAAC,SAAS,YAAY,WAAW;AAAA,EACnC;AAEA,QAAM,sBAAkB,0BAAY,MAAM;AACxC,QAAI,gBAAgB,eAAe,OAAW,eAAc;AAAA,EAC9D,GAAG,CAAC,cAAc,eAAe,UAAU,CAAC;AAM5C,QAAM,oBAAgB;AAAA,IACpB,CAAC,UAAiB;AAChB,qBAAe,KAAgC;AAE/C,YAAM,eAAe,cAAc;AACnC,UAAI,CAAC,aAAc;AAEnB,UAAI,eAAe,QAAW;AAC5B,sBAAc;AAAA,MAChB;AAAA,IACF;AAAA,IACA,CAAC,eAAe,QAAQ,gBAAgB,UAAU;AAAA,EACpD;AAGA,kDAAmB,cAAc,SAAU,YAAY,UAAU,MAAM,aAAa;AAEpF,QAAM,iBAAa;AAAA,IACjB,CAAC,QAA2B;AAC1B,aAAO,GAAG;AACV,WAAK,aAAa,GAAG;AAAA,IACvB;AAAA,IACA,CAAC,MAAM,MAAM;AAAA,EACf;AACA,SACE,6CAAC,SAAI,KAAK,aACR;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,QACV,eAAa,iDAAyB,QAAQ;AAAA,QAC9C,iBAAa;AAAA,QACb,iBAAe,cAAc;AAAA,QAC5B,OAAG,gDAAuB,UAAU;AAAA,QACrC,MAAK;AAAA,QAEJ,kBAAQ,4CAAC,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;AAAA,UACF;AAAA,UACA,4CAAC,2CAAc,GAAG,aAAa;AAAA;AAAA;AAAA,IACjC,IACE;AAAA,KACN;AAEJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -49,7 +49,7 @@ const usePopupMenuContent = ({ setIsOpen }) => {
|
|
|
49
49
|
});
|
|
50
50
|
}, []);
|
|
51
51
|
(0, import_react.useEffect)(() => {
|
|
52
|
-
allMenuItemsRef.current?.[0]?.focus();
|
|
52
|
+
setTimeout(() => allMenuItemsRef.current?.[0]?.focus(), 0);
|
|
53
53
|
}, []);
|
|
54
54
|
const keyboardNavigation = (0, import_react.useCallback)(
|
|
55
55
|
(e) => {
|
|
@@ -59,6 +59,7 @@ const usePopupMenuContent = ({ setIsOpen }) => {
|
|
|
59
59
|
const currentIndex = allMenuItemsRef.current.indexOf(e.target);
|
|
60
60
|
const allRefsLength = allMenuItemsRef.current.length;
|
|
61
61
|
if (e.key === "ArrowDown") {
|
|
62
|
+
e.preventDefault();
|
|
62
63
|
if (currentIndex < allRefsLength - 1) {
|
|
63
64
|
allMenuItemsRef.current[currentIndex + 1]?.focus?.();
|
|
64
65
|
} else {
|
|
@@ -66,6 +67,7 @@ const usePopupMenuContent = ({ setIsOpen }) => {
|
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
69
|
if (e.key === "ArrowUp") {
|
|
70
|
+
e.preventDefault();
|
|
69
71
|
if (currentIndex === 0) {
|
|
70
72
|
allMenuItemsRef.current[allRefsLength - 1]?.focus?.();
|
|
71
73
|
} else {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/parts/Toolbar/outOfTheBox/PopupMenu/menuContent/usePopupMenuContent.tsx", "../../../../../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["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 allMenuItemsRef.current?.[0]?.focus();\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 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 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", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAA+C;AAMxC,MAAM,sBAAsB,CAAC,EAAE,UAAU,MAA4B;AAC1E,QAAM,cAAU,qBAAyB,IAAI;AAC7C,QAAM,sBAAkB,qBAA4B,CAAC,CAAC;AAEtD,QAAM,aAAS,0BAAY,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,8BAAU,MAAM;AACd,
|
|
4
|
+
"sourcesContent": ["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", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAA+C;AAMxC,MAAM,sBAAsB,CAAC,EAAE,UAAU,MAA4B;AAC1E,QAAM,cAAU,qBAAyB,IAAI;AAC7C,QAAM,sBAAkB,qBAA4B,CAAC,CAAC;AAEtD,QAAM,aAAS,0BAAY,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,8BAAU,MAAM;AACd,eAAW,MAAM,gBAAgB,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC;AAAA,EAC3D,GAAG,CAAC,CAAC;AAEL,QAAM,yBAAqB;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,30 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import React2, { useEffect } from "react";
|
|
3
|
+
function useOnClickOutside(ref, cb) {
|
|
4
|
+
const cbRef = React2.useRef(cb);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
cbRef.current = cb;
|
|
7
|
+
}, [cb]);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (!ref) {
|
|
10
|
+
return () => {
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const listener = (event) => {
|
|
14
|
+
const target = event.target;
|
|
15
|
+
if (!target) return;
|
|
16
|
+
if (ref.contains(target)) return;
|
|
17
|
+
cbRef.current(event);
|
|
18
|
+
};
|
|
19
|
+
document.addEventListener("mousedown", listener, true);
|
|
20
|
+
document.addEventListener("touchstart", listener, true);
|
|
21
|
+
return () => {
|
|
22
|
+
document.removeEventListener("mousedown", listener, true);
|
|
23
|
+
document.removeEventListener("touchstart", listener, true);
|
|
24
|
+
};
|
|
25
|
+
}, [ref]);
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
useOnClickOutside
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=useOnClickOutside.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/hooks/useOnClickOutside.ts"],
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useEffect } from 'react';\n\nexport function useOnClickOutside<T extends Node>(ref: T | null, cb: (event: Event) => void): void {\n const cbRef = React.useRef(cb);\n\n useEffect(() => {\n cbRef.current = cb;\n }, [cb]);\n\n useEffect(() => {\n if (!ref) {\n return () => {};\n }\n\n const listener = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n\n if (ref.contains(target)) return;\n\n cbRef.current(event);\n };\n\n document.addEventListener('mousedown', listener, true);\n document.addEventListener('touchstart', listener, true);\n\n return () => {\n document.removeEventListener('mousedown', listener, true);\n document.removeEventListener('touchstart', listener, true);\n };\n }, [ref]);\n}\n"],
|
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,UAAS,iBAAiB;AAE1B,SAAS,kBAAkC,KAAe,IAAkC;AACjG,QAAM,QAAQA,OAAM,OAAO,EAAE;AAE7B,YAAU,MAAM;AACd,UAAM,UAAU;AAAA,EAClB,GAAG,CAAC,EAAE,CAAC;AAEP,YAAU,MAAM;AACd,QAAI,CAAC,KAAK;AACR,aAAO,MAAM;AAAA,MAAC;AAAA,IAChB;AAEA,UAAM,WAAW,CAAC,UAAmC;AACnD,YAAM,SAAS,MAAM;AACrB,UAAI,CAAC,OAAQ;AAEb,UAAI,IAAI,SAAS,MAAM,EAAG;AAE1B,YAAM,QAAQ,KAAK;AAAA,IACrB;AAEA,aAAS,iBAAiB,aAAa,UAAU,IAAI;AACrD,aAAS,iBAAiB,cAAc,UAAU,IAAI;AAEtD,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,UAAU,IAAI;AACxD,eAAS,oBAAoB,cAAc,UAAU,IAAI;AAAA,IAC3D;AAAA,EACF,GAAG,CAAC,GAAG,CAAC;AACV;",
|
|
6
|
+
"names": ["React"]
|
|
7
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useFloatingContext, PopoverArrow, FloatingWrapper } from "@elliemae/ds-floating-context";
|
|
4
4
|
import { useGetGlobalAttributes } from "@elliemae/ds-props-helpers";
|
|
5
|
-
import { useCallback,
|
|
5
|
+
import { useCallback, useRef } from "react";
|
|
6
6
|
import { DSGlobalHeaderDatatestid } from "../../../../exported-related/index.js";
|
|
7
7
|
import { StyledButton } from "../../../styles.js";
|
|
8
8
|
import { PopupMenuContent } from "./menuContent/PopupMenuContent.js";
|
|
9
|
+
import { useOnClickOutside } from "../../../../hooks/useOnClickOutside.js";
|
|
9
10
|
const PopupMenu = ({
|
|
10
11
|
Icon,
|
|
11
12
|
onClick,
|
|
@@ -13,8 +14,12 @@ const PopupMenu = ({
|
|
|
13
14
|
componentProps,
|
|
14
15
|
...otherProps
|
|
15
16
|
}) => {
|
|
16
|
-
const
|
|
17
|
-
|
|
17
|
+
const { arrowStyles, floatingStyles, isOpen, refs, context, showTooltip, hideTooltip } = useFloatingContext({
|
|
18
|
+
externallyControlledIsOpen: componentProps.isOpen,
|
|
19
|
+
placement: "bottom",
|
|
20
|
+
withoutAnimation: true,
|
|
21
|
+
withoutPortal: true
|
|
22
|
+
});
|
|
18
23
|
const {
|
|
19
24
|
onClickOutside = () => null,
|
|
20
25
|
onKeyPress,
|
|
@@ -23,39 +28,52 @@ const PopupMenu = ({
|
|
|
23
28
|
options,
|
|
24
29
|
closeOnClick
|
|
25
30
|
} = componentProps;
|
|
31
|
+
const boundaryRef = useRef(null);
|
|
26
32
|
const handleOnKeyDown = useCallback(
|
|
27
33
|
(e) => {
|
|
28
34
|
if (e.code === "ArrowDown") {
|
|
29
|
-
|
|
35
|
+
showTooltip();
|
|
30
36
|
}
|
|
31
37
|
if (onKeyPress) onKeyPress(e);
|
|
32
38
|
},
|
|
33
|
-
[onKeyPress]
|
|
39
|
+
[onKeyPress, showTooltip]
|
|
34
40
|
);
|
|
35
41
|
const handleOnClose = useCallback(() => {
|
|
36
42
|
if (userIsOpen === void 0) {
|
|
37
|
-
|
|
43
|
+
hideTooltip();
|
|
38
44
|
}
|
|
39
|
-
|
|
40
|
-
}, [
|
|
45
|
+
refs.reference?.focus();
|
|
46
|
+
}, [hideTooltip, refs.reference, userIsOpen]);
|
|
41
47
|
const handleTriggerOnClick = useCallback(
|
|
42
48
|
(e) => {
|
|
43
|
-
if (userIsOpen === void 0)
|
|
49
|
+
if (userIsOpen === void 0) showTooltip();
|
|
44
50
|
if (onClick) onClick(e);
|
|
45
51
|
},
|
|
46
|
-
[onClick, userIsOpen]
|
|
52
|
+
[onClick, userIsOpen, showTooltip]
|
|
47
53
|
);
|
|
48
54
|
const handleItemClick = useCallback(() => {
|
|
49
55
|
if (closeOnClick && userIsOpen === void 0) handleOnClose();
|
|
50
56
|
}, [closeOnClick, handleOnClose, userIsOpen]);
|
|
57
|
+
const handleOutside = useCallback(
|
|
58
|
+
(event) => {
|
|
59
|
+
onClickOutside(event);
|
|
60
|
+
const actuallyOpen = userIsOpen ?? isOpen;
|
|
61
|
+
if (!actuallyOpen) return;
|
|
62
|
+
if (userIsOpen === void 0) {
|
|
63
|
+
handleOnClose();
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
[handleOnClose, isOpen, onClickOutside, userIsOpen]
|
|
67
|
+
);
|
|
68
|
+
useOnClickOutside(userIsOpen ?? isOpen ? boundaryRef.current : null, handleOutside);
|
|
51
69
|
const handleRefs = useCallback(
|
|
52
70
|
(ref) => {
|
|
53
71
|
setRef(ref);
|
|
54
|
-
|
|
72
|
+
refs.setReference(ref);
|
|
55
73
|
},
|
|
56
|
-
[setRef]
|
|
74
|
+
[refs, setRef]
|
|
57
75
|
);
|
|
58
|
-
return /* @__PURE__ */ jsxs(
|
|
76
|
+
return /* @__PURE__ */ jsxs("div", { ref: boundaryRef, children: [
|
|
59
77
|
/* @__PURE__ */ jsx(
|
|
60
78
|
StyledButton,
|
|
61
79
|
{
|
|
@@ -70,24 +88,26 @@ const PopupMenu = ({
|
|
|
70
88
|
children: Icon && /* @__PURE__ */ jsx(Icon, { size: "m" })
|
|
71
89
|
}
|
|
72
90
|
),
|
|
73
|
-
|
|
74
|
-
|
|
91
|
+
refs.reference ? /* @__PURE__ */ jsxs(
|
|
92
|
+
FloatingWrapper,
|
|
75
93
|
{
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
94
|
+
innerRef: refs.setFloating,
|
|
95
|
+
isOpen: userIsOpen ?? isOpen,
|
|
96
|
+
floatingStyles,
|
|
97
|
+
context,
|
|
98
|
+
children: [
|
|
99
|
+
/* @__PURE__ */ jsx(
|
|
100
|
+
PopupMenuContent,
|
|
101
|
+
{
|
|
102
|
+
options,
|
|
103
|
+
onItemClick: handleItemClick,
|
|
104
|
+
onClose: handleOnClose,
|
|
105
|
+
setIsOpen: hideTooltip,
|
|
106
|
+
popupOnKeyPress
|
|
107
|
+
}
|
|
108
|
+
),
|
|
109
|
+
/* @__PURE__ */ jsx(PopoverArrow, { ...arrowStyles })
|
|
110
|
+
]
|
|
91
111
|
}
|
|
92
112
|
) : null
|
|
93
113
|
] });
|
|
@@ -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 {
|
|
5
|
-
"mappings": "AAAA,YAAY,WAAW;
|
|
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, useRef } from 'react';\nimport { DSGlobalHeaderDatatestid } from '../../../../exported-related/index.js';\nimport type { DSGlobalHeaderT } from '../../../../react-desc-prop-types.js';\nimport { StyledButton } from '../../../styles.js';\nimport { PopupMenuContent } from './menuContent/PopupMenuContent.js';\nimport { useOnClickOutside } from '../../../../hooks/useOnClickOutside.js';\nexport const PopupMenu = ({\n Icon,\n onClick,\n setRef,\n componentProps,\n ...otherProps\n}: DSGlobalHeaderT.PopupProps): JSX.Element => {\n const { arrowStyles, floatingStyles, isOpen, refs, context, showTooltip, hideTooltip } = useFloatingContext({\n externallyControlledIsOpen: componentProps.isOpen,\n placement: 'bottom',\n withoutAnimation: true,\n withoutPortal: true,\n });\n\n const {\n onClickOutside = () => null,\n onKeyPress,\n popupOnKeyPress,\n isOpen: userIsOpen,\n options,\n closeOnClick,\n } = componentProps;\n\n /**\n * We want \"outside\" to mean: outside BOTH the trigger and the floating panel.\n * So wrap them in a single DOM node and use that as the boundary.\n */\n const boundaryRef = useRef<HTMLDivElement | null>(null);\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();\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 // Close on outside click, but:\n // - always notify consumer via onClickOutside\n // - only actually close when uncontrolled (userIsOpen === undefined)\n // - only run while open\n const handleOutside = useCallback(\n (event: Event) => {\n onClickOutside(event as MouseEvent | TouchEvent);\n\n const actuallyOpen = userIsOpen ?? isOpen;\n if (!actuallyOpen) return;\n\n if (userIsOpen === undefined) {\n handleOnClose();\n }\n },\n [handleOnClose, isOpen, onClickOutside, userIsOpen],\n );\n\n // If you only want to listen when open, pass `null` when closed\n useOnClickOutside((userIsOpen ?? isOpen) ? boundaryRef.current : null, handleOutside);\n\n const handleRefs = useCallback(\n (ref: HTMLButtonElement) => {\n setRef(ref);\n refs.setReference(ref);\n },\n [refs, setRef],\n );\n return (\n <div ref={boundaryRef}>\n <StyledButton\n onClick={handleTriggerOnClick}\n onKeyDown={handleOnKeyDown}\n innerRef={handleRefs}\n data-testid={DSGlobalHeaderDatatestid.MENUBAR.ITEM_BUTTON}\n aria-haspopup\n aria-expanded={userIsOpen ?? isOpen}\n {...useGetGlobalAttributes(otherProps)}\n type=\"button\"\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 />\n <PopoverArrow {...arrowStyles} />\n </FloatingWrapper>\n ) : null}\n </div>\n );\n};\n"],
|
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;AC0GN,cAIT,YAJS;AA1GjB,SAAS,oBAAoB,cAAc,uBAAuB;AAClE,SAAS,8BAA8B;AACvC,SAAgB,aAAa,cAAc;AAC3C,SAAS,gCAAgC;AAEzC,SAAS,oBAAoB;AAC7B,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAC3B,MAAM,YAAY,CAAC;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA+C;AAC7C,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,EACjB,CAAC;AAED,QAAM;AAAA,IACJ,iBAAiB,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,EACF,IAAI;AAMJ,QAAM,cAAc,OAA8B,IAAI;AAEtD,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;AAC1C,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;AAM5C,QAAM,gBAAgB;AAAA,IACpB,CAAC,UAAiB;AAChB,qBAAe,KAAgC;AAE/C,YAAM,eAAe,cAAc;AACnC,UAAI,CAAC,aAAc;AAEnB,UAAI,eAAe,QAAW;AAC5B,sBAAc;AAAA,MAChB;AAAA,IACF;AAAA,IACA,CAAC,eAAe,QAAQ,gBAAgB,UAAU;AAAA,EACpD;AAGA,oBAAmB,cAAc,SAAU,YAAY,UAAU,MAAM,aAAa;AAEpF,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,SAAI,KAAK,aACR;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,WAAW;AAAA,QACX,UAAU;AAAA,QACV,eAAa,yBAAyB,QAAQ;AAAA,QAC9C,iBAAa;AAAA,QACb,iBAAe,cAAc;AAAA,QAC5B,GAAG,uBAAuB,UAAU;AAAA,QACrC,MAAK;AAAA,QAEJ,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;AAAA,UACF;AAAA,UACA,oBAAC,gBAAc,GAAG,aAAa;AAAA;AAAA;AAAA,IACjC,IACE;AAAA,KACN;AAEJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -16,7 +16,7 @@ const usePopupMenuContent = ({ setIsOpen }) => {
|
|
|
16
16
|
});
|
|
17
17
|
}, []);
|
|
18
18
|
useEffect(() => {
|
|
19
|
-
allMenuItemsRef.current?.[0]?.focus();
|
|
19
|
+
setTimeout(() => allMenuItemsRef.current?.[0]?.focus(), 0);
|
|
20
20
|
}, []);
|
|
21
21
|
const keyboardNavigation = useCallback(
|
|
22
22
|
(e) => {
|
|
@@ -26,6 +26,7 @@ const usePopupMenuContent = ({ setIsOpen }) => {
|
|
|
26
26
|
const currentIndex = allMenuItemsRef.current.indexOf(e.target);
|
|
27
27
|
const allRefsLength = allMenuItemsRef.current.length;
|
|
28
28
|
if (e.key === "ArrowDown") {
|
|
29
|
+
e.preventDefault();
|
|
29
30
|
if (currentIndex < allRefsLength - 1) {
|
|
30
31
|
allMenuItemsRef.current[currentIndex + 1]?.focus?.();
|
|
31
32
|
} else {
|
|
@@ -33,6 +34,7 @@ const usePopupMenuContent = ({ setIsOpen }) => {
|
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
if (e.key === "ArrowUp") {
|
|
37
|
+
e.preventDefault();
|
|
36
38
|
if (currentIndex === 0) {
|
|
37
39
|
allMenuItemsRef.current[allRefsLength - 1]?.focus?.();
|
|
38
40
|
} else {
|
|
@@ -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 allMenuItemsRef.current?.[0]?.focus();\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 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 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,
|
|
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;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useOnClickOutside<T extends Node>(ref: T | null, cb: (event: Event) => void): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elliemae/ds-global-header",
|
|
3
|
-
"version": "3.60.0-next.
|
|
3
|
+
"version": "3.60.0-next.15",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "ICE MT - Dimsum - Global Header",
|
|
6
6
|
"files": [
|
|
@@ -38,20 +38,19 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@elliemae/ds-legacy-form": "1.0.16",
|
|
40
40
|
"uid": "^2.0.2",
|
|
41
|
-
"@elliemae/ds-
|
|
42
|
-
"@elliemae/ds-
|
|
43
|
-
"@elliemae/ds-
|
|
44
|
-
"@elliemae/ds-hooks-fontsize-media": "3.60.0-next.
|
|
45
|
-
"@elliemae/ds-icons": "3.60.0-next.
|
|
46
|
-
"@elliemae/ds-props-helpers": "3.60.0-next.
|
|
47
|
-
"@elliemae/ds-system": "3.60.0-next.
|
|
41
|
+
"@elliemae/ds-floating-context": "3.60.0-next.15",
|
|
42
|
+
"@elliemae/ds-app-picker": "3.60.0-next.15",
|
|
43
|
+
"@elliemae/ds-grid": "3.60.0-next.15",
|
|
44
|
+
"@elliemae/ds-hooks-fontsize-media": "3.60.0-next.15",
|
|
45
|
+
"@elliemae/ds-icons": "3.60.0-next.15",
|
|
46
|
+
"@elliemae/ds-props-helpers": "3.60.0-next.15",
|
|
47
|
+
"@elliemae/ds-system": "3.60.0-next.15"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"
|
|
51
|
-
"jest": "~29.7.0",
|
|
50
|
+
"jest": "^30.0.0",
|
|
52
51
|
"styled-components": "~5.3.9",
|
|
53
|
-
"@elliemae/ds-monorepo-devops": "3.60.0-next.
|
|
54
|
-
"@elliemae/ds-test-utils": "3.60.0-next.
|
|
52
|
+
"@elliemae/ds-monorepo-devops": "3.60.0-next.15",
|
|
53
|
+
"@elliemae/ds-test-utils": "3.60.0-next.15"
|
|
55
54
|
},
|
|
56
55
|
"peerDependencies": {
|
|
57
56
|
"lodash-es": "^4.17.21",
|
|
@@ -65,7 +64,7 @@
|
|
|
65
64
|
},
|
|
66
65
|
"scripts": {
|
|
67
66
|
"dev": "cross-env NODE_ENV=development node ../../../scripts/build/build.mjs --watch",
|
|
68
|
-
"test": "
|
|
67
|
+
"test": "ds-monorepo-devops test --passWithNoTests --coverage=\"false\"",
|
|
69
68
|
"lint": "node ../../../scripts/lint.mjs --fix",
|
|
70
69
|
"lint:strict": "node ../../../scripts/lint-strict.mjs",
|
|
71
70
|
"dts": "node ../../../scripts/dts.mjs",
|