ZUI

Search documentation

Find a page or a heading.

Unsaved Changes Toolbar

A toolbar floating at the top or bottom of the viewport while a form has unsaved changes, with a polite message and Reset and Save actions that wait while saving.

tsx

Installation

bash

Usage

tsx
tsx

Render it while the form differs from its saved values, and write every word: the message and the labels change with the state. Use error after a save fails, with Try again on Save, and attention when the person tries to leave with changes unsaved. A Save outside the form's markup reaches it through form.

The toolbar unmounts once Reset or a successful save makes the form clean, and the button that had focus goes with it, so focus would fall to the page's body. Move focus first to an element that stays, such as the field that was edited or the form's heading: in Reset's handler, and after a save when focus is inside the toolbar.

Composition

text

API reference

UnsavedChangesToolbar

A div that takes every prop a div takes, fixed 16px in from the viewport's sides and centred, up to 512px wide, on a toast's surface. side is bottom (the default) or top, the edge it floats at, 16px in. state is default (the default), saving, error or attention: error and attention turn the message destructive, and attention the ring too. It is a group named by its message, carries data-side and data-state, and sets data-slot="unsaved-changes-toolbar". Inside an element with contain: layout it floats at that element's edge instead of the viewport's.

UnsavedChangesToolbarMessage

A p that takes every prop a p takes. Its children are the message, which names the toolbar. It is a polite live region, so a screen reader reads each new message without moving focus. Its children render one pass after it mounts, so the first message is read when the toolbar appears. It sets data-slot="unsaved-changes-toolbar-message".

UnsavedChangesToolbarActions

A div that takes every prop a div takes, holding the two actions. It sets data-slot="unsaved-changes-toolbar-actions".

UnsavedChangesToolbarReset

Renders shadcn's Button, small and ghost, and takes every prop it takes except variant and size. Its children are the label. While saving it is disabled and stays focusable, so focus does not move. It sets data-slot="unsaved-changes-toolbar-reset".

UnsavedChangesToolbarSave

Renders shadcn's Button, small, and takes every prop it takes except variant and size. Its children are the label. While saving it is disabled, stays focusable so focus does not move, and shows shadcn's Spinner before the label, hidden from a screen reader, which hears the message instead. It sets data-slot="unsaved-changes-toolbar-save".