Search docs

Jump to any table example

Discord—

Export Configuration

Export through a dialog instead of a one-click download: pick which statuses, regions, and dates to include, choose columns and format, and see how many rows match before anything downloads.

$ npx shadcn add https://www.shad-table.dev/r/export-config-table.json

30 orders

OrderCustomerRegionStatusDateAmount
ORD-1025Lucas MartinAPACFailed2026-09-22$910.00
ORD-1028Sofia PatelLATAMRefunded2026-09-20$988.79
ORD-1006Liam ChenLATAMRefunded2026-09-16$46.58
ORD-1011Isabella RossiAPACRefunded2026-09-15$929.28
ORD-1012Mason LeeEUFailed2026-09-13$154.55
ORD-1013Ava ThompsonEUPending2026-09-10$619.68
ORD-1029Liam ChenAPACPending2026-09-04$406.76
ORD-1007Amelia NovakEUFailed2026-09-03$333.07

1–8 of 30

How it works

1.The export settings are one plain object

Statuses, regions, date range, columns, and format all live in a single ExportConfig held by the table component. The dialog only edits it, so the settings survive closing and reopening the dialog, and Reset is just setting it back to defaultExportConfig().

src/components/export-config/export-config.ts
export type ExportConfig = {
statuses: Order['status'][]
regions: Order['region'][]
datePreset: DatePreset
columns: string[]
format: ExportFormat
}

2.The live count and the file come from the same function

applyExportConfig() is the only place that decides which rows are exported. The "N of 30 rows" line in the dialog and the downloaded file both call it, so the number the user sees is always the number they get.

src/components/export-config/data-table.tsx
const matches = useMemo(
() => applyExportConfig(data, config, today),
[data, config, today],
)

3.Column choices come from the table, not a second list

The dialog's column checkboxes are built from table.getAllLeafColumns(), using each column's header as its label. Add a column to columns.tsx and it shows up in the export dialog automatically. Picked columns are kept in table order, whatever order they were ticked in.

src/components/export-config/data-table.tsx
const exportColumns = table.getAllLeafColumns().map((column) => ({
id: column.id,
label: typeof column.columnDef.header === 'string'
? column.columnDef.header
: column.id,
}))

4.Exports use raw values, not what the cell displays

The table renders amounts as "$129.50" and statuses as badges, but the file gets the underlying values (129.5, "Paid") so spreadsheets can sort and sum them. Export is disabled when nothing matches or no column is selected, so an empty file is never downloaded.

src/components/export-config/data-table.tsx
const rows = matches.map((order) =>
chosen.map((c) => String(order[c.id as keyof Order])),
)