uix-image-magnify 0.1.4 → 0.2.0
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/dist/ImageMagnify-zNjM2jVN.d.cts +90 -0
- package/dist/ImageMagnify-zNjM2jVN.d.ts +90 -0
- package/dist/index.cjs +361 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +88 -83
- package/dist/index.d.ts +88 -83
- package/dist/index.js +361 -2
- package/dist/index.js.map +1 -1
- package/dist/ssr/index.d.cts +2 -2
- package/dist/ssr/index.d.ts +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { CSSProperties, ImgHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
type ZoomType = "hover" | "click" | "double-click" | "hold" | "wheel" | "none";
|
|
5
|
+
type PanePosition = "left" | "right" | "top" | "bottom";
|
|
6
|
+
type LensShape = "circle" | "square";
|
|
7
|
+
type MagnifyMode = "lens" | "side-by-side" | "inner" | "follow";
|
|
8
|
+
type DragMode = "follow" | "pan";
|
|
9
|
+
interface UseImageMagnifyOptions {
|
|
10
|
+
/** Base image URL (required when used standalone). */
|
|
11
|
+
src?: string;
|
|
12
|
+
/** High-resolution image used for the zoomed view. Defaults to `src`. */
|
|
13
|
+
zoomSrc?: string;
|
|
14
|
+
/** Magnification factor (2 = 200%). */
|
|
15
|
+
zoomScale?: number;
|
|
16
|
+
/** Minimum scale for wheel/keyboard zoom. Default `1.5`. */
|
|
17
|
+
minZoomScale?: number;
|
|
18
|
+
/** Maximum scale for wheel/keyboard zoom. Default `5`. */
|
|
19
|
+
maxZoomScale?: number;
|
|
20
|
+
/** Interaction that activates zoom. */
|
|
21
|
+
zoomType?: ZoomType;
|
|
22
|
+
/** How the zoomed content is displayed. */
|
|
23
|
+
mode?: MagnifyMode;
|
|
24
|
+
/** Drag interaction for `inner` mode. */
|
|
25
|
+
dragMode?: DragMode;
|
|
26
|
+
/** Where the side-by-side pane sits relative to the image. */
|
|
27
|
+
panePosition?: PanePosition;
|
|
28
|
+
/** Diameter / side length of the lens in px. */
|
|
29
|
+
lensSize?: number;
|
|
30
|
+
/** Lens shape. */
|
|
31
|
+
lensShape?: LensShape;
|
|
32
|
+
/** Offset (both axes, px) for `mode="follow"`. */
|
|
33
|
+
followOffset?: number;
|
|
34
|
+
/** Disable all interaction. */
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
/** Preload the high-res image to avoid a flash. */
|
|
37
|
+
zoomPreload?: boolean;
|
|
38
|
+
/** Reset zoom when the pointer leaves the container. */
|
|
39
|
+
resetOnLeave?: boolean;
|
|
40
|
+
onZoomStart?: () => void;
|
|
41
|
+
onZoomEnd?: () => void;
|
|
42
|
+
onZoomChange?: (scale: number) => void;
|
|
43
|
+
}
|
|
44
|
+
declare function useImageMagnify(options?: UseImageMagnifyOptions): {
|
|
45
|
+
isZoomed: boolean;
|
|
46
|
+
zoomScale: number;
|
|
47
|
+
bgImage: string | undefined;
|
|
48
|
+
containerRef: React.RefObject<HTMLDivElement>;
|
|
49
|
+
imageRef: React.RefObject<HTMLImageElement>;
|
|
50
|
+
lensRef: React.RefObject<HTMLDivElement>;
|
|
51
|
+
paneRef: React.RefObject<HTMLDivElement>;
|
|
52
|
+
cursorRef: React.RefObject<HTMLDivElement>;
|
|
53
|
+
handlers: {
|
|
54
|
+
onPointerEnter: (e: React.PointerEvent) => void;
|
|
55
|
+
onPointerLeave: (e: React.PointerEvent) => void;
|
|
56
|
+
onPointerDown: (e: React.PointerEvent) => void;
|
|
57
|
+
onPointerMove: (e: React.PointerEvent) => void;
|
|
58
|
+
onPointerUp: (e: React.PointerEvent) => void;
|
|
59
|
+
onPointerCancel: () => void;
|
|
60
|
+
onDoubleClick: (e: React.MouseEvent) => void;
|
|
61
|
+
onKeyDown: (e: React.KeyboardEvent) => void;
|
|
62
|
+
onFocus: () => void;
|
|
63
|
+
onBlur: () => void;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
interface ImageMagnifyProps extends UseImageMagnifyOptions {
|
|
68
|
+
src: string;
|
|
69
|
+
alt: string;
|
|
70
|
+
/** Rendered width of the image (height follows aspect ratio). */
|
|
71
|
+
width?: number | string;
|
|
72
|
+
className?: string;
|
|
73
|
+
style?: CSSProperties;
|
|
74
|
+
imageClassName?: string;
|
|
75
|
+
imageStyle?: CSSProperties;
|
|
76
|
+
lensClassName?: string;
|
|
77
|
+
lensStyle?: CSSProperties;
|
|
78
|
+
paneClassName?: string;
|
|
79
|
+
paneStyle?: CSSProperties;
|
|
80
|
+
paneWidth?: number;
|
|
81
|
+
paneHeight?: number;
|
|
82
|
+
lazy?: boolean;
|
|
83
|
+
/** Extra attributes forwarded to the underlying <img>. */
|
|
84
|
+
imageProps?: Omit<ImgHTMLAttributes<HTMLImageElement>, "src" | "alt" | "style">;
|
|
85
|
+
onLoad?: ImgHTMLAttributes<HTMLImageElement>["onLoad"];
|
|
86
|
+
onError?: ImgHTMLAttributes<HTMLImageElement>["onError"];
|
|
87
|
+
}
|
|
88
|
+
declare const ImageMagnify: React.ForwardRefExoticComponent<ImageMagnifyProps & React.RefAttributes<HTMLDivElement>>;
|
|
89
|
+
|
|
90
|
+
export { type DragMode as D, type ImageMagnifyProps as I, type LensShape as L, type MagnifyMode as M, type PanePosition as P, type UseImageMagnifyOptions as U, type ZoomType as Z, ImageMagnify as a, useImageMagnify as u };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { CSSProperties, ImgHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
type ZoomType = "hover" | "click" | "double-click" | "hold" | "wheel" | "none";
|
|
5
|
+
type PanePosition = "left" | "right" | "top" | "bottom";
|
|
6
|
+
type LensShape = "circle" | "square";
|
|
7
|
+
type MagnifyMode = "lens" | "side-by-side" | "inner" | "follow";
|
|
8
|
+
type DragMode = "follow" | "pan";
|
|
9
|
+
interface UseImageMagnifyOptions {
|
|
10
|
+
/** Base image URL (required when used standalone). */
|
|
11
|
+
src?: string;
|
|
12
|
+
/** High-resolution image used for the zoomed view. Defaults to `src`. */
|
|
13
|
+
zoomSrc?: string;
|
|
14
|
+
/** Magnification factor (2 = 200%). */
|
|
15
|
+
zoomScale?: number;
|
|
16
|
+
/** Minimum scale for wheel/keyboard zoom. Default `1.5`. */
|
|
17
|
+
minZoomScale?: number;
|
|
18
|
+
/** Maximum scale for wheel/keyboard zoom. Default `5`. */
|
|
19
|
+
maxZoomScale?: number;
|
|
20
|
+
/** Interaction that activates zoom. */
|
|
21
|
+
zoomType?: ZoomType;
|
|
22
|
+
/** How the zoomed content is displayed. */
|
|
23
|
+
mode?: MagnifyMode;
|
|
24
|
+
/** Drag interaction for `inner` mode. */
|
|
25
|
+
dragMode?: DragMode;
|
|
26
|
+
/** Where the side-by-side pane sits relative to the image. */
|
|
27
|
+
panePosition?: PanePosition;
|
|
28
|
+
/** Diameter / side length of the lens in px. */
|
|
29
|
+
lensSize?: number;
|
|
30
|
+
/** Lens shape. */
|
|
31
|
+
lensShape?: LensShape;
|
|
32
|
+
/** Offset (both axes, px) for `mode="follow"`. */
|
|
33
|
+
followOffset?: number;
|
|
34
|
+
/** Disable all interaction. */
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
/** Preload the high-res image to avoid a flash. */
|
|
37
|
+
zoomPreload?: boolean;
|
|
38
|
+
/** Reset zoom when the pointer leaves the container. */
|
|
39
|
+
resetOnLeave?: boolean;
|
|
40
|
+
onZoomStart?: () => void;
|
|
41
|
+
onZoomEnd?: () => void;
|
|
42
|
+
onZoomChange?: (scale: number) => void;
|
|
43
|
+
}
|
|
44
|
+
declare function useImageMagnify(options?: UseImageMagnifyOptions): {
|
|
45
|
+
isZoomed: boolean;
|
|
46
|
+
zoomScale: number;
|
|
47
|
+
bgImage: string | undefined;
|
|
48
|
+
containerRef: React.RefObject<HTMLDivElement>;
|
|
49
|
+
imageRef: React.RefObject<HTMLImageElement>;
|
|
50
|
+
lensRef: React.RefObject<HTMLDivElement>;
|
|
51
|
+
paneRef: React.RefObject<HTMLDivElement>;
|
|
52
|
+
cursorRef: React.RefObject<HTMLDivElement>;
|
|
53
|
+
handlers: {
|
|
54
|
+
onPointerEnter: (e: React.PointerEvent) => void;
|
|
55
|
+
onPointerLeave: (e: React.PointerEvent) => void;
|
|
56
|
+
onPointerDown: (e: React.PointerEvent) => void;
|
|
57
|
+
onPointerMove: (e: React.PointerEvent) => void;
|
|
58
|
+
onPointerUp: (e: React.PointerEvent) => void;
|
|
59
|
+
onPointerCancel: () => void;
|
|
60
|
+
onDoubleClick: (e: React.MouseEvent) => void;
|
|
61
|
+
onKeyDown: (e: React.KeyboardEvent) => void;
|
|
62
|
+
onFocus: () => void;
|
|
63
|
+
onBlur: () => void;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
interface ImageMagnifyProps extends UseImageMagnifyOptions {
|
|
68
|
+
src: string;
|
|
69
|
+
alt: string;
|
|
70
|
+
/** Rendered width of the image (height follows aspect ratio). */
|
|
71
|
+
width?: number | string;
|
|
72
|
+
className?: string;
|
|
73
|
+
style?: CSSProperties;
|
|
74
|
+
imageClassName?: string;
|
|
75
|
+
imageStyle?: CSSProperties;
|
|
76
|
+
lensClassName?: string;
|
|
77
|
+
lensStyle?: CSSProperties;
|
|
78
|
+
paneClassName?: string;
|
|
79
|
+
paneStyle?: CSSProperties;
|
|
80
|
+
paneWidth?: number;
|
|
81
|
+
paneHeight?: number;
|
|
82
|
+
lazy?: boolean;
|
|
83
|
+
/** Extra attributes forwarded to the underlying <img>. */
|
|
84
|
+
imageProps?: Omit<ImgHTMLAttributes<HTMLImageElement>, "src" | "alt" | "style">;
|
|
85
|
+
onLoad?: ImgHTMLAttributes<HTMLImageElement>["onLoad"];
|
|
86
|
+
onError?: ImgHTMLAttributes<HTMLImageElement>["onError"];
|
|
87
|
+
}
|
|
88
|
+
declare const ImageMagnify: React.ForwardRefExoticComponent<ImageMagnifyProps & React.RefAttributes<HTMLDivElement>>;
|
|
89
|
+
|
|
90
|
+
export { type DragMode as D, type ImageMagnifyProps as I, type LensShape as L, type MagnifyMode as M, type PanePosition as P, type UseImageMagnifyOptions as U, type ZoomType as Z, ImageMagnify as a, useImageMagnify as u };
|
package/dist/index.cjs
CHANGED
|
@@ -610,8 +610,369 @@ var ImageMagnify = react.forwardRef(
|
|
|
610
610
|
}
|
|
611
611
|
);
|
|
612
612
|
ImageMagnify.displayName = "ImageMagnify";
|
|
613
|
+
function useImageSlider({
|
|
614
|
+
length,
|
|
615
|
+
defaultIndex = 0,
|
|
616
|
+
index: controlledIndex,
|
|
617
|
+
onIndexChange,
|
|
618
|
+
loop = true
|
|
619
|
+
}) {
|
|
620
|
+
const [internalIndex, setInternalIndex] = react.useState(defaultIndex);
|
|
621
|
+
const safeLength = Math.max(1, length);
|
|
622
|
+
const rawIndex = controlledIndex ?? internalIndex;
|
|
623
|
+
const index = Math.max(0, Math.min(safeLength - 1, rawIndex));
|
|
624
|
+
const setIndex = react.useCallback(
|
|
625
|
+
(next2) => {
|
|
626
|
+
if (length <= 0) return;
|
|
627
|
+
let resolved;
|
|
628
|
+
if (loop) {
|
|
629
|
+
resolved = (next2 % safeLength + safeLength) % safeLength;
|
|
630
|
+
} else {
|
|
631
|
+
resolved = Math.max(0, Math.min(safeLength - 1, next2));
|
|
632
|
+
}
|
|
633
|
+
if (resolved === index) return;
|
|
634
|
+
if (controlledIndex === void 0) {
|
|
635
|
+
setInternalIndex(resolved);
|
|
636
|
+
}
|
|
637
|
+
onIndexChange?.(resolved);
|
|
638
|
+
},
|
|
639
|
+
[length, safeLength, loop, index, controlledIndex, onIndexChange]
|
|
640
|
+
);
|
|
641
|
+
const prev = react.useCallback(() => setIndex(index - 1), [setIndex, index]);
|
|
642
|
+
const next = react.useCallback(() => setIndex(index + 1), [setIndex, index]);
|
|
643
|
+
return {
|
|
644
|
+
index,
|
|
645
|
+
canPrev: loop || index > 0,
|
|
646
|
+
canNext: loop || index < safeLength - 1,
|
|
647
|
+
setIndex,
|
|
648
|
+
prev,
|
|
649
|
+
next
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
var ArrowLeftIcon = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
653
|
+
"svg",
|
|
654
|
+
{
|
|
655
|
+
viewBox: "0 0 24 24",
|
|
656
|
+
width: "20",
|
|
657
|
+
height: "20",
|
|
658
|
+
fill: "none",
|
|
659
|
+
stroke: "currentColor",
|
|
660
|
+
strokeWidth: "2",
|
|
661
|
+
strokeLinecap: "round",
|
|
662
|
+
strokeLinejoin: "round",
|
|
663
|
+
"aria-hidden": "true",
|
|
664
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "15 18 9 12 15 6" })
|
|
665
|
+
}
|
|
666
|
+
);
|
|
667
|
+
var ArrowRightIcon = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
668
|
+
"svg",
|
|
669
|
+
{
|
|
670
|
+
viewBox: "0 0 24 24",
|
|
671
|
+
width: "20",
|
|
672
|
+
height: "20",
|
|
673
|
+
fill: "none",
|
|
674
|
+
stroke: "currentColor",
|
|
675
|
+
strokeWidth: "2",
|
|
676
|
+
strokeLinecap: "round",
|
|
677
|
+
strokeLinejoin: "round",
|
|
678
|
+
"aria-hidden": "true",
|
|
679
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 18 15 12 9 6" })
|
|
680
|
+
}
|
|
681
|
+
);
|
|
682
|
+
var defaultArrowBaseStyle = {
|
|
683
|
+
position: "absolute",
|
|
684
|
+
top: "50%",
|
|
685
|
+
transform: "translateY(-50%)",
|
|
686
|
+
width: 40,
|
|
687
|
+
height: 40,
|
|
688
|
+
display: "inline-flex",
|
|
689
|
+
alignItems: "center",
|
|
690
|
+
justifyContent: "center",
|
|
691
|
+
background: "rgba(255,255,255,0.85)",
|
|
692
|
+
border: "1px solid rgba(0,0,0,0.12)",
|
|
693
|
+
borderRadius: 9999,
|
|
694
|
+
boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
|
|
695
|
+
cursor: "pointer",
|
|
696
|
+
zIndex: 10,
|
|
697
|
+
color: "#111",
|
|
698
|
+
padding: 0,
|
|
699
|
+
transition: "background 0.15s ease",
|
|
700
|
+
backdropFilter: "blur(4px)",
|
|
701
|
+
WebkitBackdropFilter: "blur(4px)"
|
|
702
|
+
};
|
|
703
|
+
var defaultThumbStripStyle = {
|
|
704
|
+
display: "flex",
|
|
705
|
+
overflowX: "auto",
|
|
706
|
+
overflowY: "hidden",
|
|
707
|
+
paddingBottom: 4,
|
|
708
|
+
scrollbarWidth: "thin",
|
|
709
|
+
WebkitOverflowScrolling: "touch"
|
|
710
|
+
};
|
|
711
|
+
var defaultThumbBaseStyle = {
|
|
712
|
+
flexShrink: 0,
|
|
713
|
+
padding: 0,
|
|
714
|
+
border: "2px solid #e5e5e5",
|
|
715
|
+
background: "#fff",
|
|
716
|
+
cursor: "pointer",
|
|
717
|
+
overflow: "hidden",
|
|
718
|
+
transition: "border-color 0.15s ease",
|
|
719
|
+
borderRadius: 2,
|
|
720
|
+
display: "inline-flex",
|
|
721
|
+
alignItems: "center",
|
|
722
|
+
justifyContent: "center"
|
|
723
|
+
};
|
|
724
|
+
var defaultThumbActiveStyle = {
|
|
725
|
+
borderColor: "#111"
|
|
726
|
+
};
|
|
727
|
+
var visuallyHidden = {
|
|
728
|
+
position: "absolute",
|
|
729
|
+
width: 1,
|
|
730
|
+
height: 1,
|
|
731
|
+
padding: 0,
|
|
732
|
+
margin: -1,
|
|
733
|
+
overflow: "hidden",
|
|
734
|
+
clip: "rect(0,0,0,0)",
|
|
735
|
+
whiteSpace: "nowrap",
|
|
736
|
+
border: 0
|
|
737
|
+
};
|
|
738
|
+
var ImageMagnifyGallery = react.forwardRef((props, ref) => {
|
|
739
|
+
const {
|
|
740
|
+
images,
|
|
741
|
+
alt,
|
|
742
|
+
activeIndex: controlledActiveIndex,
|
|
743
|
+
defaultIndex = 0,
|
|
744
|
+
onIndexChange,
|
|
745
|
+
showArrows = true,
|
|
746
|
+
showThumbnails = true,
|
|
747
|
+
showCounter = false,
|
|
748
|
+
loop = true,
|
|
749
|
+
enableKeyboard = true,
|
|
750
|
+
preloadAdjacent = true,
|
|
751
|
+
className,
|
|
752
|
+
style,
|
|
753
|
+
viewportClassName,
|
|
754
|
+
viewportStyle,
|
|
755
|
+
thumbnailContainerClassName,
|
|
756
|
+
thumbnailContainerStyle,
|
|
757
|
+
thumbnailClassName,
|
|
758
|
+
thumbnailActiveClassName,
|
|
759
|
+
thumbnailStyle,
|
|
760
|
+
thumbnailActiveStyle,
|
|
761
|
+
arrowClassName,
|
|
762
|
+
arrowStyle,
|
|
763
|
+
thumbnailSize = 80,
|
|
764
|
+
thumbnailGap = 8,
|
|
765
|
+
prevArrow,
|
|
766
|
+
nextArrow,
|
|
767
|
+
...magnifyProps
|
|
768
|
+
} = props;
|
|
769
|
+
const { index, canPrev, canNext, setIndex, prev, next } = useImageSlider({
|
|
770
|
+
length: images.length,
|
|
771
|
+
defaultIndex,
|
|
772
|
+
index: controlledActiveIndex,
|
|
773
|
+
onIndexChange,
|
|
774
|
+
loop
|
|
775
|
+
});
|
|
776
|
+
const currentSrc = images[index] ?? "";
|
|
777
|
+
const thumbStripRef = react.useRef(null);
|
|
778
|
+
const [hoveredThumb, setHoveredThumb] = react.useState(null);
|
|
779
|
+
react.useEffect(() => {
|
|
780
|
+
if (!preloadAdjacent || typeof window === "undefined") return;
|
|
781
|
+
if (images.length <= 1) return;
|
|
782
|
+
const targets = /* @__PURE__ */ new Set();
|
|
783
|
+
targets.add((index + 1) % images.length);
|
|
784
|
+
targets.add((index - 1 + images.length) % images.length);
|
|
785
|
+
targets.forEach((i) => {
|
|
786
|
+
if (images[i]) {
|
|
787
|
+
const img = new Image();
|
|
788
|
+
img.src = images[i];
|
|
789
|
+
}
|
|
790
|
+
});
|
|
791
|
+
}, [index, images, preloadAdjacent]);
|
|
792
|
+
react.useEffect(() => {
|
|
793
|
+
const strip = thumbStripRef.current;
|
|
794
|
+
if (!strip) return;
|
|
795
|
+
const active = strip.children[index];
|
|
796
|
+
if (!active) return;
|
|
797
|
+
const sr = strip.getBoundingClientRect();
|
|
798
|
+
const ar = active.getBoundingClientRect();
|
|
799
|
+
if (ar.left < sr.left) {
|
|
800
|
+
strip.scrollBy({ left: ar.left - sr.left, behavior: "smooth" });
|
|
801
|
+
} else if (ar.right > sr.right) {
|
|
802
|
+
strip.scrollBy({ left: ar.right - sr.right, behavior: "smooth" });
|
|
803
|
+
}
|
|
804
|
+
}, [index]);
|
|
805
|
+
const handleKeyDown = react.useCallback(
|
|
806
|
+
(e) => {
|
|
807
|
+
if (!enableKeyboard) return;
|
|
808
|
+
if (e.key === "ArrowLeft") {
|
|
809
|
+
if (!canPrev) return;
|
|
810
|
+
e.preventDefault();
|
|
811
|
+
prev();
|
|
812
|
+
} else if (e.key === "ArrowRight") {
|
|
813
|
+
if (!canNext) return;
|
|
814
|
+
e.preventDefault();
|
|
815
|
+
next();
|
|
816
|
+
}
|
|
817
|
+
},
|
|
818
|
+
[enableKeyboard, canPrev, canNext, prev, next]
|
|
819
|
+
);
|
|
820
|
+
const hasMultiple = images.length > 1;
|
|
821
|
+
const liveText = react.useMemo(
|
|
822
|
+
() => `Image ${index + 1} of ${images.length}`,
|
|
823
|
+
[index, images.length]
|
|
824
|
+
);
|
|
825
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
826
|
+
"div",
|
|
827
|
+
{
|
|
828
|
+
ref,
|
|
829
|
+
className,
|
|
830
|
+
style,
|
|
831
|
+
role: "region",
|
|
832
|
+
"aria-roledescription": "carousel",
|
|
833
|
+
"aria-label": `${alt} \u2014 image gallery`,
|
|
834
|
+
children: [
|
|
835
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
836
|
+
"div",
|
|
837
|
+
{
|
|
838
|
+
className: viewportClassName,
|
|
839
|
+
style: {
|
|
840
|
+
position: "relative",
|
|
841
|
+
width: "fit-content",
|
|
842
|
+
maxWidth: "100%",
|
|
843
|
+
...viewportStyle
|
|
844
|
+
},
|
|
845
|
+
tabIndex: enableKeyboard && hasMultiple ? 0 : void 0,
|
|
846
|
+
onKeyDown: handleKeyDown,
|
|
847
|
+
children: [
|
|
848
|
+
/* @__PURE__ */ jsxRuntime.jsx(ImageMagnify, { ...magnifyProps, src: currentSrc, alt }),
|
|
849
|
+
showArrows && hasMultiple && canPrev && /* @__PURE__ */ jsxRuntime.jsx(
|
|
850
|
+
"button",
|
|
851
|
+
{
|
|
852
|
+
type: "button",
|
|
853
|
+
onClick: prev,
|
|
854
|
+
className: arrowClassName,
|
|
855
|
+
style: {
|
|
856
|
+
...defaultArrowBaseStyle,
|
|
857
|
+
left: 12,
|
|
858
|
+
...arrowStyle
|
|
859
|
+
},
|
|
860
|
+
"aria-label": "Previous image",
|
|
861
|
+
children: prevArrow ?? /* @__PURE__ */ jsxRuntime.jsx(ArrowLeftIcon, {})
|
|
862
|
+
}
|
|
863
|
+
),
|
|
864
|
+
showArrows && hasMultiple && canNext && /* @__PURE__ */ jsxRuntime.jsx(
|
|
865
|
+
"button",
|
|
866
|
+
{
|
|
867
|
+
type: "button",
|
|
868
|
+
onClick: next,
|
|
869
|
+
className: arrowClassName,
|
|
870
|
+
style: {
|
|
871
|
+
...defaultArrowBaseStyle,
|
|
872
|
+
right: 12,
|
|
873
|
+
...arrowStyle
|
|
874
|
+
},
|
|
875
|
+
"aria-label": "Next image",
|
|
876
|
+
children: nextArrow ?? /* @__PURE__ */ jsxRuntime.jsx(ArrowRightIcon, {})
|
|
877
|
+
}
|
|
878
|
+
),
|
|
879
|
+
showCounter && hasMultiple && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
880
|
+
"div",
|
|
881
|
+
{
|
|
882
|
+
"aria-hidden": "true",
|
|
883
|
+
style: {
|
|
884
|
+
position: "absolute",
|
|
885
|
+
bottom: 12,
|
|
886
|
+
right: 12,
|
|
887
|
+
background: "rgba(0,0,0,0.6)",
|
|
888
|
+
color: "#fff",
|
|
889
|
+
fontSize: 12,
|
|
890
|
+
fontWeight: 600,
|
|
891
|
+
padding: "4px 8px",
|
|
892
|
+
borderRadius: 4,
|
|
893
|
+
zIndex: 10,
|
|
894
|
+
pointerEvents: "none"
|
|
895
|
+
},
|
|
896
|
+
children: [
|
|
897
|
+
index + 1,
|
|
898
|
+
" / ",
|
|
899
|
+
images.length
|
|
900
|
+
]
|
|
901
|
+
}
|
|
902
|
+
),
|
|
903
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { "aria-live": "polite", "aria-atomic": "true", style: visuallyHidden, children: liveText })
|
|
904
|
+
]
|
|
905
|
+
}
|
|
906
|
+
),
|
|
907
|
+
showThumbnails && hasMultiple && /* @__PURE__ */ jsxRuntime.jsx(
|
|
908
|
+
"div",
|
|
909
|
+
{
|
|
910
|
+
ref: thumbStripRef,
|
|
911
|
+
className: thumbnailContainerClassName,
|
|
912
|
+
role: "tablist",
|
|
913
|
+
"aria-label": "Choose image",
|
|
914
|
+
style: {
|
|
915
|
+
...defaultThumbStripStyle,
|
|
916
|
+
gap: thumbnailGap,
|
|
917
|
+
marginTop: 12,
|
|
918
|
+
...thumbnailContainerStyle
|
|
919
|
+
},
|
|
920
|
+
children: images.map((img, idx) => {
|
|
921
|
+
const isActive = idx === index;
|
|
922
|
+
const isHovered = idx === hoveredThumb;
|
|
923
|
+
const cls = isActive ? thumbnailActiveClassName : thumbnailClassName;
|
|
924
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
925
|
+
"button",
|
|
926
|
+
{
|
|
927
|
+
type: "button",
|
|
928
|
+
role: "tab",
|
|
929
|
+
onClick: () => setIndex(idx),
|
|
930
|
+
onMouseEnter: () => setHoveredThumb(idx),
|
|
931
|
+
onMouseLeave: () => setHoveredThumb(null),
|
|
932
|
+
className: cls,
|
|
933
|
+
style: {
|
|
934
|
+
...defaultThumbBaseStyle,
|
|
935
|
+
width: thumbnailSize,
|
|
936
|
+
height: thumbnailSize,
|
|
937
|
+
...thumbnailStyle,
|
|
938
|
+
...isActive ? defaultThumbActiveStyle : void 0,
|
|
939
|
+
...isActive ? thumbnailActiveStyle : void 0,
|
|
940
|
+
...isHovered && !isActive ? { borderColor: "#999" } : void 0
|
|
941
|
+
},
|
|
942
|
+
"aria-label": `View image ${idx + 1} of ${images.length}`,
|
|
943
|
+
"aria-selected": isActive,
|
|
944
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
945
|
+
"img",
|
|
946
|
+
{
|
|
947
|
+
src: img,
|
|
948
|
+
alt: "",
|
|
949
|
+
loading: "lazy",
|
|
950
|
+
draggable: false,
|
|
951
|
+
style: {
|
|
952
|
+
width: "100%",
|
|
953
|
+
height: "100%",
|
|
954
|
+
objectFit: "contain",
|
|
955
|
+
display: "block",
|
|
956
|
+
pointerEvents: "none",
|
|
957
|
+
userSelect: "none"
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
)
|
|
961
|
+
},
|
|
962
|
+
idx
|
|
963
|
+
);
|
|
964
|
+
})
|
|
965
|
+
}
|
|
966
|
+
)
|
|
967
|
+
]
|
|
968
|
+
}
|
|
969
|
+
);
|
|
970
|
+
});
|
|
971
|
+
ImageMagnifyGallery.displayName = "ImageMagnifyGallery";
|
|
613
972
|
|
|
614
973
|
exports.ImageMagnify = ImageMagnify;
|
|
974
|
+
exports.ImageMagnifyGallery = ImageMagnifyGallery;
|
|
615
975
|
exports.useImageMagnify = useImageMagnify;
|
|
976
|
+
exports.useImageSlider = useImageSlider;
|
|
616
977
|
//# sourceMappingURL=index.cjs.map
|
|
617
978
|
//# sourceMappingURL=index.cjs.map
|