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

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

The newest version!
'use strict';

var anatomy$1 = require('@zag-js/anatomy');
var domQuery = require('@zag-js/dom-query');
var core = require('@zag-js/core');
var utils = require('@zag-js/utils');
var types = require('@zag-js/types');

// src/collapsible.anatomy.ts
var anatomy = anatomy$1.createAnatomy("collapsible").parts("root", "trigger", "content");
var parts = anatomy.build();
var dom = domQuery.createScope({
  getRootId: (ctx) => ctx.ids?.root ?? `collapsible:${ctx.id}`,
  getContentId: (ctx) => ctx.ids?.content ?? `collapsible:${ctx.id}:content`,
  getTriggerId: (ctx) => ctx.ids?.trigger ?? `collapsible:${ctx.id}:trigger`,
  getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
  getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
  getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx))
});

// src/collapsible.connect.ts
function connect(state, send, normalize) {
  const visible = state.matches("open", "closing");
  const open = state.matches("open");
  const height = state.context.height;
  const width = state.context.width;
  const disabled = !!state.context.disabled;
  const skip = !state.context.initial && open;
  return {
    disabled,
    visible,
    open,
    setOpen(nextOpen) {
      if (nextOpen === open) return;
      send(nextOpen ? "OPEN" : "CLOSE");
    },
    getRootProps() {
      return normalize.element({
        ...parts.root.attrs,
        "data-state": open ? "open" : "closed",
        dir: state.context.dir,
        id: dom.getRootId(state.context)
      });
    },
    getContentProps() {
      return normalize.element({
        ...parts.content.attrs,
        "data-state": skip ? void 0 : open ? "open" : "closed",
        id: dom.getContentId(state.context),
        "data-disabled": domQuery.dataAttr(disabled),
        hidden: !visible,
        style: {
          "--height": height != null ? `${height}px` : void 0,
          "--width": width != null ? `${width}px` : void 0
        }
      });
    },
    getTriggerProps() {
      return normalize.element({
        ...parts.trigger.attrs,
        id: dom.getTriggerId(state.context),
        dir: state.context.dir,
        type: "button",
        "data-state": open ? "open" : "closed",
        "data-disabled": domQuery.dataAttr(disabled),
        "aria-controls": dom.getContentId(state.context),
        "aria-expanded": visible || false,
        onClick(event) {
          if (event.defaultPrevented) return;
          if (disabled) return;
          send({ type: open ? "CLOSE" : "OPEN", src: "trigger.click" });
        }
      });
    }
  };
}
function machine(userContext) {
  const ctx = utils.compact(userContext);
  return core.createMachine(
    {
      id: "collapsible",
      initial: ctx.open ? "open" : "closed",
      context: {
        ...ctx,
        height: 0,
        width: 0,
        initial: false,
        stylesRef: null,
        unmountAnimationName: null
      },
      watch: {
        open: ["setInitial", "computeSize", "toggleVisibility"]
      },
      exit: ["clearInitial"],
      states: {
        closed: {
          tags: ["closed"],
          on: {
            "CONTROLLED.OPEN": "open",
            OPEN: [
              {
                guard: "isOpenControlled",
                actions: ["invokeOnOpen"]
              },
              {
                target: "open",
                actions: ["setInitial", "computeSize", "invokeOnOpen"]
              }
            ]
          }
        },
        closing: {
          tags: ["open"],
          activities: ["trackAnimationEvents"],
          on: {
            "CONTROLLED.CLOSE": "closed",
            "CONTROLLED.OPEN": "open",
            OPEN: [
              {
                guard: "isOpenControlled",
                actions: ["invokeOnOpen"]
              },
              {
                target: "open",
                actions: ["setInitial", "invokeOnOpen"]
              }
            ],
            CLOSE: [
              {
                guard: "isOpenControlled",
                actions: ["invokeOnExitComplete"]
              },
              {
                target: "closed",
                actions: ["setInitial", "computeSize", "invokeOnExitComplete"]
              }
            ],
            "ANIMATION.END": {
              target: "closed",
              actions: ["invokeOnExitComplete"]
            }
          }
        },
        open: {
          tags: ["open"],
          on: {
            "CONTROLLED.CLOSE": "closing",
            CLOSE: [
              {
                guard: "isOpenControlled",
                actions: ["invokeOnClose"]
              },
              {
                target: "closing",
                actions: ["setInitial", "computeSize", "invokeOnClose"]
              }
            ]
          }
        }
      }
    },
    {
      guards: {
        isOpenControlled: (ctx2) => !!ctx2["open.controlled"]
      },
      activities: {
        trackAnimationEvents(ctx2, _evt, { send }) {
          let cleanup;
          const rafCleanup = domQuery.raf(() => {
            const contentEl = dom.getContentEl(ctx2);
            if (!contentEl) return;
            const animationName = domQuery.getComputedStyle(contentEl).animationName;
            const hasNoAnimation = !animationName || animationName === "none";
            if (hasNoAnimation) {
              send({ type: "ANIMATION.END" });
              return;
            }
            const onEnd = (event) => {
              const win = contentEl.ownerDocument.defaultView || window;
              const animationName2 = win.getComputedStyle(contentEl).animationName;
              const target = domQuery.getEventTarget(event);
              if (target === contentEl && animationName2 === ctx2.unmountAnimationName) {
                send({ type: "ANIMATION.END" });
              }
            };
            contentEl.addEventListener("animationend", onEnd);
            cleanup = () => {
              contentEl.removeEventListener("animationend", onEnd);
            };
          });
          return () => {
            rafCleanup();
            cleanup?.();
          };
        }
      },
      actions: {
        setInitial(ctx2) {
          ctx2.initial = true;
        },
        clearInitial(ctx2) {
          ctx2.initial = false;
        },
        computeSize(ctx2, evt) {
          ctx2._rafCleanup?.();
          ctx2._rafCleanup = domQuery.raf(() => {
            const contentEl = dom.getContentEl(ctx2);
            if (!contentEl) return;
            ctx2.stylesRef || (ctx2.stylesRef = core.ref({
              animationName: contentEl.style.animationName,
              animationDuration: contentEl.style.animationDuration
            }));
            if (evt.type === "CLOSE" || !ctx2.open) {
              const win = contentEl.ownerDocument.defaultView || window;
              ctx2.unmountAnimationName = win.getComputedStyle(contentEl).animationName;
            }
            const hidden = contentEl.hidden;
            contentEl.style.animationName = "none";
            contentEl.style.animationDuration = "0s";
            contentEl.hidden = false;
            const rect = contentEl.getBoundingClientRect();
            ctx2.height = rect.height;
            ctx2.width = rect.width;
            if (ctx2.initial) {
              contentEl.style.animationName = ctx2.stylesRef.animationName;
              contentEl.style.animationDuration = ctx2.stylesRef.animationDuration;
            }
            contentEl.hidden = hidden;
          });
        },
        invokeOnOpen: (ctx2) => {
          ctx2.onOpenChange?.({ open: true });
        },
        invokeOnClose: (ctx2) => {
          ctx2.onOpenChange?.({ open: false });
        },
        invokeOnExitComplete(ctx2) {
          ctx2.onExitComplete?.();
        },
        toggleVisibility: (ctx2, _evt, { send }) => {
          send({ type: ctx2.open ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE" });
        }
      }
    }
  );
}
var props = types.createProps()([
  "dir",
  "disabled",
  "getRootNode",
  "id",
  "ids",
  "onExitComplete",
  "onOpenChange",
  "open.controlled",
  "open"
]);
var splitProps = utils.createSplitProps(props);

exports.anatomy = anatomy;
exports.connect = connect;
exports.machine = machine;
exports.props = props;
exports.splitProps = splitProps;




© 2015 - 2025 Weber Informatics LLC | Privacy Policy