Skip to content

feat(LightBox): add zoom with withZoom - #3513

Open
Lisa18289 wants to merge 15 commits into
nextfrom
claude/lightbox-zoom-feature-3eca50
Open

Lisa18289 wants to merge 15 commits into
nextfrom
claude/lightbox-zoom-feature-3eca50

Conversation

@Lisa18289

@Lisa18289 Lisa18289 commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Adds withZoom to LightBox, modelled on Mantine's lightbox zoom. Click, double tap or Enter toggle 2×; the mouse wheel, a pinch and +/- zoom up to 3×, or to an image's natural size if that is larger; dragging and the arrow keys move the zoomed content, which may cover the whole screen. In a LightBoxGallery each item zooms on its own, and swiping and the arrows only page while it is not zoomed.

The gestures run on the host in the new generated LightBoxZoom, so the remote LightBox and the Vue rebuild only place it. The zoom area is focusable, describes its keys to screen readers, and its focus ring follows what is on screen.

Layout change for every light box: close and the ActionGroup now sit in one row in the screen's top right corner, close last, and the gallery's arrows and indicators sit at the screen's edges at the same distance. Hence the changed baselines; the Linux ones come from update-screenshots.

Closes #3447

🤖 Generated with Claude Code

`withZoom` makes the content zoomable: click, double tap or Enter toggle
2×, the mouse wheel, a pinch and the `+`/`-` keys zoom up to 3×, dragging
and the arrow keys move the zoomed content. Zoomed content may cover the
whole screen. In a `LightBoxGallery` each item zooms on its own, and
swiping and the arrow keys only page while the item is not zoomed.

The gestures run on the host in the new generated `LightBoxZoom`, so the
remote `LightBox` and the Vue rebuild only place it. A nested zoom (a
gallery item's) switches the surrounding one off.

The light box's actions (close and `ActionGroup`) move to the screen's
top right corner, in one row with close last, and the gallery's arrows
and indicators to the screen's edges at the same distance.

Closes #3447

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Lisa18289 Lisa18289 self-assigned this Oct 15, 2026
@Lisa18289 Lisa18289 added the update-screenshots Label a PR to update the screenshots used for visual regression testing label Oct 15, 2026
@github-actions github-actions Bot removed the update-screenshots Label a PR to update the screenshots used for visual regression testing label Oct 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

Preview environments are ready:

Type URL
docs pr-3513.docs.review.flow-components.de
storybook pr-3513.storybook.review.flow-components.de

Images:

  • docs: ghcr.io/mittwald/flow/docs:pr-3513
  • storybook: ghcr.io/mittwald/flow/storybook:pr-3513

github-actions Bot and others added 4 commits October 15, 2026 06:30
Co-authored-by: Lisa18289 <84317589+Lisa18289@users.noreply.github.com>
The actions now put the tunnelled `ActionGroup` before the close button.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
How the zoom is operated is quickly found out by using it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A wheel or Safari gesture zoom focuses the zoom area, so the arrows
  move a zoomed gallery item instead of paging
- Handle Safari's trackpad pinch (gesture events), which zoomed the page
- Leave Ctrl/Cmd/Alt key combinations to the browser (page zoom, history)
- `withZoom` always fits the content to the screen; with
  `fitScreen={false}` the wheel zoomed instead of scrolling and the
  zoomed content was clipped
- Gate the "LightBox" visual scenario for cross-version below 1.6.0: the
  close button moved behind the `ActionGroup`

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ Cross-Version Tests Passed

The current host still renders old published remote versions correctly (iframe) and in the same DOM shape (in-process).

Iframe harness (attribute-accurate): ✅ passed

In-process harness (structure-only): ✅ passed

Run details

Lisa18289 and others added 8 commits October 15, 2026 13:22
…m area

The item remounts on paging, so a focused zoom area dropped the focus to
the body. The light box's focus containment caught it a frame later, on
whatever came first in the light box.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o hooks

maxScale was a remote property no caller passed; the zoom keeps 3 as its
maximum. withZoom documents its default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The bounds were only recomputed during an interaction, so a smaller
window left the zoomed content and its focus ring off screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e-pr-3513-1e990b

# Conflicts:
#	apps/remote-dom-demo/src/app/remote-vue/_demos/modal.tsx
#	apps/remote-dom-demo/src/app/remote/modal/page.tsx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Focusing only on mount loses the focus to the dialog's autofocus, which broke the
'LightBox with Gallery' visual test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lisa18289 added a commit that referenced this pull request Oct 27, 2026
Same line as #3513 on next, so the merge of main into next stays clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Lisa18289
Lisa18289 marked this pull request as ready for review October 27, 2026 09:18
@Lisa18289
Lisa18289 requested a review from a team October 27, 2026 09:18
- Page by swipe only on the release of the pointer that started it, so a
  button press after a pinch does not page back

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Raise the maximum scale to an image's natural size, at least 3x
- Mark LightBoxGalleryItem's withZoom as internal

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

This branch has not been deployed

No deployments
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