Path: blob/master/src/packages/frontend/editors/slate/elements/table/index.tsx
1698 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { CSSProperties as CSS } from "react";6import { register, SlateElement } from "../register";7import getStyles from "./style";89export interface Table extends SlateElement {10type: "table";11}1213export interface THead extends SlateElement {14type: "thead";15}1617export interface TBody extends SlateElement {18type: "tbody";19}2021export interface TR extends SlateElement {22type: "tr";23}2425export interface TH extends SlateElement {26type: "th";27align: "left" | "center" | "right";28}2930export interface TD extends SlateElement {31type: "td";32align: "left" | "center" | "right";33}3435function toSlate({ type, children, isEmpty, state }) {36if (type == "tbody" && isEmpty) {37// Special case -- if there are no children, do NOT include38// the tbody either in the slatejs document.39// In markdown a table can have 0 rows, but40// this is not possible to *render* in slatejs, due to41// DOM structure (there's always leaf nodes for the cursor).42return;43}44if (type == "th" || type == "td") {45let align = state.attrs?.[0]?.[1]?.split(":")?.[1] ?? "left";46if (align != "left" && align != "right" && align != "center") {47align = "left"; // should be impossible; makes typescript happy48}49return { type, children, align };50} else {51return { type, children };52}53}5455export const StaticElement = ({ attributes, children, element }) => {56switch (element.type) {57case "table":58const { divStyle, tableStyle } = getStyles();59return (60<div {...attributes} style={divStyle}>61<table style={tableStyle}>{children}</table>62</div>63);64case "thead":65return <thead {...attributes}>{children}</thead>;66case "tbody":67return <tbody {...attributes}>{children}</tbody>;68case "tr":69return <tr {...attributes}>{children}</tr>;70case "th":71return (72<th73{...attributes}74style={{ textAlign: element.align ?? "left" } as CSS}75>76{children}77</th>78);79case "td":80return (81<td82{...attributes}83style={{ textAlign: element.align ?? "left" } as CSS}84>85{children}86</td>87);88default:89throw Error("not a table element type " + element.type);90}91};9293register({94slateType: ["thead", "tbody", "tr", "th", "td"],95toSlate,96StaticElement,97});9899register({100slateType: "table",101toSlate,102StaticElement,103});104105106