Styling
All styling options are passed to useExpressCSV().
Theme
Override CSS variables to match your app's design system. Pass a flat object for a single theme, or use modes to provide separate light and dark values.
Single Theme
Applies to both light and dark mode:
import { useExpressCSV, x, type ECSVTheme } from "@expresscsv/react";
const theme: ECSVTheme = {
primary: "#4F46E5",
"primary-foreground": "#ffffff",
background: "#ffffff",
foreground: "#0f172a",
border: "#e5e7eb",
ring: "#A5B4FC",
radius: "0.5rem",
};
const { open } = useExpressCSV({
schema,
publishableKey: "pk_test_...", // Your ExpressCSV publishable key
importIdentifier: "user-import", // Ties this config to a specific import flow
theme, // Applies these design tokens to the widget
});Dual-Mode Theme
Provide separate values for light and dark:
const theme: ECSVTheme = {
modes: {
light: {
primary: "#4F46E5",
background: "#ffffff",
foreground: "#0f172a",
},
dark: {
primary: "#a5b4fc",
background: "#09090b",
foreground: "#fafafa",
},
},
};Theme Variables
| Variable | Default (light) |
|---|---|
radius | 0.625rem |
background | oklch(1 0 0) |
foreground | oklch(0.145 0 0) |
card | oklch(1 0 0) |
card-foreground | oklch(0.145 0 0) |
popover | oklch(1 0 0) |
popover-foreground | oklch(0.145 0 0) |
primary | oklch(0.205 0 0) |
primary-foreground | oklch(0.985 0 0) |
secondary | oklch(0.97 0 0) |
secondary-foreground | oklch(0.205 0 0) |
muted | oklch(0.97 0 0) |
muted-foreground | oklch(0.556 0 0) |
accent | oklch(0.7 0.2 145) |
accent-foreground | oklch(0.985 0 0) |
destructive | oklch(0.577 0.245 27.325) |
destructive-foreground | oklch(0.985 0 0) |
success | oklch(0.7 0.2 145) |
success-foreground | oklch(0.985 0 0) |
warning | oklch(0.769 0.188 70) |
warning-foreground | oklch(0.985 0 0) |
border | oklch(0.922 0 0) |
input | oklch(0.922 0 0) |
ring | oklch(0.708 0 0) |
font-title | inherit |
font-body | inherit |
Color Mode
Control light/dark mode with colorMode:
const { open } = useExpressCSV({
schema,
publishableKey: "pk_test_...", // Your ExpressCSV publishable key
importIdentifier: "user-import", // Ties this config to a specific import flow
colorMode: "system", // Match the user's OS or app color preference
});Custom CSS
Every element in the widget is stylable. Open your browser inspector and look for ecsv-... class names on the element you want to target.
Class names shown before the 🔒 marker are public and safe to style. Everything after 🔒 is a private implementation detail and may change between versions.
Your customCSS is automatically scoped to the widget, so you can target public classes directly:
const { open } = useExpressCSV({
schema,
publishableKey: "pk_test_...", // Your ExpressCSV publishable key
importIdentifier: "user-import", // Ties this config to a specific import flow
customCSS: `
.ecsv-step-upload {
padding: 1.5rem;
}
.ecsv-card {
border-radius: 1rem;
}
.ecsv-button {
font-weight: 600;
border-radius: 9999px;
}
`,
});Custom Fonts
Load fonts from Google Fonts or a custom URL, then reference them in your theme:
const { open } = useExpressCSV({
schema,
publishableKey: "pk_test_...", // Your ExpressCSV publishable key
importIdentifier: "user-import", // Ties this config to a specific import flow
fonts: {
title: { source: "google", name: "Space Grotesk", weights: [400, 600, 700] }, // Load the heading font from Google Fonts
body: { source: "custom", url: "https://example.com/font.woff2", format: "woff2" }, // Load your body font from a hosted asset
},
theme: {
"font-title": "'Space Grotesk', sans-serif", // Use the loaded title font in the widget
"font-body": "'Custom Font', sans-serif", // Use the loaded body font in the widget
},
});Step Display
Control how the wizard progress indicator looks:
const { open } = useExpressCSV({
schema,
publishableKey: "pk_test_...", // Your ExpressCSV publishable key
importIdentifier: "user-import", // Ties this config to a specific import flow
stepDisplay: "segmented", // Show progress as labeled steps instead of a bar
});Template Downloads
Let users download a pre-filled template before uploading:
const { open } = useExpressCSV({
schema,
publishableKey: "pk_test_...", // Your ExpressCSV publishable key
importIdentifier: "user-import", // Ties this config to a specific import flow
templateDownload: {
source: "generate", // Build the template from your schema automatically
formats: ["csv", "xlsx"], // Offer both spreadsheet formats to the user
},
});The template is auto-generated from your schema with column headers and example values.
Schema Preview
By default, users see a preview of the expected columns before uploading. To skip it:
const { open } = useExpressCSV({
schema,
publishableKey: "pk_test_...", // Your ExpressCSV publishable key
importIdentifier: "user-import", // Ties this config to a specific import flow
previewSchemaBeforeUpload: false, // Skip the column preview and go straight to upload
});Session Persistence
Enable saveSession to let users resume interrupted imports. When a user returns, they can pick up where they left off instead of starting over.
const { open } = useExpressCSV({
schema,
publishableKey: "pk_test_...", // Your ExpressCSV publishable key
importIdentifier: "user-import", // Ties this config to a specific import flow
saveSession: true, // Lets users resume an unfinished import later
});