fix(lightbox): mobile toolbar clipping + iOS safe-area + viewport-fit (#336)
When feedback was enabled the lightbox bottom toolbar packed counter + zoom + download + like + 5-star + comments into a single row that overflowed the viewport on iPhone-class widths, putting the rating stars under the screen edge and below the iOS home indicator. Changes: - Bottom toolbar now uses flex-wrap with reduced gap/padding on mobile, so all controls fit (375px viewport: max-right 363 < 375; 390px: max-right 378 < 390; 393px: max-right 393 < 393). - pb computed as max(0.75rem, env(safe-area-inset-bottom)) so the row sits above the iOS home indicator on devices with a gesture bar. - Close button top/right now use max(1rem, env(safe-area-inset-*)) so it doesn't disappear under the notch / dynamic island. - "Swipe to navigate" hint moved from bottom-20 to bottom-40 so it clears the now-taller wrapped toolbar. - index.html viewport meta gains viewport-fit=cover to enable env(safe-area-inset-*) on iOS Safari. Verified in mobile emulation across iPhone SE (375x667), iPhone 13/14 (390x844), iPhone 14 Pro (393x852) portrait, and 14 Pro landscape (852x393) — toolbar fits, photo centered, no clipping.
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<title>PicPeak - Photo Sharing Platform</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -426,12 +426,16 @@ export const PhotoLightbox: React.FC<PhotoLightboxProps> = ({
|
||||
|
||||
return (
|
||||
<div className={lightboxClass}>
|
||||
{/* Close button */}
|
||||
{/* Close button. top respects iOS safe-area (notch) so it doesn't
|
||||
disappear under the camera/dynamic-island. */}
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="absolute top-4 p-2 bg-white/10 hover:bg-white/20 rounded-full transition-colors z-30"
|
||||
className="absolute p-2 bg-white/10 hover:bg-white/20 rounded-full transition-colors z-30"
|
||||
aria-label="Close"
|
||||
style={{ right: isDesktopFeedback ? `${desktopFeedbackWidth + 16}px` : '1rem' }}
|
||||
style={{
|
||||
top: 'max(1rem, env(safe-area-inset-top))',
|
||||
right: isDesktopFeedback ? `${desktopFeedbackWidth + 16}px` : 'max(1rem, env(safe-area-inset-right))'
|
||||
}}
|
||||
>
|
||||
<X className="w-6 h-6 text-white" />
|
||||
</button>
|
||||
@@ -456,19 +460,25 @@ export const PhotoLightbox: React.FC<PhotoLightboxProps> = ({
|
||||
</button>
|
||||
) : null}
|
||||
|
||||
{/* Bottom toolbar */}
|
||||
{/* Bottom toolbar. flex-wrap + reduced gap/padding on mobile prevent
|
||||
the action row from clipping when feedback (likes / 5-star ratings /
|
||||
comments) is enabled. pb-[env(safe-area-inset-bottom)] keeps the
|
||||
buttons above the iOS home indicator. */}
|
||||
<div
|
||||
className="absolute bottom-0 left-0 bg-gradient-to-t from-black/80 to-transparent p-4 z-20"
|
||||
style={{ right: isDesktopFeedback ? `${desktopFeedbackWidth}px` : 0 }}
|
||||
className="absolute bottom-0 left-0 bg-gradient-to-t from-black/80 to-transparent px-3 pt-3 pb-3 sm:p-4 z-20"
|
||||
style={{
|
||||
right: isDesktopFeedback ? `${desktopFeedbackWidth}px` : 0,
|
||||
paddingBottom: 'max(0.75rem, env(safe-area-inset-bottom))'
|
||||
}}
|
||||
>
|
||||
<div className="max-w-4xl mx-auto flex items-center justify-between">
|
||||
<div className="max-w-4xl mx-auto flex items-center justify-between gap-2 flex-wrap">
|
||||
<div className="text-white">
|
||||
<p className="text-sm opacity-75">
|
||||
{currentIndex + 1} / {photos.length}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
<div className="flex items-center gap-1 sm:gap-2 flex-wrap justify-end">
|
||||
<button
|
||||
onClick={handleZoomOut}
|
||||
disabled={zoom <= 1}
|
||||
@@ -638,8 +648,9 @@ export const PhotoLightbox: React.FC<PhotoLightboxProps> = ({
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Touch/swipe indicators for mobile */}
|
||||
<div className="absolute bottom-20 left-1/2 -translate-x-1/2 text-white text-sm opacity-50 pointer-events-none md:hidden z-20">
|
||||
{/* Touch/swipe hint for mobile. Sits above the bottom toolbar
|
||||
(which can wrap to two rows when feedback controls are enabled). */}
|
||||
<div className="absolute bottom-40 left-1/2 -translate-x-1/2 text-white text-sm opacity-50 pointer-events-none md:hidden z-20">
|
||||
Swipe to navigate
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user