ui(lightbox): hide nav arrow at the gallery ends
Clamp goPrev / goNext instead of wrapping the index, and hide the left chevron on the first image and the right chevron on the last one. Arrow keys, swipe gestures, and the on-screen buttons all behave like a linear gallery now, so users get a clear cue that they have reached the end instead of unexpectedly looping back.
This commit is contained in:
@@ -151,12 +151,11 @@ function LightboxView({
|
|||||||
const [isCaptionVisible, setIsCaptionVisible] = useState(true);
|
const [isCaptionVisible, setIsCaptionVisible] = useState(true);
|
||||||
const touchStartX = useRef<number | null>(null);
|
const touchStartX = useRef<number | null>(null);
|
||||||
|
|
||||||
const goPrev = useCallback(
|
// Clamp at the ends instead of wrapping; the nav arrows / swipe / arrow
|
||||||
() => setIndex((i) => (i - 1 + images.length) % images.length),
|
// keys should all behave like a linear gallery, not a carousel.
|
||||||
[images.length],
|
const goPrev = useCallback(() => setIndex((i) => Math.max(0, i - 1)), []);
|
||||||
);
|
|
||||||
const goNext = useCallback(
|
const goNext = useCallback(
|
||||||
() => setIndex((i) => (i + 1) % images.length),
|
() => setIndex((i) => Math.min(images.length - 1, i + 1)),
|
||||||
[images.length],
|
[images.length],
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -234,31 +233,31 @@ function LightboxView({
|
|||||||
|
|
||||||
{/* Image stage */}
|
{/* Image stage */}
|
||||||
<div className="relative flex min-h-0 w-full flex-1 items-center justify-center">
|
<div className="relative flex min-h-0 w-full flex-1 items-center justify-center">
|
||||||
{hasMany ? (
|
{hasMany && index > 0 ? (
|
||||||
<>
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
onClick={(e) => {
|
||||||
onClick={(e) => {
|
e.stopPropagation();
|
||||||
e.stopPropagation();
|
goPrev();
|
||||||
goPrev();
|
}}
|
||||||
}}
|
className="absolute left-2 top-1/2 z-10 flex h-12 w-12 -translate-y-1/2 items-center justify-center rounded-full bg-black/60 text-white shadow-lg ring-1 ring-white/25 transition hover:bg-black/80 md:left-6"
|
||||||
className="absolute left-2 top-1/2 z-10 flex h-12 w-12 -translate-y-1/2 items-center justify-center rounded-full bg-black/60 text-white shadow-lg ring-1 ring-white/25 transition hover:bg-black/80 md:left-6"
|
aria-label="Previous"
|
||||||
aria-label="Previous"
|
>
|
||||||
>
|
<ChevronLeft className="h-6 w-6" />
|
||||||
<ChevronLeft className="h-6 w-6" />
|
</button>
|
||||||
</button>
|
) : null}
|
||||||
<button
|
{hasMany && index < images.length - 1 ? (
|
||||||
type="button"
|
<button
|
||||||
onClick={(e) => {
|
type="button"
|
||||||
e.stopPropagation();
|
onClick={(e) => {
|
||||||
goNext();
|
e.stopPropagation();
|
||||||
}}
|
goNext();
|
||||||
className="absolute right-2 top-1/2 z-10 flex h-12 w-12 -translate-y-1/2 items-center justify-center rounded-full bg-black/60 text-white shadow-lg ring-1 ring-white/25 transition hover:bg-black/80 md:right-6"
|
}}
|
||||||
aria-label="Next"
|
className="absolute right-2 top-1/2 z-10 flex h-12 w-12 -translate-y-1/2 items-center justify-center rounded-full bg-black/60 text-white shadow-lg ring-1 ring-white/25 transition hover:bg-black/80 md:right-6"
|
||||||
>
|
aria-label="Next"
|
||||||
<ChevronRight className="h-6 w-6" />
|
>
|
||||||
</button>
|
<ChevronRight className="h-6 w-6" />
|
||||||
</>
|
</button>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|||||||
Reference in New Issue
Block a user