Commit Graph

7 Commits

Author SHA1 Message Date
Dmitrii 57cd3b5a07 feat: allow customizing icons via icons prop (#414)
* 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>
2026-03-03 15:04:26 -08:00
Hayden Bleasel 1102f1855e Fix all Biome lint and formatting errors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 20:57:01 -08:00
Hayden Bleasel 9ef44f7a05 streamdown: 100% line coverage (778 tests)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 20:11:56 -08:00
Alex Supkay 6bb03caf80 fix: escape HTML when rehype-raw is omitted (#330) (#331)
* fix: escape HTML when rehype-raw is omitted (#330)

* chore: add changeset
2026-01-20 14:29:05 -08:00
Hayden Bleasel 0b80aed583 Switch to plugin architecture (#352)
* 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>
2026-01-17 14:38:20 -08:00
Hayden Bleasel 2509917b77 Run Ultracite 2026-01-09 14:24:07 -08:00
xxchan 48c9c51f07 fix: split autolinks at CJK punctuation (#327)
* fix: split autolinks at CJK punctuation

* chore: clarify CJK autolink boundary
2026-01-05 09:42:06 -08:00