grungnet/src/components/Markdown.js
2020-07-12 18:38:53 +10:00

161 lines
2.8 KiB
JavaScript

import React from "react";
import {
Text,
Image as UIImage,
Link as UILink,
Message,
Embed,
} from "theme-ui";
import ReactMarkdown from "react-markdown";
function Paragraph(props) {
return <Text variant="body2" {...props} />;
}
function Heading({ level, ...props }) {
const fontSize = level === 1 ? 5 : level === 2 ? 3 : 1;
return (
<Text
mt={2}
mb={1}
as={`h${level}`}
sx={{ fontSize }}
variant="heading"
{...props}
/>
);
}
function Image(props) {
if (props.src.endsWith(".mp4")) {
return (
<video
style={{ width: "100%", margin: "8px 0" }}
autoPlay
muted
playsInline
loop
controls
{...props}
/>
);
}
return <UIImage mt={2} sx={{ borderRadius: "4px" }} {...props} />;
}
function ListItem(props) {
return <Text as="li" variant="body2" {...props} />;
}
function Code({ children, value }) {
let variant = "";
if (value.startsWith("Warning:")) {
variant = "warning";
} else if (value.startsWith("Note:")) {
variant = "note";
}
return (
<Message
variant={variant}
color="hsl(210, 50%, 96%)"
my={2}
as="span"
sx={{ display: "block" }}
>
{children}
</Message>
);
}
function Table({ children }) {
return (
<Text
as="table"
my={4}
style={{ borderCollapse: "collapse", width: "100%" }}
>
{children}
</Text>
);
}
function TableHead(props) {
return (
<Text
as="thead"
variant="heading"
sx={{ textAlign: "left", "& > tr": { borderBottomWidth: "2px" } }}
{...props}
/>
);
}
function TableBody(props) {
return (
<Text
as="tbody"
variant="body2"
sx={{ borderBottomWidth: "1px", "& > tr": { borderBottomWidth: "1px" } }}
{...props}
/>
);
}
function TableRow({ children }) {
return (
<Text
as="tr"
sx={{
borderBottomStyle: "solid",
borderBottomColor: "border",
}}
>
{children}
</Text>
);
}
function TableCell({ children }) {
return (
<Text as="td" p={2}>
{children}
</Text>
);
}
function Link({ href, children }) {
const linkText = children[0].props.value;
if (linkText === "embed:") {
return <Embed src={href} my={2} />;
} else {
console.log(href);
return <UILink href={href}>{children}</UILink>;
}
}
function Markdown({ source, assets }) {
const renderers = {
paragraph: Paragraph,
heading: Heading,
image: Image,
link: Link,
listItem: ListItem,
inlineCode: Code,
table: Table,
tableHead: TableHead,
tableBody: TableBody,
tableRow: TableRow,
tableCell: TableCell,
};
return (
<ReactMarkdown
source={source}
renderers={renderers}
transformImageUri={(uri) => assets[uri]}
/>
);
}
export default Markdown;