106 lines
No EOL
3.2 KiB
Svelte
106 lines
No EOL
3.2 KiB
Svelte
<script lang="ts">
|
|
import LexicalRenderer from './LexicalRenderer.svelte'
|
|
|
|
type TextNode = {
|
|
type: 'text'
|
|
text: string
|
|
format: number
|
|
}
|
|
|
|
type LineBreakNode = {
|
|
type: 'linebreak'
|
|
}
|
|
|
|
type UploadNode = {
|
|
type: 'upload'
|
|
relationTo: string
|
|
value: {
|
|
url: string
|
|
alt?: string
|
|
width?: number
|
|
height?: number
|
|
}
|
|
}
|
|
|
|
type LexicalNode = TextNode | LineBreakNode | UploadNode | {
|
|
type: 'paragraph' | 'heading' | 'root' | 'listitem' | 'list'
|
|
tag?: string
|
|
children: LexicalNode[]
|
|
format?: string
|
|
}
|
|
|
|
let { nodes }: { nodes: LexicalNode[] } = $props()
|
|
|
|
function isBold(format: number) { return (format & 1) !== 0 }
|
|
function isItalic(format: number) { return (format & 2) !== 0 }
|
|
function isStrikethrough(format: number) { return (format & 4) !== 0 }
|
|
function isUnderline(format: number) { return (format & 8) !== 0 }
|
|
function isCode(format: number) { return (format & 16) !== 0 }
|
|
</script>
|
|
|
|
{#each nodes as node}
|
|
{#if node.type === 'paragraph'}
|
|
{#if node.children?.length}
|
|
<p><LexicalRenderer nodes={node.children} /></p>
|
|
{:else}
|
|
<br />
|
|
{/if}
|
|
|
|
{:else if node.type === 'heading'}
|
|
{#if node.tag === 'h1'}
|
|
<h1><LexicalRenderer nodes={node.children} /></h1>
|
|
{:else if node.tag === 'h2'}
|
|
<h2><LexicalRenderer nodes={node.children} /></h2>
|
|
{:else if node.tag === 'h3'}
|
|
<h3><LexicalRenderer nodes={node.children} /></h3>
|
|
{:else if node.tag === 'h4'}
|
|
<h4><LexicalRenderer nodes={node.children} /></h4>
|
|
{:else if node.tag === 'h5'}
|
|
<h5><LexicalRenderer nodes={node.children} /></h5>
|
|
{:else if node.tag === 'h6'}
|
|
<h6><LexicalRenderer nodes={node.children} /></h6>
|
|
{/if}
|
|
|
|
{:else if node.type === 'list'}
|
|
{#if node.tag === 'ol'}
|
|
<ol><LexicalRenderer nodes={node.children} /></ol>
|
|
{:else}
|
|
<ul><LexicalRenderer nodes={node.children} /></ul>
|
|
{/if}
|
|
|
|
{:else if node.type === 'listitem'}
|
|
<li><LexicalRenderer nodes={node.children} /></li>
|
|
|
|
{:else if node.type === 'text'}
|
|
{#if isCode(node.format)}
|
|
<code>{node.text}</code>
|
|
{:else if isBold(node.format) && isItalic(node.format)}
|
|
<strong><em>{node.text}</em></strong>
|
|
{:else if isBold(node.format)}
|
|
<strong>{node.text}</strong>
|
|
{:else if isItalic(node.format)}
|
|
<em>{node.text}</em>
|
|
{:else if isStrikethrough(node.format)}
|
|
<s>{node.text}</s>
|
|
{:else if isUnderline(node.format)}
|
|
<u>{node.text}</u>
|
|
{:else}
|
|
{node.text}
|
|
{/if}
|
|
|
|
{:else if node.type === 'linebreak'}
|
|
<br />
|
|
|
|
{:else if node.type === 'upload'}
|
|
<figure class="my-6">
|
|
<img
|
|
src={node.value.url}
|
|
alt={node.value.alt ?? ''}
|
|
width={node.value.width}
|
|
height={node.value.height}
|
|
class="w-full"
|
|
loading="lazy"
|
|
/>
|
|
</figure>
|
|
{/if}
|
|
{/each} |