* feat: support custom starting line number in code blocks
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#287
* fix: lint errors — use literal keys, hoist regex, sort imports
* feat: allow customizing icons via icons prop
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#412
* style: fix biome lint and formatting errors
* Merge branch 'main' into feat/custom-icons
* fix: review fixes for icons and startLine features
- 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>
---------
Co-authored-by: Dmitrii Troitskii <jsleitor@gmail.com>
Co-authored-by: Hayden Bleasel <hello@haydenbleasel.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Plugin trial
* Update docs and tests
* Update homepage add new section
* Update usage.tsx
* Split out CJK plugin
* Extract plugins into new packages
* Misc fixes
* Fix lint / formatting
* Fix: The Streamdown component's memo comparison doesn't compare the plugins prop, preventing re-renders when plugins change while other props stay the same
Co-authored-by: haydenbleasel <hello@haydenbleasel.com>
* Fix: TypeScript type mismatch at line 89 in `index.ts`: the visitor function's `index` parameter is typed as `number | undefined`, but the `visit` function expects `number | null`. The `undefined` type is not assignable to `number | null`.
This commit fixes the issue reported at /vercel/path0/packages/streamdown-cjk/index.ts:89
## TypeScript type incompatibility in visitor callback
**What fails:** TypeScript compiler fails during DTS (type definitions) build in `packages/streamdown-cjk/index.ts` at line 89
**How to reproduce:**
```bash
cd packages/streamdown-cjk
pnpm build
```
**Result:**
```
index.ts(89,3): error TS2769: No overload matches this call.
Overload 1 of 2, '(tree: Root, check: "link", visitor: BuildVisitor<Root, "link">, reverse?: boolean | null | undefined): undefined', gave the following error.
Argument of type '(node: Link, index: number | null, parent?: Parent) => number | undefined' is not assignable to parameter of type 'BuildVisitor<Root, "link">'.
Types of parameters 'index' and 'index' are incompatible.
Type 'number | undefined' is not assignable to type 'number | null'.
Type 'undefined' is not assignable to type 'number | null'.
```
**Root cause:** The visitor callback function passed to the `visit()` function from `unist-util-visit` was declaring the `index` parameter as `number | null`, but the visitor can also receive `undefined` as the index value. The `BuildVisitor` type signature expects the callback to accept `number | null | undefined` to properly match the library's API.
**Fix:** Updated the `index` parameter type annotation on line 89 from `number | null` to `number | null | undefined` to match the actual possible values that the visitor receives and the expected `BuildVisitor` type signature.
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: haydenbleasel <hello@haydenbleasel.com>
* Fix tests
* Remove CDN paths
* Fix tests
* More cleanup
* Remove shiki from main bundle
* Update index.ts
* Cleanup test repo
* Cleanup website
* Delete next-env files
* Update .gitignore
* Fix lockfile
* Upgrade Next and React
* Simplify themes
* Update test site
* Misc fixes
* Type fixes
* Create perky-cobras-punch.md
---------
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>