yet-another-react-lightbox 3.30.0 → 3.31.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/index.js CHANGED
@@ -739,14 +739,18 @@ const LightboxRoot = React.forwardRef(function LightboxRoot({ className, childre
739
739
  const nodeRef = React.useRef(null);
740
740
  const [isRTL, setIsRTL] = React.useState(false);
741
741
  const { trackFocusWithin } = useA11yContext();
742
- const detectRTL = React.useCallback((node) => {
743
- if (node) {
744
- setIsRTL(window.getComputedStyle(node).direction === "rtl");
742
+ const detectRTL = useEventCallback(() => {
743
+ if (nodeRef.current) {
744
+ const rtl = window.getComputedStyle(nodeRef.current).direction === "rtl";
745
+ if (rtl !== isRTL) {
746
+ setIsRTL(rtl);
747
+ }
745
748
  }
746
- }, []);
749
+ });
750
+ React.useEffect(detectRTL);
747
751
  return (React.createElement(DocumentContextProvider, { nodeRef: nodeRef },
748
752
  React.createElement(RTLContextProvider, { isRTL: isRTL },
749
- React.createElement("div", { ref: useForkRef(useForkRef(ref, nodeRef), detectRTL), className: clsx(cssClass("root"), className), ...trackFocusWithin(onFocus, onBlur), ...rest }, children))));
753
+ React.createElement("div", { ref: useForkRef(ref, nodeRef), className: clsx(cssClass("root"), className), ...trackFocusWithin(onFocus, onBlur), ...rest }, children))));
750
754
  });
751
755
 
752
756
  var SwipeState;
@@ -32,6 +32,10 @@ declare module "yet-another-react-lightbox" {
32
32
  pinchZoomV4?: boolean;
33
33
  /** if `true`, enables image zoom via scroll gestures for mouse and trackpad users */
34
34
  scrollToZoom?: boolean;
35
+ /** custom slide types that support zoom */
36
+ supports?: readonly SlideTypeKey[];
37
+ /** maximum zoom level for custom slide types; when a function, return `undefined` to use the default (default: 8) */
38
+ maxZoom?: number | ((slide: Slide) => number | undefined);
35
39
  };
36
40
  }
37
41
  interface AnimationSettings {
@@ -14,6 +14,7 @@ const defaultZoomProps = {
14
14
  pinchZoomDistanceFactor: 100,
15
15
  pinchZoomV4: false,
16
16
  scrollToZoom: false,
17
+ maxZoom: 8,
17
18
  };
18
19
  function validateMinZoom(minZoom) {
19
20
  return Math.min(Math.max(minZoom, Number.EPSILON), 1);
@@ -77,13 +78,18 @@ function useZoomProps() {
77
78
  return resolveZoomProps(zoom);
78
79
  }
79
80
 
81
+ function resolveMaxZoom(maxZoom, slide) {
82
+ var _a;
83
+ const resolved = typeof maxZoom === "function" ? ((_a = maxZoom(slide)) !== null && _a !== void 0 ? _a : defaultZoomProps.maxZoom) : maxZoom;
84
+ return Math.max(resolved, 1);
85
+ }
80
86
  function useZoomImageRect(slideRect, imageDimensions) {
81
87
  var _a, _b;
82
88
  let imageRect = { width: 0, height: 0 };
83
89
  let maxImageRect = { width: 0, height: 0 };
84
90
  const { currentSlide } = useLightboxState();
85
91
  const { imageFit } = useLightboxProps().carousel;
86
- const { maxZoomPixelRatio } = useZoomProps();
92
+ const { maxZoomPixelRatio, maxZoom: maxZoomInProps } = useZoomProps();
87
93
  if (slideRect && currentSlide) {
88
94
  const slide = { ...currentSlide, ...imageDimensions };
89
95
  if (isImageSlide(slide)) {
@@ -112,8 +118,23 @@ function useZoomImageRect(slideRect, imageDimensions) {
112
118
  };
113
119
  }
114
120
  }
121
+ else if (slideRect.width > 0 && slideRect.height > 0) {
122
+ if (imageDimensions && imageDimensions.width > 0 && imageDimensions.height > 0) {
123
+ imageRect = {
124
+ width: Math.min(slideRect.width, imageDimensions.width),
125
+ height: Math.min(slideRect.height, imageDimensions.height),
126
+ };
127
+ }
128
+ else {
129
+ imageRect = { width: slideRect.width, height: slideRect.height };
130
+ }
131
+ }
115
132
  }
116
- const maxZoom = imageRect.width ? Math.max(round(maxImageRect.width / imageRect.width, 5), 1) : 1;
133
+ const maxZoom = currentSlide && imageRect.width
134
+ ? isImageSlide(currentSlide)
135
+ ? Math.max(round(maxImageRect.width / imageRect.width, 5), 1)
136
+ : resolveMaxZoom(maxZoomInProps, currentSlide)
137
+ : 1;
117
138
  return { imageRect, maxZoom };
118
139
  }
119
140
 
@@ -296,7 +317,7 @@ function useZoomState(imageRect, maxZoom, zoomWrapperRef) {
296
317
  const { containerRect, slideRect } = useController();
297
318
  const { minZoom, zoomInMultiplier } = useZoomProps();
298
319
  const currentSource = currentSlide && isImageSlide(currentSlide) ? currentSlide.src : undefined;
299
- const disabled = !currentSource || !(zoomWrapperRef === null || zoomWrapperRef === void 0 ? void 0 : zoomWrapperRef.current);
320
+ const disabled = !(zoomWrapperRef === null || zoomWrapperRef === void 0 ? void 0 : zoomWrapperRef.current);
300
321
  useLayoutEffect(() => {
301
322
  setZoom(1);
302
323
  setOffsetX(0);
@@ -468,10 +489,37 @@ function ZoomWrapper({ render, slide, offset, rect }) {
468
489
  var _a;
469
490
  const [imageDimensions, setImageDimensions] = React.useState();
470
491
  const zoomWrapperRef = React.useRef(null);
492
+ const isImage = isImageSlide(slide);
471
493
  const { zoom, maxZoom, offsetX, offsetY, setZoomWrapper } = useZoom();
472
494
  const interactive = zoom > 1;
473
495
  const { carousel, on } = useLightboxProps();
474
496
  const { currentIndex } = useLightboxState();
497
+ useLayoutEffect(() => {
498
+ if (offset !== 0 || isImage || !zoomWrapperRef.current)
499
+ return () => { };
500
+ const measure = () => {
501
+ const wrapper = zoomWrapperRef.current;
502
+ if (!wrapper)
503
+ return;
504
+ let width = 0;
505
+ let height = 0;
506
+ for (const child of wrapper.children) {
507
+ if (child instanceof HTMLElement) {
508
+ width = Math.max(width, child.offsetWidth);
509
+ height = Math.max(height, child.offsetHeight);
510
+ }
511
+ }
512
+ setImageDimensions((prev) => (prev && prev.width === width && prev.height === height ? prev : { width, height }));
513
+ };
514
+ measure();
515
+ if (typeof ResizeObserver === "undefined")
516
+ return () => { };
517
+ const observer = new ResizeObserver(measure);
518
+ for (const child of zoomWrapperRef.current.children) {
519
+ observer.observe(child);
520
+ }
521
+ return () => observer.disconnect();
522
+ }, [offset, isImage, rect]);
475
523
  useLayoutEffect(() => {
476
524
  if (offset === 0) {
477
525
  setZoomWrapper({ zoomWrapperRef, imageDimensions });
@@ -480,7 +528,7 @@ function ZoomWrapper({ render, slide, offset, rect }) {
480
528
  return () => { };
481
529
  }, [offset, imageDimensions, setZoomWrapper]);
482
530
  let rendered = (_a = render.slide) === null || _a === void 0 ? void 0 : _a.call(render, { slide, offset, rect, zoom, maxZoom });
483
- if (!rendered && isImageSlide(slide)) {
531
+ if (!rendered && isImage) {
484
532
  const slideProps = {
485
533
  slide,
486
534
  offset,
@@ -505,7 +553,10 @@ const Zoom = ({ augment, addModule }) => {
505
553
  toolbar: addToolbarButton(toolbar, PLUGIN_ZOOM, React.createElement(ZoomToolbarControl, null)),
506
554
  render: {
507
555
  ...render,
508
- slide: (props) => { var _a; return isImageSlide(props.slide) ? React.createElement(ZoomWrapper, { render: render, ...props }) : (_a = render.slide) === null || _a === void 0 ? void 0 : _a.call(render, props); },
556
+ slide: (props) => {
557
+ var _a, _b;
558
+ return isImageSlide(props.slide) || (props.slide.type != null && ((_a = zoom.supports) === null || _a === void 0 ? void 0 : _a.includes(props.slide.type))) ? (React.createElement(ZoomWrapper, { render: render, ...props })) : ((_b = render.slide) === null || _b === void 0 ? void 0 : _b.call(render, props));
559
+ },
509
560
  },
510
561
  controller: { ...controller, preventDefaultWheelY: zoom.scrollToZoom },
511
562
  ...restProps,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yet-another-react-lightbox",
3
- "version": "3.30.0",
3
+ "version": "3.31.0",
4
4
  "description": "Modern React lightbox component",
5
5
  "author": "Igor Danchenko",
6
6
  "license": "MIT",