svelte-streamdown 0.0.1
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 +58 -0
- package/dist/Block.svelte +34 -0
- package/dist/Block.svelte.d.ts +6 -0
- package/dist/Elements/A.svelte +48 -0
- package/dist/Elements/A.svelte.d.ts +4 -0
- package/dist/Elements/Alert.svelte +78 -0
- package/dist/Elements/Alert.svelte.d.ts +4 -0
- package/dist/Elements/Blockquote.svelte +26 -0
- package/dist/Elements/Blockquote.svelte.d.ts +4 -0
- package/dist/Elements/Code.svelte +123 -0
- package/dist/Elements/Code.svelte.d.ts +4 -0
- package/dist/Elements/Del.svelte +24 -0
- package/dist/Elements/Del.svelte.d.ts +4 -0
- package/dist/Elements/Element.svelte +122 -0
- package/dist/Elements/Element.svelte.d.ts +12 -0
- package/dist/Elements/Em.svelte +23 -0
- package/dist/Elements/Em.svelte.d.ts +4 -0
- package/dist/Elements/H1.svelte +23 -0
- package/dist/Elements/H1.svelte.d.ts +4 -0
- package/dist/Elements/H2.svelte +23 -0
- package/dist/Elements/H2.svelte.d.ts +4 -0
- package/dist/Elements/H3.svelte +23 -0
- package/dist/Elements/H3.svelte.d.ts +4 -0
- package/dist/Elements/H4.svelte +23 -0
- package/dist/Elements/H4.svelte.d.ts +4 -0
- package/dist/Elements/H5.svelte +23 -0
- package/dist/Elements/H5.svelte.d.ts +4 -0
- package/dist/Elements/H6.svelte +23 -0
- package/dist/Elements/H6.svelte.d.ts +4 -0
- package/dist/Elements/Hr.svelte +20 -0
- package/dist/Elements/Hr.svelte.d.ts +4 -0
- package/dist/Elements/Image.svelte +49 -0
- package/dist/Elements/Image.svelte.d.ts +4 -0
- package/dist/Elements/InlineCode.svelte +23 -0
- package/dist/Elements/InlineCode.svelte.d.ts +4 -0
- package/dist/Elements/Li.svelte +23 -0
- package/dist/Elements/Li.svelte.d.ts +4 -0
- package/dist/Elements/Math.svelte +73 -0
- package/dist/Elements/Math.svelte.d.ts +5 -0
- package/dist/Elements/Mermaid.svelte +80 -0
- package/dist/Elements/Mermaid.svelte.d.ts +4 -0
- package/dist/Elements/Ol.svelte +23 -0
- package/dist/Elements/Ol.svelte.d.ts +4 -0
- package/dist/Elements/P.svelte +23 -0
- package/dist/Elements/P.svelte.d.ts +4 -0
- package/dist/Elements/Slot.svelte +19 -0
- package/dist/Elements/Slot.svelte.d.ts +9 -0
- package/dist/Elements/Strong.svelte +23 -0
- package/dist/Elements/Strong.svelte.d.ts +4 -0
- package/dist/Elements/Sub.svelte +23 -0
- package/dist/Elements/Sub.svelte.d.ts +4 -0
- package/dist/Elements/Sup.svelte +23 -0
- package/dist/Elements/Sup.svelte.d.ts +4 -0
- package/dist/Elements/Table.svelte +25 -0
- package/dist/Elements/Table.svelte.d.ts +4 -0
- package/dist/Elements/Tbody.svelte +23 -0
- package/dist/Elements/Tbody.svelte.d.ts +4 -0
- package/dist/Elements/Td.svelte +23 -0
- package/dist/Elements/Td.svelte.d.ts +4 -0
- package/dist/Elements/Th.svelte +23 -0
- package/dist/Elements/Th.svelte.d.ts +4 -0
- package/dist/Elements/Thead.svelte +23 -0
- package/dist/Elements/Thead.svelte.d.ts +4 -0
- package/dist/Elements/Tr.svelte +23 -0
- package/dist/Elements/Tr.svelte.d.ts +4 -0
- package/dist/Elements/Ul.svelte +23 -0
- package/dist/Elements/Ul.svelte.d.ts +4 -0
- package/dist/Elements/element.d.ts +8 -0
- package/dist/Elements/element.js +1 -0
- package/dist/Elements/index.d.ts +34 -0
- package/dist/Elements/index.js +34 -0
- package/dist/Streamdown.d.ts +83 -0
- package/dist/Streamdown.js +1 -0
- package/dist/Streamdown.svelte +128 -0
- package/dist/Streamdown.svelte.d.ts +18 -0
- package/dist/hightlighter.svelte.d.ts +25 -0
- package/dist/hightlighter.svelte.js +413 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/theme.d.ts +247 -0
- package/dist/theme.js +138 -0
- package/dist/utils/alerts.d.ts +12 -0
- package/dist/utils/alerts.js +207 -0
- package/dist/utils/bind.d.ts +1 -0
- package/dist/utils/bind.js +6 -0
- package/dist/utils/copy.svelte.d.ts +7 -0
- package/dist/utils/copy.svelte.js +35 -0
- package/dist/utils/parse-blocks.d.ts +1 -0
- package/dist/utils/parse-blocks.js +40 -0
- package/dist/utils/parse-incomplete-markdown.d.ts +1 -0
- package/dist/utils/parse-incomplete-markdown.js +442 -0
- package/dist/utils/parse.d.ts +3 -0
- package/dist/utils/parse.js +144 -0
- package/dist/utils/save.d.ts +1 -0
- package/dist/utils/save.js +11 -0
- package/dist/utils/url.d.ts +2 -0
- package/dist/utils/url.js +71 -0
- package/package.json +92 -0
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Svelte library
|
|
2
|
+
|
|
3
|
+
Everything you need to build a Svelte library, powered by [`sv`](https://npmjs.com/package/sv).
|
|
4
|
+
|
|
5
|
+
Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
|
|
6
|
+
|
|
7
|
+
## Creating a project
|
|
8
|
+
|
|
9
|
+
If you're seeing this, you've probably already done this step. Congrats!
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
# create a new project in the current directory
|
|
13
|
+
npx sv create
|
|
14
|
+
|
|
15
|
+
# create a new project in my-app
|
|
16
|
+
npx sv create my-app
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Developing
|
|
20
|
+
|
|
21
|
+
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
npm run dev
|
|
25
|
+
|
|
26
|
+
# or start the server and open the app in a new browser tab
|
|
27
|
+
npm run dev -- --open
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
|
|
31
|
+
|
|
32
|
+
## Building
|
|
33
|
+
|
|
34
|
+
To build your library:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
npm pack
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
To create a production version of your showcase app:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
npm run build
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
You can preview the production build with `npm run preview`.
|
|
47
|
+
|
|
48
|
+
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
|
|
49
|
+
|
|
50
|
+
## Publishing
|
|
51
|
+
|
|
52
|
+
Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
|
|
53
|
+
|
|
54
|
+
To publish your library to [npm](https://www.npmjs.com):
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
npm publish
|
|
58
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script lang="ts">
|
|
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
|
+
import Element from './Elements/Element.svelte';
|
|
7
|
+
let {
|
|
8
|
+
block
|
|
9
|
+
}: {
|
|
10
|
+
block: string;
|
|
11
|
+
} = $props();
|
|
12
|
+
|
|
13
|
+
const streamdownContext = useStreamdown();
|
|
14
|
+
const root = $derived(parseMarkdown(streamdownContext, parseIncompleteMarkdown(block.trim())));
|
|
15
|
+
</script>
|
|
16
|
+
|
|
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}
|
|
31
|
+
{/each}
|
|
32
|
+
{/snippet}
|
|
33
|
+
|
|
34
|
+
{@render renderChildren(root.children)}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useStreamdown } from '../Streamdown.svelte';
|
|
3
|
+
import { transformUrl } from '../utils/url.js';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import type { ElementProps } from './element.js';
|
|
6
|
+
import Slot from './Slot.svelte';
|
|
7
|
+
|
|
8
|
+
const streamdown = useStreamdown();
|
|
9
|
+
|
|
10
|
+
const { children, className, node, props }: ElementProps = $props();
|
|
11
|
+
|
|
12
|
+
const transformedUrl = $derived(
|
|
13
|
+
transformUrl(
|
|
14
|
+
node.properties.href,
|
|
15
|
+
streamdown.allowedLinkPrefixes ?? [],
|
|
16
|
+
streamdown.defaultOrigin
|
|
17
|
+
)
|
|
18
|
+
);
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
{#if transformedUrl}
|
|
22
|
+
<Slot
|
|
23
|
+
props={{
|
|
24
|
+
href: transformedUrl,
|
|
25
|
+
target: '_blank',
|
|
26
|
+
rel: 'noopener noreferrer',
|
|
27
|
+
children,
|
|
28
|
+
node,
|
|
29
|
+
props,
|
|
30
|
+
className
|
|
31
|
+
}}
|
|
32
|
+
render={streamdown.snippets.a}
|
|
33
|
+
>
|
|
34
|
+
<a
|
|
35
|
+
{...props}
|
|
36
|
+
class={clsx(streamdown.theme.a.base, className)}
|
|
37
|
+
href={transformedUrl}
|
|
38
|
+
target="_blank"
|
|
39
|
+
rel="noopener noreferrer"
|
|
40
|
+
>
|
|
41
|
+
{@render children()}
|
|
42
|
+
</a>
|
|
43
|
+
</Slot>
|
|
44
|
+
{:else}
|
|
45
|
+
<span class={streamdown.theme.a.blocked} title={`Blocked URL: ${node.properties.href}`}>
|
|
46
|
+
{@render children()} [blocked]
|
|
47
|
+
</span>
|
|
48
|
+
{/if}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
const icons = {
|
|
3
|
+
note: `<circle cx="12" cy="12" r="10" /><path d="M12 16v-4" /><path d="M12 8h.01" />`,
|
|
4
|
+
caution: `<circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/>`,
|
|
5
|
+
important: `<path
|
|
6
|
+
d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"
|
|
7
|
+
/><path d="M7 11h10" /><path d="M7 15h6" /><path d="M7 7h8" />`,
|
|
8
|
+
tip: `<path
|
|
9
|
+
d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"
|
|
10
|
+
/><path d="M9 18h6" /><path d="M10 22h4" />`,
|
|
11
|
+
warning: `<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" /><path
|
|
12
|
+
d="M12 9v4"
|
|
13
|
+
/><path d="M12 17h.01" />`
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
import { useStreamdown } from '../Streamdown.svelte';
|
|
17
|
+
import { clsx } from 'clsx';
|
|
18
|
+
import type { ElementProps } from './element.js';
|
|
19
|
+
import Slot from './Slot.svelte';
|
|
20
|
+
|
|
21
|
+
const streamdown = useStreamdown();
|
|
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
|
+
});
|
|
38
|
+
|
|
39
|
+
// Extract icon from node properties
|
|
40
|
+
const icon = $derived((node.properties.icon as string) || '');
|
|
41
|
+
const title = $derived(streamdown.translations?.alert?.[alertType] || alertType);
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<Slot
|
|
45
|
+
props={{
|
|
46
|
+
children,
|
|
47
|
+
alertType,
|
|
48
|
+
icon,
|
|
49
|
+
node,
|
|
50
|
+
props,
|
|
51
|
+
className
|
|
52
|
+
}}
|
|
53
|
+
render={streamdown.snippets.alert}
|
|
54
|
+
>
|
|
55
|
+
<div
|
|
56
|
+
{...props}
|
|
57
|
+
class={clsx(streamdown.theme.alert.base, className, streamdown.theme.alert[alertType])}
|
|
58
|
+
>
|
|
59
|
+
<div data-alert-title class={streamdown.theme.alert.title}>
|
|
60
|
+
<svg
|
|
61
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
62
|
+
width="24"
|
|
63
|
+
height="24"
|
|
64
|
+
viewBox="0 0 24 24"
|
|
65
|
+
fill="none"
|
|
66
|
+
stroke-width="2"
|
|
67
|
+
stroke-linecap="round"
|
|
68
|
+
stroke-linejoin="round"
|
|
69
|
+
class={streamdown.theme.alert.icon}
|
|
70
|
+
>
|
|
71
|
+
<!-- {@html icon} -->
|
|
72
|
+
{@html icons[alertType]}
|
|
73
|
+
</svg>
|
|
74
|
+
{title}
|
|
75
|
+
</div>
|
|
76
|
+
{@render children()}
|
|
77
|
+
</div>
|
|
78
|
+
</Slot>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useStreamdown } from '../Streamdown.svelte';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import type { ElementProps } from './element.js';
|
|
5
|
+
import Slot from './Slot.svelte';
|
|
6
|
+
|
|
7
|
+
const streamdown = useStreamdown();
|
|
8
|
+
|
|
9
|
+
const { children, node, className, props }: ElementProps = $props();
|
|
10
|
+
|
|
11
|
+
console.log({ node });
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<Slot
|
|
15
|
+
props={{
|
|
16
|
+
children,
|
|
17
|
+
node,
|
|
18
|
+
props,
|
|
19
|
+
className
|
|
20
|
+
}}
|
|
21
|
+
render={streamdown.snippets.blockquote}
|
|
22
|
+
>
|
|
23
|
+
<blockquote {...props} class={clsx(streamdown.theme.blockquote.base, className)}>
|
|
24
|
+
{@render children()}
|
|
25
|
+
</blockquote>
|
|
26
|
+
</Slot>
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { setContext } from 'svelte';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import type { BundledLanguage, BundledTheme } from 'shiki';
|
|
5
|
+
import { useStreamdown } from '../Streamdown.svelte';
|
|
6
|
+
import { save } from '../utils/save.js';
|
|
7
|
+
import { useCopy } from '../utils/copy.svelte.js';
|
|
8
|
+
import { highlighter, languageExtensionMap } from '../hightlighter.svelte.js';
|
|
9
|
+
import { clsx } from 'clsx';
|
|
10
|
+
import type { ElementProps } from './element.js';
|
|
11
|
+
|
|
12
|
+
let { node, className, props }: ElementProps = $props();
|
|
13
|
+
|
|
14
|
+
const streamdown = useStreamdown();
|
|
15
|
+
const themes = $derived(streamdown.shikiTheme);
|
|
16
|
+
let codeContent = $derived((node.children[0] as any).value);
|
|
17
|
+
const language = $derived(node.properties.language as string);
|
|
18
|
+
const copy = useCopy({
|
|
19
|
+
get content() {
|
|
20
|
+
return codeContent;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Download button functionality
|
|
25
|
+
|
|
26
|
+
const downloadCode = () => {
|
|
27
|
+
try {
|
|
28
|
+
const extension =
|
|
29
|
+
language && language in languageExtensionMap
|
|
30
|
+
? languageExtensionMap[language as keyof typeof languageExtensionMap]
|
|
31
|
+
: 'txt';
|
|
32
|
+
const filename = `file.${extension}`;
|
|
33
|
+
const mimeType = 'text/plain';
|
|
34
|
+
save(filename, codeContent, mimeType);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error('Failed to download file:', error);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<div {...props} class={clsx(streamdown.theme.code.container, className)} data-language={language}>
|
|
42
|
+
<div class={clsx(streamdown.theme.code.header)} data-code-block-header data-language={language}>
|
|
43
|
+
<span class={streamdown.theme.code.language}>{language}</span>
|
|
44
|
+
<div class="flex items-center gap-2">
|
|
45
|
+
<!-- Download button snippet -->
|
|
46
|
+
<button
|
|
47
|
+
class={streamdown.theme.code.button}
|
|
48
|
+
onclick={downloadCode}
|
|
49
|
+
title="Download file"
|
|
50
|
+
type="button"
|
|
51
|
+
>
|
|
52
|
+
{@render downloadIcon()}
|
|
53
|
+
</button>
|
|
54
|
+
|
|
55
|
+
<button class={streamdown.theme.code.button} onclick={copy.copy} type="button">
|
|
56
|
+
{@render copyIcon()}
|
|
57
|
+
</button>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
<div style="height: fit-content; width: 100%;" class="relative overflow-visible">
|
|
61
|
+
<div class={streamdown.theme.code.base}>
|
|
62
|
+
{#await highlighter.isReady(themes, language as any)}
|
|
63
|
+
{@render Skeleton()}
|
|
64
|
+
{:then}
|
|
65
|
+
{@const code = highlighter.highlightCode(
|
|
66
|
+
codeContent,
|
|
67
|
+
language as any,
|
|
68
|
+
themes,
|
|
69
|
+
streamdown.theme.code.pre
|
|
70
|
+
)}
|
|
71
|
+
{@html code}
|
|
72
|
+
{/await}
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
{#snippet Skeleton()}
|
|
78
|
+
{@const lines = codeContent.split('\n')}
|
|
79
|
+
<!-- -->
|
|
80
|
+
<pre class={streamdown.theme.code.pre}><!-- -->
|
|
81
|
+
<!-- --><code
|
|
82
|
+
><!-- -->{#each lines as line}<!-- --><span class={streamdown.theme.code.skeleton}
|
|
83
|
+
>{line}</span
|
|
84
|
+
><!-- -->
|
|
85
|
+
<!-- -->{/each}<!-- --></code
|
|
86
|
+
><!-- -->
|
|
87
|
+
</pre>
|
|
88
|
+
{/snippet}
|
|
89
|
+
{#snippet copyIcon()}
|
|
90
|
+
<svg
|
|
91
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
92
|
+
width="100%"
|
|
93
|
+
height="100%"
|
|
94
|
+
viewBox="0 0 24 24"
|
|
95
|
+
fill="none"
|
|
96
|
+
stroke="currentColor"
|
|
97
|
+
stroke-width="2"
|
|
98
|
+
stroke-linecap="round"
|
|
99
|
+
stroke-linejoin="round"
|
|
100
|
+
class="lucide lucide-clipboard-icon lucide-clipboard"
|
|
101
|
+
><rect width="8" height="4" x="8" y="2" rx="1" ry="1" /><path
|
|
102
|
+
d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"
|
|
103
|
+
/></svg
|
|
104
|
+
>
|
|
105
|
+
{/snippet}
|
|
106
|
+
|
|
107
|
+
{#snippet downloadIcon()}
|
|
108
|
+
<svg
|
|
109
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
110
|
+
width="100%"
|
|
111
|
+
height="100%"
|
|
112
|
+
viewBox="0 0 24 24"
|
|
113
|
+
fill="none"
|
|
114
|
+
stroke="currentColor"
|
|
115
|
+
stroke-width="2"
|
|
116
|
+
stroke-linecap="round"
|
|
117
|
+
stroke-linejoin="round"
|
|
118
|
+
class="lucide lucide-download-icon lucide-download"
|
|
119
|
+
><path d="M12 15V3" /><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><path
|
|
120
|
+
d="m7 10 5 5 5-5"
|
|
121
|
+
/></svg
|
|
122
|
+
>
|
|
123
|
+
{/snippet}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useStreamdown } from '../Streamdown.svelte';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import type { ElementProps } from './element.js';
|
|
5
|
+
import Slot from './Slot.svelte';
|
|
6
|
+
|
|
7
|
+
const streamdown = useStreamdown();
|
|
8
|
+
|
|
9
|
+
const { children, node, className, props }: ElementProps = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<Slot
|
|
13
|
+
props={{
|
|
14
|
+
children,
|
|
15
|
+
node,
|
|
16
|
+
props,
|
|
17
|
+
className
|
|
18
|
+
}}
|
|
19
|
+
render={streamdown.snippets.del}
|
|
20
|
+
>
|
|
21
|
+
<del {...props} class={clsx(streamdown.theme.del.base, className)}>
|
|
22
|
+
{@render children()}
|
|
23
|
+
</del>
|
|
24
|
+
</Slot>
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Element } from 'hast';
|
|
3
|
+
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
|
+
import A from './A.svelte';
|
|
15
|
+
import Blockquote from './Blockquote.svelte';
|
|
16
|
+
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
|
+
import Hr from './Hr.svelte';
|
|
24
|
+
import Image from './Image.svelte';
|
|
25
|
+
import Li from './Li.svelte';
|
|
26
|
+
import Ol from './Ol.svelte';
|
|
27
|
+
import P from './P.svelte';
|
|
28
|
+
import Strong from './Strong.svelte';
|
|
29
|
+
import Sub from './Sub.svelte';
|
|
30
|
+
import Sup from './Sup.svelte';
|
|
31
|
+
import Table from './Table.svelte';
|
|
32
|
+
import Tbody from './Tbody.svelte';
|
|
33
|
+
import Td from './Td.svelte';
|
|
34
|
+
import Th from './Th.svelte';
|
|
35
|
+
import Thead from './Thead.svelte';
|
|
36
|
+
import Tr from './Tr.svelte';
|
|
37
|
+
import Ul from './Ul.svelte';
|
|
38
|
+
import InlineCode from './InlineCode.svelte';
|
|
39
|
+
import Mermaid from './Mermaid.svelte';
|
|
40
|
+
import Math from './Math.svelte';
|
|
41
|
+
import Em from './Em.svelte';
|
|
42
|
+
import Del from './Del.svelte';
|
|
43
|
+
import Alert from './Alert.svelte';
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
{#if type === 'a'}
|
|
47
|
+
<A {props} {className} {children} {node} />
|
|
48
|
+
{:else if type === 'blockquote'}
|
|
49
|
+
<Blockquote {props} {className} {children} {node} />
|
|
50
|
+
{:else if type === 'code' && node?.properties.language === 'math'}
|
|
51
|
+
<Math {props} {className} {children} {node} />
|
|
52
|
+
{:else if type === 'code' && node?.position?.start.line === node?.position?.end.line}
|
|
53
|
+
<InlineCode {props} {className} {children} {node} />
|
|
54
|
+
{:else if type === 'code' && node?.properties.language === 'mermaid'}
|
|
55
|
+
<Mermaid {props} {className} {children} {node} />
|
|
56
|
+
{:else if type === 'code'}
|
|
57
|
+
<Code {props} {className} {children} {node} />
|
|
58
|
+
{:else if type === 'h1'}
|
|
59
|
+
<H1 {props} {className} {children} {node} />
|
|
60
|
+
{:else if type === 'h2'}
|
|
61
|
+
<H2 {props} {className} {children} {node} />
|
|
62
|
+
{:else if type === 'h3'}
|
|
63
|
+
<H3 {props} {className} {children} {node} />
|
|
64
|
+
{:else if type === 'h4'}
|
|
65
|
+
<H4 {props} {className} {children} {node} />
|
|
66
|
+
{:else if type === 'h5'}
|
|
67
|
+
<H5 {props} {className} {children} {node} />
|
|
68
|
+
{:else if type === 'h6'}
|
|
69
|
+
<H6 {props} {className} {children} {node} />
|
|
70
|
+
{:else if type === 'hr'}
|
|
71
|
+
<Hr {children} {node} {props} {className} />
|
|
72
|
+
{:else if type === 'img'}
|
|
73
|
+
<Image
|
|
74
|
+
src={node.properties.src as string}
|
|
75
|
+
alt={node.properties.alt as string}
|
|
76
|
+
{props}
|
|
77
|
+
{className}
|
|
78
|
+
{children}
|
|
79
|
+
{node}
|
|
80
|
+
/>
|
|
81
|
+
{:else if type === 'li'}
|
|
82
|
+
<Li {props} {className} {children} {node} />
|
|
83
|
+
{:else if type === 'ol'}
|
|
84
|
+
<Ol {props} {className} {children} {node} />
|
|
85
|
+
{:else if type === 'p'}
|
|
86
|
+
<P {props} {className} {children} {node} />
|
|
87
|
+
{:else if type === 'strong'}
|
|
88
|
+
<Strong {props} {className} {children} {node} />
|
|
89
|
+
{:else if type === 'sub'}
|
|
90
|
+
<Sub {props} {className} {children} {node} />
|
|
91
|
+
{:else if type === 'sup'}
|
|
92
|
+
<Sup {props} {className} {children} {node} />
|
|
93
|
+
{:else if type === 'table'}
|
|
94
|
+
<Table {props} {className} {children} {node} />
|
|
95
|
+
{:else if type === 'tbody'}
|
|
96
|
+
<Tbody {props} {className} {children} {node} />
|
|
97
|
+
{:else if type === 'td'}
|
|
98
|
+
<Td {props} {className} {children} {node} />
|
|
99
|
+
{:else if type === 'th'}
|
|
100
|
+
<Th {props} {className} {children} {node} />
|
|
101
|
+
{:else if type === 'thead'}
|
|
102
|
+
<Thead {props} {className} {children} {node} />
|
|
103
|
+
{:else if type === 'tr'}
|
|
104
|
+
<Tr {props} {className} {children} {node} />
|
|
105
|
+
{:else if type === 'ul'}
|
|
106
|
+
<Ul {props} {className} {children} {node} />
|
|
107
|
+
{:else if type === 'ol'}
|
|
108
|
+
<Ol {props} {className} {children} {node} />
|
|
109
|
+
{:else if type === 'br'}
|
|
110
|
+
<br />
|
|
111
|
+
{:else if type === 'em'}
|
|
112
|
+
<Em {props} {className} {children} {node} />
|
|
113
|
+
{:else if type === 'ins'}
|
|
114
|
+
<!-- <Ins {props} {children} {node} /> -->
|
|
115
|
+
{:else if type === 'del'}
|
|
116
|
+
<Del {props} {className} {children} {node} />
|
|
117
|
+
{:else if type === 'alert'}
|
|
118
|
+
<Alert {props} {className} {children} {node} />
|
|
119
|
+
{:else}
|
|
120
|
+
<!-- Fallback for unsupported elements -->
|
|
121
|
+
{@render children?.()}
|
|
122
|
+
{/if}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Element } from 'hast';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
node: Element;
|
|
5
|
+
props: any;
|
|
6
|
+
className: any;
|
|
7
|
+
type: string;
|
|
8
|
+
children: Snippet;
|
|
9
|
+
};
|
|
10
|
+
declare const Element: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
11
|
+
type Element = ReturnType<typeof Element>;
|
|
12
|
+
export default Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useStreamdown } from '../Streamdown.svelte';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import type { ElementProps } from './element.js';
|
|
5
|
+
import Slot from './Slot.svelte';
|
|
6
|
+
|
|
7
|
+
const streamdown = useStreamdown();
|
|
8
|
+
|
|
9
|
+
const { children, node, className, props }: ElementProps = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<Slot
|
|
13
|
+
props={{
|
|
14
|
+
children,
|
|
15
|
+
node,
|
|
16
|
+
...props
|
|
17
|
+
}}
|
|
18
|
+
render={streamdown.snippets.em}
|
|
19
|
+
>
|
|
20
|
+
<em {...props} class={clsx(streamdown.theme.em.base, className)}>
|
|
21
|
+
{@render children()}
|
|
22
|
+
</em>
|
|
23
|
+
</Slot>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useStreamdown } from '../Streamdown.svelte';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import type { ElementProps } from './element.js';
|
|
5
|
+
import Slot from './Slot.svelte';
|
|
6
|
+
|
|
7
|
+
const streamdown = useStreamdown();
|
|
8
|
+
|
|
9
|
+
const { children, node, className, props }: ElementProps = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<Slot
|
|
13
|
+
props={{
|
|
14
|
+
children,
|
|
15
|
+
node,
|
|
16
|
+
...props
|
|
17
|
+
}}
|
|
18
|
+
render={streamdown.snippets.h1}
|
|
19
|
+
>
|
|
20
|
+
<h1 {...props} class={clsx(streamdown.theme.h1.base, className)}>
|
|
21
|
+
{@render children()}
|
|
22
|
+
</h1>
|
|
23
|
+
</Slot>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useStreamdown } from '../Streamdown.svelte';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import type { ElementProps } from './element.js';
|
|
5
|
+
import Slot from './Slot.svelte';
|
|
6
|
+
|
|
7
|
+
const streamdown = useStreamdown();
|
|
8
|
+
|
|
9
|
+
const { children, node, className, props }: ElementProps = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<Slot
|
|
13
|
+
props={{
|
|
14
|
+
children,
|
|
15
|
+
node,
|
|
16
|
+
...props
|
|
17
|
+
}}
|
|
18
|
+
render={streamdown.snippets.h2}
|
|
19
|
+
>
|
|
20
|
+
<h2 {...props} class={clsx(streamdown.theme.h2.base, className)}>
|
|
21
|
+
{@render children()}
|
|
22
|
+
</h2>
|
|
23
|
+
</Slot>
|