All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.dist.index.mjs Maven / Gradle / Ivy

The newest version!
import { createAnatomy } from '@zag-js/anatomy';
import { createScope, nextTick, raf } from '@zag-js/dom-query';
import { ariaHidden } from '@zag-js/aria-hidden';
import { createMachine } from '@zag-js/core';
import { trackDismissableElement } from '@zag-js/dismissable';
import { preventBodyScroll } from '@zag-js/remove-scroll';
import { createSplitProps, compact } from '@zag-js/utils';
import { createFocusTrap } from 'focus-trap';
import { createProps } from '@zag-js/types';

// src/dialog.anatomy.ts
var anatomy = createAnatomy("dialog").parts(
  "trigger",
  "backdrop",
  "positioner",
  "content",
  "title",
  "description",
  "closeTrigger"
);
var parts = anatomy.build();
var dom = createScope({
  getPositionerId: (ctx) => ctx.ids?.positioner ?? `dialog:${ctx.id}:positioner`,
  getBackdropId: (ctx) => ctx.ids?.backdrop ?? `dialog:${ctx.id}:backdrop`,
  getContentId: (ctx) => ctx.ids?.content ?? `dialog:${ctx.id}:content`,
  getTriggerId: (ctx) => ctx.ids?.trigger ?? `dialog:${ctx.id}:trigger`,
  getTitleId: (ctx) => ctx.ids?.title ?? `dialog:${ctx.id}:title`,
  getDescriptionId: (ctx) => ctx.ids?.description ?? `dialog:${ctx.id}:description`,
  getCloseTriggerId: (ctx) => ctx.ids?.closeTrigger ?? `dialog:${ctx.id}:close`,
  getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
  getPositionerEl: (ctx) => dom.getById(ctx, dom.getPositionerId(ctx)),
  getBackdropEl: (ctx) => dom.getById(ctx, dom.getBackdropId(ctx)),
  getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx)),
  getTitleEl: (ctx) => dom.getById(ctx, dom.getTitleId(ctx)),
  getDescriptionEl: (ctx) => dom.getById(ctx, dom.getDescriptionId(ctx)),
  getCloseTriggerEl: (ctx) => dom.getById(ctx, dom.getCloseTriggerId(ctx))
});

// src/dialog.connect.ts
function connect(state, send, normalize) {
  const ariaLabel = state.context["aria-label"];
  const open = state.matches("open");
  const rendered = state.context.renderedElements;
  return {
    open,
    setOpen(nextOpen) {
      if (nextOpen === open) return;
      send(nextOpen ? "OPEN" : "CLOSE");
    },
    getTriggerProps() {
      return normalize.button({
        ...parts.trigger.attrs,
        dir: state.context.dir,
        id: dom.getTriggerId(state.context),
        "aria-haspopup": "dialog",
        type: "button",
        "aria-expanded": open,
        "data-state": open ? "open" : "closed",
        "aria-controls": dom.getContentId(state.context),
        onClick(event) {
          if (event.defaultPrevented) return;
          send("TOGGLE");
        }
      });
    },
    getBackdropProps() {
      return normalize.element({
        ...parts.backdrop.attrs,
        dir: state.context.dir,
        hidden: !open,
        id: dom.getBackdropId(state.context),
        "data-state": open ? "open" : "closed"
      });
    },
    getPositionerProps() {
      return normalize.element({
        ...parts.positioner.attrs,
        dir: state.context.dir,
        id: dom.getPositionerId(state.context),
        style: {
          pointerEvents: open ? void 0 : "none"
        }
      });
    },
    getContentProps() {
      return normalize.element({
        ...parts.content.attrs,
        dir: state.context.dir,
        role: state.context.role,
        hidden: !open,
        id: dom.getContentId(state.context),
        tabIndex: -1,
        "data-state": open ? "open" : "closed",
        "aria-modal": true,
        "aria-label": ariaLabel || void 0,
        "aria-labelledby": ariaLabel || !rendered.title ? void 0 : dom.getTitleId(state.context),
        "aria-describedby": rendered.description ? dom.getDescriptionId(state.context) : void 0
      });
    },
    getTitleProps() {
      return normalize.element({
        ...parts.title.attrs,
        dir: state.context.dir,
        id: dom.getTitleId(state.context)
      });
    },
    getDescriptionProps() {
      return normalize.element({
        ...parts.description.attrs,
        dir: state.context.dir,
        id: dom.getDescriptionId(state.context)
      });
    },
    getCloseTriggerProps() {
      return normalize.button({
        ...parts.closeTrigger.attrs,
        dir: state.context.dir,
        id: dom.getCloseTriggerId(state.context),
        type: "button",
        onClick(event) {
          if (event.defaultPrevented) return;
          event.stopPropagation();
          send("CLOSE");
        }
      });
    }
  };
}
function machine(userContext) {
  const ctx = compact(userContext);
  return createMachine(
    {
      id: "dialog",
      initial: ctx.open ? "open" : "closed",
      context: {
        role: "dialog",
        renderedElements: {
          title: true,
          description: true
        },
        modal: true,
        trapFocus: true,
        preventScroll: true,
        closeOnInteractOutside: true,
        closeOnEscape: true,
        restoreFocus: true,
        ...ctx
      },
      created: ["setAlertDialogProps"],
      watch: {
        open: ["toggleVisibility"]
      },
      states: {
        open: {
          entry: ["checkRenderedElements", "syncZIndex"],
          activities: ["trackDismissableElement", "trapFocus", "preventScroll", "hideContentBelow"],
          on: {
            "CONTROLLED.CLOSE": {
              target: "closed"
            },
            CLOSE: [
              {
                guard: "isOpenControlled",
                actions: ["invokeOnClose"]
              },
              {
                target: "closed",
                actions: ["invokeOnClose"]
              }
            ],
            TOGGLE: [
              {
                guard: "isOpenControlled",
                actions: ["invokeOnClose"]
              },
              {
                target: "closed",
                actions: ["invokeOnClose"]
              }
            ]
          }
        },
        closed: {
          on: {
            "CONTROLLED.OPEN": {
              target: "open"
            },
            OPEN: [
              {
                guard: "isOpenControlled",
                actions: ["invokeOnOpen"]
              },
              {
                target: "open",
                actions: ["invokeOnOpen"]
              }
            ],
            TOGGLE: [
              {
                guard: "isOpenControlled",
                actions: ["invokeOnOpen"]
              },
              {
                target: "open",
                actions: ["invokeOnOpen"]
              }
            ]
          }
        }
      }
    },
    {
      guards: {
        isOpenControlled: (ctx2) => !!ctx2["open.controlled"]
      },
      activities: {
        trackDismissableElement(ctx2, _evt, { send }) {
          const getContentEl = () => dom.getContentEl(ctx2);
          return trackDismissableElement(getContentEl, {
            defer: true,
            pointerBlocking: ctx2.modal,
            exclude: [dom.getTriggerEl(ctx2)],
            onInteractOutside(event) {
              ctx2.onInteractOutside?.(event);
              if (!ctx2.closeOnInteractOutside) {
                event.preventDefault();
              }
            },
            persistentElements: ctx2.persistentElements,
            onFocusOutside: ctx2.onFocusOutside,
            onPointerDownOutside: ctx2.onPointerDownOutside,
            onEscapeKeyDown(event) {
              ctx2.onEscapeKeyDown?.(event);
              if (!ctx2.closeOnEscape) {
                event.preventDefault();
              }
            },
            onDismiss() {
              send({ type: "CLOSE", src: "interact-outside" });
            }
          });
        },
        preventScroll(ctx2) {
          if (!ctx2.preventScroll) return;
          return preventBodyScroll(dom.getDoc(ctx2));
        },
        trapFocus(ctx2) {
          if (!ctx2.trapFocus || !ctx2.modal) return;
          let trap;
          const cleanup = nextTick(() => {
            const contentEl = dom.getContentEl(ctx2);
            if (!contentEl) return;
            trap = createFocusTrap(contentEl, {
              document: dom.getDoc(ctx2),
              escapeDeactivates: false,
              preventScroll: true,
              fallbackFocus: contentEl,
              returnFocusOnDeactivate: !!ctx2.restoreFocus,
              allowOutsideClick: true,
              initialFocus: ctx2.initialFocusEl?.() ?? void 0,
              setReturnFocus(triggerEl) {
                return ctx2.finalFocusEl?.() ?? triggerEl;
              }
            });
            try {
              trap.activate();
            } catch {
            }
          });
          return () => {
            trap?.deactivate();
            cleanup();
          };
        },
        hideContentBelow(ctx2) {
          if (!ctx2.modal) return;
          const getElements = () => [dom.getContentEl(ctx2)];
          return ariaHidden(getElements, { defer: true });
        }
      },
      actions: {
        setAlertDialogProps(ctx2) {
          if (ctx2.role !== "alertdialog") return;
          ctx2.initialFocusEl || (ctx2.initialFocusEl = () => dom.getCloseTriggerEl(ctx2));
          ctx2.closeOnInteractOutside = false;
        },
        checkRenderedElements(ctx2) {
          raf(() => {
            ctx2.renderedElements.title = !!dom.getTitleEl(ctx2);
            ctx2.renderedElements.description = !!dom.getDescriptionEl(ctx2);
          });
        },
        syncZIndex(ctx2) {
          raf(() => {
            const contentEl = dom.getContentEl(ctx2);
            if (!contentEl) return;
            const win = dom.getWin(ctx2);
            const styles = win.getComputedStyle(contentEl);
            const elems = [dom.getPositionerEl(ctx2), dom.getBackdropEl(ctx2)];
            elems.forEach((node) => {
              node?.style.setProperty("--z-index", styles.zIndex);
            });
          });
        },
        invokeOnClose(ctx2) {
          ctx2.onOpenChange?.({ open: false });
        },
        invokeOnOpen(ctx2) {
          ctx2.onOpenChange?.({ open: true });
        },
        toggleVisibility(ctx2, evt, { send }) {
          send({ type: ctx2.open ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE", previousEvent: evt });
        }
      }
    }
  );
}
var props = createProps()([
  "aria-label",
  "closeOnEscape",
  "closeOnInteractOutside",
  "dir",
  "finalFocusEl",
  "getRootNode",
  "getRootNode",
  "id",
  "id",
  "ids",
  "initialFocusEl",
  "modal",
  "onEscapeKeyDown",
  "onFocusOutside",
  "onInteractOutside",
  "onOpenChange",
  "onPointerDownOutside",
  "open.controlled",
  "open",
  "persistentElements",
  "preventScroll",
  "restoreFocus",
  "role",
  "trapFocus"
]);
var splitProps = createSplitProps(props);

export { anatomy, connect, machine, props, splitProps };




© 2015 - 2025 Weber Informatics LLC | Privacy Policy