feat(lightbox): add keyboard shortcut 'i' for EXIF toggle and title tooltips on navigation buttons [#3]
Adds a keyboard shortcut (`i` or `I`) to toggle EXIF info in the Lightbox component. Also adds descriptive `title` tooltips with keyboard shortcut hints to all interactive buttons (Close, Previous, Next, Info) in the Lightbox overlay. This improves accessibility and the overall user experience by providing more discoverable navigation options. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
3
.Jules/palette.md
Normal file
3
.Jules/palette.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
## 2024-03-XX - Lightbox Accessibility
|
||||||
|
**Learning:** Found that Lightbox overlay has good keyboard navigation (esc/left/right) but lacked tooltip hints for those controls and lacked a shortcut for EXIF data toggle.
|
||||||
|
**Action:** Added `i` shortcut and `title` attributes on interactive elements in Lightbox.
|
||||||
@@ -76,6 +76,17 @@ export function Lightbox({ assets, currentIndex, onClose, onNext, onPrev }: Ligh
|
|||||||
onSwipeRight: onPrev,
|
onSwipeRight: onPrev,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Listen for 'i' key to toggle EXIF
|
||||||
|
useEffect(() => {
|
||||||
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
|
if (e.key === 'i' || e.key === 'I') {
|
||||||
|
handleExifToggle();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.addEventListener('keydown', handleKeyDown);
|
||||||
|
return () => document.removeEventListener('keydown', handleKeyDown);
|
||||||
|
}, [handleExifToggle]);
|
||||||
|
|
||||||
// Click on overlay background → close
|
// Click on overlay background → close
|
||||||
const handleOverlayClick = useCallback(
|
const handleOverlayClick = useCallback(
|
||||||
(e: React.MouseEvent) => {
|
(e: React.MouseEvent) => {
|
||||||
@@ -95,7 +106,7 @@ export function Lightbox({ assets, currentIndex, onClose, onNext, onPrev }: Ligh
|
|||||||
onTouchEnd={handleTouchEnd}
|
onTouchEnd={handleTouchEnd}
|
||||||
>
|
>
|
||||||
{/* Close button */}
|
{/* Close button */}
|
||||||
<button className={styles.close} onClick={onClose} aria-label="Close">
|
<button className={styles.close} onClick={onClose} aria-label="Close" title="Close (Esc)">
|
||||||
<svg
|
<svg
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
@@ -114,6 +125,7 @@ export function Lightbox({ assets, currentIndex, onClose, onNext, onPrev }: Ligh
|
|||||||
className={`${styles.nav} ${styles.navPrev}`}
|
className={`${styles.nav} ${styles.navPrev}`}
|
||||||
onClick={onPrev}
|
onClick={onPrev}
|
||||||
aria-label="Previous photo"
|
aria-label="Previous photo"
|
||||||
|
title="Previous photo (Left arrow)"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@@ -153,6 +165,7 @@ export function Lightbox({ assets, currentIndex, onClose, onNext, onPrev }: Ligh
|
|||||||
className={`${styles.nav} ${styles.navNext}`}
|
className={`${styles.nav} ${styles.navNext}`}
|
||||||
onClick={onNext}
|
onClick={onNext}
|
||||||
aria-label="Next photo"
|
aria-label="Next photo"
|
||||||
|
title="Next photo (Right arrow)"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@@ -176,6 +189,7 @@ export function Lightbox({ assets, currentIndex, onClose, onNext, onPrev }: Ligh
|
|||||||
className={styles.infoToggle}
|
className={styles.infoToggle}
|
||||||
onClick={handleExifToggle}
|
onClick={handleExifToggle}
|
||||||
aria-label="Toggle photo info"
|
aria-label="Toggle photo info"
|
||||||
|
title="Toggle photo info (i)"
|
||||||
>
|
>
|
||||||
{showExif ? 'Hide Info' : 'Info'}
|
{showExif ? 'Hide Info' : 'Info'}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user