🎨 Palette: [UX improvement] Auto-focus Close button in Lightbox (#104)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
Ralksta
2026-04-21 22:51:31 +02:00
committed by GitHub
parent b803daf8f9
commit 16e1c7647b
3 changed files with 24 additions and 7 deletions

View File

@@ -41,9 +41,12 @@ export async function POST(request: NextRequest) {
} }
if (!isProtected(slug, type)) { if (!isProtected(slug, type)) {
return NextResponse.json({ return NextResponse.json(
{
error: `${type === 'subpage' ? 'Subpage' : 'Album'} is not password-protected`, error: `${type === 'subpage' ? 'Subpage' : 'Album'} is not password-protected`,
}, { status: 400 }); },
{ status: 400 },
);
} }
const setCookie = authenticate(slug, password, type); const setCookie = authenticate(slug, password, type);

View File

@@ -31,6 +31,7 @@ export function Lightbox({ assets, currentIndex, onClose, onNext, onPrev }: Ligh
const { exifData, exifLoading, fetchExif, clearExif } = useExif(); const { exifData, exifLoading, fetchExif, clearExif } = useExif();
const [imageLoaded, setImageLoaded] = useState(false); const [imageLoaded, setImageLoaded] = useState(false);
const overlayRef = useRef<HTMLDivElement>(null); const overlayRef = useRef<HTMLDivElement>(null);
const closeBtnRef = useRef<HTMLButtonElement>(null);
const current = assets[currentIndex]; const current = assets[currentIndex];
const [mounted, setMounted] = useState(false); const [mounted, setMounted] = useState(false);
@@ -40,6 +41,13 @@ export function Lightbox({ assets, currentIndex, onClose, onNext, onPrev }: Ligh
setMounted(true); setMounted(true);
}, []); }, []);
// Auto-focus the close button when the modal mounts
useEffect(() => {
if (mounted) {
closeBtnRef.current?.focus();
}
}, [mounted]);
// Reset EXIF data when switching images; refetch if panel is open // Reset EXIF data when switching images; refetch if panel is open
useEffect(() => { useEffect(() => {
clearExif(); clearExif();
@@ -109,7 +117,13 @@ export function Lightbox({ assets, currentIndex, onClose, onNext, onPrev }: Ligh
aria-label="Image viewer" aria-label="Image viewer"
> >
{/* Close button */} {/* Close button */}
<button className={styles.close} onClick={onClose} aria-label="Close" title="Close (Esc)"> <button
ref={closeBtnRef}
className={styles.close}
onClick={onClose}
aria-label="Close"
title="Close (Esc)"
>
<svg <svg
aria-hidden="true" aria-hidden="true"
viewBox="0 0 24 24" viewBox="0 0 24 24"

View File

@@ -64,8 +64,8 @@ subpages:
albums: albums:
- 55555555-5555-5555-5555-555555555555 - 55555555-5555-5555-5555-555555555555
- 66666666-6666-6666-6666-666666666666: - 66666666-6666-6666-6666-666666666666:
title: "Private Highlights" title: 'Private Highlights'
password: "album-secret-123" # Optional: album-level protection password: 'album-secret-123' # Optional: album-level protection
``` ```
Alternatively, you can use the object notation (recommended): Alternatively, you can use the object notation (recommended):
@@ -99,7 +99,7 @@ albums:
- 'album-uuid': My Title # → displays "My Title" instead - 'album-uuid': My Title # → displays "My Title" instead
- 'album-uuid': - 'album-uuid':
title: My Private Title title: My Private Title
password: "secure-password" # → adds a password gate to this specific album password: 'secure-password' # → adds a password gate to this specific album
``` ```
**Full example:** **Full example:**