| 1 | import { memo, useState, type ReactNode } from "react"; |
| 2 | import type { VirtualMarkdownTableData } from "../lib/largeMarkdownTable"; |
| 3 | import { useT } from "../lib/i18n"; |
| 4 | import { RESOURCE_BUDGETS } from "../lib/resourceBudgets"; |
| 5 | |
| 6 | const TABLE_CELL_PAGE = RESOURCE_BUDGETS.markdownTableCellsPerPage; |
| 7 | |
| 8 | export const MarkdownTable = memo(function MarkdownTable({ children }: { children?: ReactNode }) { |
| 9 | return <div className="md-table-scroll"><table>{children}</table></div>; |
| 10 | }); |
| 11 | |
| 12 | /** Large plain tables retain the fast worker parse and page their DOM cells. */ |
| 13 | export const MarkdownSourceTable = memo(function MarkdownSourceTable({ data }: { data: VirtualMarkdownTableData }) { |
| 14 | const t = useT(); |
| 15 | const rowsPerPage = Math.max(20, Math.floor(TABLE_CELL_PAGE / Math.max(1, data.header.length))); |
| 16 | const [visibleRows, setVisibleRows] = useState(rowsPerPage); |
| 17 | const shown = data.rows.slice(0, visibleRows); |
| 18 | return <div className="md-table-scroll" data-markdown-source-rows={data.rows.length} |
| 19 | data-markdown-visible-rows={shown.length}><table> |
| 20 | <thead><tr>{data.header.map((cell, index) => <th key={index} align={data.align[index] ?? undefined}>{cell}</th>)}</tr></thead> |
| 21 | <tbody>{shown.map((row, index) => <tr key={index}>{row.map((cell, column) => |
| 22 | <td key={column} align={data.align[column] ?? undefined}>{cell}</td>)}</tr>)}</tbody> |
| 23 | </table>{shown.length < data.rows.length && <button type="button" className="btn" |
| 24 | onClick={() => setVisibleRows(count => count + rowsPerPage)}>{t("workspace.loadMore")}</button>}</div>; |
| 25 | }); |
| 26 |