markdown-to-jsx icon indicating copy to clipboard operation
markdown-to-jsx copied to clipboard

tbody and td do not render when using createElement

Open AkoyaRyan opened this issue 1 year ago • 2 comments

When using the createElement implementation, I noticed that for some reason the tbody and td elements were not working. When I set the th element to use the same component I was setting the td to, I noticed that the th would render just fine.

Also, if I removed the createElement implementation and used the overrides object, tbody and td would render properly. Here is an example:

createElement(type, props, children) {
        switch (type) {
            case "table":
                return <Table {...props}>{children}</Table>
            case "thead":
                return <TableHead {...props}>{children}</TableHead>
            case "tbody":
                return <TableBody {...props}>{children}</TableBody>
            case "tr":
                return <TableRow {...props}>{children}</TableRow>
            case "td":
            case "th":
                return <TableCell {...props}>{children}</TableCell>
            default:
                return createElement(type, props, children);
        }
    }

The above code will render the following HTML:

<table class="MuiTable-root css-bm78z0-MuiTable-root">
    <thead class="MuiTableHead-root css-15wwp11-MuiTableHead-root">
        <tr class="MuiTableRow-root MuiTableRow-head css-1pkudcu-MuiTableRow-root">
            <th class="MuiTableCell-root MuiTableCell-head MuiTableCell-sizeMedium css-ehm7wt-MuiTableCell-root" scope="col">Heading 1</th>
            <th class="MuiTableCell-root MuiTableCell-head MuiTableCell-sizeMedium css-ehm7wt-MuiTableCell-root" scope="col">Heading 2</th>
            <th class="MuiTableCell-root MuiTableCell-head MuiTableCell-sizeMedium css-ehm7wt-MuiTableCell-root" scope="col">Heading 3</th>
        </tr>
    </thead>
</table>

No-tbody-or-td

If I remove the createElement implementation and use the overrides object, the tbody and td will render properly. Here is an example:

overrides: {
        td: TableCell,
        tbody: TableBody,
        table: Table,
        thead: TableHead,
        th: TableCell,
        tr: TableRow
    }

This will render the following HTML:

<table class="MuiTable-root css-bm78z0-MuiTable-root">
    <thead class="MuiTableHead-root css-15wwp11-MuiTableHead-root">
        <tr class="MuiTableRow-root MuiTableRow-head css-1pkudcu-MuiTableRow-root">
            <th class="MuiTableCell-root MuiTableCell-head MuiTableCell-sizeMedium css-ehm7wt-MuiTableCell-root"
                scope="col">Heading 1</th>
            <th class="MuiTableCell-root MuiTableCell-head MuiTableCell-sizeMedium css-ehm7wt-MuiTableCell-root"
                scope="col">Heading 2</th>
            <th class="MuiTableCell-root MuiTableCell-head MuiTableCell-sizeMedium css-ehm7wt-MuiTableCell-root"
                scope="col">Heading 3</th>
        </tr>
    </thead>
    <tbody class="MuiTableBody-root css-apqrd9-MuiTableBody-root">
        <tr class="MuiTableRow-root css-1pkudcu-MuiTableRow-root">
            <td class="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-11eezss-MuiTableCell-root">Cell
                One</td>
            <td class="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-11eezss-MuiTableCell-root">Cell
                Two</td>
            <td class="MuiTableCell-root MuiTableCell-body MuiTableCell-sizeMedium css-11eezss-MuiTableCell-root">Cell 3
            </td>
        </tr>
    </tbody>
</table>

Proper-render

AkoyaRyan avatar Feb 09 '23 13:02 AkoyaRyan

I had the same problem. The children will be spread so that each child is passed as an argument, instead of an array. https://github.com/probablyup/markdown-to-jsx/blob/ef6898da4f79610a3287d6aa0ce46332435da5bf/index.tsx#L1178-L1186

So in your createElement function you will need to collect all the children back into an array and then spread them again when you delegate to React.CreateElement.

options: {
  createElement(type, props, ...children) {
    return React.createElement(type, props, ...children);
  }
}

The reason you noticed this for tbody is because your table had 2 children, thead and tbody, but you were only passing thead to React.createElement.

It would be good if the example in the docs used the spread syntax to help people avoid this foot gun.

daniel-nagy avatar Sep 05 '23 00:09 daniel-nagy

Great catch! I totally missed this. I appreciate you looking into this and helping me out with this. Worked like a charm.

ryanbeaulieu avatar Sep 06 '23 13:09 ryanbeaulieu