dso/apps/web/src/lib/components/ui/LexicalRenderer.svelte
Aron August Hohmann c452a505e2 first commit
2026-09-03 19:51:56 +02:00

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}