ImportDialog
A full-viewport step wizard — Attio's own CSV import flow.
A full-viewport takeover, not a small modal — measured live from Attio's own
Import CSV flow: 1584x871 filling a ~1600x900 viewport, border-radius: 0,
no shadow, opaque white. A 4-step header (Upload file / Map columns / Review values / Preview import), a dashed drop zone for step 1, and a
primary "Next" action.
The chrome is generic — the wizard doesn't know about CSV. Step 1's body is
typically ImportDialogDropzone; the other steps are consumer-supplied
children, since Attio's own column-mapping/review/preview UI wasn't part
of this measurement pass.
Installation
npm install @crisp-ui-kit/crispUsage
import { ImportDialog, ImportDialogDropzone } from "@crisp-ui-kit/crisp";
<ImportDialog
open={open}
onOpenChange={setOpen}
steps={[
{ id: "upload", label: "Upload file" },
{ id: "map", label: "Map columns" },
{ id: "review", label: "Review values" },
{ id: "preview", label: "Preview import" },
]}
activeStep={activeStep}
primaryLabel={activeStep === "preview" ? "Import rows" : "Next"}
onPrimary={advance}
>
{activeStep === "upload" && (
<ImportDialogDropzone onFileAccept={setFile} />
)}
{/* map / review / preview: your own step content */}
</ImportDialog>;Examples
Stepping through the wizard
Steps 2-4 are consumer-supplied children driven by activeStep; this
example advances through all four with placeholder body content.
Props
Prop
Type
ImportDialogDropzone
Prop
Type
ImportDialogFileSummary
Step 1's post-upload summary bar (crisp#662, measured live): filename +
.CSV file - {size} on the left, "Columns found"/"Rows found" stat pair on
the right. A consumer renders ImportDialogDropzone OR this, not both, once
a file exists — swap one for the other on onFileAccept.
Prop
Type