Skip to content

Undo and redo ​

createFormHistory gives a form undo and redo. Like the draft, it is not tied to an adapter: push the data whenever it changes and put what undo or redo returns back into the form.

tsx
import { createFormHistory } from '@dynamic-field-kit/core';
import { useDynamicForm } from '@dynamic-field-kit/react';

function ProfileForm() {
  const form = useDynamicForm({ fields, initialValues });
  const [history] = useState(() => createFormHistory(form.data));

  useEffect(() => history.push(form.data), [form.data]);

  const undo = () => {
    const data = history.undo();
    if (data) form.setData(data);
  };
  const redo = () => {
    const data = history.redo();
    if (data) form.setData(data);
  };
  // <button disabled={!history.canUndo()} onClick={undo}>Undo</button>
}
OptionMeaning
limitHow many undo steps are kept (default 100); the oldest go first.
coalesceMsPushes that change the same top-level fields within this window become one step (default 500). 0 turns it off.

canUndo() and canRedo() say whether there is a step to go to, current() returns the data at the current step and reset(data) forgets the history, for example after a submit or after loading a draft.

Things to know:

  • Pushing the data current() already holds is ignored. Restoring a step makes the form report that data back, and that report does not become a new step or wipe the redo steps.
  • Typing is grouped. Typing a word into one field is undone in one go; a pause longer than coalesceMs, a change to another field, or an undo starts a new step.
  • Steps are kept by reference. Plain objects and arrays are compared by content; other values (Date, File) by identity. Replace form data instead of mutating it, as the adapters already do.

Released under the MIT License.