svelte-streamdown 1.0.6 → 1.0.7

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 (90) hide show
  1. package/dist/Block.svelte +64 -20
  2. package/dist/Elements/A.svelte +17 -14
  3. package/dist/Elements/A.svelte.d.ts +7 -2
  4. package/dist/Elements/Alert.svelte +12 -28
  5. package/dist/Elements/Alert.svelte.d.ts +7 -2
  6. package/dist/Elements/Blockquote.svelte +11 -9
  7. package/dist/Elements/Blockquote.svelte.d.ts +7 -2
  8. package/dist/Elements/Code.svelte +13 -11
  9. package/dist/Elements/Code.svelte.d.ts +7 -2
  10. package/dist/Elements/Del.svelte +11 -7
  11. package/dist/Elements/Del.svelte.d.ts +7 -2
  12. package/dist/Elements/Element.svelte +50 -99
  13. package/dist/Elements/Element.svelte.d.ts +2 -5
  14. package/dist/Elements/Em.svelte +11 -6
  15. package/dist/Elements/Em.svelte.d.ts +7 -2
  16. package/dist/Elements/Heading.svelte +25 -0
  17. package/dist/Elements/Heading.svelte.d.ts +9 -0
  18. package/dist/Elements/Hr.svelte +12 -6
  19. package/dist/Elements/Hr.svelte.d.ts +7 -2
  20. package/dist/Elements/Image.svelte +17 -17
  21. package/dist/Elements/Image.svelte.d.ts +7 -2
  22. package/dist/Elements/InlineCode.svelte +12 -7
  23. package/dist/Elements/InlineCode.svelte.d.ts +7 -2
  24. package/dist/Elements/Li.svelte +11 -6
  25. package/dist/Elements/Li.svelte.d.ts +7 -2
  26. package/dist/Elements/Math.svelte +19 -9
  27. package/dist/Elements/Math.svelte.d.ts +7 -2
  28. package/dist/Elements/Mermaid.svelte +13 -9
  29. package/dist/Elements/Mermaid.svelte.d.ts +7 -2
  30. package/dist/Elements/Ol.svelte +13 -6
  31. package/dist/Elements/Ol.svelte.d.ts +7 -2
  32. package/dist/Elements/P.svelte +11 -6
  33. package/dist/Elements/P.svelte.d.ts +7 -2
  34. package/dist/Elements/Strong.svelte +11 -6
  35. package/dist/Elements/Strong.svelte.d.ts +7 -2
  36. package/dist/Elements/Sub.svelte +10 -6
  37. package/dist/Elements/Sub.svelte.d.ts +6 -2
  38. package/dist/Elements/Sup.svelte +10 -5
  39. package/dist/Elements/Sup.svelte.d.ts +6 -2
  40. package/dist/Elements/Table.svelte +12 -7
  41. package/dist/Elements/Table.svelte.d.ts +7 -2
  42. package/dist/Elements/Tbody.svelte +8 -7
  43. package/dist/Elements/Tbody.svelte.d.ts +5 -2
  44. package/dist/Elements/Td.svelte +12 -7
  45. package/dist/Elements/Td.svelte.d.ts +7 -2
  46. package/dist/Elements/Th.svelte +11 -6
  47. package/dist/Elements/Th.svelte.d.ts +7 -2
  48. package/dist/Elements/Thead.svelte +13 -9
  49. package/dist/Elements/Thead.svelte.d.ts +7 -2
  50. package/dist/Elements/Tr.svelte +13 -9
  51. package/dist/Elements/Tr.svelte.d.ts +7 -2
  52. package/dist/Elements/Ul.svelte +11 -6
  53. package/dist/Elements/Ul.svelte.d.ts +7 -2
  54. package/dist/Elements/index.d.ts +1 -6
  55. package/dist/Elements/index.js +1 -6
  56. package/dist/Streamdown.d.ts +16 -24
  57. package/dist/Streamdown.svelte +7 -39
  58. package/dist/Streamdown.svelte.d.ts +1 -1
  59. package/dist/hightlighter.svelte.js +0 -1
  60. package/dist/marked/index.d.ts +16 -0
  61. package/dist/marked/index.js +34 -0
  62. package/dist/marked/marked-alert.d.ts +19 -0
  63. package/dist/marked/marked-alert.js +54 -0
  64. package/dist/marked/marked-footnotes.d.ts +28 -0
  65. package/dist/marked/marked-footnotes.js +75 -0
  66. package/dist/marked/marked-math.d.ts +10 -0
  67. package/dist/marked/marked-math.js +60 -0
  68. package/dist/theme.d.ts +3 -3
  69. package/dist/theme.js +5 -5
  70. package/package.json +2 -14
  71. package/dist/Elements/H1.svelte +0 -23
  72. package/dist/Elements/H1.svelte.d.ts +0 -4
  73. package/dist/Elements/H2.svelte +0 -23
  74. package/dist/Elements/H2.svelte.d.ts +0 -4
  75. package/dist/Elements/H3.svelte +0 -23
  76. package/dist/Elements/H3.svelte.d.ts +0 -4
  77. package/dist/Elements/H4.svelte +0 -23
  78. package/dist/Elements/H4.svelte.d.ts +0 -4
  79. package/dist/Elements/H5.svelte +0 -23
  80. package/dist/Elements/H5.svelte.d.ts +0 -4
  81. package/dist/Elements/H6.svelte +0 -23
  82. package/dist/Elements/H6.svelte.d.ts +0 -4
  83. package/dist/Elements/element.d.ts +0 -8
  84. package/dist/Elements/element.js +0 -1
  85. package/dist/utils/alerts.d.ts +0 -12
  86. package/dist/utils/alerts.js +0 -207
  87. package/dist/utils/parse-blocks.d.ts +0 -1
  88. package/dist/utils/parse-blocks.js +0 -40
  89. package/dist/utils/parse.d.ts +0 -3
  90. package/dist/utils/parse.js +0 -131
package/dist/Block.svelte CHANGED
@@ -1,34 +1,78 @@
1
1
  <script lang="ts">
2
2
  import { parseIncompleteMarkdown } from './utils/parse-incomplete-markdown.js';
3
- import { parseMarkdown } from './utils/parse.js';
4
- import { useStreamdown } from './Streamdown.svelte';
5
- import type { Root } from 'hast';
6
3
  import Element from './Elements/Element.svelte';
4
+ import { lex, type StreamdownToken, type TableRow } from './marked/index.js';
5
+
7
6
  let {
8
7
  block
9
8
  }: {
10
9
  block: string;
11
10
  } = $props();
12
11
 
13
- const streamdownContext = useStreamdown();
14
- const root = $derived(parseMarkdown(streamdownContext, parseIncompleteMarkdown(block.trim())));
12
+ const tokens = $derived(lex(parseIncompleteMarkdown(block.trim())));
13
+
14
+ 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;
46
+ }
47
+ const children =
48
+ 'tokens' in token ? ((token.tokens || []) as StreamdownToken[]) : ([] as StreamdownToken[]);
49
+
50
+ if (!children.length && token.type !== 'text') {
51
+ return [
52
+ {
53
+ type: 'text',
54
+ text: 'text' in token ? token.text : '',
55
+ raw: 'raw' in token ? token.raw : '',
56
+ tokens: []
57
+ }
58
+ ] satisfies StreamdownToken[];
59
+ }
60
+ return children;
61
+ };
15
62
  </script>
16
63
 
17
- {#snippet renderChildren(nodeChildren: Root['children'])}
18
- {#each nodeChildren as node}
19
- {#if node.type === 'element'}
20
- {@const {
21
- properties: { className, ...props }
22
- } = node}
23
- <Element {node} {className} {props} type={node.tagName}>
24
- {#if 'children' in node && node.children?.length}
25
- {@render renderChildren(node.children)}
26
- {/if}
27
- </Element>
28
- {:else if node.type === 'text' && node.value}
29
- {node.value}
30
- {/if}
64
+ {#snippet renderChildren(tokens: StreamdownToken[])}
65
+ {#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>
31
75
  {/each}
32
76
  {/snippet}
33
77
 
34
- {@render renderChildren(root.children)}
78
+ {@render renderChildren(tokens)}
@@ -1,20 +1,22 @@
1
1
  <script lang="ts">
2
2
  import { useStreamdown } from '../Streamdown.svelte';
3
3
  import { transformUrl } from '../utils/url.js';
4
- import { clsx } from 'clsx';
5
- import type { ElementProps } from './element.js';
6
4
  import Slot from './Slot.svelte';
5
+ import type { Tokens } from 'marked';
6
+ import type { Snippet } from 'svelte';
7
7
 
8
8
  const streamdown = useStreamdown();
9
9
 
10
- const { children, className, node, props }: ElementProps = $props();
10
+ const {
11
+ children,
12
+ token
13
+ }: {
14
+ children: Snippet;
15
+ token: Tokens.Link;
16
+ } = $props();
11
17
 
12
18
  const transformedUrl = $derived(
13
- transformUrl(
14
- node.properties.href,
15
- streamdown.allowedLinkPrefixes ?? [],
16
- streamdown.defaultOrigin
17
- )
19
+ transformUrl(token.href, streamdown.allowedLinkPrefixes ?? [], streamdown.defaultOrigin)
18
20
  );
19
21
  </script>
20
22
 
@@ -24,16 +26,14 @@
24
26
  href: transformedUrl,
25
27
  target: '_blank',
26
28
  rel: 'noopener noreferrer',
29
+ title: token.title,
27
30
  children,
28
- node,
29
- props,
30
- className
31
+ token
31
32
  }}
32
33
  render={streamdown.snippets.a}
33
34
  >
34
35
  <a
35
- {...props}
36
- class={clsx(streamdown.theme.a.base, className)}
36
+ class={streamdown.theme.a.base}
37
37
  href={transformedUrl}
38
38
  target="_blank"
39
39
  rel="noopener noreferrer"
@@ -42,7 +42,10 @@
42
42
  </a>
43
43
  </Slot>
44
44
  {:else}
45
- <span class={streamdown.theme.a.blocked} title={`Blocked URL: ${node.properties.href}`}>
45
+ <span
46
+ class={streamdown.theme.a.blocked}
47
+ title={token.title ? `Blocked URL: ${token.href}` : undefined}
48
+ >
46
49
  {@render children()} [blocked]
47
50
  </span>
48
51
  {/if}
@@ -1,4 +1,9 @@
1
- import type { ElementProps } from './element.js';
2
- declare const A: import("svelte").Component<ElementProps, {}, "">;
1
+ import type { Tokens } from 'marked';
2
+ import type { Snippet } from 'svelte';
3
+ type $$ComponentProps = {
4
+ children: Snippet;
5
+ token: Tokens.Link;
6
+ };
7
+ declare const A: import("svelte").Component<$$ComponentProps, {}, "">;
3
8
  type A = ReturnType<typeof A>;
4
9
  export default A;
@@ -14,30 +14,21 @@
14
14
  };
15
15
 
16
16
  import { useStreamdown } from '../Streamdown.svelte';
17
- import { clsx } from 'clsx';
18
- import type { ElementProps } from './element.js';
19
17
  import Slot from './Slot.svelte';
18
+ import type { AlertToken } from '../marked/index.js';
19
+ import type { Snippet } from 'svelte';
20
20
 
21
21
  const streamdown = useStreamdown();
22
22
 
23
- const { children, className, node, props }: ElementProps = $props();
24
-
25
- // Extract alertType from className
26
- const alertType = $derived.by(() => {
27
- const className = node.properties.className as string[] | undefined;
28
- if (!className) return 'note';
29
- const alertClass = className.find((cls) => cls.startsWith('markdown-alert-'));
30
- if (!alertClass) return 'note';
31
- return alertClass.replace('markdown-alert-', '') as
32
- | 'note'
33
- | 'tip'
34
- | 'warning'
35
- | 'caution'
36
- | 'important';
37
- });
23
+ const {
24
+ children,
25
+ token
26
+ }: {
27
+ children: Snippet;
28
+ token: AlertToken;
29
+ } = $props();
38
30
 
39
- // Extract icon from node properties
40
- const icon = $derived((node.properties.icon as string) || '');
31
+ const alertType = $derived(token.variant);
41
32
  const title = $derived(streamdown.translations?.alert?.[alertType] || alertType);
42
33
  </script>
43
34
 
@@ -45,17 +36,11 @@
45
36
  props={{
46
37
  children,
47
38
  alertType,
48
- icon,
49
- node,
50
- props,
51
- className
39
+ token
52
40
  }}
53
41
  render={streamdown.snippets.alert}
54
42
  >
55
- <div
56
- {...props}
57
- class={clsx(streamdown.theme.alert.base, className, streamdown.theme.alert[alertType])}
58
- >
43
+ <div class={`${streamdown.theme.alert.base} ${streamdown.theme.alert[alertType]}`}>
59
44
  <div data-alert-title class={streamdown.theme.alert.title}>
60
45
  <svg
61
46
  xmlns="http://www.w3.org/2000/svg"
@@ -68,7 +53,6 @@
68
53
  stroke-linejoin="round"
69
54
  class={streamdown.theme.alert.icon}
70
55
  >
71
- <!-- {@html icon} -->
72
56
  {@html icons[alertType]}
73
57
  </svg>
74
58
  {title}
@@ -1,4 +1,9 @@
1
- import type { ElementProps } from './element.js';
2
- declare const Alert: import("svelte").Component<ElementProps, {}, "">;
1
+ import type { AlertToken } from '../marked/index.js';
2
+ import type { Snippet } from 'svelte';
3
+ type $$ComponentProps = {
4
+ children: Snippet;
5
+ token: AlertToken;
6
+ };
7
+ declare const Alert: import("svelte").Component<$$ComponentProps, {}, "">;
3
8
  type Alert = ReturnType<typeof Alert>;
4
9
  export default Alert;
@@ -1,26 +1,28 @@
1
1
  <script lang="ts">
2
2
  import { useStreamdown } from '../Streamdown.svelte';
3
- import { clsx } from 'clsx';
4
- import type { ElementProps } from './element.js';
5
3
  import Slot from './Slot.svelte';
4
+ import type { Tokens } from 'marked';
5
+ import type { Snippet } from 'svelte';
6
6
 
7
7
  const streamdown = useStreamdown();
8
8
 
9
- const { children, node, className, props }: ElementProps = $props();
10
-
11
- console.log({ node });
9
+ const {
10
+ children,
11
+ token
12
+ }: {
13
+ children: Snippet;
14
+ token: Tokens.Blockquote;
15
+ } = $props();
12
16
  </script>
13
17
 
14
18
  <Slot
15
19
  props={{
16
20
  children,
17
- node,
18
- props,
19
- className
21
+ token
20
22
  }}
21
23
  render={streamdown.snippets.blockquote}
22
24
  >
23
- <blockquote {...props} class={clsx(streamdown.theme.blockquote.base, className)}>
25
+ <blockquote class={streamdown.theme.blockquote.base}>
24
26
  {@render children()}
25
27
  </blockquote>
26
28
  </Slot>
@@ -1,4 +1,9 @@
1
- import type { ElementProps } from './element.js';
2
- declare const Blockquote: import("svelte").Component<ElementProps, {}, "">;
1
+ import type { Tokens } from 'marked';
2
+ import type { Snippet } from 'svelte';
3
+ type $$ComponentProps = {
4
+ children: Snippet;
5
+ token: Tokens.Blockquote;
6
+ };
7
+ declare const Blockquote: import("svelte").Component<$$ComponentProps, {}, "">;
3
8
  type Blockquote = ReturnType<typeof Blockquote>;
4
9
  export default Blockquote;
@@ -3,16 +3,22 @@
3
3
  import { save } from '../utils/save.js';
4
4
  import { useCopy } from '../utils/copy.svelte.js';
5
5
  import { HighlighterManager, languageExtensionMap } from '../hightlighter.svelte.js';
6
- import { clsx } from 'clsx';
7
- import type { ElementProps } from './element.js';
6
+ import type { Tokens } from 'marked';
7
+ import type { Snippet } from 'svelte';
8
8
 
9
- let { node, className, props }: ElementProps = $props();
9
+ const {
10
+ token,
11
+ children
12
+ }: {
13
+ token: Tokens.Code;
14
+ children: Snippet;
15
+ } = $props();
10
16
 
11
17
  const streamdown = useStreamdown();
12
18
  const highlighter = HighlighterManager.create(streamdown.shikiPreloadThemes || []);
13
19
  const theme = $derived(streamdown.shikiTheme);
14
- let codeContent = $derived((node.children[0] as any).value);
15
- const language = $derived(node.properties.language as string);
20
+ let codeContent = $derived(token.text);
21
+ const language = $derived(token.lang || '');
16
22
  const copy = useCopy({
17
23
  get content() {
18
24
  return codeContent;
@@ -40,12 +46,8 @@
40
46
  });
41
47
  </script>
42
48
 
43
- <div
44
- {...props}
45
- class={clsx(streamdown.theme.code.base, streamdown.theme.code.container, className)}
46
- data-language={language}
47
- >
48
- <div class={clsx(streamdown.theme.code.header)} data-code-block-header data-language={language}>
49
+ <div class={streamdown.theme.code.base} data-language={language}>
50
+ <div class={streamdown.theme.code.header} data-code-block-header data-language={language}>
49
51
  <span class={streamdown.theme.code.language}>{language}</span>
50
52
  <div class="flex items-center gap-2">
51
53
  <!-- Download button snippet -->
@@ -1,4 +1,9 @@
1
- import type { ElementProps } from './element.js';
2
- declare const Code: import("svelte").Component<ElementProps, {}, "">;
1
+ import type { Tokens } from 'marked';
2
+ import type { Snippet } from 'svelte';
3
+ type $$ComponentProps = {
4
+ token: Tokens.Code;
5
+ children: Snippet;
6
+ };
7
+ declare const Code: import("svelte").Component<$$ComponentProps, {}, "">;
3
8
  type Code = ReturnType<typeof Code>;
4
9
  export default Code;
@@ -1,24 +1,28 @@
1
1
  <script lang="ts">
2
2
  import { useStreamdown } from '../Streamdown.svelte';
3
- import { clsx } from 'clsx';
4
- import type { ElementProps } from './element.js';
5
3
  import Slot from './Slot.svelte';
4
+ import type { Tokens } from 'marked';
5
+ import type { Snippet } from 'svelte';
6
6
 
7
7
  const streamdown = useStreamdown();
8
8
 
9
- const { children, node, className, props }: ElementProps = $props();
9
+ const {
10
+ children,
11
+ token
12
+ }: {
13
+ children: Snippet;
14
+ token: Tokens.Del;
15
+ } = $props();
10
16
  </script>
11
17
 
12
18
  <Slot
13
19
  props={{
14
20
  children,
15
- node,
16
- props,
17
- className
21
+ token
18
22
  }}
19
23
  render={streamdown.snippets.del}
20
24
  >
21
- <del {...props} class={clsx(streamdown.theme.del.base, className)}>
25
+ <del class={streamdown.theme.del.base}>
22
26
  {@render children()}
23
27
  </del>
24
28
  </Slot>
@@ -1,4 +1,9 @@
1
- import type { ElementProps } from './element.js';
2
- declare const Del: import("svelte").Component<ElementProps, {}, "">;
1
+ import type { Tokens } from 'marked';
2
+ import type { Snippet } from 'svelte';
3
+ type $$ComponentProps = {
4
+ children: Snippet;
5
+ token: Tokens.Del;
6
+ };
7
+ declare const Del: import("svelte").Component<$$ComponentProps, {}, "">;
3
8
  type Del = ReturnType<typeof Del>;
4
9
  export default Del;
@@ -1,25 +1,8 @@
1
1
  <script lang="ts">
2
- import type { Element } from 'hast';
3
2
  import type { Snippet } from 'svelte';
4
-
5
- let {
6
- node,
7
- props,
8
- className,
9
- type,
10
- children
11
- }: { node: Element; props: any; className: any; type: string; children: Snippet } = $props();
12
-
13
- // Import all element components
14
3
  import A from './A.svelte';
15
4
  import Blockquote from './Blockquote.svelte';
16
5
  import Code from './Code.svelte';
17
- import H1 from './H1.svelte';
18
- import H2 from './H2.svelte';
19
- import H3 from './H3.svelte';
20
- import H4 from './H4.svelte';
21
- import H5 from './H5.svelte';
22
- import H6 from './H6.svelte';
23
6
  import Hr from './Hr.svelte';
24
7
  import Image from './Image.svelte';
25
8
  import Li from './Li.svelte';
@@ -41,90 +24,58 @@
41
24
  import Em from './Em.svelte';
42
25
  import Del from './Del.svelte';
43
26
  import Alert from './Alert.svelte';
44
- import { useStreamdown } from '../Streamdown.svelte';
45
- import { type ElementProps } from './element.js';
46
-
47
- const streamdown = useStreamdown();
27
+ import type { StreamdownToken } from '../marked/index.js';
28
+ import Heading from './Heading.svelte';
29
+ let { token, children }: { token: StreamdownToken; children: Snippet } = $props();
48
30
  </script>
49
31
 
50
- {#if type === 'a'}
51
- <A {props} {className} {children} {node} />
52
- {:else if type === 'blockquote'}
53
- <Blockquote {props} {className} {children} {node} />
54
- {:else if type === 'code' && node?.properties.language === 'math'}
55
- <Math {props} {className} {children} {node} />
56
- {:else if type === 'code' && node?.position?.start.line === node?.position?.end.line}
57
- <InlineCode {props} {className} {children} {node} />
58
- {:else if type === 'code' && node?.properties.language === 'mermaid'}
59
- <Mermaid {props} {className} {children} {node} />
60
- {:else if type === 'code'}
61
- <Code {props} {className} {children} {node} />
62
- {:else if type === 'h1'}
63
- <H1 {props} {className} {children} {node} />
64
- {:else if type === 'h2'}
65
- <H2 {props} {className} {children} {node} />
66
- {:else if type === 'h3'}
67
- <H3 {props} {className} {children} {node} />
68
- {:else if type === 'h4'}
69
- <H4 {props} {className} {children} {node} />
70
- {:else if type === 'h5'}
71
- <H5 {props} {className} {children} {node} />
72
- {:else if type === 'h6'}
73
- <H6 {props} {className} {children} {node} />
74
- {:else if type === 'hr'}
75
- <Hr {children} {node} {props} {className} />
76
- {:else if type === 'img'}
77
- <Image
78
- src={node.properties.src as string}
79
- alt={node.properties.alt as string}
80
- {props}
81
- {className}
82
- {children}
83
- {node}
84
- />
85
- {:else if type === 'li'}
86
- <Li {props} {className} {children} {node} />
87
- {:else if type === 'ol'}
88
- <Ol {props} {className} {children} {node} />
89
- {:else if type === 'p'}
90
- <P {props} {className} {children} {node} />
91
- {:else if type === 'strong'}
92
- <Strong {props} {className} {children} {node} />
93
- {:else if type === 'sub'}
94
- <Sub {props} {className} {children} {node} />
95
- {:else if type === 'sup'}
96
- <Sup {props} {className} {children} {node} />
97
- {:else if type === 'table'}
98
- <Table {props} {className} {children} {node} />
99
- {:else if type === 'tbody'}
100
- <Tbody {props} {className} {children} {node} />
101
- {:else if type === 'td'}
102
- <Td {props} {className} {children} {node} />
103
- {:else if type === 'th'}
104
- <Th {props} {className} {children} {node} />
105
- {:else if type === 'thead'}
106
- <Thead {props} {className} {children} {node} />
107
- {:else if type === 'tr'}
108
- <Tr {props} {className} {children} {node} />
109
- {:else if type === 'ul'}
110
- <Ul {props} {className} {children} {node} />
111
- {:else if type === 'ol'}
112
- <Ol {props} {className} {children} {node} />
113
- {:else if type === 'br'}
114
- <br />
115
- {:else if type === 'em'}
116
- <Em {props} {className} {children} {node} />
117
- {:else if type === 'del'}
118
- <Del {props} {className} {children} {node} />
119
- {:else if type === 'alert'}
120
- <Alert {props} {className} {children} {node} />
121
- {:else}
122
- {@const snippet = streamdown.customElements?.[type] as Snippet<[ElementProps]> | undefined}
123
- {#if snippet}
124
- {@render snippet({ props, className, children, node })}
32
+ {#if token.type === 'heading'}
33
+ <Heading {token} {children} />
34
+ {:else if token.type === 'paragraph'}
35
+ <P {token} {children} />
36
+ {:else if token.type === 'blockquote'}
37
+ <Blockquote {token} {children} />
38
+ {:else if token.type === 'code' && token.lang === 'mermaid'}
39
+ <Mermaid {token} {children} />
40
+ {:else if token.type === 'code'}
41
+ <Code {token} {children} />
42
+ {:else if token.type === 'codespan'}
43
+ <InlineCode {token} {children} />
44
+ {:else if token.type === 'list'}
45
+ {#if token.ordered}
46
+ <Ol {token} {children} />
125
47
  {:else}
126
- {@render children?.()}
48
+ <Ul {token} {children} />
127
49
  {/if}
128
-
129
- <!-- Fallback for unsupported elements -->
50
+ {:else if token.type === 'list_item'}
51
+ <Li {token} {children} />
52
+ {:else if token.type === 'table'}
53
+ <Table {token} {children} />
54
+ {:else if token.type === 'tableRow' && token.isHeader}
55
+ <Thead {token} {children} />
56
+ {:else if token.type === 'tableRow' && !token.isHeader}
57
+ <Tr {token} {children} />
58
+ {:else if token.type === 'tableCell'}
59
+ <Td {token} {children} />
60
+ {:else if token.type === 'image'}
61
+ <Image {token} {children} />
62
+ {:else if token.type === 'link'}
63
+ <A {token} {children} />
64
+ {:else if token.type === 'strong'}
65
+ <Strong {token} {children} />
66
+ {:else if token.type === 'em'}
67
+ <Em {token} {children} />
68
+ {:else if token.type === 'del'}
69
+ <Del {token} {children} />
70
+ {:else if token.type === 'hr'}
71
+ <Hr {token} {children} />
72
+ {:else if token.type === 'br'}
73
+ <br />
74
+ {:else if token.type === 'math'}
75
+ <Math {token} {children} />
76
+ {:else if token.type === 'alert'}
77
+ <Alert {token} {children} />
78
+ {:else}
79
+ <!-- For tokens we don't handle specifically, render children or fallback -->
80
+ {@render children?.()}
130
81
  {/if}
@@ -1,10 +1,7 @@
1
- import type { Element } from 'hast';
2
1
  import type { Snippet } from 'svelte';
2
+ import type { StreamdownToken } from '../marked/index.js';
3
3
  type $$ComponentProps = {
4
- node: Element;
5
- props: any;
6
- className: any;
7
- type: string;
4
+ token: StreamdownToken;
8
5
  children: Snippet;
9
6
  };
10
7
  declare const Element: import("svelte").Component<$$ComponentProps, {}, "">;
@@ -1,23 +1,28 @@
1
1
  <script lang="ts">
2
2
  import { useStreamdown } from '../Streamdown.svelte';
3
- import { clsx } from 'clsx';
4
- import type { ElementProps } from './element.js';
5
3
  import Slot from './Slot.svelte';
4
+ import type { Tokens } from 'marked';
5
+ import type { Snippet } from 'svelte';
6
6
 
7
7
  const streamdown = useStreamdown();
8
8
 
9
- const { children, node, className, props }: ElementProps = $props();
9
+ const {
10
+ children,
11
+ token
12
+ }: {
13
+ children: Snippet;
14
+ token: Tokens.Em;
15
+ } = $props();
10
16
  </script>
11
17
 
12
18
  <Slot
13
19
  props={{
14
20
  children,
15
- node,
16
- ...props
21
+ token
17
22
  }}
18
23
  render={streamdown.snippets.em}
19
24
  >
20
- <em {...props} class={clsx(streamdown.theme.em.base, className)}>
25
+ <em class={streamdown.theme.em.base}>
21
26
  {@render children()}
22
27
  </em>
23
28
  </Slot>
@@ -1,4 +1,9 @@
1
- import type { ElementProps } from './element.js';
2
- declare const Em: import("svelte").Component<ElementProps, {}, "">;
1
+ import type { Tokens } from 'marked';
2
+ import type { Snippet } from 'svelte';
3
+ type $$ComponentProps = {
4
+ children: Snippet;
5
+ token: Tokens.Em;
6
+ };
7
+ declare const Em: import("svelte").Component<$$ComponentProps, {}, "">;
3
8
  type Em = ReturnType<typeof Em>;
4
9
  export default Em;
@@ -0,0 +1,25 @@
1
+ <script lang="ts">
2
+ import { useStreamdown } from '../Streamdown.svelte';
3
+ import Slot from './Slot.svelte';
4
+ import type { Tokens } from 'marked';
5
+ import type { Snippet } from 'svelte';
6
+
7
+ const streamdown = useStreamdown();
8
+
9
+ const { token, children }: { token: Tokens.Heading; children: Snippet } = $props();
10
+
11
+ const level = $derived(`h${token.depth}`) as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
12
+ const className = $derived(streamdown.theme[level].base);
13
+ </script>
14
+
15
+ <Slot
16
+ props={{
17
+ children,
18
+ token
19
+ }}
20
+ render={streamdown.snippets.heading}
21
+ >
22
+ <svelte:element this={level} class={className}>
23
+ {@render children()}
24
+ </svelte:element>
25
+ </Slot>