undo / redo

Clicking a button - insert, delete, reset, or the counter below - always creates its own undo step, even if you click it several times fast: three clicks undo in three steps, not one. Typing into a field is different: it coalesces into a single undo step for as long as the field stays focused, the way a text editor groups keystrokes - bounded by focus, not by how fast you type. Turn it on per model with <fx-model undo>.

Basic usage

A form with undo, redo and reset

This form has keyboard-shortcuts enabled, so ⌘Z / Ctrl Z undoes and ⌘⇧Z / Ctrl ⇧ Z redoes - alongside the buttons below.

Hello Universe wash the dishes walk the dog
History: empty

Type here without pausing, click Checkpoint mid-sentence, then keep typing - still without leaving the field. Undo once and only the text typed after the checkpoint disappears, not the whole note. <fx-commit-history> forces that boundary without requiring a blur.

Nested fx-fore

Undo across a shared instance

The inner form below declares no fx-instance of its own - it only reads and writes the outer form's shared instance. Its undo and redo buttons still work correctly: they operate on the outer form's history, since that's where the shared data actually lives.

Shared-instance refresh only propagates downward (see shared-instances.html), and only reliably for widget-driven edits - not for action-driven ones like fx-setvalue, fx-undo or fx-redo. Each button below explicitly asks the outer form to refresh once it has changed the shared data, via a plain <fx-dispatch name="refresh" targetid="shared-outer"> - that's an existing, unrelated framework quirk, not part of undo/redo itself.

0

Outer form

History: empty

Inner form

History: empty