yet-another-react-lightbox 3.25.0 → 3.27.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/README.md CHANGED
@@ -9,7 +9,7 @@ extendable.
9
9
  [![Bundle Size](https://img.shields.io/bundlephobia/minzip/yet-another-react-lightbox.svg?color=blue)](https://bundlephobia.com/package/yet-another-react-lightbox)
10
10
  [![License MIT](https://img.shields.io/npm/l/yet-another-react-lightbox.svg?color=blue)](https://github.com/igordanchenko/yet-another-react-lightbox/blob/main/LICENSE)
11
11
 
12
- - **Built for React:** works with React 18, 17 and 16.8.0+
12
+ - **Built for React:** works with React 19, 18, 17 and 16.8.0+
13
13
  - **UX:** supports keyboard, mouse, touchpad and touchscreen navigation
14
14
  - **Preloading:** never displays partially downloaded images
15
15
  - **Performance:** preloads limited number of images without compromising
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- 'use client';
1
+ "use client";
2
2
  import * as React from 'react';
3
3
  import { IMAGE_FIT_COVER, IMAGE_FIT_CONTAIN, ACTION_CLOSE, MODULE_CONTROLLER, UNKNOWN_ACTION_TYPE, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_WHEEL, EVENT_ON_KEY_UP, EVENT_ON_KEY_DOWN, EVENT_ON_POINTER_CANCEL, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_UP, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_DOWN, SLIDE_STATUS_LOADING, activeSlideStatus, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_PLACEHOLDER, CLASS_SLIDE, CLASS_SLIDE_WRAPPER, ACTION_PREV, ACTION_NEXT, ACTION_SWIPE, MODULE_PORTAL, CLASS_FLEX_CENTER, MODULE_CAROUSEL, VK_ARROW_RIGHT, VK_ARROW_LEFT, VK_ESCAPE, MODULE_NAVIGATION, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, MODULE_NO_SCROLL, MODULE_ROOT, MODULE_TOOLBAR } from './types.js';
4
4
  import { createPortal } from 'react-dom';
@@ -1 +1 @@
1
- .yarl__slide_captions_container{background:var(--yarl__slide_captions_container_background,rgba(0,0,0,.5));left:var(--yarl__slide_captions_container_left,0);padding:var(--yarl__slide_captions_container_padding,16px);position:absolute;right:var(--yarl__slide_captions_container_right,0);-webkit-transform:translateZ(0)}.yarl__slide_title{color:var(--yarl__slide_title_color,#fff);font-size:var(--yarl__slide_title_font_size,125%);font-weight:var(--yarl__slide_title_font_weight,bolder);max-width:calc(100% - var(--yarl__toolbar_width, 0px));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.yarl__slide_title_container{top:var(--yarl__slide_title_container_top,0)}.yarl__slide_description{display:-webkit-box;-webkit-hyphens:auto;hyphens:auto;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:var(--yarl__slide_description_max_lines,3);color:var(--yarl__slide_description_color,#fff);text-align:var(--yarl__slide_description_text_align,start)}.yarl__slide_description_container{bottom:var(--yarl__slide_description_container_bottom,0)}
1
+ .yarl__slide_captions_container{background:var(--yarl__slide_captions_container_background,rgba(0,0,0,.5));left:var(--yarl__slide_captions_container_left,0);padding:var(--yarl__slide_captions_container_padding,16px);position:absolute;right:var(--yarl__slide_captions_container_right,0);-webkit-transform:translateZ(0)}.yarl__slide_title{color:var(--yarl__slide_title_color,#fff);font-size:var(--yarl__slide_title_font_size,125%);font-weight:var(--yarl__slide_title_font_weight,bolder);max-width:calc(100% - var(--yarl__toolbar_width, 0px));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.yarl__slide_title_container{top:var(--yarl__slide_title_container_top,0)}.yarl__slide_description{display:-webkit-box;hyphens:auto;overflow:hidden;-webkit-box-orient:vertical;color:var(--yarl__slide_description_color,#fff);-webkit-line-clamp:var(--yarl__slide_description_max_lines,3);text-align:var(--yarl__slide_description_text_align,start)}.yarl__slide_description_container{bottom:var(--yarl__slide_description_container_bottom,0)}
@@ -26,8 +26,10 @@ declare module "yet-another-react-lightbox" {
26
26
  keyboardMoveDistance?: number;
27
27
  /** wheel zoom distance factor */
28
28
  wheelZoomDistanceFactor?: number;
29
- /** pinch zoom distance factor */
29
+ /** @deprecated - pinch zoom distance factor */
30
30
  pinchZoomDistanceFactor?: number;
31
+ /** if `true`, enables the experimental pinch zoom implementation slated for v4 */
32
+ pinchZoomV4?: boolean;
31
33
  /** if `true`, enables image zoom via scroll gestures for mouse and trackpad users */
32
34
  scrollToZoom?: boolean;
33
35
  };
@@ -12,6 +12,7 @@ const defaultZoomProps = {
12
12
  keyboardMoveDistance: 50,
13
13
  wheelZoomDistanceFactor: 100,
14
14
  pinchZoomDistanceFactor: 100,
15
+ pinchZoomV4: false,
15
16
  scrollToZoom: false,
16
17
  };
17
18
  function validateMinZoom(minZoom) {
@@ -117,7 +118,7 @@ function useZoomImageRect(slideRect, imageDimensions) {
117
118
  }
118
119
 
119
120
  function distance(pointerA, pointerB) {
120
- return ((pointerA.clientX - pointerB.clientX) ** 2 + (pointerA.clientY - pointerB.clientY) ** 2) ** 0.5;
121
+ return Math.hypot(pointerA.clientX - pointerB.clientX, pointerA.clientY - pointerB.clientY);
121
122
  }
122
123
  function scaleZoom(value, delta, factor = 100, clamp = 2) {
123
124
  return value * Math.min(1 + Math.abs(delta / factor), clamp) ** Math.sign(delta);
@@ -125,11 +126,11 @@ function scaleZoom(value, delta, factor = 100, clamp = 2) {
125
126
  function useZoomSensors(zoom, minZoom, maxZoom, disabled, zoomIn, zoomOut, changeZoom, changeOffsets, zoomWrapperRef) {
126
127
  const activePointers = React.useRef([]);
127
128
  const lastPointerDown = React.useRef(0);
128
- const pinchZoomDistance = React.useRef(undefined);
129
+ const pinchZoom = React.useRef(undefined);
129
130
  const { globalIndex } = useLightboxState();
130
131
  const { getOwnerWindow } = useDocumentContext();
131
132
  const { containerRef, subscribeSensors } = useController();
132
- const { keyboardMoveDistance, zoomInMultiplier, wheelZoomDistanceFactor, scrollToZoom, doubleTapDelay, doubleClickDelay, doubleClickMaxStops, pinchZoomDistanceFactor, } = useZoomProps();
133
+ const { keyboardMoveDistance, zoomInMultiplier, wheelZoomDistanceFactor, scrollToZoom, doubleTapDelay, doubleClickDelay, doubleClickMaxStops, pinchZoomDistanceFactor, pinchZoomV4, } = useZoomProps();
133
134
  const translateCoordinates = React.useCallback((event) => {
134
135
  if (containerRef.current) {
135
136
  const { pageX, pageY } = event;
@@ -229,23 +230,28 @@ function useZoomSensors(zoom, minZoom, maxZoom, disabled, zoomIn, zoomOut, chang
229
230
  }
230
231
  replacePointer(event);
231
232
  if (pointers.length === 2) {
232
- pinchZoomDistance.current = distance(pointers[0], pointers[1]);
233
+ const initialDistance = distance(pointers[0], pointers[1]);
234
+ pinchZoom.current = {
235
+ previousDistance: initialDistance,
236
+ initialDistance: Math.max(initialDistance, 1),
237
+ initialZoom: zoom,
238
+ };
233
239
  }
234
240
  });
235
241
  const onPointerMove = useEventCallback((event) => {
236
242
  const pointers = activePointers.current;
237
243
  const activePointer = pointers.find((p) => p.pointerId === event.pointerId);
238
- if (pointers.length === 2 && pinchZoomDistance.current) {
244
+ if (pointers.length === 2 && pinchZoom.current) {
239
245
  event.stopPropagation();
240
246
  replacePointer(event);
241
247
  const currentDistance = distance(pointers[0], pointers[1]);
242
- const delta = currentDistance - pinchZoomDistance.current;
243
- if (Math.abs(delta) > 0) {
244
- changeZoom(scaleZoom(zoom, delta, pinchZoomDistanceFactor), true, ...pointers
245
- .map((x) => translateCoordinates(x))
246
- .reduce((acc, coordinate) => coordinate.map((x, i) => acc[i] + x / 2)));
247
- pinchZoomDistance.current = currentDistance;
248
- }
248
+ const targetZoom = pinchZoomV4
249
+ ? (pinchZoom.current.initialZoom / pinchZoom.current.initialDistance) * currentDistance
250
+ : scaleZoom(zoom, currentDistance - pinchZoom.current.previousDistance, pinchZoomDistanceFactor);
251
+ changeZoom(targetZoom, true, ...pointers
252
+ .map((x) => translateCoordinates(x))
253
+ .reduce((acc, coordinate) => coordinate.map((x, i) => acc[i] + x / 2)));
254
+ pinchZoom.current.previousDistance = currentDistance;
249
255
  return;
250
256
  }
251
257
  if (zoom > 1) {
@@ -261,7 +267,7 @@ function useZoomSensors(zoom, minZoom, maxZoom, disabled, zoomIn, zoomOut, chang
261
267
  const onPointerUp = React.useCallback((event) => {
262
268
  const pointers = activePointers.current;
263
269
  if (pointers.length === 2 && pointers.find((p) => p.pointerId === event.pointerId)) {
264
- pinchZoomDistance.current = undefined;
270
+ pinchZoom.current = undefined;
265
271
  }
266
272
  clearPointer(event);
267
273
  }, [clearPointer]);
@@ -269,7 +275,7 @@ function useZoomSensors(zoom, minZoom, maxZoom, disabled, zoomIn, zoomOut, chang
269
275
  const pointers = activePointers.current;
270
276
  pointers.splice(0, pointers.length);
271
277
  lastPointerDown.current = 0;
272
- pinchZoomDistance.current = undefined;
278
+ pinchZoom.current = undefined;
273
279
  }, []);
274
280
  usePointerEvents(subscribeSensors, onPointerDown, onPointerMove, onPointerUp, disabled);
275
281
  React.useEffect(cleanupSensors, [globalIndex, cleanupSensors]);
@@ -306,9 +312,7 @@ function useZoomState(imageRect, maxZoom, zoomWrapperRef) {
306
312
  setOffsetY(Math.min(Math.abs(newOffsetY), Math.max(maxOffsetY, 0)) * Math.sign(newOffsetY));
307
313
  }, [zoom, offsetX, offsetY, slideRect, imageRect.width, imageRect.height]);
308
314
  const changeZoom = React.useCallback((targetZoom, rapid, dx, dy) => {
309
- const newZoom = round(Math.min(Math.max(targetZoom + 0.001 < maxZoom ? targetZoom : maxZoom, minZoom), maxZoom), 5);
310
- if (newZoom === zoom)
311
- return;
315
+ const newZoom = round(targetZoom + 0.01 < maxZoom ? (targetZoom - 0.01 > minZoom ? targetZoom : minZoom) : maxZoom, 5);
312
316
  if (!rapid) {
313
317
  animate();
314
318
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yet-another-react-lightbox",
3
- "version": "3.25.0",
3
+ "version": "3.27.0",
4
4
  "description": "Modern React lightbox component",
5
5
  "author": "Igor Danchenko",
6
6
  "license": "MIT",
@@ -141,7 +141,7 @@
141
141
  "homepage": "https://yet-another-react-lightbox.com",
142
142
  "repository": {
143
143
  "type": "git",
144
- "url": "https://github.com/igordanchenko/yet-another-react-lightbox.git"
144
+ "url": "git+https://github.com/igordanchenko/yet-another-react-lightbox.git"
145
145
  },
146
146
  "bugs": {
147
147
  "url": "https://github.com/igordanchenko/yet-another-react-lightbox/issues"
@@ -149,10 +149,6 @@
149
149
  "engines": {
150
150
  "node": ">=14"
151
151
  },
152
- "publishConfig": {
153
- "access": "public",
154
- "provenance": true
155
- },
156
152
  "peerDependencies": {
157
153
  "@types/react": "^16 || ^17 || ^18 || ^19",
158
154
  "@types/react-dom": "^16 || ^17 || ^18 || ^19",