From c68ef346bf1f73162b11bf4425d4d87e3ee880aa Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Mon, 29 Jun 2026 14:49:24 -0400 Subject: [PATCH] fix(ui): MediaGallery lightbox uses folds Overlay + FocusTrap (native-cinny audit 8/N) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The full-screen media viewer was a raw
rendered in place with manual focus. Wrapped it in folds Overlay (portal + backdrop, proper stacking) and FocusTrap (focus management), keeping its own arrow/Escape key handling. The light-on-dark chrome (#fff over the forced-black media stage) is kept — it's a justified, always-dark media-viewer scrim, not theme chrome. Co-Authored-By: Claude Opus 4.8 --- src/app/features/room/MediaGallery.tsx | 195 +++++++++++++------------ 1 file changed, 104 insertions(+), 91 deletions(-) diff --git a/src/app/features/room/MediaGallery.tsx b/src/app/features/room/MediaGallery.tsx index bae6c024f..cd8543f7f 100644 --- a/src/app/features/room/MediaGallery.tsx +++ b/src/app/features/room/MediaGallery.tsx @@ -6,6 +6,8 @@ import { Icon, IconButton, Icons, + Overlay, + OverlayBackdrop, Scroll, Spinner, Text, @@ -15,6 +17,7 @@ import { config, } from 'folds'; import { EventType, MatrixClient, MatrixEvent, MsgType, Room } from 'matrix-js-sdk'; +import FocusTrap from 'focus-trap-react'; import classNames from 'classnames'; import { useNearViewport } from '../../hooks/useNearViewport'; import { IEncryptedFile, IImageInfo, IThumbnailContent } from '../../../types/matrix/common'; @@ -250,102 +253,112 @@ function Lightbox({ }); return ( - // eslint-disable-next-line jsx-a11y/no-static-element-interactions -
- {/* Header bar */} - }> + - - - {item.body || (item.msgtype === MsgType.Video ? 'Video' : 'Image')} - - - {item.sender} · {dateStr} - - - - {index + 1} / {items.length} - - - Close - - } + {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */} +
- {(ref) => ( - - - - )} - - + {/* Header bar */} + + + + {item.body || (item.msgtype === MsgType.Video ? 'Video' : 'Image')} + + + {item.sender} · {dateStr} + + + + {index + 1} / {items.length} + + + Close + + } + > + {(ref) => ( + + + + )} + + - {/* Media area with nav arrows */} - - {index > 0 && ( - - - - )} - - - - {index < items.length - 1 && ( - - - - )} - -
+ {index > 0 && ( + + + + )} + + + + {index < items.length - 1 && ( + + + + )} +
+
+ + ); }