Skip to content

feat: download and copy-as-code for generated components#56

Open
GeneralJerel wants to merge 3 commits intomainfrom
feat/download-generated-components
Open

feat: download and copy-as-code for generated components#56
GeneralJerel wants to merge 3 commits intomainfrom
feat/download-generated-components

Conversation

@GeneralJerel
Copy link
Collaborator

Summary

  • Add download as HTML and copy-as-code buttons to all generated components (widgets, bar charts, pie charts)
  • Downloaded files are standalone HTML that preserves animations, interactivity, and theming — open directly in a browser
  • Copy-as-code copies the raw HTML fragment (widgets) or standalone HTML (charts) to clipboard
  • Zero new dependencies — Chart.js loads from CDN in exported chart files, download uses native Blob API

Changes

New: apps/app/src/components/generative-ui/export-utils.ts

  • assembleStandaloneHtml() — wraps widget HTML in a full document with theme CSS, import maps, and stubbed bridge functions
  • chartToStandaloneHtml() — generates standalone Chart.js HTML from structured chart data
  • triggerDownload() — browser file download via Blob + object URL
  • slugify() — filename helper

Modified: apps/app/src/components/generative-ui/save-template-overlay.tsx

  • Added download (arrow icon) and copy (clipboard icon) buttons alongside existing "Save as Template"
  • Buttons appear on all components when content is ready, including when a template badge is shown
  • Copy shows a check icon confirmation for 1.8s

Modified: apps/app/src/components/generative-ui/widget-renderer.tsx

  • Exported SVG_CLASSES_CSS and FORM_STYLES_CSS constants (needed by export-utils)

Updated: .chalk/plans/demo-gallery.md

Closes

Test plan

  • Generate a widget visualization (e.g. "how does a plane fly") → click download → open .html in browser → verify animations and theme work
  • Generate a bar chart → click download → open in browser → verify Chart.js renders with animations
  • Generate a pie chart → same check
  • Click copy on a widget → paste in editor → verify raw HTML fragment
  • Click copy on a chart → paste → verify standalone HTML
  • Verify "Save as Template" still works alongside new buttons
  • Verify buttons appear on matched-template components too

🤖 Generated with Claude Code

Add the ability to download any generated visualization as a standalone
HTML file (with animations preserved) and copy the source code to
clipboard. This addresses the artifact export story needed for the
upcoming component gallery.

- New export-utils.ts with assembleStandaloneHtml (widgets),
  chartToStandaloneHtml (bar/pie charts), and triggerDownload
- Download and copy buttons added to SaveTemplateOverlay, visible on
  all generated components (widgets, bar charts, pie charts)
- Export SVG_CLASSES_CSS and FORM_STYLES_CSS from widget-renderer
- Update demo-gallery plan with Variant-style layout and #55 context

Closes #14
Closes #42
- Single three-dot (...) trigger button in top-right corner
- Dropdown menu with: Copy to clipboard, Download file, Save as artifact
- Overlay only visible on hover (hides when cursor leaves component)
- Menu stays open while interacting, closes on outside click
- Change three-dot trigger from vertical to horizontal orientation
- Remove "Save as artifact" menu item and all save-related state/UI
- Menu now shows only: Copy to clipboard, Download file
- Clean up unused imports (useAgent, SEED_TEMPLATES)
Copy link
Collaborator Author

@GeneralJerel GeneralJerel left a comment

Choose a reason for hiding this comment

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

Review

Overall: Solid feature, clean implementation. The export-utils module is well-structured, the overlay refactor to a dropdown menu is a good UX improvement, and there are no security issues. A few findings below.

Issues

1. description prop declared in interface but unusedsave-template-overlay.tsx:13

The description prop is still in SaveTemplateOverlayProps but is never destructured or used in the component body (line 21–28 omits it). All three callers (widget-renderer.tsx:694, bar-chart.tsx:43, pie-chart.tsx:52) still pass description=. Either remove the prop from the interface + callers, or add a prefixed _description to the destructure to be explicit.

2. Duplicate import lineexport-utils.ts:1-2

import { THEME_CSS } from "./widget-renderer";
import { SVG_CLASSES_CSS, FORM_STYLES_CSS } from "./widget-renderer";

Should be a single import:

import { THEME_CSS, SVG_CLASSES_CSS, FORM_STYLES_CSS } from "./widget-renderer";

3. No error handling on navigator.clipboard.writeTextsave-template-overlay.tsx:70

The .then() has no .catch(). If the clipboard API fails (e.g., browser denies permission, iframe context), this silently does nothing. Consider a minimal .catch() so the user isn't left confused.

4. Component still named SaveTemplateOverlay — The component no longer handles "Save as Template" at all — it's now a download/copy overlay. The filename and export name are misleading. Consider renaming to ExportOverlay or ComponentActionsOverlay. (Low priority if planned for a follow-up.)

5. tmpl-slideIn animation referenced but not definedsave-template-overlay.tsx:116

The dropdown references animation: "tmpl-slideIn 0.15s ease-out". This was presumably defined in a global stylesheet or the old version of this file. Verify the keyframe still exists somewhere — if it was only in the old overlay's inline styles (now removed), the dropdown won't animate.

Nit

  • .chalk/plans/demo-gallery.md (156 lines) is a planning doc that inflates the diff. If intentionally checked in for project context, fine — but it's not a code change.

What looks good

  • escapeHtml() correctly applied to all user-provided strings interpolated into HTML — no XSS risk
  • Import map in assembleStandaloneHtml mirrors widget-renderer's shell, so downloaded widgets work standalone
  • triggerDownload properly revokes the object URL after use
  • Outside-click handler correctly cleans up on unmount

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.

Add copy-as-code and download options for generated artifacts Save / Download Rendered Asset

1 participant