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
| Prop | Type | Default | Description |
|---|---|---|---|
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 / onValueChange | ImportMappingDraft | — | The mapping draft keyed by source column ID, with a revision that increments on every change. |
suggestions | Record<sourceColumnId, ImportSuggestion> | — | Hints with a reason; never accepted automatically. |
assessment | ImportMappingAssessment | — | 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. |
cancellable | boolean | — | Show Cancel while importing; the operation honours the signal. |
result / defaultResult / onResultChange | ImportMappingResultState | 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 / lifetimeNote | ReactNode / () => 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. |
drag | boolean | — | Pointer drag from a pair's grip onto a destination field; fine pointers only. Default true. |
title / emptyLabel / disabled / className / classNames | mixed | — | 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.