Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/editors/slate/elements/table/index.tsx
1698 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { CSSProperties as CSS } from "react";
7
import { register, SlateElement } from "../register";
8
import getStyles from "./style";
9
10
export interface Table extends SlateElement {
11
type: "table";
12
}
13
14
export interface THead extends SlateElement {
15
type: "thead";
16
}
17
18
export interface TBody extends SlateElement {
19
type: "tbody";
20
}
21
22
export interface TR extends SlateElement {
23
type: "tr";
24
}
25
26
export interface TH extends SlateElement {
27
type: "th";
28
align: "left" | "center" | "right";
29
}
30
31
export interface TD extends SlateElement {
32
type: "td";
33
align: "left" | "center" | "right";
34
}
35
36
function toSlate({ type, children, isEmpty, state }) {
37
if (type == "tbody" && isEmpty) {
38
// Special case -- if there are no children, do NOT include
39
// the tbody either in the slatejs document.
40
// In markdown a table can have 0 rows, but
41
// this is not possible to *render* in slatejs, due to
42
// DOM structure (there's always leaf nodes for the cursor).
43
return;
44
}
45
if (type == "th" || type == "td") {
46
let align = state.attrs?.[0]?.[1]?.split(":")?.[1] ?? "left";
47
if (align != "left" && align != "right" && align != "center") {
48
align = "left"; // should be impossible; makes typescript happy
49
}
50
return { type, children, align };
51
} else {
52
return { type, children };
53
}
54
}
55
56
export const StaticElement = ({ attributes, children, element }) => {
57
switch (element.type) {
58
case "table":
59
const { divStyle, tableStyle } = getStyles();
60
return (
61
<div {...attributes} style={divStyle}>
62
<table style={tableStyle}>{children}</table>
63
</div>
64
);
65
case "thead":
66
return <thead {...attributes}>{children}</thead>;
67
case "tbody":
68
return <tbody {...attributes}>{children}</tbody>;
69
case "tr":
70
return <tr {...attributes}>{children}</tr>;
71
case "th":
72
return (
73
<th
74
{...attributes}
75
style={{ textAlign: element.align ?? "left" } as CSS}
76
>
77
{children}
78
</th>
79
);
80
case "td":
81
return (
82
<td
83
{...attributes}
84
style={{ textAlign: element.align ?? "left" } as CSS}
85
>
86
{children}
87
</td>
88
);
89
default:
90
throw Error("not a table element type " + element.type);
91
}
92
};
93
94
register({
95
slateType: ["thead", "tbody", "tr", "th", "td"],
96
toSlate,
97
StaticElement,
98
});
99
100
register({
101
slateType: "table",
102
toSlate,
103
StaticElement,
104
});
105
106