Skip to content

Preview data editor and rendered preview pane #45

Description

@patoperpetua

Parent: #5
Depends on: #40

Goal

Add the preview-data editor and the rendered preview pane to @singleton-sd/post-kit-editor. An admin user must be able to edit the sample values in preview.json and immediately see the email rendered with those values, using the same rendering path as @singleton-sd/post-kit-compiler so what they see matches what will be published.

Scope

Preview data editor

  • src/preview/PreviewDataEditor.tsx — edits TemplatePreviewData (Record<string, string>) as a key/value list:
    • One row per declared variable, pre-populated from the working previewData.
    • Rows for variables declared in metadata.variables but missing from previewData render with an empty value rather than being hidden.
    • Rows present in previewData but not declared in metadata.variables are shown and marked as extra, so the user can remove them.
    • Add/remove row affordances; edits update the working TemplateSourceFiles state.
  • Values are strings only, matching TemplatePreviewData.

Rendered preview

  • src/preview/PreviewPane.tsx — renders the current EmailBuilder document with the current preview data substituted.
  • Reuse @singleton-sd/post-kit-compiler rather than reimplementing rendering or {{variable}} substitution. Add it as a runtime dependency.
  • Preferred approach: call the compiler's existing compile/validate entry point with the in-memory TemplateSourceFiles and render the resulting HTML. If the compiler's public surface is filesystem-bound in a way that cannot run in a browser, use the object-based entry point (compile()), and document any browser-compatibility caveat in the package README.
  • Display the result in a sandboxed <iframe> (sandbox attribute set, scripts disabled) so template markup cannot affect the host admin application.
  • Debounce re-rendering on rapid edits so typing does not re-render on every keystroke.

Preview failure handling

  • When rendering fails (malformed document, template syntax error), the preview pane shows the compiler's error message in place of the preview and leaves the rest of the editor usable. The editor must not crash or unmount the canvas.

Preview surface

Expose the rendered HTML to the consumer through a read-only callback so an application can offer its own "open preview in new tab" behaviour:

onPreviewRendered?: (html: string) => void;

Add this as an optional prop on EmailTemplateEditorProps.

Constraints

  • Do not reimplement HTML rendering or variable substitution — delegate to @singleton-sd/post-kit-compiler.
  • Pin the compiler as a workspace dependency (workspace:*), consistent with the other packages.
  • Preview must render in a sandboxed iframe with scripting disabled.
  • Do not implement validation messaging, save, or send-test — separate issues.
  • Preview data must never contain real personal data; the README section for this feature should state that sample values are committed to the consumer's repository and must stay synthetic.
  • No network calls and no filesystem access from the editor package.
  • Do not block the canvas or metadata editing while a preview render is in flight.

Acceptance criteria

  • preview.json values are editable and update the working TemplateSourceFiles state.
  • Declared-but-missing variables appear as empty rows; undeclared extras are shown and removable.
  • The preview pane renders the current document with current preview values via @singleton-sd/post-kit-compiler.
  • Rendering happens in a sandboxed iframe with scripts disabled.
  • Re-rendering is debounced so rapid typing does not render on every keystroke.
  • A render failure shows the compiler error message and leaves the rest of the editor functional.
  • onPreviewRendered is called with the rendered HTML when a render succeeds.
  • README documents that preview data is committed to the consumer repository and must contain only synthetic values.
  • Component tests cover: preview-data edits reaching state, missing/extra variable rows, and the render-failure path.
  • pnpm -r --if-present run test passes.

Agent implementation notes

Read packages/post-kit-compiler/src/compiler.ts and its README first to choose the right entry point and understand what errors it throws. Read the working-state model from #40 and extend it rather than introducing separate state. Branch: feat/<issue-number>-editor-preview.

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockedHas an unresolved Depends on: line (docs/github-source-of-truth.md, section 5) — do not claimenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions