From d538c968024f6f9317dac3d1b082a4fe0339da99 Mon Sep 17 00:00:00 2001 From: Nick Bernal Date: Fri, 27 Feb 2026 13:52:03 -0800 Subject: [PATCH 1/2] fix(document-api): fix cell shading in document api --- .../tables-adapter.regressions.test.ts | 25 +++++++++++++++++ .../document-api-adapters/tables-adapter.ts | 28 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/packages/super-editor/src/document-api-adapters/tables-adapter.regressions.test.ts b/packages/super-editor/src/document-api-adapters/tables-adapter.regressions.test.ts index 202bdab2da..7258b839bd 100644 --- a/packages/super-editor/src/document-api-adapters/tables-adapter.regressions.test.ts +++ b/packages/super-editor/src/document-api-adapters/tables-adapter.regressions.test.ts @@ -403,6 +403,31 @@ describe('tables-adapter regressions', () => { }); }); + it('applies table shading to all cells when target is a table', () => { + const editor = makeTableEditor(); + const tr = editor.state.tr as unknown as { setNodeMarkup: ReturnType }; + + const result = tablesSetShadingAdapter(editor, { + nodeId: 'table-1', + color: 'FFFF00', + }); + + expect(result.success).toBe(true); + + const cellUpdates = tr.setNodeMarkup.mock.calls.filter( + (call) => + typeof call[2] === 'object' && + call[2] != null && + (call[2] as { tableCellProperties?: { shading?: { fill?: string } } }).tableCellProperties?.shading?.fill === + 'FFFF00', + ); + + expect(cellUpdates).toHaveLength(4); + for (const call of cellUpdates) { + expect((call[2] as { background?: { color?: string } }).background).toEqual({ color: 'FFFF00' }); + } + }); + it.each([ { name: 'tables.setBorder', diff --git a/packages/super-editor/src/document-api-adapters/tables-adapter.ts b/packages/super-editor/src/document-api-adapters/tables-adapter.ts index 1b5f9ee179..783c84d899 100644 --- a/packages/super-editor/src/document-api-adapters/tables-adapter.ts +++ b/packages/super-editor/src/document-api-adapters/tables-adapter.ts @@ -2596,6 +2596,34 @@ export function tablesSetShadingAdapter( currentProps.shading = { fill: input.color, val: 'clear', color: 'auto' }; const syncAttrs = resolved.scope === 'table' ? syncExtractedTableAttrs(currentProps) : {}; tr.setNodeMarkup(resolved.pos, null, { ...currentAttrs, [propsKey]: currentProps, ...syncAttrs }); + + if (resolved.scope === 'table') { + const tableNode = resolved.node; + const tableStart = resolved.pos + 1; + const map = TableMap.get(tableNode); + const seen = new Set(); + const mapFrom = tr.mapping.maps.length; + + for (let i = 0; i < map.map.length; i++) { + const relPos = map.map[i]!; + if (seen.has(relPos)) continue; + seen.add(relPos); + + const cellNode = tableNode.nodeAt(relPos); + if (!cellNode) continue; + + const cellAttrs = cellNode.attrs as Record; + const cellProps = { ...((cellAttrs.tableCellProperties ?? {}) as Record) }; + cellProps.shading = { fill: input.color, val: 'clear', color: 'auto' }; + + tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(tableStart + relPos), null, { + ...cellAttrs, + tableCellProperties: cellProps, + background: { color: input.color }, + }); + } + } + applyDirectMutationMeta(tr); editor.dispatch(tr); clearIndexCache(editor); From 7c903071b45a05b5c2c224df1d7a6485430875d0 Mon Sep 17 00:00:00 2001 From: Nick Bernal Date: Fri, 27 Feb 2026 15:04:49 -0800 Subject: [PATCH 2/2] fix(document-api): fix auto color in setShading for tables --- .../tables-adapter.regressions.test.ts | 25 +++++++++++++++++++ .../document-api-adapters/tables-adapter.ts | 10 +++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/super-editor/src/document-api-adapters/tables-adapter.regressions.test.ts b/packages/super-editor/src/document-api-adapters/tables-adapter.regressions.test.ts index ff05fec53d..6f1b29e1af 100644 --- a/packages/super-editor/src/document-api-adapters/tables-adapter.regressions.test.ts +++ b/packages/super-editor/src/document-api-adapters/tables-adapter.regressions.test.ts @@ -559,6 +559,31 @@ describe('tables-adapter regressions', () => { } }); + it('does not write cell background when table shading color is auto', () => { + const editor = makeTableEditor(); + const tr = editor.state.tr as unknown as { setNodeMarkup: ReturnType }; + + const result = tablesSetShadingAdapter(editor, { + nodeId: 'table-1', + color: 'auto', + }); + + expect(result.success).toBe(true); + + const cellUpdates = tr.setNodeMarkup.mock.calls.filter( + (call) => + typeof call[2] === 'object' && + call[2] != null && + (call[2] as { tableCellProperties?: { shading?: { fill?: string } } }).tableCellProperties?.shading?.fill === + 'auto', + ); + + expect(cellUpdates).toHaveLength(4); + for (const call of cellUpdates) { + expect((call[2] as { background?: unknown }).background).toBeUndefined(); + } + }); + it.each([ { name: 'tables.setBorder', diff --git a/packages/super-editor/src/document-api-adapters/tables-adapter.ts b/packages/super-editor/src/document-api-adapters/tables-adapter.ts index e5bf7d803c..4c735272a4 100644 --- a/packages/super-editor/src/document-api-adapters/tables-adapter.ts +++ b/packages/super-editor/src/document-api-adapters/tables-adapter.ts @@ -2670,11 +2670,15 @@ export function tablesSetShadingAdapter( const cellProps = { ...((cellAttrs.tableCellProperties ?? {}) as Record) }; cellProps.shading = { fill: input.color, val: 'clear', color: 'auto' }; - tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(tableStart + relPos), null, { + const nextCellAttrs: Record = { ...cellAttrs, tableCellProperties: cellProps, - background: { color: input.color }, - }); + }; + + if (input.color === 'auto') delete nextCellAttrs.background; + else nextCellAttrs.background = { color: input.color }; + + tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(tableStart + relPos), null, nextCellAttrs); } }