ns-ui
A primary field with a slugified 'carbon copy' stacked underneath it, offset like a duplicate sheet peeking out from beneath a receipt. Every keystroke stamps its transformed counterpart onto the flimsy with a tiny pressure jitter; editing the flimsy directly tears it off the coupling until a real Relink button re-stamps it.
Use when one field must derive a second, still-editable value the user can watch being generated (title to URL slug, name to handle), stamped on every keystroke and visibly torn off the coupling the moment they edit the derived copy directly, restorable by a real Relink button; it is the wrong choice for a field that merely formats itself as you type (card-number-emboss) and for a read-only value the user copies out rather than edits (copy-field-crimp).
Install
npx shadcn add https://design.helpmarq.com /r/slug-field-mirror.jsonns-ui / slug-field-mirror
The slug underneath rides along with every keystroke in the title — a carbon copy that tears free the moment you edit it directly.
Auto-generated from Project title. Editing detaches it.
Waiting for a title…
Type a title and watch the slug stamp itself in below. Edit the slug directly to tear it free from the title — Relink restores the coupling with a full re-stamp sweep.
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | — | Accessible label for the primary field, e.g. "Project title". |
| derivedLabel | string | — | Accessible label for the derived flimsy field, e.g. "Slug". |
| value? | string | — | Controlled primary value. |
| defaultValue? | string | — | Initial primary value when uncontrolled. @default "" |
| onValueChange? | (value: string) => void | — | — |
| onDerivedChange? | (value: string, linked: boolean) => void | — | Fires whenever the derived value changes, with whether it's still linked. |
| transform? | (value: string) => string | — | Transforms the primary value into the derived one. @default slugify |
| placeholder? | string | — | — |
| derivedPlaceholder? | string | — | Shown in the flimsy field while its value is empty. @default "auto-generated" |
| className? | string | — | — |