Express CSV Logo

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

VariableDefault (light)
radius0.625rem
backgroundoklch(1 0 0)
foregroundoklch(0.145 0 0)
cardoklch(1 0 0)
card-foregroundoklch(0.145 0 0)
popoveroklch(1 0 0)
popover-foregroundoklch(0.145 0 0)
primaryoklch(0.205 0 0)
primary-foregroundoklch(0.985 0 0)
secondaryoklch(0.97 0 0)
secondary-foregroundoklch(0.205 0 0)
mutedoklch(0.97 0 0)
muted-foregroundoklch(0.556 0 0)
accentoklch(0.7 0.2 145)
accent-foregroundoklch(0.985 0 0)
destructiveoklch(0.577 0.245 27.325)
destructive-foregroundoklch(0.985 0 0)
successoklch(0.7 0.2 145)
success-foregroundoklch(0.985 0 0)
warningoklch(0.769 0.188 70)
warning-foregroundoklch(0.985 0 0)
borderoklch(0.922 0 0)
inputoklch(0.922 0 0)
ringoklch(0.708 0 0)
font-titleinherit
font-bodyinherit

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
});

On this page