SaveBar
A bar that rises when a form has unsaved changes, with Save and Discard.
SourcePackage @kerf-js/veneer
Preview
tsx
import { state } from '@kerf-js/core'import { Input, SaveBar, Stack, Toaster} from '@kerf-js/veneer'export function Project() { const values = state({ name: 'storefront', branch: 'main', }) const errors = state<Record<string, string>>({}) const set = (key: 'name' | 'branch', value: string) => (values.value = { ...values.value, [key]: value }) return ( <Stack as="form" gap="group" > <Input label="Project name" value={values.value.name} error={errors.value.name ?? ''} onInput={(e) => set('name', e.currentTarget.value) } /> <Input label="Production branch" value={values.value.branch} hint="Change a field and the bar rises." error={errors.value.branch ?? ''} onInput={(e) => set('branch', e.currentTarget.value) } /> <SaveBar values={values} errors={errors} validate={(v) => v.name.trim() ? {} : { name: 'A project needs a name.' } } onSave={() => wait(800)} /> <Toaster /> </Stack> )}const wait = (ms: number) => new Promise<void>((done) => { setTimeout(done, ms) })Installation
npm install @kerf-js/veneerUsage
tsx
import { SaveBar } from '@kerf-js/veneer'When to use
Use it for
- A long form that saves as a whole
Reach for something else
- Switch, when each setting saves itself the moment it changes
Accessibility
- Enter
- Saves, from any field in the form
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
values | State<T> | — | The form's live values, as a state. The bar compares them to a snapshot. |
errors | State<FieldErrors> | — | Where field errors are written, for your fields to read. |
validate | ((values: T) => FieldErrors) | — | Client checks; anything returned stops the save. |
| Event | Type | Default | Description |
|---|---|---|---|
onSave | (values: T) => void | FieldErrors | Promise<void | FieldErrors> | — | Resolve with field errors to keep the bar; throw on a transport failure. |
onDiscard | (() => void) | — | Called after Discard has put the snapshot back. |
onLeave | ((href: string) => void) | — | Where a confirmed leave goes. Default: the browser navigates. |
Parts
Every element carries a stable name, so you can style it from your own CSS: [data-scope="save-bar"] [data-part="msg"]
msgactions
RelatedSettings layoutInput