KQ-1672 · DRAFT/KEEPER

Draft Keeper

A long form that keeps itself: edits queue and are sent as one save a moment after your last keystroke, with an indicator that counts the time since; offline edits pile up with a count that rolls on springs.snap, a failed save keeps the queue and offers Retry, and Ctrl or Cmd+S saves at once. When someone else edits a field you have also changed, their avatar drops onto it on springs.recoil and the field splits along its width on springs.glide into yours and theirs, each with the words the other lacks marked; keeping one slides it into the whole field as the other folds away on the exit ease. Tab reaches the choice and the arrows move between its two buttons.

KQ-1672 · DRAFT/KEEPER

Waylight 4.2 launch brief

Shared with Mira and Jonah

Summary
Yours

Quiet Hours lets teams pause notifications on a schedule, so focus time survives the busiest weeks.

Mira's

Quiet Hours lets each team set focus windows when notifications wait, then sends them in one calm digest.

Ctrl S saves now1 to choose

All changes saved.

summary · yours or mira's · autosave on

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/draft-keeper

Props

values / defaultValues
Record<string, string>
default — / defaultDraftValues
The document, controlled or initial.
onValuesChange
(values) => void
default —
Fires from your edits, kept versions and clean remote edits, with the whole document.
fields
DraftField[]
default defaultDraftFields
The form: { id, label, kind: "text" | "textarea" | "select" | "date", options?, placeholder?, hint?, wide? }.
collaborators
DraftCollaborator[]
default defaultDraftCollaborators
Who else is in the document: { id, name, hue }.
incoming
DraftRemoteEdit[]
default []
Remote edits pushed by the host, { id, field, value, by, at, base? }; each new id is taken once. Yours differing from `base`, or a field you touched, makes a conflict.
me
string
default "You"
Your name, for your avatar in the header.
online
boolean
default true
Offline, edits queue with a count; coming back sends the queue.
onSave
(values, changed: string[]) => void | Promise<void>
default —
Saves the queued changes. A promise shows Saving; a rejection keeps the queue and offers Retry.
onConflict
(field, yours, theirs, by) => void
default —
Someone else changed a field you had also changed; it has split into two versions.
onResolve
(field, kept: "yours" | "theirs", value) => void
default —
A version was kept.
autosaveMs
number
default 1200
Quiet time after your last keystroke before an autosave, in ms.
lastSaved
number
default now − 12 s
When the document was last saved, ms on the `now` clock.
now
number
default defaultDraftNow
The moment to count from, in ms; never read from the clock during render.
indicatorStyle
"pill" | "dot" | "line"
default "pill"
The save indicator: a bordered pill, a quiet dot, or a line along the panel's top edge that fills while saving. Below 30rem each shrinks to its icon.
density
"compact" | "cozy" | "roomy"
default "cozy"
Field heights and the room between them.
tone
"neutral" | "paper" | "slate"
default "neutral"
The surface temperature in both themes: plain card, warmed paper or cooled slate, for the panel, fields and version panes.
title
string
default "Waylight 4.2 launch brief"
The form's heading and accessible name.
height
number
default 520
Panel height in px; the form scrolls inside it.
disabled
boolean
default false
Nothing can be edited or saved.
className
string
default —
Classes for the outer container.