Skip to content

Commit 0538e0f

Browse files
committed
fix: respect device safe areas in mobile fullscreen overlays
1 parent c493818 commit 0538e0f

4 files changed

Lines changed: 40 additions & 1 deletion

File tree

src/app/components/image-viewer/RoomMediaViewer.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,13 @@ export function RoomMediaViewer({
185185
if (!item) return null;
186186

187187
return (
188-
<ModalOverlay open requestClose={requestClose} mobile="fullscreen" background="#000">
188+
<ModalOverlay
189+
open
190+
requestClose={requestClose}
191+
mobile="fullscreen"
192+
background="#000"
193+
respectSafeArea={false}
194+
>
189195
<ResolvedRoomMedia
190196
item={item}
191197
requestClose={requestClose}

src/app/components/message/content/ImageContent.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ export const ImageContent = as<'div', ImageContentProps>(
311311
requestClose={() => setViewer(false)}
312312
mobile="fullscreen"
313313
background="#000"
314+
respectSafeArea={false}
314315
>
315316
{isMobile ? (
316317
viewerContent

src/app/components/modal-overlay/ModalOverlay.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,24 @@ describe('ModalOverlay', () => {
209209
expect(screen.getByTestId('modal-child')).toBeInTheDocument();
210210
});
211211

212+
it('pads the fullscreen wrapper against device safe areas by default', () => {
213+
mobile({ mobile: 'fullscreen' });
214+
215+
const wrapper = screen
216+
.getByTestId('modal-child')
217+
.closest('div[style*="padding-top"]') as HTMLElement;
218+
expect(wrapper.style.paddingTop).toBe(
219+
'var(--safe-area-inset-top, env(safe-area-inset-top, 0px))'
220+
);
221+
});
222+
223+
it('skips safe-area padding when respectSafeArea is false', () => {
224+
mobile({ mobile: 'fullscreen', respectSafeArea: false });
225+
226+
const wrapper = screen.getByTestId('modal-child').parentElement as HTMLElement;
227+
expect(wrapper.style.paddingTop ?? '').toBe('');
228+
});
229+
212230
it('wraps children in a Modal on desktop when size is set', () => {
213231
desktop({ size: '500' });
214232

src/app/components/modal-overlay/ModalOverlay.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ import * as messageCss from '$features/room/message/styles.css';
1212
type FocusTrapOptions = ComponentProps<typeof FocusTrap>['focusTrapOptions'];
1313
type ModalSize = '300' | '400' | '500';
1414

15+
const safeArea = {
16+
top: 'var(--safe-area-inset-top, env(safe-area-inset-top, 0px))',
17+
bottom: 'var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px))',
18+
left: 'var(--safe-area-inset-left, env(safe-area-inset-left, 0px))',
19+
right: 'var(--safe-area-inset-right, env(safe-area-inset-right, 0px))',
20+
};
21+
1522
type ModalOverlayProps = {
1623
open?: boolean;
1724
requestClose: () => void;
@@ -30,6 +37,8 @@ type ModalOverlayProps = {
3037
escapeDeactivates?: FocusTrapOptions['escapeDeactivates'];
3138
/** Fills the mobile fullscreen wrapper, for content that does not paint its own. */
3239
background?: string;
40+
/** Set false for full-bleed viewers that inset their own controls. */
41+
respectSafeArea?: boolean;
3342
children: ReactNode;
3443
};
3544

@@ -42,6 +51,7 @@ export function ModalOverlay({
4251
contentRef,
4352
escapeDeactivates = stopPropagation,
4453
background,
54+
respectSafeArea = true,
4555
children,
4656
}: ModalOverlayProps) {
4757
// Null outside a provider, where desktop is the safe assumption.
@@ -75,6 +85,10 @@ export function ModalOverlay({
7585
display: 'flex',
7686
flexDirection: 'column',
7787
background,
88+
paddingTop: respectSafeArea ? safeArea.top : undefined,
89+
paddingBottom: respectSafeArea ? safeArea.bottom : undefined,
90+
paddingLeft: respectSafeArea ? safeArea.left : undefined,
91+
paddingRight: respectSafeArea ? safeArea.right : undefined,
7892
}}
7993
>
8094
{children}

0 commit comments

Comments
 (0)