@zag-js/core
v1.38.1
Published
A minimal implementation of xstate fsm for UI machines
Downloads
3,292,617
Maintainers
Readme
@zag-js/core
This package contains a minimal implementation of XState FSM for finite state machines with addition of extra features we need for our components.
Features
- Finite states with optional nested (hierarchical) states
- Initial state
- Transitions (object or strings)
- Context
- Entry actions
- Exit actions
- Transition actions
- Effects
- Boolean guard helpers (
and,or,not)
Note: The core package is intentionally minimal. It doesn't include delayed transitions, interval scheduling, spawn helpers, or activities. Use actions/effects to perform side effects.
To better understand the state machines, we strongly recommend going though the xstate docs and videos. It'll give you the foundations you need.
Quick start
Installation
npm i @zag-js/core
# or
yarn add @zag-js/coreUsage (machine):
import { createMachine } from "@zag-js/core"
const toggleMachine = createMachine({
id: "toggle",
initialState() {
return "inactive"
},
states: {
inactive: { on: { TOGGLE: "active" } },
active: { on: { TOGGLE: "inactive" } },
},
})Usage (service via adapter):
import { createMachine } from "@zag-js/core"
import { VanillaMachine } from "@zag-js/vanilla"
const machine = createMachine({
initialState() {
return "inactive"
},
states: {
inactive: { on: { TOGGLE: "active" } },
active: { on: { TOGGLE: "inactive" } },
},
})
const service = new VanillaMachine(machine)
service.start()
service.subscribe(() => {
console.log(service.state.get())
})
service.send({ type: "TOGGLE" })
service.send({ type: "TOGGLE" })
service.stop()Nested states (dot notation)
import { createMachine } from "@zag-js/core"
const machine = createMachine({
initialState() {
return "dialog"
},
states: {
dialog: {
tags: ["overlay"],
initial: "closed",
states: {
closed: { on: { OPEN: { target: "dialog.open" } } },
open: { on: { CLOSE: { target: "dialog.closed" } } },
},
// parent-level transitions still work
on: { RESET: { target: "dialog.closed" } },
},
},
})
// service.state.matches("dialog.open") === true when nested state is activeState IDs and #id targets
Use id on a state node when you want to target it explicitly from anywhere in the machine.
import { createMachine } from "@zag-js/core"
const machine = createMachine({
initialState() {
return "dialog"
},
states: {
dialog: {
initial: "open",
states: {
focused: {
id: "dialogFocused",
},
open: {
initial: "idle",
states: {
idle: {
on: {
CLOSE: { target: "#dialogFocused" },
},
},
},
},
},
},
},
})Notes:
#idtargets resolve by state nodeid(XState-style).- State IDs must be unique within a machine.
API
createMachine(config, options)
Creates a new finite state machine from the config.
| Argument | Type | Description |
| --------- | ------------------ | ------------------------------------------- |
| config | object (see below) | The config object for creating the machine. |
| options | object (see below) | The optional options object. |
Returns:
A machine definition object consumed by framework adapters (React, Solid, Svelte, Vue, Preact, Vanilla) to create a runtime service.
The machine config has this schema:
Machine config
initialState(function) - returns the machine's initial state value.states(object) - mapping of state names to state configs. Supports nestedstatesandinitialfor child states.on(object) - optional global transitions available from any state.context(function) - returns bindable context fields.computed(object) - derived values based on context, props, refs.entry/exit/effects- root-level actions/effects.implementations(object) - lookup tables foractions,guards,effects.
State config
on(object) - an object mapping event types (keys) to transitions
Transition config
String syntax:
- (string) - the state name to transition to.
- Same as
{ target: stateName }
- Same as
Object syntax:
target(string) - the state name to transition to.actions(Action | Action[]) - the action(s) to execute when this transition is taken.guard(Guard) - the condition (predicate function) to test. If it returnstrue, the transition will be taken.
Machine options
actions?(object) - a lookup object for your string actions.guards?(object) - a lookup object for your string guards specified asguardin the machine.activities?(object) - a lookup object for your string activities.delays?(object) - a lookup object for your string delays used inafterandeveryconfig.
Action config
The action function to execute while transitioning from one state to another. It takes the following arguments:
context(any) - the machine's currentcontext.event(object) - the event that caused the action to be executed.
