Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/editors/slate/static-markdown.tsx
1691 views
1
/*
2
Static Markdown
3
4
This is a react component that renders markdown text using React. See the
5
comments in mostly-static-markdown.tsx for more details, since that's a very
6
similar, but more complicated component.
7
8
A constraint of this component is that it should easily render in the next.js
9
application.
10
*/
11
12
import { CSSProperties, useEffect, useState } from "react";
13
import "./elements/init-ssr";
14
import { getStaticRender } from "./elements/register";
15
import Leaf from "./leaf";
16
import { markdown_to_slate as markdownToSlate } from "./markdown-to-slate";
17
import { ChangeContext } from "./use-change";
18
19
interface Props {
20
value: string;
21
style?: CSSProperties;
22
className?: string;
23
}
24
25
type PartialSlateEditor = any; // TODO
26
27
export default function StaticMarkdown({ value, style, className }: Props) {
28
const [editor, setEditor] = useState<PartialSlateEditor>({
29
children: markdownToSlate(value),
30
});
31
const [change, setChange] = useState<number>(0);
32
useEffect(() => {
33
setChange(change + 1);
34
if (change > 0) {
35
// no need to set it the first time because it is set in the useState initialization.
36
// and we *have* to set it there so it works for server side rendering and exporting to html/pdf.
37
setEditor({ children: markdownToSlate(value) });
38
}
39
}, [value]);
40
41
if (editor == null) {
42
return null;
43
}
44
45
return (
46
<ChangeContext.Provider
47
value={{
48
change,
49
editor,
50
setEditor: (editor) => {
51
setEditor(editor);
52
setChange(change + 1);
53
},
54
}}
55
>
56
<div style={{ width: "100%", ...style }} className={className}>
57
{editor.children.map((element, n) => {
58
return <RenderElement key={n} element={element} />;
59
})}
60
</div>
61
</ChangeContext.Provider>
62
);
63
}
64
65
function RenderElement({ element }) {
66
let children: React.JSX.Element[] = [];
67
if (element["children"]) {
68
let n = 0;
69
for (const child of element["children"]) {
70
children.push(<RenderElement key={n} element={child} />);
71
n += 1;
72
}
73
}
74
if (element["type"]) {
75
const C = getStaticRender(element.type);
76
return <C children={children} element={element} attributes={{} as any} />;
77
}
78
// It's text
79
return (
80
<Leaf leaf={element} text={{} as any} attributes={{} as any}>
81
{element["text"]}
82
</Leaf>
83
);
84
}
85
86