@zag-js/popover 1.34.1 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,441 +1,10 @@
1
- import { createAnatomy } from '@zag-js/anatomy';
2
- import { raf, getInitialFocus, proxyTabFocus, dataAttr, ariaAttr, isLeftClick, isSafari } from '@zag-js/dom-query';
3
- import { getPlacement, getPlacementStyles } from '@zag-js/popper';
4
- import { ariaHidden } from '@zag-js/aria-hidden';
5
- import { createMachine } from '@zag-js/core';
6
- import { trackDismissableElement } from '@zag-js/dismissable';
7
- import { trapFocus } from '@zag-js/focus-trap';
8
- import { preventBodyScroll } from '@zag-js/remove-scroll';
9
- import { createProps } from '@zag-js/types';
10
- import { createSplitProps } from '@zag-js/utils';
11
-
12
- // src/popover.anatomy.ts
13
- var anatomy = createAnatomy("popover").parts(
14
- "arrow",
15
- "arrowTip",
16
- "anchor",
17
- "trigger",
18
- "indicator",
19
- "positioner",
20
- "content",
21
- "title",
22
- "description",
23
- "closeTrigger"
24
- );
25
- var parts = anatomy.build();
26
- var getAnchorId = (scope) => scope.ids?.anchor ?? `popover:${scope.id}:anchor`;
27
- var getTriggerId = (scope) => scope.ids?.trigger ?? `popover:${scope.id}:trigger`;
28
- var getContentId = (scope) => scope.ids?.content ?? `popover:${scope.id}:content`;
29
- var getPositionerId = (scope) => scope.ids?.positioner ?? `popover:${scope.id}:popper`;
30
- var getArrowId = (scope) => scope.ids?.arrow ?? `popover:${scope.id}:arrow`;
31
- var getTitleId = (scope) => scope.ids?.title ?? `popover:${scope.id}:title`;
32
- var getDescriptionId = (scope) => scope.ids?.description ?? `popover:${scope.id}:desc`;
33
- var getCloseTriggerId = (scope) => scope.ids?.closeTrigger ?? `popover:${scope.id}:close`;
34
- var getAnchorEl = (scope) => scope.getById(getAnchorId(scope));
35
- var getTriggerEl = (scope) => scope.getById(getTriggerId(scope));
36
- var getContentEl = (scope) => scope.getById(getContentId(scope));
37
- var getPositionerEl = (scope) => scope.getById(getPositionerId(scope));
38
- var getTitleEl = (scope) => scope.getById(getTitleId(scope));
39
- var getDescriptionEl = (scope) => scope.getById(getDescriptionId(scope));
40
-
41
- // src/popover.connect.ts
42
- function connect(service, normalize) {
43
- const { state, context, send, computed, prop, scope } = service;
44
- const open = state.matches("open");
45
- const currentPlacement = context.get("currentPlacement");
46
- const portalled = computed("currentPortalled");
47
- const rendered = context.get("renderedElements");
48
- const popperStyles = getPlacementStyles({
49
- ...prop("positioning"),
50
- placement: currentPlacement
51
- });
52
- return {
53
- portalled,
54
- open,
55
- setOpen(nextOpen) {
56
- const open2 = state.matches("open");
57
- if (open2 === nextOpen) return;
58
- send({ type: nextOpen ? "OPEN" : "CLOSE" });
59
- },
60
- reposition(options = {}) {
61
- send({ type: "POSITIONING.SET", options });
62
- },
63
- getArrowProps() {
64
- return normalize.element({
65
- id: getArrowId(scope),
66
- ...parts.arrow.attrs,
67
- dir: prop("dir"),
68
- style: popperStyles.arrow
69
- });
70
- },
71
- getArrowTipProps() {
72
- return normalize.element({
73
- ...parts.arrowTip.attrs,
74
- dir: prop("dir"),
75
- style: popperStyles.arrowTip
76
- });
77
- },
78
- getAnchorProps() {
79
- return normalize.element({
80
- ...parts.anchor.attrs,
81
- dir: prop("dir"),
82
- id: getAnchorId(scope)
83
- });
84
- },
85
- getTriggerProps() {
86
- return normalize.button({
87
- ...parts.trigger.attrs,
88
- dir: prop("dir"),
89
- type: "button",
90
- "data-placement": currentPlacement,
91
- id: getTriggerId(scope),
92
- "aria-haspopup": "dialog",
93
- "aria-expanded": open,
94
- "data-state": open ? "open" : "closed",
95
- "aria-controls": getContentId(scope),
96
- onPointerDown(event) {
97
- if (!isLeftClick(event)) return;
98
- if (isSafari()) {
99
- event.currentTarget.focus();
100
- }
101
- },
102
- onClick(event) {
103
- if (event.defaultPrevented) return;
104
- send({ type: "TOGGLE" });
105
- },
106
- onBlur(event) {
107
- send({ type: "TRIGGER_BLUR", target: event.relatedTarget });
108
- }
109
- });
110
- },
111
- getIndicatorProps() {
112
- return normalize.element({
113
- ...parts.indicator.attrs,
114
- dir: prop("dir"),
115
- "data-state": open ? "open" : "closed"
116
- });
117
- },
118
- getPositionerProps() {
119
- return normalize.element({
120
- id: getPositionerId(scope),
121
- ...parts.positioner.attrs,
122
- dir: prop("dir"),
123
- style: popperStyles.floating
124
- });
125
- },
126
- getContentProps() {
127
- return normalize.element({
128
- ...parts.content.attrs,
129
- dir: prop("dir"),
130
- id: getContentId(scope),
131
- tabIndex: -1,
132
- role: "dialog",
133
- "aria-modal": ariaAttr(prop("modal")),
134
- hidden: !open,
135
- "data-state": open ? "open" : "closed",
136
- "data-expanded": dataAttr(open),
137
- "aria-labelledby": rendered.title ? getTitleId(scope) : void 0,
138
- "aria-describedby": rendered.description ? getDescriptionId(scope) : void 0,
139
- "data-placement": currentPlacement
140
- });
141
- },
142
- getTitleProps() {
143
- return normalize.element({
144
- ...parts.title.attrs,
145
- id: getTitleId(scope),
146
- dir: prop("dir")
147
- });
148
- },
149
- getDescriptionProps() {
150
- return normalize.element({
151
- ...parts.description.attrs,
152
- id: getDescriptionId(scope),
153
- dir: prop("dir")
154
- });
155
- },
156
- getCloseTriggerProps() {
157
- return normalize.button({
158
- ...parts.closeTrigger.attrs,
159
- dir: prop("dir"),
160
- id: getCloseTriggerId(scope),
161
- type: "button",
162
- "aria-label": "close",
163
- onClick(event) {
164
- if (event.defaultPrevented) return;
165
- event.stopPropagation();
166
- send({ type: "CLOSE" });
167
- }
168
- });
169
- }
170
- };
171
- }
172
- var machine = createMachine({
173
- props({ props: props2 }) {
174
- return {
175
- closeOnInteractOutside: true,
176
- closeOnEscape: true,
177
- autoFocus: true,
178
- modal: false,
179
- portalled: true,
180
- ...props2,
181
- positioning: {
182
- placement: "bottom",
183
- ...props2.positioning
184
- }
185
- };
186
- },
187
- initialState({ prop }) {
188
- const open = prop("open") || prop("defaultOpen");
189
- return open ? "open" : "closed";
190
- },
191
- context({ bindable }) {
192
- return {
193
- currentPlacement: bindable(() => ({
194
- defaultValue: void 0
195
- })),
196
- renderedElements: bindable(() => ({
197
- defaultValue: { title: true, description: true }
198
- }))
199
- };
200
- },
201
- computed: {
202
- currentPortalled: ({ prop }) => !!prop("modal") || !!prop("portalled")
203
- },
204
- watch({ track, prop, action }) {
205
- track([() => prop("open")], () => {
206
- action(["toggleVisibility"]);
207
- });
208
- },
209
- entry: ["checkRenderedElements"],
210
- states: {
211
- closed: {
212
- on: {
213
- "CONTROLLED.OPEN": {
214
- target: "open",
215
- actions: ["setInitialFocus"]
216
- },
217
- TOGGLE: [
218
- {
219
- guard: "isOpenControlled",
220
- actions: ["invokeOnOpen"]
221
- },
222
- {
223
- target: "open",
224
- actions: ["invokeOnOpen", "setInitialFocus"]
225
- }
226
- ],
227
- OPEN: [
228
- {
229
- guard: "isOpenControlled",
230
- actions: ["invokeOnOpen"]
231
- },
232
- {
233
- target: "open",
234
- actions: ["invokeOnOpen", "setInitialFocus"]
235
- }
236
- ]
237
- }
238
- },
239
- open: {
240
- effects: [
241
- "trapFocus",
242
- "preventScroll",
243
- "hideContentBelow",
244
- "trackPositioning",
245
- "trackDismissableElement",
246
- "proxyTabFocus"
247
- ],
248
- on: {
249
- "CONTROLLED.CLOSE": {
250
- target: "closed",
251
- actions: ["setFinalFocus"]
252
- },
253
- CLOSE: [
254
- {
255
- guard: "isOpenControlled",
256
- actions: ["invokeOnClose"]
257
- },
258
- {
259
- target: "closed",
260
- actions: ["invokeOnClose", "setFinalFocus"]
261
- }
262
- ],
263
- TOGGLE: [
264
- {
265
- guard: "isOpenControlled",
266
- actions: ["invokeOnClose"]
267
- },
268
- {
269
- target: "closed",
270
- actions: ["invokeOnClose"]
271
- }
272
- ],
273
- "POSITIONING.SET": {
274
- actions: ["reposition"]
275
- }
276
- }
277
- }
278
- },
279
- implementations: {
280
- guards: {
281
- isOpenControlled: ({ prop }) => prop("open") != void 0
282
- },
283
- effects: {
284
- trackPositioning({ context, prop, scope }) {
285
- context.set("currentPlacement", prop("positioning").placement);
286
- const anchorEl = getAnchorEl(scope) ?? getTriggerEl(scope);
287
- const getPositionerEl2 = () => getPositionerEl(scope);
288
- return getPlacement(anchorEl, getPositionerEl2, {
289
- ...prop("positioning"),
290
- defer: true,
291
- onComplete(data) {
292
- context.set("currentPlacement", data.placement);
293
- }
294
- });
295
- },
296
- trackDismissableElement({ send, prop, scope }) {
297
- const getContentEl2 = () => getContentEl(scope);
298
- let restoreFocus = true;
299
- return trackDismissableElement(getContentEl2, {
300
- type: "popover",
301
- pointerBlocking: prop("modal"),
302
- exclude: getTriggerEl(scope),
303
- defer: true,
304
- onEscapeKeyDown(event) {
305
- prop("onEscapeKeyDown")?.(event);
306
- if (prop("closeOnEscape")) return;
307
- event.preventDefault();
308
- },
309
- onInteractOutside(event) {
310
- prop("onInteractOutside")?.(event);
311
- if (event.defaultPrevented) return;
312
- restoreFocus = !(event.detail.focusable || event.detail.contextmenu);
313
- if (!prop("closeOnInteractOutside")) {
314
- event.preventDefault();
315
- }
316
- },
317
- onPointerDownOutside: prop("onPointerDownOutside"),
318
- onFocusOutside: prop("onFocusOutside"),
319
- persistentElements: prop("persistentElements"),
320
- onRequestDismiss: prop("onRequestDismiss"),
321
- onDismiss() {
322
- send({ type: "CLOSE", src: "interact-outside", restoreFocus });
323
- }
324
- });
325
- },
326
- proxyTabFocus({ prop, scope }) {
327
- if (prop("modal") || !prop("portalled")) return;
328
- const getContentEl2 = () => getContentEl(scope);
329
- return proxyTabFocus(getContentEl2, {
330
- triggerElement: getTriggerEl(scope),
331
- defer: true,
332
- getShadowRoot: true,
333
- onFocus(el) {
334
- el.focus({ preventScroll: true });
335
- }
336
- });
337
- },
338
- hideContentBelow({ prop, scope }) {
339
- if (!prop("modal")) return;
340
- const getElements = () => [getContentEl(scope), getTriggerEl(scope)];
341
- return ariaHidden(getElements, { defer: true });
342
- },
343
- preventScroll({ prop, scope }) {
344
- if (!prop("modal")) return;
345
- return preventBodyScroll(scope.getDoc());
346
- },
347
- trapFocus({ prop, scope }) {
348
- if (!prop("modal")) return;
349
- const contentEl = () => getContentEl(scope);
350
- return trapFocus(contentEl, {
351
- initialFocus: () => getInitialFocus({
352
- root: getContentEl(scope),
353
- getInitialEl: prop("initialFocusEl"),
354
- enabled: prop("autoFocus")
355
- }),
356
- getShadowRoot: true
357
- });
358
- }
359
- },
360
- actions: {
361
- reposition({ event, prop, scope, context }) {
362
- const anchorEl = getAnchorEl(scope) ?? getTriggerEl(scope);
363
- const getPositionerEl2 = () => getPositionerEl(scope);
364
- getPlacement(anchorEl, getPositionerEl2, {
365
- ...prop("positioning"),
366
- ...event.options,
367
- defer: true,
368
- listeners: false,
369
- onComplete(data) {
370
- context.set("currentPlacement", data.placement);
371
- }
372
- });
373
- },
374
- checkRenderedElements({ context, scope }) {
375
- raf(() => {
376
- Object.assign(context.get("renderedElements"), {
377
- title: !!getTitleEl(scope),
378
- description: !!getDescriptionEl(scope)
379
- });
380
- });
381
- },
382
- setInitialFocus({ prop, scope }) {
383
- if (prop("modal")) return;
384
- raf(() => {
385
- const element = getInitialFocus({
386
- root: getContentEl(scope),
387
- getInitialEl: prop("initialFocusEl"),
388
- enabled: prop("autoFocus")
389
- });
390
- element?.focus({ preventScroll: true });
391
- });
392
- },
393
- setFinalFocus({ event, scope }) {
394
- const restoreFocus = event.restoreFocus ?? event.previousEvent?.restoreFocus;
395
- if (restoreFocus != null && !restoreFocus) return;
396
- raf(() => {
397
- const element = getTriggerEl(scope);
398
- element?.focus({ preventScroll: true });
399
- });
400
- },
401
- invokeOnOpen({ prop, flush }) {
402
- flush(() => {
403
- prop("onOpenChange")?.({ open: true });
404
- });
405
- },
406
- invokeOnClose({ prop, flush }) {
407
- flush(() => {
408
- prop("onOpenChange")?.({ open: false });
409
- });
410
- },
411
- toggleVisibility({ event, send, prop }) {
412
- send({ type: prop("open") ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE", previousEvent: event });
413
- }
414
- }
415
- }
416
- });
417
- var props = createProps()([
418
- "autoFocus",
419
- "closeOnEscape",
420
- "closeOnInteractOutside",
421
- "dir",
422
- "getRootNode",
423
- "id",
424
- "ids",
425
- "initialFocusEl",
426
- "modal",
427
- "onEscapeKeyDown",
428
- "onFocusOutside",
429
- "onInteractOutside",
430
- "onOpenChange",
431
- "onPointerDownOutside",
432
- "onRequestDismiss",
433
- "defaultOpen",
434
- "open",
435
- "persistentElements",
436
- "portalled",
437
- "positioning"
438
- ]);
439
- var splitProps = createSplitProps(props);
440
-
441
- export { anatomy, connect, machine, props, splitProps };
1
+ // src/index.ts
2
+ import { anatomy } from "./popover.anatomy.mjs";
3
+ import { connect } from "./popover.connect.mjs";
4
+ import { machine } from "./popover.machine.mjs";
5
+ export * from "./popover.props.mjs";
6
+ export {
7
+ anatomy,
8
+ connect,
9
+ machine
10
+ };
@@ -0,0 +1,6 @@
1
+ import * as _zag_js_anatomy from '@zag-js/anatomy';
2
+
3
+ declare const anatomy: _zag_js_anatomy.AnatomyInstance<"content" | "title" | "anchor" | "arrow" | "arrowTip" | "trigger" | "indicator" | "positioner" | "description" | "closeTrigger">;
4
+ declare const parts: Record<"content" | "title" | "anchor" | "arrow" | "arrowTip" | "trigger" | "indicator" | "positioner" | "description" | "closeTrigger", _zag_js_anatomy.AnatomyPart>;
5
+
6
+ export { anatomy, parts };
@@ -0,0 +1,6 @@
1
+ import * as _zag_js_anatomy from '@zag-js/anatomy';
2
+
3
+ declare const anatomy: _zag_js_anatomy.AnatomyInstance<"content" | "title" | "anchor" | "arrow" | "arrowTip" | "trigger" | "indicator" | "positioner" | "description" | "closeTrigger">;
4
+ declare const parts: Record<"content" | "title" | "anchor" | "arrow" | "arrowTip" | "trigger" | "indicator" | "positioner" | "description" | "closeTrigger", _zag_js_anatomy.AnatomyPart>;
5
+
6
+ export { anatomy, parts };
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/popover.anatomy.ts
21
+ var popover_anatomy_exports = {};
22
+ __export(popover_anatomy_exports, {
23
+ anatomy: () => anatomy,
24
+ parts: () => parts
25
+ });
26
+ module.exports = __toCommonJS(popover_anatomy_exports);
27
+ var import_anatomy = require("@zag-js/anatomy");
28
+ var anatomy = (0, import_anatomy.createAnatomy)("popover").parts(
29
+ "arrow",
30
+ "arrowTip",
31
+ "anchor",
32
+ "trigger",
33
+ "indicator",
34
+ "positioner",
35
+ "content",
36
+ "title",
37
+ "description",
38
+ "closeTrigger"
39
+ );
40
+ var parts = anatomy.build();
41
+ // Annotate the CommonJS export names for ESM import in node:
42
+ 0 && (module.exports = {
43
+ anatomy,
44
+ parts
45
+ });
@@ -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
+ "indicator",
9
+ "positioner",
10
+ "content",
11
+ "title",
12
+ "description",
13
+ "closeTrigger"
14
+ );
15
+ var parts = anatomy.build();
16
+ export {
17
+ anatomy,
18
+ parts
19
+ };
@@ -0,0 +1,9 @@
1
+ import { PropTypes, NormalizeProps } from '@zag-js/types';
2
+ import { PopoverService, PopoverApi } from './popover.types.mjs';
3
+ import '@zag-js/core';
4
+ import '@zag-js/dismissable';
5
+ import '@zag-js/popper';
6
+
7
+ declare function connect<T extends PropTypes>(service: PopoverService, normalize: NormalizeProps<T>): PopoverApi<T>;
8
+
9
+ export { connect };
@@ -0,0 +1,9 @@
1
+ import { PropTypes, NormalizeProps } from '@zag-js/types';
2
+ import { PopoverService, PopoverApi } from './popover.types.js';
3
+ import '@zag-js/core';
4
+ import '@zag-js/dismissable';
5
+ import '@zag-js/popper';
6
+
7
+ declare function connect<T extends PropTypes>(service: PopoverService, normalize: NormalizeProps<T>): PopoverApi<T>;
8
+
9
+ export { connect };