Smart form fill
ProA paste-to-fill form card where AI reads an email signature or messy notes and fills a contact field by field. Each value flashes in with a confidence dot, its source lights up in the pasted text, low-confidence guesses ask for review, and Undo puts the old values back.
New contact
Paste a signature, an email or rough notes. AI fills the fields and flags anything to check.
- People paste an email signature, a forwarded message or notes and expect the record to fill itself.
- You need visible confidence and an easy review path before AI-filled data is saved.
- Onboarding or CRM flows where typing six fields by hand is the main friction.
- Plain data entry with no unstructured source; use form-field and input.
- Long multi-page applications; use multi-step-form and add a paste step to one page.
- Bulk imports of many records; use a table import flow instead of one card.
Installation
Pro source and install commands unlock with a Pro plan.
import { SmartFormFill } from "@/components/arc/smart-form-fill/smart-form-fill"; export function NewContact() { return ( <SmartFormFill extract={async (text, signal) => { const response = await fetch("/api/extract-contact", { method: "POST", body: text, signal }); return response.json(); // { name: { value, confidence, source }, ... } }} onSubmit={(values) => saveContact(values)} /> );}SmartFormFill
A form card with a paste area. Pasted text is read by AI, each field fills in turn with a short highlight and a confidence dot, low-confidence fields ask for review, and Undo restores the values from before the fill.
fieldsSmartFormFillField[]contact fieldsThe form: { id, label, kind?, placeholder?, span?, autoComplete? }. kind picks the input type; "company" adds a logo slot. Defaults to name, title, company, email, phone and address.defaultValuesRecord<string, string>–Starting values keyed by field id.onValuesChange(values: Record<string, string>) => void–Called on every change, typed or filled.extract(text: string, signal: AbortSignal) => Promise<SmartFormFillResult>simulateExtractReads the pasted text and resolves { [fieldId]: { value, confidence, source?, note? } }. Abort when the signal fires (Stop, Escape, a new paste). Defaults to a simulated read: hand-checked results for the samples and a local parser for anything else.reviewThresholdnumber0.8Fields with a confidence below this ask for review and block Save until checked or edited.samples{ label: string; text: string }[]signature and messy noteTexts behind Try sample, cycled in order. Pass [] to hide the button and the autoplay.autoPlaybooleantrue without extractLoops paste, fill, review and undo while visible, and stops for good on the first pointer or key press inside the card.onFill(result: SmartFormFillResult) => void–Called once every field from a read has been filled.onUndo(restored: Record<string, string>) => void–Called after Undo restores the values from before the last fill.onSubmit(values: Record<string, string>) => void | Promise<void>–Saves the form. The button shows a loading state while the promise is pending; a rejection shows an error status. Defaults to a simulated save.resolveLogo(company: string) => ReactNode | undefined–Logo for the company field. Falls back to built-in marks for Stripe, Linear, Vercel, Figma and Notion, then a building icon.model{ name: string; mark?: ReactNode }Claude Haiku 5.5The model named beside the paste area.titlestring"New contact"Card title.descriptionstring–One line under the title. Pass an empty string to hide it.submitLabelstring"Save contact"Label of the primary action.classNamestring–Class on the root card.- Cmd/Ctrl+V
- Paste into the text area; the read starts right away.
- Cmd/Ctrl+Enter
- Read typed text from the text area.
- Escape
- Stop a read in progress; nothing changes.
- Tab
- Moves through the text area, Try sample, Fill, every field, the check buttons, Undo and Save.
- A polite live region announces each step: reading, how many fields were filled, which need review, checks, undo and save. With the default extractor it adds that the run was simulated.
- Each filled input carries an aria-description with its confidence and, for low-confidence fields, the reason. Fields that need review are aria-invalid until checked or edited.
- Status is never color alone: confidence shows a dot plus a percentage or a word (Review, Checked, Edited); the footer pairs an icon with text.
- The check button inside a review field has a label naming the field. Save focuses the first field that still needs review.
- The pasted text view is a focusable, labelled region so keyboard users can scroll it.
- Fields fill in form order 140ms apart. Each value fades in over 200ms and the input breathes an accent tint for 900ms; no movement, no size change.
- The source span for the field being filled, hovered or focused takes a stronger tint (160ms), so cause and effect read across the card.
- Labels, badges, the logo and status swap with one crossfade: out in 100ms, in over 160ms with a 2px rise. The reading label uses a calm shimmer.
- Reduced motion fills every field at once, drops the tint animation and the autoplay loop, and keeps all end states. Autoplay pauses while the card is off screen.
- Side by side from a 720px container: paste well left, form right. Below that the well stacks on top at a fixed height.
- Under 440px every field takes the full row and the footer stacks its status above the actions.
- Container queries, so it adapts to the column it sits in, not the viewport. Holds at 360px without horizontal scroll.
- Only CSS animations for the fill highlight; motion is used for small crossfades. No layout animation.
- Autoplay timers stop when the card leaves the viewport and are cleared on unmount; reads are aborted on unmount.
- The built-in marks are inline SVG, about 6KB together; resolveLogo can supply your own.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Use for creating a record from unstructured text: CRM contacts, vendor or company profiles, shipping addresses, support tickets. Pass custom fields for anything beyond a contact.
- Wire extract to your model with structured output that returns value, confidence 0 to 1 and the exact source substring; source powers the highlight, note explains low confidence.
- Keep the human in the loop: leave reviewThreshold around 0.8 so guesses (inferred states, paraphrased titles, one of several phone numbers) are flagged rather than saved silently.
- Set autoPlay={false} in product screens; the default loop is for docs and marketing.
The full library index for assistants is at /llms.txt.