Data import
ProDrop a spreadsheet, then see exactly what was read: rows, columns with sample values, and any rows that couldn't be read and why. Nothing is mapped or loaded at this step.
Preview
Install
With the Candor CLI
First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/data-import
Brings in: button, data, locale, utils · npm: lucide-react@^1.67.0
Usage
"use client"
import * as React from "react"
import { DataImport, type ImportRead } from "@/components/data-import"
// What your parser returns for a file; here, a fixed sample stands in for parsing.
const sample = (name: string, size: number): ImportRead => ({
file: { name, size },
rows: 214,
columns: [
{ header: "Flag", samples: ["new-billing-page", "dark-mode", "fast-search"] },
{ header: "Repo", samples: ["acme/web", "acme/web", "acme/api"] },
{ header: "Owner Email", samples: ["dana@acme.example", "jonas@acme", "mei@acme.example"] },
{ header: "Rollout %", samples: ["25", "100", "n/a"] },
],
skipped: [{ count: 2, reason: "the row was empty" }],
})
export default function Example() {
const [read, setRead] = React.useState<ImportRead | null>(null)
const [reading, setReading] = React.useState(false)
return (
<DataImport
className="max-w-2xl"
read={read}
reading={reading}
onFile={(file) => {
setReading(true)
setTimeout(() => {
setRead(sample(file.name, file.size))
setReading(false)
}, 600)
}}
/>
)
}<DataImport>
| Prop | Type | Default | Description |
|---|---|---|---|
| readrequired | ImportRead | null | — | What was read from the file. null shows the drop zone. |
| onFilerequired | (file: File) => void | — | Called with the file a person dropped or chose. |
| reading | boolean | undefined | false | The file is being read; the drop zone says so and the button is disabled. |
| accept | string | undefined | ".csv,.xlsx,.xls,.tsv" | File types the picker offers, as in the input accept attribute. |
| className | string | undefined | — | Extra classes for the outer element. |
Strings
The fixed words, in English by default. Change any of them under dataImport in <LocaleProvider strings={{ … }}>; the table is exported as dataImportStrings.
| Key | English |
|---|---|
| reading | Reading… |
| drop | Drop a CSV or Excel file |
| firstRow | The first row should be column names. |
| chooseFile | Choose file |
| whatWasRead | What was read |
| rows | { one: "{count} row", other: "{count} rows" } |
| columns | { one: "{count} column", other: "{count} columns" } |
| notRead | { one: "{count} row not read", other: "{count} rows not read" } |
| skippedRows | { one: "{count} row: {reason}", other: "{count} rows: {reason}" } |
Types
- ImportRead
{ file: { name: string; size: number } rows: number columns: ImportColumn[] /** Rows that couldn't be read at all, grouped by reason. */ skipped: { count: number; reason: string }[] }