@zag-js/popover 0.1.11 → 0.1.12

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.
Files changed (3) hide show
  1. package/dist/index.js +242 -234
  2. package/dist/index.mjs +242 -234
  3. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -335,262 +335,270 @@ var import_remove_scroll = require("@zag-js/remove-scroll");
335
335
  var import_focus_trap = require("focus-trap");
336
336
  var { and, or, not } = import_core.guards;
337
337
  function machine(ctx) {
338
- return (0, import_core.createMachine)({
339
- id: "popover",
340
- initial: "unknown",
341
- context: {
342
- closeOnInteractOutside: true,
343
- closeOnEsc: true,
344
- autoFocus: true,
345
- modal: false,
346
- positioning: {
347
- placement: "bottom",
348
- ...ctx.positioning
349
- },
350
- currentPlacement: void 0,
351
- ...ctx,
352
- focusTriggerOnClose: true,
353
- renderedElements: {
354
- title: true,
355
- description: true,
356
- anchor: false
357
- }
358
- },
359
- computed: {
360
- currentPortalled: (ctx2) => !!ctx2.modal || !!ctx2.portalled
361
- },
362
- states: {
363
- unknown: {
364
- on: {
365
- SETUP: {
366
- target: ctx.defaultOpen ? "open" : "closed",
367
- actions: "checkRenderedElements"
368
- }
338
+ return (0, import_core.createMachine)(
339
+ {
340
+ id: "popover",
341
+ initial: "unknown",
342
+ context: {
343
+ closeOnInteractOutside: true,
344
+ closeOnEsc: true,
345
+ autoFocus: true,
346
+ modal: false,
347
+ positioning: {
348
+ placement: "bottom",
349
+ ...ctx.positioning
350
+ },
351
+ currentPlacement: void 0,
352
+ ...ctx,
353
+ focusTriggerOnClose: true,
354
+ renderedElements: {
355
+ title: true,
356
+ description: true,
357
+ anchor: false
369
358
  }
370
359
  },
371
- closed: {
372
- entry: "invokeOnClose",
373
- on: {
374
- TOGGLE: "open",
375
- OPEN: "open"
376
- }
360
+ computed: {
361
+ currentPortalled: (ctx2) => !!ctx2.modal || !!ctx2.portalled
377
362
  },
378
- open: {
379
- activities: [
380
- "trapFocus",
381
- "preventScroll",
382
- "hideContentBelow",
383
- "computePlacement",
384
- "trackInteractionOutside",
385
- "trackTabKeyDown"
386
- ],
387
- entry: ["setInitialFocus", "invokeOnOpen"],
388
- on: {
389
- CLOSE: "closed",
390
- REQUEST_CLOSE: {
391
- target: "closed",
392
- actions: "focusTriggerIfNeeded"
393
- },
394
- TOGGLE: "closed",
395
- TRIGGER_BLUR: {
396
- guard: not("isRelatedTargetWithinContent"),
397
- target: "closed"
398
- },
399
- TAB: [
400
- {
401
- guard: and("isTriggerFocused", "portalled"),
402
- actions: "focusFirstTabbableElement"
403
- },
404
- {
405
- guard: and("isLastTabbableElement", "closeOnInteractOutside", "portalled"),
406
- target: "closed",
407
- actions: "focusNextTabbableElementAfterTrigger"
363
+ states: {
364
+ unknown: {
365
+ on: {
366
+ SETUP: {
367
+ target: ctx.defaultOpen ? "open" : "closed",
368
+ actions: "checkRenderedElements"
408
369
  }
370
+ }
371
+ },
372
+ closed: {
373
+ entry: "invokeOnClose",
374
+ on: {
375
+ TOGGLE: "open",
376
+ OPEN: "open"
377
+ }
378
+ },
379
+ open: {
380
+ activities: [
381
+ "trapFocus",
382
+ "preventScroll",
383
+ "hideContentBelow",
384
+ "computePlacement",
385
+ "trackInteractionOutside",
386
+ "trackTabKeyDown"
409
387
  ],
410
- SHIFT_TAB: {
411
- guard: and(or("isFirstTabbableElement", "isContentFocused"), "portalled"),
412
- actions: "focusTriggerIfNeeded"
388
+ entry: ["setInitialFocus", "invokeOnOpen"],
389
+ on: {
390
+ CLOSE: "closed",
391
+ REQUEST_CLOSE: {
392
+ target: "closed",
393
+ actions: "focusTriggerIfNeeded"
394
+ },
395
+ TOGGLE: "closed",
396
+ TRIGGER_BLUR: {
397
+ guard: not("isRelatedTargetWithinContent"),
398
+ target: "closed"
399
+ },
400
+ TAB: [
401
+ {
402
+ guard: and("isTriggerFocused", "portalled"),
403
+ actions: "focusFirstTabbableElement"
404
+ },
405
+ {
406
+ guard: and("isLastTabbableElement", "closeOnInteractOutside", "portalled"),
407
+ target: "closed",
408
+ actions: "focusNextTabbableElementAfterTrigger"
409
+ }
410
+ ],
411
+ SHIFT_TAB: {
412
+ guard: and(or("isFirstTabbableElement", "isContentFocused"), "portalled"),
413
+ actions: "focusTriggerIfNeeded"
414
+ }
413
415
  }
414
416
  }
415
417
  }
416
- }
417
- }, {
418
- activities: {
419
- computePlacement(ctx2) {
420
- ctx2.currentPlacement = ctx2.positioning.placement;
421
- const anchorEl = ctx2.renderedElements.anchor ? dom.getAnchorEl(ctx2) : dom.getTriggerEl(ctx2);
422
- return (0, import_popper2.getPlacement)(anchorEl, dom.getPositionerEl(ctx2), {
423
- ...ctx2.positioning,
424
- onComplete(data) {
425
- ctx2.currentPlacement = data.placement;
426
- ctx2.isPlacementComplete = true;
427
- },
428
- onCleanup() {
429
- ctx2.currentPlacement = void 0;
430
- ctx2.isPlacementComplete = false;
431
- }
432
- });
433
- },
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();
418
+ },
419
+ {
420
+ activities: {
421
+ computePlacement(ctx2) {
422
+ ctx2.currentPlacement = ctx2.positioning.placement;
423
+ const anchorEl = ctx2.renderedElements.anchor ? dom.getAnchorEl(ctx2) : dom.getTriggerEl(ctx2);
424
+ return (0, import_popper2.getPlacement)(anchorEl, dom.getPositionerEl(ctx2), {
425
+ ...ctx2.positioning,
426
+ onComplete(data) {
427
+ ctx2.currentPlacement = data.placement;
428
+ ctx2.isPlacementComplete = true;
429
+ },
430
+ onCleanup() {
431
+ ctx2.currentPlacement = void 0;
432
+ ctx2.isPlacementComplete = false;
454
433
  }
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) {
434
+ });
435
+ },
436
+ trackInteractionOutside(ctx2, _evt, { send }) {
437
+ return (0, import_dismissable.trackDismissableElement)(dom.getContentEl(ctx2), {
438
+ pointerBlocking: ctx2.modal,
439
+ exclude: dom.getTriggerEl(ctx2),
440
+ onEscapeKeyDown(event) {
441
+ var _a;
442
+ (_a = ctx2.onEscapeKeyDown) == null ? void 0 : _a.call(ctx2, event);
443
+ if (ctx2.closeOnEsc)
444
+ return;
445
+ ctx2.focusTriggerOnClose = true;
464
446
  event.preventDefault();
447
+ },
448
+ onInteractOutside(event) {
449
+ var _a;
450
+ (_a = ctx2.onInteractOutside) == null ? void 0 : _a.call(ctx2, event);
451
+ if (event.defaultPrevented)
452
+ return;
453
+ ctx2.focusTriggerOnClose = !(event.detail.focusable || event.detail.contextmenu);
454
+ if (!ctx2.closeOnInteractOutside) {
455
+ event.preventDefault();
456
+ }
457
+ },
458
+ onPointerDownOutside(event) {
459
+ var _a;
460
+ (_a = ctx2.onPointerDownOutside) == null ? void 0 : _a.call(ctx2, event);
461
+ },
462
+ onFocusOutside(event) {
463
+ var _a;
464
+ (_a = ctx2.onFocusOutside) == null ? void 0 : _a.call(ctx2, event);
465
+ if (ctx2.currentPortalled) {
466
+ event.preventDefault();
467
+ }
468
+ },
469
+ onDismiss() {
470
+ send({ type: "REQUEST_CLOSE", src: "#interact-outside" });
465
471
  }
466
- },
467
- onDismiss() {
468
- send({ type: "REQUEST_CLOSE", src: "#interact-outside" });
469
- }
470
- });
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)
472
+ });
473
+ },
474
+ trackTabKeyDown(ctx2, _evt, { send }) {
475
+ if (ctx2.modal)
478
476
  return;
479
- send({
480
- type: event.shiftKey ? "SHIFT_TAB" : "TAB",
481
- preventDefault: () => event.preventDefault()
477
+ return addDomEvent(
478
+ dom.getWin(ctx2),
479
+ "keydown",
480
+ (event) => {
481
+ const isTabKey = event.key === "Tab" && !isModifiedEvent(event);
482
+ if (!isTabKey)
483
+ return;
484
+ send({
485
+ type: event.shiftKey ? "SHIFT_TAB" : "TAB",
486
+ preventDefault: () => event.preventDefault()
487
+ });
488
+ },
489
+ true
490
+ );
491
+ },
492
+ hideContentBelow(ctx2) {
493
+ if (!ctx2.modal)
494
+ return;
495
+ let cleanup;
496
+ nextTick(() => {
497
+ cleanup = (0, import_aria_hidden.ariaHidden)([dom.getContentEl(ctx2), dom.getTriggerEl(ctx2)]);
482
498
  });
483
- }, true);
484
- },
485
- hideContentBelow(ctx2) {
486
- if (!ctx2.modal)
487
- return;
488
- let cleanup;
489
- nextTick(() => {
490
- cleanup = (0, import_aria_hidden.ariaHidden)([dom.getContentEl(ctx2), dom.getTriggerEl(ctx2)]);
491
- });
492
- return () => cleanup == null ? void 0 : cleanup();
499
+ return () => cleanup == null ? void 0 : cleanup();
500
+ },
501
+ preventScroll(ctx2) {
502
+ if (!ctx2.modal)
503
+ return;
504
+ return (0, import_remove_scroll.preventBodyScroll)(dom.getDoc(ctx2));
505
+ },
506
+ trapFocus(ctx2) {
507
+ if (!ctx2.modal)
508
+ return;
509
+ let trap;
510
+ nextTick(() => {
511
+ const el = dom.getContentEl(ctx2);
512
+ if (!el)
513
+ return;
514
+ trap = (0, import_focus_trap.createFocusTrap)(el, {
515
+ escapeDeactivates: false,
516
+ allowOutsideClick: true,
517
+ returnFocusOnDeactivate: true,
518
+ document: dom.getDoc(ctx2),
519
+ fallbackFocus: el,
520
+ initialFocus: runIfFn2(ctx2.initialFocusEl)
521
+ });
522
+ try {
523
+ trap.activate();
524
+ } catch {
525
+ }
526
+ });
527
+ return () => trap == null ? void 0 : trap.deactivate();
528
+ }
493
529
  },
494
- preventScroll(ctx2) {
495
- if (!ctx2.modal)
496
- return;
497
- return (0, import_remove_scroll.preventBodyScroll)(dom.getDoc(ctx2));
530
+ guards: {
531
+ portalled: (ctx2) => ctx2.currentPortalled,
532
+ isRelatedTargetWithinContent: (ctx2, evt) => contains(dom.getContentEl(ctx2), evt.target),
533
+ closeOnInteractOutside: (ctx2) => !!ctx2.closeOnInteractOutside,
534
+ isContentFocused: (ctx2) => dom.getContentEl(ctx2) === dom.getActiveEl(ctx2),
535
+ isTriggerFocused: (ctx2) => dom.getTriggerEl(ctx2) === dom.getActiveEl(ctx2),
536
+ isFirstTabbableElement: (ctx2) => dom.getFirstTabbableEl(ctx2) === dom.getActiveEl(ctx2),
537
+ isLastTabbableElement: (ctx2) => dom.getLastTabbableEl(ctx2) === dom.getActiveEl(ctx2)
498
538
  },
499
- trapFocus(ctx2) {
500
- if (!ctx2.modal)
501
- return;
502
- let trap;
503
- nextTick(() => {
504
- const el = dom.getContentEl(ctx2);
505
- if (!el)
506
- return;
507
- trap = (0, import_focus_trap.createFocusTrap)(el, {
508
- escapeDeactivates: false,
509
- allowOutsideClick: true,
510
- returnFocusOnDeactivate: true,
511
- document: dom.getDoc(ctx2),
512
- fallbackFocus: el,
513
- initialFocus: runIfFn2(ctx2.initialFocusEl)
539
+ actions: {
540
+ checkRenderedElements(ctx2) {
541
+ raf(() => {
542
+ Object.assign(ctx2.renderedElements, {
543
+ title: !!dom.getTitleEl(ctx2),
544
+ description: !!dom.getDescriptionEl(ctx2),
545
+ anchor: !!dom.getAnchorEl(ctx2)
546
+ });
514
547
  });
515
- try {
516
- trap.activate();
517
- } catch {
518
- }
519
- });
520
- return () => trap == null ? void 0 : trap.deactivate();
521
- }
522
- },
523
- guards: {
524
- portalled: (ctx2) => ctx2.currentPortalled,
525
- isRelatedTargetWithinContent: (ctx2, evt) => contains(dom.getContentEl(ctx2), evt.target),
526
- closeOnInteractOutside: (ctx2) => !!ctx2.closeOnInteractOutside,
527
- isContentFocused: (ctx2) => dom.getContentEl(ctx2) === dom.getActiveEl(ctx2),
528
- isTriggerFocused: (ctx2) => dom.getTriggerEl(ctx2) === dom.getActiveEl(ctx2),
529
- isFirstTabbableElement: (ctx2) => dom.getFirstTabbableEl(ctx2) === dom.getActiveEl(ctx2),
530
- isLastTabbableElement: (ctx2) => dom.getLastTabbableEl(ctx2) === dom.getActiveEl(ctx2)
531
- },
532
- actions: {
533
- checkRenderedElements(ctx2) {
534
- raf(() => {
535
- Object.assign(ctx2.renderedElements, {
536
- title: !!dom.getTitleEl(ctx2),
537
- description: !!dom.getDescriptionEl(ctx2),
538
- anchor: !!dom.getAnchorEl(ctx2)
548
+ },
549
+ setInitialFocus(ctx2) {
550
+ raf(() => {
551
+ var _a;
552
+ (_a = dom.getInitialFocusEl(ctx2)) == null ? void 0 : _a.focus();
539
553
  });
540
- });
541
- },
542
- setInitialFocus(ctx2) {
543
- raf(() => {
554
+ },
555
+ focusTriggerIfNeeded(ctx2) {
556
+ if (!ctx2.focusTriggerOnClose)
557
+ return;
558
+ raf(() => {
559
+ var _a;
560
+ return (_a = dom.getTriggerEl(ctx2)) == null ? void 0 : _a.focus();
561
+ });
562
+ },
563
+ focusFirstTabbableElement(ctx2, evt) {
544
564
  var _a;
545
- (_a = dom.getInitialFocusEl(ctx2)) == null ? void 0 : _a.focus();
546
- });
547
- },
548
- focusTriggerIfNeeded(ctx2) {
549
- if (!ctx2.focusTriggerOnClose)
550
- return;
551
- raf(() => {
565
+ evt.preventDefault();
566
+ (_a = dom.getFirstTabbableEl(ctx2)) == null ? void 0 : _a.focus();
567
+ },
568
+ invokeOnOpen(ctx2, evt) {
552
569
  var _a;
553
- return (_a = dom.getTriggerEl(ctx2)) == null ? void 0 : _a.focus();
554
- });
555
- },
556
- focusFirstTabbableElement(ctx2, evt) {
557
- var _a;
558
- evt.preventDefault();
559
- (_a = dom.getFirstTabbableEl(ctx2)) == null ? void 0 : _a.focus();
560
- },
561
- invokeOnOpen(ctx2, evt) {
562
- var _a;
563
- if (evt.type !== "SETUP") {
564
- (_a = ctx2.onOpenChange) == null ? void 0 : _a.call(ctx2, true);
565
- }
566
- },
567
- invokeOnClose(ctx2, evt) {
568
- var _a;
569
- if (evt.type !== "SETUP") {
570
- (_a = ctx2.onOpenChange) == null ? void 0 : _a.call(ctx2, false);
571
- }
572
- },
573
- focusNextTabbableElementAfterTrigger(ctx2, evt) {
574
- const content = dom.getContentEl(ctx2);
575
- const button = dom.getTriggerEl(ctx2);
576
- if (!content || !button)
577
- return;
578
- const lastTabbable = dom.getLastTabbableEl(ctx2);
579
- if (lastTabbable !== dom.getActiveEl(ctx2))
580
- return;
581
- let tabbables = dom.getDocTabbableEls(ctx2);
582
- let elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
583
- if (elementAfterTrigger === content) {
584
- tabbables = tabbables.filter((el) => !contains(content, el));
585
- elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
570
+ if (evt.type !== "SETUP") {
571
+ (_a = ctx2.onOpenChange) == null ? void 0 : _a.call(ctx2, true);
572
+ }
573
+ },
574
+ invokeOnClose(ctx2, evt) {
575
+ var _a;
576
+ if (evt.type !== "SETUP") {
577
+ (_a = ctx2.onOpenChange) == null ? void 0 : _a.call(ctx2, false);
578
+ }
579
+ },
580
+ focusNextTabbableElementAfterTrigger(ctx2, evt) {
581
+ const content = dom.getContentEl(ctx2);
582
+ const button = dom.getTriggerEl(ctx2);
583
+ if (!content || !button)
584
+ return;
585
+ const lastTabbable = dom.getLastTabbableEl(ctx2);
586
+ if (lastTabbable !== dom.getActiveEl(ctx2))
587
+ return;
588
+ let tabbables = dom.getDocTabbableEls(ctx2);
589
+ let elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
590
+ if (elementAfterTrigger === content) {
591
+ tabbables = tabbables.filter((el) => !contains(content, el));
592
+ elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
593
+ }
594
+ if (!elementAfterTrigger || elementAfterTrigger === button)
595
+ return;
596
+ evt.preventDefault();
597
+ raf(() => elementAfterTrigger == null ? void 0 : elementAfterTrigger.focus());
586
598
  }
587
- if (!elementAfterTrigger || elementAfterTrigger === button)
588
- return;
589
- evt.preventDefault();
590
- raf(() => elementAfterTrigger == null ? void 0 : elementAfterTrigger.focus());
591
599
  }
592
600
  }
593
- });
601
+ );
594
602
  }
595
603
  // Annotate the CommonJS export names for ESM import in node:
596
604
  0 && (module.exports = {
package/dist/index.mjs CHANGED
@@ -308,262 +308,270 @@ import { preventBodyScroll } from "@zag-js/remove-scroll";
308
308
  import { createFocusTrap } from "focus-trap";
309
309
  var { and, or, not } = guards;
310
310
  function machine(ctx) {
311
- return createMachine({
312
- id: "popover",
313
- initial: "unknown",
314
- context: {
315
- closeOnInteractOutside: true,
316
- closeOnEsc: true,
317
- autoFocus: true,
318
- modal: false,
319
- positioning: {
320
- placement: "bottom",
321
- ...ctx.positioning
322
- },
323
- currentPlacement: void 0,
324
- ...ctx,
325
- focusTriggerOnClose: true,
326
- renderedElements: {
327
- title: true,
328
- description: true,
329
- anchor: false
330
- }
331
- },
332
- computed: {
333
- currentPortalled: (ctx2) => !!ctx2.modal || !!ctx2.portalled
334
- },
335
- states: {
336
- unknown: {
337
- on: {
338
- SETUP: {
339
- target: ctx.defaultOpen ? "open" : "closed",
340
- actions: "checkRenderedElements"
341
- }
311
+ return createMachine(
312
+ {
313
+ id: "popover",
314
+ initial: "unknown",
315
+ context: {
316
+ closeOnInteractOutside: true,
317
+ closeOnEsc: true,
318
+ autoFocus: true,
319
+ modal: false,
320
+ positioning: {
321
+ placement: "bottom",
322
+ ...ctx.positioning
323
+ },
324
+ currentPlacement: void 0,
325
+ ...ctx,
326
+ focusTriggerOnClose: true,
327
+ renderedElements: {
328
+ title: true,
329
+ description: true,
330
+ anchor: false
342
331
  }
343
332
  },
344
- closed: {
345
- entry: "invokeOnClose",
346
- on: {
347
- TOGGLE: "open",
348
- OPEN: "open"
349
- }
333
+ computed: {
334
+ currentPortalled: (ctx2) => !!ctx2.modal || !!ctx2.portalled
350
335
  },
351
- open: {
352
- activities: [
353
- "trapFocus",
354
- "preventScroll",
355
- "hideContentBelow",
356
- "computePlacement",
357
- "trackInteractionOutside",
358
- "trackTabKeyDown"
359
- ],
360
- entry: ["setInitialFocus", "invokeOnOpen"],
361
- on: {
362
- CLOSE: "closed",
363
- REQUEST_CLOSE: {
364
- target: "closed",
365
- actions: "focusTriggerIfNeeded"
366
- },
367
- TOGGLE: "closed",
368
- TRIGGER_BLUR: {
369
- guard: not("isRelatedTargetWithinContent"),
370
- target: "closed"
371
- },
372
- TAB: [
373
- {
374
- guard: and("isTriggerFocused", "portalled"),
375
- actions: "focusFirstTabbableElement"
376
- },
377
- {
378
- guard: and("isLastTabbableElement", "closeOnInteractOutside", "portalled"),
379
- target: "closed",
380
- actions: "focusNextTabbableElementAfterTrigger"
336
+ states: {
337
+ unknown: {
338
+ on: {
339
+ SETUP: {
340
+ target: ctx.defaultOpen ? "open" : "closed",
341
+ actions: "checkRenderedElements"
381
342
  }
343
+ }
344
+ },
345
+ closed: {
346
+ entry: "invokeOnClose",
347
+ on: {
348
+ TOGGLE: "open",
349
+ OPEN: "open"
350
+ }
351
+ },
352
+ open: {
353
+ activities: [
354
+ "trapFocus",
355
+ "preventScroll",
356
+ "hideContentBelow",
357
+ "computePlacement",
358
+ "trackInteractionOutside",
359
+ "trackTabKeyDown"
382
360
  ],
383
- SHIFT_TAB: {
384
- guard: and(or("isFirstTabbableElement", "isContentFocused"), "portalled"),
385
- actions: "focusTriggerIfNeeded"
361
+ entry: ["setInitialFocus", "invokeOnOpen"],
362
+ on: {
363
+ CLOSE: "closed",
364
+ REQUEST_CLOSE: {
365
+ target: "closed",
366
+ actions: "focusTriggerIfNeeded"
367
+ },
368
+ TOGGLE: "closed",
369
+ TRIGGER_BLUR: {
370
+ guard: not("isRelatedTargetWithinContent"),
371
+ target: "closed"
372
+ },
373
+ TAB: [
374
+ {
375
+ guard: and("isTriggerFocused", "portalled"),
376
+ actions: "focusFirstTabbableElement"
377
+ },
378
+ {
379
+ guard: and("isLastTabbableElement", "closeOnInteractOutside", "portalled"),
380
+ target: "closed",
381
+ actions: "focusNextTabbableElementAfterTrigger"
382
+ }
383
+ ],
384
+ SHIFT_TAB: {
385
+ guard: and(or("isFirstTabbableElement", "isContentFocused"), "portalled"),
386
+ actions: "focusTriggerIfNeeded"
387
+ }
386
388
  }
387
389
  }
388
390
  }
389
- }
390
- }, {
391
- activities: {
392
- computePlacement(ctx2) {
393
- ctx2.currentPlacement = ctx2.positioning.placement;
394
- const anchorEl = ctx2.renderedElements.anchor ? dom.getAnchorEl(ctx2) : dom.getTriggerEl(ctx2);
395
- return getPlacement(anchorEl, dom.getPositionerEl(ctx2), {
396
- ...ctx2.positioning,
397
- onComplete(data) {
398
- ctx2.currentPlacement = data.placement;
399
- ctx2.isPlacementComplete = true;
400
- },
401
- onCleanup() {
402
- ctx2.currentPlacement = void 0;
403
- ctx2.isPlacementComplete = false;
404
- }
405
- });
406
- },
407
- trackInteractionOutside(ctx2, _evt, { send }) {
408
- return trackDismissableElement(dom.getContentEl(ctx2), {
409
- pointerBlocking: ctx2.modal,
410
- exclude: dom.getTriggerEl(ctx2),
411
- onEscapeKeyDown(event) {
412
- var _a;
413
- (_a = ctx2.onEscapeKeyDown) == null ? void 0 : _a.call(ctx2, event);
414
- if (ctx2.closeOnEsc)
415
- return;
416
- ctx2.focusTriggerOnClose = true;
417
- event.preventDefault();
418
- },
419
- onInteractOutside(event) {
420
- var _a;
421
- (_a = ctx2.onInteractOutside) == null ? void 0 : _a.call(ctx2, event);
422
- if (event.defaultPrevented)
423
- return;
424
- ctx2.focusTriggerOnClose = !(event.detail.focusable || event.detail.contextmenu);
425
- if (!ctx2.closeOnInteractOutside) {
426
- event.preventDefault();
391
+ },
392
+ {
393
+ activities: {
394
+ computePlacement(ctx2) {
395
+ ctx2.currentPlacement = ctx2.positioning.placement;
396
+ const anchorEl = ctx2.renderedElements.anchor ? dom.getAnchorEl(ctx2) : dom.getTriggerEl(ctx2);
397
+ return getPlacement(anchorEl, dom.getPositionerEl(ctx2), {
398
+ ...ctx2.positioning,
399
+ onComplete(data) {
400
+ ctx2.currentPlacement = data.placement;
401
+ ctx2.isPlacementComplete = true;
402
+ },
403
+ onCleanup() {
404
+ ctx2.currentPlacement = void 0;
405
+ ctx2.isPlacementComplete = false;
427
406
  }
428
- },
429
- onPointerDownOutside(event) {
430
- var _a;
431
- (_a = ctx2.onPointerDownOutside) == null ? void 0 : _a.call(ctx2, event);
432
- },
433
- onFocusOutside(event) {
434
- var _a;
435
- (_a = ctx2.onFocusOutside) == null ? void 0 : _a.call(ctx2, event);
436
- if (ctx2.currentPortalled) {
407
+ });
408
+ },
409
+ trackInteractionOutside(ctx2, _evt, { send }) {
410
+ return trackDismissableElement(dom.getContentEl(ctx2), {
411
+ pointerBlocking: ctx2.modal,
412
+ exclude: dom.getTriggerEl(ctx2),
413
+ onEscapeKeyDown(event) {
414
+ var _a;
415
+ (_a = ctx2.onEscapeKeyDown) == null ? void 0 : _a.call(ctx2, event);
416
+ if (ctx2.closeOnEsc)
417
+ return;
418
+ ctx2.focusTriggerOnClose = true;
437
419
  event.preventDefault();
420
+ },
421
+ onInteractOutside(event) {
422
+ var _a;
423
+ (_a = ctx2.onInteractOutside) == null ? void 0 : _a.call(ctx2, event);
424
+ if (event.defaultPrevented)
425
+ return;
426
+ ctx2.focusTriggerOnClose = !(event.detail.focusable || event.detail.contextmenu);
427
+ if (!ctx2.closeOnInteractOutside) {
428
+ event.preventDefault();
429
+ }
430
+ },
431
+ onPointerDownOutside(event) {
432
+ var _a;
433
+ (_a = ctx2.onPointerDownOutside) == null ? void 0 : _a.call(ctx2, event);
434
+ },
435
+ onFocusOutside(event) {
436
+ var _a;
437
+ (_a = ctx2.onFocusOutside) == null ? void 0 : _a.call(ctx2, event);
438
+ if (ctx2.currentPortalled) {
439
+ event.preventDefault();
440
+ }
441
+ },
442
+ onDismiss() {
443
+ send({ type: "REQUEST_CLOSE", src: "#interact-outside" });
438
444
  }
439
- },
440
- onDismiss() {
441
- send({ type: "REQUEST_CLOSE", src: "#interact-outside" });
442
- }
443
- });
444
- },
445
- trackTabKeyDown(ctx2, _evt, { send }) {
446
- if (ctx2.modal)
447
- return;
448
- return addDomEvent(dom.getWin(ctx2), "keydown", (event) => {
449
- const isTabKey = event.key === "Tab" && !isModifiedEvent(event);
450
- if (!isTabKey)
445
+ });
446
+ },
447
+ trackTabKeyDown(ctx2, _evt, { send }) {
448
+ if (ctx2.modal)
451
449
  return;
452
- send({
453
- type: event.shiftKey ? "SHIFT_TAB" : "TAB",
454
- preventDefault: () => event.preventDefault()
450
+ return addDomEvent(
451
+ dom.getWin(ctx2),
452
+ "keydown",
453
+ (event) => {
454
+ const isTabKey = event.key === "Tab" && !isModifiedEvent(event);
455
+ if (!isTabKey)
456
+ return;
457
+ send({
458
+ type: event.shiftKey ? "SHIFT_TAB" : "TAB",
459
+ preventDefault: () => event.preventDefault()
460
+ });
461
+ },
462
+ true
463
+ );
464
+ },
465
+ hideContentBelow(ctx2) {
466
+ if (!ctx2.modal)
467
+ return;
468
+ let cleanup;
469
+ nextTick(() => {
470
+ cleanup = ariaHidden([dom.getContentEl(ctx2), dom.getTriggerEl(ctx2)]);
455
471
  });
456
- }, true);
457
- },
458
- hideContentBelow(ctx2) {
459
- if (!ctx2.modal)
460
- return;
461
- let cleanup;
462
- nextTick(() => {
463
- cleanup = ariaHidden([dom.getContentEl(ctx2), dom.getTriggerEl(ctx2)]);
464
- });
465
- return () => cleanup == null ? void 0 : cleanup();
472
+ return () => cleanup == null ? void 0 : cleanup();
473
+ },
474
+ preventScroll(ctx2) {
475
+ if (!ctx2.modal)
476
+ return;
477
+ return preventBodyScroll(dom.getDoc(ctx2));
478
+ },
479
+ trapFocus(ctx2) {
480
+ if (!ctx2.modal)
481
+ return;
482
+ let trap;
483
+ nextTick(() => {
484
+ const el = dom.getContentEl(ctx2);
485
+ if (!el)
486
+ return;
487
+ trap = createFocusTrap(el, {
488
+ escapeDeactivates: false,
489
+ allowOutsideClick: true,
490
+ returnFocusOnDeactivate: true,
491
+ document: dom.getDoc(ctx2),
492
+ fallbackFocus: el,
493
+ initialFocus: runIfFn2(ctx2.initialFocusEl)
494
+ });
495
+ try {
496
+ trap.activate();
497
+ } catch {
498
+ }
499
+ });
500
+ return () => trap == null ? void 0 : trap.deactivate();
501
+ }
466
502
  },
467
- preventScroll(ctx2) {
468
- if (!ctx2.modal)
469
- return;
470
- return preventBodyScroll(dom.getDoc(ctx2));
503
+ guards: {
504
+ portalled: (ctx2) => ctx2.currentPortalled,
505
+ isRelatedTargetWithinContent: (ctx2, evt) => contains(dom.getContentEl(ctx2), evt.target),
506
+ closeOnInteractOutside: (ctx2) => !!ctx2.closeOnInteractOutside,
507
+ isContentFocused: (ctx2) => dom.getContentEl(ctx2) === dom.getActiveEl(ctx2),
508
+ isTriggerFocused: (ctx2) => dom.getTriggerEl(ctx2) === dom.getActiveEl(ctx2),
509
+ isFirstTabbableElement: (ctx2) => dom.getFirstTabbableEl(ctx2) === dom.getActiveEl(ctx2),
510
+ isLastTabbableElement: (ctx2) => dom.getLastTabbableEl(ctx2) === dom.getActiveEl(ctx2)
471
511
  },
472
- trapFocus(ctx2) {
473
- if (!ctx2.modal)
474
- return;
475
- let trap;
476
- nextTick(() => {
477
- const el = dom.getContentEl(ctx2);
478
- if (!el)
479
- return;
480
- trap = createFocusTrap(el, {
481
- escapeDeactivates: false,
482
- allowOutsideClick: true,
483
- returnFocusOnDeactivate: true,
484
- document: dom.getDoc(ctx2),
485
- fallbackFocus: el,
486
- initialFocus: runIfFn2(ctx2.initialFocusEl)
512
+ actions: {
513
+ checkRenderedElements(ctx2) {
514
+ raf(() => {
515
+ Object.assign(ctx2.renderedElements, {
516
+ title: !!dom.getTitleEl(ctx2),
517
+ description: !!dom.getDescriptionEl(ctx2),
518
+ anchor: !!dom.getAnchorEl(ctx2)
519
+ });
487
520
  });
488
- try {
489
- trap.activate();
490
- } catch {
491
- }
492
- });
493
- return () => trap == null ? void 0 : trap.deactivate();
494
- }
495
- },
496
- guards: {
497
- portalled: (ctx2) => ctx2.currentPortalled,
498
- isRelatedTargetWithinContent: (ctx2, evt) => contains(dom.getContentEl(ctx2), evt.target),
499
- closeOnInteractOutside: (ctx2) => !!ctx2.closeOnInteractOutside,
500
- isContentFocused: (ctx2) => dom.getContentEl(ctx2) === dom.getActiveEl(ctx2),
501
- isTriggerFocused: (ctx2) => dom.getTriggerEl(ctx2) === dom.getActiveEl(ctx2),
502
- isFirstTabbableElement: (ctx2) => dom.getFirstTabbableEl(ctx2) === dom.getActiveEl(ctx2),
503
- isLastTabbableElement: (ctx2) => dom.getLastTabbableEl(ctx2) === dom.getActiveEl(ctx2)
504
- },
505
- actions: {
506
- checkRenderedElements(ctx2) {
507
- raf(() => {
508
- Object.assign(ctx2.renderedElements, {
509
- title: !!dom.getTitleEl(ctx2),
510
- description: !!dom.getDescriptionEl(ctx2),
511
- anchor: !!dom.getAnchorEl(ctx2)
521
+ },
522
+ setInitialFocus(ctx2) {
523
+ raf(() => {
524
+ var _a;
525
+ (_a = dom.getInitialFocusEl(ctx2)) == null ? void 0 : _a.focus();
512
526
  });
513
- });
514
- },
515
- setInitialFocus(ctx2) {
516
- raf(() => {
527
+ },
528
+ focusTriggerIfNeeded(ctx2) {
529
+ if (!ctx2.focusTriggerOnClose)
530
+ return;
531
+ raf(() => {
532
+ var _a;
533
+ return (_a = dom.getTriggerEl(ctx2)) == null ? void 0 : _a.focus();
534
+ });
535
+ },
536
+ focusFirstTabbableElement(ctx2, evt) {
517
537
  var _a;
518
- (_a = dom.getInitialFocusEl(ctx2)) == null ? void 0 : _a.focus();
519
- });
520
- },
521
- focusTriggerIfNeeded(ctx2) {
522
- if (!ctx2.focusTriggerOnClose)
523
- return;
524
- raf(() => {
538
+ evt.preventDefault();
539
+ (_a = dom.getFirstTabbableEl(ctx2)) == null ? void 0 : _a.focus();
540
+ },
541
+ invokeOnOpen(ctx2, evt) {
525
542
  var _a;
526
- return (_a = dom.getTriggerEl(ctx2)) == null ? void 0 : _a.focus();
527
- });
528
- },
529
- focusFirstTabbableElement(ctx2, evt) {
530
- var _a;
531
- evt.preventDefault();
532
- (_a = dom.getFirstTabbableEl(ctx2)) == null ? void 0 : _a.focus();
533
- },
534
- invokeOnOpen(ctx2, evt) {
535
- var _a;
536
- if (evt.type !== "SETUP") {
537
- (_a = ctx2.onOpenChange) == null ? void 0 : _a.call(ctx2, true);
538
- }
539
- },
540
- invokeOnClose(ctx2, evt) {
541
- var _a;
542
- if (evt.type !== "SETUP") {
543
- (_a = ctx2.onOpenChange) == null ? void 0 : _a.call(ctx2, false);
544
- }
545
- },
546
- focusNextTabbableElementAfterTrigger(ctx2, evt) {
547
- const content = dom.getContentEl(ctx2);
548
- const button = dom.getTriggerEl(ctx2);
549
- if (!content || !button)
550
- return;
551
- const lastTabbable = dom.getLastTabbableEl(ctx2);
552
- if (lastTabbable !== dom.getActiveEl(ctx2))
553
- return;
554
- let tabbables = dom.getDocTabbableEls(ctx2);
555
- let elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
556
- if (elementAfterTrigger === content) {
557
- tabbables = tabbables.filter((el) => !contains(content, el));
558
- elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
543
+ if (evt.type !== "SETUP") {
544
+ (_a = ctx2.onOpenChange) == null ? void 0 : _a.call(ctx2, true);
545
+ }
546
+ },
547
+ invokeOnClose(ctx2, evt) {
548
+ var _a;
549
+ if (evt.type !== "SETUP") {
550
+ (_a = ctx2.onOpenChange) == null ? void 0 : _a.call(ctx2, false);
551
+ }
552
+ },
553
+ focusNextTabbableElementAfterTrigger(ctx2, evt) {
554
+ const content = dom.getContentEl(ctx2);
555
+ const button = dom.getTriggerEl(ctx2);
556
+ if (!content || !button)
557
+ return;
558
+ const lastTabbable = dom.getLastTabbableEl(ctx2);
559
+ if (lastTabbable !== dom.getActiveEl(ctx2))
560
+ return;
561
+ let tabbables = dom.getDocTabbableEls(ctx2);
562
+ let elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
563
+ if (elementAfterTrigger === content) {
564
+ tabbables = tabbables.filter((el) => !contains(content, el));
565
+ elementAfterTrigger = next(tabbables, tabbables.indexOf(button), { loop: false });
566
+ }
567
+ if (!elementAfterTrigger || elementAfterTrigger === button)
568
+ return;
569
+ evt.preventDefault();
570
+ raf(() => elementAfterTrigger == null ? void 0 : elementAfterTrigger.focus());
559
571
  }
560
- if (!elementAfterTrigger || elementAfterTrigger === button)
561
- return;
562
- evt.preventDefault();
563
- raf(() => elementAfterTrigger == null ? void 0 : elementAfterTrigger.focus());
564
572
  }
565
573
  }
566
- });
574
+ );
567
575
  }
568
576
  export {
569
577
  connect,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zag-js/popover",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "description": "Core logic for the popover widget implemented as a state machine",
5
5
  "keywords": [
6
6
  "js",
@@ -32,13 +32,13 @@
32
32
  "@zag-js/aria-hidden": "0.1.1",
33
33
  "@zag-js/core": "0.1.9",
34
34
  "@zag-js/dismissable": "0.1.3",
35
- "@zag-js/popper": "0.1.9",
35
+ "@zag-js/popper": "0.1.10",
36
36
  "@zag-js/remove-scroll": "0.1.3",
37
37
  "@zag-js/types": "0.2.3",
38
38
  "focus-trap": "6.9.4"
39
39
  },
40
40
  "devDependencies": {
41
- "@zag-js/dom-utils": "0.1.8",
41
+ "@zag-js/dom-utils": "0.1.9",
42
42
  "@zag-js/utils": "0.1.3"
43
43
  },
44
44
  "scripts": {