Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/2026-08-11-table-default-spans.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tiptap/extension-table': patch
---

Table cells and headers no longer render `colspan="1"` and `rowspan="1"`. Both attributes are only written to the HTML when a cell actually spans more than one column or row, which matches how prosemirror-tables serializes them.
20 changes: 20 additions & 0 deletions packages/extension-table/__tests__/tableCell.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,26 @@ describe('extension table cell', () => {
getEditorEl()?.remove()
})

it('should only render colspan and rowspan when they are not the default', () => {
const content =
'<table><tbody><tr><td>Name</td><td colspan="2">Description</td></tr><tr><td rowspan="2">Cyndi Lauper</td><td>Singer</td><td>Songwriter</td></tr></tbody></table>'

editor = new Editor({
element: createEditorEl(),
extensions: [Document, Text, Paragraph, TableCell, TableHeader, TableRow, Table],
content,
})

const html = editor.getHTML()

expect(html).toContain('<td><p>Name</p></td>')
expect(html).toContain('<td colspan="2"><p>Description</p></td>')
expect(html).toContain('<td rowspan="2"><p>Cyndi Lauper</p></td>')

editor?.destroy()
getEditorEl()?.remove()
})

it('should prefer the colwidth attribute over the colgroup col width', () => {
const content =
'<table><colgroup><col width="64" /><col /></colgroup><tbody><tr><td colwidth="200">hello</td><td>world</td></tr></tbody></table>'
Expand Down
4 changes: 2 additions & 2 deletions packages/extension-table/__tests__/tableCommands.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,15 +268,15 @@ describe('Table commands', () => {
editor.commands.clearContent()
editor.commands.insertTable({ cols: 1, rows: 1, withHeaderRow: false })
expect(editor.getHTML()).toBe(
'<table style="min-width: 25px;"><colgroup><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p></p></td></tr></tbody></table>',
'<table style="min-width: 25px;"><colgroup><col style="min-width: 25px;"></colgroup><tbody><tr><td><p></p></td></tr></tbody></table>',
)
})

it('generates correct markup for a 1x1 table with header', () => {
editor.commands.clearContent()
editor.commands.insertTable({ cols: 1, rows: 1, withHeaderRow: true })
expect(editor.getHTML()).toBe(
'<table style="min-width: 25px;"><colgroup><col style="min-width: 25px;"></colgroup><tbody><tr><th colspan="1" rowspan="1"><p></p></th></tr></tbody></table>',
'<table style="min-width: 25px;"><colgroup><col style="min-width: 25px;"></colgroup><tbody><tr><th><p></p></th></tr></tbody></table>',
)
})

Expand Down
19 changes: 19 additions & 0 deletions packages/extension-table/__tests__/tableHeader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,25 @@ describe('extension table header', () => {
getEditorEl()?.remove()
})

it('should only render colspan and rowspan when they are not the default', () => {
const content =
'<table><tbody><tr><th>Name</th><th colspan="2">Description</th></tr><tr><td>Cyndi Lauper</td><td>Singer</td><td>Songwriter</td></tr></tbody></table>'

editor = new Editor({
element: createEditorEl(),
extensions: [Document, Text, Paragraph, TableCell, TableHeader, TableRow, Table],
content,
})

const html = editor.getHTML()

expect(html).toContain('<th><p>Name</p></th>')
expect(html).toContain('<th colspan="2"><p>Description</p></th>')

editor?.destroy()
getEditorEl()?.remove()
})

it('should parse the colgroup col widths for a header row', () => {
const content =
'<table><colgroup><col width="64" /><col width="128" /></colgroup><tbody><tr><th>Name</th><th>Description</th></tr><tr><td>Cyndi Lauper</td><td>Singer</td></tr></tbody></table>'
Expand Down
18 changes: 18 additions & 0 deletions packages/extension-table/src/cell/table-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,27 @@ export const TableCell = Node.create<TableCellOptions>({
return {
colspan: {
default: 1,
renderHTML: attributes => {
if (attributes.colspan === 1) {
return {}
}

return {
colspan: attributes.colspan,
}
},
},
rowspan: {
default: 1,
renderHTML: attributes => {
if (attributes.rowspan === 1) {
return {}
}

return {
rowspan: attributes.rowspan,
}
},
},
colwidth: {
default: null,
Expand Down
18 changes: 18 additions & 0 deletions packages/extension-table/src/header/table-header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,27 @@ export const TableHeader = Node.create<TableHeaderOptions>({
return {
colspan: {
default: 1,
renderHTML: attributes => {
if (attributes.colspan === 1) {
return {}
}

return {
colspan: attributes.colspan,
}
},
},
rowspan: {
default: 1,
renderHTML: attributes => {
if (attributes.rowspan === 1) {
return {}
}

return {
rowspan: attributes.rowspan,
}
},
},
colwidth: {
default: null,
Expand Down
Loading