Skip to content

fix(super-converter): fix table-cell shading export — strip # prefix and emit val="clear" (SD-3142)#3312

Open
nazlo90 wants to merge 1 commit into
superdoc-dev:mainfrom
nazlo90:nazlo90/SD-3142-fix-table-cell-shading-export
Open

fix(super-converter): fix table-cell shading export — strip # prefix and emit val="clear" (SD-3142)#3312
nazlo90 wants to merge 1 commit into
superdoc-dev:mainfrom
nazlo90:nazlo90/SD-3142-fix-table-cell-shading-export

Conversation

@nazlo90

@nazlo90 nazlo90 commented May 14, 2026

Copy link
Copy Markdown

Partial fix for SD-3142. Addresses the export half of the bug — the import half is not fixed in this PR (details below).

Root cause

ECMA-376 §17.4.32 requires w:fill to be a bare 6-char uppercase hex string and, for solid fills, w:val="clear". SuperDoc was writing the color from the internal ProseMirror attr as-is, which could include a leading # (e.g. #A1B2C3), and was omitting w:val entirely. LibreOffice treats a missing w:val as nil (transparent) and ignores the fill value, rendering those cells black regardless of color.

What changed

translate-table-cell.js — the export path for <w:shd>:

  • Runs normalizeHexColor to strip the # prefix and uppercase the value before writing w:fill.
  • Adds val: 'clear' to every solid-fill shading element.
  • Guards against non-hex values (e.g. "auto") via isValidHexColor: these now produce no <w:shd> rather than invalid markup.

helpers.js (resolveShadingFillColor) — used on the import/display path:

  • Adds an isValidHexColor guard so w:fill="auto" (Word's sentinel for "no fill") returns null instead of the string "AUTO", preventing it from being treated as a color downstream.

Tests

11 new assertions in helpers.test.js and translate-table-cell.test.js. Also corrected an existing wrong assertion that expected w:fill as '#FF00FF'; OOXML requires 'FF00FF'. All 12 827 existing tests pass.

pnpm --filter @superdoc/super-editor exec vitest run \
  src/editors/v1/core/super-converter/helpers.test.js \
  src/editors/v1/core/super-converter/v3/handlers/w/tc/helpers/translate-table-cell.test.js

What is NOT fixed

The import side of SD-3142: cells whose background comes from a table style's conditional formatting (e.g. tblStylePr with type="firstRow") currently render as white in SuperDoc's layout engine. The style cascade in style-engine resolves the conditional-format shading, but that value isn't threaded through to the painted cell yet — it requires changes in style-engine and pm-adapter and is a separate, larger task.

Related: SD-3142.

…l + w:val="clear"

OOXML requires w:fill to be a bare 6-char hex string and a solid fill needs w:val="clear" (ECMA-376 17.4.32). The exporter wrote background.color as-is, keeping a leading '#' and omitting w:val. LibreOffice treats a missing w:val as nil and renders such cells black regardless of the fill.

generateTableCellProperties now normalizes the color to bare hex via normalizeHexColor, guards with isValidHexColor so non-hex values like "auto" produce no w:shd, and emits w:val="clear". Updates the table-cell export tests accordingly.
@caio-pizzol caio-pizzol force-pushed the nazlo90/SD-3142-fix-table-cell-shading-export branch from 9682609 to d558f53 Compare June 23, 2026 20:11
@caio-pizzol

Copy link
Copy Markdown
Contributor

Thanks for this, @nazlo90. I refreshed the branch against current main and trimmed it to the remaining export fix.

The import-side shading fix is already on main, so this now only keeps the table-cell export change: write a bare hex w:fill and add w:val="clear".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants