Skip to content

Inputs

Export Menu

An Export button with a CSV and JSON menu that builds and downloads the file in the browser.

<script>
  import { ExportMenu } from "@codeatlasdev/ui";
</script>

<ExportMenu data={rows} filename="domains" />

ExportMenu is a DropdownMenu with CSV and JSON items. Choosing one builds the file from data, downloads it and announces “Exported 3 rows as CSV” politely. It is disabled while data is empty. Pass all rows, not only the visible page.

CSV is RFC 4180 (CRLF, quoted fields) with a UTF-8 BOM in the downloaded file so Excel reads accents correctly. Text cells that start with =, +, - or @ get a leading ' so a spreadsheet never runs them as a formula (CSV injection). Numbers are left as they are.

#019

Default

Custom column order and headers. onexport receives the generated text, handy for tests or uploads.

Pick a format to download.

Reference #019 · Pick in the gallery

Code
svelte
<script lang="ts">
  import { ExportMenu } from '@codeatlasdev/ui';

  const rows = [
    { domain: 'atlas.dev', price: 12, available: true },
    { domain: 'nimbus.io', price: 38, available: false },
    { domain: 'orbit.app', price: 21, available: true },
  ];
  let last = $state('');
</script>

<div class="wrap">
  <ExportMenu
    data={rows}
    filename="domains"
    columns={[{ key: 'domain', header: 'Domain' }, { key: 'price', header: 'Price (USD)' }, { key: 'available', header: 'Available' }]}
    onexport={(e) => (last = `${e.filename}: ${e.rows} rows`)}
  />
  <p class="last" aria-live="off">{last || 'Pick a format to download.'}</p>
</div>

<style>
  .wrap { display: flex; align-items: center; gap: var(--ca-space-3); flex-wrap: wrap; }
  .last { margin: 0; color: var(--ca-text-secondary); font-size: var(--ca-font-size-body2); }
</style>

Helpers

The same logic is exported for custom UI:

import { toCsv, toJson, downloadFile } from "@codeatlasdev/ui";

downloadFile("domains.csv", toCsv(rows, columns), "text/csv;charset=utf-8");

Props

PropTypeDefaultDescription
datareadonly T[]–Rows to export.
filenamestring'export'File name without extension.
columnsExportColumn<T>[]–`{ key, header?, value? }` per column: header defaults to key, value overrides row[key]. Defaults to the keys of the first row.
formats('csv' | 'json')[]['csv', 'json']Formats offered, in menu order.
labelstring'Export' (localized)Button label.
variant'filled' | 'glass' | 'outlined' | 'ghost''outlined'Button variant.
size'sm' | 'md' | 'lg''md'Button size.
disabledbooleanfalseDisables the button.
onexport(e: { format, filename, content, rows }) => void–Called after each export with the generated text.
classstring''Extra class on the menu content.