@zag-js/popper 0.1.12 → 0.2.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.ts CHANGED
@@ -51,7 +51,7 @@ declare type PositioningOptions = {
51
51
  /**
52
52
  * The overflow boundary of the reference element
53
53
  */
54
- boundary?: Boundary;
54
+ boundary?: Boundary | (() => Boundary);
55
55
  /**
56
56
  * Options to activate auto-update listeners
57
57
  */
package/dist/index.js CHANGED
@@ -1,7 +1,35 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ getBasePlacement: () => getBasePlacement,
24
+ getPlacement: () => getPlacement,
25
+ getPlacementStyles: () => getPlacementStyles
26
+ });
27
+ module.exports = __toCommonJS(src_exports);
28
+
1
29
  // src/get-placement.ts
2
- import { arrow, computePosition, flip, offset, shift, size } from "@floating-ui/dom";
30
+ var import_dom2 = require("@floating-ui/dom");
3
31
 
4
- // ../core/dist/index.js
32
+ // ../core/dist/index.mjs
5
33
  var callAll = (...fns) => (...a) => {
6
34
  fns.forEach(function(fn) {
7
35
  fn == null ? void 0 : fn(...a);
@@ -10,12 +38,12 @@ var callAll = (...fns) => (...a) => {
10
38
  var isBoolean = (v) => v === true || v === false;
11
39
 
12
40
  // src/auto-update.ts
13
- import { getOverflowAncestors } from "@floating-ui/dom";
41
+ var import_dom = require("@floating-ui/dom");
14
42
 
15
- // ../dom/dist/index.js
43
+ // ../dom/dist/index.mjs
16
44
  var runIfFn = (v, ...a) => {
17
45
  const res = typeof v === "function" ? v(...a) : v;
18
- return res ?? void 0;
46
+ return res != null ? res : void 0;
19
47
  };
20
48
  var hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
21
49
  function isHTMLElement(v) {
@@ -84,11 +112,12 @@ function isEqual(rect1, rect2) {
84
112
 
85
113
  // src/auto-update.ts
86
114
  function resolveOptions(option) {
115
+ var _a, _b, _c;
87
116
  const bool = isBoolean(option);
88
117
  return {
89
- ancestorResize: bool ? option : option.ancestorResize ?? true,
90
- ancestorScroll: bool ? option : option.ancestorScroll ?? true,
91
- referenceResize: bool ? option : option.referenceResize ?? true
118
+ ancestorResize: bool ? option : (_a = option.ancestorResize) != null ? _a : true,
119
+ ancestorScroll: bool ? option : (_b = option.ancestorScroll) != null ? _b : true,
120
+ referenceResize: bool ? option : (_c = option.referenceResize) != null ? _c : true
92
121
  };
93
122
  }
94
123
  function autoUpdate(reference, floating, update, options = false) {
@@ -96,7 +125,7 @@ function autoUpdate(reference, floating, update, options = false) {
96
125
  const useAncestors = ancestorScroll || ancestorResize;
97
126
  const ancestors = [];
98
127
  if (useAncestors && isHTMLElement(reference)) {
99
- ancestors.push(...getOverflowAncestors(reference));
128
+ ancestors.push(...(0, import_dom.getOverflowAncestors)(reference));
100
129
  }
101
130
  function addResizeListeners() {
102
131
  let cleanups = [observeElementRect(floating, update)];
@@ -180,10 +209,11 @@ function getPlacement(reference, floating, opts = {}) {
180
209
  const options = Object.assign({}, defaultOptions, opts);
181
210
  const arrowEl = floating.querySelector("[data-part=arrow]");
182
211
  const middleware = [];
212
+ const boundary = typeof options.boundary === "function" ? options.boundary() : options.boundary;
183
213
  if (options.flip) {
184
214
  middleware.push(
185
- flip({
186
- boundary: options.boundary,
215
+ (0, import_dom2.flip)({
216
+ boundary,
187
217
  padding: options.overflowPadding
188
218
  })
189
219
  );
@@ -193,24 +223,24 @@ function getPlacement(reference, floating, opts = {}) {
193
223
  const data = options.gutter ? { mainAxis: options.gutter } : options.offset;
194
224
  if ((data == null ? void 0 : data.mainAxis) != null)
195
225
  data.mainAxis += arrowOffset;
196
- middleware.push(offset(data));
226
+ middleware.push((0, import_dom2.offset)(data));
197
227
  }
198
228
  middleware.push(
199
- shift({
200
- boundary: options.boundary,
229
+ (0, import_dom2.shift)({
230
+ boundary,
201
231
  crossAxis: options.overlap,
202
232
  padding: options.overflowPadding
203
233
  })
204
234
  );
205
235
  if (arrowEl) {
206
236
  middleware.push(
207
- arrow({ element: arrowEl, padding: 8 }),
237
+ (0, import_dom2.arrow)({ element: arrowEl, padding: 8 }),
208
238
  shiftArrow({ element: arrowEl })
209
239
  );
210
240
  }
211
241
  middleware.push(transformOrigin);
212
242
  middleware.push(
213
- size({
243
+ (0, import_dom2.size)({
214
244
  padding: options.overflowPadding,
215
245
  apply({ rects, availableHeight, availableWidth }) {
216
246
  const referenceWidth = Math.round(rects.reference.width);
@@ -236,7 +266,7 @@ function getPlacement(reference, floating, opts = {}) {
236
266
  if (!reference || !floating)
237
267
  return;
238
268
  const { placement, strategy } = options;
239
- computePosition(reference, floating, {
269
+ (0, import_dom2.computePosition)(reference, floating, {
240
270
  placement,
241
271
  middleware,
242
272
  strategy,
@@ -307,8 +337,9 @@ function getPlacementStyles(options) {
307
337
  }
308
338
  };
309
339
  }
310
- export {
340
+ // Annotate the CommonJS export names for ESM import in node:
341
+ 0 && (module.exports = {
311
342
  getBasePlacement,
312
343
  getPlacement,
313
344
  getPlacementStyles
314
- };
345
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,316 @@
1
+ // src/get-placement.ts
2
+ import { arrow, computePosition, flip, offset, shift, size } from "@floating-ui/dom";
3
+
4
+ // ../core/dist/index.mjs
5
+ var callAll = (...fns) => (...a) => {
6
+ fns.forEach(function(fn) {
7
+ fn == null ? void 0 : fn(...a);
8
+ });
9
+ };
10
+ var isBoolean = (v) => v === true || v === false;
11
+
12
+ // src/auto-update.ts
13
+ import { getOverflowAncestors } from "@floating-ui/dom";
14
+
15
+ // ../dom/dist/index.mjs
16
+ var runIfFn = (v, ...a) => {
17
+ const res = typeof v === "function" ? v(...a) : v;
18
+ return res != null ? res : void 0;
19
+ };
20
+ var hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
21
+ function isHTMLElement(v) {
22
+ return typeof v === "object" && (v == null ? void 0 : v.nodeType) === Node.ELEMENT_NODE && typeof (v == null ? void 0 : v.nodeName) === "string";
23
+ }
24
+ var isRef = (v) => hasProp(v, "current");
25
+ function addDomEvent(target, eventName, handler, options) {
26
+ const node = isRef(target) ? target.current : runIfFn(target);
27
+ node == null ? void 0 : node.addEventListener(eventName, handler, options);
28
+ return () => {
29
+ node == null ? void 0 : node.removeEventListener(eventName, handler, options);
30
+ };
31
+ }
32
+ function getObservedElements() {
33
+ ;
34
+ globalThis.__rectObserverMap__ = globalThis.__rectObserverMap__ || /* @__PURE__ */ new Map();
35
+ return globalThis.__rectObserverMap__;
36
+ }
37
+ function observeElementRect(el, fn) {
38
+ const observedElements = getObservedElements();
39
+ const data = observedElements.get(el);
40
+ if (!data) {
41
+ observedElements.set(el, { rect: {}, callbacks: [fn] });
42
+ if (observedElements.size === 1) {
43
+ rafId = requestAnimationFrame(runLoop);
44
+ }
45
+ } else {
46
+ data.callbacks.push(fn);
47
+ fn(el.getBoundingClientRect());
48
+ }
49
+ return function unobserve() {
50
+ const data2 = observedElements.get(el);
51
+ if (!data2)
52
+ return;
53
+ const index = data2.callbacks.indexOf(fn);
54
+ if (index > -1) {
55
+ data2.callbacks.splice(index, 1);
56
+ }
57
+ if (data2.callbacks.length === 0) {
58
+ observedElements.delete(el);
59
+ if (observedElements.size === 0) {
60
+ cancelAnimationFrame(rafId);
61
+ }
62
+ }
63
+ };
64
+ }
65
+ var rafId;
66
+ function runLoop() {
67
+ const observedElements = getObservedElements();
68
+ const changedRectsData = [];
69
+ observedElements.forEach((data, element) => {
70
+ const newRect = element.getBoundingClientRect();
71
+ if (!isEqual(data.rect, newRect)) {
72
+ data.rect = newRect;
73
+ changedRectsData.push(data);
74
+ }
75
+ });
76
+ changedRectsData.forEach((data) => {
77
+ data.callbacks.forEach((callback) => callback(data.rect));
78
+ });
79
+ rafId = requestAnimationFrame(runLoop);
80
+ }
81
+ function isEqual(rect1, rect2) {
82
+ return rect1.width === rect2.width && rect1.height === rect2.height && rect1.top === rect2.top && rect1.right === rect2.right && rect1.bottom === rect2.bottom && rect1.left === rect2.left;
83
+ }
84
+
85
+ // src/auto-update.ts
86
+ function resolveOptions(option) {
87
+ var _a, _b, _c;
88
+ const bool = isBoolean(option);
89
+ return {
90
+ ancestorResize: bool ? option : (_a = option.ancestorResize) != null ? _a : true,
91
+ ancestorScroll: bool ? option : (_b = option.ancestorScroll) != null ? _b : true,
92
+ referenceResize: bool ? option : (_c = option.referenceResize) != null ? _c : true
93
+ };
94
+ }
95
+ function autoUpdate(reference, floating, update, options = false) {
96
+ const { ancestorScroll, ancestorResize, referenceResize } = resolveOptions(options);
97
+ const useAncestors = ancestorScroll || ancestorResize;
98
+ const ancestors = [];
99
+ if (useAncestors && isHTMLElement(reference)) {
100
+ ancestors.push(...getOverflowAncestors(reference));
101
+ }
102
+ function addResizeListeners() {
103
+ let cleanups = [observeElementRect(floating, update)];
104
+ if (referenceResize && isHTMLElement(reference)) {
105
+ cleanups.push(observeElementRect(reference, update));
106
+ }
107
+ cleanups.push(callAll(...ancestors.map((el) => addDomEvent(el, "resize", update))));
108
+ return () => cleanups.forEach((fn) => fn());
109
+ }
110
+ function addScrollListeners() {
111
+ return callAll(...ancestors.map((el) => addDomEvent(el, "scroll", update, { passive: true })));
112
+ }
113
+ return callAll(addResizeListeners(), addScrollListeners());
114
+ }
115
+
116
+ // src/middleware.ts
117
+ var toVar = (value) => ({ variable: value, reference: `var(${value})` });
118
+ var cssVars = {
119
+ arrowSize: toVar("--arrow-size"),
120
+ arrowSizeHalf: toVar("--arrow-size-half"),
121
+ arrowBg: toVar("--arrow-background"),
122
+ transformOrigin: toVar("--transform-origin"),
123
+ arrowOffset: toVar("--arrow-offset")
124
+ };
125
+ var getTransformOrigin = (arrow2) => ({
126
+ top: "bottom center",
127
+ "top-start": arrow2 ? `${arrow2.x}px bottom` : "left bottom",
128
+ "top-end": arrow2 ? `${arrow2.x}px bottom` : "right bottom",
129
+ bottom: "top center",
130
+ "bottom-start": arrow2 ? `${arrow2.x}px top` : "top left",
131
+ "bottom-end": arrow2 ? `${arrow2.x}px top` : "top right",
132
+ left: "right center",
133
+ "left-start": arrow2 ? `right ${arrow2.y}px` : "right top",
134
+ "left-end": arrow2 ? `right ${arrow2.y}px` : "right bottom",
135
+ right: "left center",
136
+ "right-start": arrow2 ? `left ${arrow2.y}px` : "left top",
137
+ "right-end": arrow2 ? `left ${arrow2.y}px` : "left bottom"
138
+ });
139
+ var transformOrigin = {
140
+ name: "transformOrigin",
141
+ fn({ placement, elements, middlewareData }) {
142
+ const { arrow: arrow2 } = middlewareData;
143
+ const transformOrigin2 = getTransformOrigin(arrow2)[placement];
144
+ const { floating } = elements;
145
+ floating.style.setProperty(cssVars.transformOrigin.variable, transformOrigin2);
146
+ return {
147
+ data: { transformOrigin: transformOrigin2 }
148
+ };
149
+ }
150
+ };
151
+ var shiftArrow = (opts) => ({
152
+ name: "shiftArrow",
153
+ fn({ placement, middlewareData }) {
154
+ const { element: arrow2 } = opts;
155
+ if (middlewareData.arrow) {
156
+ const { x, y } = middlewareData.arrow;
157
+ const dir = placement.split("-")[0];
158
+ Object.assign(arrow2.style, {
159
+ left: x != null ? `${x}px` : "",
160
+ top: y != null ? `${y}px` : "",
161
+ [dir]: `calc(100% + ${cssVars.arrowOffset.reference})`
162
+ });
163
+ }
164
+ return {};
165
+ }
166
+ });
167
+
168
+ // src/get-placement.ts
169
+ var defaultOptions = {
170
+ strategy: "absolute",
171
+ placement: "bottom",
172
+ listeners: true,
173
+ gutter: 8,
174
+ flip: true,
175
+ sameWidth: false,
176
+ overflowPadding: 8
177
+ };
178
+ function getPlacement(reference, floating, opts = {}) {
179
+ if (!floating || !reference)
180
+ return;
181
+ const options = Object.assign({}, defaultOptions, opts);
182
+ const arrowEl = floating.querySelector("[data-part=arrow]");
183
+ const middleware = [];
184
+ const boundary = typeof options.boundary === "function" ? options.boundary() : options.boundary;
185
+ if (options.flip) {
186
+ middleware.push(
187
+ flip({
188
+ boundary,
189
+ padding: options.overflowPadding
190
+ })
191
+ );
192
+ }
193
+ if (options.gutter || options.offset) {
194
+ const arrowOffset = arrowEl ? arrowEl.offsetHeight / 2 : 0;
195
+ const data = options.gutter ? { mainAxis: options.gutter } : options.offset;
196
+ if ((data == null ? void 0 : data.mainAxis) != null)
197
+ data.mainAxis += arrowOffset;
198
+ middleware.push(offset(data));
199
+ }
200
+ middleware.push(
201
+ shift({
202
+ boundary,
203
+ crossAxis: options.overlap,
204
+ padding: options.overflowPadding
205
+ })
206
+ );
207
+ if (arrowEl) {
208
+ middleware.push(
209
+ arrow({ element: arrowEl, padding: 8 }),
210
+ shiftArrow({ element: arrowEl })
211
+ );
212
+ }
213
+ middleware.push(transformOrigin);
214
+ middleware.push(
215
+ size({
216
+ padding: options.overflowPadding,
217
+ apply({ rects, availableHeight, availableWidth }) {
218
+ const referenceWidth = Math.round(rects.reference.width);
219
+ floating.style.setProperty("--reference-width", `${referenceWidth}px`);
220
+ floating.style.setProperty("--available-width", `${availableWidth}px`);
221
+ floating.style.setProperty("--available-height", `${availableHeight}px`);
222
+ if (options.sameWidth) {
223
+ Object.assign(floating.style, {
224
+ width: `${referenceWidth}px`,
225
+ minWidth: "unset"
226
+ });
227
+ }
228
+ if (options.fitViewport) {
229
+ Object.assign(floating.style, {
230
+ maxWidth: `${availableWidth}px`,
231
+ maxHeight: `${availableHeight}px`
232
+ });
233
+ }
234
+ }
235
+ })
236
+ );
237
+ function compute(config = {}) {
238
+ if (!reference || !floating)
239
+ return;
240
+ const { placement, strategy } = options;
241
+ computePosition(reference, floating, {
242
+ placement,
243
+ middleware,
244
+ strategy,
245
+ ...config
246
+ }).then((data) => {
247
+ var _a;
248
+ const x = Math.round(data.x);
249
+ const y = Math.round(data.y);
250
+ Object.assign(floating.style, {
251
+ position: data.strategy,
252
+ top: "0",
253
+ left: "0",
254
+ transform: `translate3d(${x}px, ${y}px, 0)`
255
+ });
256
+ (_a = options.onComplete) == null ? void 0 : _a.call(options, { ...data, compute });
257
+ });
258
+ }
259
+ compute();
260
+ return callAll(
261
+ options.listeners ? autoUpdate(reference, floating, compute, options.listeners) : void 0,
262
+ options.onCleanup
263
+ );
264
+ }
265
+ function getBasePlacement(placement) {
266
+ return placement.split("-")[0];
267
+ }
268
+
269
+ // src/get-styles.ts
270
+ var UNMEASURED_FLOATING_STYLE = {
271
+ position: "fixed",
272
+ top: 0,
273
+ left: 0,
274
+ opacity: 0,
275
+ transform: "translate3d(0, -200%, 0)",
276
+ pointerEvents: "none"
277
+ };
278
+ var ARROW_FLOATING_STYLE = {
279
+ bottom: "rotate(45deg)",
280
+ left: "rotate(135deg)",
281
+ top: "rotate(225deg)",
282
+ right: "rotate(315deg)"
283
+ };
284
+ function getPlacementStyles(options) {
285
+ const { measured, strategy = "absolute", placement = "bottom" } = options;
286
+ return {
287
+ arrow: {
288
+ position: "absolute",
289
+ width: cssVars.arrowSize.reference,
290
+ height: cssVars.arrowSize.reference,
291
+ [cssVars.arrowSizeHalf.variable]: `calc(${cssVars.arrowSize.reference} / 2)`,
292
+ [cssVars.arrowOffset.variable]: `calc(${cssVars.arrowSizeHalf.reference} * -1)`,
293
+ opacity: !measured ? 0 : void 0
294
+ },
295
+ innerArrow: {
296
+ transform: ARROW_FLOATING_STYLE[placement.split("-")[0]],
297
+ background: cssVars.arrowBg.reference,
298
+ top: "0",
299
+ left: "0",
300
+ width: "100%",
301
+ height: "100%",
302
+ position: "absolute",
303
+ zIndex: "inherit"
304
+ },
305
+ floating: {
306
+ position: strategy,
307
+ minWidth: "max-content",
308
+ ...!measured && UNMEASURED_FLOATING_STYLE
309
+ }
310
+ };
311
+ }
312
+ export {
313
+ getBasePlacement,
314
+ getPlacement,
315
+ getPlacementStyles
316
+ };
package/package.json CHANGED
@@ -1,8 +1,10 @@
1
1
  {
2
- "type": "module",
3
2
  "name": "@zag-js/popper",
4
- "version": "0.1.12",
3
+ "version": "0.2.0",
5
4
  "description": "Dynamic positioning logic for ui machines",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
6
8
  "keywords": [
7
9
  "js",
8
10
  "utils",
@@ -11,8 +13,6 @@
11
13
  "author": "Segun Adebayo <sage@adebayosegun.com>",
12
14
  "homepage": "https://github.com/chakra-ui/zag#readme",
13
15
  "license": "MIT",
14
- "main": "dist/index.js",
15
- "types": "dist/index.d.ts",
16
16
  "repository": "https://github.com/chakra-ui/zag/tree/main/packages/utilities/popper",
17
17
  "sideEffects": false,
18
18
  "files": [
@@ -25,16 +25,16 @@
25
25
  "url": "https://github.com/chakra-ui/zag/issues"
26
26
  },
27
27
  "dependencies": {
28
- "@floating-ui/dom": "1.0.1"
28
+ "@floating-ui/dom": "1.0.2"
29
29
  },
30
30
  "devDependencies": {
31
- "@zag-js/dom-utils": "0.1.12",
32
- "@zag-js/utils": "0.1.5"
31
+ "@zag-js/dom-utils": "0.2.0",
32
+ "@zag-js/utils": "0.2.0"
33
33
  },
34
34
  "scripts": {
35
- "build-fast": "tsup src/index.ts --format=esm",
35
+ "build-fast": "tsup src/index.ts --format=esm,cjs",
36
36
  "start": "pnpm build --watch",
37
- "build": "tsup src/index.ts --format=esm --dts",
37
+ "build": "tsup src/index.ts --format=esm,cjs --dts",
38
38
  "test": "jest --config ../../../jest.config.js --rootDir . --passWithNoTests",
39
39
  "lint": "eslint src --ext .ts,.tsx",
40
40
  "test-ci": "pnpm test --ci --runInBand",