CentercodeDitto
DittoPorygonAPI

ImportWizardBlock

Wizard-based data import with CSV/JSON auto-detection, validation, and inline editing

Overview

A 3-step wizard for importing data from CSV or JSON. Automatically detects format, validates against a Zod schema, and allows inline editing to fix errors before final import.

Key Capabilities

Data Input

  • Paste data or upload CSV/JSON files
  • Auto-detect format (CSV vs JSON)
  • Download template files for correct format

Validation & Editing

  • Zod schema validation per row
  • Inline editing to fix validation errors
  • Fuzzy matching for lookup fields

When to Use ImportWizardBlock

  • Bulk importing data from spreadsheets or external systems
  • Allowing users to paste or upload data without strict format requirements
  • Providing error correction before committing imports

Quick Start

Define your import columns and Zod schema, then render the ImportButton component.

import { ImportButton, type ImportColumn } from '@/ui/blocks';
import { z } from 'zod';

const schema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
  status: z.enum(['active', 'pending']),
});

const columns: ImportColumn[] = [
  { key: 'name', label: 'Name', type: 'text', required: true },
  { key: 'email', label: 'Email', type: 'text', required: true },
  { key: 'status', label: 'Status', type: 'choice', choices: ['active', 'pending'] },
];

<ImportButton
  columns={columns}
  schema={schema}
  entityName="users"
  onImport={async (data) => {
    await bulkCreateUsers(data);
    return { success: true, importedCount: data.length };
  }}
/>

Live Examples

Basic Import

Simple import with text and choice fields. Click the button to open the wizard.

Click to open import wizard

Multiple Field Types

Import with text, number, date, and boolean fields. Uses matchPatterns for flexible column matching.

Integration with AdminListTable

Add an import button to the AdminListTableBlock toolbar for seamless integration.

Add ImportButton to the toolbar.actions array to enable import alongside your table.

// In a page with AdminListTableBlock
import { AdminListTableBlock, ImportButton } from '@/ui/blocks';

<AdminListTableBlock
  items={items}
  columns={tableColumns}
  toolbar={{
    actions: [
      <ImportButton
        key="import"
        columns={importColumns}
        schema={itemSchema}
        entityName="items"
        onImport={handleBulkImport}
      />
    ]
  }}
/>

Column Configuration

Each ImportColumn defines a field in your import schema.

PropTypeDescription
keystringInternal field key (matches Zod schema property)
labelstringDisplay label for templates and mapping UI
type'text' | 'number' | 'date' | 'choice' | 'boolean' | 'lookup'Field data type for parsing and editing
requiredbooleanWhether the field must have a value
choicesstring[]Valid values for choice fields
matchPatternsstring[]Alternative column names for auto-matching
examplestringExample value for template files

Props Reference

Core Props

Required props for configuring the import wizard.

PropTypeDefaultDescription
columnsImportColumn[]requiredArray of ImportColumn configurations
schemaz.ZodType<T>requiredZod schema for validating each row
onImport(data: T[]) => Promise<ImportResult>requiredCallback when import is confirmed
entityNamestring'items'Entity name for display (e.g., 'users', 'projects')

Options

Optional props for customizing behavior.

PropTypeDefaultDescription
batchMode'simple' | 'chunked''simple'Processing mode: 'simple' for <100 rows, 'chunked' for larger imports
chunkSizenumber50Number of rows per chunk when using chunked mode
titlestring-Custom modal title (overrides default)
descriptionstring-Modal description text

ImportButton Props

Props specific to the ImportButton companion component.

PropTypeDefaultDescription
variant'default' | 'outline' | 'ghost''outline'Button visual style
size'default' | 'sm' | 'lg''default'Button size
labelstring-Custom button label (defaults to 'Import')
disabledbooleanfalseDisable the button

Usage Pattern

Add ImportButton to your page toolbar to enable bulk import functionality alongside your data tables.

// In a page with AdminListTableBlock
import { AdminListTableBlock, ImportButton } from '@/ui/blocks';

<AdminListTableBlock
  items={items}
  columns={tableColumns}
  toolbar={{
    actions: [
      <ImportButton
        key="import"
        columns={importColumns}
        schema={itemSchema}
        entityName="items"
        onImport={handleBulkImport}
      />
    ]
  }}
/>