Skip to content

feat: allow customizing icons via icons prop#414

Merged
haydenbleasel merged 7 commits intovercel:mainfrom
sleitor:feat/custom-icons
Mar 3, 2026
Merged

feat: allow customizing icons via icons prop#414
haydenbleasel merged 7 commits intovercel:mainfrom
sleitor:feat/custom-icons

Conversation

@sleitor
Copy link
Contributor

@sleitor sleitor commented Feb 21, 2026

Summary

Two features in one PR:

  1. Custom icons — override any built-in icon (copy, download, zoom, etc.) via a new icons prop on <Streamdown>
  2. Custom starting line numbers — specify a starting line number in code fences via startLine=N meta string

Custom icons

New icons prop accepts a Partial<IconMap> — unspecified icons fall back to defaults.

import { Streamdown, type IconMap } from "streamdown";

const MyCheckIcon = (props) => <svg {...props}>...</svg>;

<Streamdown icons={{ CheckIcon: MyCheckIcon }}>
  {content}
</Streamdown>

Changes

  • New lib/icon-context.tsx with IconMap type, IconProvider, and useIcons() hook
  • All sub-components updated to consume icons via useIcons() instead of direct imports
  • IconMap type exported from package entry
  • Follows the existing components prop pattern using React context

Custom starting line numbers

Code blocks can specify a starting line number in the meta string:

```js startLine=10
const x = 1;
```

Changes

  • New remarkCodeMeta remark plugin that forwards fenced-code meta strings to hast
  • metastring attribute allowed through rehype-sanitize
  • startLine=N parsed in CodeComponent and passed down as a prop
  • CodeBlockBody applies counter-reset: line N-1 as an inline style
  • Includes bounds checking (values < 1 are ignored)

Closes #412, closes #287

Dmitrii Troitskii added 3 commits February 19, 2026 22:39
Add support for specifying a custom starting line number via the code
fence meta string, e.g.:

```js startLine=10
const x = 1;
```

Implementation:
- Add `remarkCodeMeta` remark plugin that forwards the fenced-code meta
  string to hast as the `metastring` property so it is available to the
  custom React code component.
- Update the rehype-sanitize default schema to allow the `metastring`
  attribute on `code` elements.
- Parse `startLine=N` from the meta string in `CodeComponent` and pass
  the value down as a `startLine` prop.
- In `CodeBlockBody`, apply `counter-reset: line N-1` as an inline style
  when `startLine > 1`, which overrides the Tailwind counter-reset class
  and makes CSS counters begin from the specified number.
- Pass `startLine` through the `CodeBlock` and
  `HighlightedCodeBlockBody` call chains.
- Add 12 tests covering the remark plugin, CodeBlockBody prop, and
  CodeBlock integration.

Closes: resolves vercel#287
Add an IconContext-based system that lets users override any of the
built-in icons (CheckIcon, CopyIcon, DownloadIcon, etc.) by passing
a Partial<IconMap> via the new `icons` prop on <Streamdown>.

- Created lib/icon-context.tsx with IconMap type, IconProvider, and useIcons hook
- Updated all sub-components to consume icons via useIcons() instead of direct imports
- Added icons prop to StreamdownProps with IconProvider wrapper
- Exported IconMap type from package entry

Closes vercel#412
@vercel
Copy link
Contributor

vercel bot commented Feb 21, 2026

Someone is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

Dmitrii Troitskii and others added 4 commits February 21, 2026 14:27
- Add missing changeset for icons feature (minor)
- Fix IconComponent type to include size prop matching actual usage
- Fix IconProvider memoization: use shallow comparison instead of
  referential equality so inline icon objects don't cause re-renders
- Move START_LINE_PATTERN constant below all imports
- Add bounds checking for startLine (must be >= 1)
- Convert dynamic imports to top-level imports in startLine tests
- Add icon-context tests (5 tests)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@haydenbleasel
Copy link
Member

thank you @sleitor 🙏

@haydenbleasel haydenbleasel merged commit 57cd3b5 into vercel:main Mar 3, 2026
2 of 5 checks passed
@sleitor sleitor deleted the feat/custom-icons branch March 4, 2026 01:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow customizing icons Feature: Support custom starting line number for codeblocks (e.g., start from line 10)

2 participants