Skip to content

refactor(editor): remove classReference, use sectionId as CssJs key - #3114

Closed
gabrielmfern wants to merge 68 commits into
canaryfrom
feat/simpler-theming-data
Closed

gabrielmfern wants to merge 68 commits into
canaryfrom
feat/simpler-theming-data

Conversation

@gabrielmfern

@gabrielmfern gabrielmfern commented Mar 25, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Remove classReference from PanelGroup and PanelInputProperty — each group's id (PanelSectionId) now directly serves as the key in the CssJs output
  • Merge the typography section into body/container (fontSize → body, lineHeight → container)
  • Rename PanelSectionId values to camelCase: code-block → codeBlock, inline-code → inlineCode
  • Add PersistedPanelGroup type for backward-compatible normalization of legacy persisted data (no as any casts)

Test plan

  • All 321 existing tests pass
  • Verify editor preview renders styles correctly (.node-* CSS classes)
  • Verify serialized email output has correct inline styles
  • Test with legacy persisted data containing classReference fields

🤖 Generated with Claude Code


Summary by cubic

Refactors the email theming model to use panel id as the single CssJs key and removes classReference. Adds a normalization layer to auto-upgrade legacy data and consolidates sections (camelCase ids, typography merged).

  • Refactors

    • Removed classReference from PanelGroup and PanelInputProperty; transformToCssJs now keys by group id.
    • Added PersistedPanelGroup and normalization that strips classReference, maps kebab-case ids (code-block/inline-code → codeBlock/inlineCode), merges legacy "typography" into body/container, and skips groups without an id.
    • Merged sections: fontSize → body, lineHeight → container; removed typography.
    • Updated themes, types, and tests to reflect new ids and inputs.
  • Migration

    • Remove any classReference usage in custom panels/persisted styles; ensure each group has an id.
    • Use camelCase ids: codeBlock, inlineCode; stop referencing typography.
    • Read/write fontSize on body and lineHeight on container.
    • When reading styles from the editor, treat them as PersistedPanelGroup[] and run normalizeThemePanelStyles before use.

Written for commit 590f0d0. Summary will update on new commits.

gabrielmfern and others added 30 commits March 2, 2026 14:47
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: João Melo <jopcmelo@Joaos-MacBook-Pro.local>
Co-authored-by: João Melo <jopcmelo@Joaos-MacBook-Pro.local>
gabrielmfern and others added 22 commits March 13, 2026 10:51
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Remove classReference from PanelGroup and PanelInputProperty. Each
group's id (PanelSectionId) now directly serves as the key in the CssJs
output, eliminating the redundant per-input classReference field.

- Merge typography section into body/container (fontSize → body,
  lineHeight → container)
- Rename PanelSectionId values to camelCase: code-block → codeBlock,
  inline-code → inlineCode
- Update transformToCssJs to use style.id instead of input.classReference
- Add backward-compat normalization for legacy persisted data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…asts

Introduce PersistedPanelGroup to properly type legacy persisted data
that may contain classReference and old-style section IDs. This
eliminates all `as any` casts in the normalization layer and tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Mar 25, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 590f0d0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercel Bot commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
react-email Ready Ready Preview, Comment Mar 25, 2026 7:41pm
react-email-demo Ready Ready Preview, Comment Mar 25, 2026 7:41pm

Request Review

@pkg-pr-new

pkg-pr-new Bot commented Mar 25, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@react-email/editor@3114

commit: b7e57a9

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 8 files

Confidence score: 3/5

  • There is a concrete regression risk in packages/editor/src/plugins/email-theming/normalization.ts: legacy typography is mapped to body at the group level, which can misroute lineHeight now that it is a container setting.
  • Because this affects normalization of persisted legacy styles, user-visible email theming can change unexpectedly for existing content, so this is more than a minor housekeeping issue.
  • Pay close attention to packages/editor/src/plugins/email-theming/normalization.ts - verify legacy-to-new mapping for lineHeight to avoid incorrect style application.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/editor/src/plugins/email-theming/normalization.ts">

<violation number="1" location="packages/editor/src/plugins/email-theming/normalization.ts:97">
P1: Mapping legacy `typography` to `body` at group level misroutes `lineHeight` (now a `container` setting), changing how old persisted styles are applied.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

// Special case: legacy 'typography' section with classReference 'body'
// should be merged into 'body' (its inputs have been redistributed)
if (group.classReference === 'body' && normalizedTitle === 'typography') {
return 'body';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Mapping legacy typography to body at group level misroutes lineHeight (now a container setting), changing how old persisted styles are applied.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/editor/src/plugins/email-theming/normalization.ts, line 97:

<comment>Mapping legacy `typography` to `body` at group level misroutes `lineHeight` (now a `container` setting), changing how old persisted styles are applied.</comment>

<file context>
@@ -51,35 +76,35 @@ function normalizeTitle(title: string | undefined): string {
+    // Special case: legacy 'typography' section with classReference 'body'
+    // should be merged into 'body' (its inputs have been redistributed)
+    if (group.classReference === 'body' && normalizedTitle === 'typography') {
+      return 'body';
+    }
+    return LEGACY_CLASS_REFERENCE_MAP[group.classReference]!;
</file context>

cursor Bot pushed a commit that referenced this pull request Mar 26, 2026
…s key, rename normalization to backwards-compatibility

- Remove classReference from PanelGroup and PanelInputProperty types
- Use group id (PanelSectionId) as CssJs key instead of per-input classReference
- Merge typography section into body (fontSize) and container (lineHeight)
- Rename section IDs to camelCase: code-block → codeBlock, inline-code → inlineCode
- Remove typography from PanelSectionId
- Rename normalization module to backwards-compatibility
- normalizeThemePanelStyles → applyPanelStylesBackwardsCompat
- normalizePanelInputs → backfillPanelInputs
- Add PersistedPanelGroup type for backward-compatible legacy data handling
- Strip classReference from inputs during normalization
- Filter out unresolvable groups instead of passing them through
- Update all tests to reflect new structure

Syncs changes from resend/resend PR #9330 (PRs #3113 and #3114 equivalent).

Co-authored-by: Gabriel Miranda <gabrielmfern@outlook.com>
Base automatically changed from feat/ai-oss-editor to canary March 27, 2026 19:02

This branch was successfully deployed

2 active deployments
Preview – react-email-demo — 590f0d0a Deployed Mar 25, 2026 by vercel[bot]
Preview – react-email — 590f0d0a Deployed Mar 25, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants