@elliemae/ds-floating-context 3.49.3 → 3.49.5

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.
@@ -52,15 +52,30 @@ const useFloatingContext = (props = {}) => {
52
52
  customOffset,
53
53
  placementOrderPreference,
54
54
  onOpen,
55
- onClose
55
+ onClose,
56
+ externallyControlledIsOpen
56
57
  } = propsWithDefault;
57
- const tooltipHelpers = (0, import_ds_hooks_headless_tooltip.useHeadlessTooltip)({ onOpen, onClose });
58
+ const [internalIsOpen, setInternalIsOpen] = import_react.default.useState(false);
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
+ setInternalIsOpen(true);
65
+ onOpen?.();
66
+ }, [onOpen]);
67
+ const overChargedOnClose = import_react.default.useCallback(() => {
68
+ setInternalIsOpen(false);
69
+ onClose?.();
70
+ }, [onClose]);
71
+ const tooltipHelpers = (0, import_ds_hooks_headless_tooltip.useHeadlessTooltip)({ onOpen: overChargedOnOpen, onClose: overChargedOnClose });
58
72
  const { setReferenceElement, hideTooltip, showTooltip } = tooltipHelpers;
59
73
  const [floatingStyles, setFloatingStyles] = (0, import_react.useState)({
60
74
  position: "absolute",
61
75
  zIndex: 3e3,
62
76
  top: 0,
63
- left: 0
77
+ left: 0,
78
+ visibility: "hidden"
64
79
  });
65
80
  const [arrowStyles, setArrowStyles] = (0, import_react.useState)({
66
81
  style: { left: 0 },
@@ -70,7 +85,7 @@ const useFloatingContext = (props = {}) => {
70
85
  const [floating, setFloating] = import_react.default.useState(null);
71
86
  (0, import_react.useEffect)(() => {
72
87
  const update = () => {
73
- if (reference && floating) {
88
+ if (isOpenSourceOfTruth && reference && floating) {
74
89
  const { coordsStyle, finalPlacement, coordsArrow } = (0, import_computePosition.computePosition)({
75
90
  reference,
76
91
  floating,
@@ -82,8 +97,8 @@ const useFloatingContext = (props = {}) => {
82
97
  const styles = {
83
98
  position: "absolute",
84
99
  zIndex: 3e3,
85
- top: 0,
86
- left: 0,
100
+ // top: 0,
101
+ // left: 0,
87
102
  ...coordsStyle
88
103
  };
89
104
  setFloatingStyles(styles);
@@ -96,7 +111,7 @@ const useFloatingContext = (props = {}) => {
96
111
  return () => {
97
112
  window.removeEventListener("scroll", debouncedCb);
98
113
  };
99
- }, [reference, floating, placement, placementOrderPreference, customOffset, withoutPortal]);
114
+ }, [reference, floating, placement, placementOrderPreference, customOffset, withoutPortal, isOpenSourceOfTruth]);
100
115
  const setReference = (0, import_ds_system.mergeRefs)(_setReference, setReferenceElement);
101
116
  const refs = import_react.default.useMemo(
102
117
  () => ({
@@ -121,7 +136,7 @@ const useFloatingContext = (props = {}) => {
121
136
  refs,
122
137
  floatingStyles,
123
138
  handlers,
124
- isOpen: tooltipHelpers.shouldShowPopover,
139
+ isOpen: isOpenSourceOfTruth,
125
140
  arrowStyles,
126
141
  hideTooltip,
127
142
  showTooltip,
@@ -133,17 +148,17 @@ const useFloatingContext = (props = {}) => {
133
148
  }
134
149
  }),
135
150
  [
136
- animationDuration,
137
- arrowStyles,
151
+ refs,
138
152
  floatingStyles,
139
153
  handlers,
154
+ isOpenSourceOfTruth,
155
+ arrowStyles,
140
156
  hideTooltip,
141
- portalDOMContainer,
142
- refs,
143
157
  showTooltip,
144
- tooltipHelpers.shouldShowPopover,
158
+ withoutPortal,
145
159
  withoutAnimation,
146
- withoutPortal
160
+ portalDOMContainer,
161
+ animationDuration
147
162
  ]
148
163
  );
149
164
  };
@@ -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 no-nested-ternary */\n/* eslint-disable arrow-body-style */\n/* eslint-disable no-unused-vars */\n/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable @typescript-eslint/no-use-before-define */\nimport React, { useState, useEffect, useMemo } from 'react';\nimport { debounce } from 'lodash';\nimport {\n useMemoMergePropsWithDefault,\n useValidateTypescriptPropTypes,\n describe,\n type ValidationMap,\n} from '@elliemae/ds-props-helpers';\nimport { useHeadlessTooltip } from '@elliemae/ds-hooks-headless-tooltip';\nimport { type CSSProperties } from 'styled-components';\nimport { mergeRefs } from '@elliemae/ds-system';\nimport { computePosition } from './utils/computePosition.js';\nimport type { DSHookFloatingContextT } from './react-desc-prop-types.js';\nimport { defaultProps, DSFloatingContextPropTypes } from './react-desc-prop-types.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 } = propsWithDefault;\n\n const tooltipHelpers = useHeadlessTooltip({ onOpen, onClose });\n\n const { setReferenceElement, hideTooltip, showTooltip } = tooltipHelpers;\n const [floatingStyles, setFloatingStyles] = useState<CSSProperties>({\n position: 'absolute',\n zIndex: 3000,\n top: 0,\n left: 0,\n });\n const [arrowStyles, setArrowStyles] = useState<{ style: CSSProperties; placement: string }>({\n style: { left: 0 },\n placement: 'top',\n });\n\n const [reference, _setReference] = React.useState<Element | null>(null);\n const [floating, setFloating] = React.useState<HTMLElement | null>(null);\n useEffect(() => {\n const update = () => {\n if (reference && floating) {\n const { coordsStyle, finalPlacement, coordsArrow } = computePosition({\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n });\n\n const styles: CSSProperties = {\n position: 'absolute',\n zIndex: 3000,\n top: 0,\n left: 0,\n ...coordsStyle,\n };\n setFloatingStyles(styles);\n setArrowStyles({ style: coordsArrow, placement: finalPlacement });\n }\n };\n\n // initial position calculation\n update();\n\n const debouncedCb = debounce(update, 300);\n\n // auto update position on scrolling\n window.addEventListener('scroll', debouncedCb);\n\n return () => {\n window.removeEventListener('scroll', debouncedCb);\n };\n }, [reference, floating, placement, placementOrderPreference, customOffset, withoutPortal]);\n\n const setReference = mergeRefs(_setReference, setReferenceElement);\n\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: tooltipHelpers.shouldShowPopover,\n arrowStyles,\n hideTooltip,\n showTooltip,\n context: {\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\n },\n }),\n [\n animationDuration,\n arrowStyles,\n floatingStyles,\n handlers,\n hideTooltip,\n portalDOMContainer,\n refs,\n showTooltip,\n tooltipHelpers.shouldShowPopover,\n withoutAnimation,\n withoutPortal,\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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",
4
+ "sourcesContent": ["/* eslint-disable no-nested-ternary */\n/* eslint-disable arrow-body-style */\n/* eslint-disable no-unused-vars */\n/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable @typescript-eslint/no-use-before-define */\nimport React, { useState, useEffect, useMemo } from 'react';\nimport { debounce } from 'lodash';\nimport {\n useMemoMergePropsWithDefault,\n useValidateTypescriptPropTypes,\n describe,\n type ValidationMap,\n} from '@elliemae/ds-props-helpers';\nimport { useHeadlessTooltip } from '@elliemae/ds-hooks-headless-tooltip';\nimport { type CSSProperties } from 'styled-components';\nimport { mergeRefs } from '@elliemae/ds-system';\nimport { computePosition } from './utils/computePosition.js';\nimport type { DSHookFloatingContextT } from './react-desc-prop-types.js';\nimport { defaultProps, DSFloatingContextPropTypes } from './react-desc-prop-types.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\n const { setReferenceElement, hideTooltip, showTooltip } = tooltipHelpers;\n const [floatingStyles, setFloatingStyles] = useState<CSSProperties>({\n position: 'absolute',\n zIndex: 3000,\n top: 0,\n left: 0,\n visibility: 'hidden',\n });\n const [arrowStyles, setArrowStyles] = useState<{ style: CSSProperties; placement: string }>({\n style: { left: 0 },\n placement: 'top',\n });\n\n const [reference, _setReference] = React.useState<Element | null>(null);\n const [floating, setFloating] = React.useState<HTMLElement | null>(null);\n useEffect(() => {\n const update = () => {\n if (isOpenSourceOfTruth && reference && floating) {\n const { coordsStyle, finalPlacement, coordsArrow } = computePosition({\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n });\n\n const styles: CSSProperties = {\n position: 'absolute',\n zIndex: 3000,\n // top: 0,\n // left: 0,\n ...coordsStyle,\n };\n\n setFloatingStyles(styles);\n setArrowStyles({ style: coordsArrow, placement: finalPlacement });\n }\n };\n\n // initial position calculation\n update();\n\n const debouncedCb = debounce(update, 300);\n\n // auto update position on scrolling\n window.addEventListener('scroll', debouncedCb);\n\n return () => {\n window.removeEventListener('scroll', debouncedCb);\n };\n }, [reference, floating, placement, placementOrderPreference, customOffset, withoutPortal, isOpenSourceOfTruth]);\n\n const setReference = mergeRefs(_setReference, setReferenceElement);\n\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 }),\n [\n refs,\n floatingStyles,\n handlers,\n isOpenSourceOfTruth,\n arrowStyles,\n hideTooltip,\n showTooltip,\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\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
  }
@@ -76,6 +76,9 @@ const DSFloatingContextPropTypes = {
76
76
  import_ds_props_helpers.PropTypes.tuple([import_ds_props_helpers.PropTypes.oneOf(["left-start"])])
77
77
  ]).description("The order of the placement preference."),
78
78
  onOpen: import_ds_props_helpers.PropTypes.func.description("Callback when the tooltip is opened."),
79
- onClose: import_ds_props_helpers.PropTypes.func.description("Callback when the tooltip is closed.")
79
+ onClose: import_ds_props_helpers.PropTypes.func.description("Callback when the tooltip is closed."),
80
+ externallyControlledIsOpen: import_ds_props_helpers.PropTypes.bool.description(
81
+ "If true, the context open/close state will be controlled externally."
82
+ )
80
83
  };
81
84
  //# sourceMappingURL=react-desc-prop-types.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/react-desc-prop-types.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { DSPropTypesSchema } from '@elliemae/ds-props-helpers';\nimport { PropTypes } from '@elliemae/ds-props-helpers';\nexport declare namespace DSHookFloatingContextT {\n export interface DefaultProps {\n withoutPortal: boolean;\n withoutAnimation: boolean;\n portalDOMContainer?: HTMLElement;\n animationDuration: number;\n placement: PopperPlacementsT;\n customOffset: [number, number];\n }\n\n export interface OptionalProps {\n placementOrderPreference?: PopperPlacementsT[];\n onOpen?: () => void;\n onClose?: () => void;\n }\n export interface Props extends Partial<DefaultProps>, OptionalProps {}\n\n export interface InternalProps extends DefaultProps, OptionalProps {}\n\n export type PopperPlacementsT =\n | 'top-start'\n | 'top'\n | 'top-end'\n | 'right-start'\n | 'right'\n | 'right-end'\n | 'bottom-end'\n | 'bottom'\n | 'bottom-start'\n | 'left-end'\n | 'left'\n | 'left-start';\n}\n\nexport const defaultProps: DSHookFloatingContextT.DefaultProps = {\n withoutAnimation: false,\n animationDuration: 300,\n withoutPortal: false,\n placement: 'top',\n customOffset: [0, 12],\n};\n\nexport const DSFloatingContextPropTypes: DSPropTypesSchema<DSHookFloatingContextT.Props> = {\n withoutPortal: PropTypes.bool\n .description('If true, the tooltip will not be rendered inside a portal.')\n .defaultValue(false),\n withoutAnimation: PropTypes.bool.description('If true, the tooltip will not have an animation.').defaultValue(false),\n portalDOMContainer: PropTypes.instanceOf(HTMLElement)\n .description('The DOM element where the tooltip will be rendered.')\n .defaultValue('the first \"main\" landmark available in the document or the body if no \"main\" is found'),\n animationDuration: PropTypes.number.description('The duration of the animation in milliseconds.').defaultValue(300),\n placement: PropTypes.oneOf([\n 'top-start',\n 'top',\n 'top-end',\n 'right-start',\n 'right',\n 'right-end',\n 'bottom-end',\n 'bottom',\n 'bottom-start',\n 'left-end',\n 'left',\n 'left-start',\n ])\n .description('The placement of the tooltip.')\n .defaultValue('top'),\n customOffset: PropTypes.arrayOf(PropTypes.number)\n .description('The custom offset of the tooltip.')\n .defaultValue([12, 12]),\n placementOrderPreference: PropTypes.oneOfType([\n PropTypes.tuple([PropTypes.oneOf(['top-start'])]),\n PropTypes.tuple([PropTypes.oneOf(['top'])]),\n PropTypes.tuple([PropTypes.oneOf(['top-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['right-start'])]),\n PropTypes.tuple([PropTypes.oneOf(['right'])]),\n PropTypes.tuple([PropTypes.oneOf(['right-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['bottom-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['bottom'])]),\n PropTypes.tuple([PropTypes.oneOf(['bottom-start'])]),\n PropTypes.tuple([PropTypes.oneOf(['left-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['left'])]),\n PropTypes.tuple([PropTypes.oneOf(['left-start'])]),\n ]).description('The order of the placement preference.'),\n onOpen: PropTypes.func.description('Callback when the tooltip is opened.'),\n onClose: PropTypes.func.description('Callback when the tooltip is closed.'),\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADEvB,8BAA0B;AAmCnB,MAAM,eAAoD;AAAA,EAC/D,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,cAAc,CAAC,GAAG,EAAE;AACtB;AAEO,MAAM,6BAA8E;AAAA,EACzF,eAAe,kCAAU,KACtB,YAAY,4DAA4D,EACxE,aAAa,KAAK;AAAA,EACrB,kBAAkB,kCAAU,KAAK,YAAY,kDAAkD,EAAE,aAAa,KAAK;AAAA,EACnH,oBAAoB,kCAAU,WAAW,WAAW,EACjD,YAAY,qDAAqD,EACjE,aAAa,uFAAuF;AAAA,EACvG,mBAAmB,kCAAU,OAAO,YAAY,gDAAgD,EAAE,aAAa,GAAG;AAAA,EAClH,WAAW,kCAAU,MAAM;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,EACE,YAAY,+BAA+B,EAC3C,aAAa,KAAK;AAAA,EACrB,cAAc,kCAAU,QAAQ,kCAAU,MAAM,EAC7C,YAAY,mCAAmC,EAC/C,aAAa,CAAC,IAAI,EAAE,CAAC;AAAA,EACxB,0BAA0B,kCAAU,UAAU;AAAA,IAC5C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AAAA,IAChD,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAAA,IAC1C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AAAA,IAC9C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;AAAA,IAClD,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AAAA,IAC5C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AAAA,IAChD,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;AAAA,IACjD,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;AAAA,IAC7C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;AAAA,IACnD,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAAA,IAC/C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AAAA,IAC3C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;AAAA,EACnD,CAAC,EAAE,YAAY,wCAAwC;AAAA,EACvD,QAAQ,kCAAU,KAAK,YAAY,sCAAsC;AAAA,EACzE,SAAS,kCAAU,KAAK,YAAY,sCAAsC;AAC5E;",
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { DSPropTypesSchema } from '@elliemae/ds-props-helpers';\nimport { PropTypes } from '@elliemae/ds-props-helpers';\nexport declare namespace DSHookFloatingContextT {\n export interface DefaultProps {\n withoutPortal: boolean;\n withoutAnimation: boolean;\n portalDOMContainer?: HTMLElement;\n animationDuration: number;\n placement: PopperPlacementsT;\n customOffset: [number, number];\n }\n\n export interface OptionalProps {\n placementOrderPreference?: PopperPlacementsT[];\n onOpen?: () => void;\n onClose?: () => void;\n externallyControlledIsOpen?: boolean;\n }\n export interface Props extends Partial<DefaultProps>, OptionalProps {}\n\n export interface InternalProps extends DefaultProps, OptionalProps {}\n\n export type PopperPlacementsT =\n | 'top-start'\n | 'top'\n | 'top-end'\n | 'right-start'\n | 'right'\n | 'right-end'\n | 'bottom-end'\n | 'bottom'\n | 'bottom-start'\n | 'left-end'\n | 'left'\n | 'left-start';\n}\n\nexport const defaultProps: DSHookFloatingContextT.DefaultProps = {\n withoutAnimation: false,\n animationDuration: 300,\n withoutPortal: false,\n placement: 'top',\n customOffset: [0, 12],\n};\n\nexport const DSFloatingContextPropTypes: DSPropTypesSchema<DSHookFloatingContextT.Props> = {\n withoutPortal: PropTypes.bool\n .description('If true, the tooltip will not be rendered inside a portal.')\n .defaultValue(false),\n withoutAnimation: PropTypes.bool.description('If true, the tooltip will not have an animation.').defaultValue(false),\n portalDOMContainer: PropTypes.instanceOf(HTMLElement)\n .description('The DOM element where the tooltip will be rendered.')\n .defaultValue('the first \"main\" landmark available in the document or the body if no \"main\" is found'),\n animationDuration: PropTypes.number.description('The duration of the animation in milliseconds.').defaultValue(300),\n placement: PropTypes.oneOf([\n 'top-start',\n 'top',\n 'top-end',\n 'right-start',\n 'right',\n 'right-end',\n 'bottom-end',\n 'bottom',\n 'bottom-start',\n 'left-end',\n 'left',\n 'left-start',\n ])\n .description('The placement of the tooltip.')\n .defaultValue('top'),\n customOffset: PropTypes.arrayOf(PropTypes.number)\n .description('The custom offset of the tooltip.')\n .defaultValue([12, 12]),\n placementOrderPreference: PropTypes.oneOfType([\n PropTypes.tuple([PropTypes.oneOf(['top-start'])]),\n PropTypes.tuple([PropTypes.oneOf(['top'])]),\n PropTypes.tuple([PropTypes.oneOf(['top-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['right-start'])]),\n PropTypes.tuple([PropTypes.oneOf(['right'])]),\n PropTypes.tuple([PropTypes.oneOf(['right-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['bottom-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['bottom'])]),\n PropTypes.tuple([PropTypes.oneOf(['bottom-start'])]),\n PropTypes.tuple([PropTypes.oneOf(['left-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['left'])]),\n PropTypes.tuple([PropTypes.oneOf(['left-start'])]),\n ]).description('The order of the placement preference.'),\n onOpen: PropTypes.func.description('Callback when the tooltip is opened.'),\n onClose: PropTypes.func.description('Callback when the tooltip is closed.'),\n externallyControlledIsOpen: PropTypes.bool.description(\n 'If true, the context open/close state will be controlled externally.',\n ),\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADEvB,8BAA0B;AAoCnB,MAAM,eAAoD;AAAA,EAC/D,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,cAAc,CAAC,GAAG,EAAE;AACtB;AAEO,MAAM,6BAA8E;AAAA,EACzF,eAAe,kCAAU,KACtB,YAAY,4DAA4D,EACxE,aAAa,KAAK;AAAA,EACrB,kBAAkB,kCAAU,KAAK,YAAY,kDAAkD,EAAE,aAAa,KAAK;AAAA,EACnH,oBAAoB,kCAAU,WAAW,WAAW,EACjD,YAAY,qDAAqD,EACjE,aAAa,uFAAuF;AAAA,EACvG,mBAAmB,kCAAU,OAAO,YAAY,gDAAgD,EAAE,aAAa,GAAG;AAAA,EAClH,WAAW,kCAAU,MAAM;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,EACE,YAAY,+BAA+B,EAC3C,aAAa,KAAK;AAAA,EACrB,cAAc,kCAAU,QAAQ,kCAAU,MAAM,EAC7C,YAAY,mCAAmC,EAC/C,aAAa,CAAC,IAAI,EAAE,CAAC;AAAA,EACxB,0BAA0B,kCAAU,UAAU;AAAA,IAC5C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AAAA,IAChD,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAAA,IAC1C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AAAA,IAC9C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;AAAA,IAClD,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AAAA,IAC5C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AAAA,IAChD,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;AAAA,IACjD,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;AAAA,IAC7C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;AAAA,IACnD,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAAA,IAC/C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AAAA,IAC3C,kCAAU,MAAM,CAAC,kCAAU,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;AAAA,EACnD,CAAC,EAAE,YAAY,wCAAwC;AAAA,EACvD,QAAQ,kCAAU,KAAK,YAAY,sCAAsC;AAAA,EACzE,SAAS,kCAAU,KAAK,YAAY,sCAAsC;AAAA,EAC1E,4BAA4B,kCAAU,KAAK;AAAA,IACzC;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -97,7 +97,15 @@ const computePosition = (props) => {
97
97
  }
98
98
  }
99
99
  return {
100
- coordsStyle: { transform: `translate(${coords.left}px, ${coords.top}px)` },
100
+ coordsStyle: {
101
+ left: 0,
102
+ top: 0,
103
+ // we use transform -> translate because we know final computed left/top probably "split a pixel" (e.g. 10.005px)
104
+ // when we use transform we force the browser to use hardware acceleration
105
+ // hardware acceleration is faster and more reliable than the browser's own rounding
106
+ // it also helps with css animations and so on
107
+ transform: `translate(${coords.left}px, ${coords.top}px)`
108
+ },
101
109
  finalPlacement,
102
110
  coordsArrow: (0, import_getArrowOffset.getArrowOffset)(finalPlacement, isVertical)
103
111
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/utils/computePosition.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable no-nested-ternary */\n/* eslint-disable complexity */\n/* eslint-disable max-statements */\n/* eslint-disable @typescript-eslint/no-use-before-define */\n/* eslint-disable max-params */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable arrow-body-style */\nimport type { DSHookFloatingContextT } from '../react-desc-prop-types.js';\nimport { getExpandedFallbackPlacements } from './getExpandedFallbackPlacements.js';\nimport { getArrowOffset } from './getArrowOffset.js';\nimport getOppositePlacement from './getOppositePlacement.js';\nimport { detectOverflow } from './detectOverflow.js';\n\ninterface ComputePositionProps {\n reference: Element;\n floating: HTMLElement;\n placement: DSHookFloatingContextT.PopperPlacementsT;\n placementOrderPreference?: DSHookFloatingContextT.PopperPlacementsT[];\n customOffset: [number, number];\n withoutPortal: boolean;\n}\n\nconst findFixedParent = (el: Element | null) => {\n let element = el;\n while (element && element !== document.body) {\n const style = getComputedStyle(element);\n if (style.position === 'fixed' || style.position === 'absolute') {\n return element;\n }\n element = element.parentElement;\n }\n return null;\n};\n\nconst adjustForFixedParent = (child: Element) => {\n const fixedParent = findFixedParent(child);\n if (fixedParent) {\n const rect = fixedParent.getBoundingClientRect();\n return { top: rect.top, left: rect.left };\n }\n return {\n top: 0,\n left: 0,\n };\n};\n\nexport const computePosition = (props: ComputePositionProps) => {\n const { reference, floating, placement, placementOrderPreference, customOffset, withoutPortal } = props;\n\n const parentOffsets = withoutPortal\n ? adjustForFixedParent(reference)\n : {\n top: 0,\n left: 0,\n };\n const referenceRect = reference.getBoundingClientRect();\n const floatingRect = floating.getBoundingClientRect();\n\n const variationPlacement = placement.split('-')[1];\n const fallbackPlacements = placementOrderPreference || getExpandedFallbackPlacements(placement);\n\n const coords: { top?: number; left?: number; bottom?: number; right?: number } = {};\n\n let isVertical = false;\n const placements = [placement].concat(fallbackPlacements as DSHookFloatingContextT.PopperPlacementsT[]);\n let finalPlacement = '';\n\n for (let i = 0; i < placements.length; i += 1) {\n const currentPlacement = placements[i];\n\n const currentBasePlacement = currentPlacement.split('-')[0] as keyof typeof coords;\n isVertical = ['top', 'bottom'].indexOf(currentBasePlacement) >= 0;\n\n const overflows = detectOverflow(referenceRect, floatingRect, currentPlacement, customOffset);\n\n const checks: boolean[] = [];\n\n const isStartVariation = variationPlacement === 'start';\n\n let mainVariationSide: keyof typeof coords = isVertical\n ? isStartVariation\n ? 'right'\n : 'left'\n : isStartVariation\n ? 'bottom'\n : 'top';\n\n const len = isVertical ? 'width' : 'height';\n\n if (referenceRect[len] > floatingRect[len]) {\n mainVariationSide = getOppositePlacement(mainVariationSide) as keyof typeof coords;\n }\n\n const altVariationSide = getOppositePlacement(mainVariationSide) as keyof typeof coords;\n\n checks.push(overflows[currentBasePlacement] <= 0);\n checks.push(overflows[mainVariationSide] <= 0, overflows[altVariationSide] <= 0);\n\n if (\n checks.every((check) => {\n return check;\n })\n ) {\n coords.top = -overflows.top + window.scrollY - parentOffsets.top;\n coords.left = -overflows.left + window.scrollX - parentOffsets.left;\n finalPlacement = currentPlacement;\n\n break;\n }\n }\n\n return {\n coordsStyle: { transform: `translate(${coords.left}px, ${coords.top}px)` },\n finalPlacement,\n coordsArrow: getArrowOffset(finalPlacement, isVertical),\n };\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADQvB,2CAA8C;AAC9C,4BAA+B;AAC/B,kCAAiC;AACjC,4BAA+B;AAW/B,MAAM,kBAAkB,CAAC,OAAuB;AAC9C,MAAI,UAAU;AACd,SAAO,WAAW,YAAY,SAAS,MAAM;AAC3C,UAAM,QAAQ,iBAAiB,OAAO;AACtC,QAAI,MAAM,aAAa,WAAW,MAAM,aAAa,YAAY;AAC/D,aAAO;AAAA,IACT;AACA,cAAU,QAAQ;AAAA,EACpB;AACA,SAAO;AACT;AAEA,MAAM,uBAAuB,CAAC,UAAmB;AAC/C,QAAM,cAAc,gBAAgB,KAAK;AACzC,MAAI,aAAa;AACf,UAAM,OAAO,YAAY,sBAAsB;AAC/C,WAAO,EAAE,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK;AAAA,EAC1C;AACA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACF;AAEO,MAAM,kBAAkB,CAAC,UAAgC;AAC9D,QAAM,EAAE,WAAW,UAAU,WAAW,0BAA0B,cAAc,cAAc,IAAI;AAElG,QAAM,gBAAgB,gBAClB,qBAAqB,SAAS,IAC9B;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACJ,QAAM,gBAAgB,UAAU,sBAAsB;AACtD,QAAM,eAAe,SAAS,sBAAsB;AAEpD,QAAM,qBAAqB,UAAU,MAAM,GAAG,EAAE,CAAC;AACjD,QAAM,qBAAqB,gCAA4B,oEAA8B,SAAS;AAE9F,QAAM,SAA2E,CAAC;AAElF,MAAI,aAAa;AACjB,QAAM,aAAa,CAAC,SAAS,EAAE,OAAO,kBAAgE;AACtG,MAAI,iBAAiB;AAErB,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK,GAAG;AAC7C,UAAM,mBAAmB,WAAW,CAAC;AAErC,UAAM,uBAAuB,iBAAiB,MAAM,GAAG,EAAE,CAAC;AAC1D,iBAAa,CAAC,OAAO,QAAQ,EAAE,QAAQ,oBAAoB,KAAK;AAEhE,UAAM,gBAAY,sCAAe,eAAe,cAAc,kBAAkB,YAAY;AAE5F,UAAM,SAAoB,CAAC;AAE3B,UAAM,mBAAmB,uBAAuB;AAEhD,QAAI,oBAAyC,aACzC,mBACE,UACA,SACF,mBACA,WACA;AAEJ,UAAM,MAAM,aAAa,UAAU;AAEnC,QAAI,cAAc,GAAG,IAAI,aAAa,GAAG,GAAG;AAC1C,8BAAoB,4BAAAA,SAAqB,iBAAiB;AAAA,IAC5D;AAEA,UAAM,uBAAmB,4BAAAA,SAAqB,iBAAiB;AAE/D,WAAO,KAAK,UAAU,oBAAoB,KAAK,CAAC;AAChD,WAAO,KAAK,UAAU,iBAAiB,KAAK,GAAG,UAAU,gBAAgB,KAAK,CAAC;AAE/E,QACE,OAAO,MAAM,CAAC,UAAU;AACtB,aAAO;AAAA,IACT,CAAC,GACD;AACA,aAAO,MAAM,CAAC,UAAU,MAAM,OAAO,UAAU,cAAc;AAC7D,aAAO,OAAO,CAAC,UAAU,OAAO,OAAO,UAAU,cAAc;AAC/D,uBAAiB;AAEjB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa,EAAE,WAAW,aAAa,OAAO,IAAI,OAAO,OAAO,GAAG,MAAM;AAAA,IACzE;AAAA,IACA,iBAAa,sCAAe,gBAAgB,UAAU;AAAA,EACxD;AACF;",
4
+ "sourcesContent": ["/* eslint-disable no-nested-ternary */\n/* eslint-disable complexity */\n/* eslint-disable max-statements */\n/* eslint-disable @typescript-eslint/no-use-before-define */\n/* eslint-disable max-params */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable arrow-body-style */\nimport type { DSHookFloatingContextT } from '../react-desc-prop-types.js';\nimport { getExpandedFallbackPlacements } from './getExpandedFallbackPlacements.js';\nimport { getArrowOffset } from './getArrowOffset.js';\nimport getOppositePlacement from './getOppositePlacement.js';\nimport { detectOverflow } from './detectOverflow.js';\n\ninterface ComputePositionProps {\n reference: Element;\n floating: HTMLElement;\n placement: DSHookFloatingContextT.PopperPlacementsT;\n placementOrderPreference?: DSHookFloatingContextT.PopperPlacementsT[];\n customOffset: [number, number];\n withoutPortal: boolean;\n}\n\nconst findFixedParent = (el: Element | null) => {\n let element = el;\n while (element && element !== document.body) {\n const style = getComputedStyle(element);\n if (style.position === 'fixed' || style.position === 'absolute') {\n return element;\n }\n element = element.parentElement;\n }\n return null;\n};\n\nconst adjustForFixedParent = (child: Element) => {\n const fixedParent = findFixedParent(child);\n if (fixedParent) {\n const rect = fixedParent.getBoundingClientRect();\n return { top: rect.top, left: rect.left };\n }\n return {\n top: 0,\n left: 0,\n };\n};\n\nexport const computePosition = (props: ComputePositionProps) => {\n const { reference, floating, placement, placementOrderPreference, customOffset, withoutPortal } = props;\n\n const parentOffsets = withoutPortal\n ? adjustForFixedParent(reference)\n : {\n top: 0,\n left: 0,\n };\n const referenceRect = reference.getBoundingClientRect();\n const floatingRect = floating.getBoundingClientRect();\n\n const variationPlacement = placement.split('-')[1];\n const fallbackPlacements = placementOrderPreference || getExpandedFallbackPlacements(placement);\n\n const coords: { top?: number; left?: number; bottom?: number; right?: number } = {};\n\n let isVertical = false;\n const placements = [placement].concat(fallbackPlacements as DSHookFloatingContextT.PopperPlacementsT[]);\n let finalPlacement = '';\n\n for (let i = 0; i < placements.length; i += 1) {\n const currentPlacement = placements[i];\n\n const currentBasePlacement = currentPlacement.split('-')[0] as keyof typeof coords;\n isVertical = ['top', 'bottom'].indexOf(currentBasePlacement) >= 0;\n\n const overflows = detectOverflow(referenceRect, floatingRect, currentPlacement, customOffset);\n\n const checks: boolean[] = [];\n\n const isStartVariation = variationPlacement === 'start';\n\n let mainVariationSide: keyof typeof coords = isVertical\n ? isStartVariation\n ? 'right'\n : 'left'\n : isStartVariation\n ? 'bottom'\n : 'top';\n\n const len = isVertical ? 'width' : 'height';\n\n if (referenceRect[len] > floatingRect[len]) {\n mainVariationSide = getOppositePlacement(mainVariationSide) as keyof typeof coords;\n }\n\n const altVariationSide = getOppositePlacement(mainVariationSide) as keyof typeof coords;\n\n checks.push(overflows[currentBasePlacement] <= 0);\n checks.push(overflows[mainVariationSide] <= 0, overflows[altVariationSide] <= 0);\n\n if (\n checks.every((check) => {\n return check;\n })\n ) {\n coords.top = -overflows.top + window.scrollY - parentOffsets.top;\n coords.left = -overflows.left + window.scrollX - parentOffsets.left;\n finalPlacement = currentPlacement;\n\n break;\n }\n }\n\n return {\n coordsStyle: {\n left: 0,\n top: 0,\n // we use transform -> translate because we know final computed left/top probably \"split a pixel\" (e.g. 10.005px)\n // when we use transform we force the browser to use hardware acceleration\n // hardware acceleration is faster and more reliable than the browser's own rounding\n // it also helps with css animations and so on\n transform: `translate(${coords.left}px, ${coords.top}px)`,\n },\n finalPlacement,\n coordsArrow: getArrowOffset(finalPlacement, isVertical),\n };\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADQvB,2CAA8C;AAC9C,4BAA+B;AAC/B,kCAAiC;AACjC,4BAA+B;AAW/B,MAAM,kBAAkB,CAAC,OAAuB;AAC9C,MAAI,UAAU;AACd,SAAO,WAAW,YAAY,SAAS,MAAM;AAC3C,UAAM,QAAQ,iBAAiB,OAAO;AACtC,QAAI,MAAM,aAAa,WAAW,MAAM,aAAa,YAAY;AAC/D,aAAO;AAAA,IACT;AACA,cAAU,QAAQ;AAAA,EACpB;AACA,SAAO;AACT;AAEA,MAAM,uBAAuB,CAAC,UAAmB;AAC/C,QAAM,cAAc,gBAAgB,KAAK;AACzC,MAAI,aAAa;AACf,UAAM,OAAO,YAAY,sBAAsB;AAC/C,WAAO,EAAE,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK;AAAA,EAC1C;AACA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACF;AAEO,MAAM,kBAAkB,CAAC,UAAgC;AAC9D,QAAM,EAAE,WAAW,UAAU,WAAW,0BAA0B,cAAc,cAAc,IAAI;AAElG,QAAM,gBAAgB,gBAClB,qBAAqB,SAAS,IAC9B;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACJ,QAAM,gBAAgB,UAAU,sBAAsB;AACtD,QAAM,eAAe,SAAS,sBAAsB;AAEpD,QAAM,qBAAqB,UAAU,MAAM,GAAG,EAAE,CAAC;AACjD,QAAM,qBAAqB,gCAA4B,oEAA8B,SAAS;AAE9F,QAAM,SAA2E,CAAC;AAElF,MAAI,aAAa;AACjB,QAAM,aAAa,CAAC,SAAS,EAAE,OAAO,kBAAgE;AACtG,MAAI,iBAAiB;AAErB,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK,GAAG;AAC7C,UAAM,mBAAmB,WAAW,CAAC;AAErC,UAAM,uBAAuB,iBAAiB,MAAM,GAAG,EAAE,CAAC;AAC1D,iBAAa,CAAC,OAAO,QAAQ,EAAE,QAAQ,oBAAoB,KAAK;AAEhE,UAAM,gBAAY,sCAAe,eAAe,cAAc,kBAAkB,YAAY;AAE5F,UAAM,SAAoB,CAAC;AAE3B,UAAM,mBAAmB,uBAAuB;AAEhD,QAAI,oBAAyC,aACzC,mBACE,UACA,SACF,mBACA,WACA;AAEJ,UAAM,MAAM,aAAa,UAAU;AAEnC,QAAI,cAAc,GAAG,IAAI,aAAa,GAAG,GAAG;AAC1C,8BAAoB,4BAAAA,SAAqB,iBAAiB;AAAA,IAC5D;AAEA,UAAM,uBAAmB,4BAAAA,SAAqB,iBAAiB;AAE/D,WAAO,KAAK,UAAU,oBAAoB,KAAK,CAAC;AAChD,WAAO,KAAK,UAAU,iBAAiB,KAAK,GAAG,UAAU,gBAAgB,KAAK,CAAC;AAE/E,QACE,OAAO,MAAM,CAAC,UAAU;AACtB,aAAO;AAAA,IACT,CAAC,GACD;AACA,aAAO,MAAM,CAAC,UAAU,MAAM,OAAO,UAAU,cAAc;AAC7D,aAAO,OAAO,CAAC,UAAU,OAAO,OAAO,UAAU,cAAc;AAC/D,uBAAiB;AAEjB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa;AAAA,MACX,MAAM;AAAA,MACN,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,MAKL,WAAW,aAAa,OAAO,IAAI,OAAO,OAAO,GAAG;AAAA,IACtD;AAAA,IACA;AAAA,IACA,iBAAa,sCAAe,gBAAgB,UAAU;AAAA,EACxD;AACF;",
6
6
  "names": ["getOppositePlacement"]
7
7
  }
@@ -22,15 +22,30 @@ const useFloatingContext = (props = {}) => {
22
22
  customOffset,
23
23
  placementOrderPreference,
24
24
  onOpen,
25
- onClose
25
+ onClose,
26
+ externallyControlledIsOpen
26
27
  } = propsWithDefault;
27
- const tooltipHelpers = useHeadlessTooltip({ onOpen, onClose });
28
+ const [internalIsOpen, setInternalIsOpen] = React2.useState(false);
29
+ const isOpenSourceOfTruth = useMemo(() => {
30
+ if (externallyControlledIsOpen !== void 0) return externallyControlledIsOpen;
31
+ return internalIsOpen;
32
+ }, [externallyControlledIsOpen, internalIsOpen]);
33
+ const overChargedOnOpen = React2.useCallback(() => {
34
+ setInternalIsOpen(true);
35
+ onOpen?.();
36
+ }, [onOpen]);
37
+ const overChargedOnClose = React2.useCallback(() => {
38
+ setInternalIsOpen(false);
39
+ onClose?.();
40
+ }, [onClose]);
41
+ const tooltipHelpers = useHeadlessTooltip({ onOpen: overChargedOnOpen, onClose: overChargedOnClose });
28
42
  const { setReferenceElement, hideTooltip, showTooltip } = tooltipHelpers;
29
43
  const [floatingStyles, setFloatingStyles] = useState({
30
44
  position: "absolute",
31
45
  zIndex: 3e3,
32
46
  top: 0,
33
- left: 0
47
+ left: 0,
48
+ visibility: "hidden"
34
49
  });
35
50
  const [arrowStyles, setArrowStyles] = useState({
36
51
  style: { left: 0 },
@@ -40,7 +55,7 @@ const useFloatingContext = (props = {}) => {
40
55
  const [floating, setFloating] = React2.useState(null);
41
56
  useEffect(() => {
42
57
  const update = () => {
43
- if (reference && floating) {
58
+ if (isOpenSourceOfTruth && reference && floating) {
44
59
  const { coordsStyle, finalPlacement, coordsArrow } = computePosition({
45
60
  reference,
46
61
  floating,
@@ -52,8 +67,8 @@ const useFloatingContext = (props = {}) => {
52
67
  const styles = {
53
68
  position: "absolute",
54
69
  zIndex: 3e3,
55
- top: 0,
56
- left: 0,
70
+ // top: 0,
71
+ // left: 0,
57
72
  ...coordsStyle
58
73
  };
59
74
  setFloatingStyles(styles);
@@ -66,7 +81,7 @@ const useFloatingContext = (props = {}) => {
66
81
  return () => {
67
82
  window.removeEventListener("scroll", debouncedCb);
68
83
  };
69
- }, [reference, floating, placement, placementOrderPreference, customOffset, withoutPortal]);
84
+ }, [reference, floating, placement, placementOrderPreference, customOffset, withoutPortal, isOpenSourceOfTruth]);
70
85
  const setReference = mergeRefs(_setReference, setReferenceElement);
71
86
  const refs = React2.useMemo(
72
87
  () => ({
@@ -91,7 +106,7 @@ const useFloatingContext = (props = {}) => {
91
106
  refs,
92
107
  floatingStyles,
93
108
  handlers,
94
- isOpen: tooltipHelpers.shouldShowPopover,
109
+ isOpen: isOpenSourceOfTruth,
95
110
  arrowStyles,
96
111
  hideTooltip,
97
112
  showTooltip,
@@ -103,17 +118,17 @@ const useFloatingContext = (props = {}) => {
103
118
  }
104
119
  }),
105
120
  [
106
- animationDuration,
107
- arrowStyles,
121
+ refs,
108
122
  floatingStyles,
109
123
  handlers,
124
+ isOpenSourceOfTruth,
125
+ arrowStyles,
110
126
  hideTooltip,
111
- portalDOMContainer,
112
- refs,
113
127
  showTooltip,
114
- tooltipHelpers.shouldShowPopover,
128
+ withoutPortal,
115
129
  withoutAnimation,
116
- withoutPortal
130
+ portalDOMContainer,
131
+ animationDuration
117
132
  ]
118
133
  );
119
134
  };
@@ -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 no-nested-ternary */\n/* eslint-disable arrow-body-style */\n/* eslint-disable no-unused-vars */\n/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable @typescript-eslint/no-use-before-define */\nimport React, { useState, useEffect, useMemo } from 'react';\nimport { debounce } from 'lodash';\nimport {\n useMemoMergePropsWithDefault,\n useValidateTypescriptPropTypes,\n describe,\n type ValidationMap,\n} from '@elliemae/ds-props-helpers';\nimport { useHeadlessTooltip } from '@elliemae/ds-hooks-headless-tooltip';\nimport { type CSSProperties } from 'styled-components';\nimport { mergeRefs } from '@elliemae/ds-system';\nimport { computePosition } from './utils/computePosition.js';\nimport type { DSHookFloatingContextT } from './react-desc-prop-types.js';\nimport { defaultProps, DSFloatingContextPropTypes } from './react-desc-prop-types.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 } = propsWithDefault;\n\n const tooltipHelpers = useHeadlessTooltip({ onOpen, onClose });\n\n const { setReferenceElement, hideTooltip, showTooltip } = tooltipHelpers;\n const [floatingStyles, setFloatingStyles] = useState<CSSProperties>({\n position: 'absolute',\n zIndex: 3000,\n top: 0,\n left: 0,\n });\n const [arrowStyles, setArrowStyles] = useState<{ style: CSSProperties; placement: string }>({\n style: { left: 0 },\n placement: 'top',\n });\n\n const [reference, _setReference] = React.useState<Element | null>(null);\n const [floating, setFloating] = React.useState<HTMLElement | null>(null);\n useEffect(() => {\n const update = () => {\n if (reference && floating) {\n const { coordsStyle, finalPlacement, coordsArrow } = computePosition({\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n });\n\n const styles: CSSProperties = {\n position: 'absolute',\n zIndex: 3000,\n top: 0,\n left: 0,\n ...coordsStyle,\n };\n setFloatingStyles(styles);\n setArrowStyles({ style: coordsArrow, placement: finalPlacement });\n }\n };\n\n // initial position calculation\n update();\n\n const debouncedCb = debounce(update, 300);\n\n // auto update position on scrolling\n window.addEventListener('scroll', debouncedCb);\n\n return () => {\n window.removeEventListener('scroll', debouncedCb);\n };\n }, [reference, floating, placement, placementOrderPreference, customOffset, withoutPortal]);\n\n const setReference = mergeRefs(_setReference, setReferenceElement);\n\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: tooltipHelpers.shouldShowPopover,\n arrowStyles,\n hideTooltip,\n showTooltip,\n context: {\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\n },\n }),\n [\n animationDuration,\n arrowStyles,\n floatingStyles,\n handlers,\n hideTooltip,\n portalDOMContainer,\n refs,\n showTooltip,\n tooltipHelpers.shouldShowPopover,\n withoutAnimation,\n withoutPortal,\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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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable no-nested-ternary */\n/* eslint-disable arrow-body-style */\n/* eslint-disable no-unused-vars */\n/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable @typescript-eslint/no-use-before-define */\nimport React, { useState, useEffect, useMemo } from 'react';\nimport { debounce } from 'lodash';\nimport {\n useMemoMergePropsWithDefault,\n useValidateTypescriptPropTypes,\n describe,\n type ValidationMap,\n} from '@elliemae/ds-props-helpers';\nimport { useHeadlessTooltip } from '@elliemae/ds-hooks-headless-tooltip';\nimport { type CSSProperties } from 'styled-components';\nimport { mergeRefs } from '@elliemae/ds-system';\nimport { computePosition } from './utils/computePosition.js';\nimport type { DSHookFloatingContextT } from './react-desc-prop-types.js';\nimport { defaultProps, DSFloatingContextPropTypes } from './react-desc-prop-types.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\n const { setReferenceElement, hideTooltip, showTooltip } = tooltipHelpers;\n const [floatingStyles, setFloatingStyles] = useState<CSSProperties>({\n position: 'absolute',\n zIndex: 3000,\n top: 0,\n left: 0,\n visibility: 'hidden',\n });\n const [arrowStyles, setArrowStyles] = useState<{ style: CSSProperties; placement: string }>({\n style: { left: 0 },\n placement: 'top',\n });\n\n const [reference, _setReference] = React.useState<Element | null>(null);\n const [floating, setFloating] = React.useState<HTMLElement | null>(null);\n useEffect(() => {\n const update = () => {\n if (isOpenSourceOfTruth && reference && floating) {\n const { coordsStyle, finalPlacement, coordsArrow } = computePosition({\n reference,\n floating,\n placement,\n placementOrderPreference,\n customOffset,\n withoutPortal,\n });\n\n const styles: CSSProperties = {\n position: 'absolute',\n zIndex: 3000,\n // top: 0,\n // left: 0,\n ...coordsStyle,\n };\n\n setFloatingStyles(styles);\n setArrowStyles({ style: coordsArrow, placement: finalPlacement });\n }\n };\n\n // initial position calculation\n update();\n\n const debouncedCb = debounce(update, 300);\n\n // auto update position on scrolling\n window.addEventListener('scroll', debouncedCb);\n\n return () => {\n window.removeEventListener('scroll', debouncedCb);\n };\n }, [reference, floating, placement, placementOrderPreference, customOffset, withoutPortal, isOpenSourceOfTruth]);\n\n const setReference = mergeRefs(_setReference, setReferenceElement);\n\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 }),\n [\n refs,\n floatingStyles,\n handlers,\n isOpenSourceOfTruth,\n arrowStyles,\n hideTooltip,\n showTooltip,\n withoutPortal,\n withoutAnimation,\n portalDOMContainer,\n animationDuration,\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
  }
@@ -42,7 +42,10 @@ const DSFloatingContextPropTypes = {
42
42
  PropTypes.tuple([PropTypes.oneOf(["left-start"])])
43
43
  ]).description("The order of the placement preference."),
44
44
  onOpen: PropTypes.func.description("Callback when the tooltip is opened."),
45
- onClose: PropTypes.func.description("Callback when the tooltip is closed.")
45
+ onClose: PropTypes.func.description("Callback when the tooltip is closed."),
46
+ externallyControlledIsOpen: PropTypes.bool.description(
47
+ "If true, the context open/close state will be controlled externally."
48
+ )
46
49
  };
47
50
  export {
48
51
  DSFloatingContextPropTypes,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/react-desc-prop-types.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { DSPropTypesSchema } from '@elliemae/ds-props-helpers';\nimport { PropTypes } from '@elliemae/ds-props-helpers';\nexport declare namespace DSHookFloatingContextT {\n export interface DefaultProps {\n withoutPortal: boolean;\n withoutAnimation: boolean;\n portalDOMContainer?: HTMLElement;\n animationDuration: number;\n placement: PopperPlacementsT;\n customOffset: [number, number];\n }\n\n export interface OptionalProps {\n placementOrderPreference?: PopperPlacementsT[];\n onOpen?: () => void;\n onClose?: () => void;\n }\n export interface Props extends Partial<DefaultProps>, OptionalProps {}\n\n export interface InternalProps extends DefaultProps, OptionalProps {}\n\n export type PopperPlacementsT =\n | 'top-start'\n | 'top'\n | 'top-end'\n | 'right-start'\n | 'right'\n | 'right-end'\n | 'bottom-end'\n | 'bottom'\n | 'bottom-start'\n | 'left-end'\n | 'left'\n | 'left-start';\n}\n\nexport const defaultProps: DSHookFloatingContextT.DefaultProps = {\n withoutAnimation: false,\n animationDuration: 300,\n withoutPortal: false,\n placement: 'top',\n customOffset: [0, 12],\n};\n\nexport const DSFloatingContextPropTypes: DSPropTypesSchema<DSHookFloatingContextT.Props> = {\n withoutPortal: PropTypes.bool\n .description('If true, the tooltip will not be rendered inside a portal.')\n .defaultValue(false),\n withoutAnimation: PropTypes.bool.description('If true, the tooltip will not have an animation.').defaultValue(false),\n portalDOMContainer: PropTypes.instanceOf(HTMLElement)\n .description('The DOM element where the tooltip will be rendered.')\n .defaultValue('the first \"main\" landmark available in the document or the body if no \"main\" is found'),\n animationDuration: PropTypes.number.description('The duration of the animation in milliseconds.').defaultValue(300),\n placement: PropTypes.oneOf([\n 'top-start',\n 'top',\n 'top-end',\n 'right-start',\n 'right',\n 'right-end',\n 'bottom-end',\n 'bottom',\n 'bottom-start',\n 'left-end',\n 'left',\n 'left-start',\n ])\n .description('The placement of the tooltip.')\n .defaultValue('top'),\n customOffset: PropTypes.arrayOf(PropTypes.number)\n .description('The custom offset of the tooltip.')\n .defaultValue([12, 12]),\n placementOrderPreference: PropTypes.oneOfType([\n PropTypes.tuple([PropTypes.oneOf(['top-start'])]),\n PropTypes.tuple([PropTypes.oneOf(['top'])]),\n PropTypes.tuple([PropTypes.oneOf(['top-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['right-start'])]),\n PropTypes.tuple([PropTypes.oneOf(['right'])]),\n PropTypes.tuple([PropTypes.oneOf(['right-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['bottom-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['bottom'])]),\n PropTypes.tuple([PropTypes.oneOf(['bottom-start'])]),\n PropTypes.tuple([PropTypes.oneOf(['left-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['left'])]),\n PropTypes.tuple([PropTypes.oneOf(['left-start'])]),\n ]).description('The order of the placement preference.'),\n onOpen: PropTypes.func.description('Callback when the tooltip is opened.'),\n onClose: PropTypes.func.description('Callback when the tooltip is closed.'),\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACEvB,SAAS,iBAAiB;AAmCnB,MAAM,eAAoD;AAAA,EAC/D,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,cAAc,CAAC,GAAG,EAAE;AACtB;AAEO,MAAM,6BAA8E;AAAA,EACzF,eAAe,UAAU,KACtB,YAAY,4DAA4D,EACxE,aAAa,KAAK;AAAA,EACrB,kBAAkB,UAAU,KAAK,YAAY,kDAAkD,EAAE,aAAa,KAAK;AAAA,EACnH,oBAAoB,UAAU,WAAW,WAAW,EACjD,YAAY,qDAAqD,EACjE,aAAa,uFAAuF;AAAA,EACvG,mBAAmB,UAAU,OAAO,YAAY,gDAAgD,EAAE,aAAa,GAAG;AAAA,EAClH,WAAW,UAAU,MAAM;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,EACE,YAAY,+BAA+B,EAC3C,aAAa,KAAK;AAAA,EACrB,cAAc,UAAU,QAAQ,UAAU,MAAM,EAC7C,YAAY,mCAAmC,EAC/C,aAAa,CAAC,IAAI,EAAE,CAAC;AAAA,EACxB,0BAA0B,UAAU,UAAU;AAAA,IAC5C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AAAA,IAChD,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAAA,IAC1C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AAAA,IAC9C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;AAAA,IAClD,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AAAA,IAC5C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AAAA,IAChD,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;AAAA,IACjD,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;AAAA,IAC7C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;AAAA,IACnD,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAAA,IAC/C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AAAA,IAC3C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;AAAA,EACnD,CAAC,EAAE,YAAY,wCAAwC;AAAA,EACvD,QAAQ,UAAU,KAAK,YAAY,sCAAsC;AAAA,EACzE,SAAS,UAAU,KAAK,YAAY,sCAAsC;AAC5E;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-empty-interface */\nimport type { DSPropTypesSchema } from '@elliemae/ds-props-helpers';\nimport { PropTypes } from '@elliemae/ds-props-helpers';\nexport declare namespace DSHookFloatingContextT {\n export interface DefaultProps {\n withoutPortal: boolean;\n withoutAnimation: boolean;\n portalDOMContainer?: HTMLElement;\n animationDuration: number;\n placement: PopperPlacementsT;\n customOffset: [number, number];\n }\n\n export interface OptionalProps {\n placementOrderPreference?: PopperPlacementsT[];\n onOpen?: () => void;\n onClose?: () => void;\n externallyControlledIsOpen?: boolean;\n }\n export interface Props extends Partial<DefaultProps>, OptionalProps {}\n\n export interface InternalProps extends DefaultProps, OptionalProps {}\n\n export type PopperPlacementsT =\n | 'top-start'\n | 'top'\n | 'top-end'\n | 'right-start'\n | 'right'\n | 'right-end'\n | 'bottom-end'\n | 'bottom'\n | 'bottom-start'\n | 'left-end'\n | 'left'\n | 'left-start';\n}\n\nexport const defaultProps: DSHookFloatingContextT.DefaultProps = {\n withoutAnimation: false,\n animationDuration: 300,\n withoutPortal: false,\n placement: 'top',\n customOffset: [0, 12],\n};\n\nexport const DSFloatingContextPropTypes: DSPropTypesSchema<DSHookFloatingContextT.Props> = {\n withoutPortal: PropTypes.bool\n .description('If true, the tooltip will not be rendered inside a portal.')\n .defaultValue(false),\n withoutAnimation: PropTypes.bool.description('If true, the tooltip will not have an animation.').defaultValue(false),\n portalDOMContainer: PropTypes.instanceOf(HTMLElement)\n .description('The DOM element where the tooltip will be rendered.')\n .defaultValue('the first \"main\" landmark available in the document or the body if no \"main\" is found'),\n animationDuration: PropTypes.number.description('The duration of the animation in milliseconds.').defaultValue(300),\n placement: PropTypes.oneOf([\n 'top-start',\n 'top',\n 'top-end',\n 'right-start',\n 'right',\n 'right-end',\n 'bottom-end',\n 'bottom',\n 'bottom-start',\n 'left-end',\n 'left',\n 'left-start',\n ])\n .description('The placement of the tooltip.')\n .defaultValue('top'),\n customOffset: PropTypes.arrayOf(PropTypes.number)\n .description('The custom offset of the tooltip.')\n .defaultValue([12, 12]),\n placementOrderPreference: PropTypes.oneOfType([\n PropTypes.tuple([PropTypes.oneOf(['top-start'])]),\n PropTypes.tuple([PropTypes.oneOf(['top'])]),\n PropTypes.tuple([PropTypes.oneOf(['top-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['right-start'])]),\n PropTypes.tuple([PropTypes.oneOf(['right'])]),\n PropTypes.tuple([PropTypes.oneOf(['right-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['bottom-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['bottom'])]),\n PropTypes.tuple([PropTypes.oneOf(['bottom-start'])]),\n PropTypes.tuple([PropTypes.oneOf(['left-end'])]),\n PropTypes.tuple([PropTypes.oneOf(['left'])]),\n PropTypes.tuple([PropTypes.oneOf(['left-start'])]),\n ]).description('The order of the placement preference.'),\n onOpen: PropTypes.func.description('Callback when the tooltip is opened.'),\n onClose: PropTypes.func.description('Callback when the tooltip is closed.'),\n externallyControlledIsOpen: PropTypes.bool.description(\n 'If true, the context open/close state will be controlled externally.',\n ),\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACEvB,SAAS,iBAAiB;AAoCnB,MAAM,eAAoD;AAAA,EAC/D,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,cAAc,CAAC,GAAG,EAAE;AACtB;AAEO,MAAM,6BAA8E;AAAA,EACzF,eAAe,UAAU,KACtB,YAAY,4DAA4D,EACxE,aAAa,KAAK;AAAA,EACrB,kBAAkB,UAAU,KAAK,YAAY,kDAAkD,EAAE,aAAa,KAAK;AAAA,EACnH,oBAAoB,UAAU,WAAW,WAAW,EACjD,YAAY,qDAAqD,EACjE,aAAa,uFAAuF;AAAA,EACvG,mBAAmB,UAAU,OAAO,YAAY,gDAAgD,EAAE,aAAa,GAAG;AAAA,EAClH,WAAW,UAAU,MAAM;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,EACE,YAAY,+BAA+B,EAC3C,aAAa,KAAK;AAAA,EACrB,cAAc,UAAU,QAAQ,UAAU,MAAM,EAC7C,YAAY,mCAAmC,EAC/C,aAAa,CAAC,IAAI,EAAE,CAAC;AAAA,EACxB,0BAA0B,UAAU,UAAU;AAAA,IAC5C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AAAA,IAChD,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAAA,IAC1C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AAAA,IAC9C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;AAAA,IAClD,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AAAA,IAC5C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;AAAA,IAChD,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;AAAA,IACjD,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;AAAA,IAC7C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;AAAA,IACnD,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAAA,IAC/C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AAAA,IAC3C,UAAU,MAAM,CAAC,UAAU,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;AAAA,EACnD,CAAC,EAAE,YAAY,wCAAwC;AAAA,EACvD,QAAQ,UAAU,KAAK,YAAY,sCAAsC;AAAA,EACzE,SAAS,UAAU,KAAK,YAAY,sCAAsC;AAAA,EAC1E,4BAA4B,UAAU,KAAK;AAAA,IACzC;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -64,7 +64,15 @@ const computePosition = (props) => {
64
64
  }
65
65
  }
66
66
  return {
67
- coordsStyle: { transform: `translate(${coords.left}px, ${coords.top}px)` },
67
+ coordsStyle: {
68
+ left: 0,
69
+ top: 0,
70
+ // we use transform -> translate because we know final computed left/top probably "split a pixel" (e.g. 10.005px)
71
+ // when we use transform we force the browser to use hardware acceleration
72
+ // hardware acceleration is faster and more reliable than the browser's own rounding
73
+ // it also helps with css animations and so on
74
+ transform: `translate(${coords.left}px, ${coords.top}px)`
75
+ },
68
76
  finalPlacement,
69
77
  coordsArrow: getArrowOffset(finalPlacement, isVertical)
70
78
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/utils/computePosition.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable no-nested-ternary */\n/* eslint-disable complexity */\n/* eslint-disable max-statements */\n/* eslint-disable @typescript-eslint/no-use-before-define */\n/* eslint-disable max-params */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable arrow-body-style */\nimport type { DSHookFloatingContextT } from '../react-desc-prop-types.js';\nimport { getExpandedFallbackPlacements } from './getExpandedFallbackPlacements.js';\nimport { getArrowOffset } from './getArrowOffset.js';\nimport getOppositePlacement from './getOppositePlacement.js';\nimport { detectOverflow } from './detectOverflow.js';\n\ninterface ComputePositionProps {\n reference: Element;\n floating: HTMLElement;\n placement: DSHookFloatingContextT.PopperPlacementsT;\n placementOrderPreference?: DSHookFloatingContextT.PopperPlacementsT[];\n customOffset: [number, number];\n withoutPortal: boolean;\n}\n\nconst findFixedParent = (el: Element | null) => {\n let element = el;\n while (element && element !== document.body) {\n const style = getComputedStyle(element);\n if (style.position === 'fixed' || style.position === 'absolute') {\n return element;\n }\n element = element.parentElement;\n }\n return null;\n};\n\nconst adjustForFixedParent = (child: Element) => {\n const fixedParent = findFixedParent(child);\n if (fixedParent) {\n const rect = fixedParent.getBoundingClientRect();\n return { top: rect.top, left: rect.left };\n }\n return {\n top: 0,\n left: 0,\n };\n};\n\nexport const computePosition = (props: ComputePositionProps) => {\n const { reference, floating, placement, placementOrderPreference, customOffset, withoutPortal } = props;\n\n const parentOffsets = withoutPortal\n ? adjustForFixedParent(reference)\n : {\n top: 0,\n left: 0,\n };\n const referenceRect = reference.getBoundingClientRect();\n const floatingRect = floating.getBoundingClientRect();\n\n const variationPlacement = placement.split('-')[1];\n const fallbackPlacements = placementOrderPreference || getExpandedFallbackPlacements(placement);\n\n const coords: { top?: number; left?: number; bottom?: number; right?: number } = {};\n\n let isVertical = false;\n const placements = [placement].concat(fallbackPlacements as DSHookFloatingContextT.PopperPlacementsT[]);\n let finalPlacement = '';\n\n for (let i = 0; i < placements.length; i += 1) {\n const currentPlacement = placements[i];\n\n const currentBasePlacement = currentPlacement.split('-')[0] as keyof typeof coords;\n isVertical = ['top', 'bottom'].indexOf(currentBasePlacement) >= 0;\n\n const overflows = detectOverflow(referenceRect, floatingRect, currentPlacement, customOffset);\n\n const checks: boolean[] = [];\n\n const isStartVariation = variationPlacement === 'start';\n\n let mainVariationSide: keyof typeof coords = isVertical\n ? isStartVariation\n ? 'right'\n : 'left'\n : isStartVariation\n ? 'bottom'\n : 'top';\n\n const len = isVertical ? 'width' : 'height';\n\n if (referenceRect[len] > floatingRect[len]) {\n mainVariationSide = getOppositePlacement(mainVariationSide) as keyof typeof coords;\n }\n\n const altVariationSide = getOppositePlacement(mainVariationSide) as keyof typeof coords;\n\n checks.push(overflows[currentBasePlacement] <= 0);\n checks.push(overflows[mainVariationSide] <= 0, overflows[altVariationSide] <= 0);\n\n if (\n checks.every((check) => {\n return check;\n })\n ) {\n coords.top = -overflows.top + window.scrollY - parentOffsets.top;\n coords.left = -overflows.left + window.scrollX - parentOffsets.left;\n finalPlacement = currentPlacement;\n\n break;\n }\n }\n\n return {\n coordsStyle: { transform: `translate(${coords.left}px, ${coords.top}px)` },\n finalPlacement,\n coordsArrow: getArrowOffset(finalPlacement, isVertical),\n };\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACQvB,SAAS,qCAAqC;AAC9C,SAAS,sBAAsB;AAC/B,OAAO,0BAA0B;AACjC,SAAS,sBAAsB;AAW/B,MAAM,kBAAkB,CAAC,OAAuB;AAC9C,MAAI,UAAU;AACd,SAAO,WAAW,YAAY,SAAS,MAAM;AAC3C,UAAM,QAAQ,iBAAiB,OAAO;AACtC,QAAI,MAAM,aAAa,WAAW,MAAM,aAAa,YAAY;AAC/D,aAAO;AAAA,IACT;AACA,cAAU,QAAQ;AAAA,EACpB;AACA,SAAO;AACT;AAEA,MAAM,uBAAuB,CAAC,UAAmB;AAC/C,QAAM,cAAc,gBAAgB,KAAK;AACzC,MAAI,aAAa;AACf,UAAM,OAAO,YAAY,sBAAsB;AAC/C,WAAO,EAAE,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK;AAAA,EAC1C;AACA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACF;AAEO,MAAM,kBAAkB,CAAC,UAAgC;AAC9D,QAAM,EAAE,WAAW,UAAU,WAAW,0BAA0B,cAAc,cAAc,IAAI;AAElG,QAAM,gBAAgB,gBAClB,qBAAqB,SAAS,IAC9B;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACJ,QAAM,gBAAgB,UAAU,sBAAsB;AACtD,QAAM,eAAe,SAAS,sBAAsB;AAEpD,QAAM,qBAAqB,UAAU,MAAM,GAAG,EAAE,CAAC;AACjD,QAAM,qBAAqB,4BAA4B,8BAA8B,SAAS;AAE9F,QAAM,SAA2E,CAAC;AAElF,MAAI,aAAa;AACjB,QAAM,aAAa,CAAC,SAAS,EAAE,OAAO,kBAAgE;AACtG,MAAI,iBAAiB;AAErB,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK,GAAG;AAC7C,UAAM,mBAAmB,WAAW,CAAC;AAErC,UAAM,uBAAuB,iBAAiB,MAAM,GAAG,EAAE,CAAC;AAC1D,iBAAa,CAAC,OAAO,QAAQ,EAAE,QAAQ,oBAAoB,KAAK;AAEhE,UAAM,YAAY,eAAe,eAAe,cAAc,kBAAkB,YAAY;AAE5F,UAAM,SAAoB,CAAC;AAE3B,UAAM,mBAAmB,uBAAuB;AAEhD,QAAI,oBAAyC,aACzC,mBACE,UACA,SACF,mBACA,WACA;AAEJ,UAAM,MAAM,aAAa,UAAU;AAEnC,QAAI,cAAc,GAAG,IAAI,aAAa,GAAG,GAAG;AAC1C,0BAAoB,qBAAqB,iBAAiB;AAAA,IAC5D;AAEA,UAAM,mBAAmB,qBAAqB,iBAAiB;AAE/D,WAAO,KAAK,UAAU,oBAAoB,KAAK,CAAC;AAChD,WAAO,KAAK,UAAU,iBAAiB,KAAK,GAAG,UAAU,gBAAgB,KAAK,CAAC;AAE/E,QACE,OAAO,MAAM,CAAC,UAAU;AACtB,aAAO;AAAA,IACT,CAAC,GACD;AACA,aAAO,MAAM,CAAC,UAAU,MAAM,OAAO,UAAU,cAAc;AAC7D,aAAO,OAAO,CAAC,UAAU,OAAO,OAAO,UAAU,cAAc;AAC/D,uBAAiB;AAEjB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa,EAAE,WAAW,aAAa,OAAO,IAAI,OAAO,OAAO,GAAG,MAAM;AAAA,IACzE;AAAA,IACA,aAAa,eAAe,gBAAgB,UAAU;AAAA,EACxD;AACF;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable no-nested-ternary */\n/* eslint-disable complexity */\n/* eslint-disable max-statements */\n/* eslint-disable @typescript-eslint/no-use-before-define */\n/* eslint-disable max-params */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable arrow-body-style */\nimport type { DSHookFloatingContextT } from '../react-desc-prop-types.js';\nimport { getExpandedFallbackPlacements } from './getExpandedFallbackPlacements.js';\nimport { getArrowOffset } from './getArrowOffset.js';\nimport getOppositePlacement from './getOppositePlacement.js';\nimport { detectOverflow } from './detectOverflow.js';\n\ninterface ComputePositionProps {\n reference: Element;\n floating: HTMLElement;\n placement: DSHookFloatingContextT.PopperPlacementsT;\n placementOrderPreference?: DSHookFloatingContextT.PopperPlacementsT[];\n customOffset: [number, number];\n withoutPortal: boolean;\n}\n\nconst findFixedParent = (el: Element | null) => {\n let element = el;\n while (element && element !== document.body) {\n const style = getComputedStyle(element);\n if (style.position === 'fixed' || style.position === 'absolute') {\n return element;\n }\n element = element.parentElement;\n }\n return null;\n};\n\nconst adjustForFixedParent = (child: Element) => {\n const fixedParent = findFixedParent(child);\n if (fixedParent) {\n const rect = fixedParent.getBoundingClientRect();\n return { top: rect.top, left: rect.left };\n }\n return {\n top: 0,\n left: 0,\n };\n};\n\nexport const computePosition = (props: ComputePositionProps) => {\n const { reference, floating, placement, placementOrderPreference, customOffset, withoutPortal } = props;\n\n const parentOffsets = withoutPortal\n ? adjustForFixedParent(reference)\n : {\n top: 0,\n left: 0,\n };\n const referenceRect = reference.getBoundingClientRect();\n const floatingRect = floating.getBoundingClientRect();\n\n const variationPlacement = placement.split('-')[1];\n const fallbackPlacements = placementOrderPreference || getExpandedFallbackPlacements(placement);\n\n const coords: { top?: number; left?: number; bottom?: number; right?: number } = {};\n\n let isVertical = false;\n const placements = [placement].concat(fallbackPlacements as DSHookFloatingContextT.PopperPlacementsT[]);\n let finalPlacement = '';\n\n for (let i = 0; i < placements.length; i += 1) {\n const currentPlacement = placements[i];\n\n const currentBasePlacement = currentPlacement.split('-')[0] as keyof typeof coords;\n isVertical = ['top', 'bottom'].indexOf(currentBasePlacement) >= 0;\n\n const overflows = detectOverflow(referenceRect, floatingRect, currentPlacement, customOffset);\n\n const checks: boolean[] = [];\n\n const isStartVariation = variationPlacement === 'start';\n\n let mainVariationSide: keyof typeof coords = isVertical\n ? isStartVariation\n ? 'right'\n : 'left'\n : isStartVariation\n ? 'bottom'\n : 'top';\n\n const len = isVertical ? 'width' : 'height';\n\n if (referenceRect[len] > floatingRect[len]) {\n mainVariationSide = getOppositePlacement(mainVariationSide) as keyof typeof coords;\n }\n\n const altVariationSide = getOppositePlacement(mainVariationSide) as keyof typeof coords;\n\n checks.push(overflows[currentBasePlacement] <= 0);\n checks.push(overflows[mainVariationSide] <= 0, overflows[altVariationSide] <= 0);\n\n if (\n checks.every((check) => {\n return check;\n })\n ) {\n coords.top = -overflows.top + window.scrollY - parentOffsets.top;\n coords.left = -overflows.left + window.scrollX - parentOffsets.left;\n finalPlacement = currentPlacement;\n\n break;\n }\n }\n\n return {\n coordsStyle: {\n left: 0,\n top: 0,\n // we use transform -> translate because we know final computed left/top probably \"split a pixel\" (e.g. 10.005px)\n // when we use transform we force the browser to use hardware acceleration\n // hardware acceleration is faster and more reliable than the browser's own rounding\n // it also helps with css animations and so on\n transform: `translate(${coords.left}px, ${coords.top}px)`,\n },\n finalPlacement,\n coordsArrow: getArrowOffset(finalPlacement, isVertical),\n };\n};\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACQvB,SAAS,qCAAqC;AAC9C,SAAS,sBAAsB;AAC/B,OAAO,0BAA0B;AACjC,SAAS,sBAAsB;AAW/B,MAAM,kBAAkB,CAAC,OAAuB;AAC9C,MAAI,UAAU;AACd,SAAO,WAAW,YAAY,SAAS,MAAM;AAC3C,UAAM,QAAQ,iBAAiB,OAAO;AACtC,QAAI,MAAM,aAAa,WAAW,MAAM,aAAa,YAAY;AAC/D,aAAO;AAAA,IACT;AACA,cAAU,QAAQ;AAAA,EACpB;AACA,SAAO;AACT;AAEA,MAAM,uBAAuB,CAAC,UAAmB;AAC/C,QAAM,cAAc,gBAAgB,KAAK;AACzC,MAAI,aAAa;AACf,UAAM,OAAO,YAAY,sBAAsB;AAC/C,WAAO,EAAE,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK;AAAA,EAC1C;AACA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACF;AAEO,MAAM,kBAAkB,CAAC,UAAgC;AAC9D,QAAM,EAAE,WAAW,UAAU,WAAW,0BAA0B,cAAc,cAAc,IAAI;AAElG,QAAM,gBAAgB,gBAClB,qBAAqB,SAAS,IAC9B;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACJ,QAAM,gBAAgB,UAAU,sBAAsB;AACtD,QAAM,eAAe,SAAS,sBAAsB;AAEpD,QAAM,qBAAqB,UAAU,MAAM,GAAG,EAAE,CAAC;AACjD,QAAM,qBAAqB,4BAA4B,8BAA8B,SAAS;AAE9F,QAAM,SAA2E,CAAC;AAElF,MAAI,aAAa;AACjB,QAAM,aAAa,CAAC,SAAS,EAAE,OAAO,kBAAgE;AACtG,MAAI,iBAAiB;AAErB,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK,GAAG;AAC7C,UAAM,mBAAmB,WAAW,CAAC;AAErC,UAAM,uBAAuB,iBAAiB,MAAM,GAAG,EAAE,CAAC;AAC1D,iBAAa,CAAC,OAAO,QAAQ,EAAE,QAAQ,oBAAoB,KAAK;AAEhE,UAAM,YAAY,eAAe,eAAe,cAAc,kBAAkB,YAAY;AAE5F,UAAM,SAAoB,CAAC;AAE3B,UAAM,mBAAmB,uBAAuB;AAEhD,QAAI,oBAAyC,aACzC,mBACE,UACA,SACF,mBACA,WACA;AAEJ,UAAM,MAAM,aAAa,UAAU;AAEnC,QAAI,cAAc,GAAG,IAAI,aAAa,GAAG,GAAG;AAC1C,0BAAoB,qBAAqB,iBAAiB;AAAA,IAC5D;AAEA,UAAM,mBAAmB,qBAAqB,iBAAiB;AAE/D,WAAO,KAAK,UAAU,oBAAoB,KAAK,CAAC;AAChD,WAAO,KAAK,UAAU,iBAAiB,KAAK,GAAG,UAAU,gBAAgB,KAAK,CAAC;AAE/E,QACE,OAAO,MAAM,CAAC,UAAU;AACtB,aAAO;AAAA,IACT,CAAC,GACD;AACA,aAAO,MAAM,CAAC,UAAU,MAAM,OAAO,UAAU,cAAc;AAC7D,aAAO,OAAO,CAAC,UAAU,OAAO,OAAO,UAAU,cAAc;AAC/D,uBAAiB;AAEjB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa;AAAA,MACX,MAAM;AAAA,MACN,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,MAKL,WAAW,aAAa,OAAO,IAAI,OAAO,OAAO,GAAG;AAAA,IACtD;AAAA,IACA;AAAA,IACA,aAAa,eAAe,gBAAgB,UAAU;AAAA,EACxD;AACF;",
6
6
  "names": []
7
7
  }
@@ -12,6 +12,7 @@ export declare namespace DSHookFloatingContextT {
12
12
  placementOrderPreference?: PopperPlacementsT[];
13
13
  onOpen?: () => void;
14
14
  onClose?: () => void;
15
+ externallyControlledIsOpen?: boolean;
15
16
  }
16
17
  interface Props extends Partial<DefaultProps>, OptionalProps {
17
18
  }
@@ -9,6 +9,8 @@ interface ComputePositionProps {
9
9
  }
10
10
  export declare const computePosition: (props: ComputePositionProps) => {
11
11
  coordsStyle: {
12
+ left: number;
13
+ top: number;
12
14
  transform: string;
13
15
  };
14
16
  finalPlacement: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-floating-context",
3
- "version": "3.49.3",
3
+ "version": "3.49.5",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Popper Hook",
6
6
  "files": [
@@ -36,16 +36,16 @@
36
36
  "indent": 4
37
37
  },
38
38
  "dependencies": {
39
- "@elliemae/ds-hooks-headless-tooltip": "3.49.3",
40
- "@elliemae/ds-props-helpers": "3.49.3",
41
- "@elliemae/ds-system": "3.49.3",
42
- "@elliemae/ds-typescript-helpers": "3.49.3"
39
+ "@elliemae/ds-hooks-headless-tooltip": "3.49.5",
40
+ "@elliemae/ds-props-helpers": "3.49.5",
41
+ "@elliemae/ds-system": "3.49.5",
42
+ "@elliemae/ds-typescript-helpers": "3.49.5"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@elliemae/pui-cli": "~9.0.0-next.31",
46
46
  "jest": "~29.7.0",
47
47
  "jest-cli": "~29.7.0",
48
- "@elliemae/ds-monorepo-devops": "3.49.3"
48
+ "@elliemae/ds-monorepo-devops": "3.49.5"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "lodash": "^4.17.21",