Illustrative example of putting it together: wrap with the Provider, use useImporter, register controllers, trigger the pipeline, and read status and result.
- Wrap your import UI with
ImporterProvider. - Call
useImporter({ layout, engine })to getprocessFile,registerValidator,registerSanitizer,registerTransform. - Register all your controller functions once (e.g. in
useEffect) so the layout ids resolve when the pipeline runs. - Trigger the pipeline by calling
processFile(file)when the user selects a file. The parser will run automatically (preview: first 10 rows). - Read status with
useImporterStatus()and result/errors withuseSheetData().
Note: The preview (first 10 rows) happens automatically when you call processFile(file). You only need useImportSheet() and startFullImport() if you want to parse the entire file after the user confirms the preview. For column alignment, call convert() from useConvert() after raw data is available — see how-to.md.
import {
ImporterProvider,
useImporter,
useImporterStatus,
useSheetData,
} from '@cristianm/react-import-sheet-headless';
import { useCallback, useEffect, useMemo } from 'react';
// LAYOUT: define as in layout.md
// trimCell, collapseSpaces: see sanitizers.md
// required, minLength: see validators.md
// toUpperCase, capitalize: see transforms.md
function ImportExampleInner() {
const { processFile, registerValidator, registerSanitizer, registerTransform } = useImporter({
layout: LAYOUT,
engine: 'auto',
});
useEffect(() => {
registerSanitizer('trim', trimCell, { type: 'cell' });
registerSanitizer('collapseSpaces', collapseSpaces, { type: 'cell' });
registerValidator('required', required, { type: 'cell' });
registerValidator('minLength', minLength, { type: 'cell' });
registerTransform('toUpperCase', toUpperCase, { type: 'cell' });
registerTransform('capitalize', capitalize, { type: 'cell' });
}, [registerSanitizer, registerValidator, registerTransform]);
const onFileChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) processFile(file);
},
[processFile]
);
const { status } = useImporterStatus();
const { sheet, errors } = useSheetData();
const summary = useMemo(() => {
if (!sheet) return null;
return {
headers: sheet.headers,
rowCount: sheet.rows.length,
errorCount: errors?.length ?? 0,
};
}, [sheet, errors]);
return (
<div>
<input
type="file"
accept=".csv,.xlsx,.xls,.ods"
onChange={onFileChange}
aria-label="Select file"
/>
<p>Status: {status}</p>
{summary && <pre>{JSON.stringify(summary, null, 2)}</pre>}
</div>
);
}
export function ImportExample() {
return (
<ImporterProvider>
<ImportExampleInner />
</ImporterProvider>
);
}| Step | Hook / API |
|---|---|
| Provider | ImporterProvider |
| Entry | useImporter({ layout, engine }) → processFile, register APIs |
| Register | registerSanitizer, registerValidator, registerTransform in useEffect |
| Status | useImporterStatus() → status |
| Result | useSheetData() → sheet, errors |
For progress UI (phase, percent, bar), see Progress. For layout and controller definitions, see Layout, Sanitizers, Validators, Transforms.