@destyler/popover 0.0.7-beta.7 → 0.0.7-beta.9

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