diff --git a/src/components/model-viewer/ModelViewerInternal.tsx b/src/components/model-viewer/ModelViewerInternal.tsx index 8c33a8f..3271eb0 100644 --- a/src/components/model-viewer/ModelViewerInternal.tsx +++ b/src/components/model-viewer/ModelViewerInternal.tsx @@ -176,7 +176,6 @@ async function initialize( renderer.setPixelRatio(window.devicePixelRatio); // We only scale down, not up const scaling = Math.min(1, width / (originalWidth * 3)); - console.info("Scaling: %o", scaling); camera.zoom = (1 / 0.625) * 16 * cameraProps.zoom * scaling; camera.left = -width / 2; camera.right = width / 2; diff --git a/src/page-compiler/compilePage.tsx b/src/page-compiler/compilePage.tsx index 0a8a0f4..f705fe6 100644 --- a/src/page-compiler/compilePage.tsx +++ b/src/page-compiler/compilePage.tsx @@ -9,6 +9,7 @@ import compileImage from "./image.tsx"; import compileError from "./compileError.tsx"; import compileList from "./list.tsx"; import compileListItem from "./listItem.tsx"; +import compileTable from "./table.tsx"; export type CompileContext = { guide: Guide; @@ -121,8 +122,8 @@ function compileContent( return compileList(context, node); case "listItem": return compileListItem(context, node, parent); - //case "table": - // break; + case "table": + return compileTable(context, node); // Text- and Block-Level JSX or HTML Element case "mdxJsxFlowElement": case "mdxJsxTextElement": diff --git a/src/page-compiler/table.tsx b/src/page-compiler/table.tsx new file mode 100644 index 0000000..5bdbd5e --- /dev/null +++ b/src/page-compiler/table.tsx @@ -0,0 +1,90 @@ +import { CompileContext } from "./compilePage.tsx"; +import { Parent, Table, TableRow } from "mdast"; +import React, { ReactComponentElement, ReactElement, ReactNode } from "react"; +import compileError from "./compileError.tsx"; + +function compileTableRow( + context: CompileContext, + node: TableRow, + parent: Table +): ReactElement { + const siblings = parent ? parent.children : undefined; + + // Generate a body row when without parent. + const rowIndex = siblings ? siblings.indexOf(node) : 1; + const tagName = rowIndex === 0 ? "th" : "td"; + const align = parent && parent.type === "table" ? parent.align : undefined; + const length = align ? align.length : node.children.length; + let cellIndex = -1; + const cells: ReactElement[] = []; + + while (++cellIndex < length) { + // Note: can also be undefined. + const cell = node.children[cellIndex]; + const properties: ReactComponentElement<"td" | "th">["props"] = {}; + const alignValue = align ? align[cellIndex] : undefined; + + if (alignValue) { + properties.align = alignValue; + } + + const cellContent = cell ? context.compileChildren(cell) : null; + const result = React.createElement(tagName, properties, cellContent); + + cells.push(result); + } + + return React.createElement("tr", null, ...cells); +} + +function getFilteredChildren( + node: Parent, + childType: S, + errors: ReactNode[] +): T[] { + const rows: T[] = []; + for (const child of node.children) { + if (child.type !== childType) { + errors.push( + compileError(node, "Unsupported child-node for table: " + child.type) + ); + continue; + } + rows.push(child as T); + } + return rows; +} + +export default function compileTable( + context: CompileContext, + table: Table +): ReactNode { + const errors: ReactNode[] = []; + + const rows: TableRow[] = getFilteredChildren(table, "tableRow", errors); + const firstRow = rows.shift(); + const tableContent: ReactElement[] = []; + + if (firstRow) { + // Generate a one-row thead for the first table row + tableContent.push( + React.createElement( + "thead", + null, + compileTableRow(context, firstRow, table) + ) + ); + } + + if (rows.length > 0) { + tableContent.push( + React.createElement( + "tbody", + null, + ...rows.map((row) => compileTableRow(context, row, table)) + ) + ); + } + + return React.createElement("table", null, ...tableContent); +}