A note that saves itself a moment after you stop typing, shows Saving, Saved at a time or a retryable error, and saves immediately when you leave the page or press the button. Use this when losing a draft is worse than saving too often.
registry/patterns/autosave-note-with-status/autosave-note-with-status.tsx
"use client"
import * as React from "react"
import { Button } from "@/components/ui/button"
import { AutosaveIndicator, useAutosave } from "@/components/ui/form-autosave"
import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
export interface AutosaveNoteWithStatusProps {
initial?: string
/** Persist the note. Reject to show a retryable error. */
save?: (text: string) => Promise<void>
delay?: number
}
const demoSave = async () => {
await new Promise((r) => setTimeout(r, 300))
}
export function AutosaveNoteWithStatus({
initial = "",
save = demoSave,
delay = 800,
}: AutosaveNoteWithStatusProps) {
const [text, setText] = React.useState(initial)
const autosave = useAutosave({ value: text, onSave: save, delay })
return (
<div className="flex w-full max-w-md flex-col gap-2">
<div className="flex items-center justify-between">
<Label htmlFor="anws-note">Meeting notes</Label>
<AutosaveIndicator {...autosave} onRetry={autosave.retry} />
</div>
<Textarea
id="anws-note"
rows={6}
value={text}
onChange={(e) => setText(e.target.value)}
onBlur={() => void autosave.flush()}
/>
<Button
type="button"
variant="outline"
size="sm"
className="self-end"
disabled={autosave.status === "saving"}
onClick={() => void autosave.flush()}
>
Save now
</Button>
</div>
)
}