svelte-streamdown 1.0.8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +155 -140
  2. package/dist/Block.svelte +17 -41
  3. package/dist/Elements/Alert.svelte +1 -2
  4. package/dist/Elements/Code.svelte +3 -5
  5. package/dist/Elements/Code.svelte.d.ts +0 -2
  6. package/dist/Elements/Element.svelte +170 -42
  7. package/dist/Elements/FootnoteRef.svelte +126 -0
  8. package/dist/Elements/FootnoteRef.svelte.d.ts +7 -0
  9. package/dist/Elements/Image.svelte +4 -4
  10. package/dist/Elements/{A.svelte → Link.svelte} +4 -4
  11. package/dist/Elements/{A.svelte.d.ts → Link.svelte.d.ts} +3 -3
  12. package/dist/Elements/Math.svelte +13 -24
  13. package/dist/Elements/Math.svelte.d.ts +0 -2
  14. package/dist/Elements/Mermaid.svelte +105 -115
  15. package/dist/Elements/Mermaid.svelte.d.ts +0 -2
  16. package/dist/Elements/Table.svelte +1 -1
  17. package/dist/Elements/index.d.ts +5 -24
  18. package/dist/Elements/index.js +5 -24
  19. package/dist/Streamdown.d.ts +52 -10
  20. package/dist/Streamdown.js +19 -1
  21. package/dist/Streamdown.svelte +2 -34
  22. package/dist/Streamdown.svelte.d.ts +1 -14
  23. package/dist/marked/index.d.ts +6 -10
  24. package/dist/marked/index.js +29 -17
  25. package/dist/marked/marked-alert.d.ts +2 -2
  26. package/dist/marked/marked-alert.js +11 -24
  27. package/dist/marked/marked-footnotes.d.ts +1 -0
  28. package/dist/marked/marked-footnotes.js +27 -8
  29. package/dist/marked/marked-list.d.ts +36 -0
  30. package/dist/marked/marked-list.js +232 -0
  31. package/dist/marked/marked-math.js +1 -4
  32. package/dist/marked/marked-subsup.d.ts +28 -0
  33. package/dist/marked/marked-subsup.js +45 -0
  34. package/dist/marked/marked-table.d.ts +59 -0
  35. package/dist/marked/marked-table.js +495 -0
  36. package/dist/theme.d.ts +54 -30
  37. package/dist/theme.js +51 -35
  38. package/dist/utils/panzoom.svelte.d.ts +17 -18
  39. package/dist/utils/panzoom.svelte.js +0 -2
  40. package/dist/utils/parse-incomplete-markdown.js +157 -0
  41. package/dist/utils/useClickOutside.svelte.d.ts +8 -0
  42. package/dist/utils/useClickOutside.svelte.js +41 -0
  43. package/dist/utils/useKeyDown.svelte.d.ts +5 -0
  44. package/dist/utils/useKeyDown.svelte.js +23 -0
  45. package/package.json +2 -1
  46. package/dist/Elements/Blockquote.svelte +0 -28
  47. package/dist/Elements/Blockquote.svelte.d.ts +0 -9
  48. package/dist/Elements/Del.svelte +0 -28
  49. package/dist/Elements/Del.svelte.d.ts +0 -9
  50. package/dist/Elements/Em.svelte +0 -28
  51. package/dist/Elements/Em.svelte.d.ts +0 -9
  52. package/dist/Elements/Heading.svelte +0 -25
  53. package/dist/Elements/Heading.svelte.d.ts +0 -9
  54. package/dist/Elements/Hr.svelte +0 -26
  55. package/dist/Elements/Hr.svelte.d.ts +0 -9
  56. package/dist/Elements/InlineCode.svelte +0 -28
  57. package/dist/Elements/InlineCode.svelte.d.ts +0 -9
  58. package/dist/Elements/Li.svelte +0 -28
  59. package/dist/Elements/Li.svelte.d.ts +0 -9
  60. package/dist/Elements/Ol.svelte +0 -30
  61. package/dist/Elements/Ol.svelte.d.ts +0 -9
  62. package/dist/Elements/P.svelte +0 -28
  63. package/dist/Elements/P.svelte.d.ts +0 -9
  64. package/dist/Elements/Strong.svelte +0 -28
  65. package/dist/Elements/Strong.svelte.d.ts +0 -9
  66. package/dist/Elements/Sub.svelte +0 -27
  67. package/dist/Elements/Sub.svelte.d.ts +0 -8
  68. package/dist/Elements/Sup.svelte +0 -28
  69. package/dist/Elements/Sup.svelte.d.ts +0 -8
  70. package/dist/Elements/Tbody.svelte +0 -24
  71. package/dist/Elements/Tbody.svelte.d.ts +0 -7
  72. package/dist/Elements/Td.svelte +0 -28
  73. package/dist/Elements/Td.svelte.d.ts +0 -9
  74. package/dist/Elements/Th.svelte +0 -28
  75. package/dist/Elements/Th.svelte.d.ts +0 -9
  76. package/dist/Elements/Thead.svelte +0 -27
  77. package/dist/Elements/Thead.svelte.d.ts +0 -9
  78. package/dist/Elements/Tr.svelte +0 -27
  79. package/dist/Elements/Tr.svelte.d.ts +0 -9
  80. package/dist/Elements/Ul.svelte +0 -28
  81. package/dist/Elements/Ul.svelte.d.ts +0 -9
  82. /package/dist/{hightlighter.svelte.d.ts → utils/hightlighter.svelte.d.ts} +0 -0
  83. /package/dist/{hightlighter.svelte.js → utils/hightlighter.svelte.js} +0 -0
package/README.md CHANGED
@@ -20,6 +20,27 @@ Perfect for AI-powered applications that need to stream and render markdown cont
20
20
 
21
21
  ## ✨ Main Features
22
22
 
23
+
24
+ ### 🔄 Streaming-Optimized
25
+
26
+ - **Incomplete Markdown Parsing**: Handles unterminated blocks gracefully
27
+ - **Progressive Rendering**: Perfect for streaming AI responses
28
+ - **Real-time Updates**: Optimized for dynamic content
29
+
30
+ ### 🔒 Security Hardening
31
+
32
+ - **Image Origin Control**: Whitelist allowed image sources
33
+ - **Link Safety**: Control link destinations
34
+ - **HTML Sanitization**: Prevent XSS attacks
35
+
36
+ ### 🎯 Fully Customizable Components & Theming
37
+
38
+ - **Every component customizable** with Svelte snippets
39
+ - **Granular theming system** - customize every part of every component
40
+ - Override default styling and behavior for any markdown element
41
+ - Full control over rendering with type-safe props
42
+ - Seamless integration with your design system
43
+
23
44
  ### 🎨 Built-in Typography Styles
24
45
 
25
46
  Beautiful, responsive typography with **built-in Tailwind CSS classes** for headings, lists, code blocks, and more. Comes with a complete default theme that works out of the box.
@@ -28,9 +49,16 @@ Beautiful, responsive typography with **built-in Tailwind CSS classes** for head
28
49
 
29
50
  Full support for GitHub Flavored Markdown including:
30
51
 
31
- - Task lists
32
52
  - Tables
33
- - Strikethrough text
53
+ - ~~Strikethrough~~
54
+ - Subscript (H~2~O)
55
+ - Superscript (E = mc^2^)
56
+ - Footnotes [^1]
57
+
58
+ [^1]:
59
+ Reference render in a popover by default.
60
+ with _rich_ **content** support
61
+ and multiline
34
62
 
35
63
  ### 💻 Interactive Code Blocks
36
64
 
@@ -91,48 +119,131 @@ pie title Project Time Allocation
91
119
  "Meetings" : 15
92
120
  ```
93
121
 
94
- ### Alert Support
122
+ ### Complex table support
95
123
 
96
- > [!IMPORTANT]
97
- > Native support for Github style Alert
124
+ #### Colspan
98
125
 
99
- ### 🔄 Streaming-Optimized
126
+ | H1 | H2 | H3 |
127
+ | ------------------------- | --- | --- |
128
+ | This cell spans 3 columns |||
100
129
 
101
- - **Incomplete Markdown Parsing**: Handles unterminated blocks gracefully
102
- - **Progressive Rendering**: Perfect for streaming AI responses
103
- - **Real-time Updates**: Optimized for dynamic content
130
+ | Header 1 | Header 2 | Header 3 |
131
+ | ------------------------- | -------- | -------- |
132
+ | This cell spans 2 columns || Normal
133
+ | Normal | Normal | Normal |
104
134
 
105
- ### 🔒 Security Hardening
135
+ #### Rowspan
136
+ | Header 1 | Header 2 |
137
+ | --------------- | -------- |
138
+ | This cell spans | Cell A |
139
+ | two rows ^ | Cell B |
140
+ #### Footer
141
+ | Header 1 | Header 2 |
142
+ | --------------- | -------- |
143
+ | Cell B | Cell A |
144
+ | --------------- | -------- |
145
+ | Footer ||
106
146
 
107
- - **Image Origin Control**: Whitelist allowed image sources
108
- - **Link Safety**: Control link destinations
109
- - **HTML Sanitization**: Prevent XSS attacks
147
+ #### Column alignment
110
148
 
111
- ### 🎯 Fully Customizable Components & Theming
149
+ | Left | Center | Right |
150
+ | :--- | :----: | ----: |
151
+ | A | B | C |
152
+
153
+ #### Multiple headers and very complex layout
154
+
155
+
156
+ | Product Category ||| Sales Data Q1-Q4 2024 ||||
157
+ | Product | Region || Q1 | Q2 | Q3 | Q4 |
158
+ | Name | Type | Area | Revenue | Revenue | Revenue | Revenue |
159
+ |-------------|---------|------------|---------|---------|---------|---------|
160
+ | Laptop Pro | Electronics | North America || $45,000 | $52,000 | $48,000 |
161
+ | Laptop Pro ^ | ^ | Europe | $32,000 | $38,000 | $41,000 | $44,000 |
162
+ | Laptop Pro ^ | ^ | Asia || $28,000 | $35,000 | $42,000 |
163
+ | Office Chair | Furniture | North America | $15,000 | $18,000 | $16,000 | $17,000 |
164
+ | Office Chair ^ | ^ | Europe | $12,000 | $14,000 | $15,000 | $16,000 |
165
+ | Wireless Mouse | Electronics | Global ||| $25,000 | $28,000 |
166
+ |-------------|---------|------------|---------|---------|---------|---------|
167
+ | **Total Revenue** ||| **$152,000** | **$185,000** | **$187,000** | **$205,000** |
168
+
169
+ ### Complex list support
170
+
171
+ #### decimal
172
+
173
+ 1. First item
174
+ 2. Second item
175
+ 3. Third item
176
+
177
+ #### lower-alpha
178
+
179
+ a. First item
180
+ b. Second item
181
+ c. Third item
182
+
183
+ #### upper-alpha
184
+
185
+ A. First item
186
+ B. Second item
187
+ C. Third item
188
+
189
+ #### lower-roman
190
+
191
+ i. First item
192
+ ii. Second item
193
+ iii. Third item
194
+
195
+ #### upper-roman
196
+
197
+ I. First item
198
+ II. Second item
199
+ III. Third item
200
+
201
+ #### Nested Lists
202
+
203
+ 1. First level (numeric)
204
+ a. Second level (lowercase alpha)
205
+ i. Third level (lowercase roman)
206
+ - Fourth level (bullet)
207
+ I. Fifth level (uppercase roman)
208
+ A. Sixth level (uppercase alpha)
209
+
210
+ 2. Back to the first level
211
+
212
+ #### Task List
213
+
214
+ - [ ] Uncompleted task
215
+ - [x] Completed task
216
+ - [ ] Another uncompleted task
217
+ - [ ] Nested uncompleted subtask
218
+ - [x] Nested completed subtask
219
+
220
+
221
+ ### Alert Support
222
+
223
+ > [!IMPORTANT]
224
+ > Native support for Github style Alert
112
225
 
113
- - **Every component customizable** with Svelte snippets
114
- - **Granular theming system** - customize every part of every component
115
- - Override default styling and behavior for any markdown element
116
- - Full control over rendering with type-safe props
117
- - Seamless integration with your design system
118
226
 
119
227
  ## 🔄 Differences from Original React Version
120
228
 
121
229
  This Svelte port maintains feature parity with the original [Streamdown](https://streamdown.ai/) while adapting to Svelte's patterns:
122
230
 
123
- | Aspect | Original (React) | Svelte Port |
124
- | ----------------- | ---------------- | ------------------------- |
125
- | **Framework** | React | Svelte 5 |
126
- | **Component API** | JSX Components | Svelte Snippets |
127
- | **Styling** | Tailwind CSS | Tailwind CSS (compatible) |
128
- | **Context** | React Context | Svelte Context |
129
- | **Build System** | Vite/React | Vite/SvelteKit |
130
- | **TypeScript** | Full TS support | Full TS support |
231
+ | Aspect | Original (React) | Svelte Port |
232
+ | ----------------- | ------------------------ | ------------------------- |
233
+ | **Framework** | React | Svelte 5 |
234
+ | **Component API** | JSX Components | Svelte Snippets |
235
+ | **Styling** | Tailwind CSS | Tailwind CSS (compatible) |
236
+ | **Context** | React Context | Svelte Context |
237
+ | **Build System** | Vite/React | Vite/SvelteKit |
238
+ | **TypeScript** | Full TS support | Full TS support |
239
+ | **Engine** | Remark / Rehype + marked | marked only |
131
240
 
132
241
  ### Tailwind CSS Setup
133
242
 
134
243
  > [!NOTE]
135
244
  > Streamdown comes with **built-in Tailwind CSS classes** for beautiful default styling. To ensure all styles are included in your build, add the following to your `app.css` or main CSS file:
245
+ > This setup is primarily necessary if you're using Tailwind CSS v4's new `@source` directive or if you have aggressive purging enabled in older versions. If you're using standard Tailwind CSS v3+ with default purging, Streamdown's styles should be automatically included when the component is imported and used in your application.
246
+ > This ensures that all Streamdown's default styling is included in your Tailwind build process.
136
247
 
137
248
  ```css
138
249
  @import 'tailwindcss';
@@ -140,10 +251,6 @@ This Svelte port maintains feature parity with the original [Streamdown](https:/
140
251
  @source "../node_modules/svelte-streamdown/**/*";
141
252
  ```
142
253
 
143
- This ensures that all Streamdown's default styling is included in your Tailwind build process.
144
-
145
- > **Note:** This setup is primarily necessary if you're using Tailwind CSS v4's new `@source` directive or if you have aggressive purging enabled in older versions. If you're using standard Tailwind CSS v3+ with default purging, Streamdown's styles should be automatically included when the component is imported and used in your application.
146
-
147
254
  ## 🚀 Quick Start
148
255
 
149
256
  ### Basic Usage
@@ -178,13 +285,13 @@ This heading will use a custom component!`;
178
285
  // Custom heading component
179
286
  </script>
180
287
 
181
- {#snippet customH1({ children, props })}
182
- <h1 class="mb-4 text-4xl font-bold text-blue-600" {...props}>
183
- {children}
288
+ {#snippet customHeading({ children, token })}
289
+ <h1 class="mb-4 text-4xl font-bold text-blue-600" {...token.props}>
290
+ {@render children()}
184
291
  </h1>
185
292
  {/snippet}
186
293
 
187
- <Streamdown {content} h1={customH1} />
294
+ <Streamdown {content} heading={customHeading} />
188
295
  ```
189
296
 
190
297
  ### Security Configuration
@@ -214,9 +321,6 @@ This heading will use a custom component!`;
214
321
  | `defaultOrigin` | `string` | - | Default origin for relative URLs |
215
322
  | `allowedLinkPrefixes` | `string[]` | `['*']` | Allowed URL prefixes for links |
216
323
  | `allowedImagePrefixes` | `string[]` | `['*']` | Allowed URL prefixes for images |
217
- | `allowElement` | `AllowElement \| null` | - | Custom element filtering function |
218
- | `allowedElements` | `readonly string[] \| null` | - | Whitelist of allowed HTML elements |
219
- | `disallowedElements` | `readonly string[] \| null` | - | Blacklist of disallowed HTML elements |
220
324
  | `skipHtml` | `boolean` | - | Skip HTML parsing entirely |
221
325
  | `unwrapDisallowed` | `boolean` | - | Unwrap instead of removing disallowed elements |
222
326
  | `urlTransform` | `UrlTransform \| null` | - | Custom URL transformation function |
@@ -226,14 +330,13 @@ This heading will use a custom component!`;
226
330
  | `shikiTheme` | `BundledTheme` | `'github-light'` | Code highlighting theme |
227
331
  | `mermaidConfig` | `MermaidConfig` | - | Mermaid diagram configuration |
228
332
  | `katexConfig` | `KatexOptions \| ((inline: boolean) => KatexOptions)` | - | KaTeX math rendering options |
229
- | `remarkPlugins` | `PluggableList` | - | Additional remark plugins |
230
- | `rehypePlugins` | `PluggableList` | - | Additional rehype plugins |
231
- | `remarkRehypeOptions` | `RemarkRehypeOptions` | - | Remark-rehype conversion options |
232
- | `customElements` | `Record<string, Snippet<[ElementProps]>>` | - | Custom snippets for not handled nodes |
233
333
 
234
334
  ### Custom Component Props
235
335
 
236
- **Every single markdown element** can be customized with Svelte snippets, giving you complete control over styling and behavior:
336
+ **Every single markdown element** can be customized with Svelte snippets, giving you
337
+ complete control over styling and behavior:
338
+
339
+ Each snippet receives `{ children, token }` where `token` is a typed token object containing the parsed markdown token with its properties and children is a snippet to be rendered.
237
340
 
238
341
  ```svelte
239
342
  <script>
@@ -244,36 +347,36 @@ This heading will use a custom component!`;
244
347
  This heading uses a custom component with your design system!`;
245
348
  </script>
246
349
 
247
- {#snippet customH1({ children, ...props })}
350
+ {#snippet customHeading({ children, token })}
248
351
  <h1
249
352
  class="text-gradient mb-6 bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-4xl font-bold text-transparent"
250
- {...props}
353
+ {...token.props}
251
354
  >
252
355
  {@render children()}
253
356
  </h1>
254
357
  {/snippet}
255
358
 
256
- {#snippet customCode({ children, ...props })}
257
- <code class="rounded bg-gray-100 px-2 py-1 font-mono text-sm dark:bg-gray-800" {...props}>
359
+ {#snippet customCode({ children, token })}
360
+ <code class="rounded bg-gray-100 px-2 py-1 font-mono text-sm dark:bg-gray-800" {...token.props}>
258
361
  {@render children()}
259
362
  </code>
260
363
  {/snippet}
261
364
 
262
- {#snippet customBlockquote({ children, ...props })}
365
+ {#snippet customBlockquote({ children, token })}
263
366
  <blockquote
264
367
  class="border-l-4 border-blue-500 pl-4 text-gray-600 italic dark:text-gray-300"
265
- {...props}
368
+ {...token.props}
266
369
  >
267
370
  {@render children()}
268
371
  </blockquote>
269
372
  {/snippet}
270
373
 
271
- <Streamdown {content} h1={customH1} code={customCode} blockquote={customBlockquote} />
374
+ <Streamdown {content} heading={customHeading} code={customCode} blockquote={customBlockquote} />
272
375
  ```
273
376
 
274
377
  #### All Available Customizable Elements:
275
378
 
276
- **Text Elements**: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `p`, `strong`, `em`, `del`
379
+ **Text Elements**: `heading`, `p`, `strong`, `em`, `del`
277
380
 
278
381
  **Links & Media**: `a`, `img`
279
382
 
@@ -285,95 +388,7 @@ This heading uses a custom component with your design system!`;
285
388
 
286
389
  **Special Content**: `blockquote`, `hr`, `alert`, `mermaid`, `math`, `inlineMath`
287
390
 
288
- **Note**: The above elements are **supported by Streamdown** and should be customized using individual props or the theme system. Use `customElements` only for HTML elements **not in this list** (like `div`, `span`, `section`, `article`, etc.).
289
-
290
- Each snippet receives `{ children, ...props }` where `props` contains all element attributes and classes.
291
-
292
- ### Using `customElements` Record
293
-
294
- The `customElements` prop is specifically for HTML elements that are **not handled by the library by default**. For elements already supported by Streamdown (like `h1`, `p`, `code`, etc.), use individual props or the theme system instead.
295
-
296
- ```svelte
297
- <script>
298
- import { Streamdown } from 'svelte-streamdown';
299
-
300
- let content = `# Custom Elements Example
301
-
302
- This content contains HTML elements not handled by Streamdown by default:
303
-
304
- <div class="special">This is a custom div element</div>
305
-
306
- <span class="highlight">This is a custom span element</span>
307
-
308
- <section class="wrapper">
309
- <article>This is a custom article inside a section</article>
310
- </section>`;
311
-
312
- // Define custom components for unsupported HTML elements
313
- </script>
314
-
315
- {#snippet customDiv({ children, props, className, node })}
316
- <div class="rounded-lg border-2 border-blue-500 p-4 {className}" {...props}>
317
- {@render children()}
318
- </div>
319
- {/snippet}
320
-
321
- {#snippet customSpan({ children, props, className, node })}
322
- <span class="rounded bg-yellow-200 px-2 py-1 {className}" {...props}>
323
- {@render children()}
324
- </span>
325
- {/snippet}
326
-
327
- {#snippet customSection({ children, props, className, node })}
328
- <section class="my-8 rounded-xl bg-gray-50 p-6 {className}" {...props}>
329
- {@render children()}
330
- </section>
331
- {/snippet}
332
-
333
- {#snippet customArticle({ children, props, className, node })}
334
- <article class="prose max-w-none {className}" {...props}>
335
- {@render children()}
336
- </article>
337
- {/snippet}
338
-
339
- <Streamdown
340
- {content}
341
- customElements={{
342
- div: customDiv,
343
- span: customSpan,
344
- section: customSection,
345
- article: customArticle
346
- }}
347
- />
348
- ```
349
-
350
- ### Benefits of `customElements`
351
-
352
- - **Handle Unsupported Elements**: Define components for HTML elements not built into Streamdown
353
- - **Semantic HTML Support**: Use elements like `<section>`, `<article>`, `<aside>`, `<nav>`, etc.
354
- - **Fallback Support**: Automatically handles unknown elements that would otherwise be ignored
355
- - **Type Safety**: Full TypeScript support with `ElementProps` interface
356
-
357
- ### `customElements` vs Individual Props
358
-
359
- Use the right approach for the right elements:
360
-
361
- **Individual Props** (for supported Streamdown elements):
362
-
363
- ```svelte
364
- <Streamdown {content} h1={customH1} p={customP} code={customCode} />
365
- ```
366
-
367
- **CustomElements Record** (for unsupported HTML elements):
368
-
369
- ```svelte
370
- <Streamdown
371
- {content}
372
- customElements={{ div: customDiv, span: customSpan, section: customSection }}
373
- />
374
- ```
375
-
376
- **Note**: For supported elements (h1, p, code, etc.), use individual props or the theme system. For unsupported elements (div, span, section, etc.), use `customElements`.
391
+ **Note**: The above elements are **supported by Streamdown** and should be customized using individual props or the theme system.
377
392
 
378
393
  ## 🎨 Advanced Theming System
379
394
 
package/dist/Block.svelte CHANGED
@@ -1,7 +1,10 @@
1
+ <script lang="ts" module>
2
+ </script>
3
+
1
4
  <script lang="ts">
2
5
  import { parseIncompleteMarkdown } from './utils/parse-incomplete-markdown.js';
3
6
  import Element from './Elements/Element.svelte';
4
- import { lex, type StreamdownToken, type TableRow } from './marked/index.js';
7
+ import { lex, type StreamdownToken } from './marked/index.js';
5
8
 
6
9
  let {
7
10
  block
@@ -12,37 +15,8 @@
12
15
  const tokens = $derived(lex(parseIncompleteMarkdown(block.trim())));
13
16
 
14
17
  const getChildren = (token: StreamdownToken) => {
15
- if (token.type === 'list') {
16
- return token.items as StreamdownToken[];
17
- }
18
-
19
- if (token.type === 'table') {
20
- const headerRow = {
21
- type: 'tableRow',
22
- tokens: token.header.map((cell) => ({
23
- type: 'tableCell',
24
- ...cell
25
- })),
26
- isHeader: true
27
- } satisfies TableRow;
28
-
29
- const rows = token.rows.reduce(
30
- (acc, cells) => {
31
- const row = {
32
- type: 'tableRow',
33
- tokens: cells.map((cell) => ({
34
- type: 'tableCell',
35
- ...cell
36
- })),
37
- isHeader: false
38
- } satisfies TableRow;
39
- acc.push(row);
40
- return acc;
41
- },
42
- [headerRow] as TableRow[]
43
- );
44
-
45
- return rows;
18
+ if (!token) {
19
+ return [];
46
20
  }
47
21
  const children =
48
22
  'tokens' in token ? ((token.tokens || []) as StreamdownToken[]) : ([] as StreamdownToken[]);
@@ -63,15 +37,17 @@
63
37
 
64
38
  {#snippet renderChildren(tokens: StreamdownToken[])}
65
39
  {#each tokens as token}
66
- {@const children = getChildren(token)}
67
- {@const isTextOnlyNode = children.length === 0}
68
- <Element {token}>
69
- {#if isTextOnlyNode}
70
- {'text' in token ? token.text : ''}
71
- {:else}
72
- {@render renderChildren(children)}
73
- {/if}
74
- </Element>
40
+ {#if token}
41
+ {@const children = getChildren(token)}
42
+ {@const isTextOnlyNode = children.length === 0}
43
+ <Element {token}>
44
+ {#if isTextOnlyNode}
45
+ {'text' in token ? token.text : ''}
46
+ {:else}
47
+ {@render renderChildren(children)}
48
+ {/if}
49
+ </Element>
50
+ {/if}
75
51
  {/each}
76
52
  {/snippet}
77
53
 
@@ -13,7 +13,7 @@
13
13
  /><path d="M12 17h.01" />`
14
14
  };
15
15
 
16
- import { useStreamdown } from '../Streamdown.svelte';
16
+ import { useStreamdown } from '../Streamdown.js';
17
17
  import Slot from './Slot.svelte';
18
18
  import type { AlertToken } from '../marked/index.js';
19
19
  import type { Snippet } from 'svelte';
@@ -35,7 +35,6 @@
35
35
  <Slot
36
36
  props={{
37
37
  children,
38
- alertType,
39
38
  token
40
39
  }}
41
40
  render={streamdown.snippets.alert}
@@ -1,17 +1,15 @@
1
1
  <script lang="ts">
2
- import { useStreamdown } from '../Streamdown.svelte';
2
+ import { useStreamdown } from '../Streamdown.js';
3
3
  import { save } from '../utils/save.js';
4
4
  import { useCopy } from '../utils/copy.svelte.js';
5
- import { HighlighterManager, languageExtensionMap } from '../hightlighter.svelte.js';
5
+ import { HighlighterManager, languageExtensionMap } from '../utils/hightlighter.svelte.js';
6
6
  import type { Tokens } from 'marked';
7
7
  import type { Snippet } from 'svelte';
8
8
 
9
9
  const {
10
- token,
11
- children
10
+ token
12
11
  }: {
13
12
  token: Tokens.Code;
14
- children: Snippet;
15
13
  } = $props();
16
14
 
17
15
  const streamdown = useStreamdown();
@@ -1,8 +1,6 @@
1
1
  import type { Tokens } from 'marked';
2
- import type { Snippet } from 'svelte';
3
2
  type $$ComponentProps = {
4
3
  token: Tokens.Code;
5
- children: Snippet;
6
4
  };
7
5
  declare const Code: import("svelte").Component<$$ComponentProps, {}, "">;
8
6
  type Code = ReturnType<typeof Code>;