Import mapping

A React component in Beamline's Data & tables category.

Map the columns of a file to the fields of one record type, see what every value becomes, then run the import and get an outcome for each row: suggestions are hints until accepted, ambiguous dates are named, and only failed rows are retried.

Use it for

  • Importing a spreadsheet or export into one record type (accounts, contacts, products) after the application has read the file.
  • Any column-to-field mapping where values are converted and some may fail: dates, people, amounts.
  • Large or nested destinations (dozens of fields, grouped paths) that need search and a destination checklist.

Not for

  • Choosing or uploading the file itself → file-dropzone (place it before this).
  • Reviewing proposed edits to existing rows → diff-table.
  • Editing records after import → data-grid.
  • Mapping value lists (Hot → Negotiation) or building transforms → the application's own form.

Anatomy

  • header: title, source line (file · rows · columns → destination), steps (Map columns / Preview / Import)
  • stage heading (focus target) and a polite status region
  • map: toolbar (filter with counts, search, bulk Accept suggestions / Don't import undecided, check status)
  • map: summary of blockers with links (after a blocked Preview)
  • map: pairs in file order — source (grip, name, path, samples), seam, chooser, suggestion with Accept, interpretation, check, invalid-value policy, transfer notice with Undo
  • map: destinations panel in destination order (grouped by path), each field mapped / not mapped / required; drop targets
  • preview: table of sample rows in destination order (field, from-column lineage, Change), converted cells, invalid cells with reasons; scope line
  • import: progress (measured when reported), Cancel; result counts, outcomes list (failed first), lifetime note
  • footer: Back · Preview / Import N rows / Retry N failed rows · View records · Done

Variants

  • frame: surface, none
  • layout: auto, stacked

States

  • map: undecided, suggested, mapped, skipped (Don't import), transferred (notice + Undo)
  • check: checking (stale revision), ok, invalid (count, examples, policy), ambiguous (interpretation needed), assessment error (Retry)
  • blocked: summary of what to settle before preview
  • preview: read-only, rows that won't import and why
  • import: working (progress, Cancel when supported), request rejected (back to preview, draft kept), result, partial failure (retry failed rows only), retrying, cancelled (remaining rows offered)
  • disabled, empty (no columns)

Keyboard

  • Tab moves through pairs in file order; each chooser keeps focus after Enter picks a field
  • Chooser: ↓/↑ open and move, type to filter by name, path or type (several words match across them: “billing city”), Enter chooses, Esc closes and restores; nested fields sit under their path's heading. Below 640 px the chooser opens as a bottom sheet with its own search and focus returns to the field
  • Accept on a suggestion moves focus to that pair's chooser
  • Interpretation and invalid-value policy are radio groups: arrows choose
  • Undo on a transfer notice restores both pairs and returns focus to the pair being edited
  • Destinations panel is one tab stop: ↑/↓, Home/End, type-ahead; Enter on a mapped field focuses its pair, on an unmapped field opens a source picker
  • Preview: Change on a column returns to that pair; Back returns to the Preview button with the list scrolled as it was
  • Every stage change moves focus to the stage heading

Motion

Choosing never moves anything; notices and the blocker summary open with the disclosure height transition (in 90ms, out 180ms); stage bodies fade in 90ms under an anchored header; drag shows a ghost chip that fades out on cancel. Reduced motion: same content and focus, all transitions instant.

Props

PropTypeDefaultDescription
source (required)ImportSource—File ID, name, row count, columns in file order and sample rows, as the application read them.
destination (required)ImportDestination—Record type ID, name and fields in destination order (type, required, path).
value / defaultValue / onValueChangeImportMappingDraft—The mapping draft keyed by source column ID, with a revision that increments on every change.
suggestionsRecord<sourceColumnId, ImportSuggestion>—Hints with a reason; never accepted automatically.
assessmentImportMappingAssessment—Caller-computed checks for one draft revision: per-pair conversions, interpretations, ready/blocked row counts.
onAssessmentRetry() => void—Retry after a failed assessment.
stage / defaultStage / onStageChange"map" | "preview" | "import"—Which stage is shown.
onImport(request, { onProgress, signal }) => Promise<ImportResult>—Runs the import; reject only when nothing was written, otherwise resolve with an outcome per processed row.
cancellableboolean—Show Cancel while importing; the operation honours the signal.
result / defaultResult / onResultChangeImportMappingResultState | null—Merged outcomes across attempts, so the caller can reopen a finished or running import.
onBack() => void—Back from the Map stage to the caller's previous step.
onOpenRecords / recordHref(recordIds) => void / (recordId) => string—Open the imported records; link each outcome's record.
resultActions / onDone / lifetimeNoteReactNode / () => void / ReactNode—Extra result actions, the finishing action and how long the result lasts.
frame"surface" | "none"—Paint the root as a surface, or none inside a dialog, sheet or card. Default surface.
layout"auto" | "stacked"—Side-by-side destinations panel from 880px component width, or always stacked. Default auto.
dragboolean—Pointer drag from a pair's grip onto a destination field; fine pointers only. Default true.
title / emptyLabel / disabled / className / classNamesmixed—Heading, empty text, read-only, root class and per-part classes keyed by part name.

Dependencies

lucide-react

Import

import { ImportMapping } from "@/components/import-mapping/import-mapping";

Get it

Import mapping is part of Beamline: 190 React components and screens your coding agent (Claude Code, Codex, Cursor or any MCP client) installs into your app through Beamline's MCP server, as a ready-built package or as plain React source you can change. $49 one payment (regular $200), no subscription, a year of updates, one licence for your whole team. Get Beamline · Connect your agent

More in Data & tables

  • Data grid: Virtualised grid for thousands of rows: multi-sort, search and value filters, resizable and pinnable columns, range selection, inline edit, footer…
  • Diff table: Proposed edits to a table before they happen: new rows green, removals struck through, changed cells old → new; each change can be left out and Apply…
  • Filter toolbar: The filters on a list kept in view: chips that remove themselves, Add filter with fields and their values, Clear all, and room for search or view controls.
  • Table: A plain, styled HTML table for small static data: header, body, footer, caption, numeric cells, three densities and a sticky header.