Pimp My IDE / garage dispatchBack to the garage
Dispatch 390 / interface craft

Three buttons can expose the whole machine.

A digital watch is a small interface with nested modes, timed actions, and one button that means several things. That makes it a better state-model test than another diagram full of login boxes.

16 Oct 20267 minute readInterface craftSource inspected. Demo not exercised.

A tiny control surface still has hidden state

Daniel Dunderfelt's Casio F-91W project replaces a watch simulation's control logic with an XState machine. The repository puts the watch beside a live statechart so each button press can be read as an event and a transition.

The source makes the structure concrete. The top machine is parallel. One region controls the watch mode while another controls the light. The watch region contains date and time, alarm, stopwatch, and time-setting states. Several of those states contain their own editing states.

That is the point. Three physical buttons do not mean three actions. Their meaning depends on the active state. A mode button can enter another mode. The same adjust button can toggle time format, start a stopwatch, or change a number.

Write events before handlers

A click handler answers, "What should this button do now?" A state model asks two earlier questions. What state is active, and which event occurred?

The repository names events such as a-down, l-down, and c-down. In the date and time state, c-down enters the alarm. In the alarm state, the same event enters the stopwatch. In the stopwatch state, it enters time setting. The transition table holds that sequence in one place.

This separation helps with review. A designer can inspect allowed movement without tracing every rendering branch. A test can send the same event from each state and assert the next state. The UI becomes an adapter to the model instead of the model hiding inside the UI.

Use hierarchy where the control already has it

Statecharts extend finite state machines with nested states, parallel regions, guarded transitions, delays, and history. Those tools fit control surfaces that already have modes inside modes.

The watch model uses a nested holding state with a delayed transition after three seconds. It also keeps the light in a parallel region. The light can turn on without replacing the current watch mode. That is more precise than inventing combined labels such as STOPWATCH_WITH_LIGHT for every possible pair.

Do not add hierarchy because the diagram tool permits it. Add a parent state when child states share transitions or meaning. Add a parallel region when two states can remain active at the same time. The shape should remove impossible combinations, not create more boxes.

Keep the gaps visible

The project README lists three limits. Holding the adjust button does not repeat increments. The alarm time can be set, but the alarm does not fire. Day-of-week setting differs because the model uses JavaScript's Date object.

Those limits belong beside the model. A statechart can make the implemented behavior easier to inspect. It does not prove that the model matches the physical watch, covers every timing edge, or has been tested on each input path.

Use the bench below as a teaching fixture. It is a simplified four-mode machine, not a Casio emulator. Its light state runs beside the mode state. Its trace records events and resulting states so a reviewer can copy a short replay.

Interactive makeover / transition test bench

Press it. Read the state.

A normal mode switch shows only the result. This bench joins three native buttons, a parallel light state, a transition map, a replay trace, and a copyable test packet.

Three-button control fixture0 events
MODE TIMELIGHT OFF
TIME
12:00:00
Adjust toggles 12 or 24 hour display.

Why this is better: the light remains independent while Mode moves through the main route. The visible state map and replay trace make that relationship inspectable.

Live model readout

Current transition

Initial state entered. No event has been sent.

TIMEActive
ALARMIdle
STOPWATCHIdle
SET TIMEIdle
Transition tapeNewest last
  1. INIT -> TIME + LIGHT_OFF

Sources read

Source check completed 16 Oct 2026. The repository was inspected at commit 060bfe4772855be661736d26d2a374f8fffa3363. We did not install its dependencies, run its browser tests, exercise the hosted demo, or compare it with physical hardware. The interactive bench on this page is a separate teaching fixture.