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 domEvent = require('@zag-js/dom-event');
var domQuery = require('@zag-js/dom-query');
var utils = require('@zag-js/utils');
var core = require('@zag-js/core');
var types = require('@zag-js/types');

// src/toggle-group.anatomy.ts
var anatomy = anatomy$1.createAnatomy("toggle-group").parts("root", "item");
var parts = anatomy.build();
var dom = domQuery.createScope({
  getRootId: (ctx) => ctx.ids?.root ?? `toggle-group:${ctx.id}`,
  getItemId: (ctx, value) => ctx.ids?.item?.(value) ?? `toggle-group:${ctx.id}:${value}`,
  getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
  getElements: (ctx) => {
    const ownerId = CSS.escape(dom.getRootId(ctx));
    const selector = `[data-ownedby='${ownerId}']:not([data-disabled])`;
    return domQuery.queryAll(dom.getRootEl(ctx), selector);
  },
  getFirstEl: (ctx) => utils.first(dom.getElements(ctx)),
  getLastEl: (ctx) => utils.last(dom.getElements(ctx)),
  getNextEl: (ctx, id) => domQuery.nextById(dom.getElements(ctx), id, ctx.currentLoopFocus),
  getPrevEl: (ctx, id) => domQuery.prevById(dom.getElements(ctx), id, ctx.currentLoopFocus)
});

// src/toggle-group.connect.ts
function connect(state, send, normalize) {
  const value = state.context.value;
  const disabled = state.context.disabled;
  const isSingle = !state.context.multiple;
  const rovingFocus = state.context.rovingFocus;
  const isHorizontal = state.context.orientation === "horizontal";
  function getItemState(props2) {
    const id = dom.getItemId(state.context, props2.value);
    return {
      id,
      disabled: Boolean(props2.disabled || disabled),
      pressed: !!value.includes(props2.value),
      focused: state.context.focusedId === id
    };
  }
  return {
    value,
    setValue(value2) {
      send({ type: "VALUE.SET", value: value2 });
    },
    getRootProps() {
      return normalize.element({
        ...parts.root.attrs,
        id: dom.getRootId(state.context),
        dir: state.context.dir,
        role: isSingle ? "radiogroup" : "group",
        tabIndex: state.context.isTabbingBackward ? -1 : 0,
        "data-disabled": domQuery.dataAttr(disabled),
        "data-orientation": state.context.orientation,
        "data-focus": domQuery.dataAttr(state.context.focusedId != null),
        style: { outline: "none" },
        onMouseDown() {
          if (disabled) return;
          send("ROOT.MOUSE_DOWN");
        },
        onFocus(event) {
          if (disabled) return;
          const evt = event.nativeEvent || event;
          if (!domQuery.isSelfTarget(evt) || !!state.context.isClickFocus || state.context.isTabbingBackward) return;
          send("ROOT.FOCUS");
        },
        onBlur() {
          if (disabled) return;
          send("ROOT.BLUR");
        }
      });
    },
    getItemState,
    getItemProps(props2) {
      const itemState = getItemState(props2);
      const rovingTabIndex = itemState.focused ? 0 : -1;
      return normalize.button({
        ...parts.item.attrs,
        id: itemState.id,
        type: "button",
        "data-ownedby": dom.getRootId(state.context),
        "data-focus": domQuery.dataAttr(itemState.focused),
        disabled: itemState.disabled,
        tabIndex: rovingFocus ? rovingTabIndex : void 0,
        // radio
        role: isSingle ? "radio" : void 0,
        "aria-checked": isSingle ? itemState.pressed : void 0,
        "aria-pressed": isSingle ? void 0 : itemState.pressed,
        //
        "data-disabled": domQuery.dataAttr(itemState.disabled),
        "data-orientation": state.context.orientation,
        dir: state.context.dir,
        "data-state": itemState.pressed ? "on" : "off",
        onFocus() {
          if (itemState.disabled) return;
          send({ type: "TOGGLE.FOCUS", id: itemState.id });
        },
        onClick(event) {
          if (itemState.disabled) return;
          send({ type: "TOGGLE.CLICK", id: itemState.id, value: props2.value });
          if (domQuery.isSafari()) {
            event.currentTarget.focus({ preventScroll: true });
          }
        },
        onKeyDown(event) {
          if (event.defaultPrevented) return;
          if (!domQuery.isSelfTarget(event)) return;
          if (itemState.disabled) return;
          const keyMap = {
            Tab(event2) {
              const isShiftTab = event2.shiftKey;
              send({ type: "TOGGLE.SHIFT_TAB", isShiftTab });
            },
            ArrowLeft() {
              if (!rovingFocus || !isHorizontal) return;
              send("TOGGLE.FOCUS_PREV");
            },
            ArrowRight() {
              if (!rovingFocus || !isHorizontal) return;
              send("TOGGLE.FOCUS_NEXT");
            },
            ArrowUp() {
              if (!rovingFocus || isHorizontal) return;
              send("TOGGLE.FOCUS_PREV");
            },
            ArrowDown() {
              if (!rovingFocus || isHorizontal) return;
              send("TOGGLE.FOCUS_NEXT");
            },
            Home() {
              if (!rovingFocus) return;
              send("TOGGLE.FOCUS_FIRST");
            },
            End() {
              if (!rovingFocus) return;
              send("TOGGLE.FOCUS_LAST");
            }
          };
          const exec = keyMap[domEvent.getEventKey(event)];
          if (exec) {
            exec(event);
            if (event.key !== "Tab") event.preventDefault();
          }
        }
      });
    }
  };
}
var { not, and } = core.guards;
function machine(userContext) {
  const ctx = utils.compact(userContext);
  return core.createMachine(
    {
      id: "toggle-group",
      initial: "idle",
      context: {
        value: [],
        disabled: false,
        orientation: "horizontal",
        rovingFocus: true,
        loopFocus: true,
        ...ctx,
        focusedId: null,
        isTabbingBackward: false,
        isClickFocus: false,
        isWithinToolbar: false
      },
      computed: {
        currentLoopFocus: (ctx2) => ctx2.loopFocus && !ctx2.isWithinToolbar
      },
      entry: ["checkIfWithinToolbar"],
      on: {
        "VALUE.SET": {
          actions: ["setValue"]
        },
        "TOGGLE.CLICK": {
          actions: ["setValue"]
        },
        "ROOT.MOUSE_DOWN": {
          actions: ["setClickFocus"]
        }
      },
      states: {
        idle: {
          on: {
            "ROOT.FOCUS": {
              target: "focused",
              guard: not(and("isClickFocus", "isTabbingBackward")),
              actions: ["focusFirstToggle", "clearClickFocus"]
            },
            "TOGGLE.FOCUS": {
              target: "focused",
              actions: ["setFocusedId"]
            }
          }
        },
        focused: {
          on: {
            "ROOT.BLUR": {
              target: "idle",
              actions: ["clearIsTabbingBackward"]
            },
            "TOGGLE.FOCUS": {
              actions: ["setFocusedId"]
            },
            "TOGGLE.FOCUS_NEXT": {
              actions: ["focusNextToggle"]
            },
            "TOGGLE.FOCUS_PREV": {
              actions: ["focusPrevToggle"]
            },
            "TOGGLE.FOCUS_FIRST": {
              actions: ["focusFirstToggle"]
            },
            "TOGGLE.FOCUS_LAST": {
              actions: ["focusLastToggle"]
            },
            "TOGGLE.SHIFT_TAB": {
              target: "idle",
              actions: ["setIsTabbingBackward"]
            }
          }
        }
      }
    },
    {
      guards: {
        isClickFocus: (ctx2) => ctx2.isClickFocus,
        isTabbingBackward: (ctx2) => ctx2.isTabbingBackward
      },
      actions: {
        setIsTabbingBackward(ctx2) {
          ctx2.isTabbingBackward = true;
        },
        clearIsTabbingBackward(ctx2) {
          ctx2.isTabbingBackward = false;
        },
        setClickFocus(ctx2) {
          ctx2.isClickFocus = true;
        },
        clearClickFocus(ctx2) {
          ctx2.isClickFocus = false;
        },
        checkIfWithinToolbar(ctx2) {
          const closestToolbar = dom.getRootEl(ctx2)?.closest("[role=toolbar]");
          ctx2.isWithinToolbar = !!closestToolbar;
        },
        setFocusedId(ctx2, evt) {
          ctx2.focusedId = evt.id;
        },
        clearFocusedId(ctx2) {
          ctx2.focusedId = null;
        },
        setValue(ctx2, evt) {
          if (!evt.value) return;
          let next = Array.from(ctx2.value);
          if (ctx2.multiple) {
            next = next.includes(evt.value) ? utils.remove(next, evt.value) : utils.add(next, evt.value);
          } else {
            next = utils.isEqual(ctx2.value, [evt.value]) ? [] : [evt.value];
          }
          set.value(ctx2, next);
        },
        focusNextToggle(ctx2) {
          domQuery.raf(() => {
            if (!ctx2.focusedId) return;
            dom.getNextEl(ctx2, ctx2.focusedId)?.focus({ preventScroll: true });
          });
        },
        focusPrevToggle(ctx2) {
          domQuery.raf(() => {
            if (!ctx2.focusedId) return;
            dom.getPrevEl(ctx2, ctx2.focusedId)?.focus({ preventScroll: true });
          });
        },
        focusFirstToggle(ctx2) {
          domQuery.raf(() => {
            dom.getFirstEl(ctx2)?.focus({ preventScroll: true });
          });
        },
        focusLastToggle(ctx2) {
          domQuery.raf(() => {
            dom.getLastEl(ctx2)?.focus({ preventScroll: true });
          });
        }
      }
    }
  );
}
var invoke = {
  change(ctx) {
    ctx.onValueChange?.({ value: Array.from(ctx.value) });
  }
};
var set = {
  value(ctx, value) {
    if (utils.isEqual(ctx.value, value)) return;
    ctx.value = value;
    invoke.change(ctx);
  }
};
var props = types.createProps()([
  "dir",
  "disabled",
  "getRootNode",
  "id",
  "ids",
  "loopFocus",
  "multiple",
  "onValueChange",
  "orientation",
  "rovingFocus",
  "value"
]);
var splitProps = utils.createSplitProps(props);
var itemProps = types.createProps()(["value", "disabled"]);
var splitItemProps = utils.createSplitProps(itemProps);

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy