@zag-js/accordion
Version:
Core logic for the accordion widget implemented as a state machine
173 lines (171 loc) • 5.44 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/accordion.machine.ts
var accordion_machine_exports = {};
__export(accordion_machine_exports, {
machine: () => machine
});
module.exports = __toCommonJS(accordion_machine_exports);
var import_core = require("@zag-js/core");
var import_utils = require("@zag-js/utils");
var dom = __toESM(require("./accordion.dom.js"));
var { and, not } = (0, import_core.createGuards)();
var machine = (0, import_core.createMachine)({
props({ props }) {
return {
collapsible: false,
multiple: false,
orientation: "vertical",
defaultValue: [],
...props
};
},
initialState() {
return "idle";
},
context({ prop, bindable }) {
return {
focusedValue: bindable(() => ({
defaultValue: null,
sync: true,
onChange(value) {
prop("onFocusChange")?.({ value });
}
})),
value: bindable(() => ({
defaultValue: prop("defaultValue"),
value: prop("value"),
onChange(value) {
prop("onValueChange")?.({ value });
}
}))
};
},
computed: {
isHorizontal: ({ prop }) => prop("orientation") === "horizontal"
},
on: {
"VALUE.SET": {
actions: ["setValue"]
}
},
states: {
idle: {
on: {
"TRIGGER.FOCUS": {
target: "focused",
actions: ["setFocusedValue"]
}
}
},
focused: {
on: {
"GOTO.NEXT": {
actions: ["focusNextTrigger"]
},
"GOTO.PREV": {
actions: ["focusPrevTrigger"]
},
"TRIGGER.CLICK": [
{
guard: and("isExpanded", "canToggle"),
actions: ["collapse"]
},
{
guard: not("isExpanded"),
actions: ["expand"]
}
],
"GOTO.FIRST": {
actions: ["focusFirstTrigger"]
},
"GOTO.LAST": {
actions: ["focusLastTrigger"]
},
"TRIGGER.BLUR": {
target: "idle",
actions: ["clearFocusedValue"]
}
}
}
},
implementations: {
guards: {
canToggle: ({ prop }) => !!prop("collapsible") || !!prop("multiple"),
isExpanded: ({ context, event }) => context.get("value").includes(event.value)
},
actions: {
collapse({ context, prop, event }) {
const next = prop("multiple") ? (0, import_utils.remove)(context.get("value"), event.value) : [];
context.set("value", next);
},
expand({ context, prop, event }) {
const next = prop("multiple") ? (0, import_utils.add)(context.get("value"), event.value) : [event.value];
context.set("value", next);
},
focusFirstTrigger({ scope }) {
dom.getFirstTriggerEl(scope)?.focus();
},
focusLastTrigger({ scope }) {
dom.getLastTriggerEl(scope)?.focus();
},
focusNextTrigger({ context, scope }) {
const focusedValue = context.get("focusedValue");
if (!focusedValue) return;
const triggerEl = dom.getNextTriggerEl(scope, focusedValue);
triggerEl?.focus();
},
focusPrevTrigger({ context, scope }) {
const focusedValue = context.get("focusedValue");
if (!focusedValue) return;
const triggerEl = dom.getPrevTriggerEl(scope, focusedValue);
triggerEl?.focus();
},
setFocusedValue({ context, event }) {
context.set("focusedValue", event.value);
},
clearFocusedValue({ context }) {
context.set("focusedValue", null);
},
setValue({ context, event }) {
context.set("value", event.value);
},
coarseValue({ context, prop }) {
if (!prop("multiple") && context.get("value").length > 1) {
(0, import_utils.warn)(`The value of accordion should be a single value when multiple is false.`);
context.set("value", [context.get("value")[0]]);
}
}
}
}
});
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
machine
});