Components · Forms
Three composite patterns the plain field primitives can't express on their own — all built by wiring Field / Input / Select / Button and the DS Radio together: a repeatable field array (add & remove rows), a conditional field that mounts a revealed block off a watched value, and an inline-editable field that swaps between a read-only view and a draft editor.
Foster onboarding — Marisol Vega. Each row is one array item keyed by a stable id; the trash control calls removeAt(i), Add another contact appends a blank row. The last row's Mobile sits focused. The array enforces its own min (1) / max (5) — the add button withdraws at the cap.
Choosing Yes mounts the dependent block (a bordered accent-ruled group). Its fields only validate & submit while it's mounted.
Switching back to No tears the block down and clears its values, so a stale “2 dogs” never rides along on submit.
At rest the field shows its value and a subtle Edit ghost trigger; an unset value reads Not set and the trigger becomes Add.
Clicking Edit swaps the value for a focused draft input (its own local state). Save commits the draft to the field; Cancel discards it and returns to the view state unchanged.
T[] of row values, each keyed by a stable id (not the index). append(blank) adds a row; removeAt(i) drops one; row inputs bind to items[i].field.min keeps at least N rows (the last remove control disables at the floor); max caps the count — the Add button is withdrawn once the array is full. A live n/max count is announced.Radio answer). It is mounted/unmounted, not hidden — so hidden fields never validate or submit, and unmounting clears their state.Save writes the draft back (and returns to view); Cancel / Esc discards it. Enter saves. Focus moves into the input on open and back to the trigger on close.<fieldset> + <legend>; radios/checkboxes ride Base UI roles; each row's remove control names its item; the inline trigger names its field (Edit display name).Source · composed from ui/Field.tsx · Input.tsx · Select.tsx · Button.tsx + @phauna/ds/overlays Radio/Checkbox (catalog/inputs.css .choice). Field-array, conditional-reveal and inline-edit are app-level patterns built on those DS primitives — no bespoke control.