Skip to content

Commit

Permalink
Build element tree from HTML
Browse files Browse the repository at this point in the history
A la `TextBlockComponent`
  • Loading branch information
frederickobrien committed Nov 21, 2024
1 parent 77a56ed commit 18978f0
Showing 1 changed file with 56 additions and 6 deletions.
62 changes: 56 additions & 6 deletions dotcom-rendering/src/components/TableBlockComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { css } from '@emotion/react';
import { textSans12 } from '@guardian/source/foundations';
import { unescapeData } from '../lib/escapeData';
import { isElement, parseHtml } from '../lib/domUtils';
import { palette } from '../palette';
import { logger } from '../server/lib/logging';
import type { TableBlockElement } from '../types/content';

const tableEmbed = css`
Expand Down Expand Up @@ -44,12 +45,61 @@ type Props = {
element: TableBlockElement;
};

const buildElementTree = (node: Node) => {
const children = Array.from(node.childNodes).map(buildElementTree);
switch (node.nodeName) {
case 'TABLE': {
return <table className="table--football">{children}</table>;
}
case 'THEAD': {
return <thead>{children}</thead>;
}
case 'TBODY': {
return <tbody>{children}</tbody>;
}
case 'ABBR': {
return (
<abbr title={(node as HTMLElement).getAttribute('title') ?? ''}>
{children}
</abbr>
);
}
case 'TR': {
return <tr>{children}</tr>;
}
case 'TH': {
return <th>{children}</th>;
}
case 'TD': {
const isMainColumn = (node as HTMLElement).className.includes(
'table-column--main',
);
return (
<td style={isMainColumn ? { width: '100%' } : undefined}>
{children}
</td>
);
}
case '#text': {
return node.textContent;
}
default:
logger.warn('TableBlockComponent: Unknown element received', {
isDev: process.env.NODE_ENV !== 'production',
element: {
name: node.nodeName,
html: isElement(node) ? node.outerHTML : undefined,
},
});
return null;
}
};

export const TableBlockComponent = ({ element }: Props) => {
const fragment = parseHtml(element.html);
return (
<div
css={tableEmbed}
data-testid="football-table-embed"
dangerouslySetInnerHTML={{ __html: unescapeData(element.html) }}
/>
<div css={tableEmbed} data-testid="football-table-embed">
{Array.from(fragment.childNodes).map(buildElementTree)}
</div>
);
};

0 comments on commit 18978f0

Please sign in to comment.