Skip to content

Commit aa472de

Browse files
feat: add data attributes to markdown components (vercel#48)
* Add data-streamdown attributes to components Added data-streamdown attributes to various rendered components for improved DOM identification and targeting. This enhances testability and integration with other tools that rely on custom data attributes. * Create little-buses-lick.md * Update verify-changesets.yml
1 parent e94154f commit aa472de

File tree

3 files changed

+88
-16
lines changed

3 files changed

+88
-16
lines changed

.changeset/little-buses-lick.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"streamdown": patch
3+
---
4+
5+
Add data-streamdown attributes to components

.github/workflows/verify-changesets.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
id: generate-token
2626
uses: actions/create-github-app-token@v1
2727
with:
28-
app-id: ${{ vars.STREAMDOWN_APP_ID }}
28+
app-id: ${{ secrets.STREAMDOWN_APP_ID }}
2929
private-key: ${{ secrets.STREAMDOWN_APP_PRIVATE_KEY }}
3030

3131
- uses: actions/checkout@v4

packages/streamdown/lib/components.tsx

Lines changed: 82 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const CodeComponent = ({
2323
if (inline) {
2424
return (
2525
<code
26+
data-streamdown="inline-code"
2627
className={cn(
2728
'rounded bg-muted px-1.5 py-0.5 font-mono text-sm',
2829
className
@@ -62,6 +63,7 @@ const CodeComponent = ({
6263
if (isMermaid) {
6364
return (
6465
<div
66+
data-streamdown="mermaid-block"
6567
className={cn(
6668
'group relative my-4 h-auto rounded-lg border p-4',
6769
className
@@ -75,6 +77,8 @@ const CodeComponent = ({
7577

7678
return (
7779
<CodeBlock
80+
data-streamdown="code-block"
81+
data-language={language}
7882
className={cn('my-4 h-auto rounded-lg border p-4', className)}
7983
code={code}
8084
language={language}
@@ -86,30 +90,51 @@ const CodeComponent = ({
8690

8791
export const components: Options['components'] = {
8892
ol: ({ node, children, className, ...props }) => (
89-
<ol className={cn('ml-4 list-outside list-decimal', className)} {...props}>
93+
<ol
94+
data-streamdown="ordered-list"
95+
className={cn('ml-4 list-outside list-decimal', className)}
96+
{...props}
97+
>
9098
{children}
9199
</ol>
92100
),
93101
li: ({ node, children, className, ...props }) => (
94-
<li className={cn('py-1', className)} {...props}>
102+
<li
103+
data-streamdown="list-item"
104+
className={cn('py-1', className)}
105+
{...props}
106+
>
95107
{children}
96108
</li>
97109
),
98110
ul: ({ node, children, className, ...props }) => (
99-
<ul className={cn('ml-4 list-outside list-disc', className)} {...props}>
111+
<ul
112+
data-streamdown="unordered-list"
113+
className={cn('ml-4 list-outside list-disc', className)}
114+
{...props}
115+
>
100116
{children}
101117
</ul>
102118
),
103119
hr: ({ node, className, ...props }) => (
104-
<hr className={cn('my-6 border-border', className)} {...props} />
120+
<hr
121+
data-streamdown="horizontal-rule"
122+
className={cn('my-6 border-border', className)}
123+
{...props}
124+
/>
105125
),
106126
strong: ({ node, children, className, ...props }) => (
107-
<span className={cn('font-semibold', className)} {...props}>
127+
<span
128+
data-streamdown="strong"
129+
className={cn('font-semibold', className)}
130+
{...props}
131+
>
108132
{children}
109133
</span>
110134
),
111135
a: ({ node, children, className, href, ...props }) => (
112136
<a
137+
data-streamdown="link"
113138
className={cn('font-medium text-primary underline', className)}
114139
href={href}
115140
rel="noreferrer"
@@ -121,6 +146,7 @@ export const components: Options['components'] = {
121146
),
122147
h1: ({ node, children, className, ...props }) => (
123148
<h1
149+
data-streamdown="heading-1"
124150
className={cn('mt-6 mb-2 font-semibold text-3xl', className)}
125151
{...props}
126152
>
@@ -129,38 +155,53 @@ export const components: Options['components'] = {
129155
),
130156
h2: ({ node, children, className, ...props }) => (
131157
<h2
158+
data-streamdown="heading-2"
132159
className={cn('mt-6 mb-2 font-semibold text-2xl', className)}
133160
{...props}
134161
>
135162
{children}
136163
</h2>
137164
),
138165
h3: ({ node, children, className, ...props }) => (
139-
<h3 className={cn('mt-6 mb-2 font-semibold text-xl', className)} {...props}>
166+
<h3
167+
data-streamdown="heading-3"
168+
className={cn('mt-6 mb-2 font-semibold text-xl', className)}
169+
{...props}
170+
>
140171
{children}
141172
</h3>
142173
),
143174
h4: ({ node, children, className, ...props }) => (
144-
<h4 className={cn('mt-6 mb-2 font-semibold text-lg', className)} {...props}>
175+
<h4
176+
data-streamdown="heading-4"
177+
className={cn('mt-6 mb-2 font-semibold text-lg', className)}
178+
{...props}
179+
>
145180
{children}
146181
</h4>
147182
),
148183
h5: ({ node, children, className, ...props }) => (
149184
<h5
185+
data-streamdown="heading-5"
150186
className={cn('mt-6 mb-2 font-semibold text-base', className)}
151187
{...props}
152188
>
153189
{children}
154190
</h5>
155191
),
156192
h6: ({ node, children, className, ...props }) => (
157-
<h6 className={cn('mt-6 mb-2 font-semibold text-sm', className)} {...props}>
193+
<h6
194+
data-streamdown="heading-6"
195+
className={cn('mt-6 mb-2 font-semibold text-sm', className)}
196+
{...props}
197+
>
158198
{children}
159199
</h6>
160200
),
161201
table: ({ node, children, className, ...props }) => (
162-
<div className="my-4 overflow-x-auto">
202+
<div data-streamdown="table-wrapper" className="my-4 overflow-x-auto">
163203
<table
204+
data-streamdown="table"
164205
className={cn('w-full border-collapse border border-border', className)}
165206
{...props}
166207
>
@@ -169,35 +210,53 @@ export const components: Options['components'] = {
169210
</div>
170211
),
171212
thead: ({ node, children, className, ...props }) => (
172-
<thead className={cn('bg-muted/50', className)} {...props}>
213+
<thead
214+
data-streamdown="table-header"
215+
className={cn('bg-muted/50', className)}
216+
{...props}
217+
>
173218
{children}
174219
</thead>
175220
),
176221
tbody: ({ node, children, className, ...props }) => (
177-
<tbody className={cn('divide-y divide-border', className)} {...props}>
222+
<tbody
223+
data-streamdown="table-body"
224+
className={cn('divide-y divide-border', className)}
225+
{...props}
226+
>
178227
{children}
179228
</tbody>
180229
),
181230
tr: ({ node, children, className, ...props }) => (
182-
<tr className={cn('border-border border-b', className)} {...props}>
231+
<tr
232+
data-streamdown="table-row"
233+
className={cn('border-border border-b', className)}
234+
{...props}
235+
>
183236
{children}
184237
</tr>
185238
),
186239
th: ({ node, children, className, ...props }) => (
187240
<th
241+
data-streamdown="table-header-cell"
188242
className={cn('px-4 py-2 text-left font-semibold text-sm', className)}
189243
{...props}
190244
>
191245
{children}
192246
</th>
193247
),
194248
td: ({ node, children, className, ...props }) => (
195-
<td className={cn('px-4 py-2 text-sm', className)} {...props}>
249+
<td
250+
data-streamdown="table-cell"
251+
className={cn('px-4 py-2 text-sm', className)}
252+
{...props}
253+
>
196254
{children}
197255
</td>
198256
),
199257
blockquote: ({ node, children, className, ...props }) => (
200258
<blockquote
259+
data-streamdown="blockquote"
201260
className={cn(
202261
'my-4 border-muted-foreground/30 border-l-4 pl-4 text-muted-foreground italic',
203262
className
@@ -210,12 +269,20 @@ export const components: Options['components'] = {
210269
code: CodeComponent,
211270
pre: ({ children }) => children,
212271
sup: ({ node, children, className, ...props }) => (
213-
<sup className={cn('text-sm', className)} {...props}>
272+
<sup
273+
data-streamdown="superscript"
274+
className={cn('text-sm', className)}
275+
{...props}
276+
>
214277
{children}
215278
</sup>
216279
),
217280
sub: ({ node, children, className, ...props }) => (
218-
<sub className={cn('text-sm', className)} {...props}>
281+
<sub
282+
data-streamdown="subscript"
283+
className={cn('text-sm', className)}
284+
{...props}
285+
>
219286
{children}
220287
</sub>
221288
),

0 commit comments

Comments
 (0)