UNPKG

@zag-js/solid

Version:

The solid.js wrapper for zag

276 lines (274 loc) • 8.93 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; 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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/machine.ts var machine_exports = {}; __export(machine_exports, { useMachine: () => useMachine }); module.exports = __toCommonJS(machine_exports); var import_core = require("@zag-js/core"); var import_utils = require("@zag-js/utils"); var import_solid_js = require("solid-js"); var import_bindable = require("./bindable.js"); var import_refs = require("./refs.js"); var import_track = require("./track.js"); function useMachine(machine, userProps = {}) { const scope = (0, import_solid_js.createMemo)(() => { const { id, ids, getRootNode } = access(userProps); return (0, import_core.createScope)({ id, ids, getRootNode }); }); const debug = (...args) => { if (machine.debug) console.log(...args); }; const props = (0, import_solid_js.createMemo)( () => machine.props?.({ props: (0, import_utils.compact)(access(userProps)), scope: scope() }) ?? access(userProps) ); const prop = createProp(props); const context = machine.context?.({ prop, bindable: import_bindable.createBindable, get scope() { return scope(); }, flush, getContext() { return ctx; }, getComputed() { return computed; }, getRefs() { return refs; }, getEvent() { return getEvent(); } }); const ctx = { get(key) { return context?.[key].get(); }, set(key, value) { context?.[key].set(value); }, initial(key) { return context?.[key].initial; }, hash(key) { const current = context?.[key].get(); return context?.[key].hash(current); } }; const effects = { current: /* @__PURE__ */ new Map() }; const transitionRef = { current: null }; const previousEventRef = { current: null }; const eventRef = { current: { type: "" } }; const getEvent = () => (0, import_solid_js.mergeProps)(eventRef.current, { current() { return eventRef.current; }, previous() { return previousEventRef.current; } }); const getState = () => (0, import_solid_js.mergeProps)(state, { matches(...values) { const current = state.get(); return values.some((value) => (0, import_core.matchesState)(current, value)); }, hasTag(tag) { const current = state.get(); return (0, import_core.hasTag)(machine, current, tag); } }); const refs = (0, import_refs.createRefs)(machine.refs?.({ prop, context: ctx }) ?? {}); const getParams = () => ({ state: getState(), context: ctx, event: getEvent(), prop, send, action, guard, track: import_track.createTrack, refs, computed, flush, get scope() { return scope(); }, choose }); const action = (keys) => { const strs = (0, import_utils.isFunction)(keys) ? keys(getParams()) : keys; if (!strs) return; const fns = strs.map((s) => { const fn = machine.implementations?.actions?.[s]; if (!fn) (0, import_utils.warn)(`[zag-js] No implementation found for action "${JSON.stringify(s)}"`); return fn; }); for (const fn of fns) { fn?.(getParams()); } }; const guard = (str) => { if ((0, import_utils.isFunction)(str)) return str(getParams()); const fn = machine.implementations?.guards?.[str]; if (!fn) (0, import_utils.warn)(`[zag-js] No implementation found for guard "${JSON.stringify(str)}"`); return fn?.(getParams()); }; const effect = (keys) => { const strs = (0, import_utils.isFunction)(keys) ? keys(getParams()) : keys; if (!strs) return; const fns = strs.map((s) => { const fn = machine.implementations?.effects?.[s]; if (!fn) (0, import_utils.warn)(`[zag-js] No implementation found for effect "${JSON.stringify(s)}"`); return fn; }); const cleanups = []; for (const fn of fns) { const cleanup = fn?.(getParams()); if (cleanup) cleanups.push(cleanup); } return () => cleanups.forEach((fn) => fn?.()); }; const choose = (transitions) => { return (0, import_utils.toArray)(transitions).find((t) => { let result = !t.guard; if ((0, import_utils.isString)(t.guard)) result = !!guard(t.guard); else if ((0, import_utils.isFunction)(t.guard)) result = t.guard(getParams()); return result; }); }; const computed = (key) => { (0, import_utils.ensure)(machine.computed, () => `[zag-js] No computed object found on machine`); const fn = machine.computed[key]; return fn({ context: ctx, event: eventRef.current, prop, refs, scope: scope(), computed }); }; const state = (0, import_bindable.createBindable)(() => ({ defaultValue: (0, import_core.resolveStateValue)(machine, machine.initialState({ prop })), onChange(nextState, prevState) { const { exiting, entering } = (0, import_core.getExitEnterStates)(machine, prevState, nextState, transitionRef.current?.reenter); exiting.forEach((item) => { const exitEffects = effects.current.get(item.path); exitEffects?.(); effects.current.delete(item.path); }); exiting.forEach((item) => { action(item.state?.exit); }); action(transitionRef.current?.actions); entering.forEach((item) => { const cleanup = effect(item.state?.effects); if (cleanup) { const existing = effects.current.get(item.path); effects.current.set(item.path, existing ? (0, import_utils.callAll)(existing, cleanup) : cleanup); } }); if (prevState === import_core.INIT_STATE) { action(machine.entry); const cleanup = effect(machine.effects); if (cleanup) { const existing = effects.current.get(import_core.INIT_STATE); effects.current.set(import_core.INIT_STATE, existing ? (0, import_utils.callAll)(existing, cleanup) : cleanup); } } entering.forEach((item) => { action(item.state?.entry); }); } })); let status = import_core.MachineStatus.NotStarted; (0, import_solid_js.onMount)(() => { const started = status === import_core.MachineStatus.Started; status = import_core.MachineStatus.Started; debug(started ? "rehydrating..." : "initializing..."); state.invoke(state.initial, import_core.INIT_STATE); }); (0, import_solid_js.onCleanup)(() => { debug("unmounting..."); status = import_core.MachineStatus.Stopped; const fns = effects.current; fns.forEach((fn) => fn?.()); effects.current = /* @__PURE__ */ new Map(); transitionRef.current = null; action(machine.exit); }); const send = (event) => { queueMicrotask(() => { if (status !== import_core.MachineStatus.Started) return; previousEventRef.current = eventRef.current; eventRef.current = event; let currentState = (0, import_solid_js.untrack)(() => state.get()); const { transitions, source } = (0, import_core.findTransition)(machine, currentState, event.type); const transition = choose(transitions); if (!transition) return; transitionRef.current = transition; const target = (0, import_core.resolveStateValue)(machine, transition.target ?? currentState, source); debug("transition", event.type, transition.target || currentState, `(${transition.actions})`); const changed = target !== currentState; if (changed) { state.set(target); } else if (transition.reenter) { state.invoke(currentState, currentState); } else { action(transition.actions); } }); }; machine.watch?.(getParams()); return { state: getState(), send, context: ctx, prop, get scope() { return scope(); }, refs, computed, event: getEvent(), getStatus: () => status }; } function flush(fn) { fn(); } function access(value) { return (0, import_utils.isFunction)(value) ? value() : value; } function createProp(value) { return function get(key) { return value()[key]; }; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { useMachine });