@elliemae/ds-floating-context 3.70.0-next.6 → 3.70.0-next.61
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/DSFloatingContext.js +129 -41
- package/dist/cjs/DSFloatingContext.js.map +2 -2
- package/dist/cjs/hooks/useFloatingClickOutside.js +60 -0
- package/dist/cjs/hooks/useFloatingClickOutside.js.map +7 -0
- package/dist/cjs/hooks/useFloatingResizeObserver.js +52 -0
- package/dist/cjs/hooks/useFloatingResizeObserver.js.map +7 -0
- package/dist/cjs/hooks/useLatestRef.js +41 -0
- package/dist/cjs/hooks/useLatestRef.js.map +7 -0
- package/dist/cjs/hooks/useReferenceHiddenByBoundary.js +59 -0
- package/dist/cjs/hooks/useReferenceHiddenByBoundary.js.map +7 -0
- package/dist/cjs/hooks/useResolvedReference.js +52 -0
- package/dist/cjs/hooks/useResolvedReference.js.map +7 -0
- package/dist/cjs/hooks/useSyntheticEventFromControlledState.js +53 -0
- package/dist/cjs/hooks/useSyntheticEventFromControlledState.js.map +7 -0
- package/dist/cjs/package.json +1 -4
- package/dist/cjs/parts/FloatingWrapper/react-desc-prop-types.js +1 -1
- package/dist/cjs/parts/FloatingWrapper/react-desc-prop-types.js.map +2 -2
- package/dist/cjs/parts/PopoverArrow.js.map +2 -2
- package/dist/cjs/react-desc-prop-types.js +23 -5
- package/dist/cjs/react-desc-prop-types.js.map +2 -2
- package/dist/cjs/typescript-testing/typescript-floating-context-valid.js +8 -2
- package/dist/cjs/typescript-testing/typescript-floating-context-valid.js.map +2 -2
- package/dist/cjs/useComputedPositionStyles.js +41 -18
- package/dist/cjs/useComputedPositionStyles.js.map +2 -2
- package/dist/cjs/utils/computePosition.js +26 -10
- package/dist/cjs/utils/computePosition.js.map +2 -2
- package/dist/cjs/utils/floatingPositioning.js +11 -0
- package/dist/cjs/utils/floatingPositioning.js.map +2 -2
- package/dist/esm/DSFloatingContext.js +130 -42
- package/dist/esm/DSFloatingContext.js.map +2 -2
- package/dist/esm/hooks/useFloatingClickOutside.js +30 -0
- package/dist/esm/hooks/useFloatingClickOutside.js.map +7 -0
- package/dist/esm/hooks/useFloatingResizeObserver.js +22 -0
- package/dist/esm/hooks/useFloatingResizeObserver.js.map +7 -0
- package/dist/esm/hooks/useLatestRef.js +11 -0
- package/dist/esm/hooks/useLatestRef.js.map +7 -0
- package/dist/esm/hooks/useReferenceHiddenByBoundary.js +29 -0
- package/dist/esm/hooks/useReferenceHiddenByBoundary.js.map +7 -0
- package/dist/esm/hooks/useResolvedReference.js +22 -0
- package/dist/esm/hooks/useResolvedReference.js.map +7 -0
- package/dist/esm/hooks/useSyntheticEventFromControlledState.js +23 -0
- package/dist/esm/hooks/useSyntheticEventFromControlledState.js.map +7 -0
- package/dist/esm/package.json +1 -4
- package/dist/esm/parts/FloatingWrapper/react-desc-prop-types.js +1 -1
- package/dist/esm/parts/FloatingWrapper/react-desc-prop-types.js.map +2 -2
- package/dist/esm/parts/PopoverArrow.js.map +2 -2
- package/dist/esm/react-desc-prop-types.js +23 -5
- package/dist/esm/react-desc-prop-types.js.map +2 -2
- package/dist/esm/typescript-testing/typescript-floating-context-valid.js +8 -2
- package/dist/esm/typescript-testing/typescript-floating-context-valid.js.map +2 -2
- package/dist/esm/useComputedPositionStyles.js +41 -18
- package/dist/esm/useComputedPositionStyles.js.map +2 -2
- package/dist/esm/utils/computePosition.js +27 -10
- package/dist/esm/utils/computePosition.js.map +2 -2
- package/dist/esm/utils/floatingPositioning.js +11 -0
- package/dist/esm/utils/floatingPositioning.js.map +2 -2
- package/dist/types/DSFloatingContext.d.ts +48 -8
- package/dist/types/hooks/useFloatingClickOutside.d.ts +20 -0
- package/dist/types/hooks/useFloatingResizeObserver.d.ts +11 -0
- package/dist/types/hooks/useLatestRef.d.ts +7 -0
- package/dist/types/hooks/useReferenceHiddenByBoundary.d.ts +17 -0
- package/dist/types/hooks/useResolvedReference.d.ts +19 -0
- package/dist/types/hooks/useSyntheticEventFromControlledState.d.ts +32 -0
- package/dist/types/react-desc-prop-types.d.ts +76 -2
- package/dist/types/useComputedPositionStyles.d.ts +7 -4
- package/dist/types/utils/computePosition.d.ts +25 -2
- package/dist/types/utils/floatingPositioning.d.ts +13 -1
- package/package.json +9 -9
- package/dist/types/tests/ControlledTestRenderer.d.ts +0 -1
- package/dist/types/tests/FloatingContext.a11y.test.d.ts +0 -1
- package/dist/types/tests/FloatingContext.data-testid.test.d.ts +0 -1
- package/dist/types/tests/FloatingContext.event.test.d.ts +0 -1
- package/dist/types/tests/FloatingContext.exports.test.d.ts +0 -1
- package/dist/types/tests/FloatingContext.get-owner-props.test.d.ts +0 -1
- package/dist/types/tests/FloatingContext.utils.test.d.ts +0 -1
- package/dist/types/tests/playwright/FloatingContext.test.playwright.d.ts +0 -1
- package/dist/types/typescript-testing/typescript-floating-context-valid.d.ts +0 -1
|
@@ -39,8 +39,19 @@ var import_ds_hooks_headless_tooltip = require("@elliemae/ds-hooks-headless-tool
|
|
|
39
39
|
var import_react_desc_prop_types = require("./react-desc-prop-types.js");
|
|
40
40
|
var import_useComputedPositionStyles = require("./useComputedPositionStyles.js");
|
|
41
41
|
var import_positionObserver = require("./utils/positionObserver.js");
|
|
42
|
+
var import_useLatestRef = require("./hooks/useLatestRef.js");
|
|
43
|
+
var import_useResolvedReference = require("./hooks/useResolvedReference.js");
|
|
44
|
+
var import_useFloatingClickOutside = require("./hooks/useFloatingClickOutside.js");
|
|
45
|
+
var import_useFloatingResizeObserver = require("./hooks/useFloatingResizeObserver.js");
|
|
46
|
+
var import_useReferenceHiddenByBoundary = require("./hooks/useReferenceHiddenByBoundary.js");
|
|
47
|
+
var import_useSyntheticEventFromControlledState = require("./hooks/useSyntheticEventFromControlledState.js");
|
|
48
|
+
const isKeyboardEvent = (event) => !!event?.key;
|
|
42
49
|
const useFloatingContext = (props = {}) => {
|
|
43
|
-
const
|
|
50
|
+
const { onClickOutside, onEscape, onOpen, onClose, externalReferenceElement, boundaryElement, ...stableProps } = props;
|
|
51
|
+
const propsWithDefault = (0, import_ds_props_helpers.useMemoMergePropsWithDefault)(
|
|
52
|
+
stableProps,
|
|
53
|
+
import_react_desc_prop_types.defaultProps
|
|
54
|
+
);
|
|
44
55
|
(0, import_ds_props_helpers.useValidateTypescriptPropTypes)(propsWithDefault, import_react_desc_prop_types.DSFloatingContextPropTypes, "FloatingContext");
|
|
45
56
|
const {
|
|
46
57
|
withoutPortal,
|
|
@@ -50,68 +61,145 @@ const useFloatingContext = (props = {}) => {
|
|
|
50
61
|
placement,
|
|
51
62
|
customOffset,
|
|
52
63
|
placementOrderPreference,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
64
|
+
externallyControlledIsOpen,
|
|
65
|
+
closeOnEscape,
|
|
66
|
+
returnFocusToReference
|
|
56
67
|
} = propsWithDefault;
|
|
68
|
+
const isControlled = externallyControlledIsOpen !== void 0;
|
|
69
|
+
const [floatingWrapperNode, setFloatingWrapperNode] = import_react.default.useState(null);
|
|
70
|
+
const triggerElementReferenceRef = import_react.default.useRef(null);
|
|
71
|
+
const onClickOutsideRef = (0, import_useLatestRef.useLatestRef)(onClickOutside);
|
|
72
|
+
const onEscapeRef = (0, import_useLatestRef.useLatestRef)(onEscape);
|
|
73
|
+
const onOpenRef = (0, import_useLatestRef.useLatestRef)(onOpen);
|
|
74
|
+
const onCloseRef = (0, import_useLatestRef.useLatestRef)(onClose);
|
|
57
75
|
const [internalIsOpen, setInternalIsOpen] = import_react.default.useState(false);
|
|
58
76
|
const isOpen = (0, import_react.useMemo)(
|
|
59
77
|
() => externallyControlledIsOpen !== void 0 ? externallyControlledIsOpen : internalIsOpen,
|
|
60
78
|
[externallyControlledIsOpen, internalIsOpen]
|
|
61
79
|
);
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
80
|
+
const isControlledRef = (0, import_useLatestRef.useLatestRef)(isControlled);
|
|
81
|
+
const closeOnEscapeRef = (0, import_useLatestRef.useLatestRef)(closeOnEscape);
|
|
82
|
+
const returnFocusToReferenceRef = (0, import_useLatestRef.useLatestRef)(returnFocusToReference);
|
|
83
|
+
const floatingWrapperNodeRef = (0, import_useLatestRef.useLatestRef)(floatingWrapperNode);
|
|
84
|
+
const isOpenRef = (0, import_useLatestRef.useLatestRef)(isOpen);
|
|
85
|
+
const handleOpen = import_react.default.useCallback(
|
|
86
|
+
(event) => {
|
|
87
|
+
setInternalIsOpen(true);
|
|
88
|
+
onOpenRef.current?.({ reason: "interaction", event, isControlled: isControlledRef.current });
|
|
89
|
+
},
|
|
90
|
+
[onOpenRef, isControlledRef]
|
|
91
|
+
);
|
|
92
|
+
const isFocusWithinFloatingScope = (0, import_react.useCallback)(() => {
|
|
93
|
+
const active = document.activeElement;
|
|
94
|
+
if (!active) return false;
|
|
95
|
+
if (floatingWrapperNodeRef.current?.contains(active)) return true;
|
|
96
|
+
const reference = triggerElementReferenceRef.current;
|
|
97
|
+
return reference === active || !!reference?.contains(active);
|
|
98
|
+
}, [floatingWrapperNodeRef]);
|
|
99
|
+
const handleClose = import_react.default.useCallback(
|
|
100
|
+
(event) => {
|
|
101
|
+
const wasOpen = isOpenRef.current;
|
|
102
|
+
setInternalIsOpen(false);
|
|
103
|
+
const isScopedEscapeClose = wasOpen && closeOnEscapeRef.current && isKeyboardEvent(event) && event.key === "Escape" && isFocusWithinFloatingScope();
|
|
104
|
+
if (isScopedEscapeClose) {
|
|
105
|
+
onEscapeRef.current?.(event);
|
|
106
|
+
if (returnFocusToReferenceRef.current && triggerElementReferenceRef.current instanceof HTMLElement) {
|
|
107
|
+
triggerElementReferenceRef.current.focus();
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
onCloseRef.current?.({ reason: "interaction", event, isControlled: isControlledRef.current });
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
[
|
|
114
|
+
isOpenRef,
|
|
115
|
+
closeOnEscapeRef,
|
|
116
|
+
isFocusWithinFloatingScope,
|
|
117
|
+
returnFocusToReferenceRef,
|
|
118
|
+
onCloseRef,
|
|
119
|
+
onEscapeRef,
|
|
120
|
+
isControlledRef
|
|
121
|
+
]
|
|
122
|
+
);
|
|
123
|
+
const shouldFocusReferenceOnEscape = (0, import_react.useCallback)(
|
|
124
|
+
() => closeOnEscapeRef.current && returnFocusToReferenceRef.current && isFocusWithinFloatingScope(),
|
|
125
|
+
[closeOnEscapeRef, returnFocusToReferenceRef, isFocusWithinFloatingScope]
|
|
126
|
+
);
|
|
127
|
+
const tooltipHelpersConfig = (0, import_react.useMemo)(
|
|
128
|
+
() => ({ onOpen: handleOpen, onClose: handleClose, focusReferenceOnEscape: shouldFocusReferenceOnEscape }),
|
|
129
|
+
[handleOpen, handleClose, shouldFocusReferenceOnEscape]
|
|
130
|
+
);
|
|
131
|
+
const tooltipHelpers = (0, import_ds_hooks_headless_tooltip.useHeadlessTooltip)(tooltipHelpersConfig);
|
|
132
|
+
const {
|
|
133
|
+
setReferenceElement: setInternalReferenceElement,
|
|
134
|
+
referenceElement: internalReferenceElement,
|
|
135
|
+
hideTooltip,
|
|
136
|
+
showTooltip
|
|
137
|
+
} = tooltipHelpers;
|
|
138
|
+
const { triggerElementReference, setReferenceElement } = (0, import_useResolvedReference.useResolvedReference)({
|
|
139
|
+
externalReferenceElement,
|
|
140
|
+
internalReferenceElement,
|
|
141
|
+
setInternalReferenceElement
|
|
142
|
+
});
|
|
143
|
+
triggerElementReferenceRef.current = triggerElementReference;
|
|
73
144
|
const { arrowStyles, floatingStyles, hasComputedOnce, updateStyles, debouncedUpdateStyles, mutableUpdateStyles } = (0, import_useComputedPositionStyles.useComputedPositionStyles)({
|
|
74
|
-
|
|
75
|
-
|
|
145
|
+
triggerElementReference,
|
|
146
|
+
floatingWrapperNode,
|
|
76
147
|
placement,
|
|
77
148
|
placementOrderPreference,
|
|
78
149
|
customOffset,
|
|
79
150
|
withoutPortal,
|
|
80
|
-
|
|
151
|
+
boundaryElement,
|
|
152
|
+
isClose: !isOpen,
|
|
81
153
|
debounceMs: 150
|
|
82
154
|
});
|
|
83
|
-
(0, import_react.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
mutableUpdateStyles.current();
|
|
89
|
-
});
|
|
90
|
-
roFloating.observe(floating);
|
|
91
|
-
observers.push(roFloating);
|
|
92
|
-
}
|
|
93
|
-
return () => observers.forEach((o) => o.disconnect());
|
|
94
|
-
}, [isOpen, floating, updateStyles, mutableUpdateStyles]);
|
|
155
|
+
const floatingResizeOberverConfig = (0, import_react.useMemo)(
|
|
156
|
+
() => ({ isOpen, floatingWrapperNode, onResize: () => mutableUpdateStyles.current() }),
|
|
157
|
+
[isOpen, floatingWrapperNode, mutableUpdateStyles]
|
|
158
|
+
);
|
|
159
|
+
(0, import_useFloatingResizeObserver.useFloatingResizeObserver)(floatingResizeOberverConfig);
|
|
95
160
|
const onObservedMovement = import_react.default.useCallback(() => {
|
|
96
161
|
if (!isOpen) return;
|
|
97
162
|
debouncedUpdateStyles();
|
|
98
163
|
}, [isOpen, debouncedUpdateStyles]);
|
|
99
|
-
(0, import_positionObserver.usePositionObserver)(
|
|
100
|
-
const
|
|
101
|
-
|
|
164
|
+
(0, import_positionObserver.usePositionObserver)(triggerElementReference, onObservedMovement);
|
|
165
|
+
const isReferenceHiddenByBoundary = (0, import_useReferenceHiddenByBoundary.useReferenceHiddenByBoundary)({
|
|
166
|
+
reference: triggerElementReference,
|
|
167
|
+
boundaryElement,
|
|
168
|
+
enabled: isOpen && !!boundaryElement
|
|
169
|
+
});
|
|
170
|
+
(0, import_useFloatingClickOutside.useFloatingClickOutside)({
|
|
171
|
+
isOpen,
|
|
172
|
+
floatingWrapperNode,
|
|
173
|
+
triggerElementReference,
|
|
174
|
+
onClickOutsideRef
|
|
175
|
+
});
|
|
176
|
+
const handleControlledOpen = (0, import_react.useCallback)(() => {
|
|
177
|
+
onOpenRef.current?.({ reason: "controlled-flip", isControlled: true });
|
|
178
|
+
}, [onOpenRef]);
|
|
179
|
+
const handleControlledClose = (0, import_react.useCallback)(() => {
|
|
180
|
+
onCloseRef.current?.({ reason: "controlled-flip", isControlled: true });
|
|
181
|
+
}, [onCloseRef]);
|
|
182
|
+
(0, import_useSyntheticEventFromControlledState.useSyntheticEventFromControlledState)({
|
|
183
|
+
controlledValue: externallyControlledIsOpen,
|
|
184
|
+
onEnter: handleControlledOpen,
|
|
185
|
+
onExit: handleControlledClose
|
|
186
|
+
});
|
|
187
|
+
const computedFloatingStyles = (0, import_react.useMemo)(() => {
|
|
188
|
+
const isInteractive = isOpen && hasComputedOnce && !isReferenceHiddenByBoundary;
|
|
189
|
+
return {
|
|
102
190
|
...floatingStyles,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
);
|
|
191
|
+
opacity: isInteractive ? 1 : 0,
|
|
192
|
+
pointerEvents: isInteractive ? "auto" : "none"
|
|
193
|
+
};
|
|
194
|
+
}, [floatingStyles, hasComputedOnce, isOpen, isReferenceHiddenByBoundary]);
|
|
107
195
|
const refs = (0, import_react.useMemo)(
|
|
108
196
|
() => ({
|
|
109
197
|
setReference: setReferenceElement,
|
|
110
|
-
setFloating,
|
|
111
|
-
floating,
|
|
112
|
-
reference:
|
|
198
|
+
setFloating: setFloatingWrapperNode,
|
|
199
|
+
floating: floatingWrapperNode,
|
|
200
|
+
reference: triggerElementReference
|
|
113
201
|
}),
|
|
114
|
-
[setReferenceElement,
|
|
202
|
+
[setReferenceElement, floatingWrapperNode, triggerElementReference]
|
|
115
203
|
);
|
|
116
204
|
const handlers = (0, import_react.useMemo)(
|
|
117
205
|
() => ({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/DSFloatingContext.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable max-lines */\n/* eslint-disable consistent-return */\n/* eslint-disable max-statements */\nimport React, { useMemo, useEffect } from 'react';\nimport {\n useMemoMergePropsWithDefault,\n useValidateTypescriptPropTypes,\n describe,\n type ValidationMap,\n} from '@elliemae/ds-props-helpers';\nimport { useHeadlessTooltip } from '@elliemae/ds-hooks-headless-tooltip';\nimport type { DSHookFloatingContextT } from './react-desc-prop-types.js';\nimport { defaultProps, DSFloatingContextPropTypes } from './react-desc-prop-types.js';\nimport { useComputedPositionStyles } from './useComputedPositionStyles.js';\nimport { usePositionObserver } from './utils/positionObserver.js';\n\nconst useFloatingContext = (props: DSHookFloatingContextT.Props = {}) => {\n const propsWithDefault = useMemoMergePropsWithDefault<DSHookFloatingContextT.InternalProps>(props, defaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSFloatingContextPropTypes, 'FloatingContext');\n\n const {\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\n placement,\n customOffset,\n placementOrderPreference,\n onOpen,\n onClose,\n externallyControlledIsOpen,\n } = propsWithDefault;\n\n const [internalIsOpen, setInternalIsOpen] = React.useState<boolean>(false);\n const isOpen = useMemo(\n () => (externallyControlledIsOpen !== undefined ? externallyControlledIsOpen : internalIsOpen),\n [externallyControlledIsOpen, internalIsOpen],\n );\n\n const handleOpen = React.useCallback(() => {\n setInternalIsOpen(true);\n onOpen?.();\n }, [onOpen]);\n\n const handleClose = React.useCallback(() => {\n setInternalIsOpen(false);\n onClose?.();\n }, [onClose]);\n\n const tooltipHelpers = useHeadlessTooltip({ onOpen: handleOpen, onClose: handleClose });\n const { setReferenceElement, referenceElement, hideTooltip, showTooltip } = tooltipHelpers;\n\n // Anchor and floating refs\n const [floating, setFloating] = React.useState<HTMLElement | null>(null);\n\n // Compute position (skip when closed)\n const { arrowStyles, floatingStyles, hasComputedOnce, updateStyles, debouncedUpdateStyles, mutableUpdateStyles } =\n useComputedPositionStyles({\n reference: referenceElement,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n preventComputing: !isOpen,\n debounceMs: 150,\n });\n\n useEffect(() => {\n if (!isOpen) return;\n\n const observers: ResizeObserver[] = [];\n\n if (floating) {\n const roFloating = new ResizeObserver(() => {\n mutableUpdateStyles.current();\n });\n roFloating.observe(floating);\n observers.push(roFloating);\n }\n\n return () => observers.forEach((o) => o.disconnect());\n }, [isOpen, floating, updateStyles, mutableUpdateStyles]);\n\n const onObservedMovement = React.useCallback(() => {\n if (!isOpen) return;\n debouncedUpdateStyles();\n }, [isOpen, debouncedUpdateStyles]);\n usePositionObserver(referenceElement, onObservedMovement);\n\n // Expose visibility: only visible if open and already computed at least once\n const computedFloatingStyles = useMemo<React.CSSProperties>(\n () => ({\n ...floatingStyles,\n visibility: isOpen && hasComputedOnce ? 'visible' : 'hidden',\n }),\n [floatingStyles, hasComputedOnce, isOpen],\n );\n\n const refs = useMemo(\n () => ({\n setReference: setReferenceElement,\n setFloating,\n floating,\n reference: referenceElement,\n }),\n [setReferenceElement, floating, referenceElement],\n );\n\n const handlers = useMemo(\n () => ({\n onMouseEnter: tooltipHelpers.onMouseEnter,\n onMouseLeave: tooltipHelpers.onMouseLeave,\n onFocus: tooltipHelpers.onFocus,\n onBlur: tooltipHelpers.onBlur,\n }),\n [tooltipHelpers.onBlur, tooltipHelpers.onFocus, tooltipHelpers.onMouseEnter, tooltipHelpers.onMouseLeave],\n );\n\n return useMemo(\n () => ({\n refs,\n floatingStyles: computedFloatingStyles,\n handlers,\n isOpen,\n arrowStyles,\n hideTooltip,\n showTooltip,\n context: {\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\n },\n mutableUpdateStyles,\n forceUpdatePosition: updateStyles,\n }),\n [\n refs,\n computedFloatingStyles,\n handlers,\n isOpen,\n arrowStyles,\n hideTooltip,\n showTooltip,\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\n mutableUpdateStyles,\n updateStyles,\n ],\n );\n};\n\nuseFloatingContext.displayName = 'FloatingContext';\nconst UseFloatingContextWithSchema = describe(useFloatingContext);\nUseFloatingContextWithSchema.propTypes =\n DSFloatingContextPropTypes as unknown as ValidationMap<DSHookFloatingContextT.Props>;\n\nexport { useFloatingContext, UseFloatingContextWithSchema };\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable max-lines */\n/* eslint-disable max-statements */\nimport React, { useCallback, useMemo } from 'react';\nimport {\n useMemoMergePropsWithDefault,\n useValidateTypescriptPropTypes,\n describe,\n type ValidationMap,\n} from '@elliemae/ds-props-helpers';\nimport { useHeadlessTooltip, type UseHeadlessTooltipConfig } from '@elliemae/ds-hooks-headless-tooltip';\nimport type { DSHookFloatingContextT } from './react-desc-prop-types.js';\nimport { defaultProps, DSFloatingContextPropTypes } from './react-desc-prop-types.js';\nimport { useComputedPositionStyles } from './useComputedPositionStyles.js';\nimport { usePositionObserver } from './utils/positionObserver.js';\nimport { useLatestRef } from './hooks/useLatestRef.js';\nimport { useResolvedReference } from './hooks/useResolvedReference.js';\nimport { useFloatingClickOutside } from './hooks/useFloatingClickOutside.js';\nimport { useFloatingResizeObserver } from './hooks/useFloatingResizeObserver.js';\nimport { useReferenceHiddenByBoundary } from './hooks/useReferenceHiddenByBoundary.js';\nimport { useSyntheticEventFromControlledState } from './hooks/useSyntheticEventFromControlledState.js';\n\nconst isKeyboardEvent = (\n event: React.FocusEvent | React.MouseEvent | KeyboardEvent | undefined,\n): event is KeyboardEvent => !!(event as KeyboardEvent)?.key;\n\n/**\n * useFloatingContext \u2014 headless positioning + open/close lifecycle for a floating surface\n * (popover / tooltip / dialog-like panel). Returns positioning styles + refs, imperative show/hide\n * helpers, interaction handlers to spread on a trigger, and a discriminated open/close notification.\n *\n * COUPLING: this hook is the shared substrate under ds-app-picker, ds-tooltip and others; its\n * open/close/escape/reason contract is relied on across packages. The consumer that leans hardest on\n * the exact semantics below is ds-app-picker\n * (layout/ds-app-picker/src/parts/AppPickerFloatingContext/useAppPickerFloatingContext.ts). Treat\n * changes to these semantics as cross-package.\n *\n * OPEN STATE \u2014 controlled vs uncontrolled\n * - Uncontrolled: `externallyControlledIsOpen` undefined \u2192 open state lives here (in the underlying\n * ds-hooks-headless-tooltip) and is driven by the focus/hover handlers + the show/hide helpers.\n * - Controlled: `externallyControlledIsOpen` is a boolean \u2192 the consumer owns visibility and the\n * internal open state is inert. `isControlled` is surfaced on every OpenChange payload.\n *\n * NOTIFICATION \u2014 one onOpen/onClose pair, two reasons (see OpenChange in react-desc-prop-types)\n * - 'interaction': fired synchronously in the event catch phase by this hook's own interaction\n * handling \u2014 focus/hover/blur/mouseleave, an imperative show/hide, or a NON-scoped Escape falling\n * through to onClose \u2014 carrying the DOM event when there is one. Fires for controlled contexts too\n * (the pre-flip signal a controlled consumer may act on).\n * - 'controlled-flip': fired from a post-commit effect (useSyntheticEventFromControlledState) when\n * `externallyControlledIsOpen` transitions. No event. NEVER fires on mount \u2014 a surface rendered\n * already-open gets no onOpen and must seed any initial focus itself.\n *\n * ESCAPE \u2014 one listener, not two\n * Escape dismissal rides ds-hooks-headless-tooltip's single always-on document keydown listener (it\n * calls hideTooltip on ANY Escape, even when this context never opened). handleClose is the one place\n * that interprets it:\n * - SCOPED Escape (was open + closeOnEscape + key 'Escape' + focus within the panel/reference)\n * \u2192 routes to `onEscape` (NOT onClose); if returnFocusToReference, focuses the reference.\n * - anything else, including a non-scoped Escape \u2192 `onClose` with reason 'interaction'.\n * returnFocusToReference is a SCOPED-ESCAPE-ONLY affordance; no other close path moves focus.\n *\n * FRAGILITY: closeOnEscape is honored independently of who owns open state. A CONTROLLED consumer that\n * leaves closeOnEscape on but does not itself close on Escape will have focus returned to the reference\n * on a scoped Escape while the consumer-owned open state has not changed \u2014 focus can leave a panel that\n * stays open. Controlled consumers should own Escape (ds-app-picker uses `closeOnEscape: !onKeyDown`).\n */\nconst useFloatingContext = (props: DSHookFloatingContextT.Props = {}) => {\n // Extract unstable callback refs BEFORE useMemoMergePropsWithDefault.\n // useMemoMergePropsWithDefault compares with fast-deep-equal which compares functions by\n // reference; an inline callback from the consumer would invalidate propsWithDefault on every\n // render, which in turn would invalidate the destructured `customOffset` array and re-trigger\n // the position-computation useLayoutEffect on every render \u2192 infinite loop.\n const { onClickOutside, onEscape, onOpen, onClose, externalReferenceElement, boundaryElement, ...stableProps } =\n props;\n\n const propsWithDefault = useMemoMergePropsWithDefault<DSHookFloatingContextT.InternalProps>(\n stableProps,\n defaultProps,\n );\n useValidateTypescriptPropTypes(propsWithDefault, DSFloatingContextPropTypes, 'FloatingContext');\n\n const {\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\n placement,\n customOffset,\n placementOrderPreference,\n externallyControlledIsOpen,\n closeOnEscape,\n returnFocusToReference,\n } = propsWithDefault;\n // Whether the consumer owns the open state. Surfaced on the OpenChange payload so a handler can\n // branch without re-reading props.\n const isControlled = externallyControlledIsOpen !== undefined;\n // Anchor and floating refs\n const [floatingWrapperNode, setFloatingWrapperNode] = React.useState<HTMLElement | null>(null);\n\n // Resolved below (after useResolvedReference) into a stable ref rather than referenced directly,\n // because isFocusWithinFloatingScope / the escape-handling below need to read it from a config\n // object built BEFORE useResolvedReference (and the useHeadlessTooltip call it depends on) runs.\n // A ref sidesteps that ordering constraint; the value it holds is always current by the time\n // anything actually reads it (Escape handling only ever happens after mount, never during this\n // synchronous render pass).\n const triggerElementReferenceRef = React.useRef<Element | null>(null);\n\n // Latest-refs for consumer callbacks (see useLatestRef docs).\n const onClickOutsideRef = useLatestRef(onClickOutside);\n const onEscapeRef = useLatestRef(onEscape);\n const onOpenRef = useLatestRef(onOpen);\n const onCloseRef = useLatestRef(onClose);\n\n // Open/close state \u2014 externally controlled when `externallyControlledIsOpen` is provided.\n const [internalIsOpen, setInternalIsOpen] = React.useState(false);\n const isOpen = useMemo(\n () => (externallyControlledIsOpen !== undefined ? externallyControlledIsOpen : internalIsOpen),\n [externallyControlledIsOpen, internalIsOpen],\n );\n\n // Latest-refs for the reactive VALUES that handleOpen/handleClose read. These handlers are wired\n // into ds-hooks-headless-tooltip's always-on document keydown listener; if a handler's identity\n // changed whenever one of these values changed (isOpen flips on every open/close,\n // floatingWrapperNode on every mount/unmount), that listener would detach + re-attach on every\n // transition. Reading through refs keeps the handlers identity-stable so the listener attaches\n // once. Handlers only ever run post-commit, so the ref always holds the current value when read \u2014\n // same rationale as the consumer-callback refs above.\n const isControlledRef = useLatestRef(isControlled);\n const closeOnEscapeRef = useLatestRef(closeOnEscape);\n const returnFocusToReferenceRef = useLatestRef(returnFocusToReference);\n const floatingWrapperNodeRef = useLatestRef(floatingWrapperNode);\n const isOpenRef = useLatestRef(isOpen);\n\n const handleOpen = React.useCallback<Required<UseHeadlessTooltipConfig>['onOpen']>(\n (event) => {\n setInternalIsOpen(true);\n onOpenRef.current?.({ reason: 'interaction', event, isControlled: isControlledRef.current });\n },\n [onOpenRef, isControlledRef],\n );\n\n // \"In scope\" = the active element is inside the floating (popover) content, or is/inside the\n // reference (trigger) element. Used to decide whether an Escape is this floating context's concern.\n const isFocusWithinFloatingScope = useCallback((): boolean => {\n const active = document.activeElement;\n if (!active) return false;\n if (floatingWrapperNodeRef.current?.contains(active)) return true;\n const reference = triggerElementReferenceRef.current;\n return reference === active || !!reference?.contains(active);\n }, [floatingWrapperNodeRef]);\n\n const handleClose = React.useCallback<Required<UseHeadlessTooltipConfig>['onClose']>(\n (event) => {\n // Read before flipping state: a global Escape press can arrive while this context is\n // already closed (the underlying listener is always-on, see ds-hooks-headless-tooltip), and\n // onEscape must not fire for that \u2014 only a close that was actually transitioning from open.\n const wasOpen = isOpenRef.current;\n setInternalIsOpen(false);\n\n // Escape routing: when the context was open, `closeOnEscape` is set, the event is a keyboard\n // Escape, AND focus was within scope, we route to the dedicated `onEscape` callback (instead\n // of `onClose`) and, if asked, return focus to the reference. Every other close \u2014 including a\n // non-opted-in Escape \u2014 goes through `onClose` with `reason: 'interaction'`. Whether that\n // interaction is meaningful to a controlled consumer is THEIR call: they discriminate on the\n // OpenChange `reason` (interaction vs controlled-flip). We do not decide that for them here.\n // All reactive values are read through refs (see the latest-ref block above) so this handler's\n // identity stays stable and the always-on keydown listener is not re-attached per transition.\n const isScopedEscapeClose =\n wasOpen &&\n closeOnEscapeRef.current &&\n isKeyboardEvent(event) &&\n event.key === 'Escape' &&\n isFocusWithinFloatingScope();\n\n if (isScopedEscapeClose) {\n onEscapeRef.current?.(event);\n // Focus the resolved reference directly rather than relying solely on\n // ds-hooks-headless-tooltip's own focusReferenceOnEscape: that mechanism focuses the\n // hook's *internal* reference element, which stays null whenever this context is\n // configured with `externalReferenceElement` (useResolvedReference makes\n // refs.setReference a no-op in that mode \u2014 see its docstring). triggerElementReferenceRef\n // is always the correctly-resolved element (internal or external), so focusing it here\n // works for both.\n if (returnFocusToReferenceRef.current && triggerElementReferenceRef.current instanceof HTMLElement) {\n triggerElementReferenceRef.current.focus();\n }\n } else {\n onCloseRef.current?.({ reason: 'interaction', event, isControlled: isControlledRef.current });\n }\n },\n [\n isOpenRef,\n closeOnEscapeRef,\n isFocusWithinFloatingScope,\n returnFocusToReferenceRef,\n onCloseRef,\n onEscapeRef,\n isControlledRef,\n ],\n );\n\n // Passed as a thunk (not a pre-computed boolean) into useHeadlessTooltip's config: this config\n // object is built before useResolvedReference runs, so a boolean computed here would be evaluated\n // one render behind the reference element it depends on. Deferring the check to actual\n // Escape-handling time (inside ds-hooks-headless-tooltip) avoids that staleness.\n // Only drives ds-hooks-headless-tooltip's *internal*-reference focus path (see handleClose above\n // for why the externally-resolved reference is focused directly instead).\n const shouldFocusReferenceOnEscape = useCallback(\n () => closeOnEscapeRef.current && returnFocusToReferenceRef.current && isFocusWithinFloatingScope(),\n [closeOnEscapeRef, returnFocusToReferenceRef, isFocusWithinFloatingScope],\n );\n const tooltipHelpersConfig: UseHeadlessTooltipConfig = useMemo(\n () => ({ onOpen: handleOpen, onClose: handleClose, focusReferenceOnEscape: shouldFocusReferenceOnEscape }),\n [handleOpen, handleClose, shouldFocusReferenceOnEscape],\n );\n // Headless tooltip exposes show/hide helpers + manages its own internal state.\n const tooltipHelpers = useHeadlessTooltip(tooltipHelpersConfig);\n const {\n setReferenceElement: setInternalReferenceElement,\n referenceElement: internalReferenceElement,\n hideTooltip,\n showTooltip,\n } = tooltipHelpers;\n\n // Reference element resolution: external takes precedence over internal.\n const { triggerElementReference, setReferenceElement } = useResolvedReference({\n externalReferenceElement,\n internalReferenceElement,\n setInternalReferenceElement,\n });\n // Keep the ref declared above in sync \u2014 see its declaration comment for why this can't just be\n // read directly from isFocusWithinFloatingScope/handleClose without going through a ref first.\n triggerElementReferenceRef.current = triggerElementReference;\n\n // Compute position (skip when closed)\n const { arrowStyles, floatingStyles, hasComputedOnce, updateStyles, debouncedUpdateStyles, mutableUpdateStyles } =\n useComputedPositionStyles({\n triggerElementReference,\n floatingWrapperNode,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n boundaryElement,\n isClose: !isOpen,\n debounceMs: 150,\n });\n\n const floatingResizeOberverConfig = useMemo(\n () => ({ isOpen, floatingWrapperNode, onResize: () => mutableUpdateStyles.current() }),\n [isOpen, floatingWrapperNode, mutableUpdateStyles],\n );\n\n // Re-compute position when the floating element's size changes (e.g. async content).\n useFloatingResizeObserver(floatingResizeOberverConfig);\n\n // Re-compute position when the reference element moves in the viewport.\n const onObservedMovement = React.useCallback(() => {\n if (!isOpen) return;\n debouncedUpdateStyles();\n }, [isOpen, debouncedUpdateStyles]);\n usePositionObserver(triggerElementReference, onObservedMovement);\n\n // Reference fully scrolled out of boundaryElement's visible area (opt-in, paired with\n // boundaryElement): a clamped position alone would leave the floating element stuck at the\n // boundary's edge with nothing left to visually anchor it to. This does NOT close the\n // floating element (isOpen/consumer state is untouched) \u2014 it's purely visual, symmetric with\n // the reappear case, so scrolling the reference back into view shows the same still-open\n // floating element again with no re-click needed.\n const isReferenceHiddenByBoundary = useReferenceHiddenByBoundary({\n reference: triggerElementReference,\n boundaryElement,\n enabled: isOpen && !!boundaryElement,\n });\n\n // Click-outside dismissal (opt-in via `onClickOutside`).\n useFloatingClickOutside({\n isOpen,\n floatingWrapperNode,\n triggerElementReference,\n onClickOutsideRef,\n });\n\n // Route controlled-flip transitions through the SAME onOpen/onClose callbacks, tagged\n // `reason: 'controlled-flip'`. The interaction handlers above emit `reason: 'interaction'` in the\n // event catch phase; these cover the transitions driven by the consumer flipping\n // `externallyControlledIsOpen`, which have no interaction to hang off \u2014 the sanctioned \"sync with\n // external system\" effect (see the hook). One callback, one contract; `reason` discriminates.\n const handleControlledOpen = useCallback(() => {\n onOpenRef.current?.({ reason: 'controlled-flip', isControlled: true });\n }, [onOpenRef]);\n const handleControlledClose = useCallback(() => {\n onCloseRef.current?.({ reason: 'controlled-flip', isControlled: true });\n }, [onCloseRef]);\n useSyntheticEventFromControlledState({\n controlledValue: externallyControlledIsOpen,\n onEnter: handleControlledOpen,\n onExit: handleControlledClose,\n });\n\n // Expose visibility via opacity (NOT visibility:hidden \u2014 that blocks programmatic focus,\n // breaking autoFocus on first-open before the position-computation effect can run).\n // When `externalReferenceElement` is provided, computation runs on the first useLayoutEffect\n // (reference is known synchronously), so the popper becomes interactive in the same commit.\n const computedFloatingStyles = useMemo<React.CSSProperties>(() => {\n const isInteractive = isOpen && hasComputedOnce && !isReferenceHiddenByBoundary;\n return {\n ...floatingStyles,\n opacity: isInteractive ? 1 : 0,\n pointerEvents: isInteractive ? 'auto' : 'none',\n };\n }, [floatingStyles, hasComputedOnce, isOpen, isReferenceHiddenByBoundary]);\n\n const refs = useMemo(\n () => ({\n setReference: setReferenceElement,\n setFloating: setFloatingWrapperNode,\n floating: floatingWrapperNode,\n reference: triggerElementReference,\n }),\n [setReferenceElement, floatingWrapperNode, triggerElementReference],\n );\n\n const handlers = useMemo(\n () => ({\n onMouseEnter: tooltipHelpers.onMouseEnter,\n onMouseLeave: tooltipHelpers.onMouseLeave,\n onFocus: tooltipHelpers.onFocus,\n onBlur: tooltipHelpers.onBlur,\n }),\n [tooltipHelpers.onBlur, tooltipHelpers.onFocus, tooltipHelpers.onMouseEnter, tooltipHelpers.onMouseLeave],\n );\n\n return useMemo(\n () => ({\n refs,\n floatingStyles: computedFloatingStyles,\n handlers,\n isOpen,\n arrowStyles,\n hideTooltip,\n showTooltip,\n context: {\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\n },\n mutableUpdateStyles,\n forceUpdatePosition: updateStyles,\n }),\n [\n refs,\n computedFloatingStyles,\n handlers,\n isOpen,\n arrowStyles,\n hideTooltip,\n showTooltip,\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\n mutableUpdateStyles,\n updateStyles,\n ],\n );\n};\n\nuseFloatingContext.displayName = 'FloatingContext';\nconst UseFloatingContextWithSchema = describe(useFloatingContext);\nUseFloatingContextWithSchema.propTypes =\n DSFloatingContextPropTypes as unknown as ValidationMap<DSHookFloatingContextT.Props>;\n\nexport { useFloatingContext, UseFloatingContextWithSchema };\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["React"]
|
|
7
7
|
}
|
|
@@ -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 useFloatingClickOutside_exports = {};
|
|
30
|
+
__export(useFloatingClickOutside_exports, {
|
|
31
|
+
useFloatingClickOutside: () => useFloatingClickOutside
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(useFloatingClickOutside_exports);
|
|
34
|
+
var React = __toESM(require("react"));
|
|
35
|
+
var import_react = require("react");
|
|
36
|
+
const useFloatingClickOutside = ({
|
|
37
|
+
isOpen,
|
|
38
|
+
floatingWrapperNode,
|
|
39
|
+
triggerElementReference,
|
|
40
|
+
onClickOutsideRef
|
|
41
|
+
}) => {
|
|
42
|
+
(0, import_react.useEffect)(() => {
|
|
43
|
+
if (!isOpen || !floatingWrapperNode || !triggerElementReference) return void 0;
|
|
44
|
+
const listener = (event) => {
|
|
45
|
+
const cb = onClickOutsideRef.current;
|
|
46
|
+
if (!cb) return;
|
|
47
|
+
const target = event.target;
|
|
48
|
+
if (!target) return;
|
|
49
|
+
if (floatingWrapperNode.contains(target) || triggerElementReference.contains(target)) return;
|
|
50
|
+
cb(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
|
+
}, [floatingWrapperNode, triggerElementReference, onClickOutsideRef, isOpen]);
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=useFloatingClickOutside.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/useFloatingClickOutside.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["import { useEffect, type MutableRefObject } from 'react';\n\ninterface UseFloatingClickOutsideParams {\n isOpen: boolean;\n floatingWrapperNode: HTMLElement | null;\n triggerElementReference: Element | null;\n /**\n * Latest-ref of the click-outside callback. Passed as a ref (rather than a value)\n * so consumers can pass inline functions without re-attaching listeners on every render.\n * Use `useLatestRef(onClickOutside)` to construct it.\n */\n onClickOutsideRef: MutableRefObject<((event: MouseEvent | TouchEvent) => void) | undefined>;\n}\n\n/**\n * Attaches mousedown/touchstart listeners on the document that fire when the click target\n * is outside BOTH the floating element and the reference element.\n *\n * Only active when `enabled === true` and both elements exist.\n */\nexport const useFloatingClickOutside = ({\n isOpen,\n floatingWrapperNode,\n triggerElementReference,\n onClickOutsideRef,\n}: UseFloatingClickOutsideParams) => {\n useEffect(() => {\n if (!isOpen || !floatingWrapperNode || !triggerElementReference) return undefined;\n\n const listener = (event: MouseEvent | TouchEvent) => {\n const cb = onClickOutsideRef.current;\n if (!cb) return;\n const target = event.target as Node | null;\n if (!target) return;\n if (floatingWrapperNode.contains(target) || triggerElementReference.contains(target)) return;\n cb(event);\n };\n\n document.addEventListener('mousedown', listener, true);\n document.addEventListener('touchstart', listener, true);\n return () => {\n document.removeEventListener('mousedown', listener, true);\n document.removeEventListener('touchstart', listener, true);\n };\n }, [floatingWrapperNode, triggerElementReference, onClickOutsideRef, isOpen]);\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAiD;AAoB1C,MAAM,0BAA0B,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAqC;AACnC,8BAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,uBAAuB,CAAC,wBAAyB,QAAO;AAExE,UAAM,WAAW,CAAC,UAAmC;AACnD,YAAM,KAAK,kBAAkB;AAC7B,UAAI,CAAC,GAAI;AACT,YAAM,SAAS,MAAM;AACrB,UAAI,CAAC,OAAQ;AACb,UAAI,oBAAoB,SAAS,MAAM,KAAK,wBAAwB,SAAS,MAAM,EAAG;AACtF,SAAG,KAAK;AAAA,IACV;AAEA,aAAS,iBAAiB,aAAa,UAAU,IAAI;AACrD,aAAS,iBAAiB,cAAc,UAAU,IAAI;AACtD,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,UAAU,IAAI;AACxD,eAAS,oBAAoB,cAAc,UAAU,IAAI;AAAA,IAC3D;AAAA,EACF,GAAG,CAAC,qBAAqB,yBAAyB,mBAAmB,MAAM,CAAC;AAC9E;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
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 useFloatingResizeObserver_exports = {};
|
|
30
|
+
__export(useFloatingResizeObserver_exports, {
|
|
31
|
+
useFloatingResizeObserver: () => useFloatingResizeObserver
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(useFloatingResizeObserver_exports);
|
|
34
|
+
var React = __toESM(require("react"));
|
|
35
|
+
var import_react = require("react");
|
|
36
|
+
const useFloatingResizeObserver = ({
|
|
37
|
+
isOpen,
|
|
38
|
+
floatingWrapperNode,
|
|
39
|
+
onResize
|
|
40
|
+
}) => {
|
|
41
|
+
const onResizeRef = (0, import_react.useRef)(onResize);
|
|
42
|
+
onResizeRef.current = onResize;
|
|
43
|
+
(0, import_react.useEffect)(() => {
|
|
44
|
+
if (!isOpen || !floatingWrapperNode) return void 0;
|
|
45
|
+
const observer = new ResizeObserver(() => {
|
|
46
|
+
onResizeRef.current();
|
|
47
|
+
});
|
|
48
|
+
observer.observe(floatingWrapperNode);
|
|
49
|
+
return () => observer.disconnect();
|
|
50
|
+
}, [isOpen, floatingWrapperNode]);
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=useFloatingResizeObserver.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/useFloatingResizeObserver.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["import { useEffect, useRef } from 'react';\n\ninterface UseFloatingResizeObserverParams {\n isOpen: boolean;\n floatingWrapperNode: HTMLElement | null;\n onResize: () => void;\n}\n\n/**\n * Observes the floating element's size and calls `onResize` when its bounding box changes.\n * Used to re-run position computation when the floating content reflows (e.g. async-loaded data).\n */\nexport const useFloatingResizeObserver = ({\n isOpen,\n floatingWrapperNode,\n onResize,\n}: UseFloatingResizeObserverParams) => {\n // Latest-ref so an inline `onResize` does not invalidate the effect on every render.\n // ResizeObserver fires an initial callback on `observe()`, so re-subscribing every render\n // would call `onResize` \u2192 setState \u2192 re-render \u2192 re-subscribe \u2192 infinite loop.\n const onResizeRef = useRef(onResize);\n onResizeRef.current = onResize;\n\n useEffect(() => {\n if (!isOpen || !floatingWrapperNode) return undefined;\n\n const observer = new ResizeObserver(() => {\n onResizeRef.current();\n });\n observer.observe(floatingWrapperNode);\n\n return () => observer.disconnect();\n }, [isOpen, floatingWrapperNode]);\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAkC;AAY3B,MAAM,4BAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AACF,MAAuC;AAIrC,QAAM,kBAAc,qBAAO,QAAQ;AACnC,cAAY,UAAU;AAEtB,8BAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,oBAAqB,QAAO;AAE5C,UAAM,WAAW,IAAI,eAAe,MAAM;AACxC,kBAAY,QAAQ;AAAA,IACtB,CAAC;AACD,aAAS,QAAQ,mBAAmB;AAEpC,WAAO,MAAM,SAAS,WAAW;AAAA,EACnC,GAAG,CAAC,QAAQ,mBAAmB,CAAC;AAClC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
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 useLatestRef_exports = {};
|
|
30
|
+
__export(useLatestRef_exports, {
|
|
31
|
+
useLatestRef: () => useLatestRef
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(useLatestRef_exports);
|
|
34
|
+
var React = __toESM(require("react"));
|
|
35
|
+
var import_react = require("react");
|
|
36
|
+
const useLatestRef = (value) => {
|
|
37
|
+
const ref = (0, import_react.useRef)(value);
|
|
38
|
+
ref.current = value;
|
|
39
|
+
return ref;
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=useLatestRef.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/useLatestRef.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["import { useRef } from 'react';\n\n/**\n * Latest-ref pattern: keeps the value in a ref that's updated on every render.\n * Use this when an effect/listener needs to read the latest value of a prop or callback\n * without including it in the effect's dependency array \u2014 avoids re-attaching listeners\n * (and infinite loops via deep-equal comparators) when consumers pass inline callbacks.\n */\nexport const useLatestRef = <T>(value: T) => {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAuB;AAQhB,MAAM,eAAe,CAAI,UAAa;AAC3C,QAAM,UAAM,qBAAO,KAAK;AACxB,MAAI,UAAU;AACd,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
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 useReferenceHiddenByBoundary_exports = {};
|
|
30
|
+
__export(useReferenceHiddenByBoundary_exports, {
|
|
31
|
+
useReferenceHiddenByBoundary: () => useReferenceHiddenByBoundary
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(useReferenceHiddenByBoundary_exports);
|
|
34
|
+
var React = __toESM(require("react"));
|
|
35
|
+
var import_react = require("react");
|
|
36
|
+
const useReferenceHiddenByBoundary = ({
|
|
37
|
+
reference,
|
|
38
|
+
boundaryElement,
|
|
39
|
+
enabled
|
|
40
|
+
}) => {
|
|
41
|
+
const [isHidden, setIsHidden] = (0, import_react.useState)(false);
|
|
42
|
+
(0, import_react.useEffect)(() => {
|
|
43
|
+
if (!enabled || !reference || !boundaryElement || !window.IntersectionObserver) {
|
|
44
|
+
setIsHidden(false);
|
|
45
|
+
return () => {
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const observer = new IntersectionObserver(
|
|
49
|
+
([entry]) => {
|
|
50
|
+
setIsHidden(!entry.isIntersecting);
|
|
51
|
+
},
|
|
52
|
+
{ root: boundaryElement, threshold: 0 }
|
|
53
|
+
);
|
|
54
|
+
observer.observe(reference);
|
|
55
|
+
return () => observer.disconnect();
|
|
56
|
+
}, [enabled, reference, boundaryElement]);
|
|
57
|
+
return isHidden;
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=useReferenceHiddenByBoundary.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/useReferenceHiddenByBoundary.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["import { useEffect, useState } from 'react';\n\n/**\n * Tracks whether `reference` is currently visible at all within `boundaryElement` \u2014 e.g. a\n * scrollable ancestor the reference lives inside. Returns true the moment the reference scrolls\n * fully out of that boundary's visible area (intersection ratio 0), even though it may still be\n * within the browser viewport; flips back to false as soon as it's visible again. This is what\n * boundaryElement/clamping cannot solve on its own: a clamped floating element just sticks at\n * the boundary's edge, orphaned, once its reference is no longer visible to anchor it to \u2014 the\n * consumer still considers it \"open,\" it should just not be shown while its anchor isn't there.\n *\n * Always false (inert) when boundaryElement is not provided \u2014 this is opt-in, paired with\n * useFloatingContext's boundaryElement prop.\n */\nexport const useReferenceHiddenByBoundary = ({\n reference,\n boundaryElement,\n enabled,\n}: {\n reference: Element | null;\n boundaryElement?: Element | null;\n enabled: boolean;\n}): boolean => {\n const [isHidden, setIsHidden] = useState(false);\n\n // Justified per antipattern_useeffect_misuse.md: this subscribes to a browser observer API\n // (IntersectionObserver), the same external-subscription shape as usePositionObserver.ts in\n // this package \u2014 not derivable via useMemo, since intersection with a scrollable ancestor is\n // asynchronous, browser-computed layout state, not something React can compute from props.\n useEffect(() => {\n if (!enabled || !reference || !boundaryElement || !window.IntersectionObserver) {\n setIsHidden(false);\n return () => {};\n }\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n setIsHidden(!entry.isIntersecting);\n },\n { root: boundaryElement, threshold: 0 },\n );\n observer.observe(reference);\n\n return () => observer.disconnect();\n }, [enabled, reference, boundaryElement]);\n\n return isHidden;\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAoC;AAc7B,MAAM,+BAA+B,CAAC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AACF,MAIe;AACb,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAM9C,8BAAU,MAAM;AACd,QAAI,CAAC,WAAW,CAAC,aAAa,CAAC,mBAAmB,CAAC,OAAO,sBAAsB;AAC9E,kBAAY,KAAK;AACjB,aAAO,MAAM;AAAA,MAAC;AAAA,IAChB;AAEA,UAAM,WAAW,IAAI;AAAA,MACnB,CAAC,CAAC,KAAK,MAAM;AACX,oBAAY,CAAC,MAAM,cAAc;AAAA,MACnC;AAAA,MACA,EAAE,MAAM,iBAAiB,WAAW,EAAE;AAAA,IACxC;AACA,aAAS,QAAQ,SAAS;AAE1B,WAAO,MAAM,SAAS,WAAW;AAAA,EACnC,GAAG,CAAC,SAAS,WAAW,eAAe,CAAC;AAExC,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
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 useResolvedReference_exports = {};
|
|
30
|
+
__export(useResolvedReference_exports, {
|
|
31
|
+
useResolvedReference: () => useResolvedReference
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(useResolvedReference_exports);
|
|
34
|
+
var React = __toESM(require("react"));
|
|
35
|
+
var import_react = require("react");
|
|
36
|
+
const useResolvedReference = ({
|
|
37
|
+
externalReferenceElement,
|
|
38
|
+
internalReferenceElement,
|
|
39
|
+
setInternalReferenceElement
|
|
40
|
+
}) => {
|
|
41
|
+
const hasExternalReference = externalReferenceElement !== void 0;
|
|
42
|
+
const triggerElementReference = hasExternalReference ? externalReferenceElement : internalReferenceElement;
|
|
43
|
+
const setReferenceElement = (0, import_react.useCallback)(
|
|
44
|
+
(el) => {
|
|
45
|
+
if (hasExternalReference) return;
|
|
46
|
+
setInternalReferenceElement(el);
|
|
47
|
+
},
|
|
48
|
+
[hasExternalReference, setInternalReferenceElement]
|
|
49
|
+
);
|
|
50
|
+
return { triggerElementReference, setReferenceElement };
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=useResolvedReference.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/useResolvedReference.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["import { useCallback } from 'react';\n\ninterface UseResolvedReferenceParams {\n externalReferenceElement: Element | null | undefined;\n internalReferenceElement: Element | null;\n setInternalReferenceElement: (el: Element | null) => void;\n}\n\n/**\n * Resolves the active reference element for the floating context.\n *\n * - When `externalReferenceElement` is provided (anything other than `undefined`, including `null`),\n * it is used as the source of truth. `setReference` becomes a no-op so consumers that mistakenly\n * call `refs.setReference()` don't desynchronize the two sources.\n * - Otherwise the internally-managed state is used, populated by the consumer via `refs.setReference()`\n * (typically as a callback ref: `innerRef={refs.setReference}`).\n */\nexport const useResolvedReference = ({\n externalReferenceElement,\n internalReferenceElement,\n setInternalReferenceElement,\n}: UseResolvedReferenceParams) => {\n const hasExternalReference = externalReferenceElement !== undefined;\n const triggerElementReference = hasExternalReference ? externalReferenceElement : internalReferenceElement;\n\n const setReferenceElement = useCallback(\n (el: Element | null) => {\n if (hasExternalReference) return;\n setInternalReferenceElement(el);\n },\n [hasExternalReference, setInternalReferenceElement],\n );\n\n return { triggerElementReference, setReferenceElement };\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAA4B;AAiBrB,MAAM,uBAAuB,CAAC;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AACF,MAAkC;AAChC,QAAM,uBAAuB,6BAA6B;AAC1D,QAAM,0BAA0B,uBAAuB,2BAA2B;AAElF,QAAM,0BAAsB;AAAA,IAC1B,CAAC,OAAuB;AACtB,UAAI,qBAAsB;AAC1B,kCAA4B,EAAE;AAAA,IAChC;AAAA,IACA,CAAC,sBAAsB,2BAA2B;AAAA,EACpD;AAEA,SAAO,EAAE,yBAAyB,oBAAoB;AACxD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|