React CSV Import Wizard

Every data tool eventually needs an importer, and a bad one poisons the database. This walks the four steps that make it safe — upload, map columns to your schema, validate every row, and commit — auto-mapping the columns it recognises and skipping the rows it can't trust.

  1. 1Upload
  2. 2Map
  3. 3Validate
  4. 4Commit

Installation

npx shadcn@latest add "https://kelvinui.com/registry/csv-import.json"

Props

PropTypeDescription
fieldsImportField[]{ key, label, required?, validate?, aliases? }
onCommit(rows: Record<string,string>[]) => voidReceives the clean, mapped rows
sampleCsvstringEnables a "use sample data" shortcut

Auto-mapping and honest validation

Two things separate a wizard people trust from one they fight:

  • Auto-mapping saves the tedious step. Each field carries aliases — "Part Number" maps to sku, "Qty" to stock — so a well-formed file often arrives at the mapping step already correct. The user confirms rather than assembles.
  • Validation is per-cell and non-destructive. The report counts valid and problem rows and lists each issue with its source line number (the +2 accounts for the header row and 1-based counting), so a user can fix the file. Rows with issues are skipped on commit, never silently coerced — a blank required field or a malformed email should not become an empty string in your table.

The bundled parser handles the parts of CSV that trip up a naive split(","): quoted fields, embedded commas, escaped quotes, and \r\n line endings. onCommit receives string values only — coerce to your own types on the far side, where you also own the database transaction. The demo's sample data deliberately includes a negative price, a missing name, a bad email, and a too-short SKU so you can watch the validation step catch them.

For a single-file, no-mapping drop, File Upload is lighter; reach for this when the columns need to line up with a real schema.

New components every week

Get the week's new Kelvin UI components and templates in one short email. No spam, unsubscribe anytime.