Skip to content

fix(web): make share image previews interactive - #1229

Merged
tiann merged 2 commits into
tiann:mainfrom
techotaku39:fix/web-share-preview-interactions
Jul 30, 2026
Merged

fix(web): make share image previews interactive#1229
tiann merged 2 commits into
tiann:mainfrom
techotaku39:fix/web-share-preview-interactions

Conversation

@techotaku39

Copy link
Copy Markdown
Contributor

Summary

  • keep code wrap and copy controls functional inside shared-turn previews
  • apply preview wrap changes to the generated PNG while stripping interactive controls from the final image
  • let preview attachments open in the existing zoomable lightbox with natural-size fitting, wheel zoom, touch pinch, and drag support
  • add stable DOM markers so cloned preview content can preserve behavior without coupling to localized labels

Testing

  • bun typecheck
  • bun run test:web
  • bun run build:web
  • PLAYWRIGHT_WEB_PORT=5196 bunx playwright test e2e/share-turn.spec.ts

The share-turn Playwright coverage verifies:

  • desktop, mobile, and dark-mode 2× exports
  • text-only user fallback and tool-content exclusion
  • Chinese localization and native share activation
  • interactive code wrap and copy controls
  • wrapped versus unwrapped export layout
  • image lightbox sizing and wheel zoom

@techotaku39 techotaku39 reopened this Jul 29, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Findings

  • One Major inline finding.

Questions

  • None.

Summary
Review mode: initial

The image lightbox bypasses the existing Radix modal stack, breaking keyboard focus and Escape behavior inside the share preview.

Testing

  • Repository CI test: passed.
  • Not run locally (automation; PR code was not executed).
  • Add Playwright coverage for Tab focus entering the lightbox and Escape closing only the lightbox.

HAPI Bot

</div>
</div>
</div>
{previewImage ? createPortal(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[MAJOR] Mount the lightbox as a nested Radix dialog

The share preview is already a modal DialogContent (web/src/components/ui/dialog.tsx:20), so Radix traps focus inside that content and treats it as the active dismissable layer. This raw portal mounts a plain role="dialog" under document.body, outside the focus scope: keyboard users cannot Tab into the zoom/close controls, while Escape is still handled by the outer share dialog and closes the share flow instead of only the image viewer.

Suggested fix:

// ZoomableLightbox.tsx
import * as DialogPrimitive from "@radix-ui/react-dialog"

return (
    <DialogPrimitive.Root open={open} onOpenChange={(next) => {
        if (!next) onClose()
    }}>
        <DialogPrimitive.Portal>
            <DialogPrimitive.Content
                className="fixed inset-0 z-50 h-[100dvh] w-full bg-black text-white"
                aria-label={ariaLabel}
            >
                {/* current viewport and toolbar */}
            </DialogPrimitive.Content>
        </DialogPrimitive.Portal>
    </DialogPrimitive.Root>
)

// ShareTurnDialog.tsx: render <ZoomableLightbox /> directly; remove createPortal().

Also let the nested Radix dialog own Escape dismissal (remove the lightbox window-handler Escape branch), and cover Tab/Escape behavior in the Playwright test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in eee3671. The lightbox now mounts as a nested Radix Dialog, lets Radix own Escape dismissal and focus trapping, and no longer uses a raw createPortal from the share dialog. The Playwright scenario now verifies that Tab focus remains inside the lightbox and that Escape closes only the lightbox while leaving the share preview open. bun typecheck, bun run test:web, bun run build:web, and all 8 share-turn Playwright scenarios pass.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Findings

  • None.

Questions

  • None.

Summary
Review mode: follow-up after new commits

No issues found in the latest full diff. The previous modal focus/Escape finding is resolved by mounting the shared lightbox as a nested Radix dialog and adding keyboard coverage. Residual risk: the shared ZoomableLightbox change also affects the existing Mermaid viewer, while this PR’s browser coverage exercises only the nested share-preview path.

Testing

  • Not run locally (automation; PR code was not executed).
  • GitHub test check pending at review time.
  • Suggested: retain or add browser coverage for opening, tabbing within, and closing the standalone Mermaid lightbox.

HAPI Bot

@tiann
tiann merged commit 99814e9 into tiann:main Jul 30, 2026
3 checks passed
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