Skip to content

feat(table): configure csvSeparator through controls - #524

Merged
farnabaz merged 1 commit into
vercel:mainfrom
aradhyacp:enhance/csv-separator
Aug 24, 2026
Merged

feat(table): configure csvSeparator through controls#524
farnabaz merged 1 commit into
vercel:mainfrom
aradhyacp:enhance/csv-separator

Conversation

@aradhyacp

@aradhyacp aradhyacp commented May 19, 2026

Copy link
Copy Markdown
Contributor

Description

This PR is a follow-up to #524, which added configurable CSV separators and locale-aware "auto" detection.

The CSV conversion work from #524 is already implemented and remains unchanged. This PR fixes where csvSeparator is exposed and configured.

The initial implementation added csvSeparator as a prop on TableCopyDropdown, TableDownloadDropdown, and TableDownloadButton. After discussion in #559, we decided that csvSeparator should be configured through the existing controls.table configuration instead.

The new API is:

<Streamdown
  controls={{
    table: {
      download: true,
      csvSeparator: "auto",
    },
  }}
>
  {markdown}
</Streamdown>

This provides a single configuration for both CSV copy and CSV download actions and allows the built-in table controls to consume the setting through StreamdownContext.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature which would cause existing functionality to not work as expected)
  • Documentation update
  • Performance improvement
  • Refactoring (no functional changes)

Related Issues

Fixes #521
Closes #521
Related to #521

Related PRs:

Changes Made

  • Added csvSeparator?: CSVSeparator to controls.table.
  • Updated TableCopyDropdown to read csvSeparator from StreamdownContext.
  • Updated TableDownloadDropdown and TableDownloadButton to read csvSeparator from StreamdownContext.
  • Removed the component-level csvSeparator props.
  • Added shared configuration resolution for controls.table.csvSeparator.
  • Preserved the existing tableDataToCSV implementation and separator handling from feat(table): configure csvSeparator through controls #524.
  • Preserved support for ",", ";", "\t", and "auto".
  • Preserved comma-separated output as the default when csvSeparator is not configured.
  • Added test coverage for configuring the separator through controls.
  • Updated documentation to use controls.table.csvSeparator.

API

CSV separator configuration is now controlled through controls.table:

<Streamdown
  controls={{
    table: {
      csvSeparator: "auto",
    },
  }}
>
  {markdown}
</Streamdown>

Supported values:

  • "," — comma
  • ";" — semicolon
  • "\t" — tab
  • "auto" — locale-aware separator selection

The default remains ",".

The lower-level tableDataToCSV utility continues to accept an explicit separator:

tableDataToCSV(data, "auto");

This remains available for custom extraction and conversion implementations.

Testing

  • All existing tests pass
  • Added new tests for the changes
  • Manually tested the changes

Test Coverage

Added test coverage to verify that csvSeparator is correctly read from controls.table for both CSV copy and CSV download.

Also manually verified the feature using the following Streamdown configuration:

import { Streamdown } from "streamdown";
import "streamdown/styles.css";

const App = () => {
  const markdown = `
| Feature | Status | Notes |
|:--------|:------:|------:|
| Markdown | Supported | CommonMark compliant |
| GFM | Supported | Tables, tasks, strikethrough |
| Code highlighting | Supported | 200+ languages via Shiki |
| Math | Supported | KaTeX rendering |
| Mermaid | Supported | Flowcharts, sequences, and more |
| CJK | Supported | Chinese, Japanese, Korean |
`;

  return (
    <div className="App">
      <div className="mx-auto mt-5 w-200">
        <Streamdown
          controls={{
            code: {
              download: true,
            },
            mermaid: {
              download: true,
            },
            table: {
              download: true,
              csvSeparator: "auto",
            },
          }}
        >
          {markdown}
        </Streamdown>
      </div>
    </div>
  );
};

export default App;

Verified that the table CSV actions use the configured separator when csvSeparator is set through controls.table.

Additional Test Coverage

  • Semicolon separator through controls.table.csvSeparator
  • "auto" separator through controls.table.csvSeparator
  • CSV copy uses the configured separator
  • CSV download uses the configured separator
  • Default comma behavior remains unchanged
  • Existing utility tests continue to cover separator handling and CSV escaping

Screenshots/Demos

Checklist

  • My code follows the project's code style
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings or errors
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have created a changeset (pnpm changeset)

Changeset

  • I have created a changeset for this PR

Additional Notes

The CSV conversion implementation from #524 is intentionally unchanged. This PR only changes how Streamdown users configure and consume the existing functionality.

The component-level API:

<TableCopyDropdown csvSeparator="auto" />
<TableDownloadDropdown csvSeparator=";" />
<TableDownloadButton format="csv" csvSeparator="\t" />

has been replaced with the table-level configuration:

<Streamdown
  controls={{
    table: {
      csvSeparator: "auto",
    },
  }}
>
  {markdown}
</Streamdown>

This keeps csvSeparator as a single table-level setting shared by both copy and download actions while retaining the existing lower-level tableDataToCSV(data, separator) API.

@vercel

vercel Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

@aradhyacp is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

@aradhyacp aradhyacp changed the title Enhance CSV export with configurable separator support and tests enhance(table): configure csvSeparator through controls Aug 22, 2026
@aradhyacp

Copy link
Copy Markdown
Contributor Author

@farnabaz I’ve made the changes as we discussed csvSeparator is now configured through controls.table rather than at the component level.

Thanks for pointing this out. This type of configuration makes a lot more sense for Streamdown and is much more useful than having it as a component-level prop.

Please let me know if any further changes are required. Thanks again 🤗

@farnabaz farnabaz added the minor label Aug 24, 2026
@farnabaz farnabaz changed the title enhance(table): configure csvSeparator through controls feat(table): configure csvSeparator through controls Aug 24, 2026
Add controls.table.csvSeparator (",", ";", "\t", "auto") so table CSV
copy and download share one locale-friendly setting, and make
tableDataToCSV escape against the resolved delimiter.

Co-authored-by: aradhyacp <cparadhya@proton.me>

@farnabaz farnabaz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍
Thanks

@farnabaz
farnabaz merged commit 4436b56 into vercel:main Aug 24, 2026
7 checks passed
lofcz added a commit to lofcz/streamdown-ng that referenced this pull request Aug 24, 2026
Keep the fork's animation timeline, animateCodeBlocks path, and ControlsConfig in streamdown-context. Take unique upstream bits: inline-code animation (vercel#595), configurable download filenames (vercel#559), and table csvSeparator (vercel#524).

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Configurable CSV separator for Excel locale compatibility

2 participants