Added rich text parsing
This commit is contained in:
parent
d11114528c
commit
a588f81803
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
import RTNode from "./components/RTNode.astro";
|
||||
|
||||
interface Props {
|
||||
content: {
|
||||
root: {
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const { content } = Astro.props;
|
||||
---
|
||||
|
||||
{
|
||||
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||
}
|
||||
|
||||
<div class="rich-text">
|
||||
{content.root.children.map((node) => <RTNode node={node} />)}
|
||||
</div>
|
||||
|
||||
{
|
||||
/* ------------------------------------------- CSS -------------------------------------------- */
|
||||
}
|
||||
|
||||
<style>
|
||||
.rich-text {
|
||||
& li[checkbox]::marker {
|
||||
content: "☐";
|
||||
}
|
||||
|
||||
& li[checkbox][checked]::marker {
|
||||
content: "☒";
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
type BasicNode = {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
|
||||
interface Props {
|
||||
node: BasicNode;
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
---
|
||||
|
||||
<p>
|
||||
{
|
||||
`Unknown node type: ${node.type}. Please contact website technical administrator.`
|
||||
}
|
||||
</p>
|
|
@ -0,0 +1,45 @@
|
|||
---
|
||||
import RTError from "../RTError.astro";
|
||||
import RTNode from "../RTNode.astro";
|
||||
import RTCustomLink from "./components/RTCustomLink.astro";
|
||||
import RTInternalLink from "./components/RTInternalLink.astro";
|
||||
|
||||
interface Props {
|
||||
node: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
version: number;
|
||||
fields: {
|
||||
linkType: "internal" | "custom";
|
||||
doc: any;
|
||||
url: string;
|
||||
newTab: boolean;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
};
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
---
|
||||
|
||||
{
|
||||
node.fields.linkType === "custom" ? (
|
||||
<RTCustomLink href={node.fields.url} newTab={node.fields.newTab}>
|
||||
{node.children.map((node) => (
|
||||
<RTNode node={node} />
|
||||
))}
|
||||
</RTCustomLink>
|
||||
) : node.fields.linkType === "internal" ? (
|
||||
<RTInternalLink doc={node.fields.doc}>
|
||||
{node.children.map((node) => (
|
||||
<RTNode node={node} />
|
||||
))}
|
||||
</RTInternalLink>
|
||||
) : (
|
||||
<RTError node={node} />
|
||||
)
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
interface Props {
|
||||
href: string;
|
||||
newTab: boolean;
|
||||
}
|
||||
|
||||
const { href, newTab } = Astro.props;
|
||||
---
|
||||
|
||||
<a
|
||||
href={href}
|
||||
target={newTab ? "_blank" : undefined}
|
||||
rel={newTab ? "noopener noreferrer" : undefined}
|
||||
>
|
||||
<slot />
|
||||
</a>
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
import { getI18n } from "translations/translations";
|
||||
|
||||
interface Props {
|
||||
doc: {
|
||||
relationTo: string;
|
||||
value: any;
|
||||
};
|
||||
}
|
||||
|
||||
const { doc } = Astro.props;
|
||||
const { getLocalizedUrl } = await getI18n(Astro.locals.currentLocale);
|
||||
---
|
||||
|
||||
{
|
||||
doc.relationTo === "folders" ? (
|
||||
<a href={getLocalizedUrl(`/folders/${doc.value.slug}`)}>
|
||||
<slot />
|
||||
</a>
|
||||
) : (
|
||||
<p>{`Unknown internal link: ${doc.relationTo}. Please contact website technical administrator.`}</p>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
import RTBasicListItem from "./components/RTBasicListItem.astro";
|
||||
import RTCheckListItem from "./components/RTCheckListItem.astro";
|
||||
|
||||
interface Props {
|
||||
node: {
|
||||
type: string;
|
||||
version: number;
|
||||
format: number;
|
||||
text: string;
|
||||
listType: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
[k: string]: unknown;
|
||||
};
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
---
|
||||
|
||||
{
|
||||
node.listType === "number" ? (
|
||||
<ol>
|
||||
{node.children.map((node) => (
|
||||
<RTBasicListItem node={node} />
|
||||
))}
|
||||
</ol>
|
||||
) : node.listType === "bullet" ? (
|
||||
<ul>
|
||||
{node.children.map((node) => (
|
||||
<RTBasicListItem node={node} />
|
||||
))}
|
||||
</ul>
|
||||
) : node.listType === "check" ? (
|
||||
<ul>
|
||||
{node.children.map((node) => (
|
||||
<RTCheckListItem node={node} />
|
||||
))}
|
||||
</ul>
|
||||
) : (
|
||||
<p>
|
||||
{`Unknown list type: ${node.listType}. Please contact website technical administrator.`}
|
||||
</p>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
import RTNode from "../../RTNode.astro";
|
||||
|
||||
interface Props {
|
||||
node: {
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
type: string;
|
||||
version: number;
|
||||
format: number;
|
||||
text: string;
|
||||
listType: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
---
|
||||
|
||||
<li>{node.children.map((node) => <RTNode node={node} />)}</li>
|
|
@ -0,0 +1,40 @@
|
|||
---
|
||||
import { Icon } from "astro-icon/components";
|
||||
import RTNode from "../../RTNode.astro";
|
||||
|
||||
interface Props {
|
||||
node: {
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
type: string;
|
||||
version: number;
|
||||
format: number;
|
||||
text: string;
|
||||
listType: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
---
|
||||
|
||||
<li>
|
||||
<Icon
|
||||
name={node.checked
|
||||
? "material-symbols:check-box"
|
||||
: "material-symbols:check-box-outline-blank"}
|
||||
/>
|
||||
{node.children.map((node) => <RTNode node={node} />)}
|
||||
</li>
|
||||
|
||||
<style>
|
||||
li {
|
||||
&::marker {
|
||||
content: ""
|
||||
}
|
||||
margin-left: -16px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
import RTParagraph from "./RTParagraph.astro";
|
||||
import RTList from "./RTList/RTList.astro";
|
||||
import RTError from "./RTError.astro";
|
||||
import RTText from "./RTText/RTText.astro";
|
||||
import RTLink from "./RTLink/RTLink.astro";
|
||||
|
||||
interface Props {
|
||||
node: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
|
||||
let NodeElement;
|
||||
switch (node.type) {
|
||||
case "paragraph":
|
||||
NodeElement = RTParagraph;
|
||||
break;
|
||||
|
||||
case "list":
|
||||
NodeElement = RTList;
|
||||
break;
|
||||
|
||||
case "text":
|
||||
NodeElement = RTText;
|
||||
break;
|
||||
|
||||
case "link":
|
||||
NodeElement = RTLink;
|
||||
break;
|
||||
|
||||
default:
|
||||
NodeElement = RTError;
|
||||
break;
|
||||
}
|
||||
---
|
||||
|
||||
<NodeElement node={node} />
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
import RTNode from "./RTNode.astro";
|
||||
|
||||
interface Props {
|
||||
node: {
|
||||
type: string;
|
||||
version: number;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
[k: string]: unknown;
|
||||
};
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
---
|
||||
|
||||
{
|
||||
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||
}
|
||||
|
||||
<p>{node.children.map((node) => <RTNode node={node} />)}</p>
|
||||
|
||||
{
|
||||
/* ------------------------------------------- CSS -------------------------------------------- */
|
||||
}
|
||||
|
||||
<style>
|
||||
p {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
import ConditionalWrapper from "components/ConditionalWrapper.astro";
|
||||
import RTBold from "./components/RTBold.astro";
|
||||
import RTItalic from "./components/RTItalic.astro";
|
||||
import RTUnderline from "./components/RTUnderline.astro";
|
||||
import RTLineThrough from "./components/RTLineThrough.astro";
|
||||
import RTSubscript from "./components/RTSubscript.astro";
|
||||
import RTSuperscript from "./components/RTSuperscript.astro";
|
||||
import RTInlineCode from "./components/RTInlineCode.astro";
|
||||
|
||||
interface Props {
|
||||
node: {
|
||||
type: string;
|
||||
version: number;
|
||||
format: number;
|
||||
text: string;
|
||||
[k: string]: unknown;
|
||||
};
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
---
|
||||
|
||||
<ConditionalWrapper wrapper={RTBold} condition={Boolean(node.format & 1)}>
|
||||
<ConditionalWrapper wrapper={RTItalic} condition={Boolean(node.format & 2)}>
|
||||
<ConditionalWrapper wrapper={RTLineThrough} condition={Boolean(node.format & 4)}>
|
||||
<ConditionalWrapper wrapper={RTUnderline} condition={Boolean(node.format & 8)}>
|
||||
<ConditionalWrapper
|
||||
wrapper={RTInlineCode}
|
||||
condition={Boolean(node.format & 16)}
|
||||
>
|
||||
<ConditionalWrapper
|
||||
wrapper={RTSubscript}
|
||||
condition={Boolean(node.format & 32)}
|
||||
>
|
||||
<ConditionalWrapper
|
||||
wrapper={RTSuperscript}
|
||||
condition={Boolean(node.format & 64)}
|
||||
>
|
||||
{node.text}
|
||||
</ConditionalWrapper>
|
||||
</ConditionalWrapper>
|
||||
</ConditionalWrapper>
|
||||
</ConditionalWrapper>
|
||||
</ConditionalWrapper>
|
||||
</ConditionalWrapper>
|
||||
</ConditionalWrapper>
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
|
||||
---
|
||||
|
||||
<b><slot /></b>
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
|
||||
---
|
||||
|
||||
<span><slot /></span>
|
||||
|
||||
<style>
|
||||
|
||||
span {
|
||||
font-family: monospace;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
|
||||
---
|
||||
|
||||
<i><slot /></i>
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
|
||||
---
|
||||
|
||||
<span><slot /></span>
|
||||
|
||||
<style>
|
||||
span {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
|
||||
---
|
||||
|
||||
<sub><slot /></sub>
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
|
||||
---
|
||||
|
||||
<sup><slot /></sup>
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
|
||||
---
|
||||
|
||||
<span><slot /></span>
|
||||
|
||||
<style>
|
||||
span {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue