@vielzeug/orbit 2.0.1 → 2.0.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.
- package/dist/auto-update.cjs.map +1 -1
- package/dist/auto-update.d.ts +10 -10
- package/dist/auto-update.d.ts.map +1 -1
- package/dist/auto-update.js.map +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js.map +1 -1
- package/dist/devtools.cjs.map +1 -1
- package/dist/devtools.d.ts.map +1 -1
- package/dist/devtools.js.map +1 -1
- package/dist/float.cjs.map +1 -1
- package/dist/float.d.ts +1 -1
- package/dist/float.d.ts.map +1 -1
- package/dist/float.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +15 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/inline.cjs.map +1 -1
- package/dist/inline.d.ts +7 -7
- package/dist/inline.d.ts.map +1 -1
- package/dist/inline.js.map +1 -1
- package/dist/middleware/auto-placement.cjs.map +1 -1
- package/dist/middleware/auto-placement.d.ts +5 -5
- package/dist/middleware/auto-placement.d.ts.map +1 -1
- package/dist/middleware/auto-placement.js.map +1 -1
- package/dist/middleware/flip.cjs.map +1 -1
- package/dist/middleware/flip.d.ts.map +1 -1
- package/dist/middleware/flip.js.map +1 -1
- package/dist/middleware/hide.cjs.map +1 -1
- package/dist/middleware/hide.d.ts.map +1 -1
- package/dist/middleware/hide.js.map +1 -1
- package/dist/middleware/shift.cjs.map +1 -1
- package/dist/middleware/shift.d.ts +5 -5
- package/dist/middleware/shift.d.ts.map +1 -1
- package/dist/middleware/shift.js.map +1 -1
- package/dist/middleware/size.cjs.map +1 -1
- package/dist/middleware/size.d.ts.map +1 -1
- package/dist/middleware/size.js.map +1 -1
- package/dist/orbit.cjs +1 -1
- package/dist/orbit.cjs.map +1 -1
- package/dist/orbit.iife.js +1 -1
- package/dist/orbit.iife.js.map +1 -1
- package/dist/orbit.js +1 -1
- package/dist/orbit.js.map +1 -1
- package/dist/presets.cjs.map +1 -1
- package/dist/presets.d.ts +1 -1
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js.map +1 -1
- package/dist/reactive.cjs.map +1 -1
- package/dist/reactive.d.ts +1 -1
- package/dist/reactive.d.ts.map +1 -1
- package/dist/reactive.js.map +1 -1
- package/dist/types.d.ts +32 -32
- package/dist/types.d.ts.map +1 -1
- package/package.json +36 -36
package/dist/auto-update.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-update.cjs","names":[],"sources":["../src/auto-update.ts"],"sourcesContent":["import type { ReferenceElement } from './types';\n\nimport { flatTreeParent, isElement } from './utils';\n\ntype ThrottledUpdate = (() => void) & { cancel(): void };\n\nfunction throttle(update: () => void, delay: number): ThrottledUpdate {\n let timer: ReturnType<typeof setTimeout> | undefined;\n let lastCall = 0;\n\n const throttled = (() => {\n const now = Date.now();\n const remaining = delay - (now - lastCall);\n\n if (remaining <= 0) {\n if (timer !== undefined) clearTimeout(timer);\n\n timer = undefined;\n lastCall = now;\n update();\n\n return;\n }\n\n if (timer !== undefined) return;\n\n timer = setTimeout(() => {\n timer = undefined;\n lastCall = Date.now();\n update();\n }, remaining);\n }) as ThrottledUpdate;\n\n throttled.cancel = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n\n timer = undefined;\n };\n\n return throttled;\n}\n\nexport interface AutoUpdateOptions {\n /** Watch the floating element for size changes. Default: `true`. */\n observeFloating?: boolean;\n /**\n * Listen to scroll events on ancestor scroll containers of the reference element\n * in addition to the window. More efficient in deeply nested DOMs.\n * Set to `false` to use only a capture-phase window listener.\n * Default: `true`.\n */\n observeAncestors?: boolean;\n /** Track visual viewport scroll and resize (useful for pinch-zoom). Default: `true`. */\n observeVisualViewport?: boolean;\n /** Re-position on every animation frame. Use only when the reference itself animates. Default: `false`. */\n animationFrame?: boolean;\n /**\n * Throttle update calls to at most once every `throttle` milliseconds.\n * Uses a leading + trailing strategy: fires immediately, then once more after the interval.\n * Default: `0` (no throttling).\n */\n throttle?: number;\n /**\n * Pause position updates while the reference element is scrolled out of the viewport.\n * Uses IntersectionObserver to detect visibility. When the reference becomes visible again,\n * one position update is fired immediately.\n * Default: `true`.\n */\n pauseWhenHidden?: boolean;\n}\n\n/**\n * Collects the ancestor scroll containers of an element (up to and including the\n * nearest scrollable ancestor). Used to scope scroll listeners to the minimal\n * set of elements rather than relying on a capture-phase window listener.\n *\n * Walks the flat (rendering) tree via `flatTreeParent` — not light-DOM `parentElement` alone —\n * so a scroll container that lives inside the shadow tree a component's light-DOM content is\n * *projected into* (e.g. a dialog's own internal scroll region, reached only by crossing its\n * `<slot>`) is still found, instead of silently skipped.\n */\nfunction getScrollAncestors(el: Element): Element[] {\n const ancestors: Element[] = [];\n let current: Element | null = flatTreeParent(el);\n\n while (current) {\n const style = getComputedStyle(current);\n const overflow = style.overflow + style.overflowX + style.overflowY;\n\n if (/auto|scroll|overlay/.test(overflow)) {\n ancestors.push(current);\n }\n\n current = flatTreeParent(current);\n }\n\n return ancestors;\n}\n\n/**\n * Calls `update` immediately and re-calls it whenever the reference or floating element\n * could have changed position: scroll, resize, ResizeObserver, or animation frames.\n *\n * By default, scroll listeners are attached to both ancestor scroll containers of the reference\n * AND the window (for document scroll). The ancestor listeners fire for nested container scrolls;\n * the window listener fires for page-level scroll. Set `observeAncestors: false` to use only a\n * capture-phase window listener.\n *\n * Returns a cleanup function that removes all listeners.\n *\n * @example\n * ```ts\n * const cleanup = autoUpdate(reference, floating, () => {\n * const { x, y } = computePosition(reference, floating, options);\n * floating.style.left = `${x}px`;\n * floating.style.top = `${y}px`;\n * });\n * // later:\n * cleanup();\n * ```\n */\nexport function autoUpdate(\n reference: ReferenceElement,\n floating: HTMLElement,\n update: () => void,\n {\n animationFrame = false,\n observeAncestors = true,\n observeFloating = true,\n observeVisualViewport = true,\n pauseWhenHidden = true,\n throttle: throttleMs = 0,\n }: AutoUpdateOptions = {},\n): () => void {\n const throttled = throttleMs > 0 ? throttle(update, throttleMs) : null;\n const notify = throttled ?? update;\n\n // ── Visibility guard ─────────────────────────────────────────────────────────\n let referenceVisible = true;\n const conditionalNotify = (): void => {\n if (referenceVisible) notify();\n };\n\n // Initial call always runs regardless of visibility state.\n notify();\n\n const cleanups: Array<() => void> = [];\n\n // IntersectionObserver: pause updates when reference is off-screen.\n if (pauseWhenHidden && isElement(reference) && typeof IntersectionObserver !== 'undefined') {\n const io = new IntersectionObserver((entries) => {\n referenceVisible = entries.at(-1)?.isIntersecting ?? true;\n\n if (referenceVisible) notify(); // Re-position immediately when becoming visible.\n });\n\n io.observe(reference);\n cleanups.push(() => io.disconnect());\n }\n\n // ── Scroll listeners ────────────────────────────────────────────────────────\n if (isElement(reference) && observeAncestors) {\n // Targeted ancestor listeners for nested container scroll.\n const ancestors = getScrollAncestors(reference);\n\n for (const ancestor of ancestors) {\n ancestor.addEventListener('scroll', conditionalNotify, { passive: true });\n cleanups.push(() => ancestor.removeEventListener('scroll', conditionalNotify));\n }\n\n // Always add window scroll for document-level scroll (non-capture, doesn't fire for nested containers).\n window.addEventListener('scroll', conditionalNotify, { passive: true });\n cleanups.push(() => window.removeEventListener('scroll', conditionalNotify));\n } else {\n // VirtualReference or observeAncestors: false — capture-phase window listener catches all scrolls.\n const scrollHandler = (e: Event): void => {\n if (e.composedPath().includes(floating)) return;\n\n conditionalNotify();\n };\n\n window.addEventListener('scroll', scrollHandler, { capture: true, passive: true });\n cleanups.push(() => window.removeEventListener('scroll', scrollHandler, { capture: true }));\n }\n\n window.addEventListener('resize', conditionalNotify, { passive: true });\n cleanups.push(() => window.removeEventListener('resize', conditionalNotify));\n\n const vv = observeVisualViewport ? window.visualViewport : null;\n\n if (vv) {\n vv.addEventListener('resize', conditionalNotify, { passive: true });\n vv.addEventListener('scroll', conditionalNotify, { passive: true });\n cleanups.push(() => {\n vv.removeEventListener('resize', conditionalNotify);\n vv.removeEventListener('scroll', conditionalNotify);\n });\n }\n\n const ro = new ResizeObserver(conditionalNotify);\n\n if (isElement(reference)) ro.observe(reference);\n\n if (observeFloating) ro.observe(floating);\n\n cleanups.push(() => ro.disconnect());\n\n let frameId = 0;\n\n if (animationFrame) {\n const frameLoop = (): void => {\n conditionalNotify();\n frameId = window.requestAnimationFrame(frameLoop);\n };\n\n frameId = window.requestAnimationFrame(frameLoop);\n cleanups.push(() => window.cancelAnimationFrame(frameId));\n }\n\n return (): void => {\n throttled?.cancel();\n\n for (const fn of cleanups) fn();\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auto-update.cjs","names":[],"sources":["../src/auto-update.ts"],"sourcesContent":["import type { ReferenceElement } from './types';\n\nimport { flatTreeParent, isElement } from './utils';\n\ntype ThrottledUpdate = (() => void) & { cancel(): void };\n\nfunction throttle(update: () => void, delay: number): ThrottledUpdate {\n let timer: ReturnType<typeof setTimeout> | undefined;\n let lastCall = 0;\n\n const throttled = (() => {\n const now = Date.now();\n const remaining = delay - (now - lastCall);\n\n if (remaining <= 0) {\n if (timer !== undefined) clearTimeout(timer);\n\n timer = undefined;\n lastCall = now;\n update();\n\n return;\n }\n\n if (timer !== undefined) return;\n\n timer = setTimeout(() => {\n timer = undefined;\n lastCall = Date.now();\n update();\n }, remaining);\n }) as ThrottledUpdate;\n\n throttled.cancel = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n\n timer = undefined;\n };\n\n return throttled;\n}\n\nexport interface AutoUpdateOptions {\n /** Re-position on every animation frame. Use only when the reference itself animates. Default: `false`. */\n animationFrame?: boolean;\n /**\n * Listen to scroll events on ancestor scroll containers of the reference element\n * in addition to the window. More efficient in deeply nested DOMs.\n * Set to `false` to use only a capture-phase window listener.\n * Default: `true`.\n */\n observeAncestors?: boolean;\n /** Watch the floating element for size changes. Default: `true`. */\n observeFloating?: boolean;\n /** Track visual viewport scroll and resize (useful for pinch-zoom). Default: `true`. */\n observeVisualViewport?: boolean;\n /**\n * Pause position updates while the reference element is scrolled out of the viewport.\n * Uses IntersectionObserver to detect visibility. When the reference becomes visible again,\n * one position update is fired immediately.\n * Default: `true`.\n */\n pauseWhenHidden?: boolean;\n /**\n * Throttle update calls to at most once every `throttle` milliseconds.\n * Uses a leading + trailing strategy: fires immediately, then once more after the interval.\n * Default: `0` (no throttling).\n */\n throttle?: number;\n}\n\n/**\n * Collects the ancestor scroll containers of an element (up to and including the\n * nearest scrollable ancestor). Used to scope scroll listeners to the minimal\n * set of elements rather than relying on a capture-phase window listener.\n *\n * Walks the flat (rendering) tree via `flatTreeParent` — not light-DOM `parentElement` alone —\n * so a scroll container that lives inside the shadow tree a component's light-DOM content is\n * *projected into* (e.g. a dialog's own internal scroll region, reached only by crossing its\n * `<slot>`) is still found, instead of silently skipped.\n */\nfunction getScrollAncestors(el: Element): Element[] {\n const ancestors: Element[] = [];\n let current: Element | null = flatTreeParent(el);\n\n while (current) {\n const style = getComputedStyle(current);\n const overflow = style.overflow + style.overflowX + style.overflowY;\n\n if (/auto|scroll|overlay/.test(overflow)) {\n ancestors.push(current);\n }\n\n current = flatTreeParent(current);\n }\n\n return ancestors;\n}\n\n/**\n * Calls `update` immediately and re-calls it whenever the reference or floating element\n * could have changed position: scroll, resize, ResizeObserver, or animation frames.\n *\n * By default, scroll listeners are attached to both ancestor scroll containers of the reference\n * AND the window (for document scroll). The ancestor listeners fire for nested container scrolls;\n * the window listener fires for page-level scroll. Set `observeAncestors: false` to use only a\n * capture-phase window listener.\n *\n * Returns a cleanup function that removes all listeners.\n *\n * @example\n * ```ts\n * const cleanup = autoUpdate(reference, floating, () => {\n * const { x, y } = computePosition(reference, floating, options);\n * floating.style.left = `${x}px`;\n * floating.style.top = `${y}px`;\n * });\n * // later:\n * cleanup();\n * ```\n */\nexport function autoUpdate(\n reference: ReferenceElement,\n floating: HTMLElement,\n update: () => void,\n {\n animationFrame = false,\n observeAncestors = true,\n observeFloating = true,\n observeVisualViewport = true,\n pauseWhenHidden = true,\n throttle: throttleMs = 0,\n }: AutoUpdateOptions = {},\n): () => void {\n const throttled = throttleMs > 0 ? throttle(update, throttleMs) : null;\n const notify = throttled ?? update;\n\n // ── Visibility guard ─────────────────────────────────────────────────────────\n let referenceVisible = true;\n const conditionalNotify = (): void => {\n if (referenceVisible) notify();\n };\n\n // Initial call always runs regardless of visibility state.\n notify();\n\n const cleanups: Array<() => void> = [];\n\n // IntersectionObserver: pause updates when reference is off-screen.\n if (pauseWhenHidden && isElement(reference) && typeof IntersectionObserver !== 'undefined') {\n const io = new IntersectionObserver((entries) => {\n referenceVisible = entries.at(-1)?.isIntersecting ?? true;\n\n if (referenceVisible) notify(); // Re-position immediately when becoming visible.\n });\n\n io.observe(reference);\n cleanups.push(() => io.disconnect());\n }\n\n // ── Scroll listeners ────────────────────────────────────────────────────────\n if (isElement(reference) && observeAncestors) {\n // Targeted ancestor listeners for nested container scroll.\n const ancestors = getScrollAncestors(reference);\n\n for (const ancestor of ancestors) {\n ancestor.addEventListener('scroll', conditionalNotify, { passive: true });\n cleanups.push(() => ancestor.removeEventListener('scroll', conditionalNotify));\n }\n\n // Always add window scroll for document-level scroll (non-capture, doesn't fire for nested containers).\n window.addEventListener('scroll', conditionalNotify, { passive: true });\n cleanups.push(() => window.removeEventListener('scroll', conditionalNotify));\n } else {\n // VirtualReference or observeAncestors: false — capture-phase window listener catches all scrolls.\n const scrollHandler = (e: Event): void => {\n if (e.composedPath().includes(floating)) return;\n\n conditionalNotify();\n };\n\n window.addEventListener('scroll', scrollHandler, { capture: true, passive: true });\n cleanups.push(() => window.removeEventListener('scroll', scrollHandler, { capture: true }));\n }\n\n window.addEventListener('resize', conditionalNotify, { passive: true });\n cleanups.push(() => window.removeEventListener('resize', conditionalNotify));\n\n const vv = observeVisualViewport ? window.visualViewport : null;\n\n if (vv) {\n vv.addEventListener('resize', conditionalNotify, { passive: true });\n vv.addEventListener('scroll', conditionalNotify, { passive: true });\n cleanups.push(() => {\n vv.removeEventListener('resize', conditionalNotify);\n vv.removeEventListener('scroll', conditionalNotify);\n });\n }\n\n const ro = new ResizeObserver(conditionalNotify);\n\n if (isElement(reference)) ro.observe(reference);\n\n if (observeFloating) ro.observe(floating);\n\n cleanups.push(() => ro.disconnect());\n\n let frameId = 0;\n\n if (animationFrame) {\n const frameLoop = (): void => {\n conditionalNotify();\n frameId = window.requestAnimationFrame(frameLoop);\n };\n\n frameId = window.requestAnimationFrame(frameLoop);\n cleanups.push(() => window.cancelAnimationFrame(frameId));\n }\n\n return (): void => {\n throttled?.cancel();\n\n for (const fn of cleanups) fn();\n };\n}\n"],"mappings":"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"}
|
package/dist/auto-update.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReferenceElement } from './types';
|
|
2
2
|
export interface AutoUpdateOptions {
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/** Re-position on every animation frame. Use only when the reference itself animates. Default: `false`. */
|
|
4
|
+
animationFrame?: boolean;
|
|
5
5
|
/**
|
|
6
6
|
* Listen to scroll events on ancestor scroll containers of the reference element
|
|
7
7
|
* in addition to the window. More efficient in deeply nested DOMs.
|
|
@@ -9,16 +9,10 @@ export interface AutoUpdateOptions {
|
|
|
9
9
|
* Default: `true`.
|
|
10
10
|
*/
|
|
11
11
|
observeAncestors?: boolean;
|
|
12
|
+
/** Watch the floating element for size changes. Default: `true`. */
|
|
13
|
+
observeFloating?: boolean;
|
|
12
14
|
/** Track visual viewport scroll and resize (useful for pinch-zoom). Default: `true`. */
|
|
13
15
|
observeVisualViewport?: boolean;
|
|
14
|
-
/** Re-position on every animation frame. Use only when the reference itself animates. Default: `false`. */
|
|
15
|
-
animationFrame?: boolean;
|
|
16
|
-
/**
|
|
17
|
-
* Throttle update calls to at most once every `throttle` milliseconds.
|
|
18
|
-
* Uses a leading + trailing strategy: fires immediately, then once more after the interval.
|
|
19
|
-
* Default: `0` (no throttling).
|
|
20
|
-
*/
|
|
21
|
-
throttle?: number;
|
|
22
16
|
/**
|
|
23
17
|
* Pause position updates while the reference element is scrolled out of the viewport.
|
|
24
18
|
* Uses IntersectionObserver to detect visibility. When the reference becomes visible again,
|
|
@@ -26,6 +20,12 @@ export interface AutoUpdateOptions {
|
|
|
26
20
|
* Default: `true`.
|
|
27
21
|
*/
|
|
28
22
|
pauseWhenHidden?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Throttle update calls to at most once every `throttle` milliseconds.
|
|
25
|
+
* Uses a leading + trailing strategy: fires immediately, then once more after the interval.
|
|
26
|
+
* Default: `0` (no throttling).
|
|
27
|
+
*/
|
|
28
|
+
throttle?: number;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* Calls `update` immediately and re-calls it whenever the reference or floating element
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-update.d.ts","sourceRoot":"","sources":["../src/auto-update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA0ChD,MAAM,WAAW,iBAAiB;IAChC,
|
|
1
|
+
{"version":3,"file":"auto-update.d.ts","sourceRoot":"","sources":["../src/auto-update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA0ChD,MAAM,WAAW,iBAAiB;IAChC,2GAA2G;IAC3G,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oEAAoE;IACpE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wFAAwF;IACxF,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA8BD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,MAAM,IAAI,EAClB,EACE,cAAsB,EACtB,gBAAuB,EACvB,eAAsB,EACtB,qBAA4B,EAC5B,eAAsB,EACtB,QAAQ,EAAE,UAAc,GACzB,GAAE,iBAAsB,GACxB,MAAM,IAAI,CA2FZ"}
|
package/dist/auto-update.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-update.js","names":[],"sources":["../src/auto-update.ts"],"sourcesContent":["import type { ReferenceElement } from './types';\n\nimport { flatTreeParent, isElement } from './utils';\n\ntype ThrottledUpdate = (() => void) & { cancel(): void };\n\nfunction throttle(update: () => void, delay: number): ThrottledUpdate {\n let timer: ReturnType<typeof setTimeout> | undefined;\n let lastCall = 0;\n\n const throttled = (() => {\n const now = Date.now();\n const remaining = delay - (now - lastCall);\n\n if (remaining <= 0) {\n if (timer !== undefined) clearTimeout(timer);\n\n timer = undefined;\n lastCall = now;\n update();\n\n return;\n }\n\n if (timer !== undefined) return;\n\n timer = setTimeout(() => {\n timer = undefined;\n lastCall = Date.now();\n update();\n }, remaining);\n }) as ThrottledUpdate;\n\n throttled.cancel = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n\n timer = undefined;\n };\n\n return throttled;\n}\n\nexport interface AutoUpdateOptions {\n /** Watch the floating element for size changes. Default: `true`. */\n observeFloating?: boolean;\n /**\n * Listen to scroll events on ancestor scroll containers of the reference element\n * in addition to the window. More efficient in deeply nested DOMs.\n * Set to `false` to use only a capture-phase window listener.\n * Default: `true`.\n */\n observeAncestors?: boolean;\n /** Track visual viewport scroll and resize (useful for pinch-zoom). Default: `true`. */\n observeVisualViewport?: boolean;\n /** Re-position on every animation frame. Use only when the reference itself animates. Default: `false`. */\n animationFrame?: boolean;\n /**\n * Throttle update calls to at most once every `throttle` milliseconds.\n * Uses a leading + trailing strategy: fires immediately, then once more after the interval.\n * Default: `0` (no throttling).\n */\n throttle?: number;\n /**\n * Pause position updates while the reference element is scrolled out of the viewport.\n * Uses IntersectionObserver to detect visibility. When the reference becomes visible again,\n * one position update is fired immediately.\n * Default: `true`.\n */\n pauseWhenHidden?: boolean;\n}\n\n/**\n * Collects the ancestor scroll containers of an element (up to and including the\n * nearest scrollable ancestor). Used to scope scroll listeners to the minimal\n * set of elements rather than relying on a capture-phase window listener.\n *\n * Walks the flat (rendering) tree via `flatTreeParent` — not light-DOM `parentElement` alone —\n * so a scroll container that lives inside the shadow tree a component's light-DOM content is\n * *projected into* (e.g. a dialog's own internal scroll region, reached only by crossing its\n * `<slot>`) is still found, instead of silently skipped.\n */\nfunction getScrollAncestors(el: Element): Element[] {\n const ancestors: Element[] = [];\n let current: Element | null = flatTreeParent(el);\n\n while (current) {\n const style = getComputedStyle(current);\n const overflow = style.overflow + style.overflowX + style.overflowY;\n\n if (/auto|scroll|overlay/.test(overflow)) {\n ancestors.push(current);\n }\n\n current = flatTreeParent(current);\n }\n\n return ancestors;\n}\n\n/**\n * Calls `update` immediately and re-calls it whenever the reference or floating element\n * could have changed position: scroll, resize, ResizeObserver, or animation frames.\n *\n * By default, scroll listeners are attached to both ancestor scroll containers of the reference\n * AND the window (for document scroll). The ancestor listeners fire for nested container scrolls;\n * the window listener fires for page-level scroll. Set `observeAncestors: false` to use only a\n * capture-phase window listener.\n *\n * Returns a cleanup function that removes all listeners.\n *\n * @example\n * ```ts\n * const cleanup = autoUpdate(reference, floating, () => {\n * const { x, y } = computePosition(reference, floating, options);\n * floating.style.left = `${x}px`;\n * floating.style.top = `${y}px`;\n * });\n * // later:\n * cleanup();\n * ```\n */\nexport function autoUpdate(\n reference: ReferenceElement,\n floating: HTMLElement,\n update: () => void,\n {\n animationFrame = false,\n observeAncestors = true,\n observeFloating = true,\n observeVisualViewport = true,\n pauseWhenHidden = true,\n throttle: throttleMs = 0,\n }: AutoUpdateOptions = {},\n): () => void {\n const throttled = throttleMs > 0 ? throttle(update, throttleMs) : null;\n const notify = throttled ?? update;\n\n // ── Visibility guard ─────────────────────────────────────────────────────────\n let referenceVisible = true;\n const conditionalNotify = (): void => {\n if (referenceVisible) notify();\n };\n\n // Initial call always runs regardless of visibility state.\n notify();\n\n const cleanups: Array<() => void> = [];\n\n // IntersectionObserver: pause updates when reference is off-screen.\n if (pauseWhenHidden && isElement(reference) && typeof IntersectionObserver !== 'undefined') {\n const io = new IntersectionObserver((entries) => {\n referenceVisible = entries.at(-1)?.isIntersecting ?? true;\n\n if (referenceVisible) notify(); // Re-position immediately when becoming visible.\n });\n\n io.observe(reference);\n cleanups.push(() => io.disconnect());\n }\n\n // ── Scroll listeners ────────────────────────────────────────────────────────\n if (isElement(reference) && observeAncestors) {\n // Targeted ancestor listeners for nested container scroll.\n const ancestors = getScrollAncestors(reference);\n\n for (const ancestor of ancestors) {\n ancestor.addEventListener('scroll', conditionalNotify, { passive: true });\n cleanups.push(() => ancestor.removeEventListener('scroll', conditionalNotify));\n }\n\n // Always add window scroll for document-level scroll (non-capture, doesn't fire for nested containers).\n window.addEventListener('scroll', conditionalNotify, { passive: true });\n cleanups.push(() => window.removeEventListener('scroll', conditionalNotify));\n } else {\n // VirtualReference or observeAncestors: false — capture-phase window listener catches all scrolls.\n const scrollHandler = (e: Event): void => {\n if (e.composedPath().includes(floating)) return;\n\n conditionalNotify();\n };\n\n window.addEventListener('scroll', scrollHandler, { capture: true, passive: true });\n cleanups.push(() => window.removeEventListener('scroll', scrollHandler, { capture: true }));\n }\n\n window.addEventListener('resize', conditionalNotify, { passive: true });\n cleanups.push(() => window.removeEventListener('resize', conditionalNotify));\n\n const vv = observeVisualViewport ? window.visualViewport : null;\n\n if (vv) {\n vv.addEventListener('resize', conditionalNotify, { passive: true });\n vv.addEventListener('scroll', conditionalNotify, { passive: true });\n cleanups.push(() => {\n vv.removeEventListener('resize', conditionalNotify);\n vv.removeEventListener('scroll', conditionalNotify);\n });\n }\n\n const ro = new ResizeObserver(conditionalNotify);\n\n if (isElement(reference)) ro.observe(reference);\n\n if (observeFloating) ro.observe(floating);\n\n cleanups.push(() => ro.disconnect());\n\n let frameId = 0;\n\n if (animationFrame) {\n const frameLoop = (): void => {\n conditionalNotify();\n frameId = window.requestAnimationFrame(frameLoop);\n };\n\n frameId = window.requestAnimationFrame(frameLoop);\n cleanups.push(() => window.cancelAnimationFrame(frameId));\n }\n\n return (): void => {\n throttled?.cancel();\n\n for (const fn of cleanups) fn();\n };\n}\n"],"mappings":"2DAMA,SAAS,EAAS,EAAoB,EAAgC,CACpE,IAAI,EACA,EAAW,EAET,OAAmB,CACvB,IAAM,EAAM,KAAK,IAAI,EACf,EAAY,GAAS,EAAM,GAEjC,GAAI,GAAa,EAAG,CACd,IAAU,IAAA,IAAW,aAAa,CAAK,EAE3C,EAAQ,IAAA,GACR,EAAW,EACX,EAAO,EAEP,MACF,CAEI,IAAU,IAAA,KAEd,EAAQ,eAAiB,CACvB,EAAQ,IAAA,GACR,EAAW,KAAK,IAAI,EACpB,EAAO,CACT,EAAG,CAAS,EACd,GAQA,MANA,GAAU,WAAqB,CACzB,IAAU,IAAA,IAAW,aAAa,CAAK,EAE3C,EAAQ,IAAA,EACV,EAEO,CACT,CAyCA,SAAS,EAAmB,EAAwB,CAClD,IAAM,EAAuB,CAAC,EAC1B,EAA0B,EAAe,CAAE,EAE/C,KAAO,GAAS,CACd,IAAM,EAAQ,iBAAiB,CAAO,EAChC,EAAW,EAAM,SAAW,EAAM,UAAY,EAAM,UAEtD,sBAAsB,KAAK,CAAQ,GACrC,EAAU,KAAK,CAAO,EAGxB,EAAU,EAAe,CAAO,CAClC,CAEA,OAAO,CACT,CAwBA,SAAgB,EACd,EACA,EACA,EACA,CACE,iBAAiB,GACjB,mBAAmB,GACnB,kBAAkB,GAClB,wBAAwB,GACxB,kBAAkB,GAClB,SAAU,EAAa,GACF,CAAC,EACZ,CACZ,IAAM,EAAY,EAAa,EAAI,EAAS,EAAQ,CAAU,EAAI,KAC5D,EAAS,GAAa,EAGxB,EAAmB,GACjB,MAAgC,CAChC,GAAkB,EAAO,CAC/B,EAGA,EAAO,EAEP,IAAM,EAA8B,CAAC,EAGrC,GAAI,GAAmB,EAAU,CAAS,GAAK,OAAO,qBAAyB,IAAa,CAC1F,IAAM,EAAK,IAAI,qBAAsB,GAAY,CAC/C,EAAmB,EAAQ,GAAG,EAAE,CAAC,EAAE,gBAAkB,GAEjD,GAAkB,EAAO,CAC/B,CAAC,EAED,EAAG,QAAQ,CAAS,EACpB,EAAS,SAAW,EAAG,WAAW,CAAC,CACrC,CAGA,GAAI,EAAU,CAAS,GAAK,EAAkB,CAE5C,IAAM,EAAY,EAAmB,CAAS,EAE9C,IAAK,IAAM,KAAY,EACrB,EAAS,iBAAiB,SAAU,EAAmB,CAAE,QAAS,EAAK,CAAC,EACxE,EAAS,SAAW,EAAS,oBAAoB,SAAU,CAAiB,CAAC,EAI/E,OAAO,iBAAiB,SAAU,EAAmB,CAAE,QAAS,EAAK,CAAC,EACtE,EAAS,SAAW,OAAO,oBAAoB,SAAU,CAAiB,CAAC,CAC7E,KAAO,CAEL,IAAM,EAAiB,GAAmB,CACpC,EAAE,aAAa,CAAC,CAAC,SAAS,CAAQ,GAEtC,EAAkB,CACpB,EAEA,OAAO,iBAAiB,SAAU,EAAe,CAAE,QAAS,GAAM,QAAS,EAAK,CAAC,EACjF,EAAS,SAAW,OAAO,oBAAoB,SAAU,EAAe,CAAE,QAAS,EAAK,CAAC,CAAC,CAC5F,CAEA,OAAO,iBAAiB,SAAU,EAAmB,CAAE,QAAS,EAAK,CAAC,EACtE,EAAS,SAAW,OAAO,oBAAoB,SAAU,CAAiB,CAAC,EAE3E,IAAM,EAAK,EAAwB,OAAO,eAAiB,KAEvD,IACF,EAAG,iBAAiB,SAAU,EAAmB,CAAE,QAAS,EAAK,CAAC,EAClE,EAAG,iBAAiB,SAAU,EAAmB,CAAE,QAAS,EAAK,CAAC,EAClE,EAAS,SAAW,CAClB,EAAG,oBAAoB,SAAU,CAAiB,EAClD,EAAG,oBAAoB,SAAU,CAAiB,CACpD,CAAC,GAGH,IAAM,EAAK,IAAI,eAAe,CAAiB,EAE3C,EAAU,CAAS,GAAG,EAAG,QAAQ,CAAS,EAE1C,GAAiB,EAAG,QAAQ,CAAQ,EAExC,EAAS,SAAW,EAAG,WAAW,CAAC,EAEnC,IAAI,EAAU,EAEd,GAAI,EAAgB,CAClB,IAAM,MAAwB,CAC5B,EAAkB,EAClB,EAAU,OAAO,sBAAsB,CAAS,CAClD,EAEA,EAAU,OAAO,sBAAsB,CAAS,EAChD,EAAS,SAAW,OAAO,qBAAqB,CAAO,CAAC,CAC1D,CAEA,UAAmB,CACjB,GAAW,OAAO,EAElB,IAAK,IAAM,KAAM,EAAU,EAAG,CAChC,CACF"}
|
|
1
|
+
{"version":3,"file":"auto-update.js","names":[],"sources":["../src/auto-update.ts"],"sourcesContent":["import type { ReferenceElement } from './types';\n\nimport { flatTreeParent, isElement } from './utils';\n\ntype ThrottledUpdate = (() => void) & { cancel(): void };\n\nfunction throttle(update: () => void, delay: number): ThrottledUpdate {\n let timer: ReturnType<typeof setTimeout> | undefined;\n let lastCall = 0;\n\n const throttled = (() => {\n const now = Date.now();\n const remaining = delay - (now - lastCall);\n\n if (remaining <= 0) {\n if (timer !== undefined) clearTimeout(timer);\n\n timer = undefined;\n lastCall = now;\n update();\n\n return;\n }\n\n if (timer !== undefined) return;\n\n timer = setTimeout(() => {\n timer = undefined;\n lastCall = Date.now();\n update();\n }, remaining);\n }) as ThrottledUpdate;\n\n throttled.cancel = (): void => {\n if (timer !== undefined) clearTimeout(timer);\n\n timer = undefined;\n };\n\n return throttled;\n}\n\nexport interface AutoUpdateOptions {\n /** Re-position on every animation frame. Use only when the reference itself animates. Default: `false`. */\n animationFrame?: boolean;\n /**\n * Listen to scroll events on ancestor scroll containers of the reference element\n * in addition to the window. More efficient in deeply nested DOMs.\n * Set to `false` to use only a capture-phase window listener.\n * Default: `true`.\n */\n observeAncestors?: boolean;\n /** Watch the floating element for size changes. Default: `true`. */\n observeFloating?: boolean;\n /** Track visual viewport scroll and resize (useful for pinch-zoom). Default: `true`. */\n observeVisualViewport?: boolean;\n /**\n * Pause position updates while the reference element is scrolled out of the viewport.\n * Uses IntersectionObserver to detect visibility. When the reference becomes visible again,\n * one position update is fired immediately.\n * Default: `true`.\n */\n pauseWhenHidden?: boolean;\n /**\n * Throttle update calls to at most once every `throttle` milliseconds.\n * Uses a leading + trailing strategy: fires immediately, then once more after the interval.\n * Default: `0` (no throttling).\n */\n throttle?: number;\n}\n\n/**\n * Collects the ancestor scroll containers of an element (up to and including the\n * nearest scrollable ancestor). Used to scope scroll listeners to the minimal\n * set of elements rather than relying on a capture-phase window listener.\n *\n * Walks the flat (rendering) tree via `flatTreeParent` — not light-DOM `parentElement` alone —\n * so a scroll container that lives inside the shadow tree a component's light-DOM content is\n * *projected into* (e.g. a dialog's own internal scroll region, reached only by crossing its\n * `<slot>`) is still found, instead of silently skipped.\n */\nfunction getScrollAncestors(el: Element): Element[] {\n const ancestors: Element[] = [];\n let current: Element | null = flatTreeParent(el);\n\n while (current) {\n const style = getComputedStyle(current);\n const overflow = style.overflow + style.overflowX + style.overflowY;\n\n if (/auto|scroll|overlay/.test(overflow)) {\n ancestors.push(current);\n }\n\n current = flatTreeParent(current);\n }\n\n return ancestors;\n}\n\n/**\n * Calls `update` immediately and re-calls it whenever the reference or floating element\n * could have changed position: scroll, resize, ResizeObserver, or animation frames.\n *\n * By default, scroll listeners are attached to both ancestor scroll containers of the reference\n * AND the window (for document scroll). The ancestor listeners fire for nested container scrolls;\n * the window listener fires for page-level scroll. Set `observeAncestors: false` to use only a\n * capture-phase window listener.\n *\n * Returns a cleanup function that removes all listeners.\n *\n * @example\n * ```ts\n * const cleanup = autoUpdate(reference, floating, () => {\n * const { x, y } = computePosition(reference, floating, options);\n * floating.style.left = `${x}px`;\n * floating.style.top = `${y}px`;\n * });\n * // later:\n * cleanup();\n * ```\n */\nexport function autoUpdate(\n reference: ReferenceElement,\n floating: HTMLElement,\n update: () => void,\n {\n animationFrame = false,\n observeAncestors = true,\n observeFloating = true,\n observeVisualViewport = true,\n pauseWhenHidden = true,\n throttle: throttleMs = 0,\n }: AutoUpdateOptions = {},\n): () => void {\n const throttled = throttleMs > 0 ? throttle(update, throttleMs) : null;\n const notify = throttled ?? update;\n\n // ── Visibility guard ─────────────────────────────────────────────────────────\n let referenceVisible = true;\n const conditionalNotify = (): void => {\n if (referenceVisible) notify();\n };\n\n // Initial call always runs regardless of visibility state.\n notify();\n\n const cleanups: Array<() => void> = [];\n\n // IntersectionObserver: pause updates when reference is off-screen.\n if (pauseWhenHidden && isElement(reference) && typeof IntersectionObserver !== 'undefined') {\n const io = new IntersectionObserver((entries) => {\n referenceVisible = entries.at(-1)?.isIntersecting ?? true;\n\n if (referenceVisible) notify(); // Re-position immediately when becoming visible.\n });\n\n io.observe(reference);\n cleanups.push(() => io.disconnect());\n }\n\n // ── Scroll listeners ────────────────────────────────────────────────────────\n if (isElement(reference) && observeAncestors) {\n // Targeted ancestor listeners for nested container scroll.\n const ancestors = getScrollAncestors(reference);\n\n for (const ancestor of ancestors) {\n ancestor.addEventListener('scroll', conditionalNotify, { passive: true });\n cleanups.push(() => ancestor.removeEventListener('scroll', conditionalNotify));\n }\n\n // Always add window scroll for document-level scroll (non-capture, doesn't fire for nested containers).\n window.addEventListener('scroll', conditionalNotify, { passive: true });\n cleanups.push(() => window.removeEventListener('scroll', conditionalNotify));\n } else {\n // VirtualReference or observeAncestors: false — capture-phase window listener catches all scrolls.\n const scrollHandler = (e: Event): void => {\n if (e.composedPath().includes(floating)) return;\n\n conditionalNotify();\n };\n\n window.addEventListener('scroll', scrollHandler, { capture: true, passive: true });\n cleanups.push(() => window.removeEventListener('scroll', scrollHandler, { capture: true }));\n }\n\n window.addEventListener('resize', conditionalNotify, { passive: true });\n cleanups.push(() => window.removeEventListener('resize', conditionalNotify));\n\n const vv = observeVisualViewport ? window.visualViewport : null;\n\n if (vv) {\n vv.addEventListener('resize', conditionalNotify, { passive: true });\n vv.addEventListener('scroll', conditionalNotify, { passive: true });\n cleanups.push(() => {\n vv.removeEventListener('resize', conditionalNotify);\n vv.removeEventListener('scroll', conditionalNotify);\n });\n }\n\n const ro = new ResizeObserver(conditionalNotify);\n\n if (isElement(reference)) ro.observe(reference);\n\n if (observeFloating) ro.observe(floating);\n\n cleanups.push(() => ro.disconnect());\n\n let frameId = 0;\n\n if (animationFrame) {\n const frameLoop = (): void => {\n conditionalNotify();\n frameId = window.requestAnimationFrame(frameLoop);\n };\n\n frameId = window.requestAnimationFrame(frameLoop);\n cleanups.push(() => window.cancelAnimationFrame(frameId));\n }\n\n return (): void => {\n throttled?.cancel();\n\n for (const fn of cleanups) fn();\n };\n}\n"],"mappings":"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"}
|
package/dist/core.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.cjs","names":[],"sources":["../src/core.ts"],"sourcesContent":["import type {\n ComputePositionOptions,\n ComputePositionResult,\n MiddlewareData,\n MiddlewareReset,\n MiddlewareResult,\n MiddlewareState,\n ReferenceElement,\n} from './types';\
|
|
1
|
+
{"version":3,"file":"core.cjs","names":[],"sources":["../src/core.ts"],"sourcesContent":["import { devOnly, warn } from './_dev';\nimport { OrbitConfigError } from './errors';\nimport type {\n ComputePositionOptions,\n ComputePositionResult,\n MiddlewareData,\n MiddlewareReset,\n MiddlewareResult,\n MiddlewareState,\n ReferenceElement,\n} from './types';\nimport { baseCoords, toRect } from './utils';\n\n// ── DOM helpers ────────────────────────────────────────────────────────────────────────────────\n\n/** Reads the bounding rects of the reference and floating elements from the DOM. */\nexport function getRects(reference: ReferenceElement, floating: HTMLElement): MiddlewareState['rects'] {\n return {\n floating: toRect(floating.getBoundingClientRect()),\n reference: toRect(reference.getBoundingClientRect()),\n };\n}\n\n// ── Internal state helpers ───────────────────────────────────────────────────────────\n\nfunction mergeState(state: MiddlewareState, result: MiddlewareResult | undefined): MiddlewareState {\n if (!result) return state;\n\n return {\n ...state,\n middlewareData: result.data\n ? (Object.assign(Object.create(null), state.middlewareData, result.data) as MiddlewareData)\n : state.middlewareData,\n placement: result.placement ?? state.placement,\n x: result.x ?? state.x,\n y: result.y ?? state.y,\n };\n}\n\n// ── Constants ─────────────────────────────────────────────────────────────────────────────────\n\n/** Maximum number of pipeline restarts allowed per `computePosition` call before throwing. */\nconst MAX_RESETS = 8;\n\n// ── Public API ────────────────────────────────────────────────────────────────────────────────\n\n/**\n * Deferred position computation. Runs `computePosition` in the next **microtask** and\n * returns a `Promise<ComputePositionResult>`.\n *\n * Useful for async component lifecycles (e.g. `await nextTick()` in Vue/React) where the\n * synchronous `computePosition` would read stale DOM measurements because layout has not been\n * committed yet. Note: this defers to the microtask queue, not the next animation frame — if you\n * need post-layout measurements use `requestAnimationFrame` instead.\n *\n * @example\n * ```ts\n * const result = await computePositionAsync(reference, floating, { placement: 'top' });\n * floating.style.left = `${result.x}px`;\n * floating.style.top = `${result.y}px`;\n * ```\n */\nexport function computePositionAsync(\n reference: ReferenceElement,\n floating: HTMLElement,\n options?: ComputePositionOptions,\n): Promise<ComputePositionResult> {\n return Promise.resolve().then(() => computePosition(reference, floating, options));\n}\n\n/**\n * Deferred position computation. Runs `computePosition` in the next **animation frame** and\n * returns a `Promise<ComputePositionResult>`.\n *\n * Useful when the layout has not yet committed (e.g. immediately after DOM insertion). Unlike\n * `computePositionAsync` which defers to the microtask queue, this waits for the next\n * `requestAnimationFrame` tick — guaranteeing post-layout DOM measurements.\n *\n * @example\n * ```ts\n * const result = await computePositionRaf(reference, floating, { placement: 'top' });\n * floating.style.left = `${result.x}px`;\n * floating.style.top = `${result.y}px`;\n * ```\n */\nexport function computePositionRaf(\n reference: ReferenceElement,\n floating: HTMLElement,\n options?: ComputePositionOptions,\n): Promise<ComputePositionResult> {\n return new Promise((resolve, reject) => {\n requestAnimationFrame(() => {\n try {\n resolve(computePosition(reference, floating, options));\n } catch (err) {\n reject(err);\n }\n });\n });\n}\n\n/**\n * Runs the middleware pipeline and returns the final position.\n *\n * Position is computed in viewport-relative coordinates assuming `position: fixed`.\n */\nexport function computePosition(\n reference: ReferenceElement,\n floating: HTMLElement,\n { boundary, containingBlock, middleware = [], padding, placement = 'bottom' }: ComputePositionOptions = {},\n): ComputePositionResult {\n const mws = middleware;\n\n if (reference === floating) {\n warn('computePosition: reference and floating are the same element.');\n }\n\n let currentPlacement = placement;\n let middlewareData: MiddlewareData = {};\n let rects = getRects(reference, floating);\n\n devOnly(() => {\n if (rects.floating.width === 0 && rects.floating.height === 0) {\n warn('computePosition: floating element has zero dimensions — is it hidden or detached from the DOM?');\n }\n\n const pos = getComputedStyle(floating).position;\n\n if (pos !== 'fixed' && pos !== 'absolute') {\n warn(\n `computePosition: floating element has \\`position: ${pos}\\`. ` +\n 'Orbit computes viewport-relative coordinates and expects position: fixed ' +\n '(or absolute for scoped stacking contexts).',\n );\n }\n });\n\n for (let resets = 0; resets < MAX_RESETS; resets += 1) {\n let state: MiddlewareState = {\n ...baseCoords(currentPlacement, rects.reference, rects.floating),\n boundary,\n elements: { floating, reference },\n initialPlacement: placement,\n middlewareData,\n padding,\n placement: currentPlacement,\n rects,\n };\n\n let reset: MiddlewareReset | undefined;\n\n for (const mw of mws) {\n const result = mw(state);\n\n state = mergeState(state, result);\n middlewareData = state.middlewareData;\n reset = result?.reset;\n\n if (reset) break;\n }\n\n if (!reset) {\n const result: ComputePositionResult = {\n middlewareData: state.middlewareData,\n placement: state.placement,\n x: state.x,\n y: state.y,\n };\n\n if (containingBlock) {\n const cb = containingBlock.getBoundingClientRect();\n\n return { ...result, x: result.x - cb.x, y: result.y - cb.y };\n }\n\n return result;\n }\n\n if (reset.remeasure) {\n rects = getRects(reference, floating);\n } else if (reset.rects != null) {\n rects = reset.rects;\n }\n\n currentPlacement = reset.placement ?? state.placement;\n }\n\n throw new OrbitConfigError('Middleware triggered too many resets in a single compute cycle.');\n}\n"],"mappings":"qFAgBA,SAAgB,EAAS,EAA6B,EAAiD,CACrG,MAAO,CACL,SAAU,EAAA,OAAO,EAAS,sBAAsB,CAAC,EACjD,UAAW,EAAA,OAAO,EAAU,sBAAsB,CAAC,CACrD,CACF,CAIA,SAAS,EAAW,EAAwB,EAAuD,CAGjG,OAFK,EAEE,CACL,GAAG,EACH,eAAgB,EAAO,KAClB,OAAO,OAAO,OAAO,OAAO,IAAI,EAAG,EAAM,eAAgB,EAAO,IAAI,EACrE,EAAM,eACV,UAAW,EAAO,WAAa,EAAM,UACrC,EAAG,EAAO,GAAK,EAAM,EACrB,EAAG,EAAO,GAAK,EAAM,CACvB,EAVoB,CAWtB,CAKA,IAAM,EAAa,EAoBnB,SAAgB,EACd,EACA,EACA,EACgC,CAChC,OAAO,QAAQ,QAAQ,CAAC,CAAC,SAAW,EAAgB,EAAW,EAAU,CAAO,CAAC,CACnF,CAiBA,SAAgB,EACd,EACA,EACA,EACgC,CAChC,OAAO,IAAI,SAAS,EAAS,IAAW,CACtC,0BAA4B,CAC1B,GAAI,CACF,EAAQ,EAAgB,EAAW,EAAU,CAAO,CAAC,CACvD,OAAS,EAAK,CACZ,EAAO,CAAG,CACZ,CACF,CAAC,CACH,CAAC,CACH,CAOA,SAAgB,EACd,EACA,EACA,CAAE,WAAU,kBAAiB,aAAa,CAAC,EAAG,UAAS,YAAY,UAAqC,CAAC,EAClF,CACvB,IAAM,EAAM,EAMR,EAAmB,EACnB,EAAiC,CAAC,EAClC,EAAQ,EAAS,EAAW,CAAQ,EAkBxC,IAAK,IAAI,EAAS,EAAG,EAAS,EAAY,GAAU,EAAG,CACrD,IAAI,EAAyB,CAC3B,GAAG,EAAA,WAAW,EAAkB,EAAM,UAAW,EAAM,QAAQ,EAC/D,WACA,SAAU,CAAE,WAAU,WAAU,EAChC,iBAAkB,EAClB,iBACA,UACA,UAAW,EACX,OACF,EAEI,EAEJ,IAAK,IAAM,KAAM,EAAK,CACpB,IAAM,EAAS,EAAG,CAAK,EAMvB,GAJA,EAAQ,EAAW,EAAO,CAAM,EAChC,EAAiB,EAAM,eACvB,EAAQ,GAAQ,MAEZ,EAAO,KACb,CAEA,GAAI,CAAC,EAAO,CACV,IAAM,EAAgC,CACpC,eAAgB,EAAM,eACtB,UAAW,EAAM,UACjB,EAAG,EAAM,EACT,EAAG,EAAM,CACX,EAEA,GAAI,EAAiB,CACnB,IAAM,EAAK,EAAgB,sBAAsB,EAEjD,MAAO,CAAE,GAAG,EAAQ,EAAG,EAAO,EAAI,EAAG,EAAG,EAAG,EAAO,EAAI,EAAG,CAAE,CAC7D,CAEA,OAAO,CACT,CAEI,EAAM,UACR,EAAQ,EAAS,EAAW,CAAQ,EAC3B,EAAM,OAAS,OACxB,EAAQ,EAAM,OAGhB,EAAmB,EAAM,WAAa,EAAM,SAC9C,CAEA,MAAM,IAAI,EAAA,iBAAiB,iEAAiE,CAC9F"}
|
package/dist/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,sBAAsB,EACtB,qBAAqB,EAIrB,eAAe,EACf,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAKjB,oFAAoF;AACpF,wBAAgB,QAAQ,CAAC,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,CAKrG;AAyBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,WAAW,EACrB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,qBAAqB,CAAC,CAEhC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,WAAW,EACrB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,qBAAqB,CAAC,CAUhC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,WAAW,EACrB,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAe,EAAE,OAAO,EAAE,SAAoB,EAAE,GAAE,sBAA2B,GACzG,qBAAqB,CA8EvB"}
|
package/dist/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.js","names":[],"sources":["../src/core.ts"],"sourcesContent":["import type {\n ComputePositionOptions,\n ComputePositionResult,\n MiddlewareData,\n MiddlewareReset,\n MiddlewareResult,\n MiddlewareState,\n ReferenceElement,\n} from './types';\
|
|
1
|
+
{"version":3,"file":"core.js","names":[],"sources":["../src/core.ts"],"sourcesContent":["import { devOnly, warn } from './_dev';\nimport { OrbitConfigError } from './errors';\nimport type {\n ComputePositionOptions,\n ComputePositionResult,\n MiddlewareData,\n MiddlewareReset,\n MiddlewareResult,\n MiddlewareState,\n ReferenceElement,\n} from './types';\nimport { baseCoords, toRect } from './utils';\n\n// ── DOM helpers ────────────────────────────────────────────────────────────────────────────────\n\n/** Reads the bounding rects of the reference and floating elements from the DOM. */\nexport function getRects(reference: ReferenceElement, floating: HTMLElement): MiddlewareState['rects'] {\n return {\n floating: toRect(floating.getBoundingClientRect()),\n reference: toRect(reference.getBoundingClientRect()),\n };\n}\n\n// ── Internal state helpers ───────────────────────────────────────────────────────────\n\nfunction mergeState(state: MiddlewareState, result: MiddlewareResult | undefined): MiddlewareState {\n if (!result) return state;\n\n return {\n ...state,\n middlewareData: result.data\n ? (Object.assign(Object.create(null), state.middlewareData, result.data) as MiddlewareData)\n : state.middlewareData,\n placement: result.placement ?? state.placement,\n x: result.x ?? state.x,\n y: result.y ?? state.y,\n };\n}\n\n// ── Constants ─────────────────────────────────────────────────────────────────────────────────\n\n/** Maximum number of pipeline restarts allowed per `computePosition` call before throwing. */\nconst MAX_RESETS = 8;\n\n// ── Public API ────────────────────────────────────────────────────────────────────────────────\n\n/**\n * Deferred position computation. Runs `computePosition` in the next **microtask** and\n * returns a `Promise<ComputePositionResult>`.\n *\n * Useful for async component lifecycles (e.g. `await nextTick()` in Vue/React) where the\n * synchronous `computePosition` would read stale DOM measurements because layout has not been\n * committed yet. Note: this defers to the microtask queue, not the next animation frame — if you\n * need post-layout measurements use `requestAnimationFrame` instead.\n *\n * @example\n * ```ts\n * const result = await computePositionAsync(reference, floating, { placement: 'top' });\n * floating.style.left = `${result.x}px`;\n * floating.style.top = `${result.y}px`;\n * ```\n */\nexport function computePositionAsync(\n reference: ReferenceElement,\n floating: HTMLElement,\n options?: ComputePositionOptions,\n): Promise<ComputePositionResult> {\n return Promise.resolve().then(() => computePosition(reference, floating, options));\n}\n\n/**\n * Deferred position computation. Runs `computePosition` in the next **animation frame** and\n * returns a `Promise<ComputePositionResult>`.\n *\n * Useful when the layout has not yet committed (e.g. immediately after DOM insertion). Unlike\n * `computePositionAsync` which defers to the microtask queue, this waits for the next\n * `requestAnimationFrame` tick — guaranteeing post-layout DOM measurements.\n *\n * @example\n * ```ts\n * const result = await computePositionRaf(reference, floating, { placement: 'top' });\n * floating.style.left = `${result.x}px`;\n * floating.style.top = `${result.y}px`;\n * ```\n */\nexport function computePositionRaf(\n reference: ReferenceElement,\n floating: HTMLElement,\n options?: ComputePositionOptions,\n): Promise<ComputePositionResult> {\n return new Promise((resolve, reject) => {\n requestAnimationFrame(() => {\n try {\n resolve(computePosition(reference, floating, options));\n } catch (err) {\n reject(err);\n }\n });\n });\n}\n\n/**\n * Runs the middleware pipeline and returns the final position.\n *\n * Position is computed in viewport-relative coordinates assuming `position: fixed`.\n */\nexport function computePosition(\n reference: ReferenceElement,\n floating: HTMLElement,\n { boundary, containingBlock, middleware = [], padding, placement = 'bottom' }: ComputePositionOptions = {},\n): ComputePositionResult {\n const mws = middleware;\n\n if (reference === floating) {\n warn('computePosition: reference and floating are the same element.');\n }\n\n let currentPlacement = placement;\n let middlewareData: MiddlewareData = {};\n let rects = getRects(reference, floating);\n\n devOnly(() => {\n if (rects.floating.width === 0 && rects.floating.height === 0) {\n warn('computePosition: floating element has zero dimensions — is it hidden or detached from the DOM?');\n }\n\n const pos = getComputedStyle(floating).position;\n\n if (pos !== 'fixed' && pos !== 'absolute') {\n warn(\n `computePosition: floating element has \\`position: ${pos}\\`. ` +\n 'Orbit computes viewport-relative coordinates and expects position: fixed ' +\n '(or absolute for scoped stacking contexts).',\n );\n }\n });\n\n for (let resets = 0; resets < MAX_RESETS; resets += 1) {\n let state: MiddlewareState = {\n ...baseCoords(currentPlacement, rects.reference, rects.floating),\n boundary,\n elements: { floating, reference },\n initialPlacement: placement,\n middlewareData,\n padding,\n placement: currentPlacement,\n rects,\n };\n\n let reset: MiddlewareReset | undefined;\n\n for (const mw of mws) {\n const result = mw(state);\n\n state = mergeState(state, result);\n middlewareData = state.middlewareData;\n reset = result?.reset;\n\n if (reset) break;\n }\n\n if (!reset) {\n const result: ComputePositionResult = {\n middlewareData: state.middlewareData,\n placement: state.placement,\n x: state.x,\n y: state.y,\n };\n\n if (containingBlock) {\n const cb = containingBlock.getBoundingClientRect();\n\n return { ...result, x: result.x - cb.x, y: result.y - cb.y };\n }\n\n return result;\n }\n\n if (reset.remeasure) {\n rects = getRects(reference, floating);\n } else if (reset.rects != null) {\n rects = reset.rects;\n }\n\n currentPlacement = reset.placement ?? state.placement;\n }\n\n throw new OrbitConfigError('Middleware triggered too many resets in a single compute cycle.');\n}\n"],"mappings":"qHAgBA,SAAgB,EAAS,EAA6B,EAAiD,CACrG,MAAO,CACL,SAAU,EAAO,EAAS,sBAAsB,CAAC,EACjD,UAAW,EAAO,EAAU,sBAAsB,CAAC,CACrD,CACF,CAIA,SAAS,EAAW,EAAwB,EAAuD,CAGjG,OAFK,EAEE,CACL,GAAG,EACH,eAAgB,EAAO,KAClB,OAAO,OAAO,OAAO,OAAO,IAAI,EAAG,EAAM,eAAgB,EAAO,IAAI,EACrE,EAAM,eACV,UAAW,EAAO,WAAa,EAAM,UACrC,EAAG,EAAO,GAAK,EAAM,EACrB,EAAG,EAAO,GAAK,EAAM,CACvB,EAVoB,CAWtB,CAKA,IAAM,EAAa,EAoBnB,SAAgB,EACd,EACA,EACA,EACgC,CAChC,OAAO,QAAQ,QAAQ,CAAC,CAAC,SAAW,EAAgB,EAAW,EAAU,CAAO,CAAC,CACnF,CAiBA,SAAgB,EACd,EACA,EACA,EACgC,CAChC,OAAO,IAAI,SAAS,EAAS,IAAW,CACtC,0BAA4B,CAC1B,GAAI,CACF,EAAQ,EAAgB,EAAW,EAAU,CAAO,CAAC,CACvD,OAAS,EAAK,CACZ,EAAO,CAAG,CACZ,CACF,CAAC,CACH,CAAC,CACH,CAOA,SAAgB,EACd,EACA,EACA,CAAE,WAAU,kBAAiB,aAAa,CAAC,EAAG,UAAS,YAAY,UAAqC,CAAC,EAClF,CACvB,IAAM,EAAM,EAMR,EAAmB,EACnB,EAAiC,CAAC,EAClC,EAAQ,EAAS,EAAW,CAAQ,EAkBxC,IAAK,IAAI,EAAS,EAAG,EAAS,EAAY,GAAU,EAAG,CACrD,IAAI,EAAyB,CAC3B,GAAG,EAAW,EAAkB,EAAM,UAAW,EAAM,QAAQ,EAC/D,WACA,SAAU,CAAE,WAAU,WAAU,EAChC,iBAAkB,EAClB,iBACA,UACA,UAAW,EACX,OACF,EAEI,EAEJ,IAAK,IAAM,KAAM,EAAK,CACpB,IAAM,EAAS,EAAG,CAAK,EAMvB,GAJA,EAAQ,EAAW,EAAO,CAAM,EAChC,EAAiB,EAAM,eACvB,EAAQ,GAAQ,MAEZ,EAAO,KACb,CAEA,GAAI,CAAC,EAAO,CACV,IAAM,EAAgC,CACpC,eAAgB,EAAM,eACtB,UAAW,EAAM,UACjB,EAAG,EAAM,EACT,EAAG,EAAM,CACX,EAEA,GAAI,EAAiB,CACnB,IAAM,EAAK,EAAgB,sBAAsB,EAEjD,MAAO,CAAE,GAAG,EAAQ,EAAG,EAAO,EAAI,EAAG,EAAG,EAAG,EAAO,EAAI,EAAG,CAAE,CAC7D,CAEA,OAAO,CACT,CAEI,EAAM,UACR,EAAQ,EAAS,EAAW,CAAQ,EAC3B,EAAM,OAAS,OACxB,EAAQ,EAAM,OAGhB,EAAmB,EAAM,WAAa,EAAM,SAC9C,CAEA,MAAM,IAAI,EAAiB,iEAAiE,CAC9F"}
|
package/dist/devtools.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.cjs","names":[],"sources":["../src/devtools.ts"],"sourcesContent":["/**\n * @vielzeug/orbit — debug overlay for positioning visualisation.\n *\n * Import from the dedicated sub-path so it is tree-shaken from production bundles:\n * ```ts\n * import { debugPositioner } from '@vielzeug/orbit/devtools';\n * ```\n */\n\nimport type { Positioner, PositionerOptions } from './float';\nimport
|
|
1
|
+
{"version":3,"file":"devtools.cjs","names":[],"sources":["../src/devtools.ts"],"sourcesContent":["/**\n * @vielzeug/orbit — debug overlay for positioning visualisation.\n *\n * Import from the dedicated sub-path so it is tree-shaken from production bundles:\n * ```ts\n * import { debugPositioner } from '@vielzeug/orbit/devtools';\n * ```\n */\n\nimport type { Positioner, PositionerOptions } from './float';\nimport { createPositioner } from './float';\nimport type { ComputePositionResult, ReferenceElement } from './types';\n\n// ── Overlay helpers ───────────────────────────────────────────────────────────\n\nfunction setStyles(el: HTMLElement, styles: Record<string, string>): void {\n for (const [key, val] of Object.entries(styles)) {\n el.style.setProperty(key, val);\n }\n}\n\nfunction createOverlay(): HTMLElement {\n const el = document.createElement('div');\n\n el.dataset.orbitDebug = '';\n setStyles(el, {\n 'font-family': 'monospace',\n 'font-size': '11px',\n left: '0',\n 'pointer-events': 'none',\n position: 'fixed',\n top: '0',\n 'z-index': '2147483647',\n });\n\n return el;\n}\n\nfunction createPlacementBadge(text: string, x: number, y: number): HTMLElement {\n const el = document.createElement('div');\n\n el.textContent = text;\n setStyles(el, {\n background: 'rgba(0,100,255,0.85)',\n 'border-radius': '3px',\n color: '#fff',\n left: `${x}px`,\n padding: '1px 6px',\n position: 'fixed',\n top: `${Math.max(0, y)}px`,\n 'white-space': 'nowrap',\n });\n\n return el;\n}\n\nfunction createOutlineBox(x: number, y: number, width: number, height: number, color: string): HTMLElement {\n const el = document.createElement('div');\n\n setStyles(el, {\n border: `1.5px dashed ${color}`,\n height: `${height}px`,\n left: `${x}px`,\n position: 'fixed',\n top: `${y}px`,\n width: `${width}px`,\n });\n\n return el;\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Wraps `createPositioner()` and attaches a persistent visual debug overlay to the document.\n *\n * The overlay renders on every position update:\n * - **Blue dashed outline** — the viewport boundary used by overflow detection.\n * - **Orange dashed outline** — the reference element's bounding rect.\n * - **Blue label** — the active placement string (e.g. `\"top-start\"`).\n *\n * The overlay is automatically removed when `handle.dispose()` is called.\n *\n * Use only in development. Tree-shaken from production bundles via the sub-path import.\n *\n * @example\n * ```ts\n * import { debugPositioner } from '@vielzeug/orbit/devtools';\n *\n * const handle = debugPositioner(reference, tooltip, {\n * placement: 'top',\n * middleware: [offset(8), flip(), shift({ padding: 6 })],\n * });\n * // on teardown:\n * handle.dispose();\n * ```\n */\nexport function debugPositioner(\n reference: ReferenceElement,\n floating: HTMLElement,\n options: PositionerOptions = {},\n): Positioner {\n const overlay = createOverlay();\n\n document.body.appendChild(overlay);\n\n function renderOverlay(result: ComputePositionResult): void {\n overlay.innerHTML = '';\n\n // Viewport boundary.\n overlay.appendChild(createOutlineBox(1, 1, window.innerWidth - 2, window.innerHeight - 2, 'rgba(0,100,255,0.3)'));\n\n // Reference element.\n if (reference instanceof Element) {\n const r = reference.getBoundingClientRect();\n\n overlay.appendChild(createOutlineBox(r.left, r.top, r.width, r.height, 'rgba(255,120,0,0.7)'));\n }\n\n // Placement label — positioned just above the floating element.\n const fr = floating.getBoundingClientRect();\n\n overlay.appendChild(createPlacementBadge(result.placement, fr.left, fr.top - 22));\n }\n\n const userApply = options.apply;\n\n function wrappedApply(result: ComputePositionResult): void {\n if (userApply) {\n userApply(result);\n } else {\n floating.style.left = `${result.x}px`;\n floating.style.top = `${result.y}px`;\n }\n\n renderOverlay(result);\n }\n\n const positioner = createPositioner(reference, floating, { ...options, apply: wrappedApply });\n const dispose = positioner.dispose.bind(positioner);\n\n positioner.start();\n\n return Object.assign(positioner, {\n dispose(): void {\n dispose();\n overlay.remove();\n },\n });\n}\n"],"mappings":"kGAeA,SAAS,EAAU,EAAiB,EAAsC,CACxE,IAAK,GAAM,CAAC,EAAK,KAAQ,OAAO,QAAQ,CAAM,EAC5C,EAAG,MAAM,YAAY,EAAK,CAAG,CAEjC,CAEA,SAAS,GAA6B,CACpC,IAAM,EAAK,SAAS,cAAc,KAAK,EAavC,MAXA,GAAG,QAAQ,WAAa,GACxB,EAAU,EAAI,CACZ,cAAe,YACf,YAAa,OACb,KAAM,IACN,iBAAkB,OAClB,SAAU,QACV,IAAK,IACL,UAAW,YACb,CAAC,EAEM,CACT,CAEA,SAAS,EAAqB,EAAc,EAAW,EAAwB,CAC7E,IAAM,EAAK,SAAS,cAAc,KAAK,EAcvC,MAZA,GAAG,YAAc,EACjB,EAAU,EAAI,CACZ,WAAY,uBACZ,gBAAiB,MACjB,MAAO,OACP,KAAM,GAAG,EAAE,IACX,QAAS,UACT,SAAU,QACV,IAAK,GAAG,KAAK,IAAI,EAAG,CAAC,EAAE,IACvB,cAAe,QACjB,CAAC,EAEM,CACT,CAEA,SAAS,EAAiB,EAAW,EAAW,EAAe,EAAgB,EAA4B,CACzG,IAAM,EAAK,SAAS,cAAc,KAAK,EAWvC,OATA,EAAU,EAAI,CACZ,OAAQ,gBAAgB,IACxB,OAAQ,GAAG,EAAO,IAClB,KAAM,GAAG,EAAE,IACX,SAAU,QACV,IAAK,GAAG,EAAE,IACV,MAAO,GAAG,EAAM,GAClB,CAAC,EAEM,CACT,CA4BA,SAAgB,EACd,EACA,EACA,EAA6B,CAAC,EAClB,CACZ,IAAM,EAAU,EAAc,EAE9B,SAAS,KAAK,YAAY,CAAO,EAEjC,SAAS,EAAc,EAAqC,CAO1D,GANA,EAAQ,UAAY,GAGpB,EAAQ,YAAY,EAAiB,EAAG,EAAG,OAAO,WAAa,EAAG,OAAO,YAAc,EAAG,qBAAqB,CAAC,EAG5G,aAAqB,QAAS,CAChC,IAAM,EAAI,EAAU,sBAAsB,EAE1C,EAAQ,YAAY,EAAiB,EAAE,KAAM,EAAE,IAAK,EAAE,MAAO,EAAE,OAAQ,qBAAqB,CAAC,CAC/F,CAGA,IAAM,EAAK,EAAS,sBAAsB,EAE1C,EAAQ,YAAY,EAAqB,EAAO,UAAW,EAAG,KAAM,EAAG,IAAM,EAAE,CAAC,CAClF,CAEA,IAAM,EAAY,EAAQ,MAE1B,SAAS,EAAa,EAAqC,CACrD,EACF,EAAU,CAAM,GAEhB,EAAS,MAAM,KAAO,GAAG,EAAO,EAAE,IAClC,EAAS,MAAM,IAAM,GAAG,EAAO,EAAE,KAGnC,EAAc,CAAM,CACtB,CAEA,IAAM,EAAa,EAAA,iBAAiB,EAAW,EAAU,CAAE,GAAG,EAAS,MAAO,CAAa,CAAC,EACtF,EAAU,EAAW,QAAQ,KAAK,CAAU,EAIlD,OAFA,EAAW,MAAM,EAEV,OAAO,OAAO,EAAY,CAC/B,SAAgB,CACd,EAAQ,EACR,EAAQ,OAAO,CACjB,CACF,CAAC,CACH"}
|
package/dist/devtools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../src/devtools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../src/devtools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE7D,OAAO,KAAK,EAAyB,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA8DvE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,WAAW,EACrB,OAAO,GAAE,iBAAsB,GAC9B,UAAU,CAgDZ"}
|
package/dist/devtools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.js","names":[],"sources":["../src/devtools.ts"],"sourcesContent":["/**\n * @vielzeug/orbit — debug overlay for positioning visualisation.\n *\n * Import from the dedicated sub-path so it is tree-shaken from production bundles:\n * ```ts\n * import { debugPositioner } from '@vielzeug/orbit/devtools';\n * ```\n */\n\nimport type { Positioner, PositionerOptions } from './float';\nimport
|
|
1
|
+
{"version":3,"file":"devtools.js","names":[],"sources":["../src/devtools.ts"],"sourcesContent":["/**\n * @vielzeug/orbit — debug overlay for positioning visualisation.\n *\n * Import from the dedicated sub-path so it is tree-shaken from production bundles:\n * ```ts\n * import { debugPositioner } from '@vielzeug/orbit/devtools';\n * ```\n */\n\nimport type { Positioner, PositionerOptions } from './float';\nimport { createPositioner } from './float';\nimport type { ComputePositionResult, ReferenceElement } from './types';\n\n// ── Overlay helpers ───────────────────────────────────────────────────────────\n\nfunction setStyles(el: HTMLElement, styles: Record<string, string>): void {\n for (const [key, val] of Object.entries(styles)) {\n el.style.setProperty(key, val);\n }\n}\n\nfunction createOverlay(): HTMLElement {\n const el = document.createElement('div');\n\n el.dataset.orbitDebug = '';\n setStyles(el, {\n 'font-family': 'monospace',\n 'font-size': '11px',\n left: '0',\n 'pointer-events': 'none',\n position: 'fixed',\n top: '0',\n 'z-index': '2147483647',\n });\n\n return el;\n}\n\nfunction createPlacementBadge(text: string, x: number, y: number): HTMLElement {\n const el = document.createElement('div');\n\n el.textContent = text;\n setStyles(el, {\n background: 'rgba(0,100,255,0.85)',\n 'border-radius': '3px',\n color: '#fff',\n left: `${x}px`,\n padding: '1px 6px',\n position: 'fixed',\n top: `${Math.max(0, y)}px`,\n 'white-space': 'nowrap',\n });\n\n return el;\n}\n\nfunction createOutlineBox(x: number, y: number, width: number, height: number, color: string): HTMLElement {\n const el = document.createElement('div');\n\n setStyles(el, {\n border: `1.5px dashed ${color}`,\n height: `${height}px`,\n left: `${x}px`,\n position: 'fixed',\n top: `${y}px`,\n width: `${width}px`,\n });\n\n return el;\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Wraps `createPositioner()` and attaches a persistent visual debug overlay to the document.\n *\n * The overlay renders on every position update:\n * - **Blue dashed outline** — the viewport boundary used by overflow detection.\n * - **Orange dashed outline** — the reference element's bounding rect.\n * - **Blue label** — the active placement string (e.g. `\"top-start\"`).\n *\n * The overlay is automatically removed when `handle.dispose()` is called.\n *\n * Use only in development. Tree-shaken from production bundles via the sub-path import.\n *\n * @example\n * ```ts\n * import { debugPositioner } from '@vielzeug/orbit/devtools';\n *\n * const handle = debugPositioner(reference, tooltip, {\n * placement: 'top',\n * middleware: [offset(8), flip(), shift({ padding: 6 })],\n * });\n * // on teardown:\n * handle.dispose();\n * ```\n */\nexport function debugPositioner(\n reference: ReferenceElement,\n floating: HTMLElement,\n options: PositionerOptions = {},\n): Positioner {\n const overlay = createOverlay();\n\n document.body.appendChild(overlay);\n\n function renderOverlay(result: ComputePositionResult): void {\n overlay.innerHTML = '';\n\n // Viewport boundary.\n overlay.appendChild(createOutlineBox(1, 1, window.innerWidth - 2, window.innerHeight - 2, 'rgba(0,100,255,0.3)'));\n\n // Reference element.\n if (reference instanceof Element) {\n const r = reference.getBoundingClientRect();\n\n overlay.appendChild(createOutlineBox(r.left, r.top, r.width, r.height, 'rgba(255,120,0,0.7)'));\n }\n\n // Placement label — positioned just above the floating element.\n const fr = floating.getBoundingClientRect();\n\n overlay.appendChild(createPlacementBadge(result.placement, fr.left, fr.top - 22));\n }\n\n const userApply = options.apply;\n\n function wrappedApply(result: ComputePositionResult): void {\n if (userApply) {\n userApply(result);\n } else {\n floating.style.left = `${result.x}px`;\n floating.style.top = `${result.y}px`;\n }\n\n renderOverlay(result);\n }\n\n const positioner = createPositioner(reference, floating, { ...options, apply: wrappedApply });\n const dispose = positioner.dispose.bind(positioner);\n\n positioner.start();\n\n return Object.assign(positioner, {\n dispose(): void {\n dispose();\n overlay.remove();\n },\n });\n}\n"],"mappings":"8CAeA,SAAS,EAAU,EAAiB,EAAsC,CACxE,IAAK,GAAM,CAAC,EAAK,KAAQ,OAAO,QAAQ,CAAM,EAC5C,EAAG,MAAM,YAAY,EAAK,CAAG,CAEjC,CAEA,SAAS,GAA6B,CACpC,IAAM,EAAK,SAAS,cAAc,KAAK,EAavC,MAXA,GAAG,QAAQ,WAAa,GACxB,EAAU,EAAI,CACZ,cAAe,YACf,YAAa,OACb,KAAM,IACN,iBAAkB,OAClB,SAAU,QACV,IAAK,IACL,UAAW,YACb,CAAC,EAEM,CACT,CAEA,SAAS,EAAqB,EAAc,EAAW,EAAwB,CAC7E,IAAM,EAAK,SAAS,cAAc,KAAK,EAcvC,MAZA,GAAG,YAAc,EACjB,EAAU,EAAI,CACZ,WAAY,uBACZ,gBAAiB,MACjB,MAAO,OACP,KAAM,GAAG,EAAE,IACX,QAAS,UACT,SAAU,QACV,IAAK,GAAG,KAAK,IAAI,EAAG,CAAC,EAAE,IACvB,cAAe,QACjB,CAAC,EAEM,CACT,CAEA,SAAS,EAAiB,EAAW,EAAW,EAAe,EAAgB,EAA4B,CACzG,IAAM,EAAK,SAAS,cAAc,KAAK,EAWvC,OATA,EAAU,EAAI,CACZ,OAAQ,gBAAgB,IACxB,OAAQ,GAAG,EAAO,IAClB,KAAM,GAAG,EAAE,IACX,SAAU,QACV,IAAK,GAAG,EAAE,IACV,MAAO,GAAG,EAAM,GAClB,CAAC,EAEM,CACT,CA4BA,SAAgB,EACd,EACA,EACA,EAA6B,CAAC,EAClB,CACZ,IAAM,EAAU,EAAc,EAE9B,SAAS,KAAK,YAAY,CAAO,EAEjC,SAAS,EAAc,EAAqC,CAO1D,GANA,EAAQ,UAAY,GAGpB,EAAQ,YAAY,EAAiB,EAAG,EAAG,OAAO,WAAa,EAAG,OAAO,YAAc,EAAG,qBAAqB,CAAC,EAG5G,aAAqB,QAAS,CAChC,IAAM,EAAI,EAAU,sBAAsB,EAE1C,EAAQ,YAAY,EAAiB,EAAE,KAAM,EAAE,IAAK,EAAE,MAAO,EAAE,OAAQ,qBAAqB,CAAC,CAC/F,CAGA,IAAM,EAAK,EAAS,sBAAsB,EAE1C,EAAQ,YAAY,EAAqB,EAAO,UAAW,EAAG,KAAM,EAAG,IAAM,EAAE,CAAC,CAClF,CAEA,IAAM,EAAY,EAAQ,MAE1B,SAAS,EAAa,EAAqC,CACrD,EACF,EAAU,CAAM,GAEhB,EAAS,MAAM,KAAO,GAAG,EAAO,EAAE,IAClC,EAAS,MAAM,IAAM,GAAG,EAAO,EAAE,KAGnC,EAAc,CAAM,CACtB,CAEA,IAAM,EAAa,EAAiB,EAAW,EAAU,CAAE,GAAG,EAAS,MAAO,CAAa,CAAC,EACtF,EAAU,EAAW,QAAQ,KAAK,CAAU,EAIlD,OAFA,EAAW,MAAM,EAEV,OAAO,OAAO,EAAY,CAC/B,SAAgB,CACd,EAAQ,EACR,EAAQ,OAAO,CACjB,CACF,CAAC,CACH"}
|
package/dist/float.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"float.cjs","names":[],"sources":["../src/float.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"float.cjs","names":[],"sources":["../src/float.ts"],"sourcesContent":["import { type AutoUpdateOptions, autoUpdate } from './auto-update';\nimport { getContainingBlock } from './containing-block';\nimport { computePosition } from './core';\nimport { getClippingAncestorRect } from './overflow';\nimport type { ComputePositionOptions, ComputePositionResult, ReferenceElement } from './types';\n\nexport type PositionStrategy = 'absolute' | 'fixed';\n\nexport interface PositionerOptions extends Omit<ComputePositionOptions, 'boundary' | 'containingBlock'> {\n apply?: (result: ComputePositionResult) => void;\n autoUpdate?: AutoUpdateOptions | false;\n boundary?: ComputePositionOptions['boundary'] | 'clippingAncestors';\n strategy?: PositionStrategy;\n}\n\nexport interface Positioner {\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n getPosition(): ComputePositionResult | null;\n start(): void;\n update(): void;\n [Symbol.dispose](): void;\n}\n\nfunction makePositioner(\n rawDispose: () => void,\n getPosition: () => ComputePositionResult | null,\n start: () => void,\n update: () => void,\n): Positioner {\n const controller = new AbortController();\n let disposed = false;\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n dispose() {\n if (disposed) return;\n\n disposed = true;\n controller.abort();\n rawDispose();\n },\n get disposed() {\n return disposed;\n },\n getPosition,\n start(): void {\n if (!disposed) start();\n },\n [Symbol.dispose](): void {\n this.dispose();\n },\n update(): void {\n if (!disposed) update();\n },\n };\n}\n\nfunction resolveContainingBlock(floating: HTMLElement, strategy: PositionStrategy): Element | null {\n if (strategy === 'absolute') return floating.offsetParent instanceof Element ? floating.offsetParent : null;\n\n return getContainingBlock(floating);\n}\n\nfunction applyDefault(result: ComputePositionResult, floating: HTMLElement, strategy: PositionStrategy): void {\n floating.style.position = strategy;\n floating.style.left = `${result.x}px`;\n floating.style.top = `${result.y}px`;\n}\n\n/**\n * Creates a lifecycle-owned floating positioner.\n *\n * The positioner owns coordinate strategy, clipping-boundary resolution, updates, and cleanup.\n * Call `start()` once the elements are mounted, then call `dispose()` when their owner ends.\n */\nexport function createPositioner(\n reference: ReferenceElement,\n floating: HTMLElement,\n {\n apply,\n autoUpdate: autoUpdateOptions = {},\n boundary: boundaryOption = 'clippingAncestors',\n middleware,\n padding,\n placement = 'bottom',\n strategy = 'fixed',\n }: PositionerOptions = {},\n): Positioner {\n let active = true;\n let cleanup: (() => void) | undefined;\n let lastPosition: ComputePositionResult | null = null;\n let started = false;\n\n function update(): void {\n if (!active) return;\n\n const containingBlock = resolveContainingBlock(floating, strategy);\n const boundary = boundaryOption === 'clippingAncestors' ? getClippingAncestorRect(floating) : boundaryOption;\n const result = computePosition(reference, floating, { boundary, containingBlock, middleware, padding, placement });\n\n lastPosition = result;\n (apply ?? ((position) => applyDefault(position, floating, strategy)))(result);\n }\n\n function start(): void {\n if (started) return;\n\n started = true;\n\n if (autoUpdateOptions === false) update();\n else cleanup = autoUpdate(reference, floating, update, autoUpdateOptions);\n }\n\n return makePositioner(\n () => {\n active = false;\n cleanup?.();\n },\n () => lastPosition,\n start,\n update,\n );\n}\n"],"mappings":"6HAyBA,SAAS,EACP,EACA,EACA,EACA,EACY,CACZ,IAAM,EAAa,IAAI,gBACnB,EAAW,GAEf,MAAO,CACL,IAAI,gBAAiB,CACnB,OAAO,EAAW,MACpB,EACA,SAAU,CACJ,IAEJ,EAAW,GACX,EAAW,MAAM,EACjB,EAAW,EACb,EACA,IAAI,UAAW,CACb,OAAO,CACT,EACA,cACA,OAAc,CACP,GAAU,EAAM,CACvB,EACA,CAAC,OAAO,UAAiB,CACvB,KAAK,QAAQ,CACf,EACA,QAAe,CACR,GAAU,EAAO,CACxB,CACF,CACF,CAEA,SAAS,EAAuB,EAAuB,EAA4C,CAGjG,OAFI,IAAa,WAAmB,EAAS,wBAAwB,QAAU,EAAS,aAAe,KAEhG,EAAA,mBAAmB,CAAQ,CACpC,CAEA,SAAS,EAAa,EAA+B,EAAuB,EAAkC,CAC5G,EAAS,MAAM,SAAW,EAC1B,EAAS,MAAM,KAAO,GAAG,EAAO,EAAE,IAClC,EAAS,MAAM,IAAM,GAAG,EAAO,EAAE,GACnC,CAQA,SAAgB,EACd,EACA,EACA,CACE,QACA,WAAY,EAAoB,CAAC,EACjC,SAAU,EAAiB,oBAC3B,aACA,UACA,YAAY,SACZ,WAAW,SACU,CAAC,EACZ,CACZ,IAAI,EAAS,GACT,EACA,EAA6C,KAC7C,EAAU,GAEd,SAAS,GAAe,CACtB,GAAI,CAAC,EAAQ,OAEb,IAAM,EAAkB,EAAuB,EAAU,CAAQ,EAC3D,EAAW,IAAmB,oBAAsB,EAAA,wBAAwB,CAAQ,EAAI,EACxF,EAAS,EAAA,gBAAgB,EAAW,EAAU,CAAE,WAAU,kBAAiB,aAAY,UAAS,WAAU,CAAC,EAEjH,EAAe,GACd,IAAW,GAAa,EAAa,EAAU,EAAU,CAAQ,GAAA,CAAI,CAAM,CAC9E,CAEA,SAAS,GAAc,CACjB,IAEJ,EAAU,GAEN,IAAsB,GAAO,EAAO,EACnC,EAAU,EAAA,WAAW,EAAW,EAAU,EAAQ,CAAiB,EAC1E,CAEA,OAAO,MACC,CACJ,EAAS,GACT,IAAU,CACZ,MACM,EACN,EACA,CACF,CACF"}
|
package/dist/float.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ComputePositionOptions, ComputePositionResult, ReferenceElement } from './types';
|
|
2
1
|
import { type AutoUpdateOptions } from './auto-update';
|
|
2
|
+
import type { ComputePositionOptions, ComputePositionResult, ReferenceElement } from './types';
|
|
3
3
|
export type PositionStrategy = 'absolute' | 'fixed';
|
|
4
4
|
export interface PositionerOptions extends Omit<ComputePositionOptions, 'boundary' | 'containingBlock'> {
|
|
5
5
|
apply?: (result: ComputePositionResult) => void;
|
package/dist/float.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"float.d.ts","sourceRoot":"","sources":["../src/float.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE/F,
|
|
1
|
+
{"version":3,"file":"float.d.ts","sourceRoot":"","sources":["../src/float.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAc,MAAM,eAAe,CAAC;AAInE,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE/F,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,OAAO,CAAC;AAEpD,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,sBAAsB,EAAE,UAAU,GAAG,iBAAiB,CAAC;IACrG,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAChD,UAAU,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAC;IACvC,QAAQ,CAAC,EAAE,sBAAsB,CAAC,UAAU,CAAC,GAAG,mBAAmB,CAAC;IACpE,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC;IACrC,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,WAAW,IAAI,qBAAqB,GAAG,IAAI,CAAC;IAC5C,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;IACf,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;CAC1B;AAkDD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,WAAW,EACrB,EACE,KAAK,EACL,UAAU,EAAE,iBAAsB,EAClC,QAAQ,EAAE,cAAoC,EAC9C,UAAU,EACV,OAAO,EACP,SAAoB,EACpB,QAAkB,GACnB,GAAE,iBAAsB,GACxB,UAAU,CAmCZ"}
|
package/dist/float.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"float.js","names":[],"sources":["../src/float.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"float.js","names":[],"sources":["../src/float.ts"],"sourcesContent":["import { type AutoUpdateOptions, autoUpdate } from './auto-update';\nimport { getContainingBlock } from './containing-block';\nimport { computePosition } from './core';\nimport { getClippingAncestorRect } from './overflow';\nimport type { ComputePositionOptions, ComputePositionResult, ReferenceElement } from './types';\n\nexport type PositionStrategy = 'absolute' | 'fixed';\n\nexport interface PositionerOptions extends Omit<ComputePositionOptions, 'boundary' | 'containingBlock'> {\n apply?: (result: ComputePositionResult) => void;\n autoUpdate?: AutoUpdateOptions | false;\n boundary?: ComputePositionOptions['boundary'] | 'clippingAncestors';\n strategy?: PositionStrategy;\n}\n\nexport interface Positioner {\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n getPosition(): ComputePositionResult | null;\n start(): void;\n update(): void;\n [Symbol.dispose](): void;\n}\n\nfunction makePositioner(\n rawDispose: () => void,\n getPosition: () => ComputePositionResult | null,\n start: () => void,\n update: () => void,\n): Positioner {\n const controller = new AbortController();\n let disposed = false;\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n dispose() {\n if (disposed) return;\n\n disposed = true;\n controller.abort();\n rawDispose();\n },\n get disposed() {\n return disposed;\n },\n getPosition,\n start(): void {\n if (!disposed) start();\n },\n [Symbol.dispose](): void {\n this.dispose();\n },\n update(): void {\n if (!disposed) update();\n },\n };\n}\n\nfunction resolveContainingBlock(floating: HTMLElement, strategy: PositionStrategy): Element | null {\n if (strategy === 'absolute') return floating.offsetParent instanceof Element ? floating.offsetParent : null;\n\n return getContainingBlock(floating);\n}\n\nfunction applyDefault(result: ComputePositionResult, floating: HTMLElement, strategy: PositionStrategy): void {\n floating.style.position = strategy;\n floating.style.left = `${result.x}px`;\n floating.style.top = `${result.y}px`;\n}\n\n/**\n * Creates a lifecycle-owned floating positioner.\n *\n * The positioner owns coordinate strategy, clipping-boundary resolution, updates, and cleanup.\n * Call `start()` once the elements are mounted, then call `dispose()` when their owner ends.\n */\nexport function createPositioner(\n reference: ReferenceElement,\n floating: HTMLElement,\n {\n apply,\n autoUpdate: autoUpdateOptions = {},\n boundary: boundaryOption = 'clippingAncestors',\n middleware,\n padding,\n placement = 'bottom',\n strategy = 'fixed',\n }: PositionerOptions = {},\n): Positioner {\n let active = true;\n let cleanup: (() => void) | undefined;\n let lastPosition: ComputePositionResult | null = null;\n let started = false;\n\n function update(): void {\n if (!active) return;\n\n const containingBlock = resolveContainingBlock(floating, strategy);\n const boundary = boundaryOption === 'clippingAncestors' ? getClippingAncestorRect(floating) : boundaryOption;\n const result = computePosition(reference, floating, { boundary, containingBlock, middleware, padding, placement });\n\n lastPosition = result;\n (apply ?? ((position) => applyDefault(position, floating, strategy)))(result);\n }\n\n function start(): void {\n if (started) return;\n\n started = true;\n\n if (autoUpdateOptions === false) update();\n else cleanup = autoUpdate(reference, floating, update, autoUpdateOptions);\n }\n\n return makePositioner(\n () => {\n active = false;\n cleanup?.();\n },\n () => lastPosition,\n start,\n update,\n );\n}\n"],"mappings":"6MAyBA,SAAS,EACP,EACA,EACA,EACA,EACY,CACZ,IAAM,EAAa,IAAI,gBACnB,EAAW,GAEf,MAAO,CACL,IAAI,gBAAiB,CACnB,OAAO,EAAW,MACpB,EACA,SAAU,CACJ,IAEJ,EAAW,GACX,EAAW,MAAM,EACjB,EAAW,EACb,EACA,IAAI,UAAW,CACb,OAAO,CACT,EACA,cACA,OAAc,CACP,GAAU,EAAM,CACvB,EACA,CAAC,OAAO,UAAiB,CACvB,KAAK,QAAQ,CACf,EACA,QAAe,CACR,GAAU,EAAO,CACxB,CACF,CACF,CAEA,SAAS,EAAuB,EAAuB,EAA4C,CAGjG,OAFI,IAAa,WAAmB,EAAS,wBAAwB,QAAU,EAAS,aAAe,KAEhG,EAAmB,CAAQ,CACpC,CAEA,SAAS,EAAa,EAA+B,EAAuB,EAAkC,CAC5G,EAAS,MAAM,SAAW,EAC1B,EAAS,MAAM,KAAO,GAAG,EAAO,EAAE,IAClC,EAAS,MAAM,IAAM,GAAG,EAAO,EAAE,GACnC,CAQA,SAAgB,EACd,EACA,EACA,CACE,QACA,WAAY,EAAoB,CAAC,EACjC,SAAU,EAAiB,oBAC3B,aACA,UACA,YAAY,SACZ,WAAW,SACU,CAAC,EACZ,CACZ,IAAI,EAAS,GACT,EACA,EAA6C,KAC7C,EAAU,GAEd,SAAS,GAAe,CACtB,GAAI,CAAC,EAAQ,OAEb,IAAM,EAAkB,EAAuB,EAAU,CAAQ,EAC3D,EAAW,IAAmB,oBAAsB,EAAwB,CAAQ,EAAI,EACxF,EAAS,EAAgB,EAAW,EAAU,CAAE,WAAU,kBAAiB,aAAY,UAAS,WAAU,CAAC,EAEjH,EAAe,GACd,IAAW,GAAa,EAAa,EAAU,EAAU,CAAQ,GAAA,CAAI,CAAM,CAC9E,CAEA,SAAS,GAAc,CACjB,IAEJ,EAAU,GAEN,IAAsB,GAAO,EAAO,EACnC,EAAU,EAAW,EAAW,EAAU,EAAQ,CAAiB,EAC1E,CAEA,OAAO,MACC,CACJ,EAAS,GACT,IAAU,CACZ,MACM,EACN,EACA,CACF,CACF"}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./utils.cjs"),t=require("./auto-update.cjs"),n=require("./errors.cjs"),r=require("./core.cjs"),i=require("./overflow.cjs"),a=require("./float.cjs"),o=require("./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./utils.cjs"),t=require("./auto-update.cjs"),n=require("./errors.cjs"),r=require("./core.cjs"),i=require("./overflow.cjs"),a=require("./float.cjs"),o=require("./inline.cjs"),s=require("./middleware/arrow.cjs"),c=require("./middleware/auto-placement.cjs"),l=require("./middleware/flip.cjs"),u=require("./middleware/hide.cjs"),d=require("./middleware/offset.cjs"),f=require("./middleware/shift.cjs"),p=require("./middleware/size.cjs");exports.OrbitConfigError=n.OrbitConfigError,exports.OrbitError=n.OrbitError,exports.arrow=s.arrow,exports.autoPlacement=c.autoPlacement,exports.autoUpdate=t.autoUpdate,exports.computePosition=r.computePosition,exports.computePositionAsync=r.computePositionAsync,exports.computePositionRaf=r.computePositionRaf,exports.createPositioner=a.createPositioner,exports.detectOverflow=i.detectOverflow,exports.flip=l.flip,exports.getAlignment=e.getAlignment,exports.getClippingAncestorRect=i.getClippingAncestorRect,exports.getRects=r.getRects,exports.getSide=e.getSide,exports.hide=u.hide,exports.inline=o.inline,exports.limitShift=f.limitShift,exports.offset=d.offset,exports.shift=f.shift,exports.size=p.size;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export type { AutoUpdateOptions } from './auto-update';
|
|
2
|
+
export { autoUpdate } from './auto-update';
|
|
2
3
|
export { computePosition, computePositionAsync, computePositionRaf, getRects } from './core';
|
|
3
|
-
export {
|
|
4
|
-
export { createPositioner } from './float';
|
|
4
|
+
export { OrbitConfigError, OrbitError } from './errors';
|
|
5
5
|
export type { Positioner, PositionerOptions, PositionStrategy } from './float';
|
|
6
|
-
export {
|
|
7
|
-
export type {
|
|
8
|
-
export {
|
|
6
|
+
export { createPositioner } from './float';
|
|
7
|
+
export type { InlineOptions } from './inline';
|
|
8
|
+
export { inline } from './inline';
|
|
9
9
|
export type { ArrowOptions } from './middleware/arrow';
|
|
10
|
-
export {
|
|
10
|
+
export { arrow } from './middleware/arrow';
|
|
11
11
|
export type { AutoPlacementOptions } from './middleware/auto-placement';
|
|
12
|
-
export {
|
|
12
|
+
export { autoPlacement } from './middleware/auto-placement';
|
|
13
13
|
export type { FlipOptions } from './middleware/flip';
|
|
14
|
-
export {
|
|
14
|
+
export { flip } from './middleware/flip';
|
|
15
15
|
export type { HideOptions } from './middleware/hide';
|
|
16
|
-
export {
|
|
17
|
-
export type { InlineOptions } from './inline';
|
|
18
|
-
export { offset } from './middleware/offset';
|
|
16
|
+
export { hide } from './middleware/hide';
|
|
19
17
|
export type { OffsetConfig, OffsetValue } from './middleware/offset';
|
|
20
|
-
export {
|
|
18
|
+
export { offset } from './middleware/offset';
|
|
21
19
|
export type { LimitShiftOptions, ShiftLimiter, ShiftOptions } from './middleware/shift';
|
|
22
|
-
export {
|
|
20
|
+
export { limitShift, shift } from './middleware/shift';
|
|
23
21
|
export type { SizeOptions } from './middleware/size';
|
|
22
|
+
export { size } from './middleware/size';
|
|
23
|
+
export { detectOverflow, getClippingAncestorRect } from './overflow';
|
|
24
24
|
export type { PositioningPreset, PresetOptions } from './presets';
|
|
25
|
-
export { getAlignment, getSide } from './utils';
|
|
26
25
|
export type { Alignment, ArrowData, ComputePositionOptions, ComputePositionResult, DetectOverflowOptions, FlipData, HideData, Middleware, MiddlewareData, MiddlewareReset, MiddlewareResult, MiddlewareState, Padding, Placement, Rect, ReferenceElement, ShiftData, Side, SideObject, SizeData, VirtualReference, } from './types';
|
|
26
|
+
export { getAlignment, getSide } from './utils';
|
|
27
27
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,YAAY,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAErE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAExF,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACvD,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAGrE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAElE,YAAY,EACV,SAAS,EACT,SAAS,EACT,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,OAAO,EACP,SAAS,EACT,IAAI,EACJ,gBAAgB,EAChB,SAAS,EACT,IAAI,EACJ,UAAU,EACV,QAAQ,EACR,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getAlignment as e,getSide as t}from"./utils.js";import{autoUpdate as n}from"./auto-update.js";import{OrbitConfigError as r,OrbitError as i}from"./errors.js";import{computePosition as a,computePositionAsync as o,computePositionRaf as s,getRects as c}from"./core.js";import{detectOverflow as l,getClippingAncestorRect as u}from"./overflow.js";import{createPositioner as d}from"./float.js";import{
|
|
1
|
+
import{getAlignment as e,getSide as t}from"./utils.js";import{autoUpdate as n}from"./auto-update.js";import{OrbitConfigError as r,OrbitError as i}from"./errors.js";import{computePosition as a,computePositionAsync as o,computePositionRaf as s,getRects as c}from"./core.js";import{detectOverflow as l,getClippingAncestorRect as u}from"./overflow.js";import{createPositioner as d}from"./float.js";import{inline as f}from"./inline.js";import{arrow as p}from"./middleware/arrow.js";import{autoPlacement as m}from"./middleware/auto-placement.js";import{flip as h}from"./middleware/flip.js";import{hide as g}from"./middleware/hide.js";import{offset as _}from"./middleware/offset.js";import{limitShift as v,shift as y}from"./middleware/shift.js";import{size as b}from"./middleware/size.js";export{r as OrbitConfigError,i as OrbitError,p as arrow,m as autoPlacement,n as autoUpdate,a as computePosition,o as computePositionAsync,s as computePositionRaf,d as createPositioner,l as detectOverflow,h as flip,e as getAlignment,u as getClippingAncestorRect,c as getRects,t as getSide,g as hide,f as inline,v as limitShift,_ as offset,y as shift,b as size};
|
package/dist/inline.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inline.cjs","names":[],"sources":["../src/inline.ts"],"sourcesContent":["import type { Middleware, Padding, Rect, ReferenceElement } from './types';\n\nimport { getSide, toRect, toSideObject } from './utils';\n\n// ── Private helpers (only used by inline) ────────────────────────────────────────────\n\nfunction getClientRects(reference: ReferenceElement): Rect[] {\n if (!('getClientRects' in reference) || typeof reference.getClientRects !== 'function') return [];\n\n return Array.from((reference.getClientRects as () => DOMRectList | DOMRect[])())\n .map(toRect)\n .filter((r) => r.width > 0 || r.height > 0);\n}\n\nfunction rectContainsPoint(rect: Rect, x: number, y: number, padding: ReturnType<typeof toSideObject>): boolean {\n return (\n x >= rect.x - padding.left &&\n x <= rect.x + rect.width + padding.right &&\n y >= rect.y - padding.top &&\n y <= rect.y + rect.height + padding.bottom\n );\n}\n\nfunction sameRect(a: Rect, b: Rect): boolean {\n return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;\n}\n\n// ── Inline middleware ─────────────────────────────────────────────────────────────────\n\nexport interface InlineOptions {\n /**\n *
|
|
1
|
+
{"version":3,"file":"inline.cjs","names":[],"sources":["../src/inline.ts"],"sourcesContent":["import type { Middleware, Padding, Rect, ReferenceElement } from './types';\n\nimport { getSide, toRect, toSideObject } from './utils';\n\n// ── Private helpers (only used by inline) ────────────────────────────────────────────\n\nfunction getClientRects(reference: ReferenceElement): Rect[] {\n if (!('getClientRects' in reference) || typeof reference.getClientRects !== 'function') return [];\n\n return Array.from((reference.getClientRects as () => DOMRectList | DOMRect[])())\n .map(toRect)\n .filter((r) => r.width > 0 || r.height > 0);\n}\n\nfunction rectContainsPoint(rect: Rect, x: number, y: number, padding: ReturnType<typeof toSideObject>): boolean {\n return (\n x >= rect.x - padding.left &&\n x <= rect.x + rect.width + padding.right &&\n y >= rect.y - padding.top &&\n y <= rect.y + rect.height + padding.bottom\n );\n}\n\nfunction sameRect(a: Rect, b: Rect): boolean {\n return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;\n}\n\n// ── Inline middleware ─────────────────────────────────────────────────────────────────\n\nexport interface InlineOptions {\n /**\n * Padding used when hit-testing cursor coordinates against client rects.\n * Prevents snapping when the cursor is just outside a rect edge. Default: `2`.\n *\n * @remarks Only applies when both `x` and `y` are provided.\n */\n padding?: Padding;\n /**\n * Cursor x-coordinate. When provided alongside `y`, the middleware picks the\n * client rect that contains the cursor instead of the closest rect to the floating element.\n */\n x?: number;\n /** Cursor y-coordinate. */\n y?: number;\n}\n\n/**\n * Improves positioning accuracy for inline references that span multiple lines\n * (e.g. `<span>` wrapping across line breaks).\n *\n * Must be placed **before** `flip()` and other middleware in the pipeline.\n *\n * @example Tooltip on selected text:\n * ```ts\n * import { createPositioner, inline, flip, shift } from '@vielzeug/orbit';\n *\n * const positioner = createPositioner(selectionRef, tooltip, {\n * placement: 'top',\n * middleware: [inline({ x: cursorX, y: cursorY }), flip(), shift({ padding: 6 })],\n * });\n * positioner.start();\n * ```\n */\nexport function inline(options: InlineOptions = {}): Middleware {\n function inlineMiddleware(state: Parameters<Middleware>[0]): ReturnType<Middleware> {\n const rects = getClientRects(state.elements.reference);\n\n if (rects.length <= 1) return;\n\n const padding = toSideObject(options.padding ?? 2);\n const side = getSide(state.placement);\n let nextRect = rects[0]!;\n\n if (options.x != null && options.y != null) {\n nextRect = rects.find((rect) => rectContainsPoint(rect, options.x!, options.y!, padding)) ?? nextRect;\n } else if (side === 'top' || side === 'bottom') {\n const targetX = state.x + state.rects.floating.width / 2;\n\n nextRect = rects.reduce((best, rect) => {\n const bestDist = Math.abs(best.x + best.width / 2 - targetX);\n const rectDist = Math.abs(rect.x + rect.width / 2 - targetX);\n\n return rectDist < bestDist ? rect : best;\n }, nextRect);\n } else {\n const targetY = state.y + state.rects.floating.height / 2;\n\n nextRect = rects.reduce((best, rect) => {\n const bestDist = Math.abs(best.y + best.height / 2 - targetY);\n const rectDist = Math.abs(rect.y + rect.height / 2 - targetY);\n\n return rectDist < bestDist ? rect : best;\n }, nextRect);\n }\n\n if (sameRect(nextRect, state.rects.reference)) return;\n\n return { reset: { rects: { ...state.rects, reference: nextRect } } };\n }\n\n return inlineMiddleware;\n}\n"],"mappings":"kGAMA,SAAS,EAAe,EAAqC,CAG3D,MAFI,EAAE,mBAAoB,IAAc,OAAO,EAAU,gBAAmB,WAAmB,CAAC,EAEzF,MAAM,KAAM,EAAU,eAAiD,CAAC,CAAC,CAC7E,IAAI,EAAA,MAAM,CAAC,CACX,OAAQ,GAAM,EAAE,MAAQ,GAAK,EAAE,OAAS,CAAC,CAC9C,CAEA,SAAS,EAAkB,EAAY,EAAW,EAAW,EAAmD,CAC9G,OACE,GAAK,EAAK,EAAI,EAAQ,MACtB,GAAK,EAAK,EAAI,EAAK,MAAQ,EAAQ,OACnC,GAAK,EAAK,EAAI,EAAQ,KACtB,GAAK,EAAK,EAAI,EAAK,OAAS,EAAQ,MAExC,CAEA,SAAS,EAAS,EAAS,EAAkB,CAC3C,OAAO,EAAE,IAAM,EAAE,GAAK,EAAE,IAAM,EAAE,GAAK,EAAE,QAAU,EAAE,OAAS,EAAE,SAAW,EAAE,MAC7E,CAsCA,SAAgB,EAAO,EAAyB,CAAC,EAAe,CAC9D,SAAS,EAAiB,EAA0D,CAClF,IAAM,EAAQ,EAAe,EAAM,SAAS,SAAS,EAErD,GAAI,EAAM,QAAU,EAAG,OAEvB,IAAM,EAAU,EAAA,aAAa,EAAQ,SAAW,CAAC,EAC3C,EAAO,EAAA,QAAQ,EAAM,SAAS,EAChC,EAAW,EAAM,GAErB,GAAI,EAAQ,GAAK,MAAQ,EAAQ,GAAK,KACpC,EAAW,EAAM,KAAM,GAAS,EAAkB,EAAM,EAAQ,EAAI,EAAQ,EAAI,CAAO,CAAC,GAAK,OACxF,GAAI,IAAS,OAAS,IAAS,SAAU,CAC9C,IAAM,EAAU,EAAM,EAAI,EAAM,MAAM,SAAS,MAAQ,EAEvD,EAAW,EAAM,QAAQ,EAAM,IAAS,CACtC,IAAM,EAAW,KAAK,IAAI,EAAK,EAAI,EAAK,MAAQ,EAAI,CAAO,EAG3D,OAFiB,KAAK,IAAI,EAAK,EAAI,EAAK,MAAQ,EAAI,CAE7C,EAAW,EAAW,EAAO,CACtC,EAAG,CAAQ,CACb,KAAO,CACL,IAAM,EAAU,EAAM,EAAI,EAAM,MAAM,SAAS,OAAS,EAExD,EAAW,EAAM,QAAQ,EAAM,IAAS,CACtC,IAAM,EAAW,KAAK,IAAI,EAAK,EAAI,EAAK,OAAS,EAAI,CAAO,EAG5D,OAFiB,KAAK,IAAI,EAAK,EAAI,EAAK,OAAS,EAAI,CAE9C,EAAW,EAAW,EAAO,CACtC,EAAG,CAAQ,CACb,CAEI,MAAS,EAAU,EAAM,MAAM,SAAS,EAE5C,MAAO,CAAE,MAAO,CAAE,MAAO,CAAE,GAAG,EAAM,MAAO,UAAW,CAAS,CAAE,CAAE,CACrE,CAEA,OAAO,CACT"}
|
package/dist/inline.d.ts
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
import type { Middleware, Padding } from './types';
|
|
2
2
|
export interface InlineOptions {
|
|
3
|
-
/**
|
|
4
|
-
* Cursor x-coordinate. When provided alongside `y`, the middleware picks the
|
|
5
|
-
* client rect that contains the cursor instead of the closest rect to the floating element.
|
|
6
|
-
*/
|
|
7
|
-
x?: number;
|
|
8
|
-
/** Cursor y-coordinate. */
|
|
9
|
-
y?: number;
|
|
10
3
|
/**
|
|
11
4
|
* Padding used when hit-testing cursor coordinates against client rects.
|
|
12
5
|
* Prevents snapping when the cursor is just outside a rect edge. Default: `2`.
|
|
@@ -14,6 +7,13 @@ export interface InlineOptions {
|
|
|
14
7
|
* @remarks Only applies when both `x` and `y` are provided.
|
|
15
8
|
*/
|
|
16
9
|
padding?: Padding;
|
|
10
|
+
/**
|
|
11
|
+
* Cursor x-coordinate. When provided alongside `y`, the middleware picks the
|
|
12
|
+
* client rect that contains the cursor instead of the closest rect to the floating element.
|
|
13
|
+
*/
|
|
14
|
+
x?: number;
|
|
15
|
+
/** Cursor y-coordinate. */
|
|
16
|
+
y?: number;
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* Improves positioning accuracy for inline references that span multiple lines
|
package/dist/inline.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../src/inline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAA0B,MAAM,SAAS,CAAC;AA6B3E,MAAM,WAAW,aAAa;IAC5B
|
|
1
|
+
{"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../src/inline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAA0B,MAAM,SAAS,CAAC;AA6B3E,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,UAAU,CAsC9D"}
|
package/dist/inline.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inline.js","names":[],"sources":["../src/inline.ts"],"sourcesContent":["import type { Middleware, Padding, Rect, ReferenceElement } from './types';\n\nimport { getSide, toRect, toSideObject } from './utils';\n\n// ── Private helpers (only used by inline) ────────────────────────────────────────────\n\nfunction getClientRects(reference: ReferenceElement): Rect[] {\n if (!('getClientRects' in reference) || typeof reference.getClientRects !== 'function') return [];\n\n return Array.from((reference.getClientRects as () => DOMRectList | DOMRect[])())\n .map(toRect)\n .filter((r) => r.width > 0 || r.height > 0);\n}\n\nfunction rectContainsPoint(rect: Rect, x: number, y: number, padding: ReturnType<typeof toSideObject>): boolean {\n return (\n x >= rect.x - padding.left &&\n x <= rect.x + rect.width + padding.right &&\n y >= rect.y - padding.top &&\n y <= rect.y + rect.height + padding.bottom\n );\n}\n\nfunction sameRect(a: Rect, b: Rect): boolean {\n return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;\n}\n\n// ── Inline middleware ─────────────────────────────────────────────────────────────────\n\nexport interface InlineOptions {\n /**\n *
|
|
1
|
+
{"version":3,"file":"inline.js","names":[],"sources":["../src/inline.ts"],"sourcesContent":["import type { Middleware, Padding, Rect, ReferenceElement } from './types';\n\nimport { getSide, toRect, toSideObject } from './utils';\n\n// ── Private helpers (only used by inline) ────────────────────────────────────────────\n\nfunction getClientRects(reference: ReferenceElement): Rect[] {\n if (!('getClientRects' in reference) || typeof reference.getClientRects !== 'function') return [];\n\n return Array.from((reference.getClientRects as () => DOMRectList | DOMRect[])())\n .map(toRect)\n .filter((r) => r.width > 0 || r.height > 0);\n}\n\nfunction rectContainsPoint(rect: Rect, x: number, y: number, padding: ReturnType<typeof toSideObject>): boolean {\n return (\n x >= rect.x - padding.left &&\n x <= rect.x + rect.width + padding.right &&\n y >= rect.y - padding.top &&\n y <= rect.y + rect.height + padding.bottom\n );\n}\n\nfunction sameRect(a: Rect, b: Rect): boolean {\n return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;\n}\n\n// ── Inline middleware ─────────────────────────────────────────────────────────────────\n\nexport interface InlineOptions {\n /**\n * Padding used when hit-testing cursor coordinates against client rects.\n * Prevents snapping when the cursor is just outside a rect edge. Default: `2`.\n *\n * @remarks Only applies when both `x` and `y` are provided.\n */\n padding?: Padding;\n /**\n * Cursor x-coordinate. When provided alongside `y`, the middleware picks the\n * client rect that contains the cursor instead of the closest rect to the floating element.\n */\n x?: number;\n /** Cursor y-coordinate. */\n y?: number;\n}\n\n/**\n * Improves positioning accuracy for inline references that span multiple lines\n * (e.g. `<span>` wrapping across line breaks).\n *\n * Must be placed **before** `flip()` and other middleware in the pipeline.\n *\n * @example Tooltip on selected text:\n * ```ts\n * import { createPositioner, inline, flip, shift } from '@vielzeug/orbit';\n *\n * const positioner = createPositioner(selectionRef, tooltip, {\n * placement: 'top',\n * middleware: [inline({ x: cursorX, y: cursorY }), flip(), shift({ padding: 6 })],\n * });\n * positioner.start();\n * ```\n */\nexport function inline(options: InlineOptions = {}): Middleware {\n function inlineMiddleware(state: Parameters<Middleware>[0]): ReturnType<Middleware> {\n const rects = getClientRects(state.elements.reference);\n\n if (rects.length <= 1) return;\n\n const padding = toSideObject(options.padding ?? 2);\n const side = getSide(state.placement);\n let nextRect = rects[0]!;\n\n if (options.x != null && options.y != null) {\n nextRect = rects.find((rect) => rectContainsPoint(rect, options.x!, options.y!, padding)) ?? nextRect;\n } else if (side === 'top' || side === 'bottom') {\n const targetX = state.x + state.rects.floating.width / 2;\n\n nextRect = rects.reduce((best, rect) => {\n const bestDist = Math.abs(best.x + best.width / 2 - targetX);\n const rectDist = Math.abs(rect.x + rect.width / 2 - targetX);\n\n return rectDist < bestDist ? rect : best;\n }, nextRect);\n } else {\n const targetY = state.y + state.rects.floating.height / 2;\n\n nextRect = rects.reduce((best, rect) => {\n const bestDist = Math.abs(best.y + best.height / 2 - targetY);\n const rectDist = Math.abs(rect.y + rect.height / 2 - targetY);\n\n return rectDist < bestDist ? rect : best;\n }, nextRect);\n }\n\n if (sameRect(nextRect, state.rects.reference)) return;\n\n return { reset: { rects: { ...state.rects, reference: nextRect } } };\n }\n\n return inlineMiddleware;\n}\n"],"mappings":"mEAMA,SAAS,EAAe,EAAqC,CAG3D,MAFI,EAAE,mBAAoB,IAAc,OAAO,EAAU,gBAAmB,WAAmB,CAAC,EAEzF,MAAM,KAAM,EAAU,eAAiD,CAAC,CAAC,CAC7E,IAAI,CAAM,CAAC,CACX,OAAQ,GAAM,EAAE,MAAQ,GAAK,EAAE,OAAS,CAAC,CAC9C,CAEA,SAAS,EAAkB,EAAY,EAAW,EAAW,EAAmD,CAC9G,OACE,GAAK,EAAK,EAAI,EAAQ,MACtB,GAAK,EAAK,EAAI,EAAK,MAAQ,EAAQ,OACnC,GAAK,EAAK,EAAI,EAAQ,KACtB,GAAK,EAAK,EAAI,EAAK,OAAS,EAAQ,MAExC,CAEA,SAAS,EAAS,EAAS,EAAkB,CAC3C,OAAO,EAAE,IAAM,EAAE,GAAK,EAAE,IAAM,EAAE,GAAK,EAAE,QAAU,EAAE,OAAS,EAAE,SAAW,EAAE,MAC7E,CAsCA,SAAgB,EAAO,EAAyB,CAAC,EAAe,CAC9D,SAAS,EAAiB,EAA0D,CAClF,IAAM,EAAQ,EAAe,EAAM,SAAS,SAAS,EAErD,GAAI,EAAM,QAAU,EAAG,OAEvB,IAAM,EAAU,EAAa,EAAQ,SAAW,CAAC,EAC3C,EAAO,EAAQ,EAAM,SAAS,EAChC,EAAW,EAAM,GAErB,GAAI,EAAQ,GAAK,MAAQ,EAAQ,GAAK,KACpC,EAAW,EAAM,KAAM,GAAS,EAAkB,EAAM,EAAQ,EAAI,EAAQ,EAAI,CAAO,CAAC,GAAK,OACxF,GAAI,IAAS,OAAS,IAAS,SAAU,CAC9C,IAAM,EAAU,EAAM,EAAI,EAAM,MAAM,SAAS,MAAQ,EAEvD,EAAW,EAAM,QAAQ,EAAM,IAAS,CACtC,IAAM,EAAW,KAAK,IAAI,EAAK,EAAI,EAAK,MAAQ,EAAI,CAAO,EAG3D,OAFiB,KAAK,IAAI,EAAK,EAAI,EAAK,MAAQ,EAAI,CAE7C,EAAW,EAAW,EAAO,CACtC,EAAG,CAAQ,CACb,KAAO,CACL,IAAM,EAAU,EAAM,EAAI,EAAM,MAAM,SAAS,OAAS,EAExD,EAAW,EAAM,QAAQ,EAAM,IAAS,CACtC,IAAM,EAAW,KAAK,IAAI,EAAK,EAAI,EAAK,OAAS,EAAI,CAAO,EAG5D,OAFiB,KAAK,IAAI,EAAK,EAAI,EAAK,OAAS,EAAI,CAE9C,EAAW,EAAW,EAAO,CACtC,EAAG,CAAQ,CACb,CAEI,MAAS,EAAU,EAAM,MAAM,SAAS,EAE5C,MAAO,CAAE,MAAO,CAAE,MAAO,CAAE,GAAG,EAAM,MAAO,UAAW,CAAS,CAAE,CAAE,CACrE,CAEA,OAAO,CACT"}
|