Traffic Light (Delayed)
export const createTrafficLight = () => { // Define states using defineStates const states = defineStates({ Red: () => "means stop", Green: () => "means go", Yellow: () => "means caution", });
// Create the base machine with states, transitions, and initial state const baseMachine = createMachine( states, { Red: { next: "Green" }, Green: { next: "Yellow" }, Yellow: { next: "Red" }, }, "Red" );
//Use assignEventApi to enhance the machine with utility methods const machine = assignEventApi(baseMachine);
setup(machine)( effect( when( (_ev) => true, (change) => tickEffect( machine.next, change.to.match({ Red: () => 2000, Green: () => 2000, Yellow: () => 1000, }) ) ) ) ); machine.next(); return machine;};import { useMachine } from "matchina/react";import { useMemo } from "react";import { createTrafficLight } from "./machine";
type TrafficLightMachine = ReturnType<typeof createTrafficLight>;
export const TrafficLight = ({ machine }: { machine?: TrafficLightMachine } = {}) => { const fallback = useMemo(() => createTrafficLight(), []); const light = machine ?? fallback; useMachine(light); const state = light.getState(); return ( <button title="Click to Change" className={`rounded px-3 py-2 text-white ${state.match({ Red: () => "bg-red-500", Yellow: () => "bg-yellow-500", Green: () => "bg-green-500", })}`} onClick={() => light.next()} > {state.key} {state.data} </button> );};