@elliemae/ds-floating-context 3.55.0-next.9 → 3.55.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/dist/cjs/DSFloatingContext.js +49 -50
  2. package/dist/cjs/DSFloatingContext.js.map +2 -2
  3. package/dist/cjs/useComputedPositionStyles.js +48 -68
  4. package/dist/cjs/useComputedPositionStyles.js.map +3 -3
  5. package/dist/esm/DSFloatingContext.js +50 -51
  6. package/dist/esm/DSFloatingContext.js.map +2 -2
  7. package/dist/esm/useComputedPositionStyles.js +48 -68
  8. package/dist/esm/useComputedPositionStyles.js.map +3 -3
  9. package/dist/types/DSFloatingContext.d.ts +1 -2
  10. package/dist/types/parts/FloatingWrapper/config/useFloatingWrapper.d.ts +1 -1
  11. package/dist/types/useComputedPositionStyles.d.ts +23 -6
  12. package/package.json +7 -7
  13. package/dist/cjs/typescript-testing/typescript-floating-context-valid.js +0 -94
  14. package/dist/cjs/typescript-testing/typescript-floating-context-valid.js.map +0 -7
  15. package/dist/esm/typescript-testing/typescript-floating-context-valid.js +0 -71
  16. package/dist/esm/typescript-testing/typescript-floating-context-valid.js.map +0 -7
  17. package/dist/types/tests/FloatingContext.data-testid.test.d.ts +0 -1
  18. package/dist/types/tests/FloatingContext.event.test.d.ts +0 -1
  19. package/dist/types/tests/FloatingContext.exports.test.d.ts +0 -1
  20. package/dist/types/tests/FloatingContext.get-owner-props.test.d.ts +0 -1
  21. package/dist/types/typescript-testing/typescript-floating-context-valid.d.ts +0 -1
  22. /package/dist/types/tests/{FloatingContext.a11y.test.d.ts → FloatingContext.test.d.ts} +0 -0
  23. /package/dist/types/tests/{playwright/FloatingContext.test.playwright.d.ts → FloatingContext.test.playwright.d.ts} +0 -0
@@ -56,66 +56,67 @@ const useFloatingContext = (props = {}) => {
56
56
  externallyControlledIsOpen
57
57
  } = propsWithDefault;
58
58
  const [internalIsOpen, setInternalIsOpen] = import_react.default.useState(false);
59
- const isOpen = (0, import_react.useMemo)(
60
- () => externallyControlledIsOpen !== void 0 ? externallyControlledIsOpen : internalIsOpen,
61
- [externallyControlledIsOpen, internalIsOpen]
62
- );
63
- const handleOpen = import_react.default.useCallback(() => {
59
+ const isOpenSourceOfTruth = (0, import_react.useMemo)(() => {
60
+ if (externallyControlledIsOpen !== void 0) return externallyControlledIsOpen;
61
+ return internalIsOpen;
62
+ }, [externallyControlledIsOpen, internalIsOpen]);
63
+ const overChargedOnOpen = import_react.default.useCallback(() => {
64
64
  setInternalIsOpen(true);
65
65
  onOpen?.();
66
66
  }, [onOpen]);
67
- const handleClose = import_react.default.useCallback(() => {
67
+ const overChargedOnClose = import_react.default.useCallback(() => {
68
68
  setInternalIsOpen(false);
69
69
  onClose?.();
70
70
  }, [onClose]);
71
- const tooltipHelpers = (0, import_ds_hooks_headless_tooltip.useHeadlessTooltip)({ onOpen: handleOpen, onClose: handleClose });
71
+ const tooltipHelpers = (0, import_ds_hooks_headless_tooltip.useHeadlessTooltip)({ onOpen: overChargedOnOpen, onClose: overChargedOnClose });
72
72
  const { setReferenceElement, hideTooltip, showTooltip } = tooltipHelpers;
73
- const [reference, setReferenceInternal] = import_react.default.useState(null);
73
+ const [reference, _setReference] = import_react.default.useState(null);
74
74
  const [floating, setFloating] = import_react.default.useState(null);
75
- const { arrowStyles, floatingStyles, hasComputedOnce, updateStyles, debouncedUpdateStyles, mutableUpdateStyles } = (0, import_useComputedPositionStyles.useComputedPositionStyles)({
75
+ const [workaroundToEnsureAPositionWasCalculatedIfOpen, setWorkaroundToEnsureAPositionWasCalculatedIfOpen] = import_react.default.useState(0);
76
+ const { arrowStyles, floatingStyles, mutableUpdateStyles, debouncedUpdateStyles } = (0, import_useComputedPositionStyles.useComputedPositionStyles)({
76
77
  reference,
77
78
  floating,
78
79
  placement,
79
80
  placementOrderPreference,
80
81
  customOffset,
81
- withoutPortal,
82
- preventComputing: !isOpen,
83
- debounceMs: 150
82
+ withoutPortal
84
83
  });
85
84
  (0, import_react.useEffect)(() => {
86
- if (!isOpen) return;
87
- const observers = [];
88
- if (floating) {
89
- const roFloating = new ResizeObserver(() => {
90
- mutableUpdateStyles.current();
91
- requestAnimationFrame(() => mutableUpdateStyles.current());
85
+ requestAnimationFrame(() => {
86
+ mutableUpdateStyles?.current();
87
+ });
88
+ }, [reference, mutableUpdateStyles]);
89
+ const updatePosOnIntersection = import_react.default.useCallback(() => {
90
+ if (reference) {
91
+ requestAnimationFrame(() => {
92
+ debouncedUpdateStyles();
92
93
  });
93
- roFloating.observe(floating);
94
- observers.push(roFloating);
95
94
  }
96
- if (reference) {
97
- const roRef = new ResizeObserver(() => {
98
- mutableUpdateStyles.current();
95
+ }, [reference, debouncedUpdateStyles]);
96
+ (0, import_positionObserver.usePositionObserver)(reference, updatePosOnIntersection);
97
+ (0, import_react.useEffect)(() => {
98
+ requestAnimationFrame(() => {
99
+ mutableUpdateStyles?.current();
100
+ });
101
+ }, [isOpenSourceOfTruth, mutableUpdateStyles]);
102
+ const { visibility } = floatingStyles;
103
+ const needsToCalculateBecauseStillInvisibleWhenShouldBeOpen = isOpenSourceOfTruth && visibility === "hidden";
104
+ (0, import_react.useEffect)(() => {
105
+ if (needsToCalculateBecauseStillInvisibleWhenShouldBeOpen) {
106
+ mutableUpdateStyles?.current();
107
+ requestAnimationFrame(() => {
108
+ setWorkaroundToEnsureAPositionWasCalculatedIfOpen((o) => o + 1);
99
109
  });
100
- roRef.observe(reference);
101
- observers.push(roRef);
102
110
  }
103
- return () => observers.forEach((o) => o.disconnect());
104
- }, [isOpen, floating, reference, mutableUpdateStyles]);
105
- const onObservedMovement = import_react.default.useCallback(() => {
106
- if (!isOpen) return;
107
- debouncedUpdateStyles();
108
- }, [isOpen, debouncedUpdateStyles]);
109
- (0, import_positionObserver.usePositionObserver)(reference, onObservedMovement);
110
- const computedFloatingStyles = (0, import_react.useMemo)(
111
- () => ({
112
- ...floatingStyles,
113
- visibility: isOpen && hasComputedOnce ? "visible" : "hidden"
114
- }),
115
- [floatingStyles, isOpen, hasComputedOnce]
116
- );
117
- const setReference = (0, import_ds_system.mergeRefs)(setReferenceInternal, setReferenceElement);
118
- const refs = (0, import_react.useMemo)(
111
+ }, [
112
+ needsToCalculateBecauseStillInvisibleWhenShouldBeOpen,
113
+ mutableUpdateStyles,
114
+ // this dependency is the point of this useEffect
115
+ // it will keep triggering until the position is calculated if it needs to be calculated
116
+ workaroundToEnsureAPositionWasCalculatedIfOpen
117
+ ]);
118
+ const setReference = (0, import_ds_system.mergeRefs)(_setReference, setReferenceElement);
119
+ const refs = import_react.default.useMemo(
119
120
  () => ({
120
121
  setReference,
121
122
  setFloating,
@@ -124,7 +125,7 @@ const useFloatingContext = (props = {}) => {
124
125
  }),
125
126
  [setReference, floating, reference]
126
127
  );
127
- const handlers = (0, import_react.useMemo)(
128
+ const handlers = import_react.default.useMemo(
128
129
  () => ({
129
130
  onMouseEnter: tooltipHelpers.onMouseEnter,
130
131
  onMouseLeave: tooltipHelpers.onMouseLeave,
@@ -136,9 +137,9 @@ const useFloatingContext = (props = {}) => {
136
137
  return (0, import_react.useMemo)(
137
138
  () => ({
138
139
  refs,
139
- floatingStyles: computedFloatingStyles,
140
+ floatingStyles,
140
141
  handlers,
141
- isOpen,
142
+ isOpen: isOpenSourceOfTruth,
142
143
  arrowStyles,
143
144
  hideTooltip,
144
145
  showTooltip,
@@ -148,14 +149,13 @@ const useFloatingContext = (props = {}) => {
148
149
  portalDOMContainer,
149
150
  animationDuration
150
151
  },
151
- mutableUpdateStyles,
152
- forceUpdatePosition: updateStyles
152
+ mutableUpdateStyles
153
153
  }),
154
154
  [
155
155
  refs,
156
- computedFloatingStyles,
156
+ floatingStyles,
157
157
  handlers,
158
- isOpen,
158
+ isOpenSourceOfTruth,
159
159
  arrowStyles,
160
160
  hideTooltip,
161
161
  showTooltip,
@@ -163,8 +163,7 @@ const useFloatingContext = (props = {}) => {
163
163
  withoutAnimation,
164
164
  portalDOMContainer,
165
165
  animationDuration,
166
- mutableUpdateStyles,
167
- updateStyles
166
+ mutableUpdateStyles
168
167
  ]
169
168
  );
170
169
  };
@@ -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 { mergeRefs } from '@elliemae/ds-system';\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, hideTooltip, showTooltip } = tooltipHelpers;\n\n // Anchor and floating refs\n const [reference, setReferenceInternal] = React.useState<Element | null>(null);\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,\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 // inmediato + siguiente frame para asentar\n mutableUpdateStyles.current();\n requestAnimationFrame(() => mutableUpdateStyles.current());\n });\n roFloating.observe(floating);\n observers.push(roFloating);\n }\n\n if (reference) {\n const roRef = new ResizeObserver(() => {\n mutableUpdateStyles.current();\n });\n roRef.observe(reference);\n observers.push(roRef);\n }\n\n return () => observers.forEach((o) => o.disconnect());\n }, [isOpen, floating, reference, mutableUpdateStyles]);\n\n const onObservedMovement = React.useCallback(() => {\n if (!isOpen) return;\n debouncedUpdateStyles();\n }, [isOpen, debouncedUpdateStyles]);\n usePositionObserver(reference, 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, isOpen, hasComputedOnce],\n );\n\n const setReference = mergeRefs(setReferenceInternal, setReferenceElement);\n\n const refs = useMemo(\n () => ({\n setReference,\n setFloating,\n floating,\n reference,\n }),\n [setReference, floating, reference],\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;ADGvB,mBAA0C;AAC1C,8BAKO;AACP,uCAAmC;AACnC,uBAA0B;AAE1B,mCAAyD;AACzD,uCAA0C;AAC1C,8BAAoC;AAEpC,MAAM,qBAAqB,CAAC,QAAsC,CAAC,MAAM;AACvE,QAAM,uBAAmB,sDAAmE,OAAO,yCAAY;AAC/G,8DAA+B,kBAAkB,yDAA4B,iBAAiB;AAE9F,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,aAAAA,QAAM,SAAkB,KAAK;AACzE,QAAM,aAAS;AAAA,IACb,MAAO,+BAA+B,SAAY,6BAA6B;AAAA,IAC/E,CAAC,4BAA4B,cAAc;AAAA,EAC7C;AAEA,QAAM,aAAa,aAAAA,QAAM,YAAY,MAAM;AACzC,sBAAkB,IAAI;AACtB,aAAS;AAAA,EACX,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,cAAc,aAAAA,QAAM,YAAY,MAAM;AAC1C,sBAAkB,KAAK;AACvB,cAAU;AAAA,EACZ,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,qBAAiB,qDAAmB,EAAE,QAAQ,YAAY,SAAS,YAAY,CAAC;AACtF,QAAM,EAAE,qBAAqB,aAAa,YAAY,IAAI;AAG1D,QAAM,CAAC,WAAW,oBAAoB,IAAI,aAAAA,QAAM,SAAyB,IAAI;AAC7E,QAAM,CAAC,UAAU,WAAW,IAAI,aAAAA,QAAM,SAA6B,IAAI;AAGvE,QAAM,EAAE,aAAa,gBAAgB,iBAAiB,cAAc,uBAAuB,oBAAoB,QAC7G,4DAA0B;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB,CAAC;AAAA,IACnB,YAAY;AAAA,EACd,CAAC;AAEH,8BAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,YAA8B,CAAC;AAErC,QAAI,UAAU;AACZ,YAAM,aAAa,IAAI,eAAe,MAAM;AAE1C,4BAAoB,QAAQ;AAC5B,8BAAsB,MAAM,oBAAoB,QAAQ,CAAC;AAAA,MAC3D,CAAC;AACD,iBAAW,QAAQ,QAAQ;AAC3B,gBAAU,KAAK,UAAU;AAAA,IAC3B;AAEA,QAAI,WAAW;AACb,YAAM,QAAQ,IAAI,eAAe,MAAM;AACrC,4BAAoB,QAAQ;AAAA,MAC9B,CAAC;AACD,YAAM,QAAQ,SAAS;AACvB,gBAAU,KAAK,KAAK;AAAA,IACtB;AAEA,WAAO,MAAM,UAAU,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;AAAA,EACtD,GAAG,CAAC,QAAQ,UAAU,WAAW,mBAAmB,CAAC;AAErD,QAAM,qBAAqB,aAAAA,QAAM,YAAY,MAAM;AACjD,QAAI,CAAC,OAAQ;AACb,0BAAsB;AAAA,EACxB,GAAG,CAAC,QAAQ,qBAAqB,CAAC;AAClC,mDAAoB,WAAW,kBAAkB;AAGjD,QAAM,6BAAyB;AAAA,IAC7B,OAAO;AAAA,MACL,GAAG;AAAA,MACH,YAAY,UAAU,kBAAkB,YAAY;AAAA,IACtD;AAAA,IACA,CAAC,gBAAgB,QAAQ,eAAe;AAAA,EAC1C;AAEA,QAAM,mBAAe,4BAAU,sBAAsB,mBAAmB;AAExE,QAAM,WAAO;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,cAAc,UAAU,SAAS;AAAA,EACpC;AAEA,QAAM,eAAW;AAAA,IACf,OAAO;AAAA,MACL,cAAc,eAAe;AAAA,MAC7B,cAAc,eAAe;AAAA,MAC7B,SAAS,eAAe;AAAA,MACxB,QAAQ,eAAe;AAAA,IACzB;AAAA,IACA,CAAC,eAAe,QAAQ,eAAe,SAAS,eAAe,cAAc,eAAe,YAAY;AAAA,EAC1G;AAEA,aAAO;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA,gBAAgB;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACA,qBAAqB;AAAA,IACvB;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,mBAAmB,cAAc;AACjC,MAAM,mCAA+B,kCAAS,kBAAkB;AAChE,6BAA6B,YAC3B;",
4
+ "sourcesContent": ["/* eslint-disable max-statements */\nimport React, { useEffect, useMemo } 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 { mergeRefs } from '@elliemae/ds-system';\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 isOpenSourceOfTruth = useMemo(() => {\n if (externallyControlledIsOpen !== undefined) return externallyControlledIsOpen;\n return internalIsOpen;\n }, [externallyControlledIsOpen, internalIsOpen]);\n\n const overChargedOnOpen = React.useCallback(() => {\n setInternalIsOpen(true);\n onOpen?.();\n }, [onOpen]);\n const overChargedOnClose = React.useCallback(() => {\n setInternalIsOpen(false);\n onClose?.();\n }, [onClose]);\n const tooltipHelpers = useHeadlessTooltip({ onOpen: overChargedOnOpen, onClose: overChargedOnClose });\n const { setReferenceElement, hideTooltip, showTooltip } = tooltipHelpers;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n const [reference, _setReference] = React.useState<Element | null>(null);\n const [floating, setFloating] = React.useState<HTMLElement | null>(null);\n const [workaroundToEnsureAPositionWasCalculatedIfOpen, setWorkaroundToEnsureAPositionWasCalculatedIfOpen] =\n React.useState<number>(0);\n\n const { arrowStyles, floatingStyles, mutableUpdateStyles, debouncedUpdateStyles } = useComputedPositionStyles({\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n });\n\n // calculate position on mount\n // AND everytime the reference (which is actually immutable because it's stored in a React.useState)\n // changes\n useEffect(() => {\n requestAnimationFrame(() => {\n mutableUpdateStyles?.current();\n });\n // the dependency array is equal to being empty because mutableUpdateStyles is a ref.\n // this is effectively an \"on mount\"\n }, [reference, mutableUpdateStyles]);\n\n // use intersection observer to detect when the position of the reference changes needing to recalculate the position\n const updatePosOnIntersection = React.useCallback(() => {\n if (reference) {\n requestAnimationFrame(() => {\n debouncedUpdateStyles();\n });\n }\n }, [reference, debouncedUpdateStyles]);\n usePositionObserver(reference, updatePosOnIntersection);\n\n // when we detect that the flag about it being open/closed changes\n // we refresh the position of the tooltip calculation\n useEffect(() => {\n requestAnimationFrame(() => {\n mutableUpdateStyles?.current();\n });\n }, [isOpenSourceOfTruth, mutableUpdateStyles]);\n\n // this is a workaround to ensure that the position is calculated at least once when the tooltip is open\n const { visibility } = floatingStyles;\n const needsToCalculateBecauseStillInvisibleWhenShouldBeOpen = isOpenSourceOfTruth && visibility === 'hidden';\n useEffect(() => {\n if (needsToCalculateBecauseStillInvisibleWhenShouldBeOpen) {\n mutableUpdateStyles?.current();\n requestAnimationFrame(() => {\n setWorkaroundToEnsureAPositionWasCalculatedIfOpen((o) => o + 1);\n });\n }\n }, [\n needsToCalculateBecauseStillInvisibleWhenShouldBeOpen,\n mutableUpdateStyles,\n // this dependency is the point of this useEffect\n // it will keep triggering until the position is calculated if it needs to be calculated\n workaroundToEnsureAPositionWasCalculatedIfOpen,\n ]);\n\n const setReference = mergeRefs(_setReference, setReferenceElement);\n const refs = React.useMemo(\n () => ({\n setReference,\n setFloating,\n floating,\n reference,\n }),\n [setReference, floating, reference],\n );\n\n const handlers = React.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,\n handlers,\n isOpen: isOpenSourceOfTruth,\n arrowStyles,\n hideTooltip,\n showTooltip,\n context: {\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\n },\n mutableUpdateStyles,\n }),\n [\n refs,\n floatingStyles,\n handlers,\n isOpenSourceOfTruth,\n arrowStyles,\n hideTooltip,\n showTooltip,\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\n mutableUpdateStyles,\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
  }
@@ -32,86 +32,66 @@ __export(useComputedPositionStyles_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(useComputedPositionStyles_exports);
34
34
  var React = __toESM(require("react"));
35
- var import_react = require("react");
35
+ var import_react = __toESM(require("react"));
36
36
  var import_lodash_es = require("lodash-es");
37
37
  var import_computePosition = require("./utils/computePosition.js");
38
38
  const useComputedPositionStyles = (config) => {
39
- const {
39
+ const { reference, floating, placement, placementOrderPreference, customOffset, withoutPortal, preventComputing } = config;
40
+ const [arrowStyles, setArrowStyles] = (0, import_react.useState)({
41
+ style: { left: 0 },
42
+ placement: "top"
43
+ });
44
+ const [floatingStyles, setFloatingStyles] = (0, import_react.useState)({
45
+ position: "absolute",
46
+ zIndex: 3e3,
47
+ top: 0,
48
+ left: 0,
49
+ visibility: "hidden"
50
+ });
51
+ const canComputePosition = reference !== null && floating !== null;
52
+ const canAndShouldComputePosition = canComputePosition && preventComputing !== true;
53
+ const updateStyles = import_react.default.useCallback(() => {
54
+ if (canAndShouldComputePosition) {
55
+ const { coordsStyle, finalPlacement, coordsArrow } = (0, import_computePosition.computePosition)({
56
+ reference,
57
+ floating,
58
+ placement,
59
+ placementOrderPreference,
60
+ customOffset,
61
+ withoutPortal
62
+ });
63
+ setFloatingStyles({
64
+ position: "absolute",
65
+ zIndex: 3e3,
66
+ ...coordsStyle
67
+ });
68
+ setArrowStyles({ style: coordsArrow, placement: finalPlacement });
69
+ }
70
+ }, [
71
+ canAndShouldComputePosition,
40
72
  reference,
41
73
  floating,
42
74
  placement,
43
75
  placementOrderPreference,
44
76
  customOffset,
45
- withoutPortal,
46
- preventComputing = false,
47
- debounceMs = 150
48
- } = config;
49
- const [arrowStyles, setArrowStyles] = (0, import_react.useState)({ style: { left: 0 }, placement: "top" });
50
- const [floatingStyles, setFloatingStyles] = (0, import_react.useState)({
51
- position: "absolute",
52
- zIndex: 3e3,
53
- visibility: "hidden",
54
- willChange: "top,left"
55
- // hint to browser for smoother positioning updates
56
- });
57
- const [hasComputedOnce, setHasComputedOnce] = (0, import_react.useState)(false);
58
- const canCompute = reference !== null && floating !== null && !preventComputing;
59
- const updateStyles = (0, import_react.useCallback)(() => {
60
- if (!canCompute) return;
61
- const { coordsStyle, finalPlacement, coordsArrow } = (0, import_computePosition.computePosition)({
62
- reference,
63
- floating,
64
- placement,
65
- placementOrderPreference,
66
- customOffset,
67
- withoutPortal
68
- });
69
- setFloatingStyles((prev) => ({
77
+ withoutPortal
78
+ ]);
79
+ const mutableUpdateStyles = import_react.default.useRef(updateStyles);
80
+ mutableUpdateStyles.current = updateStyles;
81
+ const debouncedUpdateStyles = import_react.default.useMemo(() => (0, import_lodash_es.debounce)(() => mutableUpdateStyles.current(), 100), []);
82
+ const resetStyles = import_react.default.useCallback(() => {
83
+ setFloatingStyles({
70
84
  position: "absolute",
71
85
  zIndex: 3e3,
72
- ...prev,
73
- ...coordsStyle
74
- }));
75
- setArrowStyles({ style: coordsArrow, placement: finalPlacement });
76
- setHasComputedOnce(true);
77
- }, [canCompute, reference, floating, placement, placementOrderPreference, customOffset, withoutPortal]);
78
- const mutableUpdateStyles = (0, import_react.useRef)(updateStyles);
79
- mutableUpdateStyles.current = updateStyles;
80
- const debouncedUpdateStyles = (0, import_react.useMemo)(() => {
81
- const d = (0, import_lodash_es.debounce)(() => mutableUpdateStyles.current(), debounceMs);
82
- return d;
83
- }, [debounceMs]);
84
- (0, import_react.useLayoutEffect)(
85
- () => () => {
86
- debouncedUpdateStyles.cancel();
87
- },
88
- [debouncedUpdateStyles]
89
- );
90
- (0, import_react.useLayoutEffect)(() => {
91
- if (canCompute) {
92
- mutableUpdateStyles.current();
93
- }
94
- }, [canCompute, reference, floating, placement, placementOrderPreference, customOffset, withoutPortal]);
95
- const forceUpdatePosition = (0, import_react.useCallback)(() => {
96
- mutableUpdateStyles.current();
97
- }, []);
98
- const resetVisibilityOnly = (0, import_react.useCallback)(() => {
99
- setFloatingStyles((prev) => ({
100
- ...prev,
86
+ top: 0,
87
+ left: 0,
101
88
  visibility: "hidden"
102
- }));
89
+ });
90
+ setArrowStyles({ style: { left: 0 }, placement: "top" });
103
91
  }, []);
104
- return (0, import_react.useMemo)(
105
- () => ({
106
- arrowStyles,
107
- floatingStyles,
108
- hasComputedOnce,
109
- updateStyles: forceUpdatePosition,
110
- debouncedUpdateStyles,
111
- mutableUpdateStyles,
112
- resetVisibilityOnly
113
- }),
114
- [arrowStyles, floatingStyles, hasComputedOnce, forceUpdatePosition, debouncedUpdateStyles, resetVisibilityOnly]
92
+ return import_react.default.useMemo(
93
+ () => ({ arrowStyles, floatingStyles, updateStyles, debouncedUpdateStyles, mutableUpdateStyles, resetStyles }),
94
+ [arrowStyles, floatingStyles, updateStyles, debouncedUpdateStyles, resetStyles]
115
95
  );
116
96
  };
117
97
  //# sourceMappingURL=useComputedPositionStyles.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/useComputedPositionStyles.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable max-statements */\nimport { useLayoutEffect, useMemo, useRef, useState, useCallback } from 'react';\nimport { debounce } from 'lodash-es';\nimport { type CSSProperties } from 'styled-components';\nimport { computePosition } from './utils/computePosition.js';\nimport type { DSHookFloatingContextT } from './react-desc-prop-types.js';\nimport type { PopoverArrowT } from './parts/PopoverArrow.js';\n\ntype UseComputedPositionStylesT = {\n /** Prevent computing when closed (optimization + avoids unnecessary frames) */\n preventComputing?: boolean;\n reference: Element | null;\n floating: HTMLElement | null;\n placement: DSHookFloatingContextT.PopperPlacementsT;\n placementOrderPreference?: DSHookFloatingContextT.PopperPlacementsT[];\n customOffset: [number, number];\n withoutPortal: boolean;\n /** Debounce ms for scroll/resize/observer events */\n debounceMs?: number;\n};\n\nexport const useComputedPositionStyles = (config: UseComputedPositionStylesT) => {\n const {\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n preventComputing = false,\n debounceMs = 150,\n } = config;\n\n const [arrowStyles, setArrowStyles] = useState<PopoverArrowT>({ style: { left: 0 }, placement: 'top' });\n\n // Important: do not initialize top/left to (0,0); keep hidden until the first computation\n const [floatingStyles, setFloatingStyles] = useState<CSSProperties>({\n position: 'absolute',\n zIndex: 3000,\n visibility: 'hidden',\n willChange: 'top,left', // hint to browser for smoother positioning updates\n });\n\n const [hasComputedOnce, setHasComputedOnce] = useState(false);\n\n const canCompute = reference !== null && floating !== null && !preventComputing;\n\n const updateStyles = useCallback(() => {\n if (!canCompute) return;\n\n const { coordsStyle, finalPlacement, coordsArrow } = computePosition({\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n });\n\n // Do not touch visibility here; it is managed outside depending on open/hasComputedOnce\n setFloatingStyles((prev) => ({\n position: 'absolute',\n zIndex: 3000,\n ...prev,\n ...coordsStyle,\n }));\n setArrowStyles({ style: coordsArrow, placement: finalPlacement });\n setHasComputedOnce(true);\n }, [canCompute, reference, floating, placement, placementOrderPreference, customOffset, withoutPortal]);\n\n // Store latest update function in a ref to keep debounced stable\n const mutableUpdateStyles = useRef(updateStyles);\n mutableUpdateStyles.current = updateStyles;\n\n const debouncedUpdateStyles = useMemo(() => {\n const d = debounce(() => mutableUpdateStyles.current(), debounceMs);\n return d;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debounceMs]);\n\n // Clean up debounce on unmount\n useLayoutEffect(\n () => () => {\n debouncedUpdateStyles.cancel();\n },\n [debouncedUpdateStyles],\n );\n\n // Recalculate BEFORE paint when dependencies change\n useLayoutEffect(() => {\n if (canCompute) {\n mutableUpdateStyles.current();\n }\n }, [canCompute, reference, floating, placement, placementOrderPreference, customOffset, withoutPortal]);\n\n const forceUpdatePosition = useCallback(() => {\n mutableUpdateStyles.current();\n }, []);\n\n // Do not reset coordinates when closing; just hide\n const resetVisibilityOnly = useCallback(() => {\n setFloatingStyles((prev) => ({\n ...prev,\n visibility: 'hidden',\n }));\n }, []);\n\n return useMemo(\n () => ({\n arrowStyles,\n floatingStyles,\n hasComputedOnce,\n updateStyles: forceUpdatePosition,\n debouncedUpdateStyles,\n mutableUpdateStyles,\n resetVisibilityOnly,\n }),\n [arrowStyles, floatingStyles, hasComputedOnce, forceUpdatePosition, debouncedUpdateStyles, resetVisibilityOnly],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADCvB,mBAAwE;AACxE,uBAAyB;AAEzB,6BAAgC;AAiBzB,MAAM,4BAA4B,CAAC,WAAuC;AAC/E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,IACnB,aAAa;AAAA,EACf,IAAI;AAEJ,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAwB,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,MAAM,CAAC;AAGtG,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,uBAAwB;AAAA,IAClE,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,YAAY;AAAA;AAAA,EACd,CAAC;AAED,QAAM,CAAC,iBAAiB,kBAAkB,QAAI,uBAAS,KAAK;AAE5D,QAAM,aAAa,cAAc,QAAQ,aAAa,QAAQ,CAAC;AAE/D,QAAM,mBAAe,0BAAY,MAAM;AACrC,QAAI,CAAC,WAAY;AAEjB,UAAM,EAAE,aAAa,gBAAgB,YAAY,QAAI,wCAAgB;AAAA,MACnE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAGD,sBAAkB,CAAC,UAAU;AAAA,MAC3B,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,GAAG;AAAA,MACH,GAAG;AAAA,IACL,EAAE;AACF,mBAAe,EAAE,OAAO,aAAa,WAAW,eAAe,CAAC;AAChE,uBAAmB,IAAI;AAAA,EACzB,GAAG,CAAC,YAAY,WAAW,UAAU,WAAW,0BAA0B,cAAc,aAAa,CAAC;AAGtG,QAAM,0BAAsB,qBAAO,YAAY;AAC/C,sBAAoB,UAAU;AAE9B,QAAM,4BAAwB,sBAAQ,MAAM;AAC1C,UAAM,QAAI,2BAAS,MAAM,oBAAoB,QAAQ,GAAG,UAAU;AAClE,WAAO;AAAA,EAET,GAAG,CAAC,UAAU,CAAC;AAGf;AAAA,IACE,MAAM,MAAM;AACV,4BAAsB,OAAO;AAAA,IAC/B;AAAA,IACA,CAAC,qBAAqB;AAAA,EACxB;AAGA,oCAAgB,MAAM;AACpB,QAAI,YAAY;AACd,0BAAoB,QAAQ;AAAA,IAC9B;AAAA,EACF,GAAG,CAAC,YAAY,WAAW,UAAU,WAAW,0BAA0B,cAAc,aAAa,CAAC;AAEtG,QAAM,0BAAsB,0BAAY,MAAM;AAC5C,wBAAoB,QAAQ;AAAA,EAC9B,GAAG,CAAC,CAAC;AAGL,QAAM,0BAAsB,0BAAY,MAAM;AAC5C,sBAAkB,CAAC,UAAU;AAAA,MAC3B,GAAG;AAAA,MACH,YAAY;AAAA,IACd,EAAE;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,aAAO;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,aAAa,gBAAgB,iBAAiB,qBAAqB,uBAAuB,mBAAmB;AAAA,EAChH;AACF;",
6
- "names": []
4
+ "sourcesContent": ["import React, { useState } from 'react';\nimport { debounce } from 'lodash-es';\nimport { type CSSProperties } from 'styled-components';\nimport { computePosition } from './utils/computePosition.js';\nimport type { DSHookFloatingContextT } from './react-desc-prop-types.js';\nimport type { PopoverArrowT } from './parts/PopoverArrow.js';\n\ntype UseComputedPositionStylesT = {\n preventComputing?: boolean;\n reference: Element | null;\n floating: HTMLElement | null;\n placement: DSHookFloatingContextT.PopperPlacementsT;\n placementOrderPreference?: DSHookFloatingContextT.PopperPlacementsT[];\n customOffset: [number, number];\n withoutPortal: boolean;\n};\n/**\n * this custom hook has a single purpose, to compute the position of the floating element relative to the reference element\n *\n * we ideally don't want to calculate positions if the open flag is false as the styles should not be visible so not relevant.\n * @param {UseComputedPositionStylesT} config - The configuration object.\n * @param {Boolean} config.preventComputing - If true, the position will not be computed, usually used when the open flag is false.\n * @param {Element} config.reference - The reference element as a DOM element.\n * @param {HTMLElement} config.floating - The floating element as a DOM element (required to calculate the best fitting position).\n * @param {DSHookFloatingContextT.PopperPlacementsT} config.placement - The placement of the floating element relative to the reference element to be applied if possible.\n * @param {DSHookFloatingContextT.PopperPlacementsT[]} config.placementOrderPreference - The order of preference for the placement of the floating element relative to the reference element, the first one that fits will be used.\n * @param {[number, number]} config.customOffset - The offset of the floating element relative to the reference element if any is desired.\n * @param {Boolean} config.withoutPortal - If true, the floating element will be positioned relative to the reference element, otherwise it will be positioned relative to the viewport.\n *\n * @returns results\n * @returns results.arrowStyles - the styles to be applied to the arrow element if any is desired\n * @returns results.floatingStyles - the styles to be applied to the floating element\n * @returns results.updateStyles - a function to be called to update the styles of the floating element on demand if needed\n * @returns results.debouncedUpdateStyles - a debounced version of the updateStyles function to be used when lot of invocations are expected (e.g. on scroll)\n * @returns results.mutableUpdateStyles - a ref to the updateStyles function to be used when the function needs to be called in a useEffect or similar\n */\nexport const useComputedPositionStyles = (config: UseComputedPositionStylesT) => {\n const { reference, floating, placement, placementOrderPreference, customOffset, withoutPortal, preventComputing } =\n config;\n\n const [arrowStyles, setArrowStyles] = useState<PopoverArrowT>({\n style: { left: 0 },\n placement: 'top',\n });\n const [floatingStyles, setFloatingStyles] = useState<CSSProperties>({\n position: 'absolute',\n zIndex: 3000,\n top: 0,\n left: 0,\n visibility: 'hidden',\n });\n const canComputePosition = reference !== null && floating !== null;\n const canAndShouldComputePosition = canComputePosition && preventComputing !== true;\n\n const updateStyles = React.useCallback(() => {\n if (canAndShouldComputePosition) {\n const { coordsStyle, finalPlacement, coordsArrow } = computePosition({\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n });\n\n setFloatingStyles({\n position: 'absolute',\n zIndex: 3000,\n ...coordsStyle,\n });\n setArrowStyles({ style: coordsArrow, placement: finalPlacement });\n }\n }, [\n canAndShouldComputePosition,\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n ]);\n\n // when deboucing we only care to invoke the most updated version of the function\n // continuously redefining the debouncedUpdateStyles function is a waste of resources\n // so we use a ref to store the latest version of the function\n const mutableUpdateStyles = React.useRef(updateStyles);\n mutableUpdateStyles.current = updateStyles;\n // and we only define the debounced version once, using the ref to always have the latest version of the function.\n // notice the ()=> mutableUpdateStyles.current() syntax\n // we create a new closure (the anonymous function) that is referientially stable\n // and we call the mutableUpdateStyles.current function inside it (which is NOT referentially stable)\n const debouncedUpdateStyles = React.useMemo(() => debounce(() => mutableUpdateStyles.current(), 100), []);\n\n const resetStyles = React.useCallback(() => {\n setFloatingStyles({\n position: 'absolute',\n zIndex: 3000,\n top: 0,\n left: 0,\n visibility: 'hidden',\n });\n setArrowStyles({ style: { left: 0 }, placement: 'top' });\n }, []);\n\n return React.useMemo(\n () => ({ arrowStyles, floatingStyles, updateStyles, debouncedUpdateStyles, mutableUpdateStyles, resetStyles }),\n [arrowStyles, floatingStyles, updateStyles, debouncedUpdateStyles, resetStyles],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAgC;AAChC,uBAAyB;AAEzB,6BAAgC;AAiCzB,MAAM,4BAA4B,CAAC,WAAuC;AAC/E,QAAM,EAAE,WAAW,UAAU,WAAW,0BAA0B,cAAc,eAAe,iBAAiB,IAC9G;AAEF,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAwB;AAAA,IAC5D,OAAO,EAAE,MAAM,EAAE;AAAA,IACjB,WAAW;AAAA,EACb,CAAC;AACD,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,uBAAwB;AAAA,IAClE,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,EACd,CAAC;AACD,QAAM,qBAAqB,cAAc,QAAQ,aAAa;AAC9D,QAAM,8BAA8B,sBAAsB,qBAAqB;AAE/E,QAAM,eAAe,aAAAA,QAAM,YAAY,MAAM;AAC3C,QAAI,6BAA6B;AAC/B,YAAM,EAAE,aAAa,gBAAgB,YAAY,QAAI,wCAAgB;AAAA,QACnE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAED,wBAAkB;AAAA,QAChB,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,GAAG;AAAA,MACL,CAAC;AACD,qBAAe,EAAE,OAAO,aAAa,WAAW,eAAe,CAAC;AAAA,IAClE;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAKD,QAAM,sBAAsB,aAAAA,QAAM,OAAO,YAAY;AACrD,sBAAoB,UAAU;AAK9B,QAAM,wBAAwB,aAAAA,QAAM,QAAQ,UAAM,2BAAS,MAAM,oBAAoB,QAAQ,GAAG,GAAG,GAAG,CAAC,CAAC;AAExG,QAAM,cAAc,aAAAA,QAAM,YAAY,MAAM;AAC1C,sBAAkB;AAAA,MAChB,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,MAAM;AAAA,MACN,YAAY;AAAA,IACd,CAAC;AACD,mBAAe,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,MAAM,CAAC;AAAA,EACzD,GAAG,CAAC,CAAC;AAEL,SAAO,aAAAA,QAAM;AAAA,IACX,OAAO,EAAE,aAAa,gBAAgB,cAAc,uBAAuB,qBAAqB,YAAY;AAAA,IAC5G,CAAC,aAAa,gBAAgB,cAAc,uBAAuB,WAAW;AAAA,EAChF;AACF;",
6
+ "names": ["React"]
7
7
  }
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import React2, { useMemo, useEffect } from "react";
2
+ import React2, { useEffect, useMemo } from "react";
3
3
  import {
4
4
  useMemoMergePropsWithDefault,
5
5
  useValidateTypescriptPropTypes,
@@ -26,66 +26,67 @@ const useFloatingContext = (props = {}) => {
26
26
  externallyControlledIsOpen
27
27
  } = propsWithDefault;
28
28
  const [internalIsOpen, setInternalIsOpen] = React2.useState(false);
29
- const isOpen = useMemo(
30
- () => externallyControlledIsOpen !== void 0 ? externallyControlledIsOpen : internalIsOpen,
31
- [externallyControlledIsOpen, internalIsOpen]
32
- );
33
- const handleOpen = React2.useCallback(() => {
29
+ const isOpenSourceOfTruth = useMemo(() => {
30
+ if (externallyControlledIsOpen !== void 0) return externallyControlledIsOpen;
31
+ return internalIsOpen;
32
+ }, [externallyControlledIsOpen, internalIsOpen]);
33
+ const overChargedOnOpen = React2.useCallback(() => {
34
34
  setInternalIsOpen(true);
35
35
  onOpen?.();
36
36
  }, [onOpen]);
37
- const handleClose = React2.useCallback(() => {
37
+ const overChargedOnClose = React2.useCallback(() => {
38
38
  setInternalIsOpen(false);
39
39
  onClose?.();
40
40
  }, [onClose]);
41
- const tooltipHelpers = useHeadlessTooltip({ onOpen: handleOpen, onClose: handleClose });
41
+ const tooltipHelpers = useHeadlessTooltip({ onOpen: overChargedOnOpen, onClose: overChargedOnClose });
42
42
  const { setReferenceElement, hideTooltip, showTooltip } = tooltipHelpers;
43
- const [reference, setReferenceInternal] = React2.useState(null);
43
+ const [reference, _setReference] = React2.useState(null);
44
44
  const [floating, setFloating] = React2.useState(null);
45
- const { arrowStyles, floatingStyles, hasComputedOnce, updateStyles, debouncedUpdateStyles, mutableUpdateStyles } = useComputedPositionStyles({
45
+ const [workaroundToEnsureAPositionWasCalculatedIfOpen, setWorkaroundToEnsureAPositionWasCalculatedIfOpen] = React2.useState(0);
46
+ const { arrowStyles, floatingStyles, mutableUpdateStyles, debouncedUpdateStyles } = useComputedPositionStyles({
46
47
  reference,
47
48
  floating,
48
49
  placement,
49
50
  placementOrderPreference,
50
51
  customOffset,
51
- withoutPortal,
52
- preventComputing: !isOpen,
53
- debounceMs: 150
52
+ withoutPortal
54
53
  });
55
54
  useEffect(() => {
56
- if (!isOpen) return;
57
- const observers = [];
58
- if (floating) {
59
- const roFloating = new ResizeObserver(() => {
60
- mutableUpdateStyles.current();
61
- requestAnimationFrame(() => mutableUpdateStyles.current());
55
+ requestAnimationFrame(() => {
56
+ mutableUpdateStyles?.current();
57
+ });
58
+ }, [reference, mutableUpdateStyles]);
59
+ const updatePosOnIntersection = React2.useCallback(() => {
60
+ if (reference) {
61
+ requestAnimationFrame(() => {
62
+ debouncedUpdateStyles();
62
63
  });
63
- roFloating.observe(floating);
64
- observers.push(roFloating);
65
64
  }
66
- if (reference) {
67
- const roRef = new ResizeObserver(() => {
68
- mutableUpdateStyles.current();
65
+ }, [reference, debouncedUpdateStyles]);
66
+ usePositionObserver(reference, updatePosOnIntersection);
67
+ useEffect(() => {
68
+ requestAnimationFrame(() => {
69
+ mutableUpdateStyles?.current();
70
+ });
71
+ }, [isOpenSourceOfTruth, mutableUpdateStyles]);
72
+ const { visibility } = floatingStyles;
73
+ const needsToCalculateBecauseStillInvisibleWhenShouldBeOpen = isOpenSourceOfTruth && visibility === "hidden";
74
+ useEffect(() => {
75
+ if (needsToCalculateBecauseStillInvisibleWhenShouldBeOpen) {
76
+ mutableUpdateStyles?.current();
77
+ requestAnimationFrame(() => {
78
+ setWorkaroundToEnsureAPositionWasCalculatedIfOpen((o) => o + 1);
69
79
  });
70
- roRef.observe(reference);
71
- observers.push(roRef);
72
80
  }
73
- return () => observers.forEach((o) => o.disconnect());
74
- }, [isOpen, floating, reference, mutableUpdateStyles]);
75
- const onObservedMovement = React2.useCallback(() => {
76
- if (!isOpen) return;
77
- debouncedUpdateStyles();
78
- }, [isOpen, debouncedUpdateStyles]);
79
- usePositionObserver(reference, onObservedMovement);
80
- const computedFloatingStyles = useMemo(
81
- () => ({
82
- ...floatingStyles,
83
- visibility: isOpen && hasComputedOnce ? "visible" : "hidden"
84
- }),
85
- [floatingStyles, isOpen, hasComputedOnce]
86
- );
87
- const setReference = mergeRefs(setReferenceInternal, setReferenceElement);
88
- const refs = useMemo(
81
+ }, [
82
+ needsToCalculateBecauseStillInvisibleWhenShouldBeOpen,
83
+ mutableUpdateStyles,
84
+ // this dependency is the point of this useEffect
85
+ // it will keep triggering until the position is calculated if it needs to be calculated
86
+ workaroundToEnsureAPositionWasCalculatedIfOpen
87
+ ]);
88
+ const setReference = mergeRefs(_setReference, setReferenceElement);
89
+ const refs = React2.useMemo(
89
90
  () => ({
90
91
  setReference,
91
92
  setFloating,
@@ -94,7 +95,7 @@ const useFloatingContext = (props = {}) => {
94
95
  }),
95
96
  [setReference, floating, reference]
96
97
  );
97
- const handlers = useMemo(
98
+ const handlers = React2.useMemo(
98
99
  () => ({
99
100
  onMouseEnter: tooltipHelpers.onMouseEnter,
100
101
  onMouseLeave: tooltipHelpers.onMouseLeave,
@@ -106,9 +107,9 @@ const useFloatingContext = (props = {}) => {
106
107
  return useMemo(
107
108
  () => ({
108
109
  refs,
109
- floatingStyles: computedFloatingStyles,
110
+ floatingStyles,
110
111
  handlers,
111
- isOpen,
112
+ isOpen: isOpenSourceOfTruth,
112
113
  arrowStyles,
113
114
  hideTooltip,
114
115
  showTooltip,
@@ -118,14 +119,13 @@ const useFloatingContext = (props = {}) => {
118
119
  portalDOMContainer,
119
120
  animationDuration
120
121
  },
121
- mutableUpdateStyles,
122
- forceUpdatePosition: updateStyles
122
+ mutableUpdateStyles
123
123
  }),
124
124
  [
125
125
  refs,
126
- computedFloatingStyles,
126
+ floatingStyles,
127
127
  handlers,
128
- isOpen,
128
+ isOpenSourceOfTruth,
129
129
  arrowStyles,
130
130
  hideTooltip,
131
131
  showTooltip,
@@ -133,8 +133,7 @@ const useFloatingContext = (props = {}) => {
133
133
  withoutAnimation,
134
134
  portalDOMContainer,
135
135
  animationDuration,
136
- mutableUpdateStyles,
137
- updateStyles
136
+ mutableUpdateStyles
138
137
  ]
139
138
  );
140
139
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/DSFloatingContext.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* 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 { mergeRefs } from '@elliemae/ds-system';\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, hideTooltip, showTooltip } = tooltipHelpers;\n\n // Anchor and floating refs\n const [reference, setReferenceInternal] = React.useState<Element | null>(null);\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,\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 // inmediato + siguiente frame para asentar\n mutableUpdateStyles.current();\n requestAnimationFrame(() => mutableUpdateStyles.current());\n });\n roFloating.observe(floating);\n observers.push(roFloating);\n }\n\n if (reference) {\n const roRef = new ResizeObserver(() => {\n mutableUpdateStyles.current();\n });\n roRef.observe(reference);\n observers.push(roRef);\n }\n\n return () => observers.forEach((o) => o.disconnect());\n }, [isOpen, floating, reference, mutableUpdateStyles]);\n\n const onObservedMovement = React.useCallback(() => {\n if (!isOpen) return;\n debouncedUpdateStyles();\n }, [isOpen, debouncedUpdateStyles]);\n usePositionObserver(reference, 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, isOpen, hasComputedOnce],\n );\n\n const setReference = mergeRefs(setReferenceInternal, setReferenceElement);\n\n const refs = useMemo(\n () => ({\n setReference,\n setFloating,\n floating,\n reference,\n }),\n [setReference, floating, reference],\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"],
5
- "mappings": "AAAA,YAAY,WAAW;ACGvB,OAAOA,UAAS,SAAS,iBAAiB;AAC1C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,0BAA0B;AACnC,SAAS,iBAAiB;AAE1B,SAAS,cAAc,kCAAkC;AACzD,SAAS,iCAAiC;AAC1C,SAAS,2BAA2B;AAEpC,MAAM,qBAAqB,CAAC,QAAsC,CAAC,MAAM;AACvE,QAAM,mBAAmB,6BAAmE,OAAO,YAAY;AAC/G,iCAA+B,kBAAkB,4BAA4B,iBAAiB;AAE9F,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,OAAM,SAAkB,KAAK;AACzE,QAAM,SAAS;AAAA,IACb,MAAO,+BAA+B,SAAY,6BAA6B;AAAA,IAC/E,CAAC,4BAA4B,cAAc;AAAA,EAC7C;AAEA,QAAM,aAAaA,OAAM,YAAY,MAAM;AACzC,sBAAkB,IAAI;AACtB,aAAS;AAAA,EACX,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,cAAcA,OAAM,YAAY,MAAM;AAC1C,sBAAkB,KAAK;AACvB,cAAU;AAAA,EACZ,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,iBAAiB,mBAAmB,EAAE,QAAQ,YAAY,SAAS,YAAY,CAAC;AACtF,QAAM,EAAE,qBAAqB,aAAa,YAAY,IAAI;AAG1D,QAAM,CAAC,WAAW,oBAAoB,IAAIA,OAAM,SAAyB,IAAI;AAC7E,QAAM,CAAC,UAAU,WAAW,IAAIA,OAAM,SAA6B,IAAI;AAGvE,QAAM,EAAE,aAAa,gBAAgB,iBAAiB,cAAc,uBAAuB,oBAAoB,IAC7G,0BAA0B;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB,CAAC;AAAA,IACnB,YAAY;AAAA,EACd,CAAC;AAEH,YAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,YAA8B,CAAC;AAErC,QAAI,UAAU;AACZ,YAAM,aAAa,IAAI,eAAe,MAAM;AAE1C,4BAAoB,QAAQ;AAC5B,8BAAsB,MAAM,oBAAoB,QAAQ,CAAC;AAAA,MAC3D,CAAC;AACD,iBAAW,QAAQ,QAAQ;AAC3B,gBAAU,KAAK,UAAU;AAAA,IAC3B;AAEA,QAAI,WAAW;AACb,YAAM,QAAQ,IAAI,eAAe,MAAM;AACrC,4BAAoB,QAAQ;AAAA,MAC9B,CAAC;AACD,YAAM,QAAQ,SAAS;AACvB,gBAAU,KAAK,KAAK;AAAA,IACtB;AAEA,WAAO,MAAM,UAAU,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;AAAA,EACtD,GAAG,CAAC,QAAQ,UAAU,WAAW,mBAAmB,CAAC;AAErD,QAAM,qBAAqBA,OAAM,YAAY,MAAM;AACjD,QAAI,CAAC,OAAQ;AACb,0BAAsB;AAAA,EACxB,GAAG,CAAC,QAAQ,qBAAqB,CAAC;AAClC,sBAAoB,WAAW,kBAAkB;AAGjD,QAAM,yBAAyB;AAAA,IAC7B,OAAO;AAAA,MACL,GAAG;AAAA,MACH,YAAY,UAAU,kBAAkB,YAAY;AAAA,IACtD;AAAA,IACA,CAAC,gBAAgB,QAAQ,eAAe;AAAA,EAC1C;AAEA,QAAM,eAAe,UAAU,sBAAsB,mBAAmB;AAExE,QAAM,OAAO;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,cAAc,UAAU,SAAS;AAAA,EACpC;AAEA,QAAM,WAAW;AAAA,IACf,OAAO;AAAA,MACL,cAAc,eAAe;AAAA,MAC7B,cAAc,eAAe;AAAA,MAC7B,SAAS,eAAe;AAAA,MACxB,QAAQ,eAAe;AAAA,IACzB;AAAA,IACA,CAAC,eAAe,QAAQ,eAAe,SAAS,eAAe,cAAc,eAAe,YAAY;AAAA,EAC1G;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA,gBAAgB;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACA,qBAAqB;AAAA,IACvB;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,mBAAmB,cAAc;AACjC,MAAM,+BAA+B,SAAS,kBAAkB;AAChE,6BAA6B,YAC3B;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-statements */\nimport React, { useEffect, useMemo } 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 { mergeRefs } from '@elliemae/ds-system';\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 isOpenSourceOfTruth = useMemo(() => {\n if (externallyControlledIsOpen !== undefined) return externallyControlledIsOpen;\n return internalIsOpen;\n }, [externallyControlledIsOpen, internalIsOpen]);\n\n const overChargedOnOpen = React.useCallback(() => {\n setInternalIsOpen(true);\n onOpen?.();\n }, [onOpen]);\n const overChargedOnClose = React.useCallback(() => {\n setInternalIsOpen(false);\n onClose?.();\n }, [onClose]);\n const tooltipHelpers = useHeadlessTooltip({ onOpen: overChargedOnOpen, onClose: overChargedOnClose });\n const { setReferenceElement, hideTooltip, showTooltip } = tooltipHelpers;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n const [reference, _setReference] = React.useState<Element | null>(null);\n const [floating, setFloating] = React.useState<HTMLElement | null>(null);\n const [workaroundToEnsureAPositionWasCalculatedIfOpen, setWorkaroundToEnsureAPositionWasCalculatedIfOpen] =\n React.useState<number>(0);\n\n const { arrowStyles, floatingStyles, mutableUpdateStyles, debouncedUpdateStyles } = useComputedPositionStyles({\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n });\n\n // calculate position on mount\n // AND everytime the reference (which is actually immutable because it's stored in a React.useState)\n // changes\n useEffect(() => {\n requestAnimationFrame(() => {\n mutableUpdateStyles?.current();\n });\n // the dependency array is equal to being empty because mutableUpdateStyles is a ref.\n // this is effectively an \"on mount\"\n }, [reference, mutableUpdateStyles]);\n\n // use intersection observer to detect when the position of the reference changes needing to recalculate the position\n const updatePosOnIntersection = React.useCallback(() => {\n if (reference) {\n requestAnimationFrame(() => {\n debouncedUpdateStyles();\n });\n }\n }, [reference, debouncedUpdateStyles]);\n usePositionObserver(reference, updatePosOnIntersection);\n\n // when we detect that the flag about it being open/closed changes\n // we refresh the position of the tooltip calculation\n useEffect(() => {\n requestAnimationFrame(() => {\n mutableUpdateStyles?.current();\n });\n }, [isOpenSourceOfTruth, mutableUpdateStyles]);\n\n // this is a workaround to ensure that the position is calculated at least once when the tooltip is open\n const { visibility } = floatingStyles;\n const needsToCalculateBecauseStillInvisibleWhenShouldBeOpen = isOpenSourceOfTruth && visibility === 'hidden';\n useEffect(() => {\n if (needsToCalculateBecauseStillInvisibleWhenShouldBeOpen) {\n mutableUpdateStyles?.current();\n requestAnimationFrame(() => {\n setWorkaroundToEnsureAPositionWasCalculatedIfOpen((o) => o + 1);\n });\n }\n }, [\n needsToCalculateBecauseStillInvisibleWhenShouldBeOpen,\n mutableUpdateStyles,\n // this dependency is the point of this useEffect\n // it will keep triggering until the position is calculated if it needs to be calculated\n workaroundToEnsureAPositionWasCalculatedIfOpen,\n ]);\n\n const setReference = mergeRefs(_setReference, setReferenceElement);\n const refs = React.useMemo(\n () => ({\n setReference,\n setFloating,\n floating,\n reference,\n }),\n [setReference, floating, reference],\n );\n\n const handlers = React.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,\n handlers,\n isOpen: isOpenSourceOfTruth,\n arrowStyles,\n hideTooltip,\n showTooltip,\n context: {\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\n },\n mutableUpdateStyles,\n }),\n [\n refs,\n floatingStyles,\n handlers,\n isOpenSourceOfTruth,\n arrowStyles,\n hideTooltip,\n showTooltip,\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\n mutableUpdateStyles,\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"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -1,84 +1,64 @@
1
1
  import * as React from "react";
2
- import { useLayoutEffect, useMemo, useRef, useState, useCallback } from "react";
2
+ import React2, { useState } from "react";
3
3
  import { debounce } from "lodash-es";
4
4
  import { computePosition } from "./utils/computePosition.js";
5
5
  const useComputedPositionStyles = (config) => {
6
- const {
6
+ const { reference, floating, placement, placementOrderPreference, customOffset, withoutPortal, preventComputing } = config;
7
+ const [arrowStyles, setArrowStyles] = useState({
8
+ style: { left: 0 },
9
+ placement: "top"
10
+ });
11
+ const [floatingStyles, setFloatingStyles] = useState({
12
+ position: "absolute",
13
+ zIndex: 3e3,
14
+ top: 0,
15
+ left: 0,
16
+ visibility: "hidden"
17
+ });
18
+ const canComputePosition = reference !== null && floating !== null;
19
+ const canAndShouldComputePosition = canComputePosition && preventComputing !== true;
20
+ const updateStyles = React2.useCallback(() => {
21
+ if (canAndShouldComputePosition) {
22
+ const { coordsStyle, finalPlacement, coordsArrow } = computePosition({
23
+ reference,
24
+ floating,
25
+ placement,
26
+ placementOrderPreference,
27
+ customOffset,
28
+ withoutPortal
29
+ });
30
+ setFloatingStyles({
31
+ position: "absolute",
32
+ zIndex: 3e3,
33
+ ...coordsStyle
34
+ });
35
+ setArrowStyles({ style: coordsArrow, placement: finalPlacement });
36
+ }
37
+ }, [
38
+ canAndShouldComputePosition,
7
39
  reference,
8
40
  floating,
9
41
  placement,
10
42
  placementOrderPreference,
11
43
  customOffset,
12
- withoutPortal,
13
- preventComputing = false,
14
- debounceMs = 150
15
- } = config;
16
- const [arrowStyles, setArrowStyles] = useState({ style: { left: 0 }, placement: "top" });
17
- const [floatingStyles, setFloatingStyles] = useState({
18
- position: "absolute",
19
- zIndex: 3e3,
20
- visibility: "hidden",
21
- willChange: "top,left"
22
- // hint to browser for smoother positioning updates
23
- });
24
- const [hasComputedOnce, setHasComputedOnce] = useState(false);
25
- const canCompute = reference !== null && floating !== null && !preventComputing;
26
- const updateStyles = useCallback(() => {
27
- if (!canCompute) return;
28
- const { coordsStyle, finalPlacement, coordsArrow } = computePosition({
29
- reference,
30
- floating,
31
- placement,
32
- placementOrderPreference,
33
- customOffset,
34
- withoutPortal
35
- });
36
- setFloatingStyles((prev) => ({
44
+ withoutPortal
45
+ ]);
46
+ const mutableUpdateStyles = React2.useRef(updateStyles);
47
+ mutableUpdateStyles.current = updateStyles;
48
+ const debouncedUpdateStyles = React2.useMemo(() => debounce(() => mutableUpdateStyles.current(), 100), []);
49
+ const resetStyles = React2.useCallback(() => {
50
+ setFloatingStyles({
37
51
  position: "absolute",
38
52
  zIndex: 3e3,
39
- ...prev,
40
- ...coordsStyle
41
- }));
42
- setArrowStyles({ style: coordsArrow, placement: finalPlacement });
43
- setHasComputedOnce(true);
44
- }, [canCompute, reference, floating, placement, placementOrderPreference, customOffset, withoutPortal]);
45
- const mutableUpdateStyles = useRef(updateStyles);
46
- mutableUpdateStyles.current = updateStyles;
47
- const debouncedUpdateStyles = useMemo(() => {
48
- const d = debounce(() => mutableUpdateStyles.current(), debounceMs);
49
- return d;
50
- }, [debounceMs]);
51
- useLayoutEffect(
52
- () => () => {
53
- debouncedUpdateStyles.cancel();
54
- },
55
- [debouncedUpdateStyles]
56
- );
57
- useLayoutEffect(() => {
58
- if (canCompute) {
59
- mutableUpdateStyles.current();
60
- }
61
- }, [canCompute, reference, floating, placement, placementOrderPreference, customOffset, withoutPortal]);
62
- const forceUpdatePosition = useCallback(() => {
63
- mutableUpdateStyles.current();
64
- }, []);
65
- const resetVisibilityOnly = useCallback(() => {
66
- setFloatingStyles((prev) => ({
67
- ...prev,
53
+ top: 0,
54
+ left: 0,
68
55
  visibility: "hidden"
69
- }));
56
+ });
57
+ setArrowStyles({ style: { left: 0 }, placement: "top" });
70
58
  }, []);
71
- return useMemo(
72
- () => ({
73
- arrowStyles,
74
- floatingStyles,
75
- hasComputedOnce,
76
- updateStyles: forceUpdatePosition,
77
- debouncedUpdateStyles,
78
- mutableUpdateStyles,
79
- resetVisibilityOnly
80
- }),
81
- [arrowStyles, floatingStyles, hasComputedOnce, forceUpdatePosition, debouncedUpdateStyles, resetVisibilityOnly]
59
+ return React2.useMemo(
60
+ () => ({ arrowStyles, floatingStyles, updateStyles, debouncedUpdateStyles, mutableUpdateStyles, resetStyles }),
61
+ [arrowStyles, floatingStyles, updateStyles, debouncedUpdateStyles, resetStyles]
82
62
  );
83
63
  };
84
64
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/useComputedPositionStyles.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-statements */\nimport { useLayoutEffect, useMemo, useRef, useState, useCallback } from 'react';\nimport { debounce } from 'lodash-es';\nimport { type CSSProperties } from 'styled-components';\nimport { computePosition } from './utils/computePosition.js';\nimport type { DSHookFloatingContextT } from './react-desc-prop-types.js';\nimport type { PopoverArrowT } from './parts/PopoverArrow.js';\n\ntype UseComputedPositionStylesT = {\n /** Prevent computing when closed (optimization + avoids unnecessary frames) */\n preventComputing?: boolean;\n reference: Element | null;\n floating: HTMLElement | null;\n placement: DSHookFloatingContextT.PopperPlacementsT;\n placementOrderPreference?: DSHookFloatingContextT.PopperPlacementsT[];\n customOffset: [number, number];\n withoutPortal: boolean;\n /** Debounce ms for scroll/resize/observer events */\n debounceMs?: number;\n};\n\nexport const useComputedPositionStyles = (config: UseComputedPositionStylesT) => {\n const {\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n preventComputing = false,\n debounceMs = 150,\n } = config;\n\n const [arrowStyles, setArrowStyles] = useState<PopoverArrowT>({ style: { left: 0 }, placement: 'top' });\n\n // Important: do not initialize top/left to (0,0); keep hidden until the first computation\n const [floatingStyles, setFloatingStyles] = useState<CSSProperties>({\n position: 'absolute',\n zIndex: 3000,\n visibility: 'hidden',\n willChange: 'top,left', // hint to browser for smoother positioning updates\n });\n\n const [hasComputedOnce, setHasComputedOnce] = useState(false);\n\n const canCompute = reference !== null && floating !== null && !preventComputing;\n\n const updateStyles = useCallback(() => {\n if (!canCompute) return;\n\n const { coordsStyle, finalPlacement, coordsArrow } = computePosition({\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n });\n\n // Do not touch visibility here; it is managed outside depending on open/hasComputedOnce\n setFloatingStyles((prev) => ({\n position: 'absolute',\n zIndex: 3000,\n ...prev,\n ...coordsStyle,\n }));\n setArrowStyles({ style: coordsArrow, placement: finalPlacement });\n setHasComputedOnce(true);\n }, [canCompute, reference, floating, placement, placementOrderPreference, customOffset, withoutPortal]);\n\n // Store latest update function in a ref to keep debounced stable\n const mutableUpdateStyles = useRef(updateStyles);\n mutableUpdateStyles.current = updateStyles;\n\n const debouncedUpdateStyles = useMemo(() => {\n const d = debounce(() => mutableUpdateStyles.current(), debounceMs);\n return d;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debounceMs]);\n\n // Clean up debounce on unmount\n useLayoutEffect(\n () => () => {\n debouncedUpdateStyles.cancel();\n },\n [debouncedUpdateStyles],\n );\n\n // Recalculate BEFORE paint when dependencies change\n useLayoutEffect(() => {\n if (canCompute) {\n mutableUpdateStyles.current();\n }\n }, [canCompute, reference, floating, placement, placementOrderPreference, customOffset, withoutPortal]);\n\n const forceUpdatePosition = useCallback(() => {\n mutableUpdateStyles.current();\n }, []);\n\n // Do not reset coordinates when closing; just hide\n const resetVisibilityOnly = useCallback(() => {\n setFloatingStyles((prev) => ({\n ...prev,\n visibility: 'hidden',\n }));\n }, []);\n\n return useMemo(\n () => ({\n arrowStyles,\n floatingStyles,\n hasComputedOnce,\n updateStyles: forceUpdatePosition,\n debouncedUpdateStyles,\n mutableUpdateStyles,\n resetVisibilityOnly,\n }),\n [arrowStyles, floatingStyles, hasComputedOnce, forceUpdatePosition, debouncedUpdateStyles, resetVisibilityOnly],\n );\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACCvB,SAAS,iBAAiB,SAAS,QAAQ,UAAU,mBAAmB;AACxE,SAAS,gBAAgB;AAEzB,SAAS,uBAAuB;AAiBzB,MAAM,4BAA4B,CAAC,WAAuC;AAC/E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,IACnB,aAAa;AAAA,EACf,IAAI;AAEJ,QAAM,CAAC,aAAa,cAAc,IAAI,SAAwB,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,MAAM,CAAC;AAGtG,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAwB;AAAA,IAClE,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,YAAY;AAAA;AAAA,EACd,CAAC;AAED,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAS,KAAK;AAE5D,QAAM,aAAa,cAAc,QAAQ,aAAa,QAAQ,CAAC;AAE/D,QAAM,eAAe,YAAY,MAAM;AACrC,QAAI,CAAC,WAAY;AAEjB,UAAM,EAAE,aAAa,gBAAgB,YAAY,IAAI,gBAAgB;AAAA,MACnE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAGD,sBAAkB,CAAC,UAAU;AAAA,MAC3B,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,GAAG;AAAA,MACH,GAAG;AAAA,IACL,EAAE;AACF,mBAAe,EAAE,OAAO,aAAa,WAAW,eAAe,CAAC;AAChE,uBAAmB,IAAI;AAAA,EACzB,GAAG,CAAC,YAAY,WAAW,UAAU,WAAW,0BAA0B,cAAc,aAAa,CAAC;AAGtG,QAAM,sBAAsB,OAAO,YAAY;AAC/C,sBAAoB,UAAU;AAE9B,QAAM,wBAAwB,QAAQ,MAAM;AAC1C,UAAM,IAAI,SAAS,MAAM,oBAAoB,QAAQ,GAAG,UAAU;AAClE,WAAO;AAAA,EAET,GAAG,CAAC,UAAU,CAAC;AAGf;AAAA,IACE,MAAM,MAAM;AACV,4BAAsB,OAAO;AAAA,IAC/B;AAAA,IACA,CAAC,qBAAqB;AAAA,EACxB;AAGA,kBAAgB,MAAM;AACpB,QAAI,YAAY;AACd,0BAAoB,QAAQ;AAAA,IAC9B;AAAA,EACF,GAAG,CAAC,YAAY,WAAW,UAAU,WAAW,0BAA0B,cAAc,aAAa,CAAC;AAEtG,QAAM,sBAAsB,YAAY,MAAM;AAC5C,wBAAoB,QAAQ;AAAA,EAC9B,GAAG,CAAC,CAAC;AAGL,QAAM,sBAAsB,YAAY,MAAM;AAC5C,sBAAkB,CAAC,UAAU;AAAA,MAC3B,GAAG;AAAA,MACH,YAAY;AAAA,IACd,EAAE;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,aAAa,gBAAgB,iBAAiB,qBAAqB,uBAAuB,mBAAmB;AAAA,EAChH;AACF;",
6
- "names": []
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useState } from 'react';\nimport { debounce } from 'lodash-es';\nimport { type CSSProperties } from 'styled-components';\nimport { computePosition } from './utils/computePosition.js';\nimport type { DSHookFloatingContextT } from './react-desc-prop-types.js';\nimport type { PopoverArrowT } from './parts/PopoverArrow.js';\n\ntype UseComputedPositionStylesT = {\n preventComputing?: boolean;\n reference: Element | null;\n floating: HTMLElement | null;\n placement: DSHookFloatingContextT.PopperPlacementsT;\n placementOrderPreference?: DSHookFloatingContextT.PopperPlacementsT[];\n customOffset: [number, number];\n withoutPortal: boolean;\n};\n/**\n * this custom hook has a single purpose, to compute the position of the floating element relative to the reference element\n *\n * we ideally don't want to calculate positions if the open flag is false as the styles should not be visible so not relevant.\n * @param {UseComputedPositionStylesT} config - The configuration object.\n * @param {Boolean} config.preventComputing - If true, the position will not be computed, usually used when the open flag is false.\n * @param {Element} config.reference - The reference element as a DOM element.\n * @param {HTMLElement} config.floating - The floating element as a DOM element (required to calculate the best fitting position).\n * @param {DSHookFloatingContextT.PopperPlacementsT} config.placement - The placement of the floating element relative to the reference element to be applied if possible.\n * @param {DSHookFloatingContextT.PopperPlacementsT[]} config.placementOrderPreference - The order of preference for the placement of the floating element relative to the reference element, the first one that fits will be used.\n * @param {[number, number]} config.customOffset - The offset of the floating element relative to the reference element if any is desired.\n * @param {Boolean} config.withoutPortal - If true, the floating element will be positioned relative to the reference element, otherwise it will be positioned relative to the viewport.\n *\n * @returns results\n * @returns results.arrowStyles - the styles to be applied to the arrow element if any is desired\n * @returns results.floatingStyles - the styles to be applied to the floating element\n * @returns results.updateStyles - a function to be called to update the styles of the floating element on demand if needed\n * @returns results.debouncedUpdateStyles - a debounced version of the updateStyles function to be used when lot of invocations are expected (e.g. on scroll)\n * @returns results.mutableUpdateStyles - a ref to the updateStyles function to be used when the function needs to be called in a useEffect or similar\n */\nexport const useComputedPositionStyles = (config: UseComputedPositionStylesT) => {\n const { reference, floating, placement, placementOrderPreference, customOffset, withoutPortal, preventComputing } =\n config;\n\n const [arrowStyles, setArrowStyles] = useState<PopoverArrowT>({\n style: { left: 0 },\n placement: 'top',\n });\n const [floatingStyles, setFloatingStyles] = useState<CSSProperties>({\n position: 'absolute',\n zIndex: 3000,\n top: 0,\n left: 0,\n visibility: 'hidden',\n });\n const canComputePosition = reference !== null && floating !== null;\n const canAndShouldComputePosition = canComputePosition && preventComputing !== true;\n\n const updateStyles = React.useCallback(() => {\n if (canAndShouldComputePosition) {\n const { coordsStyle, finalPlacement, coordsArrow } = computePosition({\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n });\n\n setFloatingStyles({\n position: 'absolute',\n zIndex: 3000,\n ...coordsStyle,\n });\n setArrowStyles({ style: coordsArrow, placement: finalPlacement });\n }\n }, [\n canAndShouldComputePosition,\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n ]);\n\n // when deboucing we only care to invoke the most updated version of the function\n // continuously redefining the debouncedUpdateStyles function is a waste of resources\n // so we use a ref to store the latest version of the function\n const mutableUpdateStyles = React.useRef(updateStyles);\n mutableUpdateStyles.current = updateStyles;\n // and we only define the debounced version once, using the ref to always have the latest version of the function.\n // notice the ()=> mutableUpdateStyles.current() syntax\n // we create a new closure (the anonymous function) that is referientially stable\n // and we call the mutableUpdateStyles.current function inside it (which is NOT referentially stable)\n const debouncedUpdateStyles = React.useMemo(() => debounce(() => mutableUpdateStyles.current(), 100), []);\n\n const resetStyles = React.useCallback(() => {\n setFloatingStyles({\n position: 'absolute',\n zIndex: 3000,\n top: 0,\n left: 0,\n visibility: 'hidden',\n });\n setArrowStyles({ style: { left: 0 }, placement: 'top' });\n }, []);\n\n return React.useMemo(\n () => ({ arrowStyles, floatingStyles, updateStyles, debouncedUpdateStyles, mutableUpdateStyles, resetStyles }),\n [arrowStyles, floatingStyles, updateStyles, debouncedUpdateStyles, resetStyles],\n );\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,OAAOA,UAAS,gBAAgB;AAChC,SAAS,gBAAgB;AAEzB,SAAS,uBAAuB;AAiCzB,MAAM,4BAA4B,CAAC,WAAuC;AAC/E,QAAM,EAAE,WAAW,UAAU,WAAW,0BAA0B,cAAc,eAAe,iBAAiB,IAC9G;AAEF,QAAM,CAAC,aAAa,cAAc,IAAI,SAAwB;AAAA,IAC5D,OAAO,EAAE,MAAM,EAAE;AAAA,IACjB,WAAW;AAAA,EACb,CAAC;AACD,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAwB;AAAA,IAClE,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,EACd,CAAC;AACD,QAAM,qBAAqB,cAAc,QAAQ,aAAa;AAC9D,QAAM,8BAA8B,sBAAsB,qBAAqB;AAE/E,QAAM,eAAeA,OAAM,YAAY,MAAM;AAC3C,QAAI,6BAA6B;AAC/B,YAAM,EAAE,aAAa,gBAAgB,YAAY,IAAI,gBAAgB;AAAA,QACnE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAED,wBAAkB;AAAA,QAChB,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,GAAG;AAAA,MACL,CAAC;AACD,qBAAe,EAAE,OAAO,aAAa,WAAW,eAAe,CAAC;AAAA,IAClE;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAKD,QAAM,sBAAsBA,OAAM,OAAO,YAAY;AACrD,sBAAoB,UAAU;AAK9B,QAAM,wBAAwBA,OAAM,QAAQ,MAAM,SAAS,MAAM,oBAAoB,QAAQ,GAAG,GAAG,GAAG,CAAC,CAAC;AAExG,QAAM,cAAcA,OAAM,YAAY,MAAM;AAC1C,sBAAkB;AAAA,MAChB,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,MAAM;AAAA,MACN,YAAY;AAAA,IACd,CAAC;AACD,mBAAe,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,MAAM,CAAC;AAAA,EACzD,GAAG,CAAC,CAAC;AAEL,SAAOA,OAAM;AAAA,IACX,OAAO,EAAE,aAAa,gBAAgB,cAAc,uBAAuB,qBAAqB,YAAY;AAAA,IAC5G,CAAC,aAAa,gBAAgB,cAAc,uBAAuB,WAAW;AAAA,EAChF;AACF;",
6
+ "names": ["React"]
7
7
  }
@@ -8,7 +8,7 @@ declare const useFloatingContext: {
8
8
  floating: HTMLElement | null;
9
9
  reference: Element | null;
10
10
  };
11
- floatingStyles: React.CSSProperties;
11
+ floatingStyles: import("styled-components").CSSProperties;
12
12
  handlers: {
13
13
  onMouseEnter: () => void;
14
14
  onMouseLeave: () => void;
@@ -26,7 +26,6 @@ declare const useFloatingContext: {
26
26
  animationDuration: number;
27
27
  };
28
28
  mutableUpdateStyles: React.MutableRefObject<() => void>;
29
- forceUpdatePosition: () => void;
30
29
  };
31
30
  displayName: string;
32
31
  };
@@ -115,7 +115,7 @@ export declare const useFloatingWrapper: (propsFromUser: DSFloatingWrapperT.Prop
115
115
  onBlurCapture?: React.FocusEventHandler<Element> | undefined;
116
116
  onChange?: React.FormEventHandler<Element> | undefined;
117
117
  onChangeCapture?: React.FormEventHandler<Element> | undefined;
118
- onBeforeInput?: React.InputEventHandler<Element> | undefined;
118
+ onBeforeInput?: React.FormEventHandler<Element> | undefined;
119
119
  onBeforeInputCapture?: React.FormEventHandler<Element> | undefined;
120
120
  onInput?: React.FormEventHandler<Element> | undefined;
121
121
  onInputCapture?: React.FormEventHandler<Element> | undefined;
@@ -1,8 +1,8 @@
1
+ import React from 'react';
1
2
  import { type CSSProperties } from 'styled-components';
2
3
  import type { DSHookFloatingContextT } from './react-desc-prop-types.js';
3
4
  import type { PopoverArrowT } from './parts/PopoverArrow.js';
4
5
  type UseComputedPositionStylesT = {
5
- /** Prevent computing when closed (optimization + avoids unnecessary frames) */
6
6
  preventComputing?: boolean;
7
7
  reference: Element | null;
8
8
  floating: HTMLElement | null;
@@ -10,16 +10,33 @@ type UseComputedPositionStylesT = {
10
10
  placementOrderPreference?: DSHookFloatingContextT.PopperPlacementsT[];
11
11
  customOffset: [number, number];
12
12
  withoutPortal: boolean;
13
- /** Debounce ms for scroll/resize/observer events */
14
- debounceMs?: number;
15
13
  };
14
+ /**
15
+ * this custom hook has a single purpose, to compute the position of the floating element relative to the reference element
16
+ *
17
+ * we ideally don't want to calculate positions if the open flag is false as the styles should not be visible so not relevant.
18
+ * @param {UseComputedPositionStylesT} config - The configuration object.
19
+ * @param {Boolean} config.preventComputing - If true, the position will not be computed, usually used when the open flag is false.
20
+ * @param {Element} config.reference - The reference element as a DOM element.
21
+ * @param {HTMLElement} config.floating - The floating element as a DOM element (required to calculate the best fitting position).
22
+ * @param {DSHookFloatingContextT.PopperPlacementsT} config.placement - The placement of the floating element relative to the reference element to be applied if possible.
23
+ * @param {DSHookFloatingContextT.PopperPlacementsT[]} config.placementOrderPreference - The order of preference for the placement of the floating element relative to the reference element, the first one that fits will be used.
24
+ * @param {[number, number]} config.customOffset - The offset of the floating element relative to the reference element if any is desired.
25
+ * @param {Boolean} config.withoutPortal - If true, the floating element will be positioned relative to the reference element, otherwise it will be positioned relative to the viewport.
26
+ *
27
+ * @returns results
28
+ * @returns results.arrowStyles - the styles to be applied to the arrow element if any is desired
29
+ * @returns results.floatingStyles - the styles to be applied to the floating element
30
+ * @returns results.updateStyles - a function to be called to update the styles of the floating element on demand if needed
31
+ * @returns results.debouncedUpdateStyles - a debounced version of the updateStyles function to be used when lot of invocations are expected (e.g. on scroll)
32
+ * @returns results.mutableUpdateStyles - a ref to the updateStyles function to be used when the function needs to be called in a useEffect or similar
33
+ */
16
34
  export declare const useComputedPositionStyles: (config: UseComputedPositionStylesT) => {
17
35
  arrowStyles: PopoverArrowT;
18
36
  floatingStyles: CSSProperties;
19
- hasComputedOnce: boolean;
20
37
  updateStyles: () => void;
21
38
  debouncedUpdateStyles: import("lodash").DebouncedFunc<() => void>;
22
- mutableUpdateStyles: import("react").MutableRefObject<() => void>;
23
- resetVisibilityOnly: () => void;
39
+ mutableUpdateStyles: React.MutableRefObject<() => void>;
40
+ resetStyles: () => void;
24
41
  };
25
42
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-floating-context",
3
- "version": "3.55.0-next.9",
3
+ "version": "3.55.2",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Popper Hook",
6
6
  "files": [
@@ -36,15 +36,15 @@
36
36
  "indent": 4
37
37
  },
38
38
  "dependencies": {
39
- "@elliemae/ds-hooks-headless-tooltip": "3.55.0-next.9",
40
- "@elliemae/ds-props-helpers": "3.55.0-next.9",
41
- "@elliemae/ds-system": "3.55.0-next.9",
42
- "@elliemae/ds-typescript-helpers": "3.55.0-next.9"
39
+ "@elliemae/ds-hooks-headless-tooltip": "3.55.2",
40
+ "@elliemae/ds-system": "3.55.2",
41
+ "@elliemae/ds-typescript-helpers": "3.55.2",
42
+ "@elliemae/ds-props-helpers": "3.55.2"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@elliemae/pui-cli": "9.0.0-next.65",
46
46
  "jest": "~29.7.0",
47
- "@elliemae/ds-monorepo-devops": "3.55.0-next.9"
47
+ "@elliemae/ds-monorepo-devops": "3.55.2"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "lodash-es": "^4.17.21",
@@ -59,7 +59,7 @@
59
59
  },
60
60
  "scripts": {
61
61
  "dev": "cross-env NODE_ENV=development node ../../../scripts/build/build.mjs --watch",
62
- "test": "[ -n \"$CI\" ] || playwright test -c ./playwright.config.mjs && pui-cli test --passWithNoTests --coverage=\"false\"",
62
+ "test": "pui-cli test --passWithNoTests --coverage=\"false\"",
63
63
  "lint": "node ../../../scripts/lint.mjs --fix",
64
64
  "lint:strict": "node ../../../scripts/lint-strict.mjs",
65
65
  "dts": "node ../../../scripts/dts.mjs",
@@ -1,94 +0,0 @@
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 __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (let key of __getOwnPropNames(from))
11
- if (!__hasOwnProp.call(to, key) && key !== except)
12
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
- }
14
- return to;
15
- };
16
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
- // If the importer is in node compatibility mode or this is not an ESM
18
- // file that has been converted to a CommonJS file using a Babel-
19
- // compatible transform (i.e. "__esModule" has not been set), then set
20
- // "default" to the CommonJS "module.exports" for node compatibility.
21
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
- mod
23
- ));
24
- var React = __toESM(require("react"));
25
- var import_jsx_runtime = require("react/jsx-runtime");
26
- var import_react = __toESM(require("react"));
27
- var import__ = require("../index.js");
28
- const testOptionalProps = {};
29
- const testPartialDefaults = {
30
- withoutAnimation: false,
31
- withoutPortal: false,
32
- animationDuration: 300
33
- };
34
- const testCompleteDefaults = {
35
- withoutAnimation: false,
36
- withoutPortal: false,
37
- animationDuration: 300,
38
- placement: "top",
39
- customOffset: [10, 10],
40
- portalDOMContainer: document.body
41
- };
42
- const testInternalProps = {
43
- ...testOptionalProps,
44
- ...testCompleteDefaults
45
- };
46
- const testInternalPropsAsSyntax = {
47
- ...testOptionalProps,
48
- ...testCompleteDefaults
49
- };
50
- const testExplicitDefinition = {
51
- animationDuration: 300,
52
- withoutAnimation: false,
53
- withoutPortal: false,
54
- placement: "top",
55
- customOffset: [10, 10],
56
- portalDOMContainer: document.body,
57
- ...testOptionalProps
58
- };
59
- const testInferedTypeCompatibility = {
60
- ...testOptionalProps,
61
- ...testPartialDefaults,
62
- animationDuration: 300
63
- };
64
- const testDefinitionAsConst = {
65
- animationDuration: 300,
66
- withoutAnimation: false,
67
- withoutPortal: false,
68
- placement: "top",
69
- portalDOMContainer: document.body
70
- };
71
- const ExampleUsageComponent = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
72
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
73
- import__.FloatingWrapper,
74
- {
75
- ...testExplicitDefinition,
76
- innerRef: import_react.default.createRef(),
77
- isOpen: true,
78
- floatingStyles: {},
79
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Content" })
80
- }
81
- ),
82
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
83
- import__.FloatingWrapper,
84
- {
85
- ...testInferedTypeCompatibility,
86
- innerRef: import_react.default.createRef(),
87
- isOpen: true,
88
- floatingStyles: {},
89
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Content" })
90
- }
91
- ),
92
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.FloatingWrapper, { ...testDefinitionAsConst, innerRef: import_react.default.createRef(), isOpen: true, floatingStyles: {}, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Content" }) })
93
- ] });
94
- //# sourceMappingURL=typescript-floating-context-valid.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/typescript-testing/typescript-floating-context-valid.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\nimport React from 'react';\nimport { FloatingWrapper } from '../index.js';\nimport type { DSHookFloatingContextT } from '../index.js';\n\n// test we expose the namespace and the namespace follows our deliverable conventions\ntype ComponentPropsForApp = DSHookFloatingContextT.Props;\ntype ComponentPropsInternals = DSHookFloatingContextT.InternalProps;\ntype ComponentPropsDefaultProps = DSHookFloatingContextT.DefaultProps;\ntype ComponentPropsOptionalProps = DSHookFloatingContextT.OptionalProps;\n\nconst testOptionalProps: ComponentPropsOptionalProps = {};\n\n// difference Props and InternalProps is that InternalProps has all the default props filled in\n// Props allows for partial defaults\nconst testPartialDefaults: Partial<ComponentPropsDefaultProps> = {\n withoutAnimation: false,\n withoutPortal: false,\n animationDuration: 300,\n};\n\n// InternalProps requires all defaults to be filled in\nconst testCompleteDefaults: Required<ComponentPropsDefaultProps> = {\n withoutAnimation: false,\n withoutPortal: false,\n animationDuration: 300,\n placement: 'top',\n customOffset: [10, 10],\n portalDOMContainer: document.body,\n};\n\nconst testInternalProps: ComponentPropsInternals = {\n ...testOptionalProps,\n ...testCompleteDefaults,\n};\n\nconst testInternalPropsAsSyntax = {\n ...testOptionalProps,\n ...testCompleteDefaults,\n} as ComponentPropsInternals;\n\n// using the explicit type definition, if there is an error, it will be marked on the key that is wrong\nconst testExplicitDefinition: ComponentPropsForApp = {\n animationDuration: 300,\n withoutAnimation: false,\n withoutPortal: false,\n placement: 'top',\n customOffset: [10, 10],\n portalDOMContainer: document.body,\n ...testOptionalProps,\n};\n\n// using the \"as\" syntax, if there is an error, it will be marking the whole object as wrong because it is not compatible with the type\nconst testInferedTypeCompatibility = {\n ...testOptionalProps,\n ...testPartialDefaults,\n animationDuration: 300,\n} as ComponentPropsForApp;\n\nconst testDefinitionAsConst = {\n animationDuration: 300,\n withoutAnimation: false,\n withoutPortal: false,\n placement: 'top',\n portalDOMContainer: document.body,\n} as const;\n\nconst ExampleUsageComponent = () => (\n <>\n {/* works with explicitly casted props, all syntaxes */}\n <FloatingWrapper\n {...testExplicitDefinition}\n innerRef={React.createRef<HTMLDivElement>()}\n isOpen\n floatingStyles={{}}\n >\n <div>Content</div>\n </FloatingWrapper>\n <FloatingWrapper\n {...testInferedTypeCompatibility}\n innerRef={React.createRef<HTMLDivElement>()}\n isOpen\n floatingStyles={{}}\n >\n <div>Content</div>\n </FloatingWrapper>\n <FloatingWrapper {...testDefinitionAsConst} innerRef={React.createRef<HTMLDivElement>()} isOpen floatingStyles={{}}>\n <div>Content</div>\n </FloatingWrapper>\n {/* works with inline values */}\n </>\n);\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA,YAAuB;ACoErB;AAnEF,mBAAkB;AAClB,eAAgC;AAShC,MAAM,oBAAiD,CAAC;AAIxD,MAAM,sBAA2D;AAAA,EAC/D,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,mBAAmB;AACrB;AAGA,MAAM,uBAA6D;AAAA,EACjE,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,WAAW;AAAA,EACX,cAAc,CAAC,IAAI,EAAE;AAAA,EACrB,oBAAoB,SAAS;AAC/B;AAEA,MAAM,oBAA6C;AAAA,EACjD,GAAG;AAAA,EACH,GAAG;AACL;AAEA,MAAM,4BAA4B;AAAA,EAChC,GAAG;AAAA,EACH,GAAG;AACL;AAGA,MAAM,yBAA+C;AAAA,EACnD,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,cAAc,CAAC,IAAI,EAAE;AAAA,EACrB,oBAAoB,SAAS;AAAA,EAC7B,GAAG;AACL;AAGA,MAAM,+BAA+B;AAAA,EACnC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,mBAAmB;AACrB;AAEA,MAAM,wBAAwB;AAAA,EAC5B,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,oBAAoB,SAAS;AAC/B;AAEA,MAAM,wBAAwB,MAC5B,4EAEE;AAAA;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,UAAU,aAAAA,QAAM,UAA0B;AAAA,MAC1C,QAAM;AAAA,MACN,gBAAgB,CAAC;AAAA,MAEjB,sDAAC,SAAI,qBAAO;AAAA;AAAA,EACd;AAAA,EACA;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,UAAU,aAAAA,QAAM,UAA0B;AAAA,MAC1C,QAAM;AAAA,MACN,gBAAgB,CAAC;AAAA,MAEjB,sDAAC,SAAI,qBAAO;AAAA;AAAA,EACd;AAAA,EACA,4CAAC,4BAAiB,GAAG,uBAAuB,UAAU,aAAAA,QAAM,UAA0B,GAAG,QAAM,MAAC,gBAAgB,CAAC,GAC/G,sDAAC,SAAI,qBAAO,GACd;AAAA,GAEF;",
6
- "names": ["React"]
7
- }
@@ -1,71 +0,0 @@
1
- import * as React from "react";
2
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import React2 from "react";
4
- import { FloatingWrapper } from "../index.js";
5
- const testOptionalProps = {};
6
- const testPartialDefaults = {
7
- withoutAnimation: false,
8
- withoutPortal: false,
9
- animationDuration: 300
10
- };
11
- const testCompleteDefaults = {
12
- withoutAnimation: false,
13
- withoutPortal: false,
14
- animationDuration: 300,
15
- placement: "top",
16
- customOffset: [10, 10],
17
- portalDOMContainer: document.body
18
- };
19
- const testInternalProps = {
20
- ...testOptionalProps,
21
- ...testCompleteDefaults
22
- };
23
- const testInternalPropsAsSyntax = {
24
- ...testOptionalProps,
25
- ...testCompleteDefaults
26
- };
27
- const testExplicitDefinition = {
28
- animationDuration: 300,
29
- withoutAnimation: false,
30
- withoutPortal: false,
31
- placement: "top",
32
- customOffset: [10, 10],
33
- portalDOMContainer: document.body,
34
- ...testOptionalProps
35
- };
36
- const testInferedTypeCompatibility = {
37
- ...testOptionalProps,
38
- ...testPartialDefaults,
39
- animationDuration: 300
40
- };
41
- const testDefinitionAsConst = {
42
- animationDuration: 300,
43
- withoutAnimation: false,
44
- withoutPortal: false,
45
- placement: "top",
46
- portalDOMContainer: document.body
47
- };
48
- const ExampleUsageComponent = () => /* @__PURE__ */ jsxs(Fragment, { children: [
49
- /* @__PURE__ */ jsx(
50
- FloatingWrapper,
51
- {
52
- ...testExplicitDefinition,
53
- innerRef: React2.createRef(),
54
- isOpen: true,
55
- floatingStyles: {},
56
- children: /* @__PURE__ */ jsx("div", { children: "Content" })
57
- }
58
- ),
59
- /* @__PURE__ */ jsx(
60
- FloatingWrapper,
61
- {
62
- ...testInferedTypeCompatibility,
63
- innerRef: React2.createRef(),
64
- isOpen: true,
65
- floatingStyles: {},
66
- children: /* @__PURE__ */ jsx("div", { children: "Content" })
67
- }
68
- ),
69
- /* @__PURE__ */ jsx(FloatingWrapper, { ...testDefinitionAsConst, innerRef: React2.createRef(), isOpen: true, floatingStyles: {}, children: /* @__PURE__ */ jsx("div", { children: "Content" }) })
70
- ] });
71
- //# sourceMappingURL=typescript-floating-context-valid.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/typescript-testing/typescript-floating-context-valid.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\nimport React from 'react';\nimport { FloatingWrapper } from '../index.js';\nimport type { DSHookFloatingContextT } from '../index.js';\n\n// test we expose the namespace and the namespace follows our deliverable conventions\ntype ComponentPropsForApp = DSHookFloatingContextT.Props;\ntype ComponentPropsInternals = DSHookFloatingContextT.InternalProps;\ntype ComponentPropsDefaultProps = DSHookFloatingContextT.DefaultProps;\ntype ComponentPropsOptionalProps = DSHookFloatingContextT.OptionalProps;\n\nconst testOptionalProps: ComponentPropsOptionalProps = {};\n\n// difference Props and InternalProps is that InternalProps has all the default props filled in\n// Props allows for partial defaults\nconst testPartialDefaults: Partial<ComponentPropsDefaultProps> = {\n withoutAnimation: false,\n withoutPortal: false,\n animationDuration: 300,\n};\n\n// InternalProps requires all defaults to be filled in\nconst testCompleteDefaults: Required<ComponentPropsDefaultProps> = {\n withoutAnimation: false,\n withoutPortal: false,\n animationDuration: 300,\n placement: 'top',\n customOffset: [10, 10],\n portalDOMContainer: document.body,\n};\n\nconst testInternalProps: ComponentPropsInternals = {\n ...testOptionalProps,\n ...testCompleteDefaults,\n};\n\nconst testInternalPropsAsSyntax = {\n ...testOptionalProps,\n ...testCompleteDefaults,\n} as ComponentPropsInternals;\n\n// using the explicit type definition, if there is an error, it will be marked on the key that is wrong\nconst testExplicitDefinition: ComponentPropsForApp = {\n animationDuration: 300,\n withoutAnimation: false,\n withoutPortal: false,\n placement: 'top',\n customOffset: [10, 10],\n portalDOMContainer: document.body,\n ...testOptionalProps,\n};\n\n// using the \"as\" syntax, if there is an error, it will be marking the whole object as wrong because it is not compatible with the type\nconst testInferedTypeCompatibility = {\n ...testOptionalProps,\n ...testPartialDefaults,\n animationDuration: 300,\n} as ComponentPropsForApp;\n\nconst testDefinitionAsConst = {\n animationDuration: 300,\n withoutAnimation: false,\n withoutPortal: false,\n placement: 'top',\n portalDOMContainer: document.body,\n} as const;\n\nconst ExampleUsageComponent = () => (\n <>\n {/* works with explicitly casted props, all syntaxes */}\n <FloatingWrapper\n {...testExplicitDefinition}\n innerRef={React.createRef<HTMLDivElement>()}\n isOpen\n floatingStyles={{}}\n >\n <div>Content</div>\n </FloatingWrapper>\n <FloatingWrapper\n {...testInferedTypeCompatibility}\n innerRef={React.createRef<HTMLDivElement>()}\n isOpen\n floatingStyles={{}}\n >\n <div>Content</div>\n </FloatingWrapper>\n <FloatingWrapper {...testDefinitionAsConst} innerRef={React.createRef<HTMLDivElement>()} isOpen floatingStyles={{}}>\n <div>Content</div>\n </FloatingWrapper>\n {/* works with inline values */}\n </>\n);\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACoErB,mBAQI,KARJ;AAnEF,OAAOA,YAAW;AAClB,SAAS,uBAAuB;AAShC,MAAM,oBAAiD,CAAC;AAIxD,MAAM,sBAA2D;AAAA,EAC/D,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,mBAAmB;AACrB;AAGA,MAAM,uBAA6D;AAAA,EACjE,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,WAAW;AAAA,EACX,cAAc,CAAC,IAAI,EAAE;AAAA,EACrB,oBAAoB,SAAS;AAC/B;AAEA,MAAM,oBAA6C;AAAA,EACjD,GAAG;AAAA,EACH,GAAG;AACL;AAEA,MAAM,4BAA4B;AAAA,EAChC,GAAG;AAAA,EACH,GAAG;AACL;AAGA,MAAM,yBAA+C;AAAA,EACnD,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,cAAc,CAAC,IAAI,EAAE;AAAA,EACrB,oBAAoB,SAAS;AAAA,EAC7B,GAAG;AACL;AAGA,MAAM,+BAA+B;AAAA,EACnC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,mBAAmB;AACrB;AAEA,MAAM,wBAAwB;AAAA,EAC5B,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,oBAAoB,SAAS;AAC/B;AAEA,MAAM,wBAAwB,MAC5B,iCAEE;AAAA;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,UAAUA,OAAM,UAA0B;AAAA,MAC1C,QAAM;AAAA,MACN,gBAAgB,CAAC;AAAA,MAEjB,8BAAC,SAAI,qBAAO;AAAA;AAAA,EACd;AAAA,EACA;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,UAAUA,OAAM,UAA0B;AAAA,MAC1C,QAAM;AAAA,MACN,gBAAgB,CAAC;AAAA,MAEjB,8BAAC,SAAI,qBAAO;AAAA;AAAA,EACd;AAAA,EACA,oBAAC,mBAAiB,GAAG,uBAAuB,UAAUA,OAAM,UAA0B,GAAG,QAAM,MAAC,gBAAgB,CAAC,GAC/G,8BAAC,SAAI,qBAAO,GACd;AAAA,GAEF;",
6
- "names": ["React"]
7
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};