Skip to content

feat(share): capture a surface as a shareable image - #6609

Closed
tomeredlich wants to merge 1 commit into
mainfrom
claude/snapshot-capture-infra
Closed

feat(share): capture a surface as a shareable image#6609
tomeredlich wants to merge 1 commit into
mainfrom
claude/snapshot-capture-infra

Conversation

@tomeredlich

@tomeredlich tomeredlich commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Puts the snapshot capture path on main, so the surfaces that want a snapshot can add one without each carrying the machinery. Standalone — no dependency on #6556.

What lands

  • captureShareImage.ts — rasterizes a DOM node through @zumer/snapdom at a fixed 1200×630 and brands it. Takes an element or a ref.
  • copyShareImage.ts — writes the PNG to the clipboard with the link beside it as text/plain, so a rich composer takes the image and a plain one takes the link. The blob is handed to ClipboardItem as a promise rather than awaited first, because Safari only honours a clipboard write inside the task that handled the gesture.
  • downloadShareImage.ts — the fallback when the clipboard refuses.
  • shutterSound.ts + shutter.mp3 — one shared Audio element; a rejected autoplay never fails the capture.
  • SnapshotButton.tsx — the control on top of all of it, with the shutter-sweep animation and SnapshotIcon.

What is deliberately not here

The snapshot cards (SnapshotFrame, PollSnapshotCard, HighlightTextSnapshotCard, snapshotGradient, snapshotText) stay on #6556. They describe what a particular surface captures; this PR is only the path that captures it. Same for the unrelated utilities.css animations on that branch — only the shutter sweep came across.

Nothing renders it yet

SnapshotButton has no caller on main after this merges. That is the point of porting the infra first: the placements that will use it are drawn in Features / Snapshot / Surfaces in Storybook (#6569), and land as follow-ups.

SnapshotIcon also appears on #6569. Whichever merges first, the other drops it in a rebase — it is 4 small files.

Testing

  • New SnapshotButton.spec.tsx: copies and reports it, falls back to download when the clipboard refuses, reports a failed capture rather than throwing, and names both halves when a link is passed.
  • copyShareImage.spec.ts came across with the code.
  • shared 381 suites / 2717 tests, webapp 86 / 683. typecheck-strict-changed clean, shared lint clean.
  • Lockfile adds @zumer/snapdom only — verified --frozen-lockfile accepts it unchanged.

Preview domain

https://claude-snapshot-capture-infra.preview.app.daily.dev

Puts the snapshot capture path on main so the surfaces that want a
snapshot can add one without carrying the machinery themselves.

captureShareImage rasterizes a DOM node through snapdom at a fixed
1200x630 and brands it. SnapshotButton is the control on top: it plays
the shutter, captures, and writes the PNG to the clipboard with the
link beside it as text, so a rich composer takes the image and a plain
one takes the link. A browser that refuses the clipboard write gets the
download instead, and a failed capture reports rather than throws.

Nothing renders SnapshotButton yet. The surfaces that will are drawn in
Features / Snapshot / Surfaces in Storybook.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 6, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
daily-webapp Ready Ready Preview Sep 6, 2026 5:53am UTC
1 Skipped Deployment
Project Deployment Actions Updated
storybook Ignored Ignored Sep 6, 2026 5:53am UTC

Request Review

@tomeredlich

Copy link
Copy Markdown
Contributor Author

Folded into #6610, which now carries the capture path and the hot-take placements together against main. Closing so there is one standalone PR rather than a stack.

@tomeredlich tomeredlich closed this Sep 6, 2026
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.

1 participant