@zag-js/popover 0.1.8 → 0.1.11

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.js CHANGED
@@ -1,25 +1,8 @@
1
1
  "use strict";
2
2
  var __defProp = Object.defineProperty;
3
- var __defProps = Object.defineProperties;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
- var __spreadValues = (a, b) => {
12
- for (var prop in b || (b = {}))
13
- if (__hasOwnProp.call(b, prop))
14
- __defNormalProp(a, prop, b[prop]);
15
- if (__getOwnPropSymbols)
16
- for (var prop of __getOwnPropSymbols(b)) {
17
- if (__propIsEnum.call(b, prop))
18
- __defNormalProp(a, prop, b[prop]);
19
- }
20
- return a;
21
- };
22
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
6
  var __export = (target, all) => {
24
7
  for (var name in all)
25
8
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -46,13 +29,115 @@ module.exports = __toCommonJS(src_exports);
46
29
  var dataAttr = (guard) => {
47
30
  return guard ? "" : void 0;
48
31
  };
49
- var hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
50
- var isLeftClick = (v) => v.button === 0;
51
32
  var runIfFn = (v, ...a) => {
52
33
  const res = typeof v === "function" ? v(...a) : v;
53
- return res != null ? res : void 0;
34
+ return res ?? void 0;
54
35
  };
55
- var pipe = (...fns) => (v) => fns.reduce((a, b) => b(a), v);
36
+ var hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
37
+ function isDocument(el) {
38
+ return el.nodeType === Node.DOCUMENT_NODE;
39
+ }
40
+ function isWindow(value) {
41
+ return (value == null ? void 0 : value.toString()) === "[object Window]";
42
+ }
43
+ function isFrame(element) {
44
+ return element.localName === "iframe";
45
+ }
46
+ function getDocument(el) {
47
+ if (isWindow(el))
48
+ return el.document;
49
+ if (isDocument(el))
50
+ return el;
51
+ return (el == null ? void 0 : el.ownerDocument) ?? document;
52
+ }
53
+ function defineDomHelpers(helpers) {
54
+ const dom2 = {
55
+ getRootNode: (ctx) => {
56
+ var _a;
57
+ return ((_a = ctx.getRootNode) == null ? void 0 : _a.call(ctx)) ?? document;
58
+ },
59
+ getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
60
+ getWin: (ctx) => dom2.getDoc(ctx).defaultView ?? window,
61
+ getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
62
+ getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id)
63
+ };
64
+ return {
65
+ ...dom2,
66
+ ...helpers
67
+ };
68
+ }
69
+ function contains(parent, child) {
70
+ if (!parent)
71
+ return false;
72
+ return parent === child || isHTMLElement(parent) && isHTMLElement(child) && parent.contains(child);
73
+ }
74
+ function isHTMLElement(v) {
75
+ return typeof v === "object" && (v == null ? void 0 : v.nodeType) === Node.ELEMENT_NODE && typeof (v == null ? void 0 : v.nodeName) === "string";
76
+ }
77
+ function isVisible(el) {
78
+ if (!isHTMLElement(el))
79
+ return false;
80
+ return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0;
81
+ }
82
+ var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
83
+ function hasNegativeTabIndex(element) {
84
+ const tabIndex = parseInt(element.getAttribute("tabindex") || "0", 10);
85
+ return tabIndex < 0;
86
+ }
87
+ var focusableSelector = "input:not([type='hidden']):not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href], button:not([disabled]), [tabindex], iframe, object, embed, area[href], audio[controls], video[controls], [contenteditable]:not([contenteditable='false']), details > summary:first-of-type";
88
+ var getFocusables = (container, includeContainer = false) => {
89
+ if (!container)
90
+ return [];
91
+ const elements = Array.from(container.querySelectorAll(focusableSelector));
92
+ const include = includeContainer == true || includeContainer == "if-empty" && elements.length === 0;
93
+ if (include && isHTMLElement(container) && isFocusable(container)) {
94
+ elements.unshift(container);
95
+ }
96
+ const focusableElements = elements.filter(isFocusable);
97
+ focusableElements.forEach((element, i) => {
98
+ if (isFrame(element) && element.contentDocument) {
99
+ const frameBody = element.contentDocument.body;
100
+ focusableElements.splice(i, 1, ...getFocusables(frameBody));
101
+ }
102
+ });
103
+ return focusableElements;
104
+ };
105
+ function isFocusable(element) {
106
+ if (!element)
107
+ return false;
108
+ return element.matches(focusableSelector) && isVisible(element);
109
+ }
110
+ function getTabbables(container, includeContainer) {
111
+ if (!container)
112
+ return [];
113
+ const elements = Array.from(container.querySelectorAll(focusableSelector));
114
+ const tabbableElements = elements.filter(isTabbable);
115
+ if (includeContainer && isTabbable(container)) {
116
+ tabbableElements.unshift(container);
117
+ }
118
+ tabbableElements.forEach((element, i) => {
119
+ if (isFrame(element) && element.contentDocument) {
120
+ const frameBody = element.contentDocument.body;
121
+ const allFrameTabbable = getTabbables(frameBody);
122
+ tabbableElements.splice(i, 1, ...allFrameTabbable);
123
+ }
124
+ });
125
+ if (!tabbableElements.length && includeContainer) {
126
+ return elements;
127
+ }
128
+ return tabbableElements;
129
+ }
130
+ function isTabbable(el) {
131
+ return isFocusable(el) && !hasNegativeTabIndex(el);
132
+ }
133
+ function getFirstTabbable(container, includeContainer) {
134
+ const [first] = getTabbables(container, includeContainer);
135
+ return first || null;
136
+ }
137
+ function getLastTabbable(container, includeContainer) {
138
+ const elements = getTabbables(container, includeContainer);
139
+ return elements[elements.length - 1] || null;
140
+ }
56
141
  var isRef = (v) => hasProp(v, "current");
57
142
  function addDomEvent(target, eventName, handler, options) {
58
143
  const node = isRef(target) ? target.current : runIfFn(target);
@@ -80,179 +165,11 @@ function raf(fn) {
80
165
  globalThis.cancelAnimationFrame(id);
81
166
  };
82
167
  }
83
- var changeCount = 0;
84
- var originalBodyPointerEvents;
85
- function preventBodyPointerEvents(el, opts = {}) {
86
- const { disabled = false, document: docProp } = opts;
87
- const doc = docProp || document;
88
- let isTouchOrPenPressed = false;
89
- let isLeftClickPressed = false;
90
- function listen() {
91
- const onPointerDown = (event) => {
92
- const isMouse = event.pointerType === "mouse";
93
- isTouchOrPenPressed = !isMouse;
94
- isLeftClickPressed = isMouse && isLeftClick(event);
95
- };
96
- const onPointerUp = () => {
97
- isTouchOrPenPressed = false;
98
- isLeftClickPressed = false;
99
- };
100
- return pipe(addDomEvent(doc, "pointerdown", onPointerDown), addDomEvent(doc, "pointerup", onPointerUp));
101
- }
102
- function reset() {
103
- changeCount--;
104
- if (changeCount === 0) {
105
- doc.body.style.pointerEvents = originalBodyPointerEvents;
106
- }
107
- if (el) {
108
- el.style.pointerEvents = "";
109
- }
110
- }
111
- function apply() {
112
- if (disabled)
113
- return;
114
- if (changeCount === 0) {
115
- originalBodyPointerEvents = doc.body.style.pointerEvents;
116
- }
117
- doc.body.style.pointerEvents = "none";
118
- if (el) {
119
- el.style.pointerEvents = "auto";
120
- }
121
- changeCount++;
122
- return function() {
123
- if (isTouchOrPenPressed) {
124
- addDomEvent(doc, "click", reset, { once: true });
125
- } else if (isLeftClickPressed) {
126
- addDomEvent(doc, "pointerup", reset, { once: true });
127
- } else {
128
- reset();
129
- }
130
- };
131
- }
132
- const cleanups = [];
133
- cleanups.push(apply());
134
- nextTick(() => {
135
- cleanups.push(listen());
136
- });
137
- return function() {
138
- cleanups.forEach((cleanup) => cleanup == null ? void 0 : cleanup());
139
- };
140
- }
141
- function getStyleCache() {
142
- ;
143
- globalThis.__styleCache__ = globalThis.__styleCache__ || /* @__PURE__ */ new WeakMap();
144
- return globalThis.__styleCache__;
145
- }
146
- function getComputedStyle(el) {
147
- var _a;
148
- if (!el)
149
- return {};
150
- const cache = getStyleCache();
151
- let style = cache.get(el);
152
- if (!style) {
153
- const win = (_a = el == null ? void 0 : el.ownerDocument.defaultView) != null ? _a : window;
154
- style = win.getComputedStyle(el);
155
- cache.set(el, style);
156
- }
157
- return style;
158
- }
159
- function contains(parent, child) {
160
- if (!parent)
161
- return false;
162
- return parent === child || isHTMLElement(parent) && isHTMLElement(child) && parent.contains(child);
163
- }
164
- function isHTMLElement(v) {
165
- return typeof v === "object" && (v == null ? void 0 : v.nodeType) === Node.ELEMENT_NODE && typeof (v == null ? void 0 : v.nodeName) === "string";
166
- }
167
- var isDisabled = (el) => {
168
- return (el == null ? void 0 : el.getAttribute("disabled")) != null || !!(el == null ? void 0 : el.getAttribute("aria-disabled")) === true;
169
- };
170
- function validateBlur(event, opts) {
171
- var _a;
172
- const exclude = Array.isArray(opts.exclude) ? opts.exclude : [opts.exclude];
173
- const relatedTarget = (_a = event.relatedTarget) != null ? _a : opts.fallback;
174
- return exclude.every((el) => !(el == null ? void 0 : el.contains(relatedTarget)));
175
- }
176
- var focusableSelector = /* @__PURE__ */ [
177
- "input:not([disabled]):not([type=hidden])",
178
- "select:not([disabled])",
179
- "textarea:not([disabled])",
180
- "button:not([disabled])",
181
- "embed",
182
- "iframe",
183
- "object",
184
- "a[href]",
185
- "area[href]",
186
- "[tabindex]",
187
- "audio[controls]",
188
- "video[controls]",
189
- "*[tabindex]:not([aria-disabled])",
190
- "[contenteditable]:not([contenteditable=false])",
191
- "details > summary:first-of-type"
192
- ].join(",");
193
- function isHidden(el, until) {
194
- const style = getComputedStyle(el);
195
- if (!el || style.getPropertyValue("visibility") === "hidden")
196
- return true;
197
- while (el) {
198
- if (until != null && el === until)
199
- return false;
200
- if (style.getPropertyValue("display") === "none")
201
- return true;
202
- el = el.parentElement;
203
- }
204
- return false;
205
- }
206
- var getFocusables = (el, includeContainer = false) => {
207
- if (!el)
208
- return [];
209
- let els = Array.from(el.querySelectorAll(focusableSelector));
210
- const shouldAddContainer = includeContainer == true || includeContainer == "if-empty" && els.length === 0;
211
- if (shouldAddContainer && isHTMLElement(el)) {
212
- els.unshift(el);
213
- }
214
- return els.filter((el2) => isFocusable(el2) && !isHidden(el2));
215
- };
216
- var isFocusable = (el) => {
217
- if (!isHTMLElement(el) || isHidden(el) || isDisabled(el))
218
- return false;
219
- return el == null ? void 0 : el.matches(focusableSelector);
220
- };
221
- var getTabbables = (el, includeContainer = false) => {
222
- if (!el)
223
- return [];
224
- return getFocusables(el, includeContainer).filter(isTabbable);
225
- };
226
- var isTabbable = (el) => {
227
- return isFocusable(el) && !isDisabled(el) && !isHidden(el);
228
- };
229
- function trackPointerDown(doc, onPointerDown) {
230
- var _a;
231
- const win = (_a = doc.defaultView) != null ? _a : window;
232
- const fn = (event) => {
233
- if (event.target instanceof win.HTMLElement) {
234
- onPointerDown(event.target);
235
- }
236
- };
237
- return addDomEvent(doc, "pointerdown", fn);
238
- }
239
168
 
240
169
  // src/popover.connect.ts
241
170
  var import_popper = require("@zag-js/popper");
242
171
 
243
- // ../../types/dist/index.mjs
244
- function createNormalizer(fn) {
245
- return new Proxy({}, {
246
- get() {
247
- return fn;
248
- }
249
- });
250
- }
251
- var normalizeProp = createNormalizer((v) => v);
252
-
253
172
  // ../../utilities/core/dist/index.mjs
254
- var first = (v) => v[0];
255
- var last = (v) => v[v.length - 1];
256
173
  function nextIndex(v, idx, opts = {}) {
257
174
  const { step = 1, loop = true } = opts;
258
175
  const next2 = idx + step;
@@ -271,59 +188,50 @@ function next(v, idx, opts = {}) {
271
188
  }
272
189
  var runIfFn2 = (v, ...a) => {
273
190
  const res = typeof v === "function" ? v(...a) : v;
274
- return res != null ? res : void 0;
191
+ return res ?? void 0;
275
192
  };
276
- var cast = (v) => v;
277
193
 
278
194
  // src/popover.dom.ts
279
- var dom = {
280
- getDoc: (ctx) => {
281
- var _a;
282
- return (_a = ctx.doc) != null ? _a : document;
283
- },
195
+ var dom = defineDomHelpers({
284
196
  getActiveEl: (ctx) => dom.getDoc(ctx).activeElement,
285
- getRootNode: (ctx) => {
286
- var _a;
287
- return (_a = ctx.rootNode) != null ? _a : dom.getDoc(ctx);
288
- },
289
197
  getAnchorId: (ctx) => {
290
- var _a, _b;
291
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.anchor) != null ? _b : `popover:${ctx.uid}:anchor`;
198
+ var _a;
199
+ return ((_a = ctx.ids) == null ? void 0 : _a.anchor) ?? `popover:${ctx.id}:anchor`;
292
200
  },
293
201
  getTriggerId: (ctx) => {
294
- var _a, _b;
295
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.trigger) != null ? _b : `popover:${ctx.uid}:trigger`;
202
+ var _a;
203
+ return ((_a = ctx.ids) == null ? void 0 : _a.trigger) ?? `popover:${ctx.id}:trigger`;
296
204
  },
297
205
  getContentId: (ctx) => {
298
- var _a, _b;
299
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.content) != null ? _b : `popover:${ctx.uid}:content`;
206
+ var _a;
207
+ return ((_a = ctx.ids) == null ? void 0 : _a.content) ?? `popover:${ctx.id}:content`;
300
208
  },
301
- getPositionerId: (ctx) => `popover:${ctx.uid}:popper`,
302
- getArrowId: (ctx) => `popover:${ctx.uid}:arrow`,
209
+ getPositionerId: (ctx) => `popover:${ctx.id}:popper`,
210
+ getArrowId: (ctx) => `popover:${ctx.id}:arrow`,
303
211
  getTitleId: (ctx) => {
304
- var _a, _b;
305
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.title) != null ? _b : `popover:${ctx.uid}:title`;
212
+ var _a;
213
+ return ((_a = ctx.ids) == null ? void 0 : _a.title) ?? `popover:${ctx.id}:title`;
306
214
  },
307
215
  getDescriptionId: (ctx) => {
308
- var _a, _b;
309
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.description) != null ? _b : `popover:${ctx.uid}:desc`;
216
+ var _a;
217
+ return ((_a = ctx.ids) == null ? void 0 : _a.description) ?? `popover:${ctx.id}:desc`;
310
218
  },
311
219
  getCloseButtonId: (ctx) => {
312
- var _a, _b;
313
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.closeBtn) != null ? _b : `popover:${ctx.uid}:close-button`;
220
+ var _a;
221
+ return ((_a = ctx.ids) == null ? void 0 : _a.closeBtn) ?? `popover:${ctx.id}:close-button`;
314
222
  },
315
- getAnchorEl: (ctx) => dom.getRootNode(ctx).getElementById(dom.getAnchorId(ctx)),
316
- getTriggerEl: (ctx) => dom.getRootNode(ctx).getElementById(dom.getTriggerId(ctx)),
317
- getContentEl: (ctx) => dom.getRootNode(ctx).getElementById(dom.getContentId(ctx)),
318
- getPositionerEl: (ctx) => dom.getRootNode(ctx).getElementById(dom.getPositionerId(ctx)),
319
- getTitleEl: (ctx) => dom.getRootNode(ctx).getElementById(dom.getTitleId(ctx)),
320
- getDescriptionEl: (ctx) => dom.getRootNode(ctx).getElementById(dom.getDescriptionId(ctx)),
223
+ getAnchorEl: (ctx) => dom.getById(ctx, dom.getAnchorId(ctx)),
224
+ getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx)),
225
+ getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
226
+ getPositionerEl: (ctx) => dom.getById(ctx, dom.getPositionerId(ctx)),
227
+ getTitleEl: (ctx) => dom.getById(ctx, dom.getTitleId(ctx)),
228
+ getDescriptionEl: (ctx) => dom.getById(ctx, dom.getDescriptionId(ctx)),
321
229
  getFocusableEls: (ctx) => getFocusables(dom.getContentEl(ctx)),
322
230
  getFirstFocusableEl: (ctx) => dom.getFocusableEls(ctx)[0],
323
- getDocTabbableEls: (ctx) => getTabbables(cast(dom.getDoc(ctx))),
231
+ getDocTabbableEls: (ctx) => getTabbables(dom.getDoc(ctx).body),
324
232
  getTabbableEls: (ctx) => getTabbables(dom.getContentEl(ctx), "if-empty"),
325
- getFirstTabbableEl: (ctx) => first(dom.getTabbableEls(ctx)),
326
- getLastTabbableEl: (ctx) => last(dom.getTabbableEls(ctx)),
233
+ getFirstTabbableEl: (ctx) => getFirstTabbable(dom.getContentEl(ctx), "if-empty"),
234
+ getLastTabbableEl: (ctx) => getLastTabbable(dom.getContentEl(ctx), "if-empty"),
327
235
  getInitialFocusEl: (ctx) => {
328
236
  let el = runIfFn2(ctx.initialFocusEl);
329
237
  if (!el && ctx.autoFocus)
@@ -332,19 +240,20 @@ var dom = {
332
240
  el = dom.getContentEl(ctx);
333
241
  return el;
334
242
  }
335
- };
243
+ });
336
244
 
337
245
  // src/popover.connect.ts
338
- function connect(state, send, normalize = normalizeProp) {
246
+ function connect(state, send, normalize) {
339
247
  const isOpen = state.matches("open");
340
- const pointerdownNode = state.context.pointerdownNode;
341
248
  const currentPlacement = state.context.currentPlacement;
249
+ const portalled = state.context.currentPortalled;
250
+ const rendered = state.context.renderedElements;
342
251
  const popperStyles = (0, import_popper.getPlacementStyles)({
343
252
  measured: !!state.context.isPlacementComplete,
344
253
  placement: currentPlacement
345
254
  });
346
255
  return {
347
- portalled: state.context.currentPortalled,
256
+ portalled,
348
257
  isOpen,
349
258
  open() {
350
259
  send("OPEN");
@@ -375,12 +284,10 @@ function connect(state, send, normalize = normalizeProp) {
375
284
  "data-expanded": dataAttr(isOpen),
376
285
  "aria-controls": dom.getContentId(state.context),
377
286
  onClick() {
378
- send("TRIGGER_CLICK");
287
+ send("TOGGLE");
379
288
  },
380
- onKeyDown(event) {
381
- if (event.key === "Escape") {
382
- send("ESCAPE");
383
- }
289
+ onBlur(event) {
290
+ send({ type: "TRIGGER_BLUR", target: event.relatedTarget });
384
291
  }
385
292
  }),
386
293
  positionerProps: normalize.element({
@@ -395,34 +302,9 @@ function connect(state, send, normalize = normalizeProp) {
395
302
  role: "dialog",
396
303
  hidden: !isOpen,
397
304
  "data-expanded": dataAttr(isOpen),
398
- "aria-labelledby": state.context.renderedElements.title ? dom.getTitleId(state.context) : void 0,
399
- "aria-describedby": state.context.renderedElements.description ? dom.getDescriptionId(state.context) : void 0,
400
- "data-placement": currentPlacement,
401
- onKeyDown(event) {
402
- const keyMap = {
403
- Escape(event2) {
404
- send("ESCAPE");
405
- event2.stopPropagation();
406
- },
407
- Tab(event2) {
408
- const type = event2.shiftKey ? "SHIFT_TAB" : "TAB";
409
- send({ type, preventDefault: () => event2.preventDefault() });
410
- }
411
- };
412
- const exec = keyMap[event.key];
413
- exec == null ? void 0 : exec(event);
414
- },
415
- onBlur(event) {
416
- var _a;
417
- const isValidBlur = validateBlur(event, {
418
- exclude: [dom.getTriggerEl(state.context), dom.getContentEl(state.context)],
419
- fallback: pointerdownNode
420
- });
421
- if (isValidBlur) {
422
- const el = (_a = event.relatedTarget) != null ? _a : pointerdownNode;
423
- send({ type: "INTERACT_OUTSIDE", focusable: isFocusable(el) });
424
- }
425
- }
305
+ "aria-labelledby": rendered.title ? dom.getTitleId(state.context) : void 0,
306
+ "aria-describedby": rendered.description ? dom.getDescriptionId(state.context) : void 0,
307
+ "data-placement": currentPlacement
426
308
  }),
427
309
  titleProps: normalize.element({
428
310
  "data-part": "title",
@@ -438,7 +320,7 @@ function connect(state, send, normalize = normalizeProp) {
438
320
  type: "button",
439
321
  "aria-label": "close",
440
322
  onClick() {
441
- send("CLOSE");
323
+ send("REQUEST_CLOSE");
442
324
  }
443
325
  })
444
326
  };
@@ -447,31 +329,33 @@ function connect(state, send, normalize = normalizeProp) {
447
329
  // src/popover.machine.ts
448
330
  var import_aria_hidden = require("@zag-js/aria-hidden");
449
331
  var import_core = require("@zag-js/core");
332
+ var import_dismissable = require("@zag-js/dismissable");
450
333
  var import_popper2 = require("@zag-js/popper");
451
334
  var import_remove_scroll = require("@zag-js/remove-scroll");
452
335
  var import_focus_trap = require("focus-trap");
453
- var { and, or } = import_core.guards;
454
- function machine(ctx = {}) {
336
+ var { and, or, not } = import_core.guards;
337
+ function machine(ctx) {
455
338
  return (0, import_core.createMachine)({
456
339
  id: "popover",
457
340
  initial: "unknown",
458
- context: __spreadProps(__spreadValues({
459
- uid: "",
460
- closeOnBlur: true,
341
+ context: {
342
+ closeOnInteractOutside: true,
461
343
  closeOnEsc: true,
462
344
  autoFocus: true,
463
345
  modal: false,
464
- positioning: __spreadValues({
465
- placement: "bottom"
466
- }, ctx.positioning),
467
- currentPlacement: void 0
468
- }, ctx), {
346
+ positioning: {
347
+ placement: "bottom",
348
+ ...ctx.positioning
349
+ },
350
+ currentPlacement: void 0,
351
+ ...ctx,
352
+ focusTriggerOnClose: true,
469
353
  renderedElements: {
470
354
  title: true,
471
355
  description: true,
472
356
  anchor: false
473
357
  }
474
- }),
358
+ },
475
359
  computed: {
476
360
  currentPortalled: (ctx2) => !!ctx2.modal || !!ctx2.portalled
477
361
  },
@@ -479,63 +363,54 @@ function machine(ctx = {}) {
479
363
  unknown: {
480
364
  on: {
481
365
  SETUP: {
482
- target: ctx.open ? "open" : "closed",
483
- actions: ["setupDocument", "checkRenderedElements"]
366
+ target: ctx.defaultOpen ? "open" : "closed",
367
+ actions: "checkRenderedElements"
484
368
  }
485
369
  }
486
370
  },
487
371
  closed: {
488
- entry: ["clearPointerDown", "invokeOnClose"],
372
+ entry: "invokeOnClose",
489
373
  on: {
490
- TRIGGER_CLICK: "open",
374
+ TOGGLE: "open",
491
375
  OPEN: "open"
492
376
  }
493
377
  },
494
378
  open: {
495
379
  activities: [
496
- "trackPointerDown",
497
380
  "trapFocus",
498
381
  "preventScroll",
499
382
  "hideContentBelow",
500
- "disableOutsidePointerEvents",
501
- "computePlacement"
383
+ "computePlacement",
384
+ "trackInteractionOutside",
385
+ "trackTabKeyDown"
502
386
  ],
503
387
  entry: ["setInitialFocus", "invokeOnOpen"],
504
388
  on: {
505
- CLOSE: {
506
- target: "closed",
507
- actions: "focusTrigger"
508
- },
509
- TRIGGER_CLICK: {
510
- target: "closed",
511
- actions: "focusTrigger"
512
- },
513
- ESCAPE: {
514
- guard: "closeOnEsc",
515
- target: "closed",
516
- actions: "focusTrigger"
517
- },
518
- TAB: {
519
- guard: and("isLastTabbableElement", "closeOnBlur", "portalled"),
389
+ CLOSE: "closed",
390
+ REQUEST_CLOSE: {
520
391
  target: "closed",
521
- actions: "focusNextTabbableElementAfterTrigger"
392
+ actions: "focusTriggerIfNeeded"
522
393
  },
523
- SHIFT_TAB: {
524
- guard: and(or("isFirstTabbableElement", "isContentFocused"), "closeOnBlur", "portalled"),
525
- target: "closed",
526
- actions: "focusTrigger"
394
+ TOGGLE: "closed",
395
+ TRIGGER_BLUR: {
396
+ guard: not("isRelatedTargetWithinContent"),
397
+ target: "closed"
527
398
  },
528
- INTERACT_OUTSIDE: [
399
+ TAB: [
529
400
  {
530
- guard: and("closeOnBlur", "isRelatedTargetFocusable"),
531
- target: "closed"
401
+ guard: and("isTriggerFocused", "portalled"),
402
+ actions: "focusFirstTabbableElement"
532
403
  },
533
404
  {
534
- guard: "closeOnBlur",
405
+ guard: and("isLastTabbableElement", "closeOnInteractOutside", "portalled"),
535
406
  target: "closed",
536
- actions: "focusTrigger"
407
+ actions: "focusNextTabbableElementAfterTrigger"
537
408
  }
538
- ]
409
+ ],
410
+ SHIFT_TAB: {
411
+ guard: and(or("isFirstTabbableElement", "isContentFocused"), "portalled"),
412
+ actions: "focusTriggerIfNeeded"
413
+ }
539
414
  }
540
415
  }
541
416
  }
@@ -544,7 +419,8 @@ function machine(ctx = {}) {
544
419
  computePlacement(ctx2) {
545
420
  ctx2.currentPlacement = ctx2.positioning.placement;
546
421
  const anchorEl = ctx2.renderedElements.anchor ? dom.getAnchorEl(ctx2) : dom.getTriggerEl(ctx2);
547
- return (0, import_popper2.getPlacement)(anchorEl, dom.getPositionerEl(ctx2), __spreadProps(__spreadValues({}, ctx2.positioning), {
422
+ return (0, import_popper2.getPlacement)(anchorEl, dom.getPositionerEl(ctx2), {
423
+ ...ctx2.positioning,
548
424
  onComplete(data) {
549
425
  ctx2.currentPlacement = data.placement;
550
426
  ctx2.isPlacementComplete = true;
@@ -553,34 +429,72 @@ function machine(ctx = {}) {
553
429
  ctx2.currentPlacement = void 0;
554
430
  ctx2.isPlacementComplete = false;
555
431
  }
556
- }));
557
- },
558
- trackPointerDown(ctx2) {
559
- return trackPointerDown(dom.getDoc(ctx2), (el) => {
560
- ctx2.pointerdownNode = (0, import_core.ref)(el);
561
432
  });
562
433
  },
563
- disableOutsidePointerEvents(ctx2) {
564
- const el = dom.getContentEl(ctx2);
565
- return preventBodyPointerEvents(el, {
566
- document: dom.getDoc(ctx2),
567
- disabled: !ctx2.modal
434
+ trackInteractionOutside(ctx2, _evt, { send }) {
435
+ return (0, import_dismissable.trackDismissableElement)(dom.getContentEl(ctx2), {
436
+ pointerBlocking: ctx2.modal,
437
+ exclude: dom.getTriggerEl(ctx2),
438
+ onEscapeKeyDown(event) {
439
+ var _a;
440
+ (_a = ctx2.onEscapeKeyDown) == null ? void 0 : _a.call(ctx2, event);
441
+ if (ctx2.closeOnEsc)
442
+ return;
443
+ ctx2.focusTriggerOnClose = true;
444
+ event.preventDefault();
445
+ },
446
+ onInteractOutside(event) {
447
+ var _a;
448
+ (_a = ctx2.onInteractOutside) == null ? void 0 : _a.call(ctx2, event);
449
+ if (event.defaultPrevented)
450
+ return;
451
+ ctx2.focusTriggerOnClose = !(event.detail.focusable || event.detail.contextmenu);
452
+ if (!ctx2.closeOnInteractOutside) {
453
+ event.preventDefault();
454
+ }
455
+ },
456
+ onPointerDownOutside(event) {
457
+ var _a;
458
+ (_a = ctx2.onPointerDownOutside) == null ? void 0 : _a.call(ctx2, event);
459
+ },
460
+ onFocusOutside(event) {
461
+ var _a;
462
+ (_a = ctx2.onFocusOutside) == null ? void 0 : _a.call(ctx2, event);
463
+ if (ctx2.currentPortalled) {
464
+ event.preventDefault();
465
+ }
466
+ },
467
+ onDismiss() {
468
+ send({ type: "REQUEST_CLOSE", src: "#interact-outside" });
469
+ }
568
470
  });
569
471
  },
472
+ trackTabKeyDown(ctx2, _evt, { send }) {
473
+ if (ctx2.modal)
474
+ return;
475
+ return addDomEvent(dom.getWin(ctx2), "keydown", (event) => {
476
+ const isTabKey = event.key === "Tab" && !isModifiedEvent(event);
477
+ if (!isTabKey)
478
+ return;
479
+ send({
480
+ type: event.shiftKey ? "SHIFT_TAB" : "TAB",
481
+ preventDefault: () => event.preventDefault()
482
+ });
483
+ }, true);
484
+ },
570
485
  hideContentBelow(ctx2) {
571
486
  if (!ctx2.modal)
572
487
  return;
573
- let unhide;
488
+ let cleanup;
574
489
  nextTick(() => {
575
- unhide = (0, import_aria_hidden.ariaHidden)([dom.getContentEl(ctx2), dom.getTriggerEl(ctx2)]);
490
+ cleanup = (0, import_aria_hidden.ariaHidden)([dom.getContentEl(ctx2), dom.getTriggerEl(ctx2)]);
576
491
  });
577
- return () => unhide == null ? void 0 : unhide();
492
+ return () => cleanup == null ? void 0 : cleanup();
578
493
  },
579
494
  preventScroll(ctx2) {
580
- return (0, import_remove_scroll.preventBodyScroll)({
581
- disabled: !ctx2.modal,
582
- document: dom.getDoc(ctx2)
583
- });
495
+ if (!ctx2.modal)
496
+ return;
497
+ return (0, import_remove_scroll.preventBodyScroll)(dom.getDoc(ctx2));
584
498
  },
585
499
  trapFocus(ctx2) {
586
500
  if (!ctx2.modal)
@@ -600,20 +514,18 @@ function machine(ctx = {}) {
600
514
  });
601
515
  try {
602
516
  trap.activate();
603
- } catch (e) {
517
+ } catch {
604
518
  }
605
519
  });
606
520
  return () => trap == null ? void 0 : trap.deactivate();
607
521
  }
608
522
  },
609
523
  guards: {
610
- closeOnEsc: (ctx2) => !!ctx2.closeOnEsc,
611
- autoFocus: (ctx2) => !!ctx2.autoFocus,
612
- modal: (ctx2) => !!ctx2.modal,
613
- portalled: (ctx2) => !!ctx2.portalled,
614
- isRelatedTargetFocusable: (_ctx, evt) => evt.focusable,
615
- closeOnBlur: (ctx2) => !!ctx2.closeOnBlur,
524
+ portalled: (ctx2) => ctx2.currentPortalled,
525
+ isRelatedTargetWithinContent: (ctx2, evt) => contains(dom.getContentEl(ctx2), evt.target),
526
+ closeOnInteractOutside: (ctx2) => !!ctx2.closeOnInteractOutside,
616
527
  isContentFocused: (ctx2) => dom.getContentEl(ctx2) === dom.getActiveEl(ctx2),
528
+ isTriggerFocused: (ctx2) => dom.getTriggerEl(ctx2) === dom.getActiveEl(ctx2),
617
529
  isFirstTabbableElement: (ctx2) => dom.getFirstTabbableEl(ctx2) === dom.getActiveEl(ctx2),
618
530
  isLastTabbableElement: (ctx2) => dom.getLastTabbableEl(ctx2) === dom.getActiveEl(ctx2)
619
531
  },
@@ -627,48 +539,44 @@ function machine(ctx = {}) {
627
539
  });
628
540
  });
629
541
  },
630
- setupDocument(ctx2, evt) {
631
- if (evt.doc)
632
- ctx2.doc = (0, import_core.ref)(evt.doc);
633
- if (evt.root)
634
- ctx2.rootNode = (0, import_core.ref)(evt.root);
635
- ctx2.uid = evt.id;
636
- },
637
- clearPointerDown(ctx2) {
638
- ctx2.pointerdownNode = null;
639
- },
640
542
  setInitialFocus(ctx2) {
641
543
  raf(() => {
642
544
  var _a;
643
545
  (_a = dom.getInitialFocusEl(ctx2)) == null ? void 0 : _a.focus();
644
546
  });
645
547
  },
646
- focusTrigger(ctx2) {
548
+ focusTriggerIfNeeded(ctx2) {
549
+ if (!ctx2.focusTriggerOnClose)
550
+ return;
647
551
  raf(() => {
648
552
  var _a;
649
- (_a = dom.getTriggerEl(ctx2)) == null ? void 0 : _a.focus();
553
+ return (_a = dom.getTriggerEl(ctx2)) == null ? void 0 : _a.focus();
650
554
  });
651
555
  },
556
+ focusFirstTabbableElement(ctx2, evt) {
557
+ var _a;
558
+ evt.preventDefault();
559
+ (_a = dom.getFirstTabbableEl(ctx2)) == null ? void 0 : _a.focus();
560
+ },
652
561
  invokeOnOpen(ctx2, evt) {
653
562
  var _a;
654
563
  if (evt.type !== "SETUP") {
655
- (_a = ctx2.onOpen) == null ? void 0 : _a.call(ctx2);
564
+ (_a = ctx2.onOpenChange) == null ? void 0 : _a.call(ctx2, true);
656
565
  }
657
566
  },
658
567
  invokeOnClose(ctx2, evt) {
659
568
  var _a;
660
569
  if (evt.type !== "SETUP") {
661
- (_a = ctx2.onClose) == null ? void 0 : _a.call(ctx2);
570
+ (_a = ctx2.onOpenChange) == null ? void 0 : _a.call(ctx2, false);
662
571
  }
663
572
  },
664
573
  focusNextTabbableElementAfterTrigger(ctx2, evt) {
665
574
  const content = dom.getContentEl(ctx2);
666
- const doc = dom.getDoc(ctx2);
667
575
  const button = dom.getTriggerEl(ctx2);
668
576
  if (!content || !button)
669
577
  return;
670
578
  const lastTabbable = dom.getLastTabbableEl(ctx2);
671
- if (lastTabbable !== doc.activeElement)
579
+ if (lastTabbable !== dom.getActiveEl(ctx2))
672
580
  return;
673
581
  let tabbables = dom.getDocTabbableEls(ctx2);
674
582
  let elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
@@ -684,3 +592,8 @@ function machine(ctx = {}) {
684
592
  }
685
593
  });
686
594
  }
595
+ // Annotate the CommonJS export names for ESM import in node:
596
+ 0 && (module.exports = {
597
+ connect,
598
+ machine
599
+ });