@zag-js/popover 0.2.5 → 0.2.6

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.
@@ -0,0 +1,191 @@
1
+ // ../../utilities/core/src/functions.ts
2
+ var runIfFn = (v, ...a) => {
3
+ const res = typeof v === "function" ? v(...a) : v;
4
+ return res != null ? res : void 0;
5
+ };
6
+
7
+ // ../../utilities/dom/src/query.ts
8
+ function isDocument(el) {
9
+ return el.nodeType === Node.DOCUMENT_NODE;
10
+ }
11
+ function isWindow(value) {
12
+ return (value == null ? void 0 : value.toString()) === "[object Window]";
13
+ }
14
+ function isFrame(element) {
15
+ return element.localName === "iframe";
16
+ }
17
+ function getDocument(el) {
18
+ var _a;
19
+ if (isWindow(el))
20
+ return el.document;
21
+ if (isDocument(el))
22
+ return el;
23
+ return (_a = el == null ? void 0 : el.ownerDocument) != null ? _a : document;
24
+ }
25
+ function defineDomHelpers(helpers) {
26
+ const dom2 = {
27
+ getRootNode: (ctx) => {
28
+ var _a, _b;
29
+ return (_b = (_a = ctx.getRootNode) == null ? void 0 : _a.call(ctx)) != null ? _b : document;
30
+ },
31
+ getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
32
+ getWin: (ctx) => {
33
+ var _a;
34
+ return (_a = dom2.getDoc(ctx).defaultView) != null ? _a : window;
35
+ },
36
+ getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
37
+ getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id),
38
+ createEmitter: (ctx, target) => {
39
+ const win = dom2.getWin(ctx);
40
+ return function emit(evt, detail, options) {
41
+ const { bubbles = true, cancelable, composed = true } = options != null ? options : {};
42
+ const eventName = `zag:${evt}`;
43
+ const init = { bubbles, cancelable, composed, detail };
44
+ const event = new win.CustomEvent(eventName, init);
45
+ target.dispatchEvent(event);
46
+ };
47
+ },
48
+ createListener: (target) => {
49
+ return function listen(evt, handler) {
50
+ const eventName = `zag:${evt}`;
51
+ const listener = (e) => handler(e);
52
+ target.addEventListener(eventName, listener);
53
+ return () => target.removeEventListener(eventName, listener);
54
+ };
55
+ }
56
+ };
57
+ return {
58
+ ...dom2,
59
+ ...helpers
60
+ };
61
+ }
62
+ function contains(parent, child) {
63
+ if (!parent)
64
+ return false;
65
+ return parent === child || isHTMLElement(parent) && isHTMLElement(child) && parent.contains(child);
66
+ }
67
+ function isHTMLElement(v) {
68
+ return typeof v === "object" && (v == null ? void 0 : v.nodeType) === Node.ELEMENT_NODE && typeof (v == null ? void 0 : v.nodeName) === "string";
69
+ }
70
+ function isVisible(el) {
71
+ if (!isHTMLElement(el))
72
+ return false;
73
+ return el.offsetWidth > 0 || el.offsetHeight > 0 || el.getClientRects().length > 0;
74
+ }
75
+
76
+ // ../../utilities/dom/src/focusable.ts
77
+ function hasNegativeTabIndex(element) {
78
+ const tabIndex = parseInt(element.getAttribute("tabindex") || "0", 10);
79
+ return tabIndex < 0;
80
+ }
81
+ 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";
82
+ var getFocusables = (container, includeContainer = false) => {
83
+ if (!container)
84
+ return [];
85
+ const elements = Array.from(container.querySelectorAll(focusableSelector));
86
+ const include = includeContainer == true || includeContainer == "if-empty" && elements.length === 0;
87
+ if (include && isHTMLElement(container) && isFocusable(container)) {
88
+ elements.unshift(container);
89
+ }
90
+ const focusableElements = elements.filter(isFocusable);
91
+ focusableElements.forEach((element, i) => {
92
+ if (isFrame(element) && element.contentDocument) {
93
+ const frameBody = element.contentDocument.body;
94
+ focusableElements.splice(i, 1, ...getFocusables(frameBody));
95
+ }
96
+ });
97
+ return focusableElements;
98
+ };
99
+ function isFocusable(element) {
100
+ if (!element)
101
+ return false;
102
+ return element.matches(focusableSelector) && isVisible(element);
103
+ }
104
+ function getTabbables(container, includeContainer) {
105
+ if (!container)
106
+ return [];
107
+ const elements = Array.from(container.querySelectorAll(focusableSelector));
108
+ const tabbableElements = elements.filter(isTabbable);
109
+ if (includeContainer && isTabbable(container)) {
110
+ tabbableElements.unshift(container);
111
+ }
112
+ tabbableElements.forEach((element, i) => {
113
+ if (isFrame(element) && element.contentDocument) {
114
+ const frameBody = element.contentDocument.body;
115
+ const allFrameTabbable = getTabbables(frameBody);
116
+ tabbableElements.splice(i, 1, ...allFrameTabbable);
117
+ }
118
+ });
119
+ if (!tabbableElements.length && includeContainer) {
120
+ return elements;
121
+ }
122
+ return tabbableElements;
123
+ }
124
+ function isTabbable(el) {
125
+ return isFocusable(el) && !hasNegativeTabIndex(el);
126
+ }
127
+ function getFirstTabbable(container, includeContainer) {
128
+ const [first] = getTabbables(container, includeContainer);
129
+ return first || null;
130
+ }
131
+ function getLastTabbable(container, includeContainer) {
132
+ const elements = getTabbables(container, includeContainer);
133
+ return elements[elements.length - 1] || null;
134
+ }
135
+
136
+ // src/popover.dom.ts
137
+ var dom = defineDomHelpers({
138
+ getActiveEl: (ctx) => dom.getDoc(ctx).activeElement,
139
+ getAnchorId: (ctx) => {
140
+ var _a, _b;
141
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.anchor) != null ? _b : `popover:${ctx.id}:anchor`;
142
+ },
143
+ getTriggerId: (ctx) => {
144
+ var _a, _b;
145
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.trigger) != null ? _b : `popover:${ctx.id}:trigger`;
146
+ },
147
+ getContentId: (ctx) => {
148
+ var _a, _b;
149
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.content) != null ? _b : `popover:${ctx.id}:content`;
150
+ },
151
+ getPositionerId: (ctx) => `popover:${ctx.id}:popper`,
152
+ getArrowId: (ctx) => `popover:${ctx.id}:arrow`,
153
+ getTitleId: (ctx) => {
154
+ var _a, _b;
155
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.title) != null ? _b : `popover:${ctx.id}:title`;
156
+ },
157
+ getDescriptionId: (ctx) => {
158
+ var _a, _b;
159
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.description) != null ? _b : `popover:${ctx.id}:desc`;
160
+ },
161
+ getCloseTriggerId: (ctx) => {
162
+ var _a, _b;
163
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.closeTrigger) != null ? _b : `popover:${ctx.id}:close`;
164
+ },
165
+ getAnchorEl: (ctx) => dom.getById(ctx, dom.getAnchorId(ctx)),
166
+ getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx)),
167
+ getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
168
+ getPositionerEl: (ctx) => dom.getById(ctx, dom.getPositionerId(ctx)),
169
+ getTitleEl: (ctx) => dom.getById(ctx, dom.getTitleId(ctx)),
170
+ getDescriptionEl: (ctx) => dom.getById(ctx, dom.getDescriptionId(ctx)),
171
+ getFocusableEls: (ctx) => getFocusables(dom.getContentEl(ctx)),
172
+ getFirstFocusableEl: (ctx) => dom.getFocusableEls(ctx)[0],
173
+ getDocTabbableEls: (ctx) => getTabbables(dom.getDoc(ctx).body),
174
+ getTabbableEls: (ctx) => getTabbables(dom.getContentEl(ctx), "if-empty"),
175
+ getFirstTabbableEl: (ctx) => getFirstTabbable(dom.getContentEl(ctx), "if-empty"),
176
+ getLastTabbableEl: (ctx) => getLastTabbable(dom.getContentEl(ctx), "if-empty"),
177
+ getInitialFocusEl: (ctx) => {
178
+ let el = runIfFn(ctx.initialFocusEl);
179
+ if (!el && ctx.autoFocus)
180
+ el = dom.getFirstFocusableEl(ctx);
181
+ if (!el)
182
+ el = dom.getContentEl(ctx);
183
+ return el;
184
+ }
185
+ });
186
+
187
+ export {
188
+ runIfFn,
189
+ contains,
190
+ dom
191
+ };
@@ -0,0 +1,100 @@
1
+ import {
2
+ parts
3
+ } from "./chunk-KTOPDXGV.mjs";
4
+ import {
5
+ dom
6
+ } from "./chunk-3IPU3K2L.mjs";
7
+
8
+ // ../../utilities/dom/src/attrs.ts
9
+ var dataAttr = (guard) => {
10
+ return guard ? "" : void 0;
11
+ };
12
+
13
+ // src/popover.connect.ts
14
+ import { getPlacementStyles } from "@zag-js/popper";
15
+ function connect(state, send, normalize) {
16
+ const isOpen = state.matches("open");
17
+ const currentPlacement = state.context.currentPlacement;
18
+ const portalled = state.context.currentPortalled;
19
+ const rendered = state.context.renderedElements;
20
+ const popperStyles = getPlacementStyles({
21
+ measured: !!state.context.isPlacementComplete,
22
+ placement: currentPlacement
23
+ });
24
+ return {
25
+ portalled,
26
+ isOpen,
27
+ open() {
28
+ send("OPEN");
29
+ },
30
+ close() {
31
+ send("CLOSE");
32
+ },
33
+ arrowProps: normalize.element({
34
+ id: dom.getArrowId(state.context),
35
+ ...parts.arrow.attrs,
36
+ style: popperStyles.arrow
37
+ }),
38
+ arrowTipProps: normalize.element({
39
+ ...parts.arrowTip.attrs,
40
+ style: popperStyles.arrowTip
41
+ }),
42
+ anchorProps: normalize.element({
43
+ ...parts.anchor.attrs,
44
+ id: dom.getAnchorId(state.context)
45
+ }),
46
+ triggerProps: normalize.button({
47
+ ...parts.trigger.attrs,
48
+ type: "button",
49
+ "data-placement": currentPlacement,
50
+ id: dom.getTriggerId(state.context),
51
+ "aria-haspopup": "dialog",
52
+ "aria-expanded": isOpen,
53
+ "data-expanded": dataAttr(isOpen),
54
+ "aria-controls": dom.getContentId(state.context),
55
+ onClick() {
56
+ send("TOGGLE");
57
+ },
58
+ onBlur(event) {
59
+ send({ type: "TRIGGER_BLUR", target: event.relatedTarget });
60
+ }
61
+ }),
62
+ positionerProps: normalize.element({
63
+ id: dom.getPositionerId(state.context),
64
+ ...parts.positioner.attrs,
65
+ style: popperStyles.floating
66
+ }),
67
+ contentProps: normalize.element({
68
+ ...parts.content.attrs,
69
+ id: dom.getContentId(state.context),
70
+ tabIndex: -1,
71
+ role: "dialog",
72
+ hidden: !isOpen,
73
+ "data-expanded": dataAttr(isOpen),
74
+ "aria-labelledby": rendered.title ? dom.getTitleId(state.context) : void 0,
75
+ "aria-describedby": rendered.description ? dom.getDescriptionId(state.context) : void 0,
76
+ "data-placement": currentPlacement
77
+ }),
78
+ titleProps: normalize.element({
79
+ ...parts.title.attrs,
80
+ id: dom.getTitleId(state.context)
81
+ }),
82
+ descriptionProps: normalize.element({
83
+ ...parts.description.attrs,
84
+ id: dom.getDescriptionId(state.context)
85
+ }),
86
+ closeTriggerProps: normalize.button({
87
+ ...parts.closeTrigger.attrs,
88
+ id: dom.getCloseTriggerId(state.context),
89
+ type: "button",
90
+ "aria-label": "close",
91
+ onClick() {
92
+ send("REQUEST_CLOSE");
93
+ }
94
+ })
95
+ };
96
+ }
97
+
98
+ export {
99
+ connect
100
+ };
@@ -0,0 +1,353 @@
1
+ import {
2
+ contains,
3
+ dom,
4
+ runIfFn
5
+ } from "./chunk-3IPU3K2L.mjs";
6
+
7
+ // src/popover.machine.ts
8
+ import { ariaHidden } from "@zag-js/aria-hidden";
9
+ import { createMachine, guards } from "@zag-js/core";
10
+ import { trackDismissableElement } from "@zag-js/dismissable";
11
+
12
+ // ../../utilities/core/src/array.ts
13
+ function nextIndex(v, idx, opts = {}) {
14
+ const { step = 1, loop = true } = opts;
15
+ const next2 = idx + step;
16
+ const len = v.length;
17
+ const last = len - 1;
18
+ if (idx === -1)
19
+ return step > 0 ? 0 : last;
20
+ if (next2 < 0)
21
+ return loop ? last : 0;
22
+ if (next2 >= len)
23
+ return loop ? 0 : idx > len ? len : idx;
24
+ return next2;
25
+ }
26
+ function next(v, idx, opts = {}) {
27
+ return v[nextIndex(v, idx, opts)];
28
+ }
29
+
30
+ // ../../utilities/core/src/guard.ts
31
+ var isArray = (v) => Array.isArray(v);
32
+ var isObject = (v) => !(v == null || typeof v !== "object" || isArray(v));
33
+ var hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
34
+
35
+ // ../../utilities/core/src/object.ts
36
+ function compact(obj) {
37
+ if (obj === void 0)
38
+ return obj;
39
+ return Object.fromEntries(
40
+ Object.entries(obj).filter(([, value]) => value !== void 0).map(([key, value]) => [key, isObject(value) ? compact(value) : value])
41
+ );
42
+ }
43
+
44
+ // ../../utilities/dom/src/event.ts
45
+ var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
46
+
47
+ // ../../utilities/dom/src/listener.ts
48
+ var isRef = (v) => hasProp(v, "current");
49
+ function addDomEvent(target, eventName, handler, options) {
50
+ const node = isRef(target) ? target.current : runIfFn(target);
51
+ node == null ? void 0 : node.addEventListener(eventName, handler, options);
52
+ return () => {
53
+ node == null ? void 0 : node.removeEventListener(eventName, handler, options);
54
+ };
55
+ }
56
+
57
+ // ../../utilities/dom/src/next-tick.ts
58
+ function nextTick(fn) {
59
+ const set = /* @__PURE__ */ new Set();
60
+ function raf2(fn2) {
61
+ const id = globalThis.requestAnimationFrame(fn2);
62
+ set.add(() => globalThis.cancelAnimationFrame(id));
63
+ }
64
+ raf2(() => raf2(fn));
65
+ return function cleanup() {
66
+ set.forEach(function(fn2) {
67
+ fn2();
68
+ });
69
+ };
70
+ }
71
+ function raf(fn) {
72
+ const id = globalThis.requestAnimationFrame(fn);
73
+ return function cleanup() {
74
+ globalThis.cancelAnimationFrame(id);
75
+ };
76
+ }
77
+
78
+ // src/popover.machine.ts
79
+ import { getPlacement } from "@zag-js/popper";
80
+ import { preventBodyScroll } from "@zag-js/remove-scroll";
81
+ import { createFocusTrap } from "focus-trap";
82
+ var { and, or, not } = guards;
83
+ function machine(userContext) {
84
+ const ctx = compact(userContext);
85
+ return createMachine(
86
+ {
87
+ id: "popover",
88
+ initial: "unknown",
89
+ context: {
90
+ closeOnInteractOutside: true,
91
+ closeOnEsc: true,
92
+ autoFocus: true,
93
+ modal: false,
94
+ positioning: {
95
+ placement: "bottom",
96
+ ...ctx.positioning
97
+ },
98
+ currentPlacement: void 0,
99
+ ...ctx,
100
+ focusTriggerOnClose: true,
101
+ renderedElements: {
102
+ title: true,
103
+ description: true,
104
+ anchor: false
105
+ }
106
+ },
107
+ computed: {
108
+ currentPortalled: (ctx2) => !!ctx2.modal || !!ctx2.portalled
109
+ },
110
+ states: {
111
+ unknown: {
112
+ on: {
113
+ SETUP: {
114
+ target: ctx.defaultOpen ? "open" : "closed",
115
+ actions: "checkRenderedElements"
116
+ }
117
+ }
118
+ },
119
+ closed: {
120
+ entry: "invokeOnClose",
121
+ on: {
122
+ TOGGLE: "open",
123
+ OPEN: "open"
124
+ }
125
+ },
126
+ open: {
127
+ activities: [
128
+ "trapFocus",
129
+ "preventScroll",
130
+ "hideContentBelow",
131
+ "computePlacement",
132
+ "trackInteractionOutside",
133
+ "trackTabKeyDown"
134
+ ],
135
+ entry: ["setInitialFocus", "invokeOnOpen"],
136
+ on: {
137
+ CLOSE: "closed",
138
+ REQUEST_CLOSE: {
139
+ target: "closed",
140
+ actions: "focusTriggerIfNeeded"
141
+ },
142
+ TOGGLE: "closed",
143
+ TRIGGER_BLUR: {
144
+ guard: not("isRelatedTargetWithinContent"),
145
+ target: "closed"
146
+ },
147
+ TAB: [
148
+ {
149
+ guard: and("isTriggerFocused", "portalled"),
150
+ actions: "focusFirstTabbableElement"
151
+ },
152
+ {
153
+ guard: and("isLastTabbableElement", "closeOnInteractOutside", "portalled"),
154
+ target: "closed",
155
+ actions: "focusNextTabbableElementAfterTrigger"
156
+ }
157
+ ],
158
+ SHIFT_TAB: {
159
+ guard: and(or("isFirstTabbableElement", "isContentFocused"), "portalled"),
160
+ actions: "focusTriggerIfNeeded"
161
+ }
162
+ }
163
+ }
164
+ }
165
+ },
166
+ {
167
+ activities: {
168
+ computePlacement(ctx2) {
169
+ ctx2.currentPlacement = ctx2.positioning.placement;
170
+ const anchorEl = ctx2.renderedElements.anchor ? dom.getAnchorEl(ctx2) : dom.getTriggerEl(ctx2);
171
+ return getPlacement(anchorEl, dom.getPositionerEl(ctx2), {
172
+ ...ctx2.positioning,
173
+ onComplete(data) {
174
+ ctx2.currentPlacement = data.placement;
175
+ ctx2.isPlacementComplete = true;
176
+ },
177
+ onCleanup() {
178
+ ctx2.currentPlacement = void 0;
179
+ ctx2.isPlacementComplete = false;
180
+ }
181
+ });
182
+ },
183
+ trackInteractionOutside(ctx2, _evt, { send }) {
184
+ return trackDismissableElement(dom.getContentEl(ctx2), {
185
+ pointerBlocking: ctx2.modal,
186
+ exclude: dom.getTriggerEl(ctx2),
187
+ onEscapeKeyDown(event) {
188
+ var _a;
189
+ (_a = ctx2.onEscapeKeyDown) == null ? void 0 : _a.call(ctx2, event);
190
+ if (ctx2.closeOnEsc)
191
+ return;
192
+ ctx2.focusTriggerOnClose = true;
193
+ event.preventDefault();
194
+ },
195
+ onInteractOutside(event) {
196
+ var _a;
197
+ (_a = ctx2.onInteractOutside) == null ? void 0 : _a.call(ctx2, event);
198
+ if (event.defaultPrevented)
199
+ return;
200
+ ctx2.focusTriggerOnClose = !(event.detail.focusable || event.detail.contextmenu);
201
+ if (!ctx2.closeOnInteractOutside) {
202
+ event.preventDefault();
203
+ }
204
+ },
205
+ onPointerDownOutside(event) {
206
+ var _a;
207
+ (_a = ctx2.onPointerDownOutside) == null ? void 0 : _a.call(ctx2, event);
208
+ },
209
+ onFocusOutside(event) {
210
+ var _a;
211
+ (_a = ctx2.onFocusOutside) == null ? void 0 : _a.call(ctx2, event);
212
+ if (ctx2.currentPortalled) {
213
+ event.preventDefault();
214
+ }
215
+ },
216
+ onDismiss() {
217
+ send({ type: "REQUEST_CLOSE", src: "#interact-outside" });
218
+ }
219
+ });
220
+ },
221
+ trackTabKeyDown(ctx2, _evt, { send }) {
222
+ if (ctx2.modal)
223
+ return;
224
+ return addDomEvent(
225
+ dom.getWin(ctx2),
226
+ "keydown",
227
+ (event) => {
228
+ const isTabKey = event.key === "Tab" && !isModifiedEvent(event);
229
+ if (!isTabKey)
230
+ return;
231
+ send({
232
+ type: event.shiftKey ? "SHIFT_TAB" : "TAB",
233
+ preventDefault: () => event.preventDefault()
234
+ });
235
+ },
236
+ true
237
+ );
238
+ },
239
+ hideContentBelow(ctx2) {
240
+ if (!ctx2.modal)
241
+ return;
242
+ let cleanup;
243
+ nextTick(() => {
244
+ cleanup = ariaHidden([dom.getContentEl(ctx2), dom.getTriggerEl(ctx2)]);
245
+ });
246
+ return () => cleanup == null ? void 0 : cleanup();
247
+ },
248
+ preventScroll(ctx2) {
249
+ if (!ctx2.modal)
250
+ return;
251
+ return preventBodyScroll(dom.getDoc(ctx2));
252
+ },
253
+ trapFocus(ctx2) {
254
+ if (!ctx2.modal)
255
+ return;
256
+ let trap;
257
+ nextTick(() => {
258
+ const el = dom.getContentEl(ctx2);
259
+ if (!el)
260
+ return;
261
+ trap = createFocusTrap(el, {
262
+ escapeDeactivates: false,
263
+ allowOutsideClick: true,
264
+ returnFocusOnDeactivate: true,
265
+ document: dom.getDoc(ctx2),
266
+ fallbackFocus: el,
267
+ initialFocus: runIfFn(ctx2.initialFocusEl)
268
+ });
269
+ try {
270
+ trap.activate();
271
+ } catch {
272
+ }
273
+ });
274
+ return () => trap == null ? void 0 : trap.deactivate();
275
+ }
276
+ },
277
+ guards: {
278
+ portalled: (ctx2) => ctx2.currentPortalled,
279
+ isRelatedTargetWithinContent: (ctx2, evt) => contains(dom.getContentEl(ctx2), evt.target),
280
+ closeOnInteractOutside: (ctx2) => !!ctx2.closeOnInteractOutside,
281
+ isContentFocused: (ctx2) => dom.getContentEl(ctx2) === dom.getActiveEl(ctx2),
282
+ isTriggerFocused: (ctx2) => dom.getTriggerEl(ctx2) === dom.getActiveEl(ctx2),
283
+ isFirstTabbableElement: (ctx2) => dom.getFirstTabbableEl(ctx2) === dom.getActiveEl(ctx2),
284
+ isLastTabbableElement: (ctx2) => dom.getLastTabbableEl(ctx2) === dom.getActiveEl(ctx2)
285
+ },
286
+ actions: {
287
+ checkRenderedElements(ctx2) {
288
+ raf(() => {
289
+ Object.assign(ctx2.renderedElements, {
290
+ title: !!dom.getTitleEl(ctx2),
291
+ description: !!dom.getDescriptionEl(ctx2),
292
+ anchor: !!dom.getAnchorEl(ctx2)
293
+ });
294
+ });
295
+ },
296
+ setInitialFocus(ctx2) {
297
+ raf(() => {
298
+ var _a;
299
+ (_a = dom.getInitialFocusEl(ctx2)) == null ? void 0 : _a.focus();
300
+ });
301
+ },
302
+ focusTriggerIfNeeded(ctx2) {
303
+ if (!ctx2.focusTriggerOnClose)
304
+ return;
305
+ raf(() => {
306
+ var _a;
307
+ return (_a = dom.getTriggerEl(ctx2)) == null ? void 0 : _a.focus();
308
+ });
309
+ },
310
+ focusFirstTabbableElement(ctx2, evt) {
311
+ var _a;
312
+ evt.preventDefault();
313
+ (_a = dom.getFirstTabbableEl(ctx2)) == null ? void 0 : _a.focus();
314
+ },
315
+ invokeOnOpen(ctx2, evt) {
316
+ var _a;
317
+ if (evt.type !== "SETUP") {
318
+ (_a = ctx2.onOpenChange) == null ? void 0 : _a.call(ctx2, true);
319
+ }
320
+ },
321
+ invokeOnClose(ctx2, evt) {
322
+ var _a;
323
+ if (evt.type !== "SETUP") {
324
+ (_a = ctx2.onOpenChange) == null ? void 0 : _a.call(ctx2, false);
325
+ }
326
+ },
327
+ focusNextTabbableElementAfterTrigger(ctx2, evt) {
328
+ const content = dom.getContentEl(ctx2);
329
+ const button = dom.getTriggerEl(ctx2);
330
+ if (!content || !button)
331
+ return;
332
+ const lastTabbable = dom.getLastTabbableEl(ctx2);
333
+ if (lastTabbable !== dom.getActiveEl(ctx2))
334
+ return;
335
+ let tabbables = dom.getDocTabbableEls(ctx2);
336
+ let elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
337
+ if (elementAfterTrigger === content) {
338
+ tabbables = tabbables.filter((el) => !contains(content, el));
339
+ elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
340
+ }
341
+ if (!elementAfterTrigger || elementAfterTrigger === button)
342
+ return;
343
+ evt.preventDefault();
344
+ raf(() => elementAfterTrigger == null ? void 0 : elementAfterTrigger.focus());
345
+ }
346
+ }
347
+ }
348
+ );
349
+ }
350
+
351
+ export {
352
+ machine
353
+ };
@@ -0,0 +1,19 @@
1
+ // src/popover.anatomy.ts
2
+ import { createAnatomy } from "@zag-js/anatomy";
3
+ var anatomy = createAnatomy("popover").parts(
4
+ "arrow",
5
+ "arrowTip",
6
+ "anchor",
7
+ "trigger",
8
+ "positioner",
9
+ "content",
10
+ "title",
11
+ "description",
12
+ "closeTrigger"
13
+ );
14
+ var parts = anatomy.build();
15
+
16
+ export {
17
+ anatomy,
18
+ parts
19
+ };