fix(mdxish): preserve multi-paragraph table cells#1445
Conversation
| const paragraphCount = cell.children.filter(c => c.type === 'paragraph').length; | ||
| const parsedChildren = | ||
| paragraphCount === 1 | ||
| ? cell.children.flatMap((parsedNode: Node) => { |
There was a problem hiding this comment.
This logic is kind of a duplicate to the one in mdxish-tables. I'm thinking of moving the table-related transformers under 1 subfolder under transformers/ so that it can host its own util file and share code.
There was a problem hiding this comment.
Yeah I agree with doing this. Also fine with putting an unwrapSoleParagraph (or whatever name makes sense) function into processor/utils. But we definitely don't want two duplicates that could drift if one gets updated without the other.
There was a problem hiding this comment.
The as Table casts are to fix type errors
There was a problem hiding this comment.
This is because MDAST Table doesn't expect paragraphs in table cell children right?
Can we instead type the expected shape and use it here? I also guess we'd need to update a table transformer that is also casting unsafely.
We've got this types file that already holds transitional node shapes we could put a new Table & TableCell type in https://github.com/readmeio/markdown/blob/next/processor/transform/mdxish/types.ts
There was a problem hiding this comment.
Yeah because the MDAST table cell children is typed as PhrasingContent[] which doesn't accept flow level nodes such as Paragraphs, Lists, etc.
Yes we can definitely extend the table types! I've had a thought about it, I think we should do it in a follow up so we can integrate the types more holistically and have some room for discussions as well. Will create one soon.
| @@ -251,6 +257,7 @@ const mdxishTables = (): Transform => tree => { | |||
| // we let it get handled naturally | |||
| return EXIT; | |||
| } | |||
| return undefined; | |||
There was a problem hiding this comment.
Lint error fix, shouldn't affect anything
kevinports
left a comment
There was a problem hiding this comment.
Approving with a few comments that'd be good to address before merging.
As I've alluded to in the note below the loom, even with this fix, the paragraphs in the table cell in the editor are only 1 line apart & different from the view mode. I don't think there's any more we can do in the engine though, and it would be a fix in the editor.
Unfortunately I think this part isn't a straightforward fix, one thing we could do is to add break tags to the tree to make sure the editor matches the view mode, but it will add it in the raw mode as well which I'm not sure if we want to do more of than we already do. Will think of that more.
Yeah it'd definitely be nice to clean this up. Could it just be a CSS styling difference between view vs edit rendering?
| const paragraphCount = cell.children.filter(c => c.type === 'paragraph').length; | ||
| const parsedChildren = | ||
| paragraphCount === 1 | ||
| ? cell.children.flatMap((parsedNode: Node) => { |
There was a problem hiding this comment.
Yeah I agree with doing this. Also fine with putting an unwrapSoleParagraph (or whatever name makes sense) function into processor/utils. But we definitely don't want two duplicates that could drift if one gets updated without the other.
There was a problem hiding this comment.
This is because MDAST Table doesn't expect paragraphs in table cell children right?
Can we instead type the expected shape and use it here? I also guess we'd need to update a table transformer that is also casting unsafely.
We've got this types file that already holds transitional node shapes we could put a new Table & TableCell type in https://github.com/readmeio/markdown/blob/next/processor/transform/mdxish/types.ts
## Version 14.1.1 ### 🛠 Fixes & Updates * DRY up some test helpers ([#1437](#1437)) ([f761248](f761248)) * **mdxish:** preserve multi-paragraph table cells ([#1445](#1445)) ([c821b2d](c821b2d)) * use magic block tokenizer when parsing JSX component children ([#1447](#1447)) ([51b22a9](51b22a9)), closes [#1429](#1429) <!--SKIP CI-->
This PR was released!🚀 Changes included in v14.1.1 |



🎯 What does this PR do?
Magic-block `[block:parameters]` tables (and actually JSX Tables as well) with cells containing paragraph breaks (`\n\n`) lose those breaks after a save through the MdxishEditor. A cell rendered as three paragraphs collapses into a single concatenated line (`para1para2para3`).
There are 2 issues causing this:
mdxish-tables.tsto flatten and unwrap paragraph nodes in a table cell, hence it'll become just an array of text nodes, which bunches them to one lineFixes:
🧪 QA tips
Paste the following into a doc with the MdxishEditor, save, and confirm the three paragraphs are preserved (not collapsed to `Line 1Line 2Line 3`):
Also verify a JSX <Table> with blank-line-separated content in a cell round-trips cleanly:
📸 Screenshot or Loom
BEFORE (Notice how the new lines get lost after the round-trip):
Screen.Recording.2026-04-23.at.11.25.04.pm.mov
AFTER (Serialising to JSX table and preserving newlines):
Screen.Recording.2026-04-23.at.11.25.34.pm.mov
NOTE that in the editor, the paragraph gaps are not exactly the same as in view mode. If we want to update that to be the exact same, we'd need to look into the editor side. In spite of that, the round-trip works and the view mode still renders with the correct paragraph gaps.