@zag-js/popper 1.21.9 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +59 -39
- package/dist/index.mjs +60 -40
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -72,8 +72,10 @@ interface PositioningOptions {
|
|
|
72
72
|
fitViewport?: boolean | undefined;
|
|
73
73
|
/**
|
|
74
74
|
* The overflow boundary of the reference element
|
|
75
|
+
* Accepts a function returning a Boundary, a Boundary directly,
|
|
76
|
+
* or the shorthand string 'clipping-ancestors' which maps to Floating UI's 'clippingAncestors'.
|
|
75
77
|
*/
|
|
76
|
-
boundary?: (() => Boundary) | undefined;
|
|
78
|
+
boundary?: (() => Boundary) | Boundary | "clipping-ancestors" | undefined;
|
|
77
79
|
/**
|
|
78
80
|
* Options to activate auto-update listeners
|
|
79
81
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -72,8 +72,10 @@ interface PositioningOptions {
|
|
|
72
72
|
fitViewport?: boolean | undefined;
|
|
73
73
|
/**
|
|
74
74
|
* The overflow boundary of the reference element
|
|
75
|
+
* Accepts a function returning a Boundary, a Boundary directly,
|
|
76
|
+
* or the shorthand string 'clipping-ancestors' which maps to Floating UI's 'clippingAncestors'.
|
|
75
77
|
*/
|
|
76
|
-
boundary?: (() => Boundary) | undefined;
|
|
78
|
+
boundary?: (() => Boundary) | Boundary | "clipping-ancestors" | undefined;
|
|
77
79
|
/**
|
|
78
80
|
* Options to activate auto-update listeners
|
|
79
81
|
*/
|
package/dist/index.js
CHANGED
|
@@ -49,32 +49,46 @@ var cssVars = {
|
|
|
49
49
|
transformOrigin: toVar("--transform-origin"),
|
|
50
50
|
arrowOffset: toVar("--arrow-offset")
|
|
51
51
|
};
|
|
52
|
-
var
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
};
|
|
52
|
+
var getSideAxis = (side) => side === "top" || side === "bottom" ? "y" : "x";
|
|
53
|
+
function createTransformOriginMiddleware(opts, arrowEl) {
|
|
54
|
+
return {
|
|
55
|
+
name: "transformOrigin",
|
|
56
|
+
fn(state) {
|
|
57
|
+
const { elements, middlewareData, placement, rects, y } = state;
|
|
58
|
+
const side = placement.split("-")[0];
|
|
59
|
+
const axis = getSideAxis(side);
|
|
60
|
+
const arrowX = middlewareData.arrow?.x || 0;
|
|
61
|
+
const arrowY = middlewareData.arrow?.y || 0;
|
|
62
|
+
const arrowWidth = arrowEl?.clientWidth || 0;
|
|
63
|
+
const arrowHeight = arrowEl?.clientHeight || 0;
|
|
64
|
+
const transformX = arrowX + arrowWidth / 2;
|
|
65
|
+
const transformY = arrowY + arrowHeight / 2;
|
|
66
|
+
const shiftY = Math.abs(middlewareData.shift?.y || 0);
|
|
67
|
+
const halfAnchorHeight = rects.reference.height / 2;
|
|
68
|
+
const arrowOffset = arrowHeight / 2;
|
|
69
|
+
const gutter = opts.offset?.mainAxis ?? opts.gutter;
|
|
70
|
+
const sideOffsetValue = typeof gutter === "number" ? gutter + arrowOffset : gutter ?? arrowOffset;
|
|
71
|
+
const isOverlappingAnchor = shiftY > sideOffsetValue;
|
|
72
|
+
const adjacentTransformOrigin = {
|
|
73
|
+
top: `${transformX}px calc(100% + ${sideOffsetValue}px)`,
|
|
74
|
+
bottom: `${transformX}px ${-sideOffsetValue}px`,
|
|
75
|
+
left: `calc(100% + ${sideOffsetValue}px) ${transformY}px`,
|
|
76
|
+
right: `${-sideOffsetValue}px ${transformY}px`
|
|
77
|
+
}[side];
|
|
78
|
+
const overlapTransformOrigin = `${transformX}px ${rects.reference.y + halfAnchorHeight - y}px`;
|
|
79
|
+
const useOverlap = Boolean(opts.overlap) && axis === "y" && isOverlappingAnchor;
|
|
80
|
+
elements.floating.style.setProperty(
|
|
81
|
+
cssVars.transformOrigin.variable,
|
|
82
|
+
useOverlap ? overlapTransformOrigin : adjacentTransformOrigin
|
|
83
|
+
);
|
|
84
|
+
return {
|
|
85
|
+
data: {
|
|
86
|
+
transformOrigin: useOverlap ? overlapTransformOrigin : adjacentTransformOrigin
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
78
92
|
var rectMiddleware = {
|
|
79
93
|
name: "rects",
|
|
80
94
|
fn({ rects }) {
|
|
@@ -131,15 +145,14 @@ function roundByDpr(win, value) {
|
|
|
131
145
|
const dpr = win.devicePixelRatio || 1;
|
|
132
146
|
return Math.round(value * dpr) / dpr;
|
|
133
147
|
}
|
|
134
|
-
function
|
|
135
|
-
|
|
148
|
+
function resolveBoundaryOption(boundary) {
|
|
149
|
+
if (typeof boundary === "function") return boundary();
|
|
150
|
+
if (boundary === "clipping-ancestors") return "clippingAncestors";
|
|
151
|
+
return boundary;
|
|
136
152
|
}
|
|
137
|
-
function getArrowMiddleware(arrowElement, opts) {
|
|
138
|
-
|
|
139
|
-
return dom.arrow({
|
|
140
|
-
element: arrowElement,
|
|
141
|
-
padding: opts.arrowPadding
|
|
142
|
-
});
|
|
153
|
+
function getArrowMiddleware(arrowElement, doc, opts) {
|
|
154
|
+
const element = arrowElement || doc.createElement("div");
|
|
155
|
+
return dom.arrow({ element, padding: opts.arrowPadding });
|
|
143
156
|
}
|
|
144
157
|
function getOffsetMiddleware(arrowElement, opts) {
|
|
145
158
|
if (utils.isNull(opts.offset ?? opts.gutter)) return;
|
|
@@ -159,16 +172,18 @@ function getOffsetMiddleware(arrowElement, opts) {
|
|
|
159
172
|
}
|
|
160
173
|
function getFlipMiddleware(opts) {
|
|
161
174
|
if (!opts.flip) return;
|
|
175
|
+
const boundary = resolveBoundaryOption(opts.boundary);
|
|
162
176
|
return dom.flip({
|
|
163
|
-
boundary:
|
|
177
|
+
...boundary ? { boundary } : void 0,
|
|
164
178
|
padding: opts.overflowPadding,
|
|
165
179
|
fallbackPlacements: opts.flip === true ? void 0 : opts.flip
|
|
166
180
|
});
|
|
167
181
|
}
|
|
168
182
|
function getShiftMiddleware(opts) {
|
|
169
183
|
if (!opts.slide && !opts.overlap) return;
|
|
184
|
+
const boundary = resolveBoundaryOption(opts.boundary);
|
|
170
185
|
return dom.shift({
|
|
171
|
-
boundary:
|
|
186
|
+
...boundary ? { boundary } : void 0,
|
|
172
187
|
mainAxis: opts.slide,
|
|
173
188
|
crossAxis: opts.overlap,
|
|
174
189
|
padding: opts.overflowPadding,
|
|
@@ -181,9 +196,11 @@ function getSizeMiddleware(opts) {
|
|
|
181
196
|
apply({ elements, rects, availableHeight, availableWidth }) {
|
|
182
197
|
const floating = elements.floating;
|
|
183
198
|
const referenceWidth = Math.round(rects.reference.width);
|
|
199
|
+
const referenceHeight = Math.round(rects.reference.height);
|
|
184
200
|
availableWidth = Math.floor(availableWidth);
|
|
185
201
|
availableHeight = Math.floor(availableHeight);
|
|
186
202
|
floating.style.setProperty("--reference-width", `${referenceWidth}px`);
|
|
203
|
+
floating.style.setProperty("--reference-height", `${referenceHeight}px`);
|
|
187
204
|
floating.style.setProperty("--available-width", `${availableWidth}px`);
|
|
188
205
|
floating.style.setProperty("--available-height", `${availableHeight}px`);
|
|
189
206
|
}
|
|
@@ -191,7 +208,7 @@ function getSizeMiddleware(opts) {
|
|
|
191
208
|
}
|
|
192
209
|
function hideWhenDetachedMiddleware(opts) {
|
|
193
210
|
if (!opts.hideWhenDetached) return;
|
|
194
|
-
return dom.hide({ strategy: "referenceHidden", boundary: opts.boundary
|
|
211
|
+
return dom.hide({ strategy: "referenceHidden", boundary: resolveBoundaryOption(opts.boundary) ?? "clippingAncestors" });
|
|
195
212
|
}
|
|
196
213
|
function getAutoUpdateOptions(opts) {
|
|
197
214
|
if (!opts) return {};
|
|
@@ -209,9 +226,12 @@ function getPlacementImpl(referenceOrVirtual, floating, opts = {}) {
|
|
|
209
226
|
getOffsetMiddleware(arrowEl, options),
|
|
210
227
|
getFlipMiddleware(options),
|
|
211
228
|
getShiftMiddleware(options),
|
|
212
|
-
getArrowMiddleware(arrowEl, options),
|
|
229
|
+
getArrowMiddleware(arrowEl, floating.ownerDocument, options),
|
|
213
230
|
shiftArrowMiddleware(arrowEl),
|
|
214
|
-
|
|
231
|
+
createTransformOriginMiddleware(
|
|
232
|
+
{ gutter: options.gutter, offset: options.offset, overlap: options.overlap },
|
|
233
|
+
arrowEl
|
|
234
|
+
),
|
|
215
235
|
getSizeMiddleware(options),
|
|
216
236
|
hideWhenDetachedMiddleware(options),
|
|
217
237
|
rectMiddleware
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { autoUpdate, offset, flip, shift, limitShift, arrow, size, hide, computePosition } from '@floating-ui/dom';
|
|
2
2
|
import { raf, isHTMLElement, getWindow, getComputedStyle } from '@zag-js/dom-query';
|
|
3
|
-
import { noop, isNull, compact
|
|
3
|
+
import { noop, isNull, compact } from '@zag-js/utils';
|
|
4
4
|
|
|
5
5
|
// src/get-placement.ts
|
|
6
6
|
function createDOMRect(x = 0, y = 0, width = 0, height = 0) {
|
|
@@ -47,32 +47,46 @@ var cssVars = {
|
|
|
47
47
|
transformOrigin: toVar("--transform-origin"),
|
|
48
48
|
arrowOffset: toVar("--arrow-offset")
|
|
49
49
|
};
|
|
50
|
-
var
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
};
|
|
50
|
+
var getSideAxis = (side) => side === "top" || side === "bottom" ? "y" : "x";
|
|
51
|
+
function createTransformOriginMiddleware(opts, arrowEl) {
|
|
52
|
+
return {
|
|
53
|
+
name: "transformOrigin",
|
|
54
|
+
fn(state) {
|
|
55
|
+
const { elements, middlewareData, placement, rects, y } = state;
|
|
56
|
+
const side = placement.split("-")[0];
|
|
57
|
+
const axis = getSideAxis(side);
|
|
58
|
+
const arrowX = middlewareData.arrow?.x || 0;
|
|
59
|
+
const arrowY = middlewareData.arrow?.y || 0;
|
|
60
|
+
const arrowWidth = arrowEl?.clientWidth || 0;
|
|
61
|
+
const arrowHeight = arrowEl?.clientHeight || 0;
|
|
62
|
+
const transformX = arrowX + arrowWidth / 2;
|
|
63
|
+
const transformY = arrowY + arrowHeight / 2;
|
|
64
|
+
const shiftY = Math.abs(middlewareData.shift?.y || 0);
|
|
65
|
+
const halfAnchorHeight = rects.reference.height / 2;
|
|
66
|
+
const arrowOffset = arrowHeight / 2;
|
|
67
|
+
const gutter = opts.offset?.mainAxis ?? opts.gutter;
|
|
68
|
+
const sideOffsetValue = typeof gutter === "number" ? gutter + arrowOffset : gutter ?? arrowOffset;
|
|
69
|
+
const isOverlappingAnchor = shiftY > sideOffsetValue;
|
|
70
|
+
const adjacentTransformOrigin = {
|
|
71
|
+
top: `${transformX}px calc(100% + ${sideOffsetValue}px)`,
|
|
72
|
+
bottom: `${transformX}px ${-sideOffsetValue}px`,
|
|
73
|
+
left: `calc(100% + ${sideOffsetValue}px) ${transformY}px`,
|
|
74
|
+
right: `${-sideOffsetValue}px ${transformY}px`
|
|
75
|
+
}[side];
|
|
76
|
+
const overlapTransformOrigin = `${transformX}px ${rects.reference.y + halfAnchorHeight - y}px`;
|
|
77
|
+
const useOverlap = Boolean(opts.overlap) && axis === "y" && isOverlappingAnchor;
|
|
78
|
+
elements.floating.style.setProperty(
|
|
79
|
+
cssVars.transformOrigin.variable,
|
|
80
|
+
useOverlap ? overlapTransformOrigin : adjacentTransformOrigin
|
|
81
|
+
);
|
|
82
|
+
return {
|
|
83
|
+
data: {
|
|
84
|
+
transformOrigin: useOverlap ? overlapTransformOrigin : adjacentTransformOrigin
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
76
90
|
var rectMiddleware = {
|
|
77
91
|
name: "rects",
|
|
78
92
|
fn({ rects }) {
|
|
@@ -129,15 +143,14 @@ function roundByDpr(win, value) {
|
|
|
129
143
|
const dpr = win.devicePixelRatio || 1;
|
|
130
144
|
return Math.round(value * dpr) / dpr;
|
|
131
145
|
}
|
|
132
|
-
function
|
|
133
|
-
|
|
146
|
+
function resolveBoundaryOption(boundary) {
|
|
147
|
+
if (typeof boundary === "function") return boundary();
|
|
148
|
+
if (boundary === "clipping-ancestors") return "clippingAncestors";
|
|
149
|
+
return boundary;
|
|
134
150
|
}
|
|
135
|
-
function getArrowMiddleware(arrowElement, opts) {
|
|
136
|
-
|
|
137
|
-
return arrow({
|
|
138
|
-
element: arrowElement,
|
|
139
|
-
padding: opts.arrowPadding
|
|
140
|
-
});
|
|
151
|
+
function getArrowMiddleware(arrowElement, doc, opts) {
|
|
152
|
+
const element = arrowElement || doc.createElement("div");
|
|
153
|
+
return arrow({ element, padding: opts.arrowPadding });
|
|
141
154
|
}
|
|
142
155
|
function getOffsetMiddleware(arrowElement, opts) {
|
|
143
156
|
if (isNull(opts.offset ?? opts.gutter)) return;
|
|
@@ -157,16 +170,18 @@ function getOffsetMiddleware(arrowElement, opts) {
|
|
|
157
170
|
}
|
|
158
171
|
function getFlipMiddleware(opts) {
|
|
159
172
|
if (!opts.flip) return;
|
|
173
|
+
const boundary = resolveBoundaryOption(opts.boundary);
|
|
160
174
|
return flip({
|
|
161
|
-
boundary:
|
|
175
|
+
...boundary ? { boundary } : void 0,
|
|
162
176
|
padding: opts.overflowPadding,
|
|
163
177
|
fallbackPlacements: opts.flip === true ? void 0 : opts.flip
|
|
164
178
|
});
|
|
165
179
|
}
|
|
166
180
|
function getShiftMiddleware(opts) {
|
|
167
181
|
if (!opts.slide && !opts.overlap) return;
|
|
182
|
+
const boundary = resolveBoundaryOption(opts.boundary);
|
|
168
183
|
return shift({
|
|
169
|
-
boundary:
|
|
184
|
+
...boundary ? { boundary } : void 0,
|
|
170
185
|
mainAxis: opts.slide,
|
|
171
186
|
crossAxis: opts.overlap,
|
|
172
187
|
padding: opts.overflowPadding,
|
|
@@ -179,9 +194,11 @@ function getSizeMiddleware(opts) {
|
|
|
179
194
|
apply({ elements, rects, availableHeight, availableWidth }) {
|
|
180
195
|
const floating = elements.floating;
|
|
181
196
|
const referenceWidth = Math.round(rects.reference.width);
|
|
197
|
+
const referenceHeight = Math.round(rects.reference.height);
|
|
182
198
|
availableWidth = Math.floor(availableWidth);
|
|
183
199
|
availableHeight = Math.floor(availableHeight);
|
|
184
200
|
floating.style.setProperty("--reference-width", `${referenceWidth}px`);
|
|
201
|
+
floating.style.setProperty("--reference-height", `${referenceHeight}px`);
|
|
185
202
|
floating.style.setProperty("--available-width", `${availableWidth}px`);
|
|
186
203
|
floating.style.setProperty("--available-height", `${availableHeight}px`);
|
|
187
204
|
}
|
|
@@ -189,7 +206,7 @@ function getSizeMiddleware(opts) {
|
|
|
189
206
|
}
|
|
190
207
|
function hideWhenDetachedMiddleware(opts) {
|
|
191
208
|
if (!opts.hideWhenDetached) return;
|
|
192
|
-
return hide({ strategy: "referenceHidden", boundary: opts.boundary
|
|
209
|
+
return hide({ strategy: "referenceHidden", boundary: resolveBoundaryOption(opts.boundary) ?? "clippingAncestors" });
|
|
193
210
|
}
|
|
194
211
|
function getAutoUpdateOptions(opts) {
|
|
195
212
|
if (!opts) return {};
|
|
@@ -207,9 +224,12 @@ function getPlacementImpl(referenceOrVirtual, floating, opts = {}) {
|
|
|
207
224
|
getOffsetMiddleware(arrowEl, options),
|
|
208
225
|
getFlipMiddleware(options),
|
|
209
226
|
getShiftMiddleware(options),
|
|
210
|
-
getArrowMiddleware(arrowEl, options),
|
|
227
|
+
getArrowMiddleware(arrowEl, floating.ownerDocument, options),
|
|
211
228
|
shiftArrowMiddleware(arrowEl),
|
|
212
|
-
|
|
229
|
+
createTransformOriginMiddleware(
|
|
230
|
+
{ gutter: options.gutter, offset: options.offset, overlap: options.overlap },
|
|
231
|
+
arrowEl
|
|
232
|
+
),
|
|
213
233
|
getSizeMiddleware(options),
|
|
214
234
|
hideWhenDetachedMiddleware(options),
|
|
215
235
|
rectMiddleware
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/popper",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.22.0",
|
|
4
4
|
"description": "Dynamic positioning logic for ui machines",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@floating-ui/dom": "1.7.4",
|
|
26
|
-
"@zag-js/dom-query": "1.
|
|
27
|
-
"@zag-js/utils": "1.
|
|
26
|
+
"@zag-js/dom-query": "1.22.0",
|
|
27
|
+
"@zag-js/utils": "1.22.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"clean-package": "2.2.0"
|