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:
TerryM
2026-05-30 02:27:20 +08:00
parent b848ce5db3
commit ed6e0023b8

View File

@@ -151,12 +151,11 @@ function LightboxView({
const [isCaptionVisible, setIsCaptionVisible] = useState(true);
const touchStartX = useRef<number | null>(null);
const goPrev = useCallback(
() => setIndex((i) => (i - 1 + images.length) % images.length),
[images.length],
);
// Clamp at the ends instead of wrapping; the nav arrows / swipe / arrow
// keys should all behave like a linear gallery, not a carousel.
const goPrev = useCallback(() => setIndex((i) => Math.max(0, i - 1)), []);
const goNext = useCallback(
() => setIndex((i) => (i + 1) % images.length),
() => setIndex((i) => Math.min(images.length - 1, i + 1)),
[images.length],
);
@@ -234,8 +233,7 @@ function LightboxView({
{/* Image stage */}
<div className="relative flex min-h-0 w-full flex-1 items-center justify-center">
{hasMany ? (
<>
{hasMany && index > 0 ? (
<button
type="button"
onClick={(e) => {
@@ -247,6 +245,8 @@ function LightboxView({
>
<ChevronLeft className="h-6 w-6" />
</button>
) : null}
{hasMany && index < images.length - 1 ? (
<button
type="button"
onClick={(e) => {
@@ -258,7 +258,6 @@ function LightboxView({
>
<ChevronRight className="h-6 w-6" />
</button>
</>
) : null}
<div