KQ-1668 · MEND/LIST

Mend List

A long application form that gathers every problem a submit finds into a mend list dropped in above the form and pinned to the top of its scrolling body: the list opens on springs.glide while its items fall in from 8px above on springs.snap in a cascade, each naming the field and the fix. Choosing an item scrolls the body to the field on glide, re-aimed every frame so the field lands just under the pinned list, then the field pulses once with an accent ring and takes focus; from then on checking is live, and the moment a field passes its item strikes itself through on springs.flick while the count rolls down on snap. The list is a labelled nav whose heading takes focus when it drops, Next walks the unmended fields from the keyboard, and a refused submit keeps every answer.

KQ-1668 · MEND/LIST

Studio residency application

Fernworks · Spring 2027 intake

8 of 12 answered
About you

Add the part after the @, like ana@fernworks.studio

Only used if your travel plans change.
Your practice

Tell the panel what you make and where to see it.

Start the link with https://

Two or three sentences on what you would make here.65 / 120

Write at least 120 characters · 55 to go

The residency
Preferred season

Pick early, late or either

Kiln time, press bed size, ventilation, anything else.
Agreements
Code of practice

Tick to confirm you have read it

Photographsoptional

5 to mend · next: email

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/mend-list

Props

sections
MendSection[]
default defaultMendSections
The form as sections of fields: { id, title, description?, fields }, each field { id, label, kind, required?, minLength?, pattern?, patternFix?, requiredFix?, options?, placeholder?, hint?, autoComplete?, wide?, validate? }.
values / defaultValues
Record<string, string | boolean>
default — / defaultMendValues
The answers keyed by field id, controlled or initial.
onValuesChange
(values) => void
default —
Fires from the edit that changed the answers, with all of them.
onFieldChange
(id, value, values) => void
default —
Fires from each edit with the field, its new value and every answer.
onSubmit
(values) => void | { fieldErrors? } | Promise<void | { fieldErrors? }>
default —
A submit that passed every check. A promise shows progress on the button; a rejection keeps every answer and says so; resolving with fieldErrors puts the server's words into the mend list.
onInvalid
(ids: string[]) => void
default —
A submit found problems; the ids still to mend, in form order.
onSaveDraft
(values) => void | Promise<void>
default —
Save draft was pressed; a promise shows it saving, then a check.
onMend
(id: string) => void
default —
An item in the mend list was chosen.
listStyle
"panel" | "chips" | "numbered"
default "panel"
How the mend list is drawn: a bordered panel of two-line items, a run of chips, or a numbered checklist with a progress bar.
density
"compact" | "cozy" | "roomy"
default "cozy"
Field height (32, 36, 40px) and the room between fields and sections.
accent
string
default "var(--accent-bright)"
The list's checks, the pulse ring, the strike line and the button's progress, any CSS colour.
checkOnMount
boolean
default false
Run the submit check on mount so the mend list shows from the first frame.
title
string
default "Studio residency application"
The form's heading and accessible name.
subtitle
string
default "Fernworks · Spring 2027 intake"
A quiet line under the heading.
submitLabel
string
default "Submit application"
The submit button's label.
height
number
default 520
Panel height in px; the form scrolls inside it and the mend list pins to its top.
status
"ready" | "loading"
default "ready"
Loading draws placeholder fields and holds the buttons.
disabled
boolean
default false
Nothing can be edited, saved or sent.
className
string
default —
Classes for the outer container.