import { css, cx } from "@emotion/css";
import { isEqual } from "@guanghechen/equal";
import type { Table } from "@yozora/ast";
import React from "react";
import { astClasses } from "../context";
import { NodesRenderer } from "../NodesRenderer";
/**
* Render yozora `table`, `tableRow` and `tableCell`.
*
* @see https://www.npmjs.com/package/@yozora/ast#table
* @see https://www.npmjs.com/package/@yozora/ast#tablecell
* @see https://www.npmjs.com/package/@yozora/ast#tablerow
* @see https://www.npmjs.com/package/@yozora/tokenizer-table
* @see https://www.npmjs.com/package/@yozora/tokenizer-table-row
* @see https://www.npmjs.com/package/@yozora/tokenizer-table-cell
*/
export class TableRenderer extends React.Component
{
public override shouldComponentUpdate(nextProperties: Readonly): boolean {
const properties = this.props;
return (
!isEqual(properties.columns, nextProperties.columns) || !isEqual(properties.children, nextProperties.children)
);
}
public override render(): React.ReactElement {
const { columns, children: rows } = this.props;
const aligns = columns.map(col => col.align ?? undefined);
const [ths, ...tds] = rows.map(row =>
row.children.map((cell, index) => ),
);
return (
{ths.map((children, index) => (
{children}
|
))}
{tds.map((row, rowIndex) => (
{row.map((children, index) => (
{children}
|
))}
))}
);
}
}
interface IThProperties {
align: "left" | "center" | "right" | undefined;
children: React.ReactNode;
}
class Th extends React.Component {
protected readonly ref: React.RefObject;
constructor(properties: IThProperties) {
super(properties);
this.ref = { current: null };
}
public override shouldComponentUpdate(nextProperties: Readonly): boolean {
const properties = this.props;
return properties.align !== nextProperties.align || properties.children !== nextProperties.children;
}
public override render(): React.ReactElement {
const { align, children } = this.props;
return (
{children}
|
);
}
public override componentDidMount(): void {
const th = this.ref.current;
if (th) {
// eslint-disable-next-line unicorn/prefer-dom-node-text-content
th.setAttribute("title", th.innerText);
}
}
public override componentDidUpdate(): void {
const th = this.ref.current;
if (th) {
// eslint-disable-next-line unicorn/prefer-dom-node-text-content
th.setAttribute("title", th.innerText);
}
}
}
const cls: string = cx(
astClasses.table,
css({
display: "block",
overflow: "auto",
width: "max-content",
maxWidth: "100%",
padding: 0,
borderCollapse: "collapse",
borderRadius: "6px",
borderSpacing: "0px",
border: "1px solid var(--colorBorderTable)",
margin: "0 auto 1.25em",
lineHeight: "1.6",
"> thead": {
backgroundColor: "var(--colorBgTableHead)",
borderBottom: "1px solid #f0f0f0",
th: {
padding: "0.5rem 1rem",
borderLeft: "1px solid var(--colorBorderTable)",
wordBreak: "normal",
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
"&:first-child": {
borderLeft: "none",
},
},
},
"> tbody": {
tr: {
borderTop: "1px solid var(--colorBorderTable)",
backgroundColor: "var(--colorBgTableOddRow)",
},
"tr:nth-child(2n)": {
backgroundColor: "var(--colorBgTableEvenRow)",
},
td: {
padding: "0.5rem 1rem",
borderLeft: "1px solid var(--colorBorderTable)",
"&:first-child": {
borderLeft: "none",
},
},
},
}),
);