fix(react-email): apply th styles to markdown table header cells

Merged
SA
9d ago
+38-11

Bug

I hit this when styling a markdown table in an email with <Markdown markdownCustomStyles={{ th: { fontWeight: 'bold' }, td: { color: 'gray' } }}>. The th styles never showed up. Header cells were rendered with the td styles instead, so the output was <th style="color:gray">Name</th> rather than <th style="font-weight:bold">Name</th>.

Root cause

StylesType and the default styles both define a th key, but renderer.tablecell in markdown.tsx always reads finalStyles.td when it builds the style attribute, including for header cells. As a result, markdownCustomStyles.th is never read.

Solution

The cell renderer now looks up the style by the tag it is about to render (finalStyles[type], where type is th or td). I also merged the two duplicated tag branches (with and without align) into one template, so the style string is computed once. I added a patch changeset for react-email.

Closes #3760

Testing

  • Added a test to markdown.spec.tsx that renders a table with separate th and td styles and checks that header cells get th styles and body cells get td styles, including the aligned column. It fails on canary (<th style="color:gray">) and passes with the fix.
  • The full react-email test suite passes (45 files, 300 tests), and tsc --noEmit and biome check are clean.

Summary by cubic

Fixes <Markdown> in react-email so table header cells now receive markdownCustomStyles.th instead of always inheriting td styles.

Bug Fixes

  • Header cells previously rendered with td styles because the cell renderer always read finalStyles.td; it now looks up the style by the tag it renders (th or td).
  • Merged the duplicated cell renderer branches (with and without align) into a single template.
  • Added a regression test covering separate th and td styles, including aligned columns.