diff options
Diffstat (limited to 'packages/markdown/component/Markdown.astro')
-rw-r--r-- | packages/markdown/component/Markdown.astro | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/packages/markdown/component/Markdown.astro b/packages/markdown/component/Markdown.astro new file mode 100644 index 000000000..a88fdbf34 --- /dev/null +++ b/packages/markdown/component/Markdown.astro @@ -0,0 +1,54 @@ +--- +export interface Props { + content?: string; +} + +// NOTE(fks): We are most likely moving this component out of Astro core +// in a few weeks. Checking the name like this is a bit of a hack, but we +// intentionally don't want to add an SSR flag for others to read from, just yet. +if (Astro.redirect.name !== '_onlyAvailableInSSR') { + console.error(`\x1B[31mThe <Markdown> component is not available in SSR. See https://github.com/withastro/rfcs/discussions/179 for more info.\x1B[39m`); +} + +const dedent = (str: string) => { + const _str = str.split('\n').filter(s => s.trimStart().length > 0); + if (_str.length === 0) { + return str.trimStart(); + } + const trimmedSpace = _str[0].replace(_str[0].trimStart(), ''); + return str + .split('\n') + .map((ln) => ln.startsWith(trimmedSpace) ? ln.replace(trimmedSpace, '') : ln) + .join('\n'); +} + +// Internal props that should not be part of the external interface. +interface InternalProps extends Props { + $scope: string; +} + +let { content, class: className } = Astro.props as InternalProps; +let html = null; +let htmlContent = ''; + +// If no content prop provided, use the slot. +if (!content) { + content = await Astro.slots.render('default'); + if (content !== undefined && content !== null) { + content = dedent(content); + } +} + +if (content) { + htmlContent = await (Astro as any).__renderMarkdown(content, { + mode: 'md', + $: { + scopedClassName: className, + }, + }); +} + +html = htmlContent; +--- + +{html ? <Fragment set:html={html} /> : <slot />} |