Skip to content

feat(ui): move the props editor into a panel with a highlighted JSON editor#3644

Merged
felipefreitag merged 4 commits into
canaryfrom
feat/props-editor-typed-form
Jul 14, 2026
Merged

feat(ui): move the props editor into a panel with a highlighted JSON editor#3644
felipefreitag merged 4 commits into
canaryfrom
feat/props-editor-typed-form

Conversation

@felipefreitag

@felipefreitag felipefreitag commented Jul 10, 2026

Copy link
Copy Markdown
Member

Follow-up to #3613. The props editor moves out of the bottom toolbar — whose tabs are diagnoses (Linter/Compatibility/Spam), not inputs, and whose ~160px drawer left almost no room to edit — into a collapsible panel docked right of the preview canvas, toggled from the topbar. The panel insets between the topbar and the toolbar, so neither is displaced; the toolbar returns to diagnostics + Resend.

What it does

  • Panel: open/closed state lives in a provider mounted in the preview layout, so it survives navigating between templates without closing or replaying its opening animation. State persists per workspace in localStorage; the width transition only runs on explicit toggles. Raw .html templates get neither the toggle nor the panel.
  • JSON editor: a syntax-highlighted editing surface — a transparent textarea overlaid on a prism-react-renderer render sharing the source view's theme, so it looks native and adds no dependency. Valid JSON re-renders the preview live (debounced); invalid JSON shows the parse error inline and leaves the preview on the last valid render; reset restores the template's own PreviewProps.
  • No value validation, by design: props are edited as JSON and nothing checks them against the component's expectations — wrong values break the render, and the existing error overlay is the feedback, same as editing code. An earlier iteration of this PR built typed per-prop fields plus a PreviewFields template API; it was dropped because the validation surface kept growing while real templates (nested object props) still ended up in JSON anyway.
  • Static builds show the panel read-only (disabled editor plus a short note) — the rendered props are part of the build metadata.
  • Stale ?toolbar-panel=props links coerce to a closed toolbar.

Verification

Verified end-to-end in the preview app: live re-render from JSON edits, inline parse error with the preview holding, reset, override kept across hot reload, panel state surviving template navigation and reloads without re-animating, and the read-only panel on an email-dev build + start static deployment.

@vercel

vercel Bot commented Jul 10, 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 Jul 14, 2026 4:36pm
react-email-demo Ready Ready Preview, Comment Jul 14, 2026 4:36pm

@pkg-pr-new

pkg-pr-new Bot commented Jul 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@react-email/ui@3644

commit: dd7dfa3

Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed
Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed
Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed
Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed
Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed
Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed

@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.

All reported issues were addressed across 5 files

Confidence score: 5/5

  • Safe to merge after the addressed issues were fixed.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/ui/src/utils/preview-props-fields.ts Outdated
Comment thread packages/ui/src/components/preview-props-editor.tsx Outdated
@changeset-bot

changeset-bot Bot commented Jul 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: dd7dfa3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@react-email/ui Minor
react-email Minor
@react-email/editor Patch

Not sure what this means? Click here to learn what changesets are.

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

@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.

0 issues found across 1 file (changes from recent commits).

Requires human review: Auto-approval blocked by 2 unresolved issues from previous reviews.

Re-trigger cubic

Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed
Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed
Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed
Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed
Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed
Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed
Comment thread packages/ui/src/utils/preview-props-fields.ts Fixed

@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.

All reported issues were addressed across 13 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/ui/src/utils/sanitize-preview-fields.ts Outdated
Comment thread packages/ui/src/utils/sanitize-preview-fields.ts Outdated
Comment thread packages/ui/src/utils/sanitize-preview-fields.ts Outdated
Comment thread packages/ui/src/utils/preview-props-fields.ts Outdated
Comment thread packages/ui/src/utils/preview-props-fields.ts Outdated
Comment thread packages/ui/src/components/preview-props-editor.tsx Outdated

@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 12 files (changes from recent commits).

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/ui/src/components/toolbar.tsx">

<violation number="1" location="packages/ui/src/components/toolbar.tsx:44">
P2: Existing preview URLs with `toolbar-panel=props` now open with the toolbar collapsed and the replacement Props panel closed, losing the user's previously selected Props view. Consider migrating this legacy query state to the new `props-panel-open` state (and removing the obsolete query parameter) when loading or navigating a preview.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/ui/src/components/toolbar.tsx
Comment thread packages/ui/src/components/topbar/props-panel-toggle.tsx
Comment thread packages/ui/src/contexts/props-panel.tsx Outdated

@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 2 files (changes from recent commits).

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=".changeset/preview-props-editor.md">

<violation number="1">
P3: The changelog now describes a toolbar `Props` tab, but the final UI places the editor in a right-docked panel opened from the topbar. Updating this entry to describe the panel would keep the release notes accurate.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

@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.

All reported issues were addressed across 7 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/ui/src/utils/sanitize-preview-fields.ts Outdated
Comment thread packages/ui/src/components/preview-props-editor.tsx Outdated

@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.

0 issues found across 3 files (changes from recent commits).

Requires human review: Auto-approval blocked by 6 unresolved issues from previous reviews.

Re-trigger cubic

@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.

0 issues found across 1 file (changes from recent commits).

Requires human review: Auto-approval blocked by 5 unresolved issues from previous reviews.

Re-trigger cubic

@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.

0 issues found across 15 files (changes from recent commits).

Requires human review: Auto-approval blocked by 2 unresolved issues from previous reviews.

Re-trigger cubic

Comment thread packages/ui/src/contexts/props-panel.tsx Outdated
Comment thread packages/ui/src/components/preview-props-editor.tsx
Comment thread packages/ui/src/components/preview-props-editor.tsx Outdated
Comment thread packages/ui/src/components/preview-props-editor.tsx Outdated
Comment thread .changeset/props-editor-redesign.md Outdated

@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.

All reported issues were addressed across 3 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/ui/src/components/preview-props-editor.tsx

@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.

0 issues found across 1 file (changes from recent commits).

Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.

Re-trigger cubic

@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.

0 issues found across 1 file (changes from recent commits).

Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.

Re-trigger cubic

…editor

The props editor moves out of the bottom toolbar - whose tabs are
diagnoses, not inputs, and whose drawer left almost no room to edit -
into a collapsible panel docked right of the preview canvas, toggled
from the topbar. The panel insets between the topbar and toolbar so
neither is displaced, stays open across template navigation (its state
lives in a provider mounted in the preview layout and persists per
workspace), and only animates on explicit toggles.

The editing surface is a syntax-highlighted JSON editor: a transparent
textarea overlaid on a prism-react-renderer render sharing the source
view's theme, adding no dependency. Valid JSON re-renders the preview
live, invalid JSON shows the parse error inline and leaves the preview
on the last valid render, and values are deliberately not validated
against the component - wrong values break the render, which the error
overlay surfaces. Static builds show the props read-only. Stale
?toolbar-panel=props links coerce to a closed toolbar.
The applied override is now the source of truth for the editor: local
state only holds the raw draft text, which can be momentarily invalid
or formatted differently than the applied value, so the mirror effect
and its debounce-cancellation disappear. Edits apply on every valid
keystroke. The panel's open state reads through the existing
useCachedWorkspaceState hook, and the changeset bumps only
@react-email/ui since the fixed group carries react-email along.
Applying on every keystroke queues a server render per intermediate
state - server actions run serially and each uncached render bundles
the template - so a burst of typing builds a multi-second backlog and
the preview appears stuck on a stale or broken state long after the
text is fixed. Every intermediate state also lands permanently in the
render cache. The draft still updates per keystroke; only applying is
debounced.
Navigation only changes route params, which does not remount page
components, so the editor's draft and parse error survived into the
next template. Keying the editor by the email slug remounts it per
template, matching how the override itself already resets on
navigation.
@felipefreitag
felipefreitag force-pushed the feat/props-editor-typed-form branch from b5841b3 to dd7dfa3 Compare July 14, 2026 16:35
@felipefreitag
felipefreitag merged commit badeb1b into canary Jul 14, 2026
17 checks passed
@felipefreitag
felipefreitag deleted the feat/props-editor-typed-form branch July 14, 2026 16:39
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.

3 participants