package.dist.index.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of checkbox Show documentation
Show all versions of checkbox Show documentation
Core logic for the checkbox widget implemented as a state machine
The newest version!
'use strict';
var anatomy$1 = require('@zag-js/anatomy');
var domQuery = require('@zag-js/dom-query');
var focusVisible = require('@zag-js/focus-visible');
var core = require('@zag-js/core');
var domEvent = require('@zag-js/dom-event');
var formUtils = require('@zag-js/form-utils');
var utils = require('@zag-js/utils');
var types = require('@zag-js/types');
// src/checkbox.anatomy.ts
var anatomy = anatomy$1.createAnatomy("checkbox").parts("root", "label", "control", "indicator");
var parts = anatomy.build();
var dom = domQuery.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$1 = !disabled && state.context.focusVisible;
const checked = state.context.isChecked;
const indeterminate = state.context.isIndeterminate;
const dataAttrs = {
"data-active": domQuery.dataAttr(state.context.active),
"data-focus": domQuery.dataAttr(focused),
"data-focus-visible": domQuery.dataAttr(focusVisible$1),
"data-readonly": domQuery.dataAttr(readOnly),
"data-hover": domQuery.dataAttr(state.context.hovered),
"data-disabled": domQuery.dataAttr(disabled),
"data-state": indeterminate ? "indeterminate" : state.context.checked ? "checked" : "unchecked",
"data-invalid": domQuery.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 = domQuery.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: domQuery.visuallyHiddenStyle,
onFocus() {
const focusVisible2 = focusVisible.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 } = core.guards;
function machine(userContext) {
const ctx = utils.compact(userContext);
return core.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 domEvent.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 focusVisible.trackFocusVisible({ root: dom.getRootNode(ctx2) });
},
trackFormControlState(ctx2, _evt, { send, initialContext }) {
return formUtils.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;
formUtils.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);
formUtils.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 (utils.isEqual(ctx.checked, checked)) return;
ctx.checked = checked;
invoke.change(ctx);
}
};
var props = types.createProps()([
"checked",
"dir",
"disabled",
"form",
"getRootNode",
"id",
"ids",
"invalid",
"name",
"onCheckedChange",
"readOnly",
"required",
"value"
]);
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