@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
90 lines (89 loc) • 2.84 kB
JavaScript
import { isTypingTarget } from "./useViewerGestures.mjs";
import { useCallback, useEffect, useRef } from "react";
//#region src/Image/viewer/useGalleryNav.ts
const readNatural = (element) => {
if (element.naturalWidth > 0 && element.naturalHeight > 0) return {
height: element.naturalHeight,
width: element.naturalWidth
};
const rect = element.getBoundingClientRect();
return {
height: Math.max(rect.height, 1),
width: Math.max(rect.width, 1)
};
};
const useGalleryNav = ({ cancelPendingClose, currentIndex, entries, flipX, flipY, getInitialScale, resetCloseTracking, rotate, scale, setCurrentIndex, setNatural, setSource, switchTo, syncZoomNatural, x, y }) => {
const indexRef = useRef(currentIndex);
indexRef.current = currentIndex;
const switchingRef = useRef(false);
const switchToRef = useRef(switchTo);
switchToRef.current = switchTo;
const cancelPendingCloseRef = useRef(cancelPendingClose);
cancelPendingCloseRef.current = cancelPendingClose;
const resetCloseTrackingRef = useRef(resetCloseTracking);
resetCloseTrackingRef.current = resetCloseTracking;
const goTo = useCallback((nextIndex) => {
if (switchingRef.current) return;
if (nextIndex < 0 || nextIndex >= entries.length || nextIndex === indexRef.current) return;
switchingRef.current = true;
cancelPendingCloseRef.current();
resetCloseTrackingRef.current();
switchToRef.current(() => {
const nextEntry = entries[nextIndex];
setCurrentIndex(nextIndex);
setSource(nextEntry.src);
rotate.jump(0);
flipX.jump(false);
flipY.jump(false);
const nextNatural = readNatural(nextEntry.element);
setNatural(nextNatural);
syncZoomNatural(nextNatural);
scale.jump(getInitialScale());
x.jump(0);
y.jump(0);
switchingRef.current = false;
}, nextIndex > indexRef.current ? 1 : -1);
}, [
entries,
flipX,
flipY,
getInitialScale,
rotate,
scale,
setCurrentIndex,
setNatural,
setSource,
syncZoomNatural,
x,
y
]);
const prev = useCallback(() => goTo(indexRef.current - 1), [goTo]);
const next = useCallback(() => goTo(indexRef.current + 1), [goTo]);
const isGallery = entries.length > 1;
useEffect(() => {
if (!isGallery) return;
const listener = (event) => {
if (event.altKey || event.ctrlKey || event.metaKey || event.defaultPrevented) return;
if (isTypingTarget(event.target)) return;
if (event.key === "ArrowLeft") prev();
else if (event.key === "ArrowRight") next();
else return;
event.preventDefault();
};
document.addEventListener("keydown", listener);
return () => document.removeEventListener("keydown", listener);
}, [
isGallery,
next,
prev
]);
return {
hasNext: currentIndex < entries.length - 1,
hasPrev: currentIndex > 0,
next,
prev
};
};
//#endregion
export { readNatural, useGalleryNav };
//# sourceMappingURL=useGalleryNav.mjs.map