# Vector Import Flow

Vector Import Flow [#vector-import-flow]

The **Vector Import Flow** wraps `useImportExport`: a preview panel (detected-format badge, total / with-vectors / text-only counts, detected dimensions, dimension-mismatch warning, Cancel/Confirm), a phased progress bar (parsing → validating → embedding → importing), a result stats banner (imported / skipped / re-embedded, format, duration), and a record-preview table for row-level sanity checks before a destructive ingest. It references the cross-family `FormatDetectionBadge` and inlines a minimal fallback so it builds independently.

Preview [#preview]

```tsx
'use client';

import { useState } from 'react';

import { VectorImportFlow, type ImportStatsLike } from '@/components/vector-import-flow';

const RESULT: ImportStatsLike = {
  imported: 980,
  skipped: 12,
  reEmbedded: 8,
  totalParsed: 1000,
  format: 'pinecone',
  durationMs: 4200,
};

/**
 * Demo for VectorImportFlow. Shows the pre-import preview panel with a
 * record-preview table, then a result banner on Confirm. Wire preview/progress/
 * stats to useImportExport in your app.
 */
export default function VectorImportFlowDemo() {
  const [done, setDone] = useState(false);

  return (
    <VectorImportFlow
      preview={{
        format: 'pinecone',
        totalRecords: 1000,
        recordsWithVectors: 992,
        recordsWithTextOnly: 8,
        dimensions: 384,
      }}
      targetDimensions={384}
      records={[
        { id: 'doc-1', text: 'Local-first AI runs in the browser.', hasVector: true },
        { id: 'doc-2', text: 'No servers, no API keys.', hasVector: true },
        { id: 'doc-3', text: 'Re-embed on import.', hasVector: false },
      ]}
      stats={done ? RESULT : null}
      onConfirm={() => setDone(true)}
      onCancel={() => setDone(false)}
    />
  );
}
```

Installation [#installation]

```bash
npx shadcn@latest add @localmode/ui/local-first/vector-import-flow
```

Data source & dependencies [#data-source--dependencies]

**Data source:** renders the import preview/progress/result you pass and emits Cancel/Confirm — works with any backend. Recommended producer: `useImportExport` (backed by the import/export parsers) from `@localmode/react` (on-device, optional).

* `lucide-react` — icons
* `clsx` + `tailwind-merge` — via the shared `cn()` util (installed automatically as a registry dependency)

Registry dependencies [#registry-dependencies]

* `@localmode/ui/data-documents/format-detection-badge` — the shared format badge (a minimal inline fallback ships with this item)

Files installed [#files-installed]

* `vector-import-flow.tsx` — the `VectorImportFlow` component
* `lib/utils.ts` — the `cn()` helper (if not already present)

Props [#props]

**VectorImportFlow**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `preview` | `object \| null` | — | Parse preview shown before a destructive import. |
| `targetDimensions` | `number` | — | Target VectorDB dimensions (for the mismatch warning). |
| `records` | `array` | — | Sample records for the preview table. |
| `progress` | `object \| null` | — | Live import progress. |
| `stats` | `object \| null` | — | Final import stats (shown when the import completes). |
| `isImporting` | `boolean` | — | Whether an import is running. |
| `onConfirm` | `function` | — | Fired to confirm the import. |
| `onCancel` | `function` | — | Fired to cancel/dismiss the preview. |

**ImportPreview**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `format` | `ExternalFormat` | — | **Required.** |
| `totalRecords` | `number` | — | **Required.** |
| `recordsWithVectors` | `number` | — | **Required.** |
| `recordsWithTextOnly` | `number` | — | **Required.** |
| `dimensions` | `number \| null` | — | **Required.** |

Examples [#examples]

Preview then import [#preview-then-import]

```tsx
const { parseResult, progress, stats, parsePreview, importData } = useImportExport({ db, model });
<VectorImportFlow
  preview={parseResult}
  targetDimensions={db.dimensions}
  progress={progress}
  stats={stats}
  onConfirm={() => importData({ content })}
/>
```

Customization [#customization]

The dimension-mismatch warning compares `preview.dimensions` against `targetDimensions`. Swap the inline `FormatBadge` for the installed `@localmode/ui/data-documents/format-detection-badge` when present. Styled entirely with shadcn/ui CSS-variable utilities so it inherits your theme — because you own the copied file, every class and threshold is yours to change.