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