yet-another-react-lightbox 1.13.4 → 2.0.0-rc.3

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.
Files changed (121) hide show
  1. package/dist/Lightbox.js +1 -1
  2. package/dist/core/components/IconButton.d.ts +1 -1
  3. package/dist/core/components/IconButton.js +3 -2
  4. package/dist/core/components/ImageSlide.js +15 -24
  5. package/dist/core/consts.d.ts +36 -0
  6. package/dist/core/consts.js +36 -0
  7. package/dist/core/contexts/Events.d.ts +5 -9
  8. package/dist/core/contexts/Events.js +23 -25
  9. package/dist/core/contexts/LightboxState.d.ts +20 -0
  10. package/dist/core/contexts/LightboxState.js +23 -0
  11. package/dist/core/contexts/Timeouts.d.ts +1 -2
  12. package/dist/core/contexts/Timeouts.js +26 -29
  13. package/dist/core/contexts/index.d.ts +1 -0
  14. package/dist/core/contexts/index.js +1 -0
  15. package/dist/core/hooks/index.d.ts +2 -1
  16. package/dist/core/hooks/index.js +2 -1
  17. package/dist/core/hooks/useEventCallback.d.ts +1 -0
  18. package/dist/core/hooks/useEventCallback.js +9 -0
  19. package/dist/core/hooks/useForkRef.d.ts +3 -0
  20. package/dist/core/hooks/useForkRef.js +15 -0
  21. package/dist/core/hooks/useMotionPreference.js +1 -2
  22. package/dist/core/hooks/useSensors.d.ts +4 -5
  23. package/dist/core/hooks/useSensors.js +9 -12
  24. package/dist/core/modules/Carousel.js +29 -31
  25. package/dist/core/modules/Controller.d.ts +3 -7
  26. package/dist/core/modules/Controller.js +144 -263
  27. package/dist/core/modules/Core.js +6 -4
  28. package/dist/core/modules/Navigation.js +16 -13
  29. package/dist/core/modules/NoScroll.js +4 -3
  30. package/dist/core/modules/Portal.js +51 -40
  31. package/dist/core/modules/Toolbar.js +6 -4
  32. package/dist/core/modules/controller/index.d.ts +8 -0
  33. package/dist/core/modules/controller/index.js +9 -0
  34. package/dist/core/modules/controller/useOffset.d.ts +2 -0
  35. package/dist/core/modules/controller/useOffset.js +10 -0
  36. package/dist/core/modules/controller/usePointerSwipe.d.ts +3 -0
  37. package/dist/core/modules/controller/usePointerSwipe.js +61 -0
  38. package/dist/core/modules/controller/usePreventSwipeNavigation.d.ts +3 -0
  39. package/dist/core/modules/controller/usePreventSwipeNavigation.js +20 -0
  40. package/dist/core/modules/controller/useWheelSwipe.d.ts +3 -0
  41. package/dist/core/modules/controller/useWheelSwipe.js +94 -0
  42. package/dist/core/utils.d.ts +12 -1
  43. package/dist/core/utils.js +14 -0
  44. package/dist/plugins/captions/Captions.d.ts +7 -0
  45. package/dist/plugins/captions/Captions.js +23 -0
  46. package/dist/plugins/captions/CaptionsContext.d.ts +8 -0
  47. package/dist/plugins/captions/CaptionsContext.js +15 -0
  48. package/dist/plugins/captions/Description.d.ts +5 -0
  49. package/dist/plugins/captions/Description.js +17 -0
  50. package/dist/plugins/captions/Title.d.ts +5 -0
  51. package/dist/plugins/captions/Title.js +9 -0
  52. package/dist/plugins/{captions.css → captions/captions.css} +0 -2
  53. package/dist/plugins/{Captions.d.ts → captions/index.d.ts} +3 -9
  54. package/dist/plugins/captions/index.js +2 -0
  55. package/dist/plugins/captions/utils.d.ts +1 -0
  56. package/dist/plugins/captions/utils.js +2 -0
  57. package/dist/plugins/fullscreen/Fullscreen.d.ts +3 -0
  58. package/dist/plugins/fullscreen/Fullscreen.js +17 -0
  59. package/dist/plugins/fullscreen/FullscreenButton.d.ts +8 -0
  60. package/dist/plugins/{Fullscreen.js → fullscreen/FullscreenButton.js} +16 -30
  61. package/dist/plugins/fullscreen/FullscreenContext.d.ts +5 -0
  62. package/dist/plugins/fullscreen/FullscreenContext.js +9 -0
  63. package/dist/plugins/{Fullscreen.d.ts → fullscreen/index.d.ts} +2 -11
  64. package/dist/plugins/fullscreen/index.js +2 -0
  65. package/dist/plugins/index.d.ts +7 -7
  66. package/dist/plugins/index.js +7 -7
  67. package/dist/plugins/inline/Inline.d.ts +3 -0
  68. package/dist/plugins/{Inline.js → inline/Inline.js} +5 -7
  69. package/dist/plugins/inline/index.d.ts +9 -0
  70. package/dist/plugins/inline/index.js +2 -0
  71. package/dist/plugins/slideshow/Slideshow.d.ts +7 -0
  72. package/dist/plugins/slideshow/Slideshow.js +20 -0
  73. package/dist/plugins/slideshow/SlideshowButton.d.ts +2 -0
  74. package/dist/plugins/{Slideshow.js → slideshow/SlideshowButton.js} +17 -44
  75. package/dist/plugins/{Slideshow.d.ts → slideshow/index.d.ts} +2 -4
  76. package/dist/plugins/slideshow/index.js +2 -0
  77. package/dist/plugins/thumbnails/Thumbnail.d.ts +21 -0
  78. package/dist/plugins/thumbnails/Thumbnail.js +45 -0
  79. package/dist/plugins/thumbnails/Thumbnails.d.ts +13 -0
  80. package/dist/plugins/thumbnails/Thumbnails.js +28 -0
  81. package/dist/plugins/thumbnails/ThumbnailsContainer.d.ts +3 -0
  82. package/dist/plugins/thumbnails/ThumbnailsContainer.js +14 -0
  83. package/dist/plugins/thumbnails/ThumbnailsTrack.d.ts +12 -0
  84. package/dist/plugins/thumbnails/ThumbnailsTrack.js +148 -0
  85. package/dist/plugins/{Thumbnails.d.ts → thumbnails/index.d.ts} +4 -16
  86. package/dist/plugins/thumbnails/index.js +2 -0
  87. package/dist/plugins/{thumbnails.css → thumbnails/thumbnails.css} +27 -37
  88. package/dist/plugins/thumbnails/utils.d.ts +2 -0
  89. package/dist/plugins/thumbnails/utils.js +4 -0
  90. package/dist/plugins/video/Video.d.ts +7 -0
  91. package/dist/plugins/video/Video.js +24 -0
  92. package/dist/plugins/video/VideoSlide.d.ts +9 -0
  93. package/dist/plugins/{Video.js → video/VideoSlide.js} +14 -39
  94. package/dist/plugins/{Video.d.ts → video/index.d.ts} +5 -13
  95. package/dist/plugins/video/index.js +2 -0
  96. package/dist/plugins/zoom/Zoom.d.ts +14 -0
  97. package/dist/plugins/zoom/Zoom.js +36 -0
  98. package/dist/plugins/zoom/ZoomButton.d.ts +7 -0
  99. package/dist/plugins/zoom/ZoomButton.js +50 -0
  100. package/dist/plugins/zoom/ZoomButtonsGroup.d.ts +5 -0
  101. package/dist/plugins/zoom/ZoomButtonsGroup.js +23 -0
  102. package/dist/plugins/zoom/ZoomContainer.d.ts +9 -0
  103. package/dist/plugins/zoom/ZoomContainer.js +303 -0
  104. package/dist/plugins/zoom/ZoomContext.d.ts +12 -0
  105. package/dist/plugins/zoom/ZoomContext.js +18 -0
  106. package/dist/plugins/zoom/ZoomWrapper.d.ts +3 -0
  107. package/dist/plugins/zoom/ZoomWrapper.js +26 -0
  108. package/dist/plugins/{Zoom.d.ts → zoom/index.d.ts} +5 -5
  109. package/dist/plugins/zoom/index.js +4 -0
  110. package/dist/props.d.ts +2 -0
  111. package/dist/props.js +31 -0
  112. package/dist/styles.css +33 -27
  113. package/dist/types.d.ts +8 -22
  114. package/dist/types.js +1 -30
  115. package/package.json +17 -17
  116. package/dist/core/hooks/useLatest.d.ts +0 -3
  117. package/dist/core/hooks/useLatest.js +0 -6
  118. package/dist/plugins/Captions.js +0 -58
  119. package/dist/plugins/Inline.d.ts +0 -15
  120. package/dist/plugins/Thumbnails.js +0 -243
  121. package/dist/plugins/Zoom.js +0 -441
@@ -0,0 +1,303 @@
1
+ import * as React from "react";
2
+ import { CLASS_FLEX_CENTER, CLASS_FULLSIZE, cleanup, clsx, cssClass, EVENT_ON_KEY_DOWN, EVENT_ON_POINTER_CANCEL, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_WHEEL, ImageSlide, isImageSlide, round, useContainerRect, useController, useEventCallback, useEvents, useLayoutEffect, useMotionPreference, } from "../../core/index.js";
3
+ import { useZoom } from "./ZoomContext.js";
4
+ import { defaultZoomProps } from "./Zoom.js";
5
+ import { ACTION_ZOOM_IN, ACTION_ZOOM_OUT } from "./index.js";
6
+ const getSlideRects = (slide, cover, maxZoomPixelRatio, rect) => {
7
+ var _a, _b;
8
+ let slideRect = { width: 0, height: 0 };
9
+ let maxSlideRect = { width: 0, height: 0 };
10
+ if (rect && isImageSlide(slide)) {
11
+ const width = Math.max(...(((_a = slide.srcSet) === null || _a === void 0 ? void 0 : _a.map((x) => x.width)) || []).concat(slide.width ? [slide.width] : []));
12
+ const height = Math.max(...(((_b = slide.srcSet) === null || _b === void 0 ? void 0 : _b.map((x) => x.height)) || []).concat(slide.height ? [slide.height] : []));
13
+ if (width > 0 && height > 0 && rect.width > 0 && rect.height > 0) {
14
+ maxSlideRect = cover
15
+ ? {
16
+ width: Math.round(Math.min(width, (rect.width / rect.height) * height)),
17
+ height: Math.round(Math.min(height, (rect.height / rect.width) * width)),
18
+ }
19
+ : { width, height };
20
+ maxSlideRect = {
21
+ width: maxSlideRect.width * maxZoomPixelRatio,
22
+ height: maxSlideRect.height * maxZoomPixelRatio,
23
+ };
24
+ slideRect = cover
25
+ ? {
26
+ width: Math.min(rect.width, maxSlideRect.width),
27
+ height: Math.min(rect.height, maxSlideRect.height),
28
+ }
29
+ : {
30
+ width: Math.round(Math.min(rect.width, (rect.height / height) * width)),
31
+ height: Math.round(Math.min(rect.height, (rect.width / width) * height)),
32
+ };
33
+ }
34
+ }
35
+ return { slideRect, maxSlideRect };
36
+ };
37
+ const distance = (pointerA, pointerB) => ((pointerA.clientX - pointerB.clientX) ** 2 + (pointerA.clientY - pointerB.clientY) ** 2) ** 0.5;
38
+ export const ZoomContainer = ({ slide, offset, rect, render, carousel, animation, zoom: originalZoomProps }) => {
39
+ var _a;
40
+ const zoomProps = { ...defaultZoomProps, ...originalZoomProps };
41
+ const [zoom, setZoom] = React.useState(1);
42
+ const [offsetX, setOffsetX] = React.useState(0);
43
+ const [offsetY, setOffsetY] = React.useState(0);
44
+ const activePointers = React.useRef([]);
45
+ const lastPointerDown = React.useRef(0);
46
+ const zoomAnimation = React.useRef();
47
+ const zoomAnimationStart = React.useRef();
48
+ const pinchZoomDistance = React.useRef();
49
+ const { isMinZoom, isMaxZoom, setIsMinZoom, setIsMaxZoom } = useZoom();
50
+ const { setContainerRef, containerRef, containerRect } = useContainerRect();
51
+ const { subscribeSensors, containerRef: controllerRef, containerRect: controllerRect } = useController();
52
+ const { subscribe } = useEvents();
53
+ const reduceMotion = useMotionPreference();
54
+ const { slideRect, maxSlideRect: currentMaxSlideRect } = getSlideRects(slide, carousel.imageFit === "cover" || ("imageFit" in slide && slide.imageFit === "cover"), zoomProps.maxZoomPixelRatio, containerRect);
55
+ const maxZoom = slideRect.width ? Math.max(round(currentMaxSlideRect.width / slideRect.width, 5), 1) : 1;
56
+ const changeOffsets = useEventCallback((dx, dy, targetZoom) => {
57
+ const newZoom = targetZoom || zoom;
58
+ const newOffsetX = offsetX - (dx || 0);
59
+ const newOffsetY = offsetY - (dy || 0);
60
+ const maxOffsetX = containerRect ? (slideRect.width * newZoom - containerRect.width) / 2 / newZoom : 0;
61
+ const maxOffsetY = containerRect ? (slideRect.height * newZoom - containerRect.height) / 2 / newZoom : 0;
62
+ setOffsetX(Math.min(Math.abs(newOffsetX), Math.max(maxOffsetX, 0)) * Math.sign(newOffsetX));
63
+ setOffsetY(Math.min(Math.abs(newOffsetY), Math.max(maxOffsetY, 0)) * Math.sign(newOffsetY));
64
+ });
65
+ const changeZoom = useEventCallback((value, rapid, dx, dy) => {
66
+ if (!containerRef.current || !containerRect)
67
+ return;
68
+ const newZoom = round(Math.min(Math.max(value + 0.001 < maxZoom ? value : maxZoom, 1), maxZoom), 5);
69
+ if (newZoom === zoom)
70
+ return;
71
+ if (!rapid) {
72
+ zoomAnimationStart.current = window.getComputedStyle(containerRef.current).transform;
73
+ }
74
+ changeOffsets(dx ? dx * (1 / zoom - 1 / newZoom) : 0, dy ? dy * (1 / zoom - 1 / newZoom) : 0, newZoom);
75
+ setZoom(newZoom);
76
+ });
77
+ const handleControllerRectChange = useEventCallback(() => {
78
+ if (zoom > 1) {
79
+ if (zoom > maxZoom) {
80
+ changeZoom(maxZoom, true);
81
+ }
82
+ changeOffsets();
83
+ }
84
+ });
85
+ useLayoutEffect(handleControllerRectChange, [
86
+ controllerRect.width,
87
+ controllerRect.height,
88
+ handleControllerRectChange,
89
+ ]);
90
+ const handleZoomAndOffsetChange = useEventCallback(() => {
91
+ var _a, _b, _c, _d;
92
+ (_a = zoomAnimation.current) === null || _a === void 0 ? void 0 : _a.cancel();
93
+ if (zoomAnimationStart.current && containerRef.current) {
94
+ zoomAnimation.current = (_c = (_b = containerRef.current).animate) === null || _c === void 0 ? void 0 : _c.call(_b, [
95
+ { transform: zoomAnimationStart.current },
96
+ {
97
+ transform: `scale(${zoom}) translateX(${offsetX}px) translateY(${offsetY}px)`,
98
+ },
99
+ ], {
100
+ duration: reduceMotion ? 0 : (_d = animation.zoom) !== null && _d !== void 0 ? _d : 500,
101
+ easing: zoomAnimation ? "ease-out" : "ease-in-out",
102
+ });
103
+ zoomAnimationStart.current = undefined;
104
+ if (zoomAnimation.current) {
105
+ zoomAnimation.current.onfinish = () => {
106
+ zoomAnimation.current = undefined;
107
+ };
108
+ }
109
+ }
110
+ });
111
+ useLayoutEffect(handleZoomAndOffsetChange, [zoom, offsetX, offsetY, handleZoomAndOffsetChange]);
112
+ useLayoutEffect(() => {
113
+ if (offset === 0) {
114
+ const resetZoom = () => {
115
+ setZoom(1);
116
+ setOffsetX(0);
117
+ setOffsetY(0);
118
+ setIsMinZoom(true);
119
+ setIsMaxZoom(false);
120
+ };
121
+ resetZoom();
122
+ return () => {
123
+ resetZoom();
124
+ };
125
+ }
126
+ return () => { };
127
+ }, [offset, setIsMinZoom, setIsMaxZoom]);
128
+ useLayoutEffect(() => {
129
+ if (offset === 0) {
130
+ const newMinZoom = zoom <= 1;
131
+ if (newMinZoom !== isMinZoom) {
132
+ setIsMinZoom(newMinZoom);
133
+ }
134
+ const newMaxZoom = zoom >= maxZoom;
135
+ if (newMaxZoom !== isMaxZoom) {
136
+ setIsMaxZoom(newMaxZoom);
137
+ }
138
+ }
139
+ }, [offset, zoom, maxZoom, isMinZoom, isMaxZoom, setIsMinZoom, setIsMaxZoom]);
140
+ const translateCoordinates = React.useCallback((event) => {
141
+ if (controllerRef.current) {
142
+ const { pageX, pageY } = event;
143
+ const { scrollX, scrollY } = window;
144
+ const { left, top, width, height } = controllerRef.current.getBoundingClientRect();
145
+ return [pageX - left - scrollX - width / 2, pageY - top - scrollY - height / 2];
146
+ }
147
+ return [];
148
+ }, [controllerRef]);
149
+ const onKeyDown = useEventCallback((event) => {
150
+ const { keyboardMoveDistance, zoomInMultiplier } = zoomProps;
151
+ const preventDefault = () => {
152
+ event.preventDefault();
153
+ event.stopPropagation();
154
+ };
155
+ if (zoom > 1) {
156
+ const move = (deltaX, deltaY) => {
157
+ preventDefault();
158
+ changeOffsets(deltaX, deltaY);
159
+ };
160
+ if (event.key === "ArrowDown") {
161
+ move(0, keyboardMoveDistance);
162
+ }
163
+ else if (event.key === "ArrowUp") {
164
+ move(0, -keyboardMoveDistance);
165
+ }
166
+ else if (event.key === "ArrowLeft") {
167
+ move(-keyboardMoveDistance, 0);
168
+ }
169
+ else if (event.key === "ArrowRight") {
170
+ move(keyboardMoveDistance, 0);
171
+ }
172
+ }
173
+ const handleChangeZoom = (zoomValue) => {
174
+ preventDefault();
175
+ changeZoom(zoomValue);
176
+ };
177
+ const hasMeta = () => event.getModifierState("Meta") || event.getModifierState("OS");
178
+ if (event.key === "+" || (event.key === "=" && hasMeta())) {
179
+ handleChangeZoom(zoom * zoomInMultiplier);
180
+ }
181
+ else if (event.key === "-" || (event.key === "_" && hasMeta())) {
182
+ handleChangeZoom(zoom / zoomInMultiplier);
183
+ }
184
+ else if (event.key === "0" && hasMeta()) {
185
+ handleChangeZoom(1);
186
+ }
187
+ });
188
+ const onWheel = useEventCallback((event) => {
189
+ const { wheelZoomDistanceFactor, scrollToZoom } = zoomProps;
190
+ if (event.ctrlKey || scrollToZoom) {
191
+ if (Math.abs(event.deltaY) > Math.abs(event.deltaX)) {
192
+ event.stopPropagation();
193
+ changeZoom(zoom * (1 - event.deltaY / wheelZoomDistanceFactor), true, ...translateCoordinates(event));
194
+ return;
195
+ }
196
+ }
197
+ if (zoom > 1) {
198
+ event.stopPropagation();
199
+ if (!scrollToZoom) {
200
+ changeOffsets(event.deltaX, event.deltaY);
201
+ }
202
+ }
203
+ });
204
+ const clearPointer = React.useCallback((event) => {
205
+ const pointers = activePointers.current;
206
+ pointers.splice(0, pointers.length, ...pointers.filter((p) => p.pointerId !== event.pointerId));
207
+ }, []);
208
+ const replacePointer = React.useCallback((event) => {
209
+ clearPointer(event);
210
+ activePointers.current.push(event);
211
+ }, [clearPointer]);
212
+ const onPointerDown = useEventCallback((event) => {
213
+ var _a;
214
+ const { doubleTapDelay, doubleClickDelay, zoomInMultiplier, doubleClickMaxStops } = zoomProps;
215
+ const pointers = activePointers.current;
216
+ if (!((_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target))) {
217
+ return;
218
+ }
219
+ if (zoom > 1) {
220
+ event.stopPropagation();
221
+ }
222
+ const { timeStamp } = event;
223
+ if (pointers.length === 0 &&
224
+ timeStamp - lastPointerDown.current < (event.pointerType === "touch" ? doubleTapDelay : doubleClickDelay)) {
225
+ lastPointerDown.current = 0;
226
+ changeZoom(zoom !== maxZoom ? zoom * Math.max(maxZoom ** (1 / doubleClickMaxStops), zoomInMultiplier) : 1, false, ...translateCoordinates(event));
227
+ }
228
+ else {
229
+ lastPointerDown.current = timeStamp;
230
+ }
231
+ replacePointer(event);
232
+ if (pointers.length === 2) {
233
+ pinchZoomDistance.current = distance(pointers[0], pointers[1]);
234
+ }
235
+ });
236
+ const onPointerMove = useEventCallback((event) => {
237
+ const pointers = activePointers.current;
238
+ const activePointer = pointers.find((p) => p.pointerId === event.pointerId);
239
+ if (pointers.length === 2 && pinchZoomDistance.current) {
240
+ event.stopPropagation();
241
+ replacePointer(event);
242
+ const currentDistance = distance(pointers[0], pointers[1]);
243
+ const delta = currentDistance - pinchZoomDistance.current;
244
+ if (Math.abs(delta) > 0) {
245
+ changeZoom(zoom * (1 + delta / zoomProps.pinchZoomDistanceFactor), true, ...pointers
246
+ .map((x) => translateCoordinates(x))
247
+ .reduce((acc, coordinate) => coordinate.map((x, i) => acc[i] + x / 2)));
248
+ pinchZoomDistance.current = currentDistance;
249
+ }
250
+ return;
251
+ }
252
+ if (zoom > 1) {
253
+ event.stopPropagation();
254
+ if (activePointer) {
255
+ if (pointers.length === 1) {
256
+ changeOffsets((activePointer.clientX - event.clientX) / zoom, (activePointer.clientY - event.clientY) / zoom);
257
+ }
258
+ replacePointer(event);
259
+ }
260
+ }
261
+ });
262
+ const onPointerUp = React.useCallback((event) => {
263
+ const pointers = activePointers.current;
264
+ if (pointers.length === 2 && pointers.find((p) => p.pointerId === event.pointerId)) {
265
+ pinchZoomDistance.current = undefined;
266
+ }
267
+ clearPointer(event);
268
+ }, [clearPointer]);
269
+ const handleZoomIn = useEventCallback(() => {
270
+ changeZoom(zoom * zoomProps.zoomInMultiplier);
271
+ });
272
+ const handleZoomOut = useEventCallback(() => {
273
+ changeZoom(zoom / zoomProps.zoomInMultiplier);
274
+ });
275
+ React.useEffect(() => offset === 0
276
+ ? cleanup(subscribe(ACTION_ZOOM_IN, handleZoomIn), subscribe(ACTION_ZOOM_OUT, handleZoomOut), subscribeSensors(EVENT_ON_KEY_DOWN, onKeyDown), subscribeSensors(EVENT_ON_WHEEL, onWheel), subscribeSensors(EVENT_ON_POINTER_DOWN, onPointerDown), subscribeSensors(EVENT_ON_POINTER_MOVE, onPointerMove), subscribeSensors(EVENT_ON_POINTER_UP, onPointerUp), subscribeSensors(EVENT_ON_POINTER_LEAVE, onPointerUp), subscribeSensors(EVENT_ON_POINTER_CANCEL, onPointerUp))
277
+ : () => { }, [
278
+ offset,
279
+ subscribe,
280
+ subscribeSensors,
281
+ onKeyDown,
282
+ onPointerDown,
283
+ onPointerMove,
284
+ onPointerUp,
285
+ onWheel,
286
+ changeZoom,
287
+ handleZoomIn,
288
+ handleZoomOut,
289
+ ]);
290
+ const scaledRect = offset === 0
291
+ ? {
292
+ width: rect.width * zoom,
293
+ height: rect.height * zoom,
294
+ }
295
+ : rect;
296
+ let rendered = (_a = render.slide) === null || _a === void 0 ? void 0 : _a.call(render, slide, offset, scaledRect);
297
+ if (!rendered && isImageSlide(slide)) {
298
+ rendered = (React.createElement(ImageSlide, { slide: slide, offset: offset, rect: scaledRect, render: render, imageFit: carousel.imageFit }));
299
+ }
300
+ return rendered ? (React.createElement("div", { ref: setContainerRef, className: clsx(cssClass(CLASS_FULLSIZE), cssClass(CLASS_FLEX_CENTER)), ...(offset === 0
301
+ ? { style: { transform: `scale(${zoom}) translateX(${offsetX}px) translateY(${offsetY}px)` } }
302
+ : null) }, rendered)) : null;
303
+ };
@@ -0,0 +1,12 @@
1
+ import { Component } from "../../types.js";
2
+ declare type ZoomContextType = {
3
+ isMinZoom: boolean;
4
+ isMaxZoom: boolean;
5
+ isZoomSupported: boolean;
6
+ setIsMinZoom: (value: boolean) => void;
7
+ setIsMaxZoom: (value: boolean) => void;
8
+ setIsZoomSupported: (value: boolean) => void;
9
+ };
10
+ export declare const useZoom: () => ZoomContextType;
11
+ export declare const ZoomContextProvider: Component;
12
+ export {};
@@ -0,0 +1,18 @@
1
+ import * as React from "react";
2
+ import { makeUseContext } from "../../core/index.js";
3
+ const ZoomContext = React.createContext(null);
4
+ export const useZoom = makeUseContext("useZoom", "ZoomContext", ZoomContext);
5
+ export const ZoomContextProvider = ({ children }) => {
6
+ const [isMinZoom, setIsMinZoom] = React.useState(false);
7
+ const [isMaxZoom, setIsMaxZoom] = React.useState(false);
8
+ const [isZoomSupported, setIsZoomSupported] = React.useState(false);
9
+ const context = React.useMemo(() => ({
10
+ isMinZoom,
11
+ isMaxZoom,
12
+ isZoomSupported,
13
+ setIsMinZoom,
14
+ setIsMaxZoom,
15
+ setIsZoomSupported,
16
+ }), [isMinZoom, isMaxZoom, isZoomSupported]);
17
+ return React.createElement(ZoomContext.Provider, { value: context }, children);
18
+ };
@@ -0,0 +1,3 @@
1
+ import { ZoomContainer } from "./ZoomContainer.js";
2
+ /** Zoom slide wrapper */
3
+ export declare const ZoomWrapper: typeof ZoomContainer;
@@ -0,0 +1,26 @@
1
+ import * as React from "react";
2
+ import { ImageSlide, isImageSlide, useEventCallback } from "../../core/index.js";
3
+ import { ZoomContainer } from "./ZoomContainer.js";
4
+ import { useZoom } from "./ZoomContext.js";
5
+ export const ZoomWrapper = ({ slide, offset, rect, render, carousel, animation, zoom }) => {
6
+ var _a;
7
+ const { setIsZoomSupported, isZoomSupported } = useZoom();
8
+ const zoomSupported = isImageSlide(slide) && (Boolean(slide.srcSet) || Boolean(slide.width && slide.height));
9
+ const updateIsZoomSupported = useEventCallback(() => {
10
+ if (offset === 0 && zoomSupported !== isZoomSupported) {
11
+ setIsZoomSupported(zoomSupported);
12
+ }
13
+ });
14
+ React.useEffect(updateIsZoomSupported, [offset, updateIsZoomSupported]);
15
+ if (zoomSupported) {
16
+ return (React.createElement(ZoomContainer, { slide: slide, offset: offset, rect: rect, render: render, carousel: carousel, animation: animation, zoom: zoom }));
17
+ }
18
+ const rendered = (_a = render.slide) === null || _a === void 0 ? void 0 : _a.call(render, slide, offset, rect);
19
+ if (rendered) {
20
+ return React.createElement(React.Fragment, null, rendered);
21
+ }
22
+ if (isImageSlide(slide)) {
23
+ return React.createElement(ImageSlide, { slide: slide, offset: offset, rect: rect, render: render, imageFit: carousel.imageFit });
24
+ }
25
+ return null;
26
+ };
@@ -1,5 +1,8 @@
1
1
  import * as React from "react";
2
- import { LightboxProps, Plugin } from "../types.js";
2
+ import { LightboxProps } from "../../types.js";
3
+ import { Zoom } from "./Zoom.js";
4
+ export declare const ACTION_ZOOM_IN = "zoom-in";
5
+ export declare const ACTION_ZOOM_OUT = "zoom-out";
3
6
  /** Custom zoom button render function */
4
7
  declare type RenderZoomButton = ({ ref, labels, disabled, onClick, onFocus, onBlur, }: Pick<LightboxProps, "labels"> & {
5
8
  ref: React.ForwardedRef<HTMLButtonElement>;
@@ -8,7 +11,7 @@ declare type RenderZoomButton = ({ ref, labels, disabled, onClick, onFocus, onBl
8
11
  onFocus: () => void;
9
12
  onBlur: () => void;
10
13
  }) => React.ReactNode;
11
- declare module "../types.js" {
14
+ declare module "../../types" {
12
15
  interface LightboxProps {
13
16
  /** Zoom plugin settings */
14
17
  zoom?: {
@@ -47,7 +50,4 @@ declare module "../types.js" {
47
50
  iconZoomOut?: () => React.ReactNode;
48
51
  }
49
52
  }
50
- export declare const ZoomModule: import("../types.js").Module;
51
- /** Zoom plugin */
52
- export declare const Zoom: Plugin;
53
53
  export default Zoom;
@@ -0,0 +1,4 @@
1
+ import { Zoom } from "./Zoom.js";
2
+ export const ACTION_ZOOM_IN = "zoom-in";
3
+ export const ACTION_ZOOM_OUT = "zoom-out";
4
+ export default Zoom;
@@ -0,0 +1,2 @@
1
+ import { LightboxProps } from "./types.js";
2
+ export declare const LightboxDefaultProps: LightboxProps;
package/dist/props.js ADDED
@@ -0,0 +1,31 @@
1
+ import { ACTION_CLOSE, IMAGE_FIT_CONTAIN } from "./core/consts.js";
2
+ export const LightboxDefaultProps = {
3
+ open: false,
4
+ close: () => { },
5
+ index: 0,
6
+ slides: [],
7
+ render: {},
8
+ plugins: [],
9
+ toolbar: { buttons: [ACTION_CLOSE] },
10
+ labels: {},
11
+ animation: {
12
+ fade: 330,
13
+ swipe: 500,
14
+ },
15
+ carousel: {
16
+ finite: false,
17
+ preload: 2,
18
+ padding: "16px",
19
+ spacing: "30%",
20
+ imageFit: IMAGE_FIT_CONTAIN,
21
+ },
22
+ controller: {
23
+ focus: true,
24
+ aria: false,
25
+ touchAction: "none",
26
+ closeOnBackdropClick: false,
27
+ },
28
+ on: {},
29
+ styles: {},
30
+ className: "",
31
+ };
package/dist/styles.css CHANGED
@@ -2,6 +2,9 @@
2
2
  width: 100%;
3
3
  height: 100%;
4
4
  }
5
+ .yarl__relative {
6
+ position: relative;
7
+ }
5
8
  .yarl__portal {
6
9
  position: fixed;
7
10
  inset: 0;
@@ -14,21 +17,30 @@
14
17
  opacity: 1;
15
18
  }
16
19
  .yarl__container {
20
+ position: absolute;
21
+ inset: 0;
22
+ overflow: hidden;
23
+ background-color: var(--yarl__container_background_color, var(--yarl__color_backdrop, #000));
24
+ outline: 0;
17
25
  -webkit-user-select: none;
18
26
  -moz-user-select: none;
19
27
  user-select: none;
20
28
  touch-action: var(--yarl__controller_touch_action, none);
21
- }
22
- .yarl__container {
23
- position: relative;
24
- overflow: hidden;
25
- background-color: var(--yarl__container_background_color, var(--yarl__color_backdrop, #000));
26
- outline: 0;
29
+ overscroll-behavior: var(--yarl__controller_overscroll-behavior, contain);
27
30
  }
28
31
  .yarl__carousel {
29
- position: absolute;
30
- overflow: hidden;
31
- inset: 0;
32
+ display: flex;
33
+ flex: 0 0 auto;
34
+ height: 100%;
35
+ align-content: center;
36
+ justify-content: center;
37
+ align-items: stretch;
38
+ width: calc(100% + (var(--yarl__carousel_slides_count, 0) - 1) * (100% + var(--yarl__carousel_spacing_px, 0) * 1px + var(--yarl__carousel_spacing_percent, 0) * 1%));
39
+ -webkit-column-gap: calc(var(--yarl__carousel_spacing_px, 0) * 1px + 100 / (100 * var(--yarl__carousel_slides_count, 0) + (var(--yarl__carousel_slides_count, 0) - 1) * var(--yarl__carousel_spacing_percent, 0)) * var(--yarl__carousel_spacing_percent, 0) * 1%);
40
+ -moz-column-gap: calc(var(--yarl__carousel_spacing_px, 0) * 1px + 100 / (100 * var(--yarl__carousel_slides_count, 0) + (var(--yarl__carousel_slides_count, 0) - 1) * var(--yarl__carousel_spacing_percent, 0)) * var(--yarl__carousel_spacing_percent, 0) * 1%);
41
+ column-gap: calc(var(--yarl__carousel_spacing_px, 0) * 1px + 100 / (100 * var(--yarl__carousel_slides_count, 0) + (var(--yarl__carousel_slides_count, 0) - 1) * var(--yarl__carousel_spacing_percent, 0)) * var(--yarl__carousel_spacing_percent, 0) * 1%);
42
+ -webkit-transform: translateX(var(--yarl__swipe_offset, 0px));
43
+ transform: translateX(var(--yarl__swipe_offset, 0px));
32
44
  }
33
45
  .yarl__flex_center {
34
46
  display: flex;
@@ -37,24 +49,13 @@
37
49
  align-items: center;
38
50
  }
39
51
  .yarl__slide {
40
- position: absolute;
41
- overflow: hidden;
42
- inset: 0;
43
- padding: var(--yarl__carousel_padding, 16px);
44
- -webkit-transform: translate3d(calc(var(--yarl__slide_offset, 0) * (100% + var(--yarl__carousel_spacing, 30%)) * var(--yarl__direction, 1)), 0, 0);
45
- transform: translate3d(calc(var(--yarl__slide_offset, 0) * (100% + var(--yarl__carousel_spacing, 30%)) * var(--yarl__direction, 1)), 0, 0);
46
- transition: -webkit-transform var(--yarl__swipe_animation_duration, 500ms) var(--yarl__swipe_animation_timing_function, ease-out);
47
- transition: transform var(--yarl__swipe_animation_duration, 500ms) var(--yarl__swipe_animation_timing_function, ease-out);
48
- transition: transform var(--yarl__swipe_animation_duration, 500ms) var(--yarl__swipe_animation_timing_function, ease-out), -webkit-transform var(--yarl__swipe_animation_duration, 500ms) var(--yarl__swipe_animation_timing_function, ease-out);
52
+ flex: 1;
53
+ position: relative;
54
+ padding: calc(var(--yarl__carousel_padding_px, 0) * 1px + 100 / (100 * var(--yarl__carousel_slides_count, 0) + (var(--yarl__carousel_slides_count, 0) - 1) * var(--yarl__carousel_spacing_percent, 0)) * var(--yarl__carousel_padding_percent, 0) * 1%);
49
55
  }
50
56
  [dir=rtl] .yarl__slide {
51
57
  --yarl__direction: -1;
52
58
  }
53
- .yarl__container_swipe .yarl__slide {
54
- -webkit-transform: translate3d(calc(var(--yarl__slide_offset, 0) * (100% + var(--yarl__carousel_spacing, 30%)) * var(--yarl__direction, 1)), 0, 0) translate3d(var(--yarl__swipe_offset, 0px), 0, 0);
55
- transform: translate3d(calc(var(--yarl__slide_offset, 0) * (100% + var(--yarl__carousel_spacing, 30%)) * var(--yarl__direction, 1)), 0, 0) translate3d(var(--yarl__swipe_offset, 0px), 0, 0);
56
- transition: unset;
57
- }
58
59
  .yarl__slide_image {
59
60
  -o-object-fit: contain;
60
61
  object-fit: contain;
@@ -62,8 +63,13 @@
62
63
  user-select: none;
63
64
  -webkit-user-select: none;
64
65
  -webkit-touch-callout: none;
65
- -webkit-transform: translate3d(0, 0, 0);
66
- transform: translate3d(0, 0, 0);
66
+ }
67
+ @media screen and (min-width: 800px) {
68
+ .yarl__slide_image {
69
+ -webkit-transform: translateZ(0);
70
+ -webkit-backface-visibility: hidden;
71
+ -webkit-transform-style: preserve-3d;
72
+ }
67
73
  }
68
74
  .yarl__slide_image_cover {
69
75
  width: 100%;
@@ -78,8 +84,8 @@
78
84
  position: absolute;
79
85
  top: 50%;
80
86
  left: 50%;
81
- -webkit-transform: translate3d(-50%, -50%, 0);
82
- transform: translate3d(-50%, -50%, 0);
87
+ -webkit-transform: translateX(-50%) translateY(-50%);
88
+ transform: translateX(-50%) translateY(-50%);
83
89
  line-height: 0;
84
90
  }
85
91
  .yarl__slide_loading {
package/dist/types.d.ts CHANGED
@@ -2,14 +2,16 @@ import * as React from "react";
2
2
  import { ContainerRect } from "./core/hooks/useContainerRect.js";
3
3
  /** Image fit setting */
4
4
  export declare type ImageFit = "contain" | "cover";
5
+ export interface GenericSlide {
6
+ }
5
7
  /** Image slide properties */
6
- export interface SlideImage {
8
+ export interface SlideImage extends GenericSlide {
9
+ /** slide type */
10
+ type?: "image";
7
11
  /** image URL */
8
- src?: string;
12
+ src: string;
9
13
  /** image 'alt' attribute */
10
14
  alt?: string;
11
- /** @deprecated use `width` and `height` instead */
12
- aspectRatio?: number;
13
15
  /** image width in pixels */
14
16
  width?: number;
15
17
  /** image height in pixels */
@@ -23,7 +25,7 @@ export interface SlideImage {
23
25
  /** image width in pixels */
24
26
  width: number;
25
27
  /** image height in pixels */
26
- height?: number;
28
+ height: number;
27
29
  }[];
28
30
  }
29
31
  /** Supported slide types */
@@ -163,22 +165,6 @@ export interface LightboxProps {
163
165
  /** CSS class of the lightbox root element */
164
166
  className: string;
165
167
  }
166
- export declare const LightboxDefaultProps: {
167
- open: boolean;
168
- close: () => void;
169
- index: number;
170
- slides: Slide[];
171
- render: Render;
172
- plugins: Plugin[];
173
- toolbar: ToolbarSettings;
174
- labels: Labels;
175
- animation: AnimationSettings;
176
- carousel: CarouselSettings;
177
- controller: ControllerSettings;
178
- on: Callbacks;
179
- styles: SlotStyles;
180
- className: string;
181
- };
182
168
  /** Custom UI labels */
183
169
  export declare type Labels = {
184
170
  [key: string]: string;
@@ -238,4 +224,4 @@ export declare type DeepNonNullable<T> = NonNullable<{
238
224
  [K in keyof T]-?: NonNullable<T[K]>;
239
225
  }>;
240
226
  /** Lightbox external props */
241
- export declare type LightboxExternalProps = DeepPartial<Partial<LightboxProps>, "carousel" | "animation" | "render" | "toolbar" | "controller" | "on">;
227
+ export declare type LightboxExternalProps = DeepPartial<Partial<LightboxProps>, "carousel" | "animation" | "controller" | "toolbar">;
package/dist/types.js CHANGED
@@ -1,30 +1 @@
1
- export const LightboxDefaultProps = {
2
- open: false,
3
- close: () => { },
4
- index: 0,
5
- slides: [],
6
- render: {},
7
- plugins: [],
8
- toolbar: { buttons: ["close"] },
9
- labels: {},
10
- animation: {
11
- fade: 330,
12
- swipe: 500,
13
- },
14
- carousel: {
15
- finite: false,
16
- preload: 2,
17
- padding: "16px",
18
- spacing: "30%",
19
- imageFit: "contain",
20
- },
21
- controller: {
22
- focus: true,
23
- aria: false,
24
- touchAction: "none",
25
- closeOnBackdropClick: false,
26
- },
27
- on: {},
28
- styles: {},
29
- className: "",
30
- };
1
+ export {};