A button that writes the rows the user sees into a CSV file for a spreadsheet (also called download or export to Excel). Hand the application the text instead where it wants the clipboard or a file of its own.
import { Export } from "@umriss-ui/table";
It writes the filtered set across all pages, in the visible columns, in the order and sorting on screen – and the values, not their presentation: numbers with the decimal mark of the formats, yes and no from the wording, a point in time as a timestamp, an absent value as an empty field. The separator follows the mark – a comma, or a semicolon where the mark is a comma – and a byte order mark tells the spreadsheet it is UTF-8. English gets commas and a point; the German wording and formats from @umriss-ui/core/wording/de get the file the table always wrote, and German wording with English formats gets German words with comma and point – take both halves (ADR-0061).
A verdict column exports its value, not the verdict. In server mode the table holds one page of the server's, so it exports that page, and the button says so. The same text is t.asCsv(), without a button.
Ctrl or Cmd with C copies the selected rows – the visible columns under a header line, tab-separated, with the same values and the formats' decimal mark – and in a grid with no selection the Active cell. What was copied flashes once in an accent tint (shown without the fade under reduced motion), and a screen reader is told how many rows were copied, or that the copy failed. Marked text and a focused field keep the browser's own copy; in an open cell editor with nothing marked the key copies the value that stands in the field. t.selectionAsText() is the same text for a button of your own, as in the last example.
Put an Export into the toolbar: the file holds what the user sees – the filtered, sorted rows of every page, in the visible columns.
import { Export, Search, Toolbar, useTable } from "@umriss-ui/table";
interface Shipment {
id: string;
customer: string;
parcels: number;
weight: number;
}
const SHIPMENTS: Shipment[] = [
{ id: "FP-1004210", customer: "Holloway Garden Supplies", parcels: 3, weight: 23.5 },
{ id: "FP-1004223", customer: "Northgate Florists", parcels: 6, weight: 41.25 },
{ id: "FP-1004236", customer: "Pellham Hardware", parcels: 1, weight: 4 },
{ id: "FP-1004249", customer: "Northbay Books", parcels: 2, weight: 18.4 },
];
export default function DownloadAFile() {
const { Table, Column } = useTable(SHIPMENTS, { rowKey: (s) => s.id });
return (
<Table ariaLabel="Shipments">
<Toolbar>
<Search placeholder="Search customer" />
<Export filename="shipments.csv" />
</Toolbar>
<Column value="id" label="Shipment" rowHeader />
<Column value="customer" label="Customer" />
<Column value="parcels" label="Parcels" />
<Column value="weight" label="Weight (kg)" format={{ decimals: 2 }} />
</Table>
);
}
Pass onExport to receive the CSV text instead of a download – for the clipboard or a service; values, not their presentation.
import { useState } from "react";
import { Stack, Text } from "@umriss-ui/core";
import { Export, Toolbar, useTable } from "@umriss-ui/table";
interface Shipment {
id: string;
weight: number;
delivered: Date | null;
signed: boolean;
}
const SHIPMENTS: Shipment[] = [
{ id: "FP-1004210", weight: 23.5, delivered: new Date(Date.UTC(2026, 2, 17, 8, 12)), signed: true },
{ id: "FP-1004223", weight: 14, delivered: null, signed: false },
];
export default function TakeTheText() {
const [text, setText] = useState("Not exported yet.");
const { Table, Column } = useTable(SHIPMENTS, { rowKey: (s) => s.id });
return (
<Stack gap={3}>
<Table ariaLabel="Shipments to export">
<Toolbar>
<Export onExport={setText} />
</Toolbar>
<Column value="id" label="Shipment" rowHeader />
<Column value="weight" label="Weight (kg)" />
<Column value="delivered" label="Delivered" format="dateTime" />
<Column value="signed" label="Signed" />
</Table>
<Text as="pre" size="xs" mono>
{text}
</Text>
</Stack>
);
}
Ctrl or Cmd with C copies the selected rows, tab-separated under a header line, and they flash once; selectionAsText() hands the same text to a button of your own.
import { Button, Stack, Text } from "@umriss-ui/core";
import { useTable } from "@umriss-ui/table";
interface Shipment {
id: string;
customer: string;
weight: number;
}
const SHIPMENTS: Shipment[] = [
{ id: "FP-1004210", customer: "Holloway Garden Supplies", weight: 23.5 },
{ id: "FP-1004223", customer: "Northgate Florists", weight: 41.25 },
{ id: "FP-1004236", customer: "Pellham Hardware", weight: 4 },
];
export default function CopyTheSelection() {
const t = useTable(SHIPMENTS, { rowKey: (s) => s.id });
const { Table, Column } = t;
return (
<Stack gap={3}>
<Stack direction="row" gap={2} align="center">
<Button size="sm" variant="secondary" onClick={() => void navigator.clipboard.writeText(t.selectionAsText())} disabled={t.selection.count === 0}>
Copy as table
</Button>
<Text size="xs" tone="muted">
{t.selection.count} selected
</Text>
</Stack>
<Table selectable ariaLabel="Shipments to copy">
<Column value="id" label="Shipment" rowHeader />
<Column value="customer" label="Customer" />
<Column value="weight" label="Weight (kg)" />
</Table>
</Stack>
);
}
The keys of First table, Input and Button apply here.
ExportProps| Name | Type | Default | Description |
|---|---|---|---|
filename | string | the wording's "table.csv" | File name of the download. Shown in: Download a file, Set wording and formats once (Provider), Search takes the line (Search) and 6 more |
size | ToolbarSize"sm" | "md" | the size of the toolbar it stands in, "sm" outside one | The size of the part: sm or md.Shown in: Parts outside a toolbar (Toolbar) |
of | TableRef | — | The table, when the part does not stand inside it: the return value of useTable.Shown in: Place it outside the table (Toolbar), Parts outside a toolbar (Toolbar), Review cost centres against budget (Scenarios) |
| Name | Type | Default | Description |
|---|---|---|---|
onExport | (text: string) => void | — | Gets the text instead of triggering a file. Shown in: Take the text, Sort and export a value that is an object (Sorting) |
ToolbarSizeThe size of a toolbar's controls.
type ToolbarSize = "sm" | "md";TableRefWhat a part without a row type needs from a table – for of.
type TableRef = Omit<TableSnapshot<unknown>, "setFilter" | "conditionOf"> & {
readonly Table: unknown;
/** Without a row kind: any id, any condition. */
setFilter(column: string, condition: unknown): void;
};What umriss deliberately does not build, and why: ADR-0032.