@zag-js/popper 0.30.0 → 0.31.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/dist/index.d.mts CHANGED
@@ -7,6 +7,17 @@ interface AutoUpdateOptions {
7
7
  referenceResize?: boolean;
8
8
  }
9
9
 
10
+ type MaybeRectElement = HTMLElement | VirtualElement | null;
11
+ type MaybeElement = HTMLElement | null;
12
+ type MaybeFn<T> = T | (() => T);
13
+ type PlacementSide = "top" | "right" | "bottom" | "left";
14
+ type PlacementAlign = "start" | "center" | "end";
15
+ interface AnchorRect {
16
+ x?: number;
17
+ y?: number;
18
+ width?: number;
19
+ height?: number;
20
+ }
10
21
  interface PositioningOptions {
11
22
  /**
12
23
  * The strategy to use for positioning
@@ -27,14 +38,27 @@ interface PositioningOptions {
27
38
  * The main axis offset or gap between the reference and floating elements
28
39
  */
29
40
  gutter?: number;
41
+ /**
42
+ * The secondary axis offset or gap between the reference and floating elements
43
+ */
44
+ shift?: number;
30
45
  /**
31
46
  * The virtual padding around the viewport edges to check for overflow
32
47
  */
33
48
  overflowPadding?: number;
49
+ /**
50
+ * The minimum padding between the arrow and the floating element's corner.
51
+ * @default 4
52
+ */
53
+ arrowPadding?: number;
34
54
  /**
35
55
  * Whether to flip the placement
36
56
  */
37
- flip?: boolean;
57
+ flip?: boolean | Placement[];
58
+ /**
59
+ * Whether the popover should slide when it overflows.
60
+ */
61
+ slide?: boolean;
38
62
  /**
39
63
  * Whether the floating element can overlap the reference element
40
64
  * @default false
@@ -60,17 +84,29 @@ interface PositioningOptions {
60
84
  * Function called when the placement is computed
61
85
  */
62
86
  onComplete?(data: ComputePositionReturn): void;
87
+ /**
88
+ * Function called when the floating element is positioned or not
89
+ */
90
+ onPositioned?(data: {
91
+ placed: boolean;
92
+ }): void;
63
93
  /**
64
94
  * Function called on cleanup of all listeners
65
95
  */
66
96
  onCleanup?: VoidFunction;
97
+ /**
98
+ * Function that returns the anchor rect of the combobox
99
+ */
100
+ getAnchorRect?: (element: HTMLElement | VirtualElement | null) => AnchorRect | null;
101
+ /**
102
+ * A callback that will be called when the popover needs to calculate its
103
+ * position.
104
+ */
105
+ updatePosition?: (data: {
106
+ updatePosition: () => Promise<void>;
107
+ }) => void | Promise<void>;
67
108
  }
68
- type BasePlacement = "top" | "right" | "bottom" | "left";
69
109
 
70
- type MaybeRectElement = HTMLElement | VirtualElement | null;
71
- type MaybeElement = HTMLElement | null;
72
- type MaybeFn<T> = T | (() => T);
73
- declare function getBasePlacement(placement: Placement): BasePlacement;
74
110
  declare function getPlacement(referenceOrFn: MaybeFn<MaybeRectElement>, floatingOrFn: MaybeFn<MaybeElement>, opts?: PositioningOptions & {
75
111
  defer?: boolean;
76
112
  }): () => void;
@@ -104,9 +140,12 @@ declare function getPlacementStyles(options?: PositioningOptions): {
104
140
  readonly maxHeight: "var(--available-height)" | undefined;
105
141
  readonly top: "0px";
106
142
  readonly left: "0px";
107
- readonly transform: "translate3d(var(--x), var(--y), 0)";
143
+ readonly transform: "translate3d(var(--x), var(--y), 0)" | "translate3d(0, -100vh, 0)";
108
144
  readonly zIndex: "var(--z-index)";
109
145
  };
110
146
  };
111
147
 
112
- export { AutoUpdateOptions, BasePlacement, GetPlacementStylesOptions, PositioningOptions, getBasePlacement, getPlacement, getPlacementStyles };
148
+ declare function isValidPlacement(v: string): v is Placement;
149
+ declare function getPlacementSide(placement: Placement): PlacementSide;
150
+
151
+ export { type AnchorRect, type AutoUpdateOptions, type GetPlacementStylesOptions, type PlacementAlign, type PlacementSide, type PositioningOptions, getPlacement, getPlacementSide, getPlacementStyles, isValidPlacement };
package/dist/index.d.ts CHANGED
@@ -7,6 +7,17 @@ interface AutoUpdateOptions {
7
7
  referenceResize?: boolean;
8
8
  }
9
9
 
10
+ type MaybeRectElement = HTMLElement | VirtualElement | null;
11
+ type MaybeElement = HTMLElement | null;
12
+ type MaybeFn<T> = T | (() => T);
13
+ type PlacementSide = "top" | "right" | "bottom" | "left";
14
+ type PlacementAlign = "start" | "center" | "end";
15
+ interface AnchorRect {
16
+ x?: number;
17
+ y?: number;
18
+ width?: number;
19
+ height?: number;
20
+ }
10
21
  interface PositioningOptions {
11
22
  /**
12
23
  * The strategy to use for positioning
@@ -27,14 +38,27 @@ interface PositioningOptions {
27
38
  * The main axis offset or gap between the reference and floating elements
28
39
  */
29
40
  gutter?: number;
41
+ /**
42
+ * The secondary axis offset or gap between the reference and floating elements
43
+ */
44
+ shift?: number;
30
45
  /**
31
46
  * The virtual padding around the viewport edges to check for overflow
32
47
  */
33
48
  overflowPadding?: number;
49
+ /**
50
+ * The minimum padding between the arrow and the floating element's corner.
51
+ * @default 4
52
+ */
53
+ arrowPadding?: number;
34
54
  /**
35
55
  * Whether to flip the placement
36
56
  */
37
- flip?: boolean;
57
+ flip?: boolean | Placement[];
58
+ /**
59
+ * Whether the popover should slide when it overflows.
60
+ */
61
+ slide?: boolean;
38
62
  /**
39
63
  * Whether the floating element can overlap the reference element
40
64
  * @default false
@@ -60,17 +84,29 @@ interface PositioningOptions {
60
84
  * Function called when the placement is computed
61
85
  */
62
86
  onComplete?(data: ComputePositionReturn): void;
87
+ /**
88
+ * Function called when the floating element is positioned or not
89
+ */
90
+ onPositioned?(data: {
91
+ placed: boolean;
92
+ }): void;
63
93
  /**
64
94
  * Function called on cleanup of all listeners
65
95
  */
66
96
  onCleanup?: VoidFunction;
97
+ /**
98
+ * Function that returns the anchor rect of the combobox
99
+ */
100
+ getAnchorRect?: (element: HTMLElement | VirtualElement | null) => AnchorRect | null;
101
+ /**
102
+ * A callback that will be called when the popover needs to calculate its
103
+ * position.
104
+ */
105
+ updatePosition?: (data: {
106
+ updatePosition: () => Promise<void>;
107
+ }) => void | Promise<void>;
67
108
  }
68
- type BasePlacement = "top" | "right" | "bottom" | "left";
69
109
 
70
- type MaybeRectElement = HTMLElement | VirtualElement | null;
71
- type MaybeElement = HTMLElement | null;
72
- type MaybeFn<T> = T | (() => T);
73
- declare function getBasePlacement(placement: Placement): BasePlacement;
74
110
  declare function getPlacement(referenceOrFn: MaybeFn<MaybeRectElement>, floatingOrFn: MaybeFn<MaybeElement>, opts?: PositioningOptions & {
75
111
  defer?: boolean;
76
112
  }): () => void;
@@ -104,9 +140,12 @@ declare function getPlacementStyles(options?: PositioningOptions): {
104
140
  readonly maxHeight: "var(--available-height)" | undefined;
105
141
  readonly top: "0px";
106
142
  readonly left: "0px";
107
- readonly transform: "translate3d(var(--x), var(--y), 0)";
143
+ readonly transform: "translate3d(var(--x), var(--y), 0)" | "translate3d(0, -100vh, 0)";
108
144
  readonly zIndex: "var(--z-index)";
109
145
  };
110
146
  };
111
147
 
112
- export { AutoUpdateOptions, BasePlacement, GetPlacementStylesOptions, PositioningOptions, getBasePlacement, getPlacement, getPlacementStyles };
148
+ declare function isValidPlacement(v: string): v is Placement;
149
+ declare function getPlacementSide(placement: Placement): PlacementSide;
150
+
151
+ export { type AnchorRect, type AutoUpdateOptions, type GetPlacementStylesOptions, type PlacementAlign, type PlacementSide, type PositioningOptions, getPlacement, getPlacementSide, getPlacementStyles, isValidPlacement };
package/dist/index.js CHANGED
@@ -20,24 +20,23 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
- getBasePlacement: () => getBasePlacement,
24
23
  getPlacement: () => getPlacement,
25
- getPlacementStyles: () => getPlacementStyles
24
+ getPlacementSide: () => getPlacementSide,
25
+ getPlacementStyles: () => getPlacementStyles,
26
+ isValidPlacement: () => isValidPlacement
26
27
  });
27
28
  module.exports = __toCommonJS(src_exports);
28
29
 
29
30
  // src/get-placement.ts
30
31
  var import_dom2 = require("@floating-ui/dom");
31
- var import_dom_query = require("@zag-js/dom-query");
32
- var import_utils = require("@zag-js/utils");
32
+ var import_dom_query3 = require("@zag-js/dom-query");
33
+ var import_utils2 = require("@zag-js/utils");
33
34
 
34
35
  // src/auto-update.ts
35
36
  var import_dom = require("@floating-ui/dom");
37
+ var import_dom_query = require("@zag-js/dom-query");
36
38
  var import_element_rect = require("@zag-js/element-rect");
37
- var callAll = (...fns) => () => fns.forEach((fn) => fn());
38
- var isHTMLElement = (el) => {
39
- return typeof el === "object" && el !== null && el.nodeType === 1;
40
- };
39
+ var import_utils = require("@zag-js/utils");
41
40
  var addDomEvent = (el, type, fn, options) => {
42
41
  el.addEventListener(type, fn, options);
43
42
  return () => el.removeEventListener(type, fn, options);
@@ -54,21 +53,59 @@ function autoUpdate(reference, floating, update, options = false) {
54
53
  const { ancestorScroll, ancestorResize, referenceResize } = resolveOptions(options);
55
54
  const useAncestors = ancestorScroll || ancestorResize;
56
55
  const ancestors = [];
57
- if (useAncestors && isHTMLElement(reference)) {
56
+ if (useAncestors && (0, import_dom_query.isHTMLElement)(reference)) {
58
57
  ancestors.push(...(0, import_dom.getOverflowAncestors)(reference));
59
58
  }
60
59
  function addResizeListeners() {
61
60
  let cleanups = [(0, import_element_rect.trackElementRect)(floating, { scope: "size", onChange: update })];
62
- if (referenceResize && isHTMLElement(reference)) {
61
+ if (referenceResize && (0, import_dom_query.isHTMLElement)(reference)) {
63
62
  cleanups.push((0, import_element_rect.trackElementRect)(reference, { onChange: update }));
64
63
  }
65
- cleanups.push(callAll(...ancestors.map((el) => addDomEvent(el, "resize", update))));
64
+ cleanups.push((0, import_utils.callAll)(...ancestors.map((el) => addDomEvent(el, "resize", update))));
66
65
  return () => cleanups.forEach((fn) => fn());
67
66
  }
68
67
  function addScrollListeners() {
69
- return callAll(...ancestors.map((el) => addDomEvent(el, "scroll", update, { passive: true })));
68
+ return (0, import_utils.callAll)(...ancestors.map((el) => addDomEvent(el, "scroll", update, { passive: true })));
69
+ }
70
+ return (0, import_utils.callAll)(addResizeListeners(), addScrollListeners());
71
+ }
72
+
73
+ // src/get-anchor.ts
74
+ var import_dom_query2 = require("@zag-js/dom-query");
75
+ function createDOMRect(x = 0, y = 0, width = 0, height = 0) {
76
+ if (typeof DOMRect === "function") {
77
+ return new DOMRect(x, y, width, height);
70
78
  }
71
- return callAll(addResizeListeners(), addScrollListeners());
79
+ const rect = {
80
+ x,
81
+ y,
82
+ width,
83
+ height,
84
+ top: y,
85
+ right: x + width,
86
+ bottom: y + height,
87
+ left: x
88
+ };
89
+ return { ...rect, toJSON: () => rect };
90
+ }
91
+ function getDOMRect(anchorRect) {
92
+ if (!anchorRect)
93
+ return createDOMRect();
94
+ const { x, y, width, height } = anchorRect;
95
+ return createDOMRect(x, y, width, height);
96
+ }
97
+ function getAnchorElement(anchorElement, getAnchorRect) {
98
+ return {
99
+ contextElement: (0, import_dom_query2.isHTMLElement)(anchorElement) ? anchorElement : void 0,
100
+ getBoundingClientRect: () => {
101
+ const anchor = anchorElement;
102
+ const anchorRect = getAnchorRect?.(anchor);
103
+ if (anchorRect || !anchor) {
104
+ return getDOMRect(anchorRect);
105
+ }
106
+ return anchor.getBoundingClientRect();
107
+ }
108
+ };
72
109
  }
73
110
 
74
111
  // src/middleware.ts
@@ -94,34 +131,49 @@ var getTransformOrigin = (arrow2) => ({
94
131
  "right-start": arrow2 ? `left ${arrow2.y}px` : "left top",
95
132
  "right-end": arrow2 ? `left ${arrow2.y}px` : "left bottom"
96
133
  });
97
- var transformOrigin = {
134
+ var __transformOrigin = {
98
135
  name: "transformOrigin",
99
136
  fn({ placement, elements, middlewareData }) {
100
137
  const { arrow: arrow2 } = middlewareData;
101
- const transformOrigin2 = getTransformOrigin(arrow2)[placement];
138
+ const transformOrigin = getTransformOrigin(arrow2)[placement];
102
139
  const { floating } = elements;
103
- floating.style.setProperty(cssVars.transformOrigin.variable, transformOrigin2);
140
+ floating.style.setProperty(cssVars.transformOrigin.variable, transformOrigin);
104
141
  return {
105
- data: { transformOrigin: transformOrigin2 }
142
+ data: { transformOrigin }
106
143
  };
107
144
  }
108
145
  };
109
- var shiftArrow = (opts) => ({
110
- name: "shiftArrow",
111
- fn({ placement, middlewareData }) {
112
- const { element: arrow2 } = opts;
113
- if (middlewareData.arrow) {
146
+ var __shiftArrow = (arrowEl) => {
147
+ if (!arrowEl)
148
+ return;
149
+ return {
150
+ name: "shiftArrow",
151
+ fn({ placement, middlewareData }) {
152
+ if (!middlewareData.arrow)
153
+ return {};
114
154
  const { x, y } = middlewareData.arrow;
115
155
  const dir = placement.split("-")[0];
116
- Object.assign(arrow2.style, {
156
+ Object.assign(arrowEl.style, {
117
157
  left: x != null ? `${x}px` : "",
118
158
  top: y != null ? `${y}px` : "",
119
159
  [dir]: `calc(100% + ${cssVars.arrowOffset.reference})`
120
160
  });
161
+ return {};
121
162
  }
122
- return {};
123
- }
124
- });
163
+ };
164
+ };
165
+
166
+ // src/placement.ts
167
+ function isValidPlacement(v) {
168
+ return /^(?:top|bottom|left|right)(?:-(?:start|end))?$/.test(v);
169
+ }
170
+ function getPlacementDetails(placement) {
171
+ const [side, align] = placement.split("-");
172
+ return { side, align, hasAlign: align != null };
173
+ }
174
+ function getPlacementSide(placement) {
175
+ return placement.split("-")[0];
176
+ }
125
177
 
126
178
  // src/get-placement.ts
127
179
  var defaultOptions = {
@@ -130,99 +182,138 @@ var defaultOptions = {
130
182
  listeners: true,
131
183
  gutter: 8,
132
184
  flip: true,
185
+ slide: true,
186
+ overlap: false,
133
187
  sameWidth: false,
134
- overflowPadding: 8
188
+ fitViewport: false,
189
+ overflowPadding: 8,
190
+ arrowPadding: 4
135
191
  };
136
- function getPlacementImpl(reference, floating, opts = {}) {
192
+ function __dpr(win, value) {
193
+ const dpr = win.devicePixelRatio || 1;
194
+ return Math.round(value * dpr) / dpr;
195
+ }
196
+ function __boundary(opts) {
197
+ return (0, import_utils2.runIfFn)(opts.boundary);
198
+ }
199
+ function __arrow(arrowElement, opts) {
200
+ if (!arrowElement)
201
+ return;
202
+ return (0, import_dom2.arrow)({
203
+ element: arrowElement,
204
+ padding: opts.arrowPadding
205
+ });
206
+ }
207
+ function __offset(arrowElement, opts) {
208
+ if ((0, import_utils2.isNull)(opts.offset ?? opts.gutter))
209
+ return;
210
+ return (0, import_dom2.offset)(({ placement }) => {
211
+ const arrowOffset = (arrowElement?.clientHeight || 0) / 2;
212
+ const gutter = opts.offset?.mainAxis ?? opts.gutter;
213
+ const mainAxis = typeof gutter === "number" ? gutter + arrowOffset : gutter ?? arrowOffset;
214
+ const { hasAlign } = getPlacementDetails(placement);
215
+ return (0, import_utils2.compact)({
216
+ crossAxis: hasAlign ? opts.shift : void 0,
217
+ mainAxis,
218
+ alignmentAxis: opts.shift
219
+ });
220
+ });
221
+ }
222
+ function __flip(opts) {
223
+ if (!opts.flip)
224
+ return;
225
+ return (0, import_dom2.flip)({
226
+ boundary: __boundary(opts),
227
+ padding: opts.overflowPadding,
228
+ fallbackPlacements: opts.flip === true ? void 0 : opts.flip
229
+ });
230
+ }
231
+ function __shift(opts) {
232
+ if (!opts.slide && !opts.overlap)
233
+ return;
234
+ return (0, import_dom2.shift)({
235
+ boundary: __boundary(opts),
236
+ mainAxis: opts.slide,
237
+ crossAxis: opts.overlap,
238
+ padding: opts.overflowPadding
239
+ });
240
+ }
241
+ function __size(opts) {
242
+ return (0, import_dom2.size)({
243
+ padding: opts.overflowPadding,
244
+ apply({ elements, rects, availableHeight, availableWidth }) {
245
+ const floating = elements.floating;
246
+ const referenceWidth = Math.round(rects.reference.width);
247
+ availableWidth = Math.floor(availableWidth);
248
+ availableHeight = Math.floor(availableHeight);
249
+ floating.style.setProperty("--reference-width", `${referenceWidth}px`);
250
+ floating.style.setProperty("--available-width", `${availableWidth}px`);
251
+ floating.style.setProperty("--available-height", `${availableHeight}px`);
252
+ }
253
+ });
254
+ }
255
+ function getPlacementImpl(referenceOrVirtual, floating, opts = {}) {
256
+ const reference = getAnchorElement(referenceOrVirtual, opts.getAnchorRect);
137
257
  if (!floating || !reference)
138
258
  return;
139
259
  const options = Object.assign({}, defaultOptions, opts);
140
260
  const arrowEl = floating.querySelector("[data-part=arrow]");
141
- const middleware = [];
142
- const boundary = typeof options.boundary === "function" ? options.boundary() : options.boundary;
143
- if (options.flip) {
144
- middleware.push(
145
- (0, import_dom2.flip)({
146
- boundary,
147
- padding: options.overflowPadding
148
- })
149
- );
150
- }
151
- if (options.gutter || options.offset) {
152
- const arrowOffset = arrowEl ? arrowEl.offsetHeight / 2 : 0;
153
- let mainAxis = options.offset?.mainAxis ?? options.gutter;
154
- let crossAxis = options.offset?.crossAxis;
155
- if (mainAxis != null)
156
- mainAxis += arrowOffset;
157
- const offsetOptions = (0, import_utils.compact)({ mainAxis, crossAxis });
158
- middleware.push((0, import_dom2.offset)(offsetOptions));
159
- }
160
- middleware.push(
161
- (0, import_dom2.shift)({
162
- boundary,
163
- crossAxis: options.overlap,
164
- padding: options.overflowPadding
165
- })
166
- );
167
- if (arrowEl) {
168
- middleware.push(
169
- (0, import_dom2.arrow)({ element: arrowEl, padding: 8 }),
170
- shiftArrow({ element: arrowEl })
171
- );
172
- }
173
- middleware.push(transformOrigin);
174
- middleware.push(
175
- (0, import_dom2.size)({
176
- padding: options.overflowPadding,
177
- apply({ rects, availableHeight, availableWidth }) {
178
- const referenceWidth = Math.round(rects.reference.width);
179
- floating.style.setProperty("--reference-width", `${referenceWidth}px`);
180
- floating.style.setProperty("--available-width", `${availableWidth}px`);
181
- floating.style.setProperty("--available-height", `${availableHeight}px`);
182
- }
183
- })
184
- );
185
- function compute(config = {}) {
186
- const { placement, strategy, onComplete } = options;
261
+ const middleware = [
262
+ __offset(arrowEl, options),
263
+ __flip(options),
264
+ __shift(options),
265
+ __arrow(arrowEl, options),
266
+ __shiftArrow(arrowEl),
267
+ __transformOrigin,
268
+ __size(options)
269
+ ];
270
+ const { placement, strategy, onComplete, onPositioned } = options;
271
+ const updatePosition = async () => {
187
272
  if (!reference || !floating)
188
273
  return;
189
- (0, import_dom2.computePosition)(reference, floating, {
274
+ const pos = await (0, import_dom2.computePosition)(reference, floating, {
190
275
  placement,
191
276
  middleware,
192
- strategy,
193
- ...config
194
- }).then((data) => {
195
- const x = Math.round(data.x);
196
- const y = Math.round(data.y);
197
- floating.style.setProperty("--x", `${x}px`);
198
- floating.style.setProperty("--y", `${y}px`);
199
- const win = (0, import_dom_query.getWindow)(floating);
200
- const contentEl = floating.firstElementChild;
201
- if (contentEl) {
202
- const zIndex = win.getComputedStyle(contentEl).zIndex;
203
- floating.style.setProperty("--z-index", zIndex);
204
- }
205
- onComplete?.(data);
277
+ strategy
206
278
  });
207
- }
208
- compute();
209
- return (0, import_utils.callAll)(
210
- options.listeners ? autoUpdate(reference, floating, compute, options.listeners) : void 0,
211
- options.onCleanup
212
- );
213
- }
214
- function getBasePlacement(placement) {
215
- return placement.split("-")[0];
279
+ onComplete?.(pos);
280
+ onPositioned?.({ placed: true });
281
+ const win = (0, import_dom_query3.getWindow)(floating);
282
+ const x = __dpr(win, pos.x);
283
+ const y = __dpr(win, pos.y);
284
+ floating.style.setProperty("--x", `${x}px`);
285
+ floating.style.setProperty("--y", `${y}px`);
286
+ const contentEl = floating.firstElementChild;
287
+ if (contentEl) {
288
+ const zIndex = win.getComputedStyle(contentEl).zIndex;
289
+ floating.style.setProperty("--z-index", zIndex);
290
+ }
291
+ };
292
+ const update = async () => {
293
+ if (opts.updatePosition) {
294
+ await opts.updatePosition({ updatePosition });
295
+ onPositioned?.({ placed: true });
296
+ } else {
297
+ await updatePosition();
298
+ }
299
+ };
300
+ const cancelAutoUpdate = options.listeners ? autoUpdate(reference, floating, update, options.listeners) : void 0;
301
+ update();
302
+ return () => {
303
+ cancelAutoUpdate?.();
304
+ onPositioned?.({ placed: false });
305
+ options.onCleanup?.();
306
+ };
216
307
  }
217
308
  function getPlacement(referenceOrFn, floatingOrFn, opts = {}) {
218
- const { defer, ...restOptions } = opts;
219
- const func = defer ? import_dom_query.raf : (v) => v();
309
+ const { defer, ...options } = opts;
310
+ const func = defer ? import_dom_query3.raf : (v) => v();
220
311
  const cleanups = [];
221
312
  cleanups.push(
222
313
  func(() => {
223
314
  const reference = typeof referenceOrFn === "function" ? referenceOrFn() : referenceOrFn;
224
315
  const floating = typeof floatingOrFn === "function" ? floatingOrFn() : floatingOrFn;
225
- cleanups.push(getPlacementImpl(reference, floating, restOptions));
316
+ cleanups.push(getPlacementImpl(reference, floating, options));
226
317
  })
227
318
  );
228
319
  return () => {
@@ -238,7 +329,7 @@ var ARROW_FLOATING_STYLE = {
238
329
  right: "rotate(315deg)"
239
330
  };
240
331
  function getPlacementStyles(options = {}) {
241
- const { placement = "bottom", sameWidth, fitViewport, strategy = "absolute" } = options;
332
+ const { placement, sameWidth, fitViewport, strategy = "absolute" } = options;
242
333
  return {
243
334
  arrow: {
244
335
  position: "absolute",
@@ -248,7 +339,7 @@ function getPlacementStyles(options = {}) {
248
339
  [cssVars.arrowOffset.variable]: `calc(${cssVars.arrowSizeHalf.reference} * -1)`
249
340
  },
250
341
  arrowTip: {
251
- transform: ARROW_FLOATING_STYLE[placement.split("-")[0]],
342
+ transform: placement ? ARROW_FLOATING_STYLE[placement.split("-")[0]] : void 0,
252
343
  background: cssVars.arrowBg.reference,
253
344
  top: "0",
254
345
  left: "0",
@@ -266,15 +357,17 @@ function getPlacementStyles(options = {}) {
266
357
  maxHeight: fitViewport ? "var(--available-height)" : void 0,
267
358
  top: "0px",
268
359
  left: "0px",
269
- transform: `translate3d(var(--x), var(--y), 0)`,
360
+ // move off-screen if placement is not defined
361
+ transform: placement ? "translate3d(var(--x), var(--y), 0)" : "translate3d(0, -100vh, 0)",
270
362
  zIndex: "var(--z-index)"
271
363
  }
272
364
  };
273
365
  }
274
366
  // Annotate the CommonJS export names for ESM import in node:
275
367
  0 && (module.exports = {
276
- getBasePlacement,
277
368
  getPlacement,
278
- getPlacementStyles
369
+ getPlacementSide,
370
+ getPlacementStyles,
371
+ isValidPlacement
279
372
  });
280
373
  //# sourceMappingURL=index.js.map