svelte-streamdown 1.0.8 → 1.0.9
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.
- package/README.md +11 -5
- package/dist/Block.svelte +26 -10
- package/dist/Elements/Code.svelte +1 -1
- package/dist/Elements/Element.svelte +120 -37
- package/dist/Elements/FootnoteRef.svelte +113 -0
- package/dist/Elements/FootnoteRef.svelte.d.ts +7 -0
- package/dist/Elements/Image.svelte +3 -3
- package/dist/Elements/{A.svelte → Link.svelte} +3 -3
- package/dist/Elements/{A.svelte.d.ts → Link.svelte.d.ts} +3 -3
- package/dist/Elements/Math.svelte +3 -2
- package/dist/Elements/index.d.ts +5 -24
- package/dist/Elements/index.js +5 -24
- package/dist/Streamdown.d.ts +1 -1
- package/dist/Streamdown.svelte +7 -1
- package/dist/Streamdown.svelte.d.ts +6 -0
- package/dist/marked/index.d.ts +18 -5
- package/dist/marked/index.js +4 -0
- package/dist/marked/marked-alert.d.ts +2 -2
- package/dist/marked/marked-alert.js +18 -18
- package/dist/marked/marked-footnotes.d.ts +1 -0
- package/dist/marked/marked-footnotes.js +28 -8
- package/dist/marked/marked-list.d.ts +36 -0
- package/dist/marked/marked-list.js +215 -0
- package/dist/marked/marked-math.js +0 -3
- package/dist/marked/marked-subsup.d.ts +28 -0
- package/dist/marked/marked-subsup.js +44 -0
- package/dist/theme.d.ts +48 -42
- package/dist/theme.js +47 -43
- package/dist/utils/parse-incomplete-markdown.js +157 -0
- package/dist/utils/useClickOutside.svelte.d.ts +8 -0
- package/dist/utils/useClickOutside.svelte.js +42 -0
- package/dist/utils/useKeyDown.svelte.d.ts +5 -0
- package/dist/utils/useKeyDown.svelte.js +20 -0
- package/package.json +3 -1
- package/dist/Elements/Blockquote.svelte +0 -28
- package/dist/Elements/Blockquote.svelte.d.ts +0 -9
- package/dist/Elements/Del.svelte +0 -28
- package/dist/Elements/Del.svelte.d.ts +0 -9
- package/dist/Elements/Em.svelte +0 -28
- package/dist/Elements/Em.svelte.d.ts +0 -9
- package/dist/Elements/Heading.svelte +0 -25
- package/dist/Elements/Heading.svelte.d.ts +0 -9
- package/dist/Elements/Hr.svelte +0 -26
- package/dist/Elements/Hr.svelte.d.ts +0 -9
- package/dist/Elements/InlineCode.svelte +0 -28
- package/dist/Elements/InlineCode.svelte.d.ts +0 -9
- package/dist/Elements/Li.svelte +0 -28
- package/dist/Elements/Li.svelte.d.ts +0 -9
- package/dist/Elements/Ol.svelte +0 -30
- package/dist/Elements/Ol.svelte.d.ts +0 -9
- package/dist/Elements/P.svelte +0 -28
- package/dist/Elements/P.svelte.d.ts +0 -9
- package/dist/Elements/Strong.svelte +0 -28
- package/dist/Elements/Strong.svelte.d.ts +0 -9
- package/dist/Elements/Sub.svelte +0 -27
- package/dist/Elements/Sub.svelte.d.ts +0 -8
- package/dist/Elements/Sup.svelte +0 -28
- package/dist/Elements/Sup.svelte.d.ts +0 -8
- package/dist/Elements/Tbody.svelte +0 -24
- package/dist/Elements/Tbody.svelte.d.ts +0 -7
- package/dist/Elements/Td.svelte +0 -28
- package/dist/Elements/Td.svelte.d.ts +0 -9
- package/dist/Elements/Th.svelte +0 -28
- package/dist/Elements/Th.svelte.d.ts +0 -9
- package/dist/Elements/Thead.svelte +0 -27
- package/dist/Elements/Thead.svelte.d.ts +0 -9
- package/dist/Elements/Tr.svelte +0 -27
- package/dist/Elements/Tr.svelte.d.ts +0 -9
- package/dist/Elements/Ul.svelte +0 -28
- package/dist/Elements/Ul.svelte.d.ts +0 -9
- /package/dist/{hightlighter.svelte.d.ts → utils/hightlighter.svelte.d.ts} +0 -0
- /package/dist/{hightlighter.svelte.js → utils/hightlighter.svelte.js} +0 -0
package/README.md
CHANGED
|
@@ -30,7 +30,15 @@ Full support for GitHub Flavored Markdown including:
|
|
|
30
30
|
|
|
31
31
|
- Task lists
|
|
32
32
|
- Tables
|
|
33
|
-
- Strikethrough
|
|
33
|
+
- ~~Strikethrough~~
|
|
34
|
+
- Subscript (H~2~O)
|
|
35
|
+
- Superscript (E = mc^2^)
|
|
36
|
+
- Footnotes [^1]
|
|
37
|
+
|
|
38
|
+
[^1]:
|
|
39
|
+
Reference render in a popover by default.
|
|
40
|
+
with _rich_ **content** support
|
|
41
|
+
and multiline
|
|
34
42
|
|
|
35
43
|
### 💻 Interactive Code Blocks
|
|
36
44
|
|
|
@@ -133,6 +141,8 @@ This Svelte port maintains feature parity with the original [Streamdown](https:/
|
|
|
133
141
|
|
|
134
142
|
> [!NOTE]
|
|
135
143
|
> 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:
|
|
144
|
+
> 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.
|
|
145
|
+
> This ensures that all Streamdown's default styling is included in your Tailwind build process.
|
|
136
146
|
|
|
137
147
|
```css
|
|
138
148
|
@import 'tailwindcss';
|
|
@@ -140,10 +150,6 @@ This Svelte port maintains feature parity with the original [Streamdown](https:/
|
|
|
140
150
|
@source "../node_modules/svelte-streamdown/**/*";
|
|
141
151
|
```
|
|
142
152
|
|
|
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
153
|
## 🚀 Quick Start
|
|
148
154
|
|
|
149
155
|
### Basic Usage
|
package/dist/Block.svelte
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
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';
|
|
@@ -17,21 +20,27 @@
|
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
if (token.type === 'table') {
|
|
20
|
-
const headerRow =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
const headerRow = token.header?.length
|
|
24
|
+
? ({
|
|
25
|
+
type: 'tableRow',
|
|
26
|
+
raw: '',
|
|
27
|
+
tokens: token.header.map((cell) => ({
|
|
28
|
+
type: 'th',
|
|
29
|
+
raw: '',
|
|
30
|
+
...cell
|
|
31
|
+
})),
|
|
32
|
+
isHeader: true
|
|
33
|
+
} satisfies TableRow)
|
|
34
|
+
: null;
|
|
28
35
|
|
|
29
36
|
const rows = token.rows.reduce(
|
|
30
37
|
(acc, cells) => {
|
|
31
38
|
const row = {
|
|
32
39
|
type: 'tableRow',
|
|
40
|
+
raw: '',
|
|
33
41
|
tokens: cells.map((cell) => ({
|
|
34
|
-
type: '
|
|
42
|
+
type: 'td',
|
|
43
|
+
raw: '',
|
|
35
44
|
...cell
|
|
36
45
|
})),
|
|
37
46
|
isHeader: false
|
|
@@ -39,7 +48,14 @@
|
|
|
39
48
|
acc.push(row);
|
|
40
49
|
return acc;
|
|
41
50
|
},
|
|
42
|
-
|
|
51
|
+
headerRow
|
|
52
|
+
? ([
|
|
53
|
+
{
|
|
54
|
+
type: 'tableHead',
|
|
55
|
+
tokens: [headerRow]
|
|
56
|
+
}
|
|
57
|
+
] as StreamdownToken[])
|
|
58
|
+
: []
|
|
43
59
|
);
|
|
44
60
|
|
|
45
61
|
return rows;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { useStreamdown } from '../Streamdown.svelte';
|
|
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
|
|
|
@@ -1,80 +1,163 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
import
|
|
4
|
-
import Blockquote from './Blockquote.svelte';
|
|
3
|
+
import Link from './Link.svelte';
|
|
5
4
|
import Code from './Code.svelte';
|
|
6
|
-
import Hr from './Hr.svelte';
|
|
7
5
|
import Image from './Image.svelte';
|
|
8
|
-
import Li from './Li.svelte';
|
|
9
|
-
import Ol from './Ol.svelte';
|
|
10
|
-
import P from './P.svelte';
|
|
11
|
-
import Strong from './Strong.svelte';
|
|
12
|
-
import Sub from './Sub.svelte';
|
|
13
|
-
import Sup from './Sup.svelte';
|
|
14
6
|
import Table from './Table.svelte';
|
|
15
|
-
import Tbody from './Tbody.svelte';
|
|
16
|
-
import Td from './Td.svelte';
|
|
17
|
-
import Th from './Th.svelte';
|
|
18
|
-
import Thead from './Thead.svelte';
|
|
19
|
-
import Tr from './Tr.svelte';
|
|
20
|
-
import Ul from './Ul.svelte';
|
|
21
|
-
import InlineCode from './InlineCode.svelte';
|
|
22
7
|
import Mermaid from './Mermaid.svelte';
|
|
23
8
|
import Math from './Math.svelte';
|
|
24
|
-
import Em from './Em.svelte';
|
|
25
|
-
import Del from './Del.svelte';
|
|
26
9
|
import Alert from './Alert.svelte';
|
|
27
10
|
import type { StreamdownToken } from '../marked/index.js';
|
|
28
|
-
import
|
|
11
|
+
import Slot from './Slot.svelte';
|
|
12
|
+
import { useStreamdown } from '../Streamdown.svelte';
|
|
13
|
+
import FootnoteRef from './FootnoteRef.svelte';
|
|
29
14
|
let { token, children }: { token: StreamdownToken; children: Snippet } = $props();
|
|
15
|
+
const id = $props.id();
|
|
16
|
+
const streamdown = useStreamdown();
|
|
30
17
|
</script>
|
|
31
18
|
|
|
32
19
|
{#if token.type === 'heading'}
|
|
33
|
-
|
|
20
|
+
{@const level = `h${token.depth}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'}
|
|
21
|
+
{@const className = streamdown.theme[level].base}
|
|
22
|
+
<Slot
|
|
23
|
+
props={{
|
|
24
|
+
children,
|
|
25
|
+
token
|
|
26
|
+
}}
|
|
27
|
+
render={streamdown.snippets.heading}
|
|
28
|
+
>
|
|
29
|
+
<svelte:element this={level} class={className}>
|
|
30
|
+
{@render children()}
|
|
31
|
+
</svelte:element>
|
|
32
|
+
</Slot>
|
|
34
33
|
{:else if token.type === 'paragraph'}
|
|
35
|
-
<
|
|
34
|
+
<Slot props={{ children, token }} render={streamdown.snippets.paragraph}>
|
|
35
|
+
<p class={streamdown.theme.paragraph.base}>
|
|
36
|
+
{@render children()}
|
|
37
|
+
</p>
|
|
38
|
+
</Slot>
|
|
36
39
|
{:else if token.type === 'blockquote'}
|
|
37
|
-
<
|
|
40
|
+
<Slot props={{ children, token }} render={streamdown.snippets.blockquote}>
|
|
41
|
+
<blockquote class={streamdown.theme.blockquote.base}>
|
|
42
|
+
{@render children()}
|
|
43
|
+
</blockquote>
|
|
44
|
+
</Slot>
|
|
38
45
|
{:else if token.type === 'code' && token.lang === 'mermaid'}
|
|
39
46
|
<Mermaid {token} {children} />
|
|
40
47
|
{:else if token.type === 'code'}
|
|
41
48
|
<Code {token} {children} />
|
|
42
49
|
{:else if token.type === 'codespan'}
|
|
43
|
-
<
|
|
50
|
+
<Slot props={{ children, token }} render={streamdown.snippets.codespan}>
|
|
51
|
+
<code class={streamdown.theme.codespan.base}>
|
|
52
|
+
{token.text}
|
|
53
|
+
</code>
|
|
54
|
+
</Slot>
|
|
44
55
|
{:else if token.type === 'list'}
|
|
45
56
|
{#if token.ordered}
|
|
46
|
-
|
|
57
|
+
{@const firstItemValue = token.items[0]?.value || 1}
|
|
58
|
+
{@const counterName = `counter-${id}`}
|
|
59
|
+
<Slot props={{ children, token }} render={streamdown.snippets.ol}>
|
|
60
|
+
<ol style:list-style-type={token.listType} class={streamdown.theme.ol.base}>
|
|
61
|
+
{@render children()}
|
|
62
|
+
</ol>
|
|
63
|
+
</Slot>
|
|
47
64
|
{:else}
|
|
48
|
-
<
|
|
65
|
+
<Slot props={{ children, token }} render={streamdown.snippets.ul}>
|
|
66
|
+
<ul class={streamdown.theme.ul.base}>
|
|
67
|
+
{@render children()}
|
|
68
|
+
</ul>
|
|
69
|
+
</Slot>
|
|
49
70
|
{/if}
|
|
50
71
|
{:else if token.type === 'list_item'}
|
|
51
|
-
<
|
|
72
|
+
<Slot props={{ children, token }} render={streamdown.snippets.li}>
|
|
73
|
+
<li
|
|
74
|
+
style:list-style-type={token.task ? 'none' : undefined}
|
|
75
|
+
value={token.value}
|
|
76
|
+
class={streamdown.theme.li.base}
|
|
77
|
+
>
|
|
78
|
+
{#if token.task}
|
|
79
|
+
<input
|
|
80
|
+
disabled
|
|
81
|
+
type="checkbox"
|
|
82
|
+
checked={token.checked}
|
|
83
|
+
class={streamdown.theme.li.checkbox}
|
|
84
|
+
/>
|
|
85
|
+
{/if}
|
|
86
|
+
{@render children()}
|
|
87
|
+
</li>
|
|
88
|
+
</Slot>
|
|
52
89
|
{:else if token.type === 'table'}
|
|
53
90
|
<Table {token} {children} />
|
|
54
|
-
{:else if token.type === 'tableRow'
|
|
55
|
-
<
|
|
56
|
-
{
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
91
|
+
{:else if token.type === 'tableRow'}
|
|
92
|
+
<Slot props={{ token, children }} render={streamdown.snippets.tableRow}>
|
|
93
|
+
<tr class={streamdown.theme.tableRow.base}>
|
|
94
|
+
{@render children?.()}
|
|
95
|
+
</tr>
|
|
96
|
+
</Slot>
|
|
97
|
+
{:else if token.type === 'tableHead'}
|
|
98
|
+
<Slot props={{ token, children }} render={streamdown.snippets.tableHead}>
|
|
99
|
+
<thead class={streamdown.theme.tableHead.base}>
|
|
100
|
+
{@render children?.()}
|
|
101
|
+
</thead>
|
|
102
|
+
</Slot>
|
|
103
|
+
{:else if token.type === 'td'}
|
|
104
|
+
<Slot props={{ children, token }} render={streamdown.snippets.td}>
|
|
105
|
+
<td class={streamdown.theme.td.base}>
|
|
106
|
+
{@render children?.()}
|
|
107
|
+
</td>
|
|
108
|
+
</Slot>
|
|
109
|
+
{:else if token.type === 'th'}
|
|
110
|
+
<Slot props={{ children, token }} render={streamdown.snippets.th}>
|
|
111
|
+
<th class={streamdown.theme.th.base}>
|
|
112
|
+
{@render children?.()}
|
|
113
|
+
</th>
|
|
114
|
+
</Slot>
|
|
60
115
|
{:else if token.type === 'image'}
|
|
61
116
|
<Image {token} {children} />
|
|
62
117
|
{:else if token.type === 'link'}
|
|
63
|
-
<
|
|
118
|
+
<Link {token} {children} />
|
|
119
|
+
{:else if token.type === 'sub'}
|
|
120
|
+
<Slot props={{ children, token }} render={streamdown.snippets.sub}>
|
|
121
|
+
<sub class={streamdown.theme.sub.base}>
|
|
122
|
+
{@render children()}
|
|
123
|
+
</sub>
|
|
124
|
+
</Slot>
|
|
125
|
+
{:else if token.type === 'sup'}
|
|
126
|
+
<Slot props={{ children, token }} render={streamdown.snippets.sup}>
|
|
127
|
+
<sup class={streamdown.theme.sup.base}>
|
|
128
|
+
{@render children()}
|
|
129
|
+
</sup>
|
|
130
|
+
</Slot>
|
|
64
131
|
{:else if token.type === 'strong'}
|
|
65
|
-
<
|
|
132
|
+
<Slot props={{ children, token }} render={streamdown.snippets.strong}>
|
|
133
|
+
<strong class={streamdown.theme.strong.base}>
|
|
134
|
+
{@render children()}
|
|
135
|
+
</strong>
|
|
136
|
+
</Slot>
|
|
66
137
|
{:else if token.type === 'em'}
|
|
67
|
-
<
|
|
138
|
+
<Slot props={{ children, token }} render={streamdown.snippets.em}>
|
|
139
|
+
<em class={streamdown.theme.em.base}>
|
|
140
|
+
{@render children()}
|
|
141
|
+
</em>
|
|
142
|
+
</Slot>
|
|
68
143
|
{:else if token.type === 'del'}
|
|
69
|
-
<
|
|
144
|
+
<Slot props={{ children, token }} render={streamdown.snippets.del}>
|
|
145
|
+
<del class={streamdown.theme.del.base}>
|
|
146
|
+
{@render children()}
|
|
147
|
+
</del>
|
|
148
|
+
</Slot>
|
|
70
149
|
{:else if token.type === 'hr'}
|
|
71
|
-
<
|
|
150
|
+
<Slot props={{ children, token }} render={streamdown.snippets.hr}>
|
|
151
|
+
<hr class={streamdown.theme.hr.base} />
|
|
152
|
+
</Slot>
|
|
72
153
|
{:else if token.type === 'br'}
|
|
73
154
|
<br />
|
|
74
155
|
{:else if token.type === 'math'}
|
|
75
156
|
<Math {token} {children} />
|
|
76
157
|
{:else if token.type === 'alert'}
|
|
77
158
|
<Alert {token} {children} />
|
|
159
|
+
{:else if token.type === 'footnoteRef'}
|
|
160
|
+
<FootnoteRef {token} />
|
|
78
161
|
{:else}
|
|
79
162
|
<!-- For tokens we don't handle specifically, render children or fallback -->
|
|
80
163
|
{@render children?.()}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useStreamdown } from '../Streamdown.svelte';
|
|
3
|
+
import Slot from './Slot.svelte';
|
|
4
|
+
import type { FootnoteRef } from '../marked/marked-footnotes.js';
|
|
5
|
+
import { autoPlacement, computePosition, hide, offset, shift, size } from '@floating-ui/dom';
|
|
6
|
+
import { useClickOutside } from '../utils/useClickOutside.svelte.js';
|
|
7
|
+
import { scale } from 'svelte/transition';
|
|
8
|
+
import Block from '../Block.svelte';
|
|
9
|
+
import { useKeyDown } from '../utils/useKeyDown.svelte.js';
|
|
10
|
+
|
|
11
|
+
const streamdown = useStreamdown();
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
token
|
|
15
|
+
}: {
|
|
16
|
+
token: FootnoteRef;
|
|
17
|
+
} = $props();
|
|
18
|
+
|
|
19
|
+
let isOpen = $state(false);
|
|
20
|
+
|
|
21
|
+
let reference = $state<HTMLButtonElement>();
|
|
22
|
+
let content = $state<HTMLDialogElement>();
|
|
23
|
+
|
|
24
|
+
const clickOutside = useClickOutside({
|
|
25
|
+
get isActive() {
|
|
26
|
+
return isOpen;
|
|
27
|
+
},
|
|
28
|
+
callback: () => {
|
|
29
|
+
isOpen = false;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
useKeyDown({
|
|
34
|
+
keys: ['Escape'],
|
|
35
|
+
get isActive() {
|
|
36
|
+
return isOpen;
|
|
37
|
+
},
|
|
38
|
+
callback: () => {
|
|
39
|
+
isOpen = false;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const place = async (node: HTMLElement) => {
|
|
44
|
+
const middleware = [
|
|
45
|
+
hide(),
|
|
46
|
+
offset(0),
|
|
47
|
+
shift({
|
|
48
|
+
mainAxis: true
|
|
49
|
+
}),
|
|
50
|
+
autoPlacement({
|
|
51
|
+
allowedPlacements: ['top', 'top-end', 'top-start', 'bottom', 'bottom-end', 'bottom-start']
|
|
52
|
+
}),
|
|
53
|
+
size()
|
|
54
|
+
];
|
|
55
|
+
const { x, y, strategy, placement, middlewareData } = await computePosition(reference!, node, {
|
|
56
|
+
strategy: 'fixed',
|
|
57
|
+
middleware
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
Object.assign(node.style, {
|
|
61
|
+
position: strategy,
|
|
62
|
+
left: `${x}px`,
|
|
63
|
+
top: `${y}px`
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const popoverAttachment = (node: HTMLDialogElement) => {
|
|
68
|
+
content = node;
|
|
69
|
+
void place(node);
|
|
70
|
+
|
|
71
|
+
return () => {
|
|
72
|
+
//
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
{#if isOpen}
|
|
78
|
+
<Slot
|
|
79
|
+
props={{
|
|
80
|
+
token,
|
|
81
|
+
isOpen
|
|
82
|
+
}}
|
|
83
|
+
render={streamdown.snippets.footnotePopover}
|
|
84
|
+
>
|
|
85
|
+
<dialog
|
|
86
|
+
transition:scale|global={{ start: 0.95, duration: 100 }}
|
|
87
|
+
{@attach clickOutside.attachment}
|
|
88
|
+
{@attach popoverAttachment}
|
|
89
|
+
open
|
|
90
|
+
class={`${streamdown.theme.footnotePopover.base}`}
|
|
91
|
+
>
|
|
92
|
+
{#each token.content.lines as line}
|
|
93
|
+
<Block block={line} />
|
|
94
|
+
{/each}
|
|
95
|
+
</dialog>
|
|
96
|
+
</Slot>
|
|
97
|
+
{/if}
|
|
98
|
+
|
|
99
|
+
<Slot
|
|
100
|
+
props={{
|
|
101
|
+
token
|
|
102
|
+
}}
|
|
103
|
+
render={streamdown.snippets.footnoteRef}
|
|
104
|
+
>
|
|
105
|
+
<button
|
|
106
|
+
bind:this={reference}
|
|
107
|
+
class={streamdown.theme.footnoteRef.base}
|
|
108
|
+
onclick={() => (isOpen = !isOpen)}
|
|
109
|
+
{@attach clickOutside.attachment}
|
|
110
|
+
>
|
|
111
|
+
{token.label.replace('^', '')}
|
|
112
|
+
</button>
|
|
113
|
+
</Slot>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FootnoteRef } from '../marked/marked-footnotes.js';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
token: FootnoteRef;
|
|
4
|
+
};
|
|
5
|
+
declare const FootnoteRef: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
6
|
+
type FootnoteRef = ReturnType<typeof FootnoteRef>;
|
|
7
|
+
export default FootnoteRef;
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
children,
|
|
29
29
|
token
|
|
30
30
|
}}
|
|
31
|
-
render={streamdown.snippets.
|
|
31
|
+
render={streamdown.snippets.image}
|
|
32
32
|
>
|
|
33
|
-
<div class={streamdown.theme.
|
|
34
|
-
<img class={streamdown.theme.
|
|
33
|
+
<div class={streamdown.theme.image.base}>
|
|
34
|
+
<img class={streamdown.theme.image.image} src={transformedUrl} alt={token.text} />
|
|
35
35
|
</div>
|
|
36
36
|
</Slot>
|
|
37
37
|
{:else}
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
children,
|
|
31
31
|
token
|
|
32
32
|
}}
|
|
33
|
-
render={streamdown.snippets.
|
|
33
|
+
render={streamdown.snippets.link}
|
|
34
34
|
>
|
|
35
35
|
<a
|
|
36
|
-
class={streamdown.theme.
|
|
36
|
+
class={streamdown.theme.link.base}
|
|
37
37
|
href={transformedUrl}
|
|
38
38
|
target="_blank"
|
|
39
39
|
rel="noopener noreferrer"
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
</Slot>
|
|
44
44
|
{:else}
|
|
45
45
|
<span
|
|
46
|
-
class={streamdown.theme.
|
|
46
|
+
class={streamdown.theme.link.blocked}
|
|
47
47
|
title={token.title ? `Blocked URL: ${token.href}` : undefined}
|
|
48
48
|
>
|
|
49
49
|
{@render children()} [blocked]
|
|
@@ -4,6 +4,6 @@ type $$ComponentProps = {
|
|
|
4
4
|
children: Snippet;
|
|
5
5
|
token: Tokens.Link;
|
|
6
6
|
};
|
|
7
|
-
declare const
|
|
8
|
-
type
|
|
9
|
-
export default
|
|
7
|
+
declare const Link: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type Link = ReturnType<typeof Link>;
|
|
9
|
+
export default Link;
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
: streamdown.katexConfig || {})
|
|
43
43
|
};
|
|
44
44
|
const code = token.text;
|
|
45
|
+
console.log({ code });
|
|
45
46
|
try {
|
|
46
47
|
return katexInstance.renderToString(code, config);
|
|
47
48
|
} catch (error) {
|
|
@@ -60,13 +61,13 @@
|
|
|
60
61
|
render={streamdown.snippets.math}
|
|
61
62
|
>
|
|
62
63
|
{#if isInline}
|
|
63
|
-
<span bind:this={inner} class={streamdown.theme.
|
|
64
|
+
<span bind:this={inner} class={streamdown.theme.math.inline}>
|
|
64
65
|
{@html html}
|
|
65
66
|
</span>
|
|
66
67
|
{:else}
|
|
67
68
|
<div class="h-fit w-full">
|
|
68
69
|
<div class="overflow-x-auto">
|
|
69
|
-
<div bind:this={inner} class={streamdown.theme.math.
|
|
70
|
+
<div bind:this={inner} class={streamdown.theme.math.block}>
|
|
70
71
|
{@html html}
|
|
71
72
|
</div>
|
|
72
73
|
</div>
|
package/dist/Elements/index.d.ts
CHANGED
|
@@ -1,28 +1,9 @@
|
|
|
1
|
-
export { default as
|
|
2
|
-
export { default as Blockquote } from './Blockquote.svelte';
|
|
1
|
+
export { default as Alert } from './Alert.svelte';
|
|
3
2
|
export { default as Code } from './Code.svelte';
|
|
4
|
-
export { default as
|
|
5
|
-
export { default as Heading } from './Heading.svelte';
|
|
6
|
-
export { default as Hr } from './Hr.svelte';
|
|
3
|
+
export { default as Element } from './Element.svelte';
|
|
7
4
|
export { default as Image } from './Image.svelte';
|
|
8
|
-
export { default as
|
|
9
|
-
export { default as
|
|
10
|
-
export { default as
|
|
5
|
+
export { default as Link } from './Link.svelte';
|
|
6
|
+
export { default as Math } from './Math.svelte';
|
|
7
|
+
export { default as Mermaid } from './Mermaid.svelte';
|
|
11
8
|
export { default as Slot } from './Slot.svelte';
|
|
12
|
-
export { default as Strong } from './Strong.svelte';
|
|
13
|
-
export { default as Sub } from './Sub.svelte';
|
|
14
|
-
export { default as Sup } from './Sup.svelte';
|
|
15
9
|
export { default as Table } from './Table.svelte';
|
|
16
|
-
export { default as Tbody } from './Tbody.svelte';
|
|
17
|
-
export { default as Td } from './Td.svelte';
|
|
18
|
-
export { default as Th } from './Th.svelte';
|
|
19
|
-
export { default as Thead } from './Thead.svelte';
|
|
20
|
-
export { default as Tr } from './Tr.svelte';
|
|
21
|
-
export { default as Ul } from './Ul.svelte';
|
|
22
|
-
export { default as InlineCode } from './InlineCode.svelte';
|
|
23
|
-
export { default as Mermaid } from './Mermaid.svelte';
|
|
24
|
-
export { default as Math } from './Math.svelte';
|
|
25
|
-
export { default as Em } from './Em.svelte';
|
|
26
|
-
export { default as Del } from './Del.svelte';
|
|
27
|
-
export { default as Alert } from './Alert.svelte';
|
|
28
|
-
export { default as Element } from './Element.svelte';
|
package/dist/Elements/index.js
CHANGED
|
@@ -1,28 +1,9 @@
|
|
|
1
|
-
export { default as
|
|
2
|
-
export { default as Blockquote } from './Blockquote.svelte';
|
|
1
|
+
export { default as Alert } from './Alert.svelte';
|
|
3
2
|
export { default as Code } from './Code.svelte';
|
|
4
|
-
export { default as
|
|
5
|
-
export { default as Heading } from './Heading.svelte';
|
|
6
|
-
export { default as Hr } from './Hr.svelte';
|
|
3
|
+
export { default as Element } from './Element.svelte';
|
|
7
4
|
export { default as Image } from './Image.svelte';
|
|
8
|
-
export { default as
|
|
9
|
-
export { default as
|
|
10
|
-
export { default as
|
|
5
|
+
export { default as Link } from './Link.svelte';
|
|
6
|
+
export { default as Math } from './Math.svelte';
|
|
7
|
+
export { default as Mermaid } from './Mermaid.svelte';
|
|
11
8
|
export { default as Slot } from './Slot.svelte';
|
|
12
|
-
export { default as Strong } from './Strong.svelte';
|
|
13
|
-
export { default as Sub } from './Sub.svelte';
|
|
14
|
-
export { default as Sup } from './Sup.svelte';
|
|
15
9
|
export { default as Table } from './Table.svelte';
|
|
16
|
-
export { default as Tbody } from './Tbody.svelte';
|
|
17
|
-
export { default as Td } from './Td.svelte';
|
|
18
|
-
export { default as Th } from './Th.svelte';
|
|
19
|
-
export { default as Thead } from './Thead.svelte';
|
|
20
|
-
export { default as Tr } from './Tr.svelte';
|
|
21
|
-
export { default as Ul } from './Ul.svelte';
|
|
22
|
-
export { default as InlineCode } from './InlineCode.svelte';
|
|
23
|
-
export { default as Mermaid } from './Mermaid.svelte';
|
|
24
|
-
export { default as Math } from './Math.svelte';
|
|
25
|
-
export { default as Em } from './Em.svelte';
|
|
26
|
-
export { default as Del } from './Del.svelte';
|
|
27
|
-
export { default as Alert } from './Alert.svelte';
|
|
28
|
-
export { default as Element } from './Element.svelte';
|
package/dist/Streamdown.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { MermaidConfig } from 'mermaid';
|
|
|
5
5
|
import type { KatexOptions } from 'katex';
|
|
6
6
|
import type { StreamdownContext } from './Streamdown.svelte';
|
|
7
7
|
import type { StreamdownToken } from './marked/index.js';
|
|
8
|
-
type PredefinedElements = '
|
|
8
|
+
type PredefinedElements = 'heading' | 'paragraph' | 'blockquote' | 'code' | 'codespan' | 'ul' | 'ol' | 'li' | 'table' | 'tableRow' | 'tableHead' | 'td' | 'th' | 'image' | 'link' | 'strong' | 'em' | 'del' | 'hr' | 'br' | 'math' | 'alert' | 'mermaid' | 'footnoteRef' | 'footnotePopover' | 'sup' | 'sub';
|
|
9
9
|
export type Snippets = {
|
|
10
10
|
[K in PredefinedElements]?: Snippet<[
|
|
11
11
|
{
|
package/dist/Streamdown.svelte
CHANGED
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
theme: Theme;
|
|
9
9
|
}
|
|
10
10
|
export class StreamdownContext {
|
|
11
|
+
footnotes = {
|
|
12
|
+
refs: new Map<string, FootnoteRef>(),
|
|
13
|
+
footnotes: new Map<string, Footnote>()
|
|
14
|
+
};
|
|
11
15
|
constructor(props: Omit<StreamdownProps, keyof Snippets | 'class'> & { snippets: Snippets }) {
|
|
12
16
|
bind(this, props);
|
|
13
17
|
setContext('streamdown', this);
|
|
@@ -30,7 +34,9 @@
|
|
|
30
34
|
import { mergeTheme, type Theme, shadcnTheme } from './theme.js';
|
|
31
35
|
import type { BundledTheme } from 'shiki';
|
|
32
36
|
import { parseBlocks } from './marked/index.js';
|
|
33
|
-
|
|
37
|
+
import { SvelteMap } from 'svelte/reactivity';
|
|
38
|
+
import type { FootnoteRef } from './marked/marked-footnotes.js';
|
|
39
|
+
import type { Footnote } from './marked/marked-footnotes.js';
|
|
34
40
|
let {
|
|
35
41
|
content = '',
|
|
36
42
|
class: className,
|
|
@@ -4,6 +4,10 @@ export interface StreamdownContext extends Omit<StreamdownProps, keyof Snippets
|
|
|
4
4
|
theme: Theme;
|
|
5
5
|
}
|
|
6
6
|
export declare class StreamdownContext {
|
|
7
|
+
footnotes: {
|
|
8
|
+
refs: Map<string, FootnoteRef>;
|
|
9
|
+
footnotes: Map<string, Footnote>;
|
|
10
|
+
};
|
|
7
11
|
constructor(props: Omit<StreamdownProps, keyof Snippets | 'class'> & {
|
|
8
12
|
snippets: Snippets;
|
|
9
13
|
});
|
|
@@ -13,6 +17,8 @@ import type { Snippets, StreamdownProps } from './Streamdown.js';
|
|
|
13
17
|
import 'katex/dist/katex.min.css';
|
|
14
18
|
import { type Theme } from './theme.js';
|
|
15
19
|
import type { BundledTheme } from 'shiki';
|
|
20
|
+
import type { FootnoteRef } from './marked/marked-footnotes.js';
|
|
21
|
+
import type { Footnote } from './marked/marked-footnotes.js';
|
|
16
22
|
declare const Streamdown: import("svelte").Component<StreamdownProps, {}, "streamdown">;
|
|
17
23
|
type Streamdown = ReturnType<typeof Streamdown>;
|
|
18
24
|
export default Streamdown;
|
package/dist/marked/index.d.ts
CHANGED
|
@@ -2,15 +2,28 @@ import { type MarkedToken, type Tokens } from 'marked';
|
|
|
2
2
|
import { type AlertToken } from './marked-alert.js';
|
|
3
3
|
import { type FootnoteToken } from './marked-footnotes.js';
|
|
4
4
|
import { type MathToken } from './marked-math.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import { type SubSupToken } from './marked-subsup.js';
|
|
6
|
+
import { type ListItemToken, type ListToken } from './marked-list.js';
|
|
7
|
+
export type StreamdownToken = Exclude<MarkedToken, Tokens.List | Tokens.ListItem> | ListToken | ListItemToken | MathToken | AlertToken | FootnoteToken | SubSupToken | TableRow | TD | TH | TableHead;
|
|
8
|
+
export type TD = Tokens.TableCell & {
|
|
9
|
+
type: 'td';
|
|
10
|
+
raw: string;
|
|
11
|
+
};
|
|
12
|
+
export type TH = Tokens.TableCell & {
|
|
13
|
+
type: 'th';
|
|
14
|
+
raw: string;
|
|
8
15
|
};
|
|
9
16
|
export type TableRow = {
|
|
10
17
|
type: 'tableRow';
|
|
11
|
-
|
|
18
|
+
raw: string;
|
|
19
|
+
tokens: (TD | TH)[];
|
|
12
20
|
isHeader: boolean;
|
|
13
21
|
};
|
|
22
|
+
export type TableHead = {
|
|
23
|
+
type: 'tableHead';
|
|
24
|
+
raw: string;
|
|
25
|
+
tokens: TableRow[];
|
|
26
|
+
};
|
|
14
27
|
export declare const lex: (markdown: string) => StreamdownToken[];
|
|
15
28
|
export declare const parseBlocks: (markdown: string) => string[];
|
|
16
|
-
export type { MathToken, AlertToken, FootnoteToken };
|
|
29
|
+
export type { MathToken, AlertToken, FootnoteToken, SubSupToken };
|