@zag-js/popover 0.2.13 → 0.5.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/{chunk-JT2RXXW4.mjs → chunk-I6GHRN6K.mjs} +39 -94
- package/dist/{chunk-GKHXQZZB.mjs → chunk-QLF6NDJW.mjs} +6 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +42 -92
- package/dist/index.mjs +2 -2
- package/dist/popover.connect.d.ts +5 -1
- package/dist/popover.connect.js +6 -1
- package/dist/popover.connect.mjs +1 -1
- package/dist/popover.machine.js +36 -91
- package/dist/popover.machine.mjs +1 -1
- package/dist/popover.types.d.ts +2 -2
- package/package.json +8 -9
|
@@ -4,21 +4,20 @@ import {
|
|
|
4
4
|
|
|
5
5
|
// src/popover.machine.ts
|
|
6
6
|
import { ariaHidden } from "@zag-js/aria-hidden";
|
|
7
|
-
import { createMachine
|
|
7
|
+
import { createMachine } from "@zag-js/core";
|
|
8
8
|
import { trackDismissableElement } from "@zag-js/dismissable";
|
|
9
|
-
import {
|
|
10
|
-
import { addDomEvent, isModifiedEvent } from "@zag-js/dom-event";
|
|
9
|
+
import { nextTick, raf } from "@zag-js/dom-query";
|
|
11
10
|
import { getPlacement } from "@zag-js/popper";
|
|
12
11
|
import { preventBodyScroll } from "@zag-js/remove-scroll";
|
|
13
|
-
import {
|
|
12
|
+
import { proxyTabFocus } from "@zag-js/tabbable";
|
|
13
|
+
import { compact, runIfFn } from "@zag-js/utils";
|
|
14
14
|
import { createFocusTrap } from "focus-trap";
|
|
15
|
-
var { and, or, not } = guards;
|
|
16
15
|
function machine(userContext) {
|
|
17
16
|
const ctx = compact(userContext);
|
|
18
17
|
return createMachine(
|
|
19
18
|
{
|
|
20
19
|
id: "popover",
|
|
21
|
-
initial: ctx.
|
|
20
|
+
initial: ctx.open ? "open" : "closed",
|
|
22
21
|
context: {
|
|
23
22
|
closeOnInteractOutside: true,
|
|
24
23
|
closeOnEsc: true,
|
|
@@ -33,13 +32,15 @@ function machine(userContext) {
|
|
|
33
32
|
focusTriggerOnClose: true,
|
|
34
33
|
renderedElements: {
|
|
35
34
|
title: true,
|
|
36
|
-
description: true
|
|
37
|
-
anchor: false
|
|
35
|
+
description: true
|
|
38
36
|
}
|
|
39
37
|
},
|
|
40
38
|
computed: {
|
|
41
39
|
currentPortalled: (ctx2) => !!ctx2.modal || !!ctx2.portalled
|
|
42
40
|
},
|
|
41
|
+
watch: {
|
|
42
|
+
open: ["toggleVisibility"]
|
|
43
|
+
},
|
|
43
44
|
entry: ["checkRenderedElements"],
|
|
44
45
|
states: {
|
|
45
46
|
closed: {
|
|
@@ -54,9 +55,9 @@ function machine(userContext) {
|
|
|
54
55
|
"trapFocus",
|
|
55
56
|
"preventScroll",
|
|
56
57
|
"hideContentBelow",
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
58
|
+
"trackPositioning",
|
|
59
|
+
"trackDismissableElement",
|
|
60
|
+
"proxyTabFocus"
|
|
60
61
|
],
|
|
61
62
|
entry: ["setInitialFocus", "invokeOnOpen"],
|
|
62
63
|
on: {
|
|
@@ -66,24 +67,8 @@ function machine(userContext) {
|
|
|
66
67
|
actions: "focusTriggerIfNeeded"
|
|
67
68
|
},
|
|
68
69
|
TOGGLE: "closed",
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
target: "closed"
|
|
72
|
-
},
|
|
73
|
-
TAB: [
|
|
74
|
-
{
|
|
75
|
-
guard: and("isTriggerFocused", "portalled"),
|
|
76
|
-
actions: "focusFirstTabbableElement"
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
guard: and("isLastTabbableElement", "closeOnInteractOutside", "portalled"),
|
|
80
|
-
target: "closed",
|
|
81
|
-
actions: "focusNextTabbableElementAfterTrigger"
|
|
82
|
-
}
|
|
83
|
-
],
|
|
84
|
-
SHIFT_TAB: {
|
|
85
|
-
guard: and(or("isFirstTabbableElement", "isContentFocused"), "portalled"),
|
|
86
|
-
actions: "focusTriggerIfNeeded"
|
|
70
|
+
SET_POSITIONING: {
|
|
71
|
+
actions: "setPositioning"
|
|
87
72
|
}
|
|
88
73
|
}
|
|
89
74
|
}
|
|
@@ -91,22 +76,20 @@ function machine(userContext) {
|
|
|
91
76
|
},
|
|
92
77
|
{
|
|
93
78
|
activities: {
|
|
94
|
-
|
|
79
|
+
trackPositioning(ctx2) {
|
|
95
80
|
ctx2.currentPlacement = ctx2.positioning.placement;
|
|
96
|
-
const anchorEl =
|
|
81
|
+
const anchorEl = dom.getAnchorEl(ctx2) ?? dom.getTriggerEl(ctx2);
|
|
97
82
|
return getPlacement(anchorEl, dom.getPositionerEl(ctx2), {
|
|
98
83
|
...ctx2.positioning,
|
|
99
84
|
onComplete(data) {
|
|
100
85
|
ctx2.currentPlacement = data.placement;
|
|
101
|
-
ctx2.isPlacementComplete = true;
|
|
102
86
|
},
|
|
103
87
|
onCleanup() {
|
|
104
88
|
ctx2.currentPlacement = void 0;
|
|
105
|
-
ctx2.isPlacementComplete = false;
|
|
106
89
|
}
|
|
107
90
|
});
|
|
108
91
|
},
|
|
109
|
-
|
|
92
|
+
trackDismissableElement(ctx2, _evt, { send }) {
|
|
110
93
|
return trackDismissableElement(dom.getContentEl(ctx2), {
|
|
111
94
|
pointerBlocking: ctx2.modal,
|
|
112
95
|
exclude: dom.getTriggerEl(ctx2),
|
|
@@ -131,32 +114,18 @@ function machine(userContext) {
|
|
|
131
114
|
},
|
|
132
115
|
onFocusOutside(event) {
|
|
133
116
|
ctx2.onFocusOutside?.(event);
|
|
134
|
-
if (ctx2.currentPortalled) {
|
|
135
|
-
event.preventDefault();
|
|
136
|
-
}
|
|
137
117
|
},
|
|
138
118
|
onDismiss() {
|
|
139
119
|
send({ type: "REQUEST_CLOSE", src: "#interact-outside" });
|
|
140
120
|
}
|
|
141
121
|
});
|
|
142
122
|
},
|
|
143
|
-
|
|
144
|
-
if (ctx2.modal)
|
|
123
|
+
proxyTabFocus(ctx2) {
|
|
124
|
+
if (ctx2.modal || !ctx2.portalled)
|
|
145
125
|
return;
|
|
146
|
-
return
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
(event) => {
|
|
150
|
-
const isTabKey = event.key === "Tab" && !isModifiedEvent(event);
|
|
151
|
-
if (!isTabKey)
|
|
152
|
-
return;
|
|
153
|
-
send({
|
|
154
|
-
type: event.shiftKey ? "SHIFT_TAB" : "TAB",
|
|
155
|
-
preventDefault: () => event.preventDefault()
|
|
156
|
-
});
|
|
157
|
-
},
|
|
158
|
-
true
|
|
159
|
-
);
|
|
126
|
+
return proxyTabFocus(dom.getContentEl(ctx2), dom.getTriggerEl(ctx2), (el) => {
|
|
127
|
+
el.focus({ preventScroll: true });
|
|
128
|
+
});
|
|
160
129
|
},
|
|
161
130
|
hideContentBelow(ctx2) {
|
|
162
131
|
if (!ctx2.modal)
|
|
@@ -196,22 +165,22 @@ function machine(userContext) {
|
|
|
196
165
|
return () => trap?.deactivate();
|
|
197
166
|
}
|
|
198
167
|
},
|
|
199
|
-
guards: {
|
|
200
|
-
portalled: (ctx2) => ctx2.currentPortalled,
|
|
201
|
-
isRelatedTargetWithinContent: (ctx2, evt) => contains(dom.getContentEl(ctx2), evt.target),
|
|
202
|
-
closeOnInteractOutside: (ctx2) => !!ctx2.closeOnInteractOutside,
|
|
203
|
-
isContentFocused: (ctx2) => dom.getContentEl(ctx2) === dom.getActiveEl(ctx2),
|
|
204
|
-
isTriggerFocused: (ctx2) => dom.getTriggerEl(ctx2) === dom.getActiveEl(ctx2),
|
|
205
|
-
isFirstTabbableElement: (ctx2) => dom.getFirstTabbableEl(ctx2) === dom.getActiveEl(ctx2),
|
|
206
|
-
isLastTabbableElement: (ctx2) => dom.getLastTabbableEl(ctx2) === dom.getActiveEl(ctx2)
|
|
207
|
-
},
|
|
208
168
|
actions: {
|
|
169
|
+
setPositioning(ctx2, evt) {
|
|
170
|
+
raf(() => {
|
|
171
|
+
const anchorEl = dom.getAnchorEl(ctx2) ?? dom.getTriggerEl(ctx2);
|
|
172
|
+
getPlacement(anchorEl, dom.getPositionerEl(ctx2), {
|
|
173
|
+
...ctx2.positioning,
|
|
174
|
+
...evt.options,
|
|
175
|
+
listeners: false
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
},
|
|
209
179
|
checkRenderedElements(ctx2) {
|
|
210
180
|
raf(() => {
|
|
211
181
|
Object.assign(ctx2.renderedElements, {
|
|
212
182
|
title: !!dom.getTitleEl(ctx2),
|
|
213
|
-
description: !!dom.getDescriptionEl(ctx2)
|
|
214
|
-
anchor: !!dom.getAnchorEl(ctx2)
|
|
183
|
+
description: !!dom.getDescriptionEl(ctx2)
|
|
215
184
|
});
|
|
216
185
|
});
|
|
217
186
|
},
|
|
@@ -225,38 +194,14 @@ function machine(userContext) {
|
|
|
225
194
|
return;
|
|
226
195
|
raf(() => dom.getTriggerEl(ctx2)?.focus());
|
|
227
196
|
},
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
dom.getFirstTabbableEl(ctx2)?.focus();
|
|
231
|
-
},
|
|
232
|
-
invokeOnOpen(ctx2, evt) {
|
|
233
|
-
if (evt.type !== "SETUP") {
|
|
234
|
-
ctx2.onOpenChange?.(true);
|
|
235
|
-
}
|
|
197
|
+
invokeOnOpen(ctx2) {
|
|
198
|
+
ctx2.onOpenChange?.(true);
|
|
236
199
|
},
|
|
237
|
-
invokeOnClose(ctx2
|
|
238
|
-
|
|
239
|
-
ctx2.onOpenChange?.(false);
|
|
240
|
-
}
|
|
200
|
+
invokeOnClose(ctx2) {
|
|
201
|
+
ctx2.onOpenChange?.(false);
|
|
241
202
|
},
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
const button = dom.getTriggerEl(ctx2);
|
|
245
|
-
if (!content || !button)
|
|
246
|
-
return;
|
|
247
|
-
const lastTabbable = dom.getLastTabbableEl(ctx2);
|
|
248
|
-
if (lastTabbable !== dom.getActiveEl(ctx2))
|
|
249
|
-
return;
|
|
250
|
-
let tabbables = dom.getDocTabbableEls(ctx2);
|
|
251
|
-
let elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
|
|
252
|
-
if (elementAfterTrigger === content) {
|
|
253
|
-
tabbables = tabbables.filter((el) => !contains(content, el));
|
|
254
|
-
elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
|
|
255
|
-
}
|
|
256
|
-
if (!elementAfterTrigger || elementAfterTrigger === button)
|
|
257
|
-
return;
|
|
258
|
-
evt.preventDefault();
|
|
259
|
-
raf(() => elementAfterTrigger?.focus());
|
|
203
|
+
toggleVisibility(ctx2, _evt, { send }) {
|
|
204
|
+
send({ type: ctx2.open ? "OPEN" : "CLOSE", src: "controlled" });
|
|
260
205
|
}
|
|
261
206
|
}
|
|
262
207
|
}
|
|
@@ -14,7 +14,6 @@ function connect(state, send, normalize) {
|
|
|
14
14
|
const portalled = state.context.currentPortalled;
|
|
15
15
|
const rendered = state.context.renderedElements;
|
|
16
16
|
const popperStyles = getPlacementStyles({
|
|
17
|
-
measured: !!state.context.isPlacementComplete,
|
|
18
17
|
placement: currentPlacement
|
|
19
18
|
});
|
|
20
19
|
return {
|
|
@@ -38,6 +37,12 @@ function connect(state, send, normalize) {
|
|
|
38
37
|
close() {
|
|
39
38
|
send("CLOSE");
|
|
40
39
|
},
|
|
40
|
+
/**
|
|
41
|
+
* Function to reposition the popover
|
|
42
|
+
*/
|
|
43
|
+
setPositioning(options) {
|
|
44
|
+
send({ type: "SET_POSITIONING", options });
|
|
45
|
+
},
|
|
41
46
|
arrowProps: normalize.element({
|
|
42
47
|
id: dom.getArrowId(state.context),
|
|
43
48
|
...parts.arrow.attrs,
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { connect } from './popover.connect.js';
|
|
|
3
3
|
export { machine } from './popover.machine.js';
|
|
4
4
|
export { UserDefinedContext as Context } from './popover.types.js';
|
|
5
5
|
import '@zag-js/anatomy';
|
|
6
|
+
import '@zag-js/popper';
|
|
6
7
|
import '@zag-js/types';
|
|
7
8
|
import '@zag-js/core';
|
|
8
9
|
import '@zag-js/dismissable';
|
|
9
|
-
import '@zag-js/popper';
|
package/dist/index.js
CHANGED
|
@@ -88,7 +88,6 @@ function connect(state, send, normalize) {
|
|
|
88
88
|
const portalled = state.context.currentPortalled;
|
|
89
89
|
const rendered = state.context.renderedElements;
|
|
90
90
|
const popperStyles = (0, import_popper.getPlacementStyles)({
|
|
91
|
-
measured: !!state.context.isPlacementComplete,
|
|
92
91
|
placement: currentPlacement
|
|
93
92
|
});
|
|
94
93
|
return {
|
|
@@ -112,6 +111,12 @@ function connect(state, send, normalize) {
|
|
|
112
111
|
close() {
|
|
113
112
|
send("CLOSE");
|
|
114
113
|
},
|
|
114
|
+
/**
|
|
115
|
+
* Function to reposition the popover
|
|
116
|
+
*/
|
|
117
|
+
setPositioning(options) {
|
|
118
|
+
send({ type: "SET_POSITIONING", options });
|
|
119
|
+
},
|
|
115
120
|
arrowProps: normalize.element({
|
|
116
121
|
id: dom.getArrowId(state.context),
|
|
117
122
|
...parts.arrow.attrs,
|
|
@@ -182,18 +187,17 @@ var import_aria_hidden = require("@zag-js/aria-hidden");
|
|
|
182
187
|
var import_core = require("@zag-js/core");
|
|
183
188
|
var import_dismissable = require("@zag-js/dismissable");
|
|
184
189
|
var import_dom_query3 = require("@zag-js/dom-query");
|
|
185
|
-
var import_dom_event = require("@zag-js/dom-event");
|
|
186
190
|
var import_popper2 = require("@zag-js/popper");
|
|
187
191
|
var import_remove_scroll = require("@zag-js/remove-scroll");
|
|
192
|
+
var import_tabbable2 = require("@zag-js/tabbable");
|
|
188
193
|
var import_utils2 = require("@zag-js/utils");
|
|
189
194
|
var import_focus_trap = require("focus-trap");
|
|
190
|
-
var { and, or, not } = import_core.guards;
|
|
191
195
|
function machine(userContext) {
|
|
192
196
|
const ctx = (0, import_utils2.compact)(userContext);
|
|
193
197
|
return (0, import_core.createMachine)(
|
|
194
198
|
{
|
|
195
199
|
id: "popover",
|
|
196
|
-
initial: ctx.
|
|
200
|
+
initial: ctx.open ? "open" : "closed",
|
|
197
201
|
context: {
|
|
198
202
|
closeOnInteractOutside: true,
|
|
199
203
|
closeOnEsc: true,
|
|
@@ -208,13 +212,15 @@ function machine(userContext) {
|
|
|
208
212
|
focusTriggerOnClose: true,
|
|
209
213
|
renderedElements: {
|
|
210
214
|
title: true,
|
|
211
|
-
description: true
|
|
212
|
-
anchor: false
|
|
215
|
+
description: true
|
|
213
216
|
}
|
|
214
217
|
},
|
|
215
218
|
computed: {
|
|
216
219
|
currentPortalled: (ctx2) => !!ctx2.modal || !!ctx2.portalled
|
|
217
220
|
},
|
|
221
|
+
watch: {
|
|
222
|
+
open: ["toggleVisibility"]
|
|
223
|
+
},
|
|
218
224
|
entry: ["checkRenderedElements"],
|
|
219
225
|
states: {
|
|
220
226
|
closed: {
|
|
@@ -229,9 +235,9 @@ function machine(userContext) {
|
|
|
229
235
|
"trapFocus",
|
|
230
236
|
"preventScroll",
|
|
231
237
|
"hideContentBelow",
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
"
|
|
238
|
+
"trackPositioning",
|
|
239
|
+
"trackDismissableElement",
|
|
240
|
+
"proxyTabFocus"
|
|
235
241
|
],
|
|
236
242
|
entry: ["setInitialFocus", "invokeOnOpen"],
|
|
237
243
|
on: {
|
|
@@ -241,24 +247,8 @@ function machine(userContext) {
|
|
|
241
247
|
actions: "focusTriggerIfNeeded"
|
|
242
248
|
},
|
|
243
249
|
TOGGLE: "closed",
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
target: "closed"
|
|
247
|
-
},
|
|
248
|
-
TAB: [
|
|
249
|
-
{
|
|
250
|
-
guard: and("isTriggerFocused", "portalled"),
|
|
251
|
-
actions: "focusFirstTabbableElement"
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
guard: and("isLastTabbableElement", "closeOnInteractOutside", "portalled"),
|
|
255
|
-
target: "closed",
|
|
256
|
-
actions: "focusNextTabbableElementAfterTrigger"
|
|
257
|
-
}
|
|
258
|
-
],
|
|
259
|
-
SHIFT_TAB: {
|
|
260
|
-
guard: and(or("isFirstTabbableElement", "isContentFocused"), "portalled"),
|
|
261
|
-
actions: "focusTriggerIfNeeded"
|
|
250
|
+
SET_POSITIONING: {
|
|
251
|
+
actions: "setPositioning"
|
|
262
252
|
}
|
|
263
253
|
}
|
|
264
254
|
}
|
|
@@ -266,22 +256,20 @@ function machine(userContext) {
|
|
|
266
256
|
},
|
|
267
257
|
{
|
|
268
258
|
activities: {
|
|
269
|
-
|
|
259
|
+
trackPositioning(ctx2) {
|
|
270
260
|
ctx2.currentPlacement = ctx2.positioning.placement;
|
|
271
|
-
const anchorEl =
|
|
261
|
+
const anchorEl = dom.getAnchorEl(ctx2) ?? dom.getTriggerEl(ctx2);
|
|
272
262
|
return (0, import_popper2.getPlacement)(anchorEl, dom.getPositionerEl(ctx2), {
|
|
273
263
|
...ctx2.positioning,
|
|
274
264
|
onComplete(data) {
|
|
275
265
|
ctx2.currentPlacement = data.placement;
|
|
276
|
-
ctx2.isPlacementComplete = true;
|
|
277
266
|
},
|
|
278
267
|
onCleanup() {
|
|
279
268
|
ctx2.currentPlacement = void 0;
|
|
280
|
-
ctx2.isPlacementComplete = false;
|
|
281
269
|
}
|
|
282
270
|
});
|
|
283
271
|
},
|
|
284
|
-
|
|
272
|
+
trackDismissableElement(ctx2, _evt, { send }) {
|
|
285
273
|
return (0, import_dismissable.trackDismissableElement)(dom.getContentEl(ctx2), {
|
|
286
274
|
pointerBlocking: ctx2.modal,
|
|
287
275
|
exclude: dom.getTriggerEl(ctx2),
|
|
@@ -306,32 +294,18 @@ function machine(userContext) {
|
|
|
306
294
|
},
|
|
307
295
|
onFocusOutside(event) {
|
|
308
296
|
ctx2.onFocusOutside?.(event);
|
|
309
|
-
if (ctx2.currentPortalled) {
|
|
310
|
-
event.preventDefault();
|
|
311
|
-
}
|
|
312
297
|
},
|
|
313
298
|
onDismiss() {
|
|
314
299
|
send({ type: "REQUEST_CLOSE", src: "#interact-outside" });
|
|
315
300
|
}
|
|
316
301
|
});
|
|
317
302
|
},
|
|
318
|
-
|
|
319
|
-
if (ctx2.modal)
|
|
303
|
+
proxyTabFocus(ctx2) {
|
|
304
|
+
if (ctx2.modal || !ctx2.portalled)
|
|
320
305
|
return;
|
|
321
|
-
return (0,
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
(event) => {
|
|
325
|
-
const isTabKey = event.key === "Tab" && !(0, import_dom_event.isModifiedEvent)(event);
|
|
326
|
-
if (!isTabKey)
|
|
327
|
-
return;
|
|
328
|
-
send({
|
|
329
|
-
type: event.shiftKey ? "SHIFT_TAB" : "TAB",
|
|
330
|
-
preventDefault: () => event.preventDefault()
|
|
331
|
-
});
|
|
332
|
-
},
|
|
333
|
-
true
|
|
334
|
-
);
|
|
306
|
+
return (0, import_tabbable2.proxyTabFocus)(dom.getContentEl(ctx2), dom.getTriggerEl(ctx2), (el) => {
|
|
307
|
+
el.focus({ preventScroll: true });
|
|
308
|
+
});
|
|
335
309
|
},
|
|
336
310
|
hideContentBelow(ctx2) {
|
|
337
311
|
if (!ctx2.modal)
|
|
@@ -371,22 +345,22 @@ function machine(userContext) {
|
|
|
371
345
|
return () => trap?.deactivate();
|
|
372
346
|
}
|
|
373
347
|
},
|
|
374
|
-
guards: {
|
|
375
|
-
portalled: (ctx2) => ctx2.currentPortalled,
|
|
376
|
-
isRelatedTargetWithinContent: (ctx2, evt) => (0, import_dom_query3.contains)(dom.getContentEl(ctx2), evt.target),
|
|
377
|
-
closeOnInteractOutside: (ctx2) => !!ctx2.closeOnInteractOutside,
|
|
378
|
-
isContentFocused: (ctx2) => dom.getContentEl(ctx2) === dom.getActiveEl(ctx2),
|
|
379
|
-
isTriggerFocused: (ctx2) => dom.getTriggerEl(ctx2) === dom.getActiveEl(ctx2),
|
|
380
|
-
isFirstTabbableElement: (ctx2) => dom.getFirstTabbableEl(ctx2) === dom.getActiveEl(ctx2),
|
|
381
|
-
isLastTabbableElement: (ctx2) => dom.getLastTabbableEl(ctx2) === dom.getActiveEl(ctx2)
|
|
382
|
-
},
|
|
383
348
|
actions: {
|
|
349
|
+
setPositioning(ctx2, evt) {
|
|
350
|
+
(0, import_dom_query3.raf)(() => {
|
|
351
|
+
const anchorEl = dom.getAnchorEl(ctx2) ?? dom.getTriggerEl(ctx2);
|
|
352
|
+
(0, import_popper2.getPlacement)(anchorEl, dom.getPositionerEl(ctx2), {
|
|
353
|
+
...ctx2.positioning,
|
|
354
|
+
...evt.options,
|
|
355
|
+
listeners: false
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
},
|
|
384
359
|
checkRenderedElements(ctx2) {
|
|
385
360
|
(0, import_dom_query3.raf)(() => {
|
|
386
361
|
Object.assign(ctx2.renderedElements, {
|
|
387
362
|
title: !!dom.getTitleEl(ctx2),
|
|
388
|
-
description: !!dom.getDescriptionEl(ctx2)
|
|
389
|
-
anchor: !!dom.getAnchorEl(ctx2)
|
|
363
|
+
description: !!dom.getDescriptionEl(ctx2)
|
|
390
364
|
});
|
|
391
365
|
});
|
|
392
366
|
},
|
|
@@ -400,38 +374,14 @@ function machine(userContext) {
|
|
|
400
374
|
return;
|
|
401
375
|
(0, import_dom_query3.raf)(() => dom.getTriggerEl(ctx2)?.focus());
|
|
402
376
|
},
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
dom.getFirstTabbableEl(ctx2)?.focus();
|
|
406
|
-
},
|
|
407
|
-
invokeOnOpen(ctx2, evt) {
|
|
408
|
-
if (evt.type !== "SETUP") {
|
|
409
|
-
ctx2.onOpenChange?.(true);
|
|
410
|
-
}
|
|
377
|
+
invokeOnOpen(ctx2) {
|
|
378
|
+
ctx2.onOpenChange?.(true);
|
|
411
379
|
},
|
|
412
|
-
invokeOnClose(ctx2
|
|
413
|
-
|
|
414
|
-
ctx2.onOpenChange?.(false);
|
|
415
|
-
}
|
|
380
|
+
invokeOnClose(ctx2) {
|
|
381
|
+
ctx2.onOpenChange?.(false);
|
|
416
382
|
},
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
const button = dom.getTriggerEl(ctx2);
|
|
420
|
-
if (!content || !button)
|
|
421
|
-
return;
|
|
422
|
-
const lastTabbable = dom.getLastTabbableEl(ctx2);
|
|
423
|
-
if (lastTabbable !== dom.getActiveEl(ctx2))
|
|
424
|
-
return;
|
|
425
|
-
let tabbables = dom.getDocTabbableEls(ctx2);
|
|
426
|
-
let elementAfterTrigger = (0, import_utils2.next)(tabbables, tabbables.indexOf(button), { loop: false });
|
|
427
|
-
if (elementAfterTrigger === content) {
|
|
428
|
-
tabbables = tabbables.filter((el) => !(0, import_dom_query3.contains)(content, el));
|
|
429
|
-
elementAfterTrigger = (0, import_utils2.next)(tabbables, tabbables.indexOf(button), { loop: false });
|
|
430
|
-
}
|
|
431
|
-
if (!elementAfterTrigger || elementAfterTrigger === button)
|
|
432
|
-
return;
|
|
433
|
-
evt.preventDefault();
|
|
434
|
-
(0, import_dom_query3.raf)(() => elementAfterTrigger?.focus());
|
|
383
|
+
toggleVisibility(ctx2, _evt, { send }) {
|
|
384
|
+
send({ type: ctx2.open ? "OPEN" : "CLOSE", src: "controlled" });
|
|
435
385
|
}
|
|
436
386
|
}
|
|
437
387
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
connect
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QLF6NDJW.mjs";
|
|
4
4
|
import {
|
|
5
5
|
anatomy
|
|
6
6
|
} from "./chunk-KTOPDXGV.mjs";
|
|
7
7
|
import {
|
|
8
8
|
machine
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-I6GHRN6K.mjs";
|
|
10
10
|
import "./chunk-4IGGT6KB.mjs";
|
|
11
11
|
export {
|
|
12
12
|
anatomy,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { PositioningOptions } from '@zag-js/popper';
|
|
1
2
|
import { PropTypes, NormalizeProps } from '@zag-js/types';
|
|
2
3
|
import { State, Send } from './popover.types.js';
|
|
3
4
|
import '@zag-js/core';
|
|
4
5
|
import '@zag-js/dismissable';
|
|
5
|
-
import '@zag-js/popper';
|
|
6
6
|
|
|
7
7
|
declare function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): {
|
|
8
8
|
/**
|
|
@@ -21,6 +21,10 @@ declare function connect<T extends PropTypes>(state: State, send: Send, normaliz
|
|
|
21
21
|
* Function to close the popover
|
|
22
22
|
*/
|
|
23
23
|
close(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Function to reposition the popover
|
|
26
|
+
*/
|
|
27
|
+
setPositioning(options: Partial<PositioningOptions>): void;
|
|
24
28
|
arrowProps: T["element"];
|
|
25
29
|
arrowTipProps: T["element"];
|
|
26
30
|
anchorProps: T["element"];
|
package/dist/popover.connect.js
CHANGED
|
@@ -84,7 +84,6 @@ function connect(state, send, normalize) {
|
|
|
84
84
|
const portalled = state.context.currentPortalled;
|
|
85
85
|
const rendered = state.context.renderedElements;
|
|
86
86
|
const popperStyles = (0, import_popper.getPlacementStyles)({
|
|
87
|
-
measured: !!state.context.isPlacementComplete,
|
|
88
87
|
placement: currentPlacement
|
|
89
88
|
});
|
|
90
89
|
return {
|
|
@@ -108,6 +107,12 @@ function connect(state, send, normalize) {
|
|
|
108
107
|
close() {
|
|
109
108
|
send("CLOSE");
|
|
110
109
|
},
|
|
110
|
+
/**
|
|
111
|
+
* Function to reposition the popover
|
|
112
|
+
*/
|
|
113
|
+
setPositioning(options) {
|
|
114
|
+
send({ type: "SET_POSITIONING", options });
|
|
115
|
+
},
|
|
111
116
|
arrowProps: normalize.element({
|
|
112
117
|
id: dom.getArrowId(state.context),
|
|
113
118
|
...parts.arrow.attrs,
|
package/dist/popover.connect.mjs
CHANGED
package/dist/popover.machine.js
CHANGED
|
@@ -27,9 +27,9 @@ var import_aria_hidden = require("@zag-js/aria-hidden");
|
|
|
27
27
|
var import_core = require("@zag-js/core");
|
|
28
28
|
var import_dismissable = require("@zag-js/dismissable");
|
|
29
29
|
var import_dom_query2 = require("@zag-js/dom-query");
|
|
30
|
-
var import_dom_event = require("@zag-js/dom-event");
|
|
31
30
|
var import_popper = require("@zag-js/popper");
|
|
32
31
|
var import_remove_scroll = require("@zag-js/remove-scroll");
|
|
32
|
+
var import_tabbable2 = require("@zag-js/tabbable");
|
|
33
33
|
var import_utils2 = require("@zag-js/utils");
|
|
34
34
|
var import_focus_trap = require("focus-trap");
|
|
35
35
|
|
|
@@ -70,13 +70,12 @@ var dom = (0, import_dom_query.createScope)({
|
|
|
70
70
|
});
|
|
71
71
|
|
|
72
72
|
// src/popover.machine.ts
|
|
73
|
-
var { and, or, not } = import_core.guards;
|
|
74
73
|
function machine(userContext) {
|
|
75
74
|
const ctx = (0, import_utils2.compact)(userContext);
|
|
76
75
|
return (0, import_core.createMachine)(
|
|
77
76
|
{
|
|
78
77
|
id: "popover",
|
|
79
|
-
initial: ctx.
|
|
78
|
+
initial: ctx.open ? "open" : "closed",
|
|
80
79
|
context: {
|
|
81
80
|
closeOnInteractOutside: true,
|
|
82
81
|
closeOnEsc: true,
|
|
@@ -91,13 +90,15 @@ function machine(userContext) {
|
|
|
91
90
|
focusTriggerOnClose: true,
|
|
92
91
|
renderedElements: {
|
|
93
92
|
title: true,
|
|
94
|
-
description: true
|
|
95
|
-
anchor: false
|
|
93
|
+
description: true
|
|
96
94
|
}
|
|
97
95
|
},
|
|
98
96
|
computed: {
|
|
99
97
|
currentPortalled: (ctx2) => !!ctx2.modal || !!ctx2.portalled
|
|
100
98
|
},
|
|
99
|
+
watch: {
|
|
100
|
+
open: ["toggleVisibility"]
|
|
101
|
+
},
|
|
101
102
|
entry: ["checkRenderedElements"],
|
|
102
103
|
states: {
|
|
103
104
|
closed: {
|
|
@@ -112,9 +113,9 @@ function machine(userContext) {
|
|
|
112
113
|
"trapFocus",
|
|
113
114
|
"preventScroll",
|
|
114
115
|
"hideContentBelow",
|
|
115
|
-
"
|
|
116
|
-
"
|
|
117
|
-
"
|
|
116
|
+
"trackPositioning",
|
|
117
|
+
"trackDismissableElement",
|
|
118
|
+
"proxyTabFocus"
|
|
118
119
|
],
|
|
119
120
|
entry: ["setInitialFocus", "invokeOnOpen"],
|
|
120
121
|
on: {
|
|
@@ -124,24 +125,8 @@ function machine(userContext) {
|
|
|
124
125
|
actions: "focusTriggerIfNeeded"
|
|
125
126
|
},
|
|
126
127
|
TOGGLE: "closed",
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
target: "closed"
|
|
130
|
-
},
|
|
131
|
-
TAB: [
|
|
132
|
-
{
|
|
133
|
-
guard: and("isTriggerFocused", "portalled"),
|
|
134
|
-
actions: "focusFirstTabbableElement"
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
guard: and("isLastTabbableElement", "closeOnInteractOutside", "portalled"),
|
|
138
|
-
target: "closed",
|
|
139
|
-
actions: "focusNextTabbableElementAfterTrigger"
|
|
140
|
-
}
|
|
141
|
-
],
|
|
142
|
-
SHIFT_TAB: {
|
|
143
|
-
guard: and(or("isFirstTabbableElement", "isContentFocused"), "portalled"),
|
|
144
|
-
actions: "focusTriggerIfNeeded"
|
|
128
|
+
SET_POSITIONING: {
|
|
129
|
+
actions: "setPositioning"
|
|
145
130
|
}
|
|
146
131
|
}
|
|
147
132
|
}
|
|
@@ -149,22 +134,20 @@ function machine(userContext) {
|
|
|
149
134
|
},
|
|
150
135
|
{
|
|
151
136
|
activities: {
|
|
152
|
-
|
|
137
|
+
trackPositioning(ctx2) {
|
|
153
138
|
ctx2.currentPlacement = ctx2.positioning.placement;
|
|
154
|
-
const anchorEl =
|
|
139
|
+
const anchorEl = dom.getAnchorEl(ctx2) ?? dom.getTriggerEl(ctx2);
|
|
155
140
|
return (0, import_popper.getPlacement)(anchorEl, dom.getPositionerEl(ctx2), {
|
|
156
141
|
...ctx2.positioning,
|
|
157
142
|
onComplete(data) {
|
|
158
143
|
ctx2.currentPlacement = data.placement;
|
|
159
|
-
ctx2.isPlacementComplete = true;
|
|
160
144
|
},
|
|
161
145
|
onCleanup() {
|
|
162
146
|
ctx2.currentPlacement = void 0;
|
|
163
|
-
ctx2.isPlacementComplete = false;
|
|
164
147
|
}
|
|
165
148
|
});
|
|
166
149
|
},
|
|
167
|
-
|
|
150
|
+
trackDismissableElement(ctx2, _evt, { send }) {
|
|
168
151
|
return (0, import_dismissable.trackDismissableElement)(dom.getContentEl(ctx2), {
|
|
169
152
|
pointerBlocking: ctx2.modal,
|
|
170
153
|
exclude: dom.getTriggerEl(ctx2),
|
|
@@ -189,32 +172,18 @@ function machine(userContext) {
|
|
|
189
172
|
},
|
|
190
173
|
onFocusOutside(event) {
|
|
191
174
|
ctx2.onFocusOutside?.(event);
|
|
192
|
-
if (ctx2.currentPortalled) {
|
|
193
|
-
event.preventDefault();
|
|
194
|
-
}
|
|
195
175
|
},
|
|
196
176
|
onDismiss() {
|
|
197
177
|
send({ type: "REQUEST_CLOSE", src: "#interact-outside" });
|
|
198
178
|
}
|
|
199
179
|
});
|
|
200
180
|
},
|
|
201
|
-
|
|
202
|
-
if (ctx2.modal)
|
|
181
|
+
proxyTabFocus(ctx2) {
|
|
182
|
+
if (ctx2.modal || !ctx2.portalled)
|
|
203
183
|
return;
|
|
204
|
-
return (0,
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
(event) => {
|
|
208
|
-
const isTabKey = event.key === "Tab" && !(0, import_dom_event.isModifiedEvent)(event);
|
|
209
|
-
if (!isTabKey)
|
|
210
|
-
return;
|
|
211
|
-
send({
|
|
212
|
-
type: event.shiftKey ? "SHIFT_TAB" : "TAB",
|
|
213
|
-
preventDefault: () => event.preventDefault()
|
|
214
|
-
});
|
|
215
|
-
},
|
|
216
|
-
true
|
|
217
|
-
);
|
|
184
|
+
return (0, import_tabbable2.proxyTabFocus)(dom.getContentEl(ctx2), dom.getTriggerEl(ctx2), (el) => {
|
|
185
|
+
el.focus({ preventScroll: true });
|
|
186
|
+
});
|
|
218
187
|
},
|
|
219
188
|
hideContentBelow(ctx2) {
|
|
220
189
|
if (!ctx2.modal)
|
|
@@ -254,22 +223,22 @@ function machine(userContext) {
|
|
|
254
223
|
return () => trap?.deactivate();
|
|
255
224
|
}
|
|
256
225
|
},
|
|
257
|
-
guards: {
|
|
258
|
-
portalled: (ctx2) => ctx2.currentPortalled,
|
|
259
|
-
isRelatedTargetWithinContent: (ctx2, evt) => (0, import_dom_query2.contains)(dom.getContentEl(ctx2), evt.target),
|
|
260
|
-
closeOnInteractOutside: (ctx2) => !!ctx2.closeOnInteractOutside,
|
|
261
|
-
isContentFocused: (ctx2) => dom.getContentEl(ctx2) === dom.getActiveEl(ctx2),
|
|
262
|
-
isTriggerFocused: (ctx2) => dom.getTriggerEl(ctx2) === dom.getActiveEl(ctx2),
|
|
263
|
-
isFirstTabbableElement: (ctx2) => dom.getFirstTabbableEl(ctx2) === dom.getActiveEl(ctx2),
|
|
264
|
-
isLastTabbableElement: (ctx2) => dom.getLastTabbableEl(ctx2) === dom.getActiveEl(ctx2)
|
|
265
|
-
},
|
|
266
226
|
actions: {
|
|
227
|
+
setPositioning(ctx2, evt) {
|
|
228
|
+
(0, import_dom_query2.raf)(() => {
|
|
229
|
+
const anchorEl = dom.getAnchorEl(ctx2) ?? dom.getTriggerEl(ctx2);
|
|
230
|
+
(0, import_popper.getPlacement)(anchorEl, dom.getPositionerEl(ctx2), {
|
|
231
|
+
...ctx2.positioning,
|
|
232
|
+
...evt.options,
|
|
233
|
+
listeners: false
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
},
|
|
267
237
|
checkRenderedElements(ctx2) {
|
|
268
238
|
(0, import_dom_query2.raf)(() => {
|
|
269
239
|
Object.assign(ctx2.renderedElements, {
|
|
270
240
|
title: !!dom.getTitleEl(ctx2),
|
|
271
|
-
description: !!dom.getDescriptionEl(ctx2)
|
|
272
|
-
anchor: !!dom.getAnchorEl(ctx2)
|
|
241
|
+
description: !!dom.getDescriptionEl(ctx2)
|
|
273
242
|
});
|
|
274
243
|
});
|
|
275
244
|
},
|
|
@@ -283,38 +252,14 @@ function machine(userContext) {
|
|
|
283
252
|
return;
|
|
284
253
|
(0, import_dom_query2.raf)(() => dom.getTriggerEl(ctx2)?.focus());
|
|
285
254
|
},
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
dom.getFirstTabbableEl(ctx2)?.focus();
|
|
289
|
-
},
|
|
290
|
-
invokeOnOpen(ctx2, evt) {
|
|
291
|
-
if (evt.type !== "SETUP") {
|
|
292
|
-
ctx2.onOpenChange?.(true);
|
|
293
|
-
}
|
|
255
|
+
invokeOnOpen(ctx2) {
|
|
256
|
+
ctx2.onOpenChange?.(true);
|
|
294
257
|
},
|
|
295
|
-
invokeOnClose(ctx2
|
|
296
|
-
|
|
297
|
-
ctx2.onOpenChange?.(false);
|
|
298
|
-
}
|
|
258
|
+
invokeOnClose(ctx2) {
|
|
259
|
+
ctx2.onOpenChange?.(false);
|
|
299
260
|
},
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const button = dom.getTriggerEl(ctx2);
|
|
303
|
-
if (!content || !button)
|
|
304
|
-
return;
|
|
305
|
-
const lastTabbable = dom.getLastTabbableEl(ctx2);
|
|
306
|
-
if (lastTabbable !== dom.getActiveEl(ctx2))
|
|
307
|
-
return;
|
|
308
|
-
let tabbables = dom.getDocTabbableEls(ctx2);
|
|
309
|
-
let elementAfterTrigger = (0, import_utils2.next)(tabbables, tabbables.indexOf(button), { loop: false });
|
|
310
|
-
if (elementAfterTrigger === content) {
|
|
311
|
-
tabbables = tabbables.filter((el) => !(0, import_dom_query2.contains)(content, el));
|
|
312
|
-
elementAfterTrigger = (0, import_utils2.next)(tabbables, tabbables.indexOf(button), { loop: false });
|
|
313
|
-
}
|
|
314
|
-
if (!elementAfterTrigger || elementAfterTrigger === button)
|
|
315
|
-
return;
|
|
316
|
-
evt.preventDefault();
|
|
317
|
-
(0, import_dom_query2.raf)(() => elementAfterTrigger?.focus());
|
|
261
|
+
toggleVisibility(ctx2, _evt, { send }) {
|
|
262
|
+
send({ type: ctx2.open ? "OPEN" : "CLOSE", src: "controlled" });
|
|
318
263
|
}
|
|
319
264
|
}
|
|
320
265
|
}
|
package/dist/popover.machine.mjs
CHANGED
package/dist/popover.types.d.ts
CHANGED
|
@@ -56,9 +56,9 @@ type PublicContext = DismissableElementHandlers & CommonProperties & {
|
|
|
56
56
|
*/
|
|
57
57
|
positioning: PositioningOptions;
|
|
58
58
|
/**
|
|
59
|
-
* Whether
|
|
59
|
+
* Whether the popover is open
|
|
60
60
|
*/
|
|
61
|
-
|
|
61
|
+
open?: boolean;
|
|
62
62
|
};
|
|
63
63
|
type UserDefinedContext = RequiredBy<PublicContext, "id">;
|
|
64
64
|
type ComputedContext = Readonly<{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/popover",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Core logic for the popover widget implemented as a state machine",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -26,18 +26,17 @@
|
|
|
26
26
|
"url": "https://github.com/chakra-ui/zag/issues"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"focus-trap": "7.
|
|
29
|
+
"focus-trap": "7.4.0",
|
|
30
30
|
"@zag-js/anatomy": "0.1.4",
|
|
31
31
|
"@zag-js/aria-hidden": "0.2.2",
|
|
32
|
-
"@zag-js/core": "0.
|
|
32
|
+
"@zag-js/core": "0.5.0",
|
|
33
33
|
"@zag-js/dom-query": "0.1.4",
|
|
34
|
-
"@zag-js/
|
|
35
|
-
"@zag-js/
|
|
36
|
-
"@zag-js/
|
|
37
|
-
"@zag-js/
|
|
38
|
-
"@zag-js/popper": "0.2.5",
|
|
34
|
+
"@zag-js/utils": "0.3.4",
|
|
35
|
+
"@zag-js/dismissable": "0.5.0",
|
|
36
|
+
"@zag-js/tabbable": "0.1.1",
|
|
37
|
+
"@zag-js/popper": "0.2.7",
|
|
39
38
|
"@zag-js/remove-scroll": "0.2.4",
|
|
40
|
-
"@zag-js/types": "0.
|
|
39
|
+
"@zag-js/types": "0.5.0"
|
|
41
40
|
},
|
|
42
41
|
"devDependencies": {
|
|
43
42
|
"clean-package": "2.2.0"
|