@vielzeug/floatit 2.1.0 → 3.0.1
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/README.md +36 -44
- package/dist/floatit.cjs +1 -1
- package/dist/floatit.cjs.map +1 -1
- package/dist/floatit.d.ts +90 -71
- package/dist/floatit.d.ts.map +1 -1
- package/dist/floatit.js +1 -1
- package/dist/floatit.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -4,81 +4,73 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@vielzeug/floatit) [](https://opensource.org/licenses/MIT)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Floatit is a zero-dependency DOM positioning engine with composable middleware for overflow handling, sizing, arrows, hiding, and inline text anchors.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
12
|
pnpm add @vielzeug/floatit
|
|
13
|
-
# npm install @vielzeug/floatit
|
|
14
|
-
# yarn add @vielzeug/floatit
|
|
15
13
|
```
|
|
16
14
|
|
|
17
15
|
## Quick Start
|
|
18
16
|
|
|
19
17
|
```ts
|
|
20
|
-
import { autoUpdate, flip, offset,
|
|
18
|
+
import { arrow, autoUpdate, computePosition, flip, offset, shift } from '@vielzeug/floatit';
|
|
21
19
|
|
|
22
|
-
const reference = document.querySelector('#trigger')!;
|
|
23
|
-
const floating = document.querySelector('#tooltip')!;
|
|
24
|
-
|
|
25
|
-
await positionFloat(reference, floating, {
|
|
26
|
-
placement: 'top',
|
|
27
|
-
middleware: [offset(8), flip(), shift({ padding: 6 })],
|
|
28
|
-
});
|
|
20
|
+
const reference = document.querySelector<HTMLElement>('#trigger')!;
|
|
21
|
+
const floating = document.querySelector<HTMLElement>('#tooltip')!;
|
|
22
|
+
const arrowEl = floating.querySelector<HTMLElement>('.arrow')!;
|
|
29
23
|
|
|
30
24
|
const cleanup = autoUpdate(reference, floating, () => {
|
|
31
|
-
|
|
25
|
+
const result = computePosition(reference, floating, {
|
|
32
26
|
placement: 'top',
|
|
33
|
-
middleware: [offset(8), flip(), shift({ padding: 6 })],
|
|
27
|
+
middleware: [offset(8), flip(), shift({ padding: 6 }), arrow({ element: arrowEl, padding: 6 })],
|
|
34
28
|
});
|
|
29
|
+
|
|
30
|
+
floating.style.left = `${result.x}px`;
|
|
31
|
+
floating.style.top = `${result.y}px`;
|
|
32
|
+
|
|
33
|
+
floating.dataset.placement = result.placement;
|
|
35
34
|
});
|
|
36
35
|
|
|
37
|
-
// later
|
|
38
36
|
cleanup();
|
|
39
37
|
```
|
|
40
38
|
|
|
41
39
|
## Features
|
|
42
40
|
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
41
|
+
- `computePosition()` returns `x`, `y`, `placement`, and `middlewareData`
|
|
42
|
+
- Main APIs accept both DOM elements and virtual references
|
|
43
|
+
- `detectOverflow()` is available for custom middleware
|
|
44
|
+
- Built-in middleware: `offset`, `flip`, `autoPlacement`, `shift`, `size`, `arrow`, `hide`, and `inline`
|
|
45
|
+
- `float()` covers the common position-and-follow case and applies `left`/`top` by default
|
|
46
|
+
- `autoUpdate()` supports resize, scroll, visualViewport, and `animationFrame`
|
|
47
|
+
- Zero dependencies
|
|
49
48
|
|
|
50
49
|
## API Summary
|
|
51
50
|
|
|
52
51
|
| Export | Description |
|
|
53
|
-
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| `computePosition(reference, floating, options?)` | Return `x`, `y`, `placement`, and `middlewareData` |
|
|
54
|
+
| `float(reference, floating, options?)` | Position immediately and keep following with optional custom `apply` |
|
|
56
55
|
| `autoUpdate(reference, floating, update, options?)` | Re-run positioning when layout conditions change |
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
56
|
+
| `detectOverflow(state, options?)` | Return per-side overflow offsets |
|
|
57
|
+
| `offset(value)` | Add distance between reference and floating element (main/cross axis) |
|
|
58
|
+
| `flip(options?)` | Move to a fallback placement when the current one overflows |
|
|
59
|
+
| `autoPlacement(options?)` | Choose the placement with the most space |
|
|
60
|
+
| `shift(options?)` | Clamp the floating element inside a boundary |
|
|
60
61
|
| `size(options?)` | Provide available dimensions and resize hooks |
|
|
62
|
+
| `arrow(options)` | Provide arrow coordinates via `middlewareData.arrow` |
|
|
63
|
+
| `hide(options?)` | Provide visibility metadata via `middlewareData.hide` |
|
|
64
|
+
| `inline(options?)` | Improve placement for multi-line inline references |
|
|
61
65
|
|
|
62
|
-
##
|
|
66
|
+
## Notes
|
|
63
67
|
|
|
64
|
-
-
|
|
65
|
-
-
|
|
68
|
+
- Positions are viewport-relative; use `position: fixed` on the floating element unless you have a custom rendering strategy.
|
|
69
|
+
- `reference` can be either a DOM element or a virtual reference object with `getBoundingClientRect()`.
|
|
70
|
+
- Use either `flip()` or `autoPlacement()`, not both.
|
|
71
|
+
- Middleware return partial updates rather than whole-state clones.
|
|
66
72
|
- Call the cleanup returned by `autoUpdate()` when the floating UI closes.
|
|
67
|
-
- Use `autoUpdate(..., { observeFloating: false })` when observing floating-size changes would cause unnecessary update loops.
|
|
68
|
-
- Use `computePosition()` when you want to apply transforms or animations yourself.
|
|
69
73
|
|
|
70
74
|
## Documentation
|
|
71
75
|
|
|
72
|
-
Full docs at
|
|
73
|
-
|
|
74
|
-
| | |
|
|
75
|
-
|---|---|
|
|
76
|
-
| [Overview](https://vielzeug.dev/floatit/) | Installation, quick start, and feature overview |
|
|
77
|
-
| [Usage Guide](https://vielzeug.dev/floatit/usage) | Placement, middleware, and lifecycle patterns |
|
|
78
|
-
| [API Reference](https://vielzeug.dev/floatit/api) | Complete function signatures and types |
|
|
79
|
-
| [Examples](https://vielzeug.dev/floatit/examples) | Tooltips, dropdowns, and framework recipes |
|
|
80
|
-
|
|
81
|
-
## License
|
|
82
|
-
|
|
83
|
-
MIT © [Helmuth Saatkamp](https://github.com/helmuthdu) — Part of the [Vielzeug](https://github.com/helmuthdu/vielzeug) monorepo.
|
|
84
|
-
|
|
76
|
+
Full docs at [vielzeug.dev/floatit](https://vielzeug.dev/floatit)
|
package/dist/floatit.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e={bottom:`top`,left:`right`,right:`left`,top:`bottom`};function t(e){return e.split(`-`)[0]}function n(e){return e.split(`-`)[1]??null}function r({height:e,width:t,x:n,y:r}){return{height:e,width:t,x:n,y:r}}function i(e,t,n,r){return e===`start`?t:e===`end`?t+n-r:t+(n-r)/2}function
|
|
1
|
+
var e={bottom:`top`,left:`right`,right:`left`,top:`bottom`};function t(e){return e.split(`-`)[0]}function n(e){return e.split(`-`)[1]??null}function r(e,t){return t?`${e}-${t}`:e}function i({height:e,width:t,x:n,y:r}){return{height:e,width:t,x:n,y:r}}function a(e=0){return typeof e==`number`?{bottom:e,left:e,right:e,top:e}:{bottom:e.bottom??0,left:e.left??0,right:e.right??0,top:e.top??0}}function o(){let e=window.visualViewport;return e?{height:e.height,width:e.width,x:e.offsetLeft,y:e.offsetTop}:{height:window.innerHeight,width:window.innerWidth,x:0,y:0}}function s(e){return e?`getBoundingClientRect`in e?i(e.getBoundingClientRect()):e:o()}function c(e,t){return{floating:i(t.getBoundingClientRect()),reference:i(e.getBoundingClientRect())}}function l(e,t,n){return Math.min(Math.max(e,t),n)}function u(e,t,n,r){return e===`start`?t:e===`end`?t+n-r:t+(n-r)/2}function d(e,r,i){let a=t(e),o=n(e);switch(a){case`bottom`:return{x:u(o,r.x,r.width,i.width),y:r.y+r.height};case`left`:return{x:r.x-i.width,y:u(o,r.y,r.height,i.height)};case`right`:return{x:r.x+r.width,y:u(o,r.y,r.height,i.height)};case`top`:return{x:u(o,r.x,r.width,i.width),y:r.y-i.height}}}function f(e){return{...e.rects.floating,x:e.x,y:e.y}}function p(e,t){return t?{...e,middlewareData:t.data?{...e.middlewareData,...t.data}:e.middlewareData,placement:t.placement??e.placement,x:t.x??e.x,y:t.y??e.y}:e}function m(e){return Math.max(e.top,0)+Math.max(e.right,0)+Math.max(e.bottom,0)+Math.max(e.left,0)}function h(e){return e.top>0||e.right>0||e.bottom>0||e.left>0}function g(e,n,r,i){let a=e.rects.reference,o=t(n),s=r.y+i.top,c=r.x+r.width-i.right,l=r.y+r.height-i.bottom,u=r.x+i.left;switch(o){case`bottom`:return l-(a.y+a.height);case`left`:return a.x-u;case`right`:return c-(a.x+a.width);case`top`:return a.y-s}}function _(e,t){return t.top>=e.height||t.right>=e.width||t.bottom>=e.height||t.left>=e.width}function v(e){return!(`getClientRects`in e)||typeof e.getClientRects!=`function`?[]:Array.from(e.getClientRects()).map(e=>i(e)).filter(e=>e.width>0||e.height>0)}function y(e){return typeof Element<`u`&&e instanceof Element}function b(e,t,n,r){return t>=e.x-r.left&&t<=e.x+e.width+r.right&&n>=e.y-r.top&&n<=e.y+e.height+r.bottom}function x(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function S(e,t,n){return{bottom:e.y+e.height-(t.y+t.height-n.bottom),left:t.x+n.left-e.x,right:e.x+e.width-(t.x+t.width-n.right),top:t.y+n.top-e.y}}function C(e,t={}){let n=s(t.boundary),r=a(t.padding);return S(f(e),n,r)}function w(e,t,n={}){let{x:r,y:i}=d(t,e.rects.reference,e.rects.floating),o=s(n.boundary),c=a(n.padding);return S({...e.rects.floating,x:r,y:i},o,c)}function T(e,t,{middleware:n=[],placement:r=`bottom`}={}){let i=n.filter(Boolean),a=r,o={},s=c(e,t);for(let n=0;n<50;n+=1){let n={...d(a,s.reference,s.floating),elements:{floating:t,reference:e},initialPlacement:r,middlewareData:o,placement:a,rects:s},l;for(let e of i){let t=e(n);if(n=p(n,t),o=n.middlewareData,l=t?.reset,l)break}if(!l)return{middlewareData:n.middlewareData,placement:n.placement,x:n.x,y:n.y};l.rects===!0?s=c(e,t):l.rects&&(s=l.rects),a=l.placement??n.placement}throw Error(`[floatit] Middleware triggered too many resets in a single compute cycle.`)}function E(e,t){let n=typeof e==`function`?e(t):e;return typeof n==`number`?{crossAxis:0,mainAxis:n}:{crossAxis:n.crossAxis??0,mainAxis:n.mainAxis??0}}function D(e){return n=>{let r=t(n.placement),{crossAxis:i,mainAxis:a}=E(e,n);switch(r){case`bottom`:return{x:n.x+i,y:n.y+a};case`left`:return{x:n.x-a,y:n.y+i};case`right`:return{x:n.x+a,y:n.y+i};case`top`:return{x:n.x+i,y:n.y-a}}}}function O(i={}){return a=>{let o=C(a,i);if(!h(o))return;let s=t(a.placement),c=n(a.placement),l=i.fallbackPlacements??[r(e[s],c)],u=a.placement,d=m(o);for(let e of l){let t=w(a,e,i),n=m(t);if(!h(t))return{placement:e,reset:{placement:e}};n<d&&(u=e,d=n)}if(u!==a.placement)return{placement:u,reset:{placement:u}}}}function k(e={}){return t=>{let n=a(e.padding),r=s(e.boundary),i=e.allowedPlacements??[`top`,`right`,`bottom`,`left`],o=t.placement,c=1/0,l=-1/0;for(let a of i){let i=m(w(t,a,e)),s=g(t,a,r,n);(i<c||i===c&&s>l)&&(o=a,c=i,l=s)}if(o!==t.placement)return{placement:o,reset:{placement:o}}}}function A(e={}){return t=>{let n=C(t,e);return{x:t.x+Math.max(n.left,0)-Math.max(n.right,0),y:t.y+Math.max(n.top,0)-Math.max(n.bottom,0)}}}function j(e={}){let{apply:n}=e;return r=>{let i=s(e.boundary),o=a(e.padding),c=t(r.placement),l=i.y+o.top,u=i.x+i.width-o.right,d=i.y+i.height-o.bottom,f=i.x+o.left,p=c===`bottom`?Math.max(0,d-r.y):c===`top`?Math.max(0,r.rects.reference.y-l):Math.max(0,d-l),m=c===`right`?Math.max(0,u-r.x):c===`left`?Math.max(0,r.rects.reference.x-f):Math.max(0,u-f);n?.({availableHeight:p,availableWidth:m,elements:r.elements})}}function M({element:e,padding:n=0}){return r=>{let o=t(r.placement),s=a(n),c=i(e.getBoundingClientRect());if(o===`top`||o===`bottom`){let e=r.rects.reference.x+r.rects.reference.width/2-r.x-c.width/2,t=s.left,n=l(e,t,Math.max(t,r.rects.floating.width-c.width-s.right));return{data:{arrow:{centerOffset:e-n,x:n}}}}let u=r.rects.reference.y+r.rects.reference.height/2-r.y-c.height/2,d=s.top,f=l(u,d,Math.max(d,r.rects.floating.height-c.height-s.bottom));return{data:{arrow:{centerOffset:u-f,y:f}}}}}function N(e={}){let t=e.strategy??`both`;return n=>{let r=s(e.boundary),i=a(e.padding),o={};if(t===`escaped`||t===`both`){let e=S(f(n),r,i);o.escaped=_(f(n),e),o.escapedOffsets=e}if(t===`referenceHidden`||t===`both`){let e=S(n.rects.reference,r,i);o.referenceHidden=_(n.rects.reference,e),o.referenceHiddenOffsets=e}return{data:{hide:o}}}}function P(e={}){return n=>{let r=v(n.elements.reference);if(r.length<=1)return;let i=a(e.padding??2),o=t(n.placement),s=r[0];if(e.x!=null&&e.y!=null)s=r.find(t=>b(t,e.x,e.y,i))??s;else if(o===`top`||o===`bottom`){let e=n.x+n.rects.floating.width/2;s=r.reduce((t,n)=>{let r=Math.abs(t.x+t.width/2-e);return Math.abs(n.x+n.width/2-e)<r?n:t},s)}else{let e=n.y+n.rects.floating.height/2;s=r.reduce((t,n)=>{let r=Math.abs(t.y+t.height/2-e);return Math.abs(n.y+n.height/2-e)<r?n:t},s)}if(!x(s,n.rects.reference))return{reset:{rects:{...n.rects,reference:s}}}}}function F(e,t,n,{animationFrame:r=!1,observeFloating:i=!0,observeVisualViewport:a=!0}={}){n();let o=e=>{e.composedPath().includes(t)||n()};window.addEventListener(`scroll`,o,{capture:!0,passive:!0}),window.addEventListener(`resize`,n,{passive:!0});let s=a?window.visualViewport:null;s?.addEventListener(`resize`,n,{passive:!0}),s?.addEventListener(`scroll`,n,{passive:!0});let c=new ResizeObserver(n);y(e)&&c.observe(e),i&&c.observe(t);let l=0;if(r){let e=()=>{n(),l=window.requestAnimationFrame(e)};l=window.requestAnimationFrame(e)}return()=>{window.removeEventListener(`scroll`,o,{capture:!0}),window.removeEventListener(`resize`,n),s?.removeEventListener(`resize`,n),s?.removeEventListener(`scroll`,n),c.disconnect(),l&&window.cancelAnimationFrame(l)}}function I(e,t){t.floating.style.left=`${e.x}px`,t.floating.style.top=`${e.y}px`}function L(e,t,{animationFrame:n,apply:r=I,middleware:i,observeFloating:a,observeVisualViewport:o,placement:s}={}){return F(e,t,()=>{r(T(e,t,{middleware:i,placement:s}),{floating:t,reference:e})},{animationFrame:n,observeFloating:a,observeVisualViewport:o})}exports.arrow=M,exports.autoPlacement=k,exports.autoUpdate=F,exports.computePosition=T,exports.detectOverflow=C,exports.flip=O,exports.float=L,exports.hide=N,exports.inline=P,exports.offset=D,exports.shift=A,exports.size=j;
|
|
2
2
|
//# sourceMappingURL=floatit.cjs.map
|
package/dist/floatit.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floatit.cjs","names":[],"sources":["../src/floatit.ts"],"sourcesContent":["/** @vielzeug/floatit — Lightweight floating element positioning. */\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type Side = 'top' | 'bottom' | 'left' | 'right';\nexport type Alignment = 'start' | 'end';\nexport type Placement = Side | `${Side}-${Alignment}`;\n\ninterface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface MiddlewareState {\n x: number;\n y: number;\n placement: Placement;\n rects: { floating: Rect; reference: Rect };\n elements: { floating: HTMLElement; reference: Element };\n}\n\nexport interface Middleware {\n name: string;\n fn: (state: MiddlewareState) => MiddlewareState;\n}\n\nexport interface ComputePositionConfig {\n placement?: Placement;\n middleware?: Array<Middleware | null | undefined | false>;\n}\n\nexport interface ComputePositionResult {\n x: number;\n y: number;\n placement: Placement;\n}\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\nconst OPPOSITE: Record<Side, Side> = { bottom: 'top', left: 'right', right: 'left', top: 'bottom' };\n\nfunction getSide(p: Placement): Side {\n return p.split('-')[0] as Side;\n}\n\nfunction getAlign(p: Placement): Alignment | null {\n return (p.split('-')[1] as Alignment) ?? null;\n}\n\nfunction toRect({ height, width, x, y }: DOMRect): Rect {\n return { height, width, x, y };\n}\n\nfunction alignedOffset(align: Alignment | null, refStart: number, refSize: number, floatSize: number): number {\n if (align === 'start') return refStart;\n\n if (align === 'end') return refStart + refSize - floatSize;\n\n return refStart + (refSize - floatSize) / 2;\n}\n\nfunction baseCoords(placement: Placement, ref: Rect, float: Rect): { x: number; y: number } {\n const side = getSide(placement);\n const align = getAlign(placement);\n\n if (side === 'top') return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y - float.height };\n\n if (side === 'bottom') return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y + ref.height };\n\n if (side === 'left') return { x: ref.x - float.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n\n /* right */ return { x: ref.x + ref.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n}\n\n// ─── Pipeline ─────────────────────────────────────────────────────────────────\n\nfunction runPipeline(\n mws: Middleware[],\n placement: Placement,\n reference: Element,\n floating: HTMLElement,\n): ComputePositionResult {\n const refRect = toRect(reference.getBoundingClientRect());\n const floatRect = toRect(floating.getBoundingClientRect());\n let state: MiddlewareState = {\n ...baseCoords(placement, refRect, floatRect),\n elements: { floating, reference },\n placement,\n rects: { floating: floatRect, reference: refRect },\n };\n\n for (const mw of mws) state = mw.fn(state);\n\n // If a middleware (e.g. flip) changed the placement, restart once with the new one.\n if (state.placement !== placement) {\n return runPipeline(mws, state.placement, reference, floating);\n }\n\n return { placement: state.placement, x: state.x, y: state.y };\n}\n\n// ─── computePosition ──────────────────────────────────────────────────────────\n\n/** Computes the position of a floating element relative to a reference element. */\nexport function computePosition(\n reference: Element,\n floating: HTMLElement,\n config: ComputePositionConfig = {},\n): ComputePositionResult {\n const { middleware = [], placement = 'bottom' } = config;\n\n return runPipeline(middleware.filter(Boolean) as Middleware[], placement, reference, floating);\n}\n\n// ─── Middlewares ──────────────────────────────────────────────────────────────\n\n/** Adds a gap (in px) between the reference and the floating element. */\nexport function offset(value: number): Middleware {\n return {\n fn(state) {\n const side = getSide(state.placement);\n\n return {\n ...state,\n x: state.x + (side === 'right' ? value : side === 'left' ? -value : 0),\n y: state.y + (side === 'bottom' ? value : side === 'top' ? -value : 0),\n };\n },\n name: 'offset',\n };\n}\n\nexport interface FlipOptions {\n /** Minimum distance from the viewport edge before flipping (px). */\n padding?: number;\n}\n\n/** Flips the floating element to the opposite side when it would overflow the viewport. */\nexport function flip(options: FlipOptions = {}): Middleware {\n const { padding = 0 } = options;\n\n return {\n fn(state) {\n const {\n placement,\n rects: { floating },\n x,\n y,\n } = state;\n const side = getSide(placement);\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const overflows =\n (side === 'top' && y < padding) ||\n (side === 'bottom' && y + floating.height > vh - padding) ||\n (side === 'left' && x < padding) ||\n (side === 'right' && x + floating.width > vw - padding);\n\n if (!overflows) return state;\n\n const align = getAlign(placement);\n const opp = OPPOSITE[side];\n const flipped = (align ? `${opp}-${align}` : opp) as Placement;\n\n return { ...state, placement: flipped };\n },\n name: 'flip',\n };\n}\n\nexport interface ShiftOptions {\n /** Minimum distance to maintain from the viewport edges (px). */\n padding?: number;\n}\n\n/** Shifts the floating element along its axis to keep it within the viewport. */\nexport function shift(options: ShiftOptions = {}): Middleware {\n const { padding = 0 } = options;\n\n return {\n fn(state) {\n const {\n rects: { floating },\n x,\n y,\n } = state;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n return {\n ...state,\n x: Math.min(Math.max(x, padding), vw - floating.width - padding),\n y: Math.min(Math.max(y, padding), vh - floating.height - padding),\n };\n },\n name: 'shift',\n };\n}\n\nexport interface SizeApplyArgs {\n availableWidth: number;\n availableHeight: number;\n elements: { floating: HTMLElement; reference: Element };\n}\n\nexport interface SizeOptions {\n /** Minimum distance to maintain from the viewport edges (px). */\n padding?: number;\n /** Called with available dimensions — use to resize the floating element. */\n apply?: (args: SizeApplyArgs) => void;\n}\n\n/** Provides available width/height based on actual float position and optionally resizes the floating element. */\nexport function size(options: SizeOptions = {}): Middleware {\n const { apply, padding = 0 } = options;\n\n return {\n fn(state) {\n const {\n placement,\n rects: { floating },\n x,\n y,\n } = state;\n const side = getSide(placement);\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const availableHeight =\n side === 'bottom' ? vh - y - padding : side === 'top' ? y + floating.height - padding : vh - padding * 2;\n\n const availableWidth =\n side === 'right' ? vw - x - padding : side === 'left' ? x + floating.width - padding : vw - padding * 2;\n\n apply?.({ availableHeight, availableWidth, elements: state.elements });\n\n return state;\n },\n name: 'size',\n };\n}\n\n// ─── autoUpdate ───────────────────────────────────────────────────────────────\n\nexport interface AutoUpdateOptions {\n /**\n * Whether to observe size changes on the floating element itself.\n * Set to `false` for virtual-scroll dropdowns whose outer dimensions are\n * managed entirely by the caller (e.g. width set via `size()` middleware),\n * to avoid a ResizeObserver feedback loop.\n * Defaults to `true`.\n */\n observeFloating?: boolean;\n /**\n * Whether to observe `window.visualViewport` resize/scroll changes.\n * Helps keep floating UI aligned during pinch-zoom and virtual keyboard changes.\n * Defaults to `true`.\n */\n observeVisualViewport?: boolean;\n}\n\n/**\n * Automatically calls `update` whenever the floating element's position may have\n * changed (viewport resize, scroll events, or reference / floating element resize).\n * Calls `update` once immediately on registration.\n * Returns a cleanup function.\n */\nexport function autoUpdate(\n reference: Element,\n floating: HTMLElement,\n update: () => void,\n { observeFloating = true, observeVisualViewport = true }: AutoUpdateOptions = {},\n): () => void {\n update();\n\n // Use composedPath() instead of e.target — shadow DOM retargets e.target to\n // the shadow host at the window listener boundary.\n const scrollHandler = (e: Event) => {\n if (e.composedPath().includes(floating)) return;\n\n update();\n };\n\n window.addEventListener('scroll', scrollHandler, { capture: true, passive: true });\n window.addEventListener('resize', update, { passive: true });\n\n const vv = observeVisualViewport ? window.visualViewport : null;\n\n vv?.addEventListener('resize', update, { passive: true });\n vv?.addEventListener('scroll', update, { passive: true });\n\n const ro = new ResizeObserver(update);\n\n ro.observe(reference);\n\n if (observeFloating) ro.observe(floating);\n\n return () => {\n window.removeEventListener('scroll', scrollHandler, { capture: true } as EventListenerOptions);\n window.removeEventListener('resize', update);\n vv?.removeEventListener('resize', update);\n vv?.removeEventListener('scroll', update);\n ro.disconnect();\n };\n}\n\n// ─── positionFloat / float ────────────────────────────────────────────────────\n\nexport interface FloatOptions {\n /** Preferred placement relative to the reference element. */\n placement?: Placement;\n /** Middleware to modify positioning behavior. */\n middleware?: Array<Middleware | null | undefined | false>;\n}\n\n/**\n * Computes and applies the floating position to a floating element.\n * Sets `left`/`top` inline styles and returns the resolved placement.\n */\nexport function positionFloat(reference: Element, floating: HTMLElement, options: FloatOptions = {}): Placement {\n const { placement, x, y } = computePosition(reference, floating, options);\n\n floating.style.left = `${x}px`;\n floating.style.top = `${y}px`;\n\n return placement;\n}\n\n/**\n * Positions a floating element relative to a reference element and keeps it in\n * sync as the viewport or elements change. Returns a cleanup function.\n *\n * @example\n * ```ts\n * const cleanup = float(trigger, tooltip, {\n * placement: 'top',\n * middleware: [offset(8), flip(), shift({ padding: 6 })],\n * });\n *\n * // When done:\n * cleanup();\n * ```\n */\nexport function float(reference: Element, floating: HTMLElement, options: FloatOptions = {}): () => void {\n return autoUpdate(reference, floating, () => positionFloat(reference, floating, options));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"floatit.cjs","names":[],"sources":["../src/floatit.ts"],"sourcesContent":["/** @vielzeug/floatit - Lightweight floating element positioning. */\n\nexport type Side = 'top' | 'bottom' | 'left' | 'right';\nexport type Alignment = 'start' | 'end';\nexport type Placement = Side | `${Side}-${Alignment}`;\n\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface VirtualReference {\n getBoundingClientRect: () => DOMRect | Rect;\n getClientRects?: () => DOMRectList | DOMRect[];\n}\n\nexport type ReferenceElement = Element | VirtualReference;\n\nexport interface SideObject {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\nexport type Padding = number | Partial<SideObject>;\ntype Boundary = Element | Rect;\n\nexport interface ArrowData {\n x?: number;\n y?: number;\n centerOffset: number;\n}\n\nexport interface HideData {\n escaped?: boolean;\n escapedOffsets?: SideObject;\n referenceHidden?: boolean;\n referenceHiddenOffsets?: SideObject;\n}\n\nexport interface MiddlewareData {\n arrow?: ArrowData;\n hide?: HideData;\n [key: string]: unknown;\n}\n\nexport interface MiddlewareState {\n x: number;\n y: number;\n initialPlacement: Placement;\n placement: Placement;\n rects: { floating: Rect; reference: Rect };\n elements: { floating: HTMLElement; reference: ReferenceElement };\n middlewareData: MiddlewareData;\n}\n\nexport type MiddlewareReset = {\n placement?: Placement;\n rects?: true | MiddlewareState['rects'];\n};\n\nexport interface MiddlewareResult {\n x?: number;\n y?: number;\n placement?: Placement;\n data?: MiddlewareData;\n reset?: MiddlewareReset;\n}\n\nexport type Middleware = (state: MiddlewareState) => MiddlewareResult | void;\n\nexport interface FloatOptions {\n placement?: Placement;\n middleware?: Array<Middleware | null | undefined | false>;\n}\n\nexport interface ComputePositionResult {\n x: number;\n y: number;\n placement: Placement;\n middlewareData: MiddlewareData;\n}\n\nexport type Cleanup = () => void;\n\nconst OPPOSITE: Record<Side, Side> = { bottom: 'top', left: 'right', right: 'left', top: 'bottom' };\n\nfunction getSide(p: Placement): Side {\n return p.split('-')[0] as Side;\n}\n\nfunction getAlign(p: Placement): Alignment | null {\n return (p.split('-')[1] as Alignment) ?? null;\n}\n\nfunction withPlacement(side: Side, align: Alignment | null): Placement {\n return (align ? `${side}-${align}` : side) as Placement;\n}\n\nfunction toRect({ height, width, x, y }: DOMRect | Rect): Rect {\n return { height, width, x, y };\n}\n\nfunction toSideObject(padding: Padding = 0): SideObject {\n if (typeof padding === 'number') {\n return { bottom: padding, left: padding, right: padding, top: padding };\n }\n\n return {\n bottom: padding.bottom ?? 0,\n left: padding.left ?? 0,\n right: padding.right ?? 0,\n top: padding.top ?? 0,\n };\n}\n\nfunction getViewportRect(): Rect {\n const vv = window.visualViewport;\n\n if (vv) return { height: vv.height, width: vv.width, x: vv.offsetLeft, y: vv.offsetTop };\n\n return { height: window.innerHeight, width: window.innerWidth, x: 0, y: 0 };\n}\n\nfunction getBoundaryRect(boundary?: Boundary): Rect {\n if (!boundary) return getViewportRect();\n\n if ('getBoundingClientRect' in boundary) return toRect(boundary.getBoundingClientRect());\n\n return boundary;\n}\n\nfunction getRects(reference: ReferenceElement, floating: HTMLElement): MiddlewareState['rects'] {\n return {\n floating: toRect(floating.getBoundingClientRect()),\n reference: toRect(reference.getBoundingClientRect()),\n };\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction alignedOffset(align: Alignment | null, refStart: number, refSize: number, floatSize: number): number {\n if (align === 'start') return refStart;\n\n if (align === 'end') return refStart + refSize - floatSize;\n\n return refStart + (refSize - floatSize) / 2;\n}\n\nfunction baseCoords(placement: Placement, ref: Rect, float: Rect): { x: number; y: number } {\n const side = getSide(placement);\n const align = getAlign(placement);\n\n switch (side) {\n case 'bottom':\n return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y + ref.height };\n case 'left':\n return { x: ref.x - float.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n case 'right':\n return { x: ref.x + ref.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n case 'top':\n return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y - float.height };\n }\n}\n\nfunction getFloatingRect(state: MiddlewareState): Rect {\n return { ...state.rects.floating, x: state.x, y: state.y };\n}\n\nfunction mergeState(state: MiddlewareState, result: MiddlewareResult | void): MiddlewareState {\n if (!result) return state;\n\n return {\n ...state,\n middlewareData: result.data ? { ...state.middlewareData, ...result.data } : state.middlewareData,\n placement: result.placement ?? state.placement,\n x: result.x ?? state.x,\n y: result.y ?? state.y,\n };\n}\n\nfunction totalOverflow(overflow: SideObject): number {\n return (\n Math.max(overflow.top, 0) + Math.max(overflow.right, 0) + Math.max(overflow.bottom, 0) + Math.max(overflow.left, 0)\n );\n}\n\nfunction hasOverflow(overflow: SideObject): boolean {\n return overflow.top > 0 || overflow.right > 0 || overflow.bottom > 0 || overflow.left > 0;\n}\n\nfunction getAvailableSpace(state: MiddlewareState, placement: Placement, boundary: Rect, padding: SideObject): number {\n const refRect = state.rects.reference;\n const side = getSide(placement);\n const boundaryTop = boundary.y + padding.top;\n const boundaryRight = boundary.x + boundary.width - padding.right;\n const boundaryBottom = boundary.y + boundary.height - padding.bottom;\n const boundaryLeft = boundary.x + padding.left;\n\n switch (side) {\n case 'bottom':\n return boundaryBottom - (refRect.y + refRect.height);\n case 'left':\n return refRect.x - boundaryLeft;\n case 'right':\n return boundaryRight - (refRect.x + refRect.width);\n case 'top':\n return refRect.y - boundaryTop;\n }\n}\n\nfunction isFullyClipped(rect: Rect, overflow: SideObject): boolean {\n return (\n overflow.top >= rect.height ||\n overflow.right >= rect.width ||\n overflow.bottom >= rect.height ||\n overflow.left >= rect.width\n );\n}\n\nfunction getClientRects(reference: ReferenceElement): Rect[] {\n if (!('getClientRects' in reference) || typeof reference.getClientRects !== 'function') return [];\n\n return Array.from(reference.getClientRects())\n .map((rect) => toRect(rect))\n .filter((rect) => rect.width > 0 || rect.height > 0);\n}\n\nfunction isElement(value: unknown): value is Element {\n return typeof Element !== 'undefined' && value instanceof Element;\n}\n\nfunction rectContainsPoint(rect: Rect, x: number, y: number, padding: SideObject): 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\nfunction detectOverflowAtRect(rect: Rect, boundary: Rect, padding: SideObject): SideObject {\n return {\n bottom: rect.y + rect.height - (boundary.y + boundary.height - padding.bottom),\n left: boundary.x + padding.left - rect.x,\n right: rect.x + rect.width - (boundary.x + boundary.width - padding.right),\n top: boundary.y + padding.top - rect.y,\n };\n}\n\nexport interface DetectOverflowOptions {\n boundary?: Element | Rect;\n padding?: Padding;\n}\n\nexport function detectOverflow(state: MiddlewareState, options: DetectOverflowOptions = {}): SideObject {\n const boundary = getBoundaryRect(options.boundary);\n const padding = toSideObject(options.padding);\n\n return detectOverflowAtRect(getFloatingRect(state), boundary, padding);\n}\n\nfunction getPlacementOverflow(\n state: MiddlewareState,\n placement: Placement,\n options: DetectOverflowOptions = {},\n): SideObject {\n const { x, y } = baseCoords(placement, state.rects.reference, state.rects.floating);\n const boundary = getBoundaryRect(options.boundary);\n const padding = toSideObject(options.padding);\n const rect = { ...state.rects.floating, x, y };\n\n return detectOverflowAtRect(rect, boundary, padding);\n}\n\nexport function computePosition(\n reference: ReferenceElement,\n floating: HTMLElement,\n { middleware = [], placement = 'bottom' }: FloatOptions = {},\n): ComputePositionResult {\n const mws = middleware.filter(Boolean) as Middleware[];\n let currentPlacement = placement;\n let middlewareData: MiddlewareData = {};\n let rects = getRects(reference, floating);\n\n for (let resets = 0; resets < 50; resets += 1) {\n let state: MiddlewareState = {\n ...baseCoords(currentPlacement, rects.reference, rects.floating),\n elements: { floating, reference },\n initialPlacement: placement,\n middlewareData,\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 return { middlewareData: state.middlewareData, placement: state.placement, x: state.x, y: state.y };\n }\n\n if (reset.rects === true) {\n rects = getRects(reference, floating);\n } else if (reset.rects) {\n rects = reset.rects;\n }\n\n currentPlacement = reset.placement ?? state.placement;\n }\n\n throw new Error('[floatit] Middleware triggered too many resets in a single compute cycle.');\n}\n\nexport type OffsetConfig = {\n crossAxis?: number;\n mainAxis?: number;\n};\n\nexport type OffsetValue = number | OffsetConfig | ((state: MiddlewareState) => number | OffsetConfig);\n\nfunction resolveOffsetConfig(value: OffsetValue, state: MiddlewareState): Required<OffsetConfig> {\n const raw = typeof value === 'function' ? value(state) : value;\n\n if (typeof raw === 'number') {\n return { crossAxis: 0, mainAxis: raw };\n }\n\n return {\n crossAxis: raw.crossAxis ?? 0,\n mainAxis: raw.mainAxis ?? 0,\n };\n}\n\nexport function offset(value: OffsetValue): Middleware {\n return (state) => {\n const side = getSide(state.placement);\n const { crossAxis, mainAxis } = resolveOffsetConfig(value, state);\n\n switch (side) {\n case 'bottom':\n return { x: state.x + crossAxis, y: state.y + mainAxis };\n case 'left':\n return { x: state.x - mainAxis, y: state.y + crossAxis };\n case 'right':\n return { x: state.x + mainAxis, y: state.y + crossAxis };\n case 'top':\n return { x: state.x + crossAxis, y: state.y - mainAxis };\n }\n };\n}\n\nexport interface FlipOptions extends DetectOverflowOptions {\n fallbackPlacements?: Placement[];\n}\n\nexport function flip(options: FlipOptions = {}): Middleware {\n return (state) => {\n const currentOverflow = detectOverflow(state, options);\n\n if (!hasOverflow(currentOverflow)) return;\n\n const side = getSide(state.placement);\n const align = getAlign(state.placement);\n const fallbackPlacements = options.fallbackPlacements ?? [withPlacement(OPPOSITE[side], align)];\n let bestPlacement = state.placement;\n let bestScore = totalOverflow(currentOverflow);\n\n for (const candidate of fallbackPlacements) {\n const candidateOverflow = getPlacementOverflow(state, candidate, options);\n const score = totalOverflow(candidateOverflow);\n\n if (!hasOverflow(candidateOverflow)) {\n return { placement: candidate, reset: { placement: candidate } };\n }\n\n if (score < bestScore) {\n bestPlacement = candidate;\n bestScore = score;\n }\n }\n\n if (bestPlacement !== state.placement) {\n return { placement: bestPlacement, reset: { placement: bestPlacement } };\n }\n };\n}\n\nexport interface AutoPlacementOptions extends DetectOverflowOptions {\n allowedPlacements?: Placement[];\n}\n\nexport function autoPlacement(options: AutoPlacementOptions = {}): Middleware {\n return (state) => {\n const padding = toSideObject(options.padding);\n const boundary = getBoundaryRect(options.boundary);\n const placements = options.allowedPlacements ?? ['top', 'right', 'bottom', 'left'];\n let bestPlacement = state.placement;\n let bestOverflow = Number.POSITIVE_INFINITY;\n let bestSpace = Number.NEGATIVE_INFINITY;\n\n for (const candidate of placements) {\n const overflow = getPlacementOverflow(state, candidate, options);\n const overflowScore = totalOverflow(overflow);\n const availableSpace = getAvailableSpace(state, candidate, boundary, padding);\n\n if (overflowScore < bestOverflow || (overflowScore === bestOverflow && availableSpace > bestSpace)) {\n bestPlacement = candidate;\n bestOverflow = overflowScore;\n bestSpace = availableSpace;\n }\n }\n\n if (bestPlacement !== state.placement) {\n return { placement: bestPlacement, reset: { placement: bestPlacement } };\n }\n };\n}\n\nexport type ShiftOptions = DetectOverflowOptions;\n\nexport function shift(options: ShiftOptions = {}): Middleware {\n return (state) => {\n const overflow = detectOverflow(state, options);\n\n return {\n x: state.x + Math.max(overflow.left, 0) - Math.max(overflow.right, 0),\n y: state.y + Math.max(overflow.top, 0) - Math.max(overflow.bottom, 0),\n };\n };\n}\n\nexport interface SizeApplyArgs {\n availableWidth: number;\n availableHeight: number;\n elements: { floating: HTMLElement; reference: ReferenceElement };\n}\n\nexport interface SizeOptions extends DetectOverflowOptions {\n apply?: (args: SizeApplyArgs) => void;\n}\n\nexport function size(options: SizeOptions = {}): Middleware {\n const { apply } = options;\n\n return (state) => {\n const boundary = getBoundaryRect(options.boundary);\n const padding = toSideObject(options.padding);\n const side = getSide(state.placement);\n const top = boundary.y + padding.top;\n const right = boundary.x + boundary.width - padding.right;\n const bottom = boundary.y + boundary.height - padding.bottom;\n const left = boundary.x + padding.left;\n\n const availableHeight =\n side === 'bottom'\n ? Math.max(0, bottom - state.y)\n : side === 'top'\n ? Math.max(0, state.rects.reference.y - top)\n : Math.max(0, bottom - top);\n\n const availableWidth =\n side === 'right'\n ? Math.max(0, right - state.x)\n : side === 'left'\n ? Math.max(0, state.rects.reference.x - left)\n : Math.max(0, right - left);\n\n apply?.({ availableHeight, availableWidth, elements: state.elements });\n };\n}\n\nexport interface ArrowOptions {\n element: HTMLElement;\n padding?: Padding;\n}\n\nexport function arrow({ element, padding = 0 }: ArrowOptions): Middleware {\n return (state) => {\n const side = getSide(state.placement);\n const inset = toSideObject(padding);\n const arrowRect = toRect(element.getBoundingClientRect());\n\n if (side === 'top' || side === 'bottom') {\n const idealX = state.rects.reference.x + state.rects.reference.width / 2 - state.x - arrowRect.width / 2;\n const minX = inset.left;\n const maxX = Math.max(minX, state.rects.floating.width - arrowRect.width - inset.right);\n const x = clamp(idealX, minX, maxX);\n\n return { data: { arrow: { centerOffset: idealX - x, x } } };\n }\n\n const idealY = state.rects.reference.y + state.rects.reference.height / 2 - state.y - arrowRect.height / 2;\n const minY = inset.top;\n const maxY = Math.max(minY, state.rects.floating.height - arrowRect.height - inset.bottom);\n const y = clamp(idealY, minY, maxY);\n\n return { data: { arrow: { centerOffset: idealY - y, y } } };\n };\n}\n\nexport interface HideOptions extends DetectOverflowOptions {\n strategy?: 'referenceHidden' | 'escaped' | 'both';\n}\n\nexport function hide(options: HideOptions = {}): Middleware {\n const strategy = options.strategy ?? 'both';\n\n return (state) => {\n const boundary = getBoundaryRect(options.boundary);\n const padding = toSideObject(options.padding);\n const next: HideData = {};\n\n if (strategy === 'escaped' || strategy === 'both') {\n const escapedOffsets = detectOverflowAtRect(getFloatingRect(state), boundary, padding);\n\n next.escaped = isFullyClipped(getFloatingRect(state), escapedOffsets);\n next.escapedOffsets = escapedOffsets;\n }\n\n if (strategy === 'referenceHidden' || strategy === 'both') {\n const referenceHiddenOffsets = detectOverflowAtRect(state.rects.reference, boundary, padding);\n\n next.referenceHidden = isFullyClipped(state.rects.reference, referenceHiddenOffsets);\n next.referenceHiddenOffsets = referenceHiddenOffsets;\n }\n\n return { data: { hide: next } };\n };\n}\n\nexport interface InlineOptions {\n x?: number;\n y?: number;\n padding?: Padding;\n}\n\nexport function inline(options: InlineOptions = {}): Middleware {\n return (state) => {\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 bestDistance = Math.abs(best.x + best.width / 2 - targetX);\n const rectDistance = Math.abs(rect.x + rect.width / 2 - targetX);\n\n return rectDistance < bestDistance ? 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 bestDistance = Math.abs(best.y + best.height / 2 - targetY);\n const rectDistance = Math.abs(rect.y + rect.height / 2 - targetY);\n\n return rectDistance < bestDistance ? rect : best;\n }, nextRect);\n }\n\n if (sameRect(nextRect, state.rects.reference)) return;\n\n return {\n reset: {\n rects: { ...state.rects, reference: nextRect },\n },\n };\n };\n}\n\nexport interface AutoUpdateOptions {\n observeFloating?: boolean;\n observeVisualViewport?: boolean;\n animationFrame?: boolean;\n}\n\nexport function autoUpdate(\n reference: ReferenceElement,\n floating: HTMLElement,\n update: () => void,\n { animationFrame = false, observeFloating = true, observeVisualViewport = true }: AutoUpdateOptions = {},\n): Cleanup {\n update();\n\n const scrollHandler = (e: Event) => {\n if (e.composedPath().includes(floating)) return;\n\n update();\n };\n\n window.addEventListener('scroll', scrollHandler, { capture: true, passive: true });\n window.addEventListener('resize', update, { passive: true });\n\n const vv = observeVisualViewport ? window.visualViewport : null;\n\n vv?.addEventListener('resize', update, { passive: true });\n vv?.addEventListener('scroll', update, { passive: true });\n\n const ro = new ResizeObserver(update);\n\n if (isElement(reference)) ro.observe(reference);\n\n if (observeFloating) ro.observe(floating);\n\n let frameId = 0;\n\n if (animationFrame) {\n const frameLoop = () => {\n update();\n frameId = window.requestAnimationFrame(frameLoop);\n };\n\n frameId = window.requestAnimationFrame(frameLoop);\n }\n\n return () => {\n window.removeEventListener('scroll', scrollHandler, { capture: true });\n window.removeEventListener('resize', update);\n vv?.removeEventListener('resize', update);\n vv?.removeEventListener('scroll', update);\n ro.disconnect();\n\n if (frameId) window.cancelAnimationFrame(frameId);\n };\n}\n\nexport interface FloatRuntimeOptions extends FloatOptions, AutoUpdateOptions {\n apply?: (result: ComputePositionResult, elements: { floating: HTMLElement; reference: ReferenceElement }) => void;\n}\n\nfunction applyDefault(result: ComputePositionResult, elements: { floating: HTMLElement }): void {\n elements.floating.style.left = `${result.x}px`;\n elements.floating.style.top = `${result.y}px`;\n}\n\nexport function float(\n reference: ReferenceElement,\n floating: HTMLElement,\n {\n animationFrame,\n apply = applyDefault,\n middleware,\n observeFloating,\n observeVisualViewport,\n placement,\n }: FloatRuntimeOptions = {},\n): Cleanup {\n return autoUpdate(\n reference,\n floating,\n () => {\n const result = computePosition(reference, floating, { middleware, placement });\n\n apply(result, { floating, reference });\n },\n { animationFrame, observeFloating, observeVisualViewport },\n );\n}\n"],"mappings":"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"}
|
package/dist/floatit.d.ts
CHANGED
|
@@ -1,16 +1,45 @@
|
|
|
1
|
-
/** @vielzeug/floatit
|
|
1
|
+
/** @vielzeug/floatit - Lightweight floating element positioning. */
|
|
2
2
|
export type Side = 'top' | 'bottom' | 'left' | 'right';
|
|
3
3
|
export type Alignment = 'start' | 'end';
|
|
4
4
|
export type Placement = Side | `${Side}-${Alignment}`;
|
|
5
|
-
interface Rect {
|
|
5
|
+
export interface Rect {
|
|
6
6
|
x: number;
|
|
7
7
|
y: number;
|
|
8
8
|
width: number;
|
|
9
9
|
height: number;
|
|
10
10
|
}
|
|
11
|
+
export interface VirtualReference {
|
|
12
|
+
getBoundingClientRect: () => DOMRect | Rect;
|
|
13
|
+
getClientRects?: () => DOMRectList | DOMRect[];
|
|
14
|
+
}
|
|
15
|
+
export type ReferenceElement = Element | VirtualReference;
|
|
16
|
+
export interface SideObject {
|
|
17
|
+
top: number;
|
|
18
|
+
right: number;
|
|
19
|
+
bottom: number;
|
|
20
|
+
left: number;
|
|
21
|
+
}
|
|
22
|
+
export type Padding = number | Partial<SideObject>;
|
|
23
|
+
export interface ArrowData {
|
|
24
|
+
x?: number;
|
|
25
|
+
y?: number;
|
|
26
|
+
centerOffset: number;
|
|
27
|
+
}
|
|
28
|
+
export interface HideData {
|
|
29
|
+
escaped?: boolean;
|
|
30
|
+
escapedOffsets?: SideObject;
|
|
31
|
+
referenceHidden?: boolean;
|
|
32
|
+
referenceHiddenOffsets?: SideObject;
|
|
33
|
+
}
|
|
34
|
+
export interface MiddlewareData {
|
|
35
|
+
arrow?: ArrowData;
|
|
36
|
+
hide?: HideData;
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
}
|
|
11
39
|
export interface MiddlewareState {
|
|
12
40
|
x: number;
|
|
13
41
|
y: number;
|
|
42
|
+
initialPlacement: Placement;
|
|
14
43
|
placement: Placement;
|
|
15
44
|
rects: {
|
|
16
45
|
floating: Rect;
|
|
@@ -18,14 +47,23 @@ export interface MiddlewareState {
|
|
|
18
47
|
};
|
|
19
48
|
elements: {
|
|
20
49
|
floating: HTMLElement;
|
|
21
|
-
reference:
|
|
50
|
+
reference: ReferenceElement;
|
|
22
51
|
};
|
|
52
|
+
middlewareData: MiddlewareData;
|
|
23
53
|
}
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
|
|
54
|
+
export type MiddlewareReset = {
|
|
55
|
+
placement?: Placement;
|
|
56
|
+
rects?: true | MiddlewareState['rects'];
|
|
57
|
+
};
|
|
58
|
+
export interface MiddlewareResult {
|
|
59
|
+
x?: number;
|
|
60
|
+
y?: number;
|
|
61
|
+
placement?: Placement;
|
|
62
|
+
data?: MiddlewareData;
|
|
63
|
+
reset?: MiddlewareReset;
|
|
27
64
|
}
|
|
28
|
-
export
|
|
65
|
+
export type Middleware = (state: MiddlewareState) => MiddlewareResult | void;
|
|
66
|
+
export interface FloatOptions {
|
|
29
67
|
placement?: Placement;
|
|
30
68
|
middleware?: Array<Middleware | null | undefined | false>;
|
|
31
69
|
}
|
|
@@ -33,88 +71,69 @@ export interface ComputePositionResult {
|
|
|
33
71
|
x: number;
|
|
34
72
|
y: number;
|
|
35
73
|
placement: Placement;
|
|
74
|
+
middlewareData: MiddlewareData;
|
|
36
75
|
}
|
|
37
|
-
|
|
38
|
-
export
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
76
|
+
export type Cleanup = () => void;
|
|
77
|
+
export interface DetectOverflowOptions {
|
|
78
|
+
boundary?: Element | Rect;
|
|
79
|
+
padding?: Padding;
|
|
80
|
+
}
|
|
81
|
+
export declare function detectOverflow(state: MiddlewareState, options?: DetectOverflowOptions): SideObject;
|
|
82
|
+
export declare function computePosition(reference: ReferenceElement, floating: HTMLElement, { middleware, placement }?: FloatOptions): ComputePositionResult;
|
|
83
|
+
export type OffsetConfig = {
|
|
84
|
+
crossAxis?: number;
|
|
85
|
+
mainAxis?: number;
|
|
86
|
+
};
|
|
87
|
+
export type OffsetValue = number | OffsetConfig | ((state: MiddlewareState) => number | OffsetConfig);
|
|
88
|
+
export declare function offset(value: OffsetValue): Middleware;
|
|
89
|
+
export interface FlipOptions extends DetectOverflowOptions {
|
|
90
|
+
fallbackPlacements?: Placement[];
|
|
44
91
|
}
|
|
45
|
-
/** Flips the floating element to the opposite side when it would overflow the viewport. */
|
|
46
92
|
export declare function flip(options?: FlipOptions): Middleware;
|
|
47
|
-
export interface
|
|
48
|
-
|
|
49
|
-
padding?: number;
|
|
93
|
+
export interface AutoPlacementOptions extends DetectOverflowOptions {
|
|
94
|
+
allowedPlacements?: Placement[];
|
|
50
95
|
}
|
|
51
|
-
|
|
96
|
+
export declare function autoPlacement(options?: AutoPlacementOptions): Middleware;
|
|
97
|
+
export type ShiftOptions = DetectOverflowOptions;
|
|
52
98
|
export declare function shift(options?: ShiftOptions): Middleware;
|
|
53
99
|
export interface SizeApplyArgs {
|
|
54
100
|
availableWidth: number;
|
|
55
101
|
availableHeight: number;
|
|
56
102
|
elements: {
|
|
57
103
|
floating: HTMLElement;
|
|
58
|
-
reference:
|
|
104
|
+
reference: ReferenceElement;
|
|
59
105
|
};
|
|
60
106
|
}
|
|
61
|
-
export interface SizeOptions {
|
|
62
|
-
/** Minimum distance to maintain from the viewport edges (px). */
|
|
63
|
-
padding?: number;
|
|
64
|
-
/** Called with available dimensions — use to resize the floating element. */
|
|
107
|
+
export interface SizeOptions extends DetectOverflowOptions {
|
|
65
108
|
apply?: (args: SizeApplyArgs) => void;
|
|
66
109
|
}
|
|
67
|
-
/** Provides available width/height based on actual float position and optionally resizes the floating element. */
|
|
68
110
|
export declare function size(options?: SizeOptions): Middleware;
|
|
111
|
+
export interface ArrowOptions {
|
|
112
|
+
element: HTMLElement;
|
|
113
|
+
padding?: Padding;
|
|
114
|
+
}
|
|
115
|
+
export declare function arrow({ element, padding }: ArrowOptions): Middleware;
|
|
116
|
+
export interface HideOptions extends DetectOverflowOptions {
|
|
117
|
+
strategy?: 'referenceHidden' | 'escaped' | 'both';
|
|
118
|
+
}
|
|
119
|
+
export declare function hide(options?: HideOptions): Middleware;
|
|
120
|
+
export interface InlineOptions {
|
|
121
|
+
x?: number;
|
|
122
|
+
y?: number;
|
|
123
|
+
padding?: Padding;
|
|
124
|
+
}
|
|
125
|
+
export declare function inline(options?: InlineOptions): Middleware;
|
|
69
126
|
export interface AutoUpdateOptions {
|
|
70
|
-
/**
|
|
71
|
-
* Whether to observe size changes on the floating element itself.
|
|
72
|
-
* Set to `false` for virtual-scroll dropdowns whose outer dimensions are
|
|
73
|
-
* managed entirely by the caller (e.g. width set via `size()` middleware),
|
|
74
|
-
* to avoid a ResizeObserver feedback loop.
|
|
75
|
-
* Defaults to `true`.
|
|
76
|
-
*/
|
|
77
127
|
observeFloating?: boolean;
|
|
78
|
-
/**
|
|
79
|
-
* Whether to observe `window.visualViewport` resize/scroll changes.
|
|
80
|
-
* Helps keep floating UI aligned during pinch-zoom and virtual keyboard changes.
|
|
81
|
-
* Defaults to `true`.
|
|
82
|
-
*/
|
|
83
128
|
observeVisualViewport?: boolean;
|
|
129
|
+
animationFrame?: boolean;
|
|
84
130
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
export declare function autoUpdate(reference: Element, floating: HTMLElement, update: () => void, { observeFloating, observeVisualViewport }?: AutoUpdateOptions): () => void;
|
|
92
|
-
export interface FloatOptions {
|
|
93
|
-
/** Preferred placement relative to the reference element. */
|
|
94
|
-
placement?: Placement;
|
|
95
|
-
/** Middleware to modify positioning behavior. */
|
|
96
|
-
middleware?: Array<Middleware | null | undefined | false>;
|
|
131
|
+
export declare function autoUpdate(reference: ReferenceElement, floating: HTMLElement, update: () => void, { animationFrame, observeFloating, observeVisualViewport }?: AutoUpdateOptions): Cleanup;
|
|
132
|
+
export interface FloatRuntimeOptions extends FloatOptions, AutoUpdateOptions {
|
|
133
|
+
apply?: (result: ComputePositionResult, elements: {
|
|
134
|
+
floating: HTMLElement;
|
|
135
|
+
reference: ReferenceElement;
|
|
136
|
+
}) => void;
|
|
97
137
|
}
|
|
98
|
-
|
|
99
|
-
* Computes and applies the floating position to a floating element.
|
|
100
|
-
* Sets `left`/`top` inline styles and returns the resolved placement.
|
|
101
|
-
*/
|
|
102
|
-
export declare function positionFloat(reference: Element, floating: HTMLElement, options?: FloatOptions): Placement;
|
|
103
|
-
/**
|
|
104
|
-
* Positions a floating element relative to a reference element and keeps it in
|
|
105
|
-
* sync as the viewport or elements change. Returns a cleanup function.
|
|
106
|
-
*
|
|
107
|
-
* @example
|
|
108
|
-
* ```ts
|
|
109
|
-
* const cleanup = float(trigger, tooltip, {
|
|
110
|
-
* placement: 'top',
|
|
111
|
-
* middleware: [offset(8), flip(), shift({ padding: 6 })],
|
|
112
|
-
* });
|
|
113
|
-
*
|
|
114
|
-
* // When done:
|
|
115
|
-
* cleanup();
|
|
116
|
-
* ```
|
|
117
|
-
*/
|
|
118
|
-
export declare function float(reference: Element, floating: HTMLElement, options?: FloatOptions): () => void;
|
|
119
|
-
export {};
|
|
138
|
+
export declare function float(reference: ReferenceElement, floating: HTMLElement, { animationFrame, apply, middleware, observeFloating, observeVisualViewport, placement, }?: FloatRuntimeOptions): Cleanup;
|
|
120
139
|
//# sourceMappingURL=floatit.d.ts.map
|
package/dist/floatit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floatit.d.ts","sourceRoot":"","sources":["../src/floatit.ts"],"names":[],"mappings":"AAAA,oEAAoE;
|
|
1
|
+
{"version":3,"file":"floatit.d.ts","sourceRoot":"","sources":["../src/floatit.ts"],"names":[],"mappings":"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"}
|
package/dist/floatit.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e={bottom:`top`,left:`right`,right:`left`,top:`bottom`};function t(e){return e.split(`-`)[0]}function n(e){return e.split(`-`)[1]??null}function r({height:e,width:t,x:n,y:r}){return{height:e,width:t,x:n,y:r}}function i(e,t,n,r){return e===`start`?t:e===`end`?t+n-r:t+(n-r)/2}function
|
|
1
|
+
var e={bottom:`top`,left:`right`,right:`left`,top:`bottom`};function t(e){return e.split(`-`)[0]}function n(e){return e.split(`-`)[1]??null}function r(e,t){return t?`${e}-${t}`:e}function i({height:e,width:t,x:n,y:r}){return{height:e,width:t,x:n,y:r}}function a(e=0){return typeof e==`number`?{bottom:e,left:e,right:e,top:e}:{bottom:e.bottom??0,left:e.left??0,right:e.right??0,top:e.top??0}}function o(){let e=window.visualViewport;return e?{height:e.height,width:e.width,x:e.offsetLeft,y:e.offsetTop}:{height:window.innerHeight,width:window.innerWidth,x:0,y:0}}function s(e){return e?`getBoundingClientRect`in e?i(e.getBoundingClientRect()):e:o()}function c(e,t){return{floating:i(t.getBoundingClientRect()),reference:i(e.getBoundingClientRect())}}function l(e,t,n){return Math.min(Math.max(e,t),n)}function u(e,t,n,r){return e===`start`?t:e===`end`?t+n-r:t+(n-r)/2}function d(e,r,i){let a=t(e),o=n(e);switch(a){case`bottom`:return{x:u(o,r.x,r.width,i.width),y:r.y+r.height};case`left`:return{x:r.x-i.width,y:u(o,r.y,r.height,i.height)};case`right`:return{x:r.x+r.width,y:u(o,r.y,r.height,i.height)};case`top`:return{x:u(o,r.x,r.width,i.width),y:r.y-i.height}}}function f(e){return{...e.rects.floating,x:e.x,y:e.y}}function p(e,t){return t?{...e,middlewareData:t.data?{...e.middlewareData,...t.data}:e.middlewareData,placement:t.placement??e.placement,x:t.x??e.x,y:t.y??e.y}:e}function m(e){return Math.max(e.top,0)+Math.max(e.right,0)+Math.max(e.bottom,0)+Math.max(e.left,0)}function h(e){return e.top>0||e.right>0||e.bottom>0||e.left>0}function g(e,n,r,i){let a=e.rects.reference,o=t(n),s=r.y+i.top,c=r.x+r.width-i.right,l=r.y+r.height-i.bottom,u=r.x+i.left;switch(o){case`bottom`:return l-(a.y+a.height);case`left`:return a.x-u;case`right`:return c-(a.x+a.width);case`top`:return a.y-s}}function _(e,t){return t.top>=e.height||t.right>=e.width||t.bottom>=e.height||t.left>=e.width}function v(e){return!(`getClientRects`in e)||typeof e.getClientRects!=`function`?[]:Array.from(e.getClientRects()).map(e=>i(e)).filter(e=>e.width>0||e.height>0)}function y(e){return typeof Element<`u`&&e instanceof Element}function b(e,t,n,r){return t>=e.x-r.left&&t<=e.x+e.width+r.right&&n>=e.y-r.top&&n<=e.y+e.height+r.bottom}function x(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function S(e,t,n){return{bottom:e.y+e.height-(t.y+t.height-n.bottom),left:t.x+n.left-e.x,right:e.x+e.width-(t.x+t.width-n.right),top:t.y+n.top-e.y}}function C(e,t={}){let n=s(t.boundary),r=a(t.padding);return S(f(e),n,r)}function w(e,t,n={}){let{x:r,y:i}=d(t,e.rects.reference,e.rects.floating),o=s(n.boundary),c=a(n.padding);return S({...e.rects.floating,x:r,y:i},o,c)}function T(e,t,{middleware:n=[],placement:r=`bottom`}={}){let i=n.filter(Boolean),a=r,o={},s=c(e,t);for(let n=0;n<50;n+=1){let n={...d(a,s.reference,s.floating),elements:{floating:t,reference:e},initialPlacement:r,middlewareData:o,placement:a,rects:s},l;for(let e of i){let t=e(n);if(n=p(n,t),o=n.middlewareData,l=t?.reset,l)break}if(!l)return{middlewareData:n.middlewareData,placement:n.placement,x:n.x,y:n.y};l.rects===!0?s=c(e,t):l.rects&&(s=l.rects),a=l.placement??n.placement}throw Error(`[floatit] Middleware triggered too many resets in a single compute cycle.`)}function E(e,t){let n=typeof e==`function`?e(t):e;return typeof n==`number`?{crossAxis:0,mainAxis:n}:{crossAxis:n.crossAxis??0,mainAxis:n.mainAxis??0}}function D(e){return n=>{let r=t(n.placement),{crossAxis:i,mainAxis:a}=E(e,n);switch(r){case`bottom`:return{x:n.x+i,y:n.y+a};case`left`:return{x:n.x-a,y:n.y+i};case`right`:return{x:n.x+a,y:n.y+i};case`top`:return{x:n.x+i,y:n.y-a}}}}function O(i={}){return a=>{let o=C(a,i);if(!h(o))return;let s=t(a.placement),c=n(a.placement),l=i.fallbackPlacements??[r(e[s],c)],u=a.placement,d=m(o);for(let e of l){let t=w(a,e,i),n=m(t);if(!h(t))return{placement:e,reset:{placement:e}};n<d&&(u=e,d=n)}if(u!==a.placement)return{placement:u,reset:{placement:u}}}}function k(e={}){return t=>{let n=a(e.padding),r=s(e.boundary),i=e.allowedPlacements??[`top`,`right`,`bottom`,`left`],o=t.placement,c=1/0,l=-1/0;for(let a of i){let i=m(w(t,a,e)),s=g(t,a,r,n);(i<c||i===c&&s>l)&&(o=a,c=i,l=s)}if(o!==t.placement)return{placement:o,reset:{placement:o}}}}function A(e={}){return t=>{let n=C(t,e);return{x:t.x+Math.max(n.left,0)-Math.max(n.right,0),y:t.y+Math.max(n.top,0)-Math.max(n.bottom,0)}}}function j(e={}){let{apply:n}=e;return r=>{let i=s(e.boundary),o=a(e.padding),c=t(r.placement),l=i.y+o.top,u=i.x+i.width-o.right,d=i.y+i.height-o.bottom,f=i.x+o.left,p=c===`bottom`?Math.max(0,d-r.y):c===`top`?Math.max(0,r.rects.reference.y-l):Math.max(0,d-l),m=c===`right`?Math.max(0,u-r.x):c===`left`?Math.max(0,r.rects.reference.x-f):Math.max(0,u-f);n?.({availableHeight:p,availableWidth:m,elements:r.elements})}}function M({element:e,padding:n=0}){return r=>{let o=t(r.placement),s=a(n),c=i(e.getBoundingClientRect());if(o===`top`||o===`bottom`){let e=r.rects.reference.x+r.rects.reference.width/2-r.x-c.width/2,t=s.left,n=l(e,t,Math.max(t,r.rects.floating.width-c.width-s.right));return{data:{arrow:{centerOffset:e-n,x:n}}}}let u=r.rects.reference.y+r.rects.reference.height/2-r.y-c.height/2,d=s.top,f=l(u,d,Math.max(d,r.rects.floating.height-c.height-s.bottom));return{data:{arrow:{centerOffset:u-f,y:f}}}}}function N(e={}){let t=e.strategy??`both`;return n=>{let r=s(e.boundary),i=a(e.padding),o={};if(t===`escaped`||t===`both`){let e=S(f(n),r,i);o.escaped=_(f(n),e),o.escapedOffsets=e}if(t===`referenceHidden`||t===`both`){let e=S(n.rects.reference,r,i);o.referenceHidden=_(n.rects.reference,e),o.referenceHiddenOffsets=e}return{data:{hide:o}}}}function P(e={}){return n=>{let r=v(n.elements.reference);if(r.length<=1)return;let i=a(e.padding??2),o=t(n.placement),s=r[0];if(e.x!=null&&e.y!=null)s=r.find(t=>b(t,e.x,e.y,i))??s;else if(o===`top`||o===`bottom`){let e=n.x+n.rects.floating.width/2;s=r.reduce((t,n)=>{let r=Math.abs(t.x+t.width/2-e);return Math.abs(n.x+n.width/2-e)<r?n:t},s)}else{let e=n.y+n.rects.floating.height/2;s=r.reduce((t,n)=>{let r=Math.abs(t.y+t.height/2-e);return Math.abs(n.y+n.height/2-e)<r?n:t},s)}if(!x(s,n.rects.reference))return{reset:{rects:{...n.rects,reference:s}}}}}function F(e,t,n,{animationFrame:r=!1,observeFloating:i=!0,observeVisualViewport:a=!0}={}){n();let o=e=>{e.composedPath().includes(t)||n()};window.addEventListener(`scroll`,o,{capture:!0,passive:!0}),window.addEventListener(`resize`,n,{passive:!0});let s=a?window.visualViewport:null;s?.addEventListener(`resize`,n,{passive:!0}),s?.addEventListener(`scroll`,n,{passive:!0});let c=new ResizeObserver(n);y(e)&&c.observe(e),i&&c.observe(t);let l=0;if(r){let e=()=>{n(),l=window.requestAnimationFrame(e)};l=window.requestAnimationFrame(e)}return()=>{window.removeEventListener(`scroll`,o,{capture:!0}),window.removeEventListener(`resize`,n),s?.removeEventListener(`resize`,n),s?.removeEventListener(`scroll`,n),c.disconnect(),l&&window.cancelAnimationFrame(l)}}function I(e,t){t.floating.style.left=`${e.x}px`,t.floating.style.top=`${e.y}px`}function L(e,t,{animationFrame:n,apply:r=I,middleware:i,observeFloating:a,observeVisualViewport:o,placement:s}={}){return F(e,t,()=>{r(T(e,t,{middleware:i,placement:s}),{floating:t,reference:e})},{animationFrame:n,observeFloating:a,observeVisualViewport:o})}export{M as arrow,k as autoPlacement,F as autoUpdate,T as computePosition,C as detectOverflow,O as flip,L as float,N as hide,P as inline,D as offset,A as shift,j as size};
|
|
2
2
|
//# sourceMappingURL=floatit.js.map
|
package/dist/floatit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floatit.js","names":[],"sources":["../src/floatit.ts"],"sourcesContent":["/** @vielzeug/floatit — Lightweight floating element positioning. */\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type Side = 'top' | 'bottom' | 'left' | 'right';\nexport type Alignment = 'start' | 'end';\nexport type Placement = Side | `${Side}-${Alignment}`;\n\ninterface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface MiddlewareState {\n x: number;\n y: number;\n placement: Placement;\n rects: { floating: Rect; reference: Rect };\n elements: { floating: HTMLElement; reference: Element };\n}\n\nexport interface Middleware {\n name: string;\n fn: (state: MiddlewareState) => MiddlewareState;\n}\n\nexport interface ComputePositionConfig {\n placement?: Placement;\n middleware?: Array<Middleware | null | undefined | false>;\n}\n\nexport interface ComputePositionResult {\n x: number;\n y: number;\n placement: Placement;\n}\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\nconst OPPOSITE: Record<Side, Side> = { bottom: 'top', left: 'right', right: 'left', top: 'bottom' };\n\nfunction getSide(p: Placement): Side {\n return p.split('-')[0] as Side;\n}\n\nfunction getAlign(p: Placement): Alignment | null {\n return (p.split('-')[1] as Alignment) ?? null;\n}\n\nfunction toRect({ height, width, x, y }: DOMRect): Rect {\n return { height, width, x, y };\n}\n\nfunction alignedOffset(align: Alignment | null, refStart: number, refSize: number, floatSize: number): number {\n if (align === 'start') return refStart;\n\n if (align === 'end') return refStart + refSize - floatSize;\n\n return refStart + (refSize - floatSize) / 2;\n}\n\nfunction baseCoords(placement: Placement, ref: Rect, float: Rect): { x: number; y: number } {\n const side = getSide(placement);\n const align = getAlign(placement);\n\n if (side === 'top') return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y - float.height };\n\n if (side === 'bottom') return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y + ref.height };\n\n if (side === 'left') return { x: ref.x - float.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n\n /* right */ return { x: ref.x + ref.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n}\n\n// ─── Pipeline ─────────────────────────────────────────────────────────────────\n\nfunction runPipeline(\n mws: Middleware[],\n placement: Placement,\n reference: Element,\n floating: HTMLElement,\n): ComputePositionResult {\n const refRect = toRect(reference.getBoundingClientRect());\n const floatRect = toRect(floating.getBoundingClientRect());\n let state: MiddlewareState = {\n ...baseCoords(placement, refRect, floatRect),\n elements: { floating, reference },\n placement,\n rects: { floating: floatRect, reference: refRect },\n };\n\n for (const mw of mws) state = mw.fn(state);\n\n // If a middleware (e.g. flip) changed the placement, restart once with the new one.\n if (state.placement !== placement) {\n return runPipeline(mws, state.placement, reference, floating);\n }\n\n return { placement: state.placement, x: state.x, y: state.y };\n}\n\n// ─── computePosition ──────────────────────────────────────────────────────────\n\n/** Computes the position of a floating element relative to a reference element. */\nexport function computePosition(\n reference: Element,\n floating: HTMLElement,\n config: ComputePositionConfig = {},\n): ComputePositionResult {\n const { middleware = [], placement = 'bottom' } = config;\n\n return runPipeline(middleware.filter(Boolean) as Middleware[], placement, reference, floating);\n}\n\n// ─── Middlewares ──────────────────────────────────────────────────────────────\n\n/** Adds a gap (in px) between the reference and the floating element. */\nexport function offset(value: number): Middleware {\n return {\n fn(state) {\n const side = getSide(state.placement);\n\n return {\n ...state,\n x: state.x + (side === 'right' ? value : side === 'left' ? -value : 0),\n y: state.y + (side === 'bottom' ? value : side === 'top' ? -value : 0),\n };\n },\n name: 'offset',\n };\n}\n\nexport interface FlipOptions {\n /** Minimum distance from the viewport edge before flipping (px). */\n padding?: number;\n}\n\n/** Flips the floating element to the opposite side when it would overflow the viewport. */\nexport function flip(options: FlipOptions = {}): Middleware {\n const { padding = 0 } = options;\n\n return {\n fn(state) {\n const {\n placement,\n rects: { floating },\n x,\n y,\n } = state;\n const side = getSide(placement);\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const overflows =\n (side === 'top' && y < padding) ||\n (side === 'bottom' && y + floating.height > vh - padding) ||\n (side === 'left' && x < padding) ||\n (side === 'right' && x + floating.width > vw - padding);\n\n if (!overflows) return state;\n\n const align = getAlign(placement);\n const opp = OPPOSITE[side];\n const flipped = (align ? `${opp}-${align}` : opp) as Placement;\n\n return { ...state, placement: flipped };\n },\n name: 'flip',\n };\n}\n\nexport interface ShiftOptions {\n /** Minimum distance to maintain from the viewport edges (px). */\n padding?: number;\n}\n\n/** Shifts the floating element along its axis to keep it within the viewport. */\nexport function shift(options: ShiftOptions = {}): Middleware {\n const { padding = 0 } = options;\n\n return {\n fn(state) {\n const {\n rects: { floating },\n x,\n y,\n } = state;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n return {\n ...state,\n x: Math.min(Math.max(x, padding), vw - floating.width - padding),\n y: Math.min(Math.max(y, padding), vh - floating.height - padding),\n };\n },\n name: 'shift',\n };\n}\n\nexport interface SizeApplyArgs {\n availableWidth: number;\n availableHeight: number;\n elements: { floating: HTMLElement; reference: Element };\n}\n\nexport interface SizeOptions {\n /** Minimum distance to maintain from the viewport edges (px). */\n padding?: number;\n /** Called with available dimensions — use to resize the floating element. */\n apply?: (args: SizeApplyArgs) => void;\n}\n\n/** Provides available width/height based on actual float position and optionally resizes the floating element. */\nexport function size(options: SizeOptions = {}): Middleware {\n const { apply, padding = 0 } = options;\n\n return {\n fn(state) {\n const {\n placement,\n rects: { floating },\n x,\n y,\n } = state;\n const side = getSide(placement);\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const availableHeight =\n side === 'bottom' ? vh - y - padding : side === 'top' ? y + floating.height - padding : vh - padding * 2;\n\n const availableWidth =\n side === 'right' ? vw - x - padding : side === 'left' ? x + floating.width - padding : vw - padding * 2;\n\n apply?.({ availableHeight, availableWidth, elements: state.elements });\n\n return state;\n },\n name: 'size',\n };\n}\n\n// ─── autoUpdate ───────────────────────────────────────────────────────────────\n\nexport interface AutoUpdateOptions {\n /**\n * Whether to observe size changes on the floating element itself.\n * Set to `false` for virtual-scroll dropdowns whose outer dimensions are\n * managed entirely by the caller (e.g. width set via `size()` middleware),\n * to avoid a ResizeObserver feedback loop.\n * Defaults to `true`.\n */\n observeFloating?: boolean;\n /**\n * Whether to observe `window.visualViewport` resize/scroll changes.\n * Helps keep floating UI aligned during pinch-zoom and virtual keyboard changes.\n * Defaults to `true`.\n */\n observeVisualViewport?: boolean;\n}\n\n/**\n * Automatically calls `update` whenever the floating element's position may have\n * changed (viewport resize, scroll events, or reference / floating element resize).\n * Calls `update` once immediately on registration.\n * Returns a cleanup function.\n */\nexport function autoUpdate(\n reference: Element,\n floating: HTMLElement,\n update: () => void,\n { observeFloating = true, observeVisualViewport = true }: AutoUpdateOptions = {},\n): () => void {\n update();\n\n // Use composedPath() instead of e.target — shadow DOM retargets e.target to\n // the shadow host at the window listener boundary.\n const scrollHandler = (e: Event) => {\n if (e.composedPath().includes(floating)) return;\n\n update();\n };\n\n window.addEventListener('scroll', scrollHandler, { capture: true, passive: true });\n window.addEventListener('resize', update, { passive: true });\n\n const vv = observeVisualViewport ? window.visualViewport : null;\n\n vv?.addEventListener('resize', update, { passive: true });\n vv?.addEventListener('scroll', update, { passive: true });\n\n const ro = new ResizeObserver(update);\n\n ro.observe(reference);\n\n if (observeFloating) ro.observe(floating);\n\n return () => {\n window.removeEventListener('scroll', scrollHandler, { capture: true } as EventListenerOptions);\n window.removeEventListener('resize', update);\n vv?.removeEventListener('resize', update);\n vv?.removeEventListener('scroll', update);\n ro.disconnect();\n };\n}\n\n// ─── positionFloat / float ────────────────────────────────────────────────────\n\nexport interface FloatOptions {\n /** Preferred placement relative to the reference element. */\n placement?: Placement;\n /** Middleware to modify positioning behavior. */\n middleware?: Array<Middleware | null | undefined | false>;\n}\n\n/**\n * Computes and applies the floating position to a floating element.\n * Sets `left`/`top` inline styles and returns the resolved placement.\n */\nexport function positionFloat(reference: Element, floating: HTMLElement, options: FloatOptions = {}): Placement {\n const { placement, x, y } = computePosition(reference, floating, options);\n\n floating.style.left = `${x}px`;\n floating.style.top = `${y}px`;\n\n return placement;\n}\n\n/**\n * Positions a floating element relative to a reference element and keeps it in\n * sync as the viewport or elements change. Returns a cleanup function.\n *\n * @example\n * ```ts\n * const cleanup = float(trigger, tooltip, {\n * placement: 'top',\n * middleware: [offset(8), flip(), shift({ padding: 6 })],\n * });\n *\n * // When done:\n * cleanup();\n * ```\n */\nexport function float(reference: Element, floating: HTMLElement, options: FloatOptions = {}): () => void {\n return autoUpdate(reference, floating, () => positionFloat(reference, floating, options));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"floatit.js","names":[],"sources":["../src/floatit.ts"],"sourcesContent":["/** @vielzeug/floatit - Lightweight floating element positioning. */\n\nexport type Side = 'top' | 'bottom' | 'left' | 'right';\nexport type Alignment = 'start' | 'end';\nexport type Placement = Side | `${Side}-${Alignment}`;\n\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface VirtualReference {\n getBoundingClientRect: () => DOMRect | Rect;\n getClientRects?: () => DOMRectList | DOMRect[];\n}\n\nexport type ReferenceElement = Element | VirtualReference;\n\nexport interface SideObject {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\nexport type Padding = number | Partial<SideObject>;\ntype Boundary = Element | Rect;\n\nexport interface ArrowData {\n x?: number;\n y?: number;\n centerOffset: number;\n}\n\nexport interface HideData {\n escaped?: boolean;\n escapedOffsets?: SideObject;\n referenceHidden?: boolean;\n referenceHiddenOffsets?: SideObject;\n}\n\nexport interface MiddlewareData {\n arrow?: ArrowData;\n hide?: HideData;\n [key: string]: unknown;\n}\n\nexport interface MiddlewareState {\n x: number;\n y: number;\n initialPlacement: Placement;\n placement: Placement;\n rects: { floating: Rect; reference: Rect };\n elements: { floating: HTMLElement; reference: ReferenceElement };\n middlewareData: MiddlewareData;\n}\n\nexport type MiddlewareReset = {\n placement?: Placement;\n rects?: true | MiddlewareState['rects'];\n};\n\nexport interface MiddlewareResult {\n x?: number;\n y?: number;\n placement?: Placement;\n data?: MiddlewareData;\n reset?: MiddlewareReset;\n}\n\nexport type Middleware = (state: MiddlewareState) => MiddlewareResult | void;\n\nexport interface FloatOptions {\n placement?: Placement;\n middleware?: Array<Middleware | null | undefined | false>;\n}\n\nexport interface ComputePositionResult {\n x: number;\n y: number;\n placement: Placement;\n middlewareData: MiddlewareData;\n}\n\nexport type Cleanup = () => void;\n\nconst OPPOSITE: Record<Side, Side> = { bottom: 'top', left: 'right', right: 'left', top: 'bottom' };\n\nfunction getSide(p: Placement): Side {\n return p.split('-')[0] as Side;\n}\n\nfunction getAlign(p: Placement): Alignment | null {\n return (p.split('-')[1] as Alignment) ?? null;\n}\n\nfunction withPlacement(side: Side, align: Alignment | null): Placement {\n return (align ? `${side}-${align}` : side) as Placement;\n}\n\nfunction toRect({ height, width, x, y }: DOMRect | Rect): Rect {\n return { height, width, x, y };\n}\n\nfunction toSideObject(padding: Padding = 0): SideObject {\n if (typeof padding === 'number') {\n return { bottom: padding, left: padding, right: padding, top: padding };\n }\n\n return {\n bottom: padding.bottom ?? 0,\n left: padding.left ?? 0,\n right: padding.right ?? 0,\n top: padding.top ?? 0,\n };\n}\n\nfunction getViewportRect(): Rect {\n const vv = window.visualViewport;\n\n if (vv) return { height: vv.height, width: vv.width, x: vv.offsetLeft, y: vv.offsetTop };\n\n return { height: window.innerHeight, width: window.innerWidth, x: 0, y: 0 };\n}\n\nfunction getBoundaryRect(boundary?: Boundary): Rect {\n if (!boundary) return getViewportRect();\n\n if ('getBoundingClientRect' in boundary) return toRect(boundary.getBoundingClientRect());\n\n return boundary;\n}\n\nfunction getRects(reference: ReferenceElement, floating: HTMLElement): MiddlewareState['rects'] {\n return {\n floating: toRect(floating.getBoundingClientRect()),\n reference: toRect(reference.getBoundingClientRect()),\n };\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction alignedOffset(align: Alignment | null, refStart: number, refSize: number, floatSize: number): number {\n if (align === 'start') return refStart;\n\n if (align === 'end') return refStart + refSize - floatSize;\n\n return refStart + (refSize - floatSize) / 2;\n}\n\nfunction baseCoords(placement: Placement, ref: Rect, float: Rect): { x: number; y: number } {\n const side = getSide(placement);\n const align = getAlign(placement);\n\n switch (side) {\n case 'bottom':\n return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y + ref.height };\n case 'left':\n return { x: ref.x - float.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n case 'right':\n return { x: ref.x + ref.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n case 'top':\n return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y - float.height };\n }\n}\n\nfunction getFloatingRect(state: MiddlewareState): Rect {\n return { ...state.rects.floating, x: state.x, y: state.y };\n}\n\nfunction mergeState(state: MiddlewareState, result: MiddlewareResult | void): MiddlewareState {\n if (!result) return state;\n\n return {\n ...state,\n middlewareData: result.data ? { ...state.middlewareData, ...result.data } : state.middlewareData,\n placement: result.placement ?? state.placement,\n x: result.x ?? state.x,\n y: result.y ?? state.y,\n };\n}\n\nfunction totalOverflow(overflow: SideObject): number {\n return (\n Math.max(overflow.top, 0) + Math.max(overflow.right, 0) + Math.max(overflow.bottom, 0) + Math.max(overflow.left, 0)\n );\n}\n\nfunction hasOverflow(overflow: SideObject): boolean {\n return overflow.top > 0 || overflow.right > 0 || overflow.bottom > 0 || overflow.left > 0;\n}\n\nfunction getAvailableSpace(state: MiddlewareState, placement: Placement, boundary: Rect, padding: SideObject): number {\n const refRect = state.rects.reference;\n const side = getSide(placement);\n const boundaryTop = boundary.y + padding.top;\n const boundaryRight = boundary.x + boundary.width - padding.right;\n const boundaryBottom = boundary.y + boundary.height - padding.bottom;\n const boundaryLeft = boundary.x + padding.left;\n\n switch (side) {\n case 'bottom':\n return boundaryBottom - (refRect.y + refRect.height);\n case 'left':\n return refRect.x - boundaryLeft;\n case 'right':\n return boundaryRight - (refRect.x + refRect.width);\n case 'top':\n return refRect.y - boundaryTop;\n }\n}\n\nfunction isFullyClipped(rect: Rect, overflow: SideObject): boolean {\n return (\n overflow.top >= rect.height ||\n overflow.right >= rect.width ||\n overflow.bottom >= rect.height ||\n overflow.left >= rect.width\n );\n}\n\nfunction getClientRects(reference: ReferenceElement): Rect[] {\n if (!('getClientRects' in reference) || typeof reference.getClientRects !== 'function') return [];\n\n return Array.from(reference.getClientRects())\n .map((rect) => toRect(rect))\n .filter((rect) => rect.width > 0 || rect.height > 0);\n}\n\nfunction isElement(value: unknown): value is Element {\n return typeof Element !== 'undefined' && value instanceof Element;\n}\n\nfunction rectContainsPoint(rect: Rect, x: number, y: number, padding: SideObject): 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\nfunction detectOverflowAtRect(rect: Rect, boundary: Rect, padding: SideObject): SideObject {\n return {\n bottom: rect.y + rect.height - (boundary.y + boundary.height - padding.bottom),\n left: boundary.x + padding.left - rect.x,\n right: rect.x + rect.width - (boundary.x + boundary.width - padding.right),\n top: boundary.y + padding.top - rect.y,\n };\n}\n\nexport interface DetectOverflowOptions {\n boundary?: Element | Rect;\n padding?: Padding;\n}\n\nexport function detectOverflow(state: MiddlewareState, options: DetectOverflowOptions = {}): SideObject {\n const boundary = getBoundaryRect(options.boundary);\n const padding = toSideObject(options.padding);\n\n return detectOverflowAtRect(getFloatingRect(state), boundary, padding);\n}\n\nfunction getPlacementOverflow(\n state: MiddlewareState,\n placement: Placement,\n options: DetectOverflowOptions = {},\n): SideObject {\n const { x, y } = baseCoords(placement, state.rects.reference, state.rects.floating);\n const boundary = getBoundaryRect(options.boundary);\n const padding = toSideObject(options.padding);\n const rect = { ...state.rects.floating, x, y };\n\n return detectOverflowAtRect(rect, boundary, padding);\n}\n\nexport function computePosition(\n reference: ReferenceElement,\n floating: HTMLElement,\n { middleware = [], placement = 'bottom' }: FloatOptions = {},\n): ComputePositionResult {\n const mws = middleware.filter(Boolean) as Middleware[];\n let currentPlacement = placement;\n let middlewareData: MiddlewareData = {};\n let rects = getRects(reference, floating);\n\n for (let resets = 0; resets < 50; resets += 1) {\n let state: MiddlewareState = {\n ...baseCoords(currentPlacement, rects.reference, rects.floating),\n elements: { floating, reference },\n initialPlacement: placement,\n middlewareData,\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 return { middlewareData: state.middlewareData, placement: state.placement, x: state.x, y: state.y };\n }\n\n if (reset.rects === true) {\n rects = getRects(reference, floating);\n } else if (reset.rects) {\n rects = reset.rects;\n }\n\n currentPlacement = reset.placement ?? state.placement;\n }\n\n throw new Error('[floatit] Middleware triggered too many resets in a single compute cycle.');\n}\n\nexport type OffsetConfig = {\n crossAxis?: number;\n mainAxis?: number;\n};\n\nexport type OffsetValue = number | OffsetConfig | ((state: MiddlewareState) => number | OffsetConfig);\n\nfunction resolveOffsetConfig(value: OffsetValue, state: MiddlewareState): Required<OffsetConfig> {\n const raw = typeof value === 'function' ? value(state) : value;\n\n if (typeof raw === 'number') {\n return { crossAxis: 0, mainAxis: raw };\n }\n\n return {\n crossAxis: raw.crossAxis ?? 0,\n mainAxis: raw.mainAxis ?? 0,\n };\n}\n\nexport function offset(value: OffsetValue): Middleware {\n return (state) => {\n const side = getSide(state.placement);\n const { crossAxis, mainAxis } = resolveOffsetConfig(value, state);\n\n switch (side) {\n case 'bottom':\n return { x: state.x + crossAxis, y: state.y + mainAxis };\n case 'left':\n return { x: state.x - mainAxis, y: state.y + crossAxis };\n case 'right':\n return { x: state.x + mainAxis, y: state.y + crossAxis };\n case 'top':\n return { x: state.x + crossAxis, y: state.y - mainAxis };\n }\n };\n}\n\nexport interface FlipOptions extends DetectOverflowOptions {\n fallbackPlacements?: Placement[];\n}\n\nexport function flip(options: FlipOptions = {}): Middleware {\n return (state) => {\n const currentOverflow = detectOverflow(state, options);\n\n if (!hasOverflow(currentOverflow)) return;\n\n const side = getSide(state.placement);\n const align = getAlign(state.placement);\n const fallbackPlacements = options.fallbackPlacements ?? [withPlacement(OPPOSITE[side], align)];\n let bestPlacement = state.placement;\n let bestScore = totalOverflow(currentOverflow);\n\n for (const candidate of fallbackPlacements) {\n const candidateOverflow = getPlacementOverflow(state, candidate, options);\n const score = totalOverflow(candidateOverflow);\n\n if (!hasOverflow(candidateOverflow)) {\n return { placement: candidate, reset: { placement: candidate } };\n }\n\n if (score < bestScore) {\n bestPlacement = candidate;\n bestScore = score;\n }\n }\n\n if (bestPlacement !== state.placement) {\n return { placement: bestPlacement, reset: { placement: bestPlacement } };\n }\n };\n}\n\nexport interface AutoPlacementOptions extends DetectOverflowOptions {\n allowedPlacements?: Placement[];\n}\n\nexport function autoPlacement(options: AutoPlacementOptions = {}): Middleware {\n return (state) => {\n const padding = toSideObject(options.padding);\n const boundary = getBoundaryRect(options.boundary);\n const placements = options.allowedPlacements ?? ['top', 'right', 'bottom', 'left'];\n let bestPlacement = state.placement;\n let bestOverflow = Number.POSITIVE_INFINITY;\n let bestSpace = Number.NEGATIVE_INFINITY;\n\n for (const candidate of placements) {\n const overflow = getPlacementOverflow(state, candidate, options);\n const overflowScore = totalOverflow(overflow);\n const availableSpace = getAvailableSpace(state, candidate, boundary, padding);\n\n if (overflowScore < bestOverflow || (overflowScore === bestOverflow && availableSpace > bestSpace)) {\n bestPlacement = candidate;\n bestOverflow = overflowScore;\n bestSpace = availableSpace;\n }\n }\n\n if (bestPlacement !== state.placement) {\n return { placement: bestPlacement, reset: { placement: bestPlacement } };\n }\n };\n}\n\nexport type ShiftOptions = DetectOverflowOptions;\n\nexport function shift(options: ShiftOptions = {}): Middleware {\n return (state) => {\n const overflow = detectOverflow(state, options);\n\n return {\n x: state.x + Math.max(overflow.left, 0) - Math.max(overflow.right, 0),\n y: state.y + Math.max(overflow.top, 0) - Math.max(overflow.bottom, 0),\n };\n };\n}\n\nexport interface SizeApplyArgs {\n availableWidth: number;\n availableHeight: number;\n elements: { floating: HTMLElement; reference: ReferenceElement };\n}\n\nexport interface SizeOptions extends DetectOverflowOptions {\n apply?: (args: SizeApplyArgs) => void;\n}\n\nexport function size(options: SizeOptions = {}): Middleware {\n const { apply } = options;\n\n return (state) => {\n const boundary = getBoundaryRect(options.boundary);\n const padding = toSideObject(options.padding);\n const side = getSide(state.placement);\n const top = boundary.y + padding.top;\n const right = boundary.x + boundary.width - padding.right;\n const bottom = boundary.y + boundary.height - padding.bottom;\n const left = boundary.x + padding.left;\n\n const availableHeight =\n side === 'bottom'\n ? Math.max(0, bottom - state.y)\n : side === 'top'\n ? Math.max(0, state.rects.reference.y - top)\n : Math.max(0, bottom - top);\n\n const availableWidth =\n side === 'right'\n ? Math.max(0, right - state.x)\n : side === 'left'\n ? Math.max(0, state.rects.reference.x - left)\n : Math.max(0, right - left);\n\n apply?.({ availableHeight, availableWidth, elements: state.elements });\n };\n}\n\nexport interface ArrowOptions {\n element: HTMLElement;\n padding?: Padding;\n}\n\nexport function arrow({ element, padding = 0 }: ArrowOptions): Middleware {\n return (state) => {\n const side = getSide(state.placement);\n const inset = toSideObject(padding);\n const arrowRect = toRect(element.getBoundingClientRect());\n\n if (side === 'top' || side === 'bottom') {\n const idealX = state.rects.reference.x + state.rects.reference.width / 2 - state.x - arrowRect.width / 2;\n const minX = inset.left;\n const maxX = Math.max(minX, state.rects.floating.width - arrowRect.width - inset.right);\n const x = clamp(idealX, minX, maxX);\n\n return { data: { arrow: { centerOffset: idealX - x, x } } };\n }\n\n const idealY = state.rects.reference.y + state.rects.reference.height / 2 - state.y - arrowRect.height / 2;\n const minY = inset.top;\n const maxY = Math.max(minY, state.rects.floating.height - arrowRect.height - inset.bottom);\n const y = clamp(idealY, minY, maxY);\n\n return { data: { arrow: { centerOffset: idealY - y, y } } };\n };\n}\n\nexport interface HideOptions extends DetectOverflowOptions {\n strategy?: 'referenceHidden' | 'escaped' | 'both';\n}\n\nexport function hide(options: HideOptions = {}): Middleware {\n const strategy = options.strategy ?? 'both';\n\n return (state) => {\n const boundary = getBoundaryRect(options.boundary);\n const padding = toSideObject(options.padding);\n const next: HideData = {};\n\n if (strategy === 'escaped' || strategy === 'both') {\n const escapedOffsets = detectOverflowAtRect(getFloatingRect(state), boundary, padding);\n\n next.escaped = isFullyClipped(getFloatingRect(state), escapedOffsets);\n next.escapedOffsets = escapedOffsets;\n }\n\n if (strategy === 'referenceHidden' || strategy === 'both') {\n const referenceHiddenOffsets = detectOverflowAtRect(state.rects.reference, boundary, padding);\n\n next.referenceHidden = isFullyClipped(state.rects.reference, referenceHiddenOffsets);\n next.referenceHiddenOffsets = referenceHiddenOffsets;\n }\n\n return { data: { hide: next } };\n };\n}\n\nexport interface InlineOptions {\n x?: number;\n y?: number;\n padding?: Padding;\n}\n\nexport function inline(options: InlineOptions = {}): Middleware {\n return (state) => {\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 bestDistance = Math.abs(best.x + best.width / 2 - targetX);\n const rectDistance = Math.abs(rect.x + rect.width / 2 - targetX);\n\n return rectDistance < bestDistance ? 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 bestDistance = Math.abs(best.y + best.height / 2 - targetY);\n const rectDistance = Math.abs(rect.y + rect.height / 2 - targetY);\n\n return rectDistance < bestDistance ? rect : best;\n }, nextRect);\n }\n\n if (sameRect(nextRect, state.rects.reference)) return;\n\n return {\n reset: {\n rects: { ...state.rects, reference: nextRect },\n },\n };\n };\n}\n\nexport interface AutoUpdateOptions {\n observeFloating?: boolean;\n observeVisualViewport?: boolean;\n animationFrame?: boolean;\n}\n\nexport function autoUpdate(\n reference: ReferenceElement,\n floating: HTMLElement,\n update: () => void,\n { animationFrame = false, observeFloating = true, observeVisualViewport = true }: AutoUpdateOptions = {},\n): Cleanup {\n update();\n\n const scrollHandler = (e: Event) => {\n if (e.composedPath().includes(floating)) return;\n\n update();\n };\n\n window.addEventListener('scroll', scrollHandler, { capture: true, passive: true });\n window.addEventListener('resize', update, { passive: true });\n\n const vv = observeVisualViewport ? window.visualViewport : null;\n\n vv?.addEventListener('resize', update, { passive: true });\n vv?.addEventListener('scroll', update, { passive: true });\n\n const ro = new ResizeObserver(update);\n\n if (isElement(reference)) ro.observe(reference);\n\n if (observeFloating) ro.observe(floating);\n\n let frameId = 0;\n\n if (animationFrame) {\n const frameLoop = () => {\n update();\n frameId = window.requestAnimationFrame(frameLoop);\n };\n\n frameId = window.requestAnimationFrame(frameLoop);\n }\n\n return () => {\n window.removeEventListener('scroll', scrollHandler, { capture: true });\n window.removeEventListener('resize', update);\n vv?.removeEventListener('resize', update);\n vv?.removeEventListener('scroll', update);\n ro.disconnect();\n\n if (frameId) window.cancelAnimationFrame(frameId);\n };\n}\n\nexport interface FloatRuntimeOptions extends FloatOptions, AutoUpdateOptions {\n apply?: (result: ComputePositionResult, elements: { floating: HTMLElement; reference: ReferenceElement }) => void;\n}\n\nfunction applyDefault(result: ComputePositionResult, elements: { floating: HTMLElement }): void {\n elements.floating.style.left = `${result.x}px`;\n elements.floating.style.top = `${result.y}px`;\n}\n\nexport function float(\n reference: ReferenceElement,\n floating: HTMLElement,\n {\n animationFrame,\n apply = applyDefault,\n middleware,\n observeFloating,\n observeVisualViewport,\n placement,\n }: FloatRuntimeOptions = {},\n): Cleanup {\n return autoUpdate(\n reference,\n floating,\n () => {\n const result = computePosition(reference, floating, { middleware, placement });\n\n apply(result, { floating, reference });\n },\n { animationFrame, observeFloating, observeVisualViewport },\n );\n}\n"],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./floatit.cjs`);exports.autoUpdate=e.autoUpdate,exports.computePosition=e.computePosition,exports.flip=e.flip,exports.float=e.float,exports.
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./floatit.cjs`);exports.arrow=e.arrow,exports.autoPlacement=e.autoPlacement,exports.autoUpdate=e.autoUpdate,exports.computePosition=e.computePosition,exports.detectOverflow=e.detectOverflow,exports.flip=e.flip,exports.float=e.float,exports.hide=e.hide,exports.inline=e.inline,exports.offset=e.offset,exports.shift=e.shift,exports.size=e.size;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{arrow as e,autoPlacement as t,autoUpdate as n,computePosition as r,detectOverflow as i,flip as a,float as o,hide as s,inline as c,offset as l,shift as u,size as d}from"./floatit.js";export{e as arrow,t as autoPlacement,n as autoUpdate,r as computePosition,i as detectOverflow,a as flip,o as float,s as hide,c as inline,l as offset,u as shift,d as size};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vielzeug/floatit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@types/node": "^25.
|
|
34
|
-
"typescript": "~6.0.
|
|
35
|
-
"vite": "^8.0.
|
|
36
|
-
"vitest": "^4.1.
|
|
33
|
+
"@types/node": "^25.8.0",
|
|
34
|
+
"typescript": "~6.0.3",
|
|
35
|
+
"vite": "^8.0.13",
|
|
36
|
+
"vitest": "^4.1.6"
|
|
37
37
|
}
|
|
38
38
|
}
|