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, dataAttr, getEventTarget, visuallyHiddenStyle } from '@zag-js/dom-query';
import { isFocusVisible, trackFocusVisible } from '@zag-js/focus-visible';
import { createMachine, guards } from '@zag-js/core';
import { trackPress } from '@zag-js/dom-event';
import { trackFormControl, setElementChecked, dispatchInputCheckedEvent } from '@zag-js/form-utils';
import { createSplitProps, compact, isEqual } from '@zag-js/utils';
import { createProps } from '@zag-js/types';

// src/checkbox.anatomy.ts
var anatomy = createAnatomy("checkbox").parts("root", "label", "control", "indicator");
var parts = anatomy.build();
var dom = createScope({
  getRootId: (ctx) => ctx.ids?.root ?? `checkbox:${ctx.id}`,
  getLabelId: (ctx) => ctx.ids?.label ?? `checkbox:${ctx.id}:label`,
  getControlId: (ctx) => ctx.ids?.control ?? `checkbox:${ctx.id}:control`,
  getHiddenInputId: (ctx) => ctx.ids?.hiddenInput ?? `checkbox:${ctx.id}:input`,
  getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
  getHiddenInputEl: (ctx) => dom.getById(ctx, dom.getHiddenInputId(ctx))
});
function connect(state, send, normalize) {
  const disabled = state.context.isDisabled;
  const readOnly = state.context.readOnly;
  const focused = !disabled && state.context.focused;
  const focusVisible = !disabled && state.context.focusVisible;
  const checked = state.context.isChecked;
  const indeterminate = state.context.isIndeterminate;
  const dataAttrs = {
    "data-active": dataAttr(state.context.active),
    "data-focus": dataAttr(focused),
    "data-focus-visible": dataAttr(focusVisible),
    "data-readonly": dataAttr(readOnly),
    "data-hover": dataAttr(state.context.hovered),
    "data-disabled": dataAttr(disabled),
    "data-state": indeterminate ? "indeterminate" : state.context.checked ? "checked" : "unchecked",
    "data-invalid": dataAttr(state.context.invalid)
  };
  return {
    checked,
    disabled,
    indeterminate,
    focused,
    checkedState: state.context.checked,
    setChecked(checked2) {
      send({ type: "CHECKED.SET", checked: checked2, isTrusted: false });
    },
    toggleChecked() {
      send({ type: "CHECKED.TOGGLE", checked, isTrusted: false });
    },
    getRootProps() {
      return normalize.label({
        ...parts.root.attrs,
        ...dataAttrs,
        dir: state.context.dir,
        id: dom.getRootId(state.context),
        htmlFor: dom.getHiddenInputId(state.context),
        onPointerMove() {
          if (disabled) return;
          send({ type: "CONTEXT.SET", context: { hovered: true } });
        },
        onPointerLeave() {
          if (disabled) return;
          send({ type: "CONTEXT.SET", context: { hovered: false } });
        },
        onClick(event) {
          const target = getEventTarget(event);
          if (target === dom.getHiddenInputEl(state.context)) {
            event.stopPropagation();
          }
        }
      });
    },
    getLabelProps() {
      return normalize.element({
        ...parts.label.attrs,
        ...dataAttrs,
        dir: state.context.dir,
        id: dom.getLabelId(state.context)
      });
    },
    getControlProps() {
      return normalize.element({
        ...parts.control.attrs,
        ...dataAttrs,
        dir: state.context.dir,
        id: dom.getControlId(state.context),
        "aria-hidden": true
      });
    },
    getIndicatorProps() {
      return normalize.element({
        ...parts.indicator.attrs,
        ...dataAttrs,
        dir: state.context.dir,
        hidden: !indeterminate && !state.context.checked
      });
    },
    getHiddenInputProps() {
      return normalize.input({
        id: dom.getHiddenInputId(state.context),
        type: "checkbox",
        required: state.context.required,
        defaultChecked: checked,
        disabled,
        "aria-labelledby": dom.getLabelId(state.context),
        "aria-invalid": state.context.invalid,
        name: state.context.name,
        form: state.context.form,
        value: state.context.value,
        style: visuallyHiddenStyle,
        onFocus() {
          const focusVisible2 = isFocusVisible();
          send({ type: "CONTEXT.SET", context: { focused: true, focusVisible: focusVisible2 } });
        },
        onBlur() {
          send({ type: "CONTEXT.SET", context: { focused: false, focusVisible: false } });
        },
        onClick(event) {
          if (readOnly) {
            event.preventDefault();
            return;
          }
          const checked2 = event.currentTarget.checked;
          send({ type: "CHECKED.SET", checked: checked2, isTrusted: true });
        }
      });
    }
  };
}
var { not } = guards;
function machine(userContext) {
  const ctx = compact(userContext);
  return createMachine(
    {
      id: "checkbox",
      initial: "ready",
      context: {
        checked: false,
        value: "on",
        disabled: false,
        ...ctx,
        fieldsetDisabled: false,
        focusVisible: false
      },
      watch: {
        disabled: "removeFocusIfNeeded",
        checked: "syncInputElement"
      },
      activities: ["trackFormControlState", "trackPressEvent", "trackFocusVisible"],
      on: {
        "CHECKED.TOGGLE": [
          {
            guard: not("isTrusted"),
            actions: ["toggleChecked", "dispatchChangeEvent"]
          },
          {
            actions: ["toggleChecked"]
          }
        ],
        "CHECKED.SET": [
          {
            guard: not("isTrusted"),
            actions: ["setChecked", "dispatchChangeEvent"]
          },
          {
            actions: ["setChecked"]
          }
        ],
        "CONTEXT.SET": {
          actions: ["setContext"]
        }
      },
      computed: {
        isIndeterminate: (ctx2) => isIndeterminate(ctx2.checked),
        isChecked: (ctx2) => isChecked(ctx2.checked),
        isDisabled: (ctx2) => !!ctx2.disabled || ctx2.fieldsetDisabled
      },
      states: {
        ready: {}
      }
    },
    {
      guards: {
        isTrusted: (_ctx, evt) => !!evt.isTrusted
      },
      activities: {
        trackPressEvent(ctx2) {
          if (ctx2.isDisabled) return;
          return trackPress({
            pointerNode: dom.getRootEl(ctx2),
            keyboardNode: dom.getHiddenInputEl(ctx2),
            isValidKey: (event) => event.key === " ",
            onPress: () => ctx2.active = false,
            onPressStart: () => ctx2.active = true,
            onPressEnd: () => ctx2.active = false
          });
        },
        trackFocusVisible(ctx2) {
          if (ctx2.isDisabled) return;
          return trackFocusVisible({ root: dom.getRootNode(ctx2) });
        },
        trackFormControlState(ctx2, _evt, { send, initialContext }) {
          return trackFormControl(dom.getHiddenInputEl(ctx2), {
            onFieldsetDisabledChange(disabled) {
              ctx2.fieldsetDisabled = disabled;
            },
            onFormReset() {
              send({ type: "CHECKED.SET", checked: !!initialContext.checked });
            }
          });
        }
      },
      actions: {
        setContext(ctx2, evt) {
          Object.assign(ctx2, evt.context);
        },
        syncInputElement(ctx2) {
          const inputEl = dom.getHiddenInputEl(ctx2);
          if (!inputEl) return;
          setElementChecked(inputEl, ctx2.isChecked);
          inputEl.indeterminate = ctx2.isIndeterminate;
        },
        removeFocusIfNeeded(ctx2) {
          if (ctx2.disabled && ctx2.focused) {
            ctx2.focused = false;
            ctx2.focusVisible = false;
          }
        },
        setChecked(ctx2, evt) {
          set.checked(ctx2, evt.checked);
        },
        toggleChecked(ctx2) {
          const checked = isIndeterminate(ctx2.checked) ? true : !ctx2.checked;
          set.checked(ctx2, checked);
        },
        dispatchChangeEvent(ctx2) {
          const inputEl = dom.getHiddenInputEl(ctx2);
          dispatchInputCheckedEvent(inputEl, { checked: isChecked(ctx2.checked) });
        }
      }
    }
  );
}
function isIndeterminate(checked) {
  return checked === "indeterminate";
}
function isChecked(checked) {
  return isIndeterminate(checked) ? false : !!checked;
}
var invoke = {
  change: (ctx) => {
    ctx.onCheckedChange?.({ checked: ctx.checked });
  }
};
var set = {
  checked: (ctx, checked) => {
    if (isEqual(ctx.checked, checked)) return;
    ctx.checked = checked;
    invoke.change(ctx);
  }
};
var props = createProps()([
  "checked",
  "dir",
  "disabled",
  "form",
  "getRootNode",
  "id",
  "ids",
  "invalid",
  "name",
  "onCheckedChange",
  "readOnly",
  "required",
  "value"
]);
var splitProps = createSplitProps(props);

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy