fix(render): unwrap BlockNote tableCell objects so table cells render content

BlockNote >=0.15 (the editor ships 0.47) stores each table cell as a
{type:"tableCell", content:[...]} object. The renderer passed each cell
straight to inlineContentFromRaw, which only understands strings and bare
inline arrays, so object-form cells rendered an empty grid (correct rows
and columns, no content). Unwrap content[] from tableCell objects while
keeping the legacy bare-array/string cell formats working.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Dunmow 2026-06-18 21:59:30 +08:00
parent d5e9d7ecd3
commit 5170d3adf4
2 changed files with 44 additions and 1 deletions

View File

@ -374,8 +374,17 @@ func renderBlock(ctx context.Context, block map[string]any) string {
cellTag = "th"
cellClass = "px-4 py-3 text-left text-sm font-semibold"
}
// BlockNote >=0.15 wraps each cell as a tableCell object
// {type:"tableCell", content:[...]}; older docs store the
// cell's inline content (string or array) directly.
cellContent := cell
if cellMap, ok := cell.(map[string]any); ok {
if t, _ := cellMap["type"].(string); t == "tableCell" {
cellContent = cellMap["content"]
}
}
fmt.Fprintf(&sb, "<%s class=\"%s\">", cellTag, cellClass)
sb.WriteString(renderInlineContent(inlineContentFromRaw(cell), false))
sb.WriteString(renderInlineContent(inlineContentFromRaw(cellContent), false))
fmt.Fprintf(&sb, "</%s>", cellTag)
}
}

View File

@ -520,6 +520,40 @@ func TestTableCellStringContent(t *testing.T) {
}
}
// BlockNote >=0.15 (the editor ships 0.47) stores each table cell as a
// tableCell object: {type:"tableCell", props:{...}, content:[...inline]}.
// The renderer must unwrap content[] from these objects, not just bare
// inline arrays/strings.
func TestTableCellObjectContent(t *testing.T) {
cell := func(text string) map[string]any {
return map[string]any{
"type": "tableCell",
"props": map[string]any{},
"content": []any{map[string]any{"type": "text", "text": text}},
}
}
doc := map[string]any{
"blocks": []any{
map[string]any{
"type": "table",
"content": map[string]any{
"type": "tableContent",
"rows": []any{
map[string]any{"cells": []any{cell("Header A"), cell("Header B")}},
map[string]any{"cells": []any{cell("Cell A"), cell("Cell B")}},
},
},
},
},
}
html := BlockNoteToHTML(context.Background(), doc)
for _, want := range []string{"Header A", "Header B", "Cell A", "Cell B"} {
if !strings.Contains(html, want) {
t.Errorf("expected table cell content %q in output: %s", want, html)
}
}
}
func TestNestedListRendering(t *testing.T) {
doc := map[string]any{
"blocks": []any{