uix-image-magnify 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +266 -89
- package/dist/{ImageMagnify-DssaU7jS.d.cts → ImageMagnifyGallery-Bw_SkDZq.d.cts} +35 -18
- package/dist/{ImageMagnify-DssaU7jS.d.ts → ImageMagnifyGallery-Bw_SkDZq.d.ts} +35 -18
- package/dist/index.cjs +128 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -50
- package/dist/index.d.ts +3 -50
- package/dist/index.js +130 -75
- package/dist/index.js.map +1 -1
- package/dist/ssr/index.cjs +406 -4
- package/dist/ssr/index.cjs.map +1 -1
- package/dist/ssr/index.d.cts +11 -4
- package/dist/ssr/index.d.ts +11 -4
- package/dist/ssr/index.js +407 -7
- package/dist/ssr/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { forwardRef, useState, useRef,
|
|
1
|
+
import { forwardRef, useState, useRef, useMemo, useEffect, useCallback, useLayoutEffect } from 'react';
|
|
2
2
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
import { Swiper, SwiperSlide } from 'swiper/react';
|
|
4
|
-
import { Navigation,
|
|
4
|
+
import { Navigation, Keyboard, A11y } from 'swiper/modules';
|
|
5
5
|
import 'swiper/css';
|
|
6
6
|
import 'swiper/css/navigation';
|
|
7
|
-
import 'swiper/css/thumbs';
|
|
8
7
|
|
|
9
8
|
// src/components/ImageMagnify.tsx
|
|
10
9
|
var clamp = (v, min, max) => Math.max(min, Math.min(max, v));
|
|
@@ -80,6 +79,15 @@ function useImageMagnify(options = {}) {
|
|
|
80
79
|
isZoomedRef.current = z;
|
|
81
80
|
setIsZoomed(z);
|
|
82
81
|
if (z) {
|
|
82
|
+
if (modeRef.current === "inner" && dragModeRef.current === "pan") {
|
|
83
|
+
const container = containerRef.current;
|
|
84
|
+
if (container) {
|
|
85
|
+
const rect = container.getBoundingClientRect();
|
|
86
|
+
const s = scaleRef.current;
|
|
87
|
+
txRef.current = rect.width * (1 - s) / 2;
|
|
88
|
+
tyRef.current = rect.height * (1 - s) / 2;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
83
91
|
onZoomStart?.();
|
|
84
92
|
} else {
|
|
85
93
|
if (zoomType === "wheel") {
|
|
@@ -286,8 +294,6 @@ function useImageMagnify(options = {}) {
|
|
|
286
294
|
setZoomed(!isZoomedRef.current);
|
|
287
295
|
} else if (zoomType === "click") {
|
|
288
296
|
setZoomed(!isZoomedRef.current);
|
|
289
|
-
} else if (zoomType === "wheel") {
|
|
290
|
-
setZoomed(!isZoomedRef.current);
|
|
291
297
|
}
|
|
292
298
|
schedule();
|
|
293
299
|
},
|
|
@@ -504,7 +510,8 @@ var ImageMagnify = forwardRef(
|
|
|
504
510
|
const showLens = (mode === "lens" || mode === "follow") && isZoomed;
|
|
505
511
|
const showPane = mode === "side-by-side" && isZoomed;
|
|
506
512
|
const showCursor = mode === "side-by-side" && isZoomed;
|
|
507
|
-
const
|
|
513
|
+
const isInteractive = !disabled && zoomType !== "none";
|
|
514
|
+
const cursorStyle = !isInteractive ? "default" : zoomType === "hover" || zoomType === "hold" || zoomType === "wheel" ? "crosshair" : isZoomed ? "zoom-out" : "zoom-in";
|
|
508
515
|
const outerWidth = isMobile ? "100%" : width;
|
|
509
516
|
return /* @__PURE__ */ jsxs(
|
|
510
517
|
"div",
|
|
@@ -524,7 +531,7 @@ var ImageMagnify = forwardRef(
|
|
|
524
531
|
"div",
|
|
525
532
|
{
|
|
526
533
|
ref: containerRef,
|
|
527
|
-
tabIndex: 0,
|
|
534
|
+
tabIndex: isInteractive ? 0 : -1,
|
|
528
535
|
role: "img",
|
|
529
536
|
"aria-label": alt,
|
|
530
537
|
"aria-disabled": disabled || void 0,
|
|
@@ -691,6 +698,23 @@ var defaultArrowBaseStyle = {
|
|
|
691
698
|
backdropFilter: "blur(4px)",
|
|
692
699
|
WebkitBackdropFilter: "blur(4px)"
|
|
693
700
|
};
|
|
701
|
+
var defaultThumbBaseStyle = {
|
|
702
|
+
flexShrink: 0,
|
|
703
|
+
padding: 0,
|
|
704
|
+
border: "2px solid #e5e5e5",
|
|
705
|
+
background: "#fff",
|
|
706
|
+
cursor: "pointer",
|
|
707
|
+
overflow: "hidden",
|
|
708
|
+
transition: "border-color 0.15s ease, opacity 0.15s ease",
|
|
709
|
+
borderRadius: 2,
|
|
710
|
+
display: "inline-flex",
|
|
711
|
+
alignItems: "center",
|
|
712
|
+
justifyContent: "center",
|
|
713
|
+
boxSizing: "border-box"
|
|
714
|
+
};
|
|
715
|
+
var defaultThumbActiveStyle = {
|
|
716
|
+
borderColor: "#111"
|
|
717
|
+
};
|
|
694
718
|
var visuallyHidden = {
|
|
695
719
|
position: "absolute",
|
|
696
720
|
width: 1,
|
|
@@ -719,6 +743,7 @@ var ImageMagnifyGallery = forwardRef((props, ref) => {
|
|
|
719
743
|
style,
|
|
720
744
|
viewportClassName,
|
|
721
745
|
viewportStyle,
|
|
746
|
+
swiperStyle,
|
|
722
747
|
thumbnailContainerClassName,
|
|
723
748
|
thumbnailContainerStyle,
|
|
724
749
|
thumbnailClassName,
|
|
@@ -735,13 +760,17 @@ var ImageMagnifyGallery = forwardRef((props, ref) => {
|
|
|
735
760
|
...magnifyProps
|
|
736
761
|
} = props;
|
|
737
762
|
const [swiper, setSwiper] = useState(null);
|
|
738
|
-
const [
|
|
739
|
-
|
|
763
|
+
const [localIndex, setLocalIndex] = useState(() => {
|
|
764
|
+
const safeLength = Math.max(1, images.length);
|
|
765
|
+
return Math.max(0, Math.min(safeLength - 1, defaultIndex));
|
|
766
|
+
});
|
|
740
767
|
const prevRef = useRef(null);
|
|
741
768
|
const nextRef = useRef(null);
|
|
742
769
|
const isControlled = controlledActiveIndex !== void 0;
|
|
743
|
-
const
|
|
770
|
+
const rawIndex = isControlled ? controlledActiveIndex : localIndex;
|
|
771
|
+
const activeIndex = images.length ? Math.max(0, Math.min(images.length - 1, rawIndex)) : 0;
|
|
744
772
|
const hasMultiple = images.length > 1;
|
|
773
|
+
const modules = useMemo(() => [Navigation, Keyboard, A11y], []);
|
|
745
774
|
useEffect(() => {
|
|
746
775
|
if (!swiper || swiper.destroyed) return;
|
|
747
776
|
if (isControlled && swiper.activeIndex !== controlledActiveIndex) {
|
|
@@ -751,22 +780,31 @@ var ImageMagnifyGallery = forwardRef((props, ref) => {
|
|
|
751
780
|
useEffect(() => {
|
|
752
781
|
if (!preloadAdjacent || typeof window === "undefined" || images.length <= 1)
|
|
753
782
|
return;
|
|
754
|
-
const targets = /* @__PURE__ */ new Set(
|
|
755
|
-
|
|
756
|
-
(activeIndex
|
|
757
|
-
|
|
783
|
+
const targets = /* @__PURE__ */ new Set();
|
|
784
|
+
if (loop) {
|
|
785
|
+
targets.add((activeIndex + 1) % images.length);
|
|
786
|
+
targets.add((activeIndex - 1 + images.length) % images.length);
|
|
787
|
+
} else {
|
|
788
|
+
if (activeIndex < images.length - 1) targets.add(activeIndex + 1);
|
|
789
|
+
if (activeIndex > 0) targets.add(activeIndex - 1);
|
|
790
|
+
}
|
|
758
791
|
targets.forEach((i) => {
|
|
759
|
-
|
|
792
|
+
const src = images[i];
|
|
793
|
+
if (src) {
|
|
760
794
|
const img = new Image();
|
|
761
|
-
img.src =
|
|
795
|
+
img.src = src;
|
|
762
796
|
}
|
|
763
797
|
});
|
|
764
|
-
}, [activeIndex, images, preloadAdjacent]);
|
|
765
|
-
const
|
|
766
|
-
const
|
|
767
|
-
if (
|
|
768
|
-
|
|
769
|
-
}
|
|
798
|
+
}, [activeIndex, images, preloadAdjacent, loop]);
|
|
799
|
+
const handleSlideChange = (s) => {
|
|
800
|
+
const idx = s.activeIndex;
|
|
801
|
+
if (!isControlled) setLocalIndex(idx);
|
|
802
|
+
onIndexChange?.(idx);
|
|
803
|
+
};
|
|
804
|
+
const handleThumbClick = (idx) => {
|
|
805
|
+
if (!swiper || swiper.destroyed) return;
|
|
806
|
+
swiper.slideTo(idx);
|
|
807
|
+
};
|
|
770
808
|
if (images.length === 0) {
|
|
771
809
|
return /* @__PURE__ */ jsx("div", { ref, className, style });
|
|
772
810
|
}
|
|
@@ -792,36 +830,29 @@ var ImageMagnifyGallery = forwardRef((props, ref) => {
|
|
|
792
830
|
modules,
|
|
793
831
|
onSwiper: setSwiper,
|
|
794
832
|
initialSlide: isControlled ? controlledActiveIndex : defaultIndex,
|
|
795
|
-
onSlideChange:
|
|
796
|
-
if (!isControlled) setLocalIndex(s.activeIndex);
|
|
797
|
-
onIndexChange?.(s.activeIndex);
|
|
798
|
-
},
|
|
833
|
+
onSlideChange: handleSlideChange,
|
|
799
834
|
onBeforeInit: (s) => {
|
|
800
835
|
if (!showArrows || !hasMultiple) return;
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
836
|
+
const nav = s.params.navigation;
|
|
837
|
+
if (nav && typeof nav === "object") {
|
|
838
|
+
nav.prevEl = prevRef.current;
|
|
839
|
+
nav.nextEl = nextRef.current;
|
|
804
840
|
}
|
|
805
841
|
},
|
|
806
842
|
navigation: showArrows && hasMultiple ? {} : false,
|
|
807
|
-
keyboard: enableKeyboard ? { enabled: true } :
|
|
808
|
-
thumbs: {
|
|
809
|
-
swiper: thumbsSwiper && !thumbsSwiper.destroyed ? thumbsSwiper : null
|
|
810
|
-
},
|
|
843
|
+
keyboard: enableKeyboard ? { enabled: true } : false,
|
|
811
844
|
loop: loop && hasMultiple,
|
|
812
845
|
autoHeight: true,
|
|
813
846
|
spaceBetween: 10,
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
...arrowStyle
|
|
818
|
-
},
|
|
847
|
+
observer: true,
|
|
848
|
+
observeParents: true,
|
|
849
|
+
style: { width: "100%", ...swiperStyle },
|
|
819
850
|
children: images.map((src, idx) => /* @__PURE__ */ jsx(SwiperSlide, { children: /* @__PURE__ */ jsx(
|
|
820
851
|
ImageMagnify,
|
|
821
852
|
{
|
|
822
853
|
...magnifyProps,
|
|
823
854
|
src,
|
|
824
|
-
alt
|
|
855
|
+
alt: `${alt} \u2014 image ${idx + 1} of ${images.length}`,
|
|
825
856
|
width: "100%"
|
|
826
857
|
}
|
|
827
858
|
) }, idx))
|
|
@@ -834,7 +865,7 @@ var ImageMagnifyGallery = forwardRef((props, ref) => {
|
|
|
834
865
|
ref: prevRef,
|
|
835
866
|
type: "button",
|
|
836
867
|
className: arrowClassName,
|
|
837
|
-
style: { ...defaultArrowBaseStyle, left: 12 },
|
|
868
|
+
style: { ...defaultArrowBaseStyle, left: 12, ...arrowStyle },
|
|
838
869
|
"aria-label": "Previous image",
|
|
839
870
|
children: prevArrow ?? /* @__PURE__ */ jsx(ArrowLeftIcon, {})
|
|
840
871
|
}
|
|
@@ -845,7 +876,7 @@ var ImageMagnifyGallery = forwardRef((props, ref) => {
|
|
|
845
876
|
ref: nextRef,
|
|
846
877
|
type: "button",
|
|
847
878
|
className: arrowClassName,
|
|
848
|
-
style: { ...defaultArrowBaseStyle, right: 12 },
|
|
879
|
+
style: { ...defaultArrowBaseStyle, right: 12, ...arrowStyle },
|
|
849
880
|
"aria-label": "Next image",
|
|
850
881
|
children: nextArrow ?? /* @__PURE__ */ jsx(ArrowRightIcon, {})
|
|
851
882
|
}
|
|
@@ -885,41 +916,62 @@ var ImageMagnifyGallery = forwardRef((props, ref) => {
|
|
|
885
916
|
}
|
|
886
917
|
),
|
|
887
918
|
showThumbnails && hasMultiple && /* @__PURE__ */ jsx(
|
|
888
|
-
|
|
919
|
+
"div",
|
|
889
920
|
{
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
nav.nextEl = nextRef.current;
|
|
903
|
-
}
|
|
904
|
-
},
|
|
905
|
-
navigation: showArrows && hasMultiple ? {} : false,
|
|
906
|
-
keyboard: enableKeyboard ? { enabled: true } : void 0,
|
|
907
|
-
thumbs: {
|
|
908
|
-
swiper: thumbsSwiper && !thumbsSwiper.destroyed ? thumbsSwiper : null
|
|
921
|
+
className: thumbnailContainerClassName,
|
|
922
|
+
role: "group",
|
|
923
|
+
"aria-label": "Image thumbnails",
|
|
924
|
+
style: {
|
|
925
|
+
display: "flex",
|
|
926
|
+
gap: thumbnailGap,
|
|
927
|
+
marginTop: 12,
|
|
928
|
+
overflowX: "auto",
|
|
929
|
+
overflowY: "hidden",
|
|
930
|
+
paddingBottom: 4,
|
|
931
|
+
scrollbarWidth: "thin",
|
|
932
|
+
...thumbnailContainerStyle
|
|
909
933
|
},
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
934
|
+
children: images.map((src, idx) => {
|
|
935
|
+
const isActive = idx === activeIndex;
|
|
936
|
+
const mergedClassName = [
|
|
937
|
+
thumbnailClassName,
|
|
938
|
+
isActive ? thumbnailActiveClassName : void 0
|
|
939
|
+
].filter(Boolean).join(" ") || void 0;
|
|
940
|
+
return /* @__PURE__ */ jsx(
|
|
941
|
+
"button",
|
|
942
|
+
{
|
|
943
|
+
type: "button",
|
|
944
|
+
onClick: () => handleThumbClick(idx),
|
|
945
|
+
className: mergedClassName,
|
|
946
|
+
style: {
|
|
947
|
+
...defaultThumbBaseStyle,
|
|
948
|
+
width: thumbnailSize,
|
|
949
|
+
height: thumbnailSize,
|
|
950
|
+
...thumbnailStyle,
|
|
951
|
+
...isActive ? { ...defaultThumbActiveStyle, ...thumbnailActiveStyle } : void 0
|
|
952
|
+
},
|
|
953
|
+
"aria-label": `View image ${idx + 1}`,
|
|
954
|
+
"aria-current": isActive ? "true" : void 0,
|
|
955
|
+
children: /* @__PURE__ */ jsx(
|
|
956
|
+
"img",
|
|
957
|
+
{
|
|
958
|
+
src,
|
|
959
|
+
alt: "",
|
|
960
|
+
loading: "lazy",
|
|
961
|
+
draggable: false,
|
|
962
|
+
style: {
|
|
963
|
+
width: "100%",
|
|
964
|
+
height: "100%",
|
|
965
|
+
objectFit: "cover",
|
|
966
|
+
display: "block",
|
|
967
|
+
pointerEvents: "none"
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
)
|
|
971
|
+
},
|
|
972
|
+
idx
|
|
973
|
+
);
|
|
974
|
+
})
|
|
923
975
|
}
|
|
924
976
|
)
|
|
925
977
|
]
|
|
@@ -934,7 +986,10 @@ function useImageSlider({
|
|
|
934
986
|
onIndexChange,
|
|
935
987
|
loop = true
|
|
936
988
|
}) {
|
|
937
|
-
const [internalIndex, setInternalIndex] = useState(
|
|
989
|
+
const [internalIndex, setInternalIndex] = useState(() => {
|
|
990
|
+
const safeLength2 = Math.max(1, length);
|
|
991
|
+
return Math.max(0, Math.min(safeLength2 - 1, defaultIndex));
|
|
992
|
+
});
|
|
938
993
|
const safeLength = Math.max(1, length);
|
|
939
994
|
const rawIndex = controlledIndex ?? internalIndex;
|
|
940
995
|
const index = Math.max(0, Math.min(safeLength - 1, rawIndex));
|