yet-another-react-lightbox 3.32.2 → 3.33.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
@@ -151,6 +151,8 @@ The following plugins are bundled in the package:
151
151
  support for fullscreen mode
152
152
  - [Inline](https://yet-another-react-lightbox.com/plugins/inline) - transforms
153
153
  the lightbox into an image carousel
154
+ - [Rotate](https://yet-another-react-lightbox.com/plugins/rotate) - adds image
155
+ rotation control
154
156
  - [Share](https://yet-another-react-lightbox.com/plugins/share) - adds sharing
155
157
  button
156
158
  - [Slideshow](https://yet-another-react-lightbox.com/plugins/slideshow) - adds
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { LightboxExternalProps, LightboxProps, ToolbarSettings, CarouselSettings, Slide, ContainerRect, LengthOrPercentage, SlideImage, Labels, Label, Component, Module, Node as Node$1, Plugin, Augmentation, EventTypes, ComponentProps, LightboxStateSwipeAction, LightboxStateUpdateAction, LightboxState, Render, ControllerSettings, ControllerRef, Callback, RenderFunction } from './types.js';
3
- export { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, ACTIVE_SLIDE_COMPLETE, ACTIVE_SLIDE_ERROR, ACTIVE_SLIDE_LOADING, ACTIVE_SLIDE_PLAYING, AnimationSettings, CLASS_FLEX_CENTER, CLASS_FULLSIZE, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, CLASS_SLIDE, CLASS_SLIDE_WRAPPER, CLASS_SLIDE_WRAPPER_INTERACTIVE, Callbacks, ClickCallbackProps, DeepPartial, DeepPartialValue, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_KEY_DOWN, EVENT_ON_KEY_UP, EVENT_ON_POINTER_CANCEL, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_WHEEL, GenericSlide, IMAGE_FIT_CONTAIN, IMAGE_FIT_COVER, ImageFit, ImageProps, ImageSource, MODULE_CAROUSEL, MODULE_CONTROLLER, MODULE_NAVIGATION, MODULE_NO_SCROLL, MODULE_PORTAL, MODULE_ROOT, MODULE_TOOLBAR, NavigationAction, NoScrollSettings, PLUGIN_CAPTIONS, PLUGIN_COUNTER, PLUGIN_DOWNLOAD, PLUGIN_FULLSCREEN, PLUGIN_INLINE, PLUGIN_SHARE, PLUGIN_SLIDESHOW, PLUGIN_THUMBNAILS, PLUGIN_ZOOM, PluginProps, PortalSettings, RenderSlideContainerProps, RenderSlideFooterProps, RenderSlideHeaderProps, RenderSlideProps, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_LOADING, SLIDE_STATUS_PLACEHOLDER, SLIDE_STATUS_PLAYING, SlideStatus, SlideTypeKey, SlideTypes, Slot, SlotStyles, SlotType, ToolbarButtonKey, ToolbarButtonKeys, UNKNOWN_ACTION_TYPE, VK_ARROW_LEFT, VK_ARROW_RIGHT, VK_ESCAPE, ViewCallbackProps, activeSlideStatus } from './types.js';
3
+ export { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, ACTIVE_SLIDE_COMPLETE, ACTIVE_SLIDE_ERROR, ACTIVE_SLIDE_LOADING, ACTIVE_SLIDE_PLAYING, AnimationSettings, CLASS_FLEX_CENTER, CLASS_FULLSIZE, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, CLASS_SLIDE, CLASS_SLIDE_WRAPPER, CLASS_SLIDE_WRAPPER_INTERACTIVE, Callbacks, ClickCallbackProps, DeepPartial, DeepPartialValue, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_KEY_DOWN, EVENT_ON_KEY_UP, EVENT_ON_POINTER_CANCEL, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_WHEEL, GenericSlide, IMAGE_FIT_CONTAIN, IMAGE_FIT_COVER, ImageFit, ImageProps, ImageSource, MODULE_CAROUSEL, MODULE_CONTROLLER, MODULE_NAVIGATION, MODULE_NO_SCROLL, MODULE_PORTAL, MODULE_ROOT, MODULE_TOOLBAR, NavigationAction, NoScrollSettings, PLUGIN_CAPTIONS, PLUGIN_COUNTER, PLUGIN_DOWNLOAD, PLUGIN_FULLSCREEN, PLUGIN_INLINE, PLUGIN_ROTATE, PLUGIN_SHARE, PLUGIN_SLIDESHOW, PLUGIN_THUMBNAILS, PLUGIN_ZOOM, PluginProps, PortalSettings, RenderSlideContainerProps, RenderSlideFooterProps, RenderSlideHeaderProps, RenderSlideProps, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_LOADING, SLIDE_STATUS_PLACEHOLDER, SLIDE_STATUS_PLAYING, SlideStatus, SlideTypeKey, SlideTypes, Slot, SlotStyles, SlotType, ToolbarButtonKey, ToolbarButtonKeys, UNKNOWN_ACTION_TYPE, VK_ARROW_LEFT, VK_ARROW_RIGHT, VK_ESCAPE, ViewCallbackProps, activeSlideStatus } from './types.js';
4
4
 
5
5
  /** Lightbox component */
6
6
  declare function Lightbox({ carousel, animation, render, toolbar, controller, noScroll, on, plugins, slides, index, ...restProps }: LightboxExternalProps): React.JSX.Element | null;
@@ -34,6 +34,8 @@ declare function computeSlideRect(containerRect: ContainerRect, padding: LengthO
34
34
  width: number;
35
35
  height: number;
36
36
  };
37
+ /** normalize rotation to a quarter turn in the [0, 360) range (non-finite values resolve to 0) */
38
+ declare function normalizeRotation(rotation: number): number;
37
39
  declare function devicePixelRatio(): number;
38
40
  declare function getSlideIndex(index: number, slidesCount: number): number;
39
41
  declare function hasSlides(slides: readonly Slide[]): slides is [Slide, ...Slide[]];
@@ -183,6 +185,11 @@ type RTLContextProviderProps = React.PropsWithChildren & {
183
185
  };
184
186
  declare function RTLContextProvider({ isRTL, children }: RTLContextProviderProps): React.JSX.Element;
185
187
 
188
+ type SlideRotationContextType = (slide: Slide) => number;
189
+ declare const SlideRotationContext: React.Context<SlideRotationContextType | null>;
190
+ /** clockwise rotation of the given slide in degrees (0, 90, 180 or 270; always `0` unless provided by a plugin) */
191
+ declare function useSlideRotation(slide?: Slide): number;
192
+
186
193
  type TimeoutsContextType = {
187
194
  setTimeout: (fn: () => void, delay?: number) => number;
188
195
  clearTimeout: (id?: number) => void;
@@ -232,12 +239,14 @@ type ImageSlideProps = Partial<Pick<CarouselSettings, "imageFit" | "imageProps">
232
239
  offset?: number;
233
240
  render?: Render;
234
241
  rect?: ContainerRect;
242
+ /** clockwise rotation in degrees (multiples of 90) */
243
+ rotation?: number;
235
244
  onClick?: () => void;
236
245
  onLoad?: (image: HTMLImageElement) => void;
237
246
  onError?: () => void;
238
247
  style?: React.CSSProperties;
239
248
  };
240
- declare function ImageSlide({ slide: image, offset, render, rect, imageFit, imageProps, onClick, onLoad, onError, style, }: ImageSlideProps): React.JSX.Element;
249
+ declare function ImageSlide({ slide: image, offset, render, rect, rotation: rotationProp, imageFit, imageProps, onClick, onLoad, onError, style, }: ImageSlideProps): React.JSX.Element;
241
250
 
242
251
  declare const LightboxRoot: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
243
252
 
@@ -310,5 +319,5 @@ declare const RootModule: Module;
310
319
  declare function Toolbar({ toolbar: { buttons }, render: { buttonClose, iconClose }, styles }: ComponentProps): React.JSX.Element;
311
320
  declare const ToolbarModule: Module;
312
321
 
313
- export { A11yContext, A11yContextProvider, Augmentation, Callback, Carousel, CarouselModule, CarouselSettings, CloseIcon, Component, ComponentProps, ContainerRect, Controller, ControllerContext, ControllerModule, ControllerRef, ControllerSettings, DocumentContext, DocumentContextProvider, ErrorIcon, EventTypes, EventsContext, EventsProvider, IconButton, ImageSlide, Label, Labels, LengthOrPercentage, Lightbox, LightboxDefaultProps, LightboxDispatchContext, LightboxExternalProps, LightboxProps, LightboxPropsContext, LightboxPropsProvider, LightboxRoot, LightboxState, LightboxStateContext, LightboxStateProvider, LightboxStateSwipeAction, LightboxStateUpdateAction, LoadingIcon, Module, Navigation, NavigationButton, NavigationModule, NextIcon, NoScroll, NoScrollModule, Node$1 as Node, Plugin, Portal, PortalModule, PreviousIcon, RTLContext, RTLContextProvider, Render, RenderFunction, Root, RootModule, Slide, SlideImage, SwipeState, TimeoutsContext, TimeoutsProvider, Toolbar, ToolbarModule, ToolbarSettings, addToolbarButton, calculatePreload, cleanup, clsx, composePrefix, computeSlideRect, createIcon, createIconDisabled, createModule, createNode, cssClass, cssVar, Lightbox as default, devicePixelRatio, getSlide, getSlideIfPresent, getSlideIndex, getSlideKey, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeInertWhen, makeUseContext, parseInt, parseLengthPercentage, reflow, round, setRef, stopNavigationEventsPropagation, translateLabel, translateSlideCounter, useA11yContext, useAnimation, useContainerRect, useController, useDelay, useDocumentContext, useEventCallback, useEvents, useForkRef, useKeyboardNavigation, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useNavigationState, usePointerSwipe, usePreventWheelDefaults, useRTL, useRTLContext, useSensors, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
314
- export type { A11yContextType, ComputeAnimation, ControllerContextType, DocumentContextProviderProps, DocumentContextType, Event, EventCallback, EventsContextType, IconButtonProps, ImageSlideProps, KeyboardEventType, LightboxDispatchContextType, LightboxPropsContextType, LightboxStateAction, LightboxStateContextType, LightboxStateProviderProps, NavigationButtonProps, PointerEventType, Publish, RTLContextProviderProps, RTLContextType, ReactEventType, RegisterSensors, SensorCallback, Subscribe, SubscribeSensors, SupportedEventType, TimeoutsContextType, Topic, Unsubscribe, UseSensors, WheelEventType };
322
+ export { A11yContext, A11yContextProvider, Augmentation, Callback, Carousel, CarouselModule, CarouselSettings, CloseIcon, Component, ComponentProps, ContainerRect, Controller, ControllerContext, ControllerModule, ControllerRef, ControllerSettings, DocumentContext, DocumentContextProvider, ErrorIcon, EventTypes, EventsContext, EventsProvider, IconButton, ImageSlide, Label, Labels, LengthOrPercentage, Lightbox, LightboxDefaultProps, LightboxDispatchContext, LightboxExternalProps, LightboxProps, LightboxPropsContext, LightboxPropsProvider, LightboxRoot, LightboxState, LightboxStateContext, LightboxStateProvider, LightboxStateSwipeAction, LightboxStateUpdateAction, LoadingIcon, Module, Navigation, NavigationButton, NavigationModule, NextIcon, NoScroll, NoScrollModule, Node$1 as Node, Plugin, Portal, PortalModule, PreviousIcon, RTLContext, RTLContextProvider, Render, RenderFunction, Root, RootModule, Slide, SlideImage, SlideRotationContext, SwipeState, TimeoutsContext, TimeoutsProvider, Toolbar, ToolbarModule, ToolbarSettings, addToolbarButton, calculatePreload, cleanup, clsx, composePrefix, computeSlideRect, createIcon, createIconDisabled, createModule, createNode, cssClass, cssVar, Lightbox as default, devicePixelRatio, getSlide, getSlideIfPresent, getSlideIndex, getSlideKey, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeInertWhen, makeUseContext, normalizeRotation, parseInt, parseLengthPercentage, reflow, round, setRef, stopNavigationEventsPropagation, translateLabel, translateSlideCounter, useA11yContext, useAnimation, useContainerRect, useController, useDelay, useDocumentContext, useEventCallback, useEvents, useForkRef, useKeyboardNavigation, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useNavigationState, usePointerSwipe, usePreventWheelDefaults, useRTL, useRTLContext, useSensors, useSlideRotation, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
323
+ export type { A11yContextType, ComputeAnimation, ControllerContextType, DocumentContextProviderProps, DocumentContextType, Event, EventCallback, EventsContextType, IconButtonProps, ImageSlideProps, KeyboardEventType, LightboxDispatchContextType, LightboxPropsContextType, LightboxStateAction, LightboxStateContextType, LightboxStateProviderProps, NavigationButtonProps, PointerEventType, Publish, RTLContextProviderProps, RTLContextType, ReactEventType, RegisterSensors, SensorCallback, SlideRotationContextType, Subscribe, SubscribeSensors, SupportedEventType, TimeoutsContextType, Topic, Unsubscribe, UseSensors, WheelEventType };
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
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';
5
- export { ACTIVE_SLIDE_COMPLETE, ACTIVE_SLIDE_ERROR, ACTIVE_SLIDE_LOADING, ACTIVE_SLIDE_PLAYING, CLASS_FULLSIZE, CLASS_SLIDE_WRAPPER_INTERACTIVE, PLUGIN_CAPTIONS, PLUGIN_COUNTER, PLUGIN_DOWNLOAD, PLUGIN_FULLSCREEN, PLUGIN_INLINE, PLUGIN_SHARE, PLUGIN_SLIDESHOW, PLUGIN_THUMBNAILS, PLUGIN_ZOOM, SLIDE_STATUS_PLAYING } from './types.js';
5
+ export { ACTIVE_SLIDE_COMPLETE, ACTIVE_SLIDE_ERROR, ACTIVE_SLIDE_LOADING, ACTIVE_SLIDE_PLAYING, CLASS_FULLSIZE, CLASS_SLIDE_WRAPPER_INTERACTIVE, PLUGIN_CAPTIONS, PLUGIN_COUNTER, PLUGIN_DOWNLOAD, PLUGIN_FULLSCREEN, PLUGIN_INLINE, PLUGIN_ROTATE, PLUGIN_SHARE, PLUGIN_SLIDESHOW, PLUGIN_THUMBNAILS, PLUGIN_ZOOM, SLIDE_STATUS_PLAYING } from './types.js';
6
6
 
7
7
  const cssPrefix$3 = "yarl__";
8
8
  function clsx(...classes) {
@@ -82,6 +82,9 @@ function computeSlideRect(containerRect, padding) {
82
82
  height: Math.max(containerRect.height - 2 * paddingPixels, 0),
83
83
  };
84
84
  }
85
+ function normalizeRotation(rotation) {
86
+ return Number.isFinite(rotation) ? (((Math.round(rotation / 90) * 90) % 360) + 360) % 360 : 0;
87
+ }
85
88
  function devicePixelRatio() {
86
89
  return (hasWindow() ? window === null || window === void 0 ? void 0 : window.devicePixelRatio : undefined) || 1;
87
90
  }
@@ -402,6 +405,12 @@ function RTLContextProvider({ isRTL, children }) {
402
405
  return React.createElement(RTLContext.Provider, { value: context }, children);
403
406
  }
404
407
 
408
+ const SlideRotationContext = React.createContext(null);
409
+ function useSlideRotation(slide) {
410
+ const getRotation = React.useContext(SlideRotationContext);
411
+ return slide && getRotation ? normalizeRotation(getRotation(slide)) : 0;
412
+ }
413
+
405
414
  const TimeoutsContext = React.createContext(null);
406
415
  const useTimeouts = makeUseContext("useTimeouts", "TimeoutsContext", TimeoutsContext);
407
416
  function TimeoutsProvider({ children }) {
@@ -673,7 +682,7 @@ function useThrottle(callback, delay) {
673
682
 
674
683
  const slidePrefix = makeComposePrefix("slide");
675
684
  const slideImagePrefix = makeComposePrefix("slide_image");
676
- function ImageSlide({ slide: image, offset, render, rect, imageFit, imageProps, onClick, onLoad, onError, style, }) {
685
+ function ImageSlide({ slide: image, offset, render, rect, rotation: rotationProp = 0, imageFit, imageProps, onClick, onLoad, onError, style, }) {
677
686
  var _a, _b, _c, _d, _e, _f, _g, _h;
678
687
  const [status, setStatus] = React.useState(SLIDE_STATUS_LOADING);
679
688
  const { publish } = useEvents();
@@ -711,24 +720,51 @@ function ImageSlide({ slide: image, offset, render, rect, imageFit, imageProps,
711
720
  onError === null || onError === void 0 ? void 0 : onError();
712
721
  });
713
722
  const cover = isImageFitCover(image, imageFit);
723
+ const rotation = normalizeRotation(rotationProp);
724
+ const rotated = rotation % 180 !== 0;
725
+ const imageRect = rect && rotated ? { width: rect.height, height: rect.width } : rect;
726
+ const widthLimit = rotated && imageRect ? `${imageRect.width}px` : "100%";
727
+ const heightLimit = rotated && imageRect ? `${imageRect.height}px` : "100%";
714
728
  const nonInfinite = (value, fallback) => (Number.isFinite(value) ? value : fallback);
715
729
  const maxWidth = nonInfinite(Math.max(...((_b = (_a = image.srcSet) === null || _a === void 0 ? void 0 : _a.map((x) => x.width)) !== null && _b !== void 0 ? _b : []).concat(image.width ? [image.width] : []).filter(Boolean)), ((_c = imageRef.current) === null || _c === void 0 ? void 0 : _c.naturalWidth) || 0);
716
730
  const maxHeight = nonInfinite(Math.max(...((_e = (_d = image.srcSet) === null || _d === void 0 ? void 0 : _d.map((x) => x.height)) !== null && _e !== void 0 ? _e : []).concat(image.height ? [image.height] : []).filter(Boolean)), ((_f = imageRef.current) === null || _f === void 0 ? void 0 : _f.naturalHeight) || 0);
717
731
  const defaultStyle = maxWidth && maxHeight
718
732
  ? {
719
- maxWidth: `min(${maxWidth}px, 100%)`,
720
- maxHeight: `min(${maxHeight}px, 100%)`,
733
+ maxWidth: `min(${maxWidth}px, ${widthLimit})`,
734
+ maxHeight: `min(${maxHeight}px, ${heightLimit})`,
721
735
  }
722
736
  : {
723
- maxWidth: "100%",
724
- maxHeight: "100%",
737
+ maxWidth: widthLimit,
738
+ maxHeight: heightLimit,
725
739
  };
740
+ const fitScale = imageRect && maxWidth && maxHeight ? Math.min(imageRect.width / maxWidth, imageRect.height / maxHeight, 1) : 0;
741
+ const rotatedSize = rotated && imageRect
742
+ ? cover
743
+ ? { width: imageRect.width, height: imageRect.height }
744
+ : fitScale
745
+ ? { width: maxWidth * fitScale, height: maxHeight * fitScale }
746
+ : null
747
+ : null;
726
748
  const srcSet = (_g = image.srcSet) === null || _g === void 0 ? void 0 : _g.slice().sort((a, b) => a.width - b.width).map((item) => `${item.src} ${item.width}w`).join(", ");
727
- const estimateActualWidth = () => rect && !cover && image.width && image.height ? (rect.height / image.height) * image.width : Number.MAX_VALUE;
728
- const sizes = srcSet && rect && hasWindow() ? `${Math.round(Math.min(estimateActualWidth(), rect.width))}px` : undefined;
749
+ const estimateActualWidth = () => {
750
+ if (!imageRect)
751
+ return undefined;
752
+ if (!image.width || !image.height)
753
+ return imageRect.width;
754
+ return (cover ? Math.max : Math.min)((imageRect.height / image.height) * image.width, imageRect.width);
755
+ };
756
+ const actualWidth = estimateActualWidth();
757
+ const sizes = srcSet && actualWidth !== undefined && hasWindow() ? `${Math.round(actualWidth)}px` : undefined;
729
758
  const { style: imagePropsStyle, className: imagePropsClassName, ...restImageProps } = (typeof imageProps === "function" ? imageProps(image) : imageProps) || {};
730
759
  return (React.createElement(React.Fragment, null,
731
- React.createElement("img", { ref: setImageRef, onLoad: handleOnLoad, onError: handleOnError, onClick: onClick, draggable: false, className: clsx(cssClass(slideImagePrefix()), cover && cssClass(slideImagePrefix("cover")), status !== SLIDE_STATUS_COMPLETE && cssClass(slideImagePrefix("loading")), imagePropsClassName), style: { ...defaultStyle, ...style, ...imagePropsStyle }, ...restImageProps, alt: (_h = image.alt) !== null && _h !== void 0 ? _h : "", sizes: sizes, srcSet: srcSet, src: image.src }),
760
+ React.createElement("img", { ref: setImageRef, onLoad: handleOnLoad, onError: handleOnError, onClick: onClick, draggable: false, className: clsx(cssClass(slideImagePrefix()), cover && cssClass(slideImagePrefix("cover")), status !== SLIDE_STATUS_COMPLETE && cssClass(slideImagePrefix("loading")), imagePropsClassName), style: {
761
+ ...defaultStyle,
762
+ ...(rotation ? { rotate: `${rotation}deg` } : null),
763
+ ...(rotated ? { flexShrink: 0 } : null),
764
+ ...rotatedSize,
765
+ ...style,
766
+ ...imagePropsStyle,
767
+ }, ...restImageProps, alt: (_h = image.alt) !== null && _h !== void 0 ? _h : "", sizes: sizes, srcSet: srcSet, src: image.src }),
732
768
  status !== SLIDE_STATUS_COMPLETE && (React.createElement("div", { className: cssClass(slidePrefix(SLIDE_STATUS_PLACEHOLDER)) },
733
769
  status === SLIDE_STATUS_LOADING &&
734
770
  ((render === null || render === void 0 ? void 0 : render.iconLoading) ? (render.iconLoading()) : (React.createElement(LoadingIcon, { className: clsx(cssClass(ELEMENT_ICON), cssClass(slidePrefix(SLIDE_STATUS_LOADING))) }))),
@@ -1294,6 +1330,7 @@ function CarouselSlide({ slide, offset }) {
1294
1330
  const { slideRect, focus } = useController();
1295
1331
  const { render, carousel: { imageFit, imageProps }, on: { click: onClick }, styles: { slide: style }, labels, } = useLightboxProps();
1296
1332
  const { getOwnerDocument } = useDocumentContext();
1333
+ const rotation = useSlideRotation(slide);
1297
1334
  const offscreen = offset !== 0;
1298
1335
  React.useEffect(() => {
1299
1336
  var _a;
@@ -1305,7 +1342,7 @@ function CarouselSlide({ slide, offset }) {
1305
1342
  var _a, _b, _c, _d;
1306
1343
  let rendered = (_a = render.slide) === null || _a === void 0 ? void 0 : _a.call(render, { slide, offset, rect: slideRect });
1307
1344
  if (!rendered && isImageSlide(slide)) {
1308
- rendered = (React.createElement(ImageSlide, { slide: slide, offset: offset, render: render, rect: slideRect, imageFit: imageFit, imageProps: imageProps, onClick: !offscreen ? () => onClick === null || onClick === void 0 ? void 0 : onClick({ index: currentIndex }) : undefined }));
1345
+ rendered = (React.createElement(ImageSlide, { slide: slide, offset: offset, render: render, rect: slideRect, rotation: rotation, imageFit: imageFit, imageProps: imageProps, onClick: !offscreen ? () => onClick === null || onClick === void 0 ? void 0 : onClick({ index: currentIndex }) : undefined }));
1309
1346
  }
1310
1347
  return rendered ? (React.createElement(React.Fragment, null, (_b = render.slideHeader) === null || _b === void 0 ? void 0 :
1311
1348
  _b.call(render, { slide }),
@@ -1620,4 +1657,4 @@ function Lightbox({ carousel, animation, render, toolbar, controller, noScroll,
1620
1657
  React.createElement(A11yContextProvider, null, renderNode(createNode(RootModule, config), props)))))));
1621
1658
  }
1622
1659
 
1623
- export { A11yContext, A11yContextProvider, ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, CLASS_FLEX_CENTER, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, CLASS_SLIDE, CLASS_SLIDE_WRAPPER, Carousel, CarouselModule, CloseIcon, Controller, ControllerContext, ControllerModule, DocumentContext, DocumentContextProvider, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_KEY_DOWN, EVENT_ON_KEY_UP, EVENT_ON_POINTER_CANCEL, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_WHEEL, ErrorIcon, EventsContext, EventsProvider, IMAGE_FIT_CONTAIN, IMAGE_FIT_COVER, IconButton, ImageSlide, Lightbox, LightboxDefaultProps, LightboxDispatchContext, LightboxPropsContext, LightboxPropsProvider, LightboxRoot, LightboxStateContext, LightboxStateProvider, LoadingIcon, MODULE_CAROUSEL, MODULE_CONTROLLER, MODULE_NAVIGATION, MODULE_NO_SCROLL, MODULE_PORTAL, MODULE_ROOT, MODULE_TOOLBAR, Navigation, NavigationButton, NavigationModule, NextIcon, NoScroll, NoScrollModule, Portal, PortalModule, PreviousIcon, RTLContext, RTLContextProvider, Root, RootModule, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_LOADING, SLIDE_STATUS_PLACEHOLDER, SwipeState, TimeoutsContext, TimeoutsProvider, Toolbar, ToolbarModule, UNKNOWN_ACTION_TYPE, VK_ARROW_LEFT, VK_ARROW_RIGHT, VK_ESCAPE, activeSlideStatus, addToolbarButton, calculatePreload, cleanup, clsx, composePrefix, computeSlideRect, createIcon, createIconDisabled, createModule, createNode, cssClass, cssVar, Lightbox as default, devicePixelRatio, getSlide, getSlideIfPresent, getSlideIndex, getSlideKey, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeInertWhen, makeUseContext, parseInt, parseLengthPercentage, reflow, round, setRef, stopNavigationEventsPropagation, translateLabel, translateSlideCounter, useA11yContext, useAnimation, useContainerRect, useController, useDelay, useDocumentContext, useEventCallback, useEvents, useForkRef, useKeyboardNavigation, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useNavigationState, usePointerEvents, usePointerSwipe, usePreventWheelDefaults, useRTL, useRTLContext, useSensors, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
1660
+ export { A11yContext, A11yContextProvider, ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, CLASS_FLEX_CENTER, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, CLASS_SLIDE, CLASS_SLIDE_WRAPPER, Carousel, CarouselModule, CloseIcon, Controller, ControllerContext, ControllerModule, DocumentContext, DocumentContextProvider, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_KEY_DOWN, EVENT_ON_KEY_UP, EVENT_ON_POINTER_CANCEL, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_WHEEL, ErrorIcon, EventsContext, EventsProvider, IMAGE_FIT_CONTAIN, IMAGE_FIT_COVER, IconButton, ImageSlide, Lightbox, LightboxDefaultProps, LightboxDispatchContext, LightboxPropsContext, LightboxPropsProvider, LightboxRoot, LightboxStateContext, LightboxStateProvider, LoadingIcon, MODULE_CAROUSEL, MODULE_CONTROLLER, MODULE_NAVIGATION, MODULE_NO_SCROLL, MODULE_PORTAL, MODULE_ROOT, MODULE_TOOLBAR, Navigation, NavigationButton, NavigationModule, NextIcon, NoScroll, NoScrollModule, Portal, PortalModule, PreviousIcon, RTLContext, RTLContextProvider, Root, RootModule, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_LOADING, SLIDE_STATUS_PLACEHOLDER, SlideRotationContext, SwipeState, TimeoutsContext, TimeoutsProvider, Toolbar, ToolbarModule, UNKNOWN_ACTION_TYPE, VK_ARROW_LEFT, VK_ARROW_RIGHT, VK_ESCAPE, activeSlideStatus, addToolbarButton, calculatePreload, cleanup, clsx, composePrefix, computeSlideRect, createIcon, createIconDisabled, createModule, createNode, cssClass, cssVar, Lightbox as default, devicePixelRatio, getSlide, getSlideIfPresent, getSlideIndex, getSlideKey, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeInertWhen, makeUseContext, normalizeRotation, parseInt, parseLengthPercentage, reflow, round, setRef, stopNavigationEventsPropagation, translateLabel, translateSlideCounter, useA11yContext, useAnimation, useContainerRect, useController, useDelay, useDocumentContext, useEventCallback, useEvents, useForkRef, useKeyboardNavigation, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useNavigationState, usePointerEvents, usePointerSwipe, usePreventWheelDefaults, useRTL, useRTLContext, useSensors, useSlideRotation, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
@@ -1 +1 @@
1
- .yarl__slide_captions_container{position:absolute;left:var(--yarl__slide_captions_container_left,0);right:var(--yarl__slide_captions_container_right,0);padding:var(--yarl__slide_captions_container_padding,16px);background:var(--yarl__slide_captions_container_background,rgba(0,0,0,.5));-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{overflow:hidden;hyphens:auto;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--yarl__slide_description_max_lines,3);text-align:var(--yarl__slide_description_text_align,start);color:var(--yarl__slide_description_color,#fff)}.yarl__slide_description_container{bottom:var(--yarl__slide_description_container_bottom,0)}
1
+ .yarl__slide_captions_container{position:absolute;left:var(--yarl__slide_captions_container_left,0);right:var(--yarl__slide_captions_container_right,0);padding:var(--yarl__slide_captions_container_padding,16px);background:var(--yarl__slide_captions_container_background,rgba(0,0,0,.5));-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{overflow:hidden;hyphens:auto;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--yarl__slide_description_max_lines,3);text-align:var(--yarl__slide_description_text_align,start);color:var(--yarl__slide_description_color,#fff)}.yarl__slide_description_container{bottom:var(--yarl__slide_description_container_bottom,0)}
@@ -3,6 +3,7 @@ export { default as Counter } from './counter/index.js';
3
3
  export { default as Download } from './download/index.js';
4
4
  export { default as Fullscreen } from './fullscreen/index.js';
5
5
  export { default as Inline } from './inline/index.js';
6
+ export { default as Rotate } from './rotate/index.js';
6
7
  export { default as Share } from './share/index.js';
7
8
  export { default as Slideshow } from './slideshow/index.js';
8
9
  export { default as Thumbnails } from './thumbnails/index.js';
@@ -3,6 +3,7 @@ export { default as Counter } from './counter/index.js';
3
3
  export { default as Download } from './download/index.js';
4
4
  export { default as Fullscreen } from './fullscreen/index.js';
5
5
  export { default as Inline } from './inline/index.js';
6
+ export { default as Rotate } from './rotate/index.js';
6
7
  export { default as Share } from './share/index.js';
7
8
  export { default as Slideshow } from './slideshow/index.js';
8
9
  export { default as Thumbnails } from './thumbnails/index.js';
@@ -0,0 +1,62 @@
1
+ import * as React from 'react';
2
+ import { PluginProps, PLUGIN_ROTATE, Callback, RenderFunction } from '../../types.js';
3
+
4
+ /** Rotate plugin */
5
+ declare function Rotate({ augment, addParent }: PluginProps): void;
6
+
7
+ declare module "yet-another-react-lightbox" {
8
+ interface LightboxProps {
9
+ /** Rotate plugin settings */
10
+ rotate?: {
11
+ /** Rotate plugin ref */
12
+ ref?: React.ForwardedRef<RotateRef>;
13
+ /** toolbar buttons to display (default: "both") */
14
+ buttons?: "clockwise" | "counterclockwise" | "both";
15
+ };
16
+ }
17
+ interface SlideImage {
18
+ /** initial clockwise image rotation in degrees (multiples of 90) */
19
+ rotation?: number;
20
+ }
21
+ interface Render {
22
+ /** render custom Rotate control in the toolbar */
23
+ buttonRotate?: RenderFunction<RotateRef>;
24
+ /** render custom Rotate Clockwise icon */
25
+ iconRotateClockwise?: RenderFunction;
26
+ /** render custom Rotate Counterclockwise icon */
27
+ iconRotateCounterClockwise?: RenderFunction;
28
+ }
29
+ interface Labels {
30
+ /** `Rotate clockwise` button title */
31
+ "Rotate clockwise"?: string;
32
+ /** `Rotate counterclockwise` button title */
33
+ "Rotate counterclockwise"?: string;
34
+ }
35
+ interface Callbacks {
36
+ /** rotate callback */
37
+ rotate?: Callback<RotateCallbackProps>;
38
+ }
39
+ /** Rotate callback props */
40
+ interface RotateCallbackProps {
41
+ /** index of the rotated slide */
42
+ index: number;
43
+ /** new clockwise rotation in degrees */
44
+ rotation: number;
45
+ }
46
+ interface ToolbarButtonKeys {
47
+ [PLUGIN_ROTATE]: null;
48
+ }
49
+ /** Rotate plugin ref */
50
+ interface RotateRef {
51
+ /** clockwise rotation of the current slide in degrees (0, 90, 180 or 270) */
52
+ rotation: number;
53
+ /** if `true`, rotation is unavailable for the current slide */
54
+ disabled: boolean;
55
+ /** rotate the current slide 90 degrees clockwise */
56
+ rotateClockwise: Callback;
57
+ /** rotate the current slide 90 degrees counterclockwise */
58
+ rotateCounterClockwise: Callback;
59
+ }
60
+ }
61
+
62
+ export { Rotate as default };
@@ -0,0 +1,94 @@
1
+ import * as React from 'react';
2
+ import { useLightboxProps, makeUseContext, useLightboxState, getSlideKey, isImageSlide, normalizeRotation, useEventCallback, SlideRotationContext, createIcon, useController, IconButton, addToolbarButton, createModule } from '../../index.js';
3
+ import { PLUGIN_ROTATE } from '../../types.js';
4
+
5
+ const defaultRotateProps = {
6
+ ref: null,
7
+ buttons: "both",
8
+ };
9
+ function resolveRotateProps(rotate) {
10
+ return { ...defaultRotateProps, ...rotate };
11
+ }
12
+ function useRotateProps() {
13
+ const { rotate } = useLightboxProps();
14
+ return resolveRotateProps(rotate);
15
+ }
16
+
17
+ const RotateContext = React.createContext(null);
18
+ const useRotate = makeUseContext("useRotate", "RotateContext", RotateContext);
19
+ function RotateContextProvider({ children }) {
20
+ const [rotations, setRotations] = React.useState(() => new Map());
21
+ const lastRotation = React.useRef(undefined);
22
+ const { currentSlide, currentIndex } = useLightboxState();
23
+ const { on } = useLightboxProps();
24
+ const { ref } = useRotateProps();
25
+ const getRotation = React.useCallback((slide) => {
26
+ var _a, _b;
27
+ const key = getSlideKey(slide);
28
+ if (!key || !isImageSlide(slide))
29
+ return 0;
30
+ return normalizeRotation((_b = (_a = rotations.get(key)) !== null && _a !== void 0 ? _a : slide.rotation) !== null && _b !== void 0 ? _b : 0);
31
+ }, [rotations]);
32
+ const currentKey = currentSlide && isImageSlide(currentSlide) ? getSlideKey(currentSlide) : undefined;
33
+ const rotation = currentSlide ? getRotation(currentSlide) : 0;
34
+ const disabled = !currentKey;
35
+ const rotateBy = useEventCallback((delta) => {
36
+ var _a, _b;
37
+ if (!currentKey)
38
+ return;
39
+ const baseRotation = ((_a = lastRotation.current) === null || _a === void 0 ? void 0 : _a.key) === currentKey ? lastRotation.current.rotation : rotation;
40
+ const newRotation = normalizeRotation(baseRotation + delta);
41
+ lastRotation.current = { key: currentKey, rotation: newRotation };
42
+ setRotations((prev) => new Map(prev).set(currentKey, newRotation));
43
+ (_b = on.rotate) === null || _b === void 0 ? void 0 : _b.call(on, { index: currentIndex, rotation: newRotation });
44
+ });
45
+ const rotateClockwise = React.useCallback(() => rotateBy(90), [rotateBy]);
46
+ const rotateCounterClockwise = React.useCallback(() => rotateBy(-90), [rotateBy]);
47
+ const context = React.useMemo(() => ({ rotation, disabled, rotateClockwise, rotateCounterClockwise }), [rotation, disabled, rotateClockwise, rotateCounterClockwise]);
48
+ React.useImperativeHandle(ref, () => context, [context]);
49
+ return (React.createElement(SlideRotationContext.Provider, { value: getRotation },
50
+ React.createElement(RotateContext.Provider, { value: context }, children)));
51
+ }
52
+
53
+ const RotateClockwiseIcon = createIcon("RotateClockwise", React.createElement("path", { d: "M15.55 5.55 11 1v3.07C7.06 4.56 4 7.92 4 12s3.05 7.44 7 7.93v-2.02c-2.84-.48-5-2.94-5-5.91s2.16-5.43 5-5.91V10l4.55-4.45zM19.93 11c-.17-1.39-.72-2.73-1.62-3.89l-1.42 1.42c.54.75.88 1.6 1.02 2.47h2.02zM13 17.9v2.02c1.39-.17 2.74-.71 3.9-1.61l-1.44-1.44c-.75.54-1.59.89-2.46 1.03zm3.89-2.42 1.42 1.41c.9-1.16 1.45-2.5 1.62-3.89h-2.02c-.14.87-.48 1.72-1.02 2.48z" }));
54
+ const RotateCounterClockwiseIcon = createIcon("RotateCounterClockwise", React.createElement("path", { d: "M7.11 8.53 5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z" }));
55
+ function RotateButton({ counterClockwise }) {
56
+ const focused = React.useRef(false);
57
+ const { render } = useLightboxProps();
58
+ const { focus } = useController();
59
+ const { disabled, rotateClockwise, rotateCounterClockwise } = useRotate();
60
+ React.useEffect(() => {
61
+ if (disabled && focused.current) {
62
+ focused.current = false;
63
+ focus();
64
+ }
65
+ }, [disabled, focus]);
66
+ return (React.createElement(IconButton, { disabled: disabled, label: counterClockwise ? "Rotate counterclockwise" : "Rotate clockwise", icon: counterClockwise ? RotateCounterClockwiseIcon : RotateClockwiseIcon, renderIcon: counterClockwise ? render.iconRotateCounterClockwise : render.iconRotateClockwise, onClick: counterClockwise ? rotateCounterClockwise : rotateClockwise, onFocus: () => {
67
+ focused.current = true;
68
+ }, onBlur: () => {
69
+ focused.current = false;
70
+ } }));
71
+ }
72
+
73
+ function RotateToolbarControl() {
74
+ const { render } = useLightboxProps();
75
+ const { buttons } = useRotateProps();
76
+ const rotateRef = useRotate();
77
+ if (render.buttonRotate) {
78
+ return React.createElement(React.Fragment, null, render.buttonRotate(rotateRef));
79
+ }
80
+ return (React.createElement(React.Fragment, null,
81
+ buttons !== "clockwise" && React.createElement(RotateButton, { counterClockwise: true }),
82
+ buttons !== "counterclockwise" && React.createElement(RotateButton, null)));
83
+ }
84
+
85
+ function Rotate({ augment, addParent }) {
86
+ augment(({ rotate, toolbar, ...restProps }) => ({
87
+ rotate: resolveRotateProps(rotate),
88
+ toolbar: addToolbarButton(toolbar, PLUGIN_ROTATE, React.createElement(RotateToolbarControl, null)),
89
+ ...restProps,
90
+ }));
91
+ addParent("", createModule(PLUGIN_ROTATE, RotateContextProvider));
92
+ }
93
+
94
+ export { Rotate as default };
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { useLightboxProps, composePrefix, createIcon, ImageSlide, isImageSlide, cssClass, makeComposePrefix, useLightboxState, useDocumentContext, useEventCallback, translateSlideCounter, cssVar, clsx, getSlideKey, useRTL, useEvents, useSensors, useKeyboardNavigation, useAnimation, cleanup, calculatePreload, hasSlides, getSlide, translateLabel, makeUseContext, LightboxPropsProvider, createIconDisabled, IconButton, addToolbarButton, createModule } from '../../index.js';
2
+ import { useLightboxProps, composePrefix, createIcon, ImageSlide, isImageSlide, cssClass, makeComposePrefix, useLightboxState, useDocumentContext, useSlideRotation, useEventCallback, translateSlideCounter, cssVar, clsx, getSlideKey, useRTL, useEvents, useSensors, useKeyboardNavigation, useAnimation, cleanup, calculatePreload, hasSlides, getSlide, translateLabel, makeUseContext, LightboxPropsProvider, createIconDisabled, IconButton, addToolbarButton, createModule } from '../../index.js';
3
3
  import { PLUGIN_THUMBNAILS, ELEMENT_ICON, CLASS_FLEX_CENTER, ACTION_SWIPE, ACTION_NEXT, ACTION_PREV, PLUGIN_FULLSCREEN, MODULE_CONTROLLER } from '../../types.js';
4
4
 
5
5
  const defaultThumbnailsProps = {
@@ -30,13 +30,13 @@ const cssThumbnailPrefix = (value) => cssPrefix(composePrefix("thumbnail", value
30
30
 
31
31
  const VideoThumbnailIcon = createIcon("VideoThumbnail", React.createElement("path", { d: "M10 16.5l6-4.5-6-4.5v9zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" }));
32
32
  const UnknownThumbnailIcon = createIcon("UnknownThumbnail", React.createElement("path", { d: "M23 18V6c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zM8.5 12.5l2.5 3.01L14.5 11l4.5 6H5l3.5-4.5z" }));
33
- function renderThumbnail({ slide, render, rect, imageFit }) {
33
+ function renderThumbnail({ slide, render, rect, imageFit, rotation }) {
34
34
  var _a;
35
35
  const customThumbnail = (_a = render.thumbnail) === null || _a === void 0 ? void 0 : _a.call(render, { slide, render, rect, imageFit });
36
36
  if (customThumbnail) {
37
37
  return customThumbnail;
38
38
  }
39
- const imageSlideProps = { render, rect, imageFit };
39
+ const imageSlideProps = { render, rect, imageFit, rotation };
40
40
  if (slide.thumbnail) {
41
41
  return React.createElement(ImageSlide, { slide: { src: slide.thumbnail }, ...imageSlideProps });
42
42
  }
@@ -64,6 +64,7 @@ function Thumbnail({ slide, index, onClick, fadeIn, fadeOut, placeholder, onLose
64
64
  const { getOwnerDocument } = useDocumentContext();
65
65
  const { width, height, imageFit } = useThumbnailsProps();
66
66
  const rect = { width, height };
67
+ const rotation = useSlideRotation(slide !== null && slide !== void 0 ? slide : undefined);
67
68
  const active = index === globalIndex;
68
69
  const onLoseFocusCallback = useEventCallback(onLoseFocus);
69
70
  React.useEffect(() => {
@@ -85,7 +86,7 @@ function Thumbnail({ slide, index, onClick, fadeIn, fadeOut, placeholder, onLose
85
86
  }
86
87
  : null),
87
88
  ...styles.thumbnail,
88
- }, onClick: onClick, "aria-current": active ? true : undefined, "aria-label": translateSlideCounter(labels, slides, index) }, slide && renderThumbnail({ slide, render, rect, imageFit })));
89
+ }, onClick: onClick, "aria-current": active ? true : undefined, "aria-label": translateSlideCounter(labels, slides, index) }, slide && renderThumbnail({ slide, render, rect, imageFit, rotation })));
89
90
  }
90
91
 
91
92
  function isHorizontal(position) {
@@ -1 +1 @@
1
- .yarl__thumbnails{display:flex;height:100%}.yarl__thumbnails_bottom,.yarl__thumbnails_end .yarl__thumbnails_track,.yarl__thumbnails_start .yarl__thumbnails_track,.yarl__thumbnails_top{flex-direction:column}.yarl__thumbnails_wrapper{flex:1;position:relative}.yarl__thumbnails_container{flex:0 0 auto;background-color:var(--yarl__thumbnails_container_background_color,var(--yarl__color_backdrop,#000));padding:var(--yarl__thumbnails_container_padding,16px);position:relative;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-touch-callout:none}.yarl__thumbnails_vignette{position:absolute;pointer-events:none;--yarl__thumbnails_vignette_size:12%}@media (min-width:1200px){.yarl__thumbnails_vignette{--yarl__thumbnails_vignette_size:8%}}@media (min-width:2000px){.yarl__thumbnails_vignette{--yarl__thumbnails_vignette_size:5%}}.yarl__thumbnails_bottom .yarl__thumbnails_vignette,.yarl__thumbnails_top .yarl__thumbnails_vignette{height:100%;left:0;right:0;background:linear-gradient(to right,var(--yarl__color_backdrop,#000) 0,transparent var(--yarl__thumbnails_vignette_size,12%) calc(100% - var(--yarl__thumbnails_vignette_size, 12%)),var(--yarl__color_backdrop,#000) 100%)}.yarl__thumbnails_end .yarl__thumbnails_vignette,.yarl__thumbnails_start .yarl__thumbnails_vignette{width:100%;top:0;bottom:0;background:linear-gradient(to bottom,var(--yarl__color_backdrop,#000) 0,transparent var(--yarl__thumbnails_vignette_size,12%) calc(100% - var(--yarl__thumbnails_vignette_size, 12%)),var(--yarl__color_backdrop,#000) 100%)}.yarl__thumbnails_track{outline:none;gap:var(--yarl__thumbnails_thumbnail_gap,16px)}.yarl__thumbnails_thumbnail{flex:0 0 auto;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:var(--yarl__thumbnails_thumbnail_background,#000);border-width:var(--yarl__thumbnails_thumbnail_border,1px);border-style:var(--yarl__thumbnails_thumbnail_border_style,solid);border-color:var(--yarl__thumbnails_thumbnail_border_color,var(--yarl__color_button,hsla(0,0%,100%,.8)));border-radius:var(--yarl__thumbnails_thumbnail_border_radius,4px);-webkit-tap-highlight-color:transparent;position:relative;overflow:hidden;padding:var(--yarl__thumbnails_thumbnail_padding,4px);outline:none;width:var(--yarl__thumbnails_thumbnail_width,120px);height:var(--yarl__thumbnails_thumbnail_height,80px);box-sizing:content-box}.yarl__thumbnails_thumbnail_active{border-color:var(--yarl__thumbnails_thumbnail_active_border_color,var(--yarl__color_button_active,#fff))}.yarl__thumbnails_thumbnail_fadein{opacity:0;animation:yarl__thumbnails_thumbnail_fadein var(--yarl__thumbnails_thumbnail_fadein_duration,.5s) ease-in-out var(--yarl__thumbnails_thumbnail_fadein_delay,0s) forwards}.yarl__thumbnails_thumbnail_fadeout{animation:yarl__thumbnails_thumbnail_fadeout var(--yarl__thumbnails_thumbnail_fadeout_duration,.5s) ease-in-out var(--yarl__thumbnails_thumbnail_fadeout_delay,0s) forwards;cursor:unset}.yarl__thumbnails_thumbnail_placeholder{visibility:hidden;cursor:unset}.yarl__thumbnails_thumbnail:focus{box-shadow:var(--yarl__thumbnails_thumbnail_focus_box_shadow,#000 0 0 0 2px,var(--yarl__color_button,hsla(0,0%,100%,.8)) 0 0 0 4px)}.yarl__thumbnails_thumbnail:focus:not(:focus-visible){box-shadow:unset}.yarl__thumbnails_thumbnail:focus-visible{box-shadow:var(--yarl__thumbnails_thumbnail_focus_box_shadow,#000 0 0 0 2px,var(--yarl__color_button,hsla(0,0%,100%,.8)) 0 0 0 4px)}.yarl__thumbnails_thumbnail_icon{color:var(--yarl__thumbnails_thumbnail_icon_color,var(--yarl__color_button,hsla(0,0%,100%,.8)));filter:var(--yarl__thumbnails_thumbnail_icon_filter,drop-shadow(2px 2px 2px rgba(0,0,0,.8)));position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);width:var(--yarl__thumbnails_thumbnail_icon_size,32px);height:var(--yarl__thumbnails_thumbnail_icon_size,32px)}@keyframes yarl__thumbnails_thumbnail_fadein{0%{opacity:0}to{opacity:1}}@keyframes yarl__thumbnails_thumbnail_fadeout{0%{opacity:1}to{opacity:0}}
1
+ .yarl__thumbnails{display:flex;height:100%}.yarl__thumbnails_bottom,.yarl__thumbnails_end .yarl__thumbnails_track,.yarl__thumbnails_start .yarl__thumbnails_track,.yarl__thumbnails_top{flex-direction:column}.yarl__thumbnails_wrapper{flex:1;position:relative}.yarl__thumbnails_container{flex:0 0 auto;background-color:var(--yarl__thumbnails_container_background_color,var(--yarl__color_backdrop,#000));padding:var(--yarl__thumbnails_container_padding,16px);position:relative;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-touch-callout:none}.yarl__thumbnails_vignette{position:absolute;pointer-events:none;--yarl__thumbnails_vignette_size:12%}@media(min-width:1200px){.yarl__thumbnails_vignette{--yarl__thumbnails_vignette_size:8%}}@media(min-width:2000px){.yarl__thumbnails_vignette{--yarl__thumbnails_vignette_size:5%}}.yarl__thumbnails_bottom .yarl__thumbnails_vignette,.yarl__thumbnails_top .yarl__thumbnails_vignette{height:100%;left:0;right:0;background:linear-gradient(to right,var(--yarl__color_backdrop,#000) 0,transparent var(--yarl__thumbnails_vignette_size,12%) calc(100% - var(--yarl__thumbnails_vignette_size,12%)),var(--yarl__color_backdrop,#000) 100%)}.yarl__thumbnails_end .yarl__thumbnails_vignette,.yarl__thumbnails_start .yarl__thumbnails_vignette{width:100%;top:0;bottom:0;background:linear-gradient(to bottom,var(--yarl__color_backdrop,#000) 0,transparent var(--yarl__thumbnails_vignette_size,12%) calc(100% - var(--yarl__thumbnails_vignette_size,12%)),var(--yarl__color_backdrop,#000) 100%)}.yarl__thumbnails_track{outline:none;gap:var(--yarl__thumbnails_thumbnail_gap,16px)}.yarl__thumbnails_thumbnail{flex:0 0 auto;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:var(--yarl__thumbnails_thumbnail_background,#000);border-width:var(--yarl__thumbnails_thumbnail_border,1px);border-style:var(--yarl__thumbnails_thumbnail_border_style,solid);border-color:var(--yarl__thumbnails_thumbnail_border_color,var(--yarl__color_button,hsla(0,0%,100%,.8)));border-radius:var(--yarl__thumbnails_thumbnail_border_radius,4px);-webkit-tap-highlight-color:transparent;position:relative;overflow:hidden;padding:var(--yarl__thumbnails_thumbnail_padding,4px);outline:none;width:var(--yarl__thumbnails_thumbnail_width,120px);height:var(--yarl__thumbnails_thumbnail_height,80px);box-sizing:content-box}.yarl__thumbnails_thumbnail_active{border-color:var(--yarl__thumbnails_thumbnail_active_border_color,var(--yarl__color_button_active,#fff))}.yarl__thumbnails_thumbnail_fadein{opacity:0;animation:yarl__thumbnails_thumbnail_fadein var(--yarl__thumbnails_thumbnail_fadein_duration,.5s) ease-in-out var(--yarl__thumbnails_thumbnail_fadein_delay,0s) forwards}.yarl__thumbnails_thumbnail_fadeout{animation:yarl__thumbnails_thumbnail_fadeout var(--yarl__thumbnails_thumbnail_fadeout_duration,.5s) ease-in-out var(--yarl__thumbnails_thumbnail_fadeout_delay,0s) forwards;cursor:unset}.yarl__thumbnails_thumbnail_placeholder{visibility:hidden;cursor:unset}.yarl__thumbnails_thumbnail:focus{box-shadow:var(--yarl__thumbnails_thumbnail_focus_box_shadow,#000 0 0 0 2px,var(--yarl__color_button,hsla(0,0%,100%,.8)) 0 0 0 4px)}.yarl__thumbnails_thumbnail:focus:not(:focus-visible){box-shadow:unset}.yarl__thumbnails_thumbnail:focus-visible{box-shadow:var(--yarl__thumbnails_thumbnail_focus_box_shadow,#000 0 0 0 2px,var(--yarl__color_button,hsla(0,0%,100%,.8)) 0 0 0 4px)}.yarl__thumbnails_thumbnail_icon{color:var(--yarl__thumbnails_thumbnail_icon_color,var(--yarl__color_button,hsla(0,0%,100%,.8)));filter:var(--yarl__thumbnails_thumbnail_icon_filter,drop-shadow(2px 2px 2px rgba(0,0,0,.8)));position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);width:var(--yarl__thumbnails_thumbnail_icon_size,32px);height:var(--yarl__thumbnails_thumbnail_icon_size,32px)}@keyframes yarl__thumbnails_thumbnail_fadein{0%{opacity:0}to{opacity:1}}@keyframes yarl__thumbnails_thumbnail_fadeout{0%{opacity:1}to{opacity:0}}
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { useLightboxProps, useMotionPreference, useEventCallback, useLayoutEffect, useLightboxState, isImageSlide, isImageFitCover, round, useDocumentContext, useController, usePointerEvents, cleanup, makeUseContext, createIcon, IconButton, devicePixelRatio, ImageSlide, clsx, cssClass, addToolbarButton, createModule } from '../../index.js';
2
+ import { useLightboxProps, useMotionPreference, useEventCallback, useLayoutEffect, useLightboxState, useSlideRotation, isImageSlide, isImageFitCover, round, useDocumentContext, useController, usePointerEvents, cleanup, makeUseContext, createIcon, IconButton, devicePixelRatio, ImageSlide, clsx, cssClass, addToolbarButton, createModule } from '../../index.js';
3
3
  import { EVENT_ON_KEY_DOWN, EVENT_ON_WHEEL, UNKNOWN_ACTION_TYPE, CLASS_FULLSIZE, CLASS_FLEX_CENTER, CLASS_SLIDE_WRAPPER, CLASS_SLIDE_WRAPPER_INTERACTIVE, PLUGIN_ZOOM } from '../../types.js';
4
4
 
5
5
  const defaultZoomProps = {
@@ -88,14 +88,18 @@ function useZoomImageRect(slideRect, imageDimensions) {
88
88
  let imageRect = { width: 0, height: 0 };
89
89
  let maxImageRect = { width: 0, height: 0 };
90
90
  const { currentSlide } = useLightboxState();
91
+ const rotation = useSlideRotation(currentSlide);
91
92
  const { imageFit } = useLightboxProps().carousel;
92
93
  const { maxZoomPixelRatio, maxZoom: maxZoomInProps } = useZoomProps();
93
94
  if (slideRect && currentSlide) {
94
95
  const slide = { ...currentSlide, ...imageDimensions };
95
96
  if (isImageSlide(slide)) {
96
97
  const cover = isImageFitCover(slide, imageFit);
97
- const width = Math.max(...(((_a = slide.srcSet) === null || _a === void 0 ? void 0 : _a.map((x) => x.width)) || []).concat(slide.width ? [slide.width] : []));
98
- const height = Math.max(...(((_b = slide.srcSet) === null || _b === void 0 ? void 0 : _b.map((x) => x.height)) || []).concat(slide.height ? [slide.height] : []));
98
+ const sourceWidth = Math.max(...(((_a = slide.srcSet) === null || _a === void 0 ? void 0 : _a.map((x) => x.width)) || []).concat(slide.width ? [slide.width] : []));
99
+ const sourceHeight = Math.max(...(((_b = slide.srcSet) === null || _b === void 0 ? void 0 : _b.map((x) => x.height)) || []).concat(slide.height ? [slide.height] : []));
100
+ const rotated = rotation % 180 !== 0;
101
+ const width = rotated ? sourceHeight : sourceWidth;
102
+ const height = rotated ? sourceWidth : sourceHeight;
99
103
  if (width > 0 && height > 0 && slideRect.width > 0 && slideRect.height > 0) {
100
104
  maxImageRect = cover
101
105
  ? {
@@ -144,7 +148,7 @@ function distance(pointerA, pointerB) {
144
148
  function scaleZoom(value, delta, factor = 100, clamp = 2) {
145
149
  return value * Math.min(1 + Math.abs(delta / factor), clamp) ** Math.sign(delta);
146
150
  }
147
- function useZoomSensors(zoom, minZoom, maxZoom, disabled, zoomIn, zoomOut, changeZoom, changeOffsets, zoomWrapperRef) {
151
+ function useZoomSensors(getZoom, minZoom, maxZoom, disabled, zoomIn, zoomOut, changeZoom, changeOffsets, zoomWrapperRef) {
148
152
  const activePointers = React.useRef([]);
149
153
  const lastPointerDown = React.useRef(0);
150
154
  const pinchZoom = React.useRef(undefined);
@@ -162,6 +166,7 @@ function useZoomSensors(zoom, minZoom, maxZoom, disabled, zoomIn, zoomOut, chang
162
166
  return [];
163
167
  }, [containerRef, getOwnerWindow]);
164
168
  const onKeyDown = useEventCallback((event) => {
169
+ const zoom = getZoom();
165
170
  const { key, metaKey, ctrlKey } = event;
166
171
  const meta = metaKey || ctrlKey;
167
172
  const preventDefault = () => {
@@ -200,6 +205,7 @@ function useZoomSensors(zoom, minZoom, maxZoom, disabled, zoomIn, zoomOut, chang
200
205
  }
201
206
  });
202
207
  const onWheel = useEventCallback((event) => {
208
+ const zoom = getZoom();
203
209
  if (event.ctrlKey || scrollToZoom) {
204
210
  if (Math.abs(event.deltaY) > Math.abs(event.deltaX)) {
205
211
  event.stopPropagation();
@@ -225,6 +231,7 @@ function useZoomSensors(zoom, minZoom, maxZoom, disabled, zoomIn, zoomOut, chang
225
231
  }, [clearPointer]);
226
232
  const onPointerDown = useEventCallback((event) => {
227
233
  var _a;
234
+ const zoom = getZoom();
228
235
  const pointers = activePointers.current;
229
236
  if ((event.pointerType === "mouse" && event.buttons > 1) ||
230
237
  !((_a = zoomWrapperRef === null || zoomWrapperRef === void 0 ? void 0 : zoomWrapperRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target))) {
@@ -260,6 +267,7 @@ function useZoomSensors(zoom, minZoom, maxZoom, disabled, zoomIn, zoomOut, chang
260
267
  }
261
268
  });
262
269
  const onPointerMove = useEventCallback((event) => {
270
+ const zoom = getZoom();
263
271
  const pointers = activePointers.current;
264
272
  const activePointer = pointers.find((p) => p.pointerId === event.pointerId);
265
273
  if (pointers.length === 2 && pinchZoom.current) {
@@ -312,37 +320,46 @@ function useZoomState(imageRect, maxZoom, zoomWrapperRef) {
312
320
  const [zoom, setZoom] = React.useState(1);
313
321
  const [offsetX, setOffsetX] = React.useState(0);
314
322
  const [offsetY, setOffsetY] = React.useState(0);
323
+ const latest = React.useRef({ zoom, offsetX, offsetY });
315
324
  const animate = useZoomAnimation(zoom, offsetX, offsetY, zoomWrapperRef);
316
325
  const { currentSlide, globalIndex } = useLightboxState();
317
326
  const { containerRect, slideRect } = useController();
318
327
  const { minZoom, zoomInMultiplier } = useZoomProps();
319
328
  const currentSource = currentSlide && isImageSlide(currentSlide) ? currentSlide.src : undefined;
329
+ const rotation = useSlideRotation(currentSlide);
320
330
  const disabled = !(zoomWrapperRef === null || zoomWrapperRef === void 0 ? void 0 : zoomWrapperRef.current);
321
331
  useLayoutEffect(() => {
332
+ latest.current = { zoom: 1, offsetX: 0, offsetY: 0 };
322
333
  setZoom(1);
323
334
  setOffsetX(0);
324
335
  setOffsetY(0);
325
- }, [globalIndex, currentSource]);
336
+ }, [globalIndex, currentSource, rotation]);
326
337
  const changeOffsets = React.useCallback((dx, dy, targetZoom) => {
327
- const newZoom = targetZoom || zoom;
328
- const newOffsetX = offsetX - (dx || 0);
329
- const newOffsetY = offsetY - (dy || 0);
338
+ const newZoom = targetZoom || latest.current.zoom;
339
+ const newOffsetX = latest.current.offsetX - (dx || 0);
340
+ const newOffsetY = latest.current.offsetY - (dy || 0);
330
341
  const maxOffsetX = (imageRect.width * newZoom - slideRect.width) / 2 / newZoom;
331
342
  const maxOffsetY = (imageRect.height * newZoom - slideRect.height) / 2 / newZoom;
332
- setOffsetX(Math.min(Math.abs(newOffsetX), Math.max(maxOffsetX, 0)) * Math.sign(newOffsetX));
333
- setOffsetY(Math.min(Math.abs(newOffsetY), Math.max(maxOffsetY, 0)) * Math.sign(newOffsetY));
334
- }, [zoom, offsetX, offsetY, slideRect, imageRect.width, imageRect.height]);
343
+ latest.current.offsetX = Math.min(Math.abs(newOffsetX), Math.max(maxOffsetX, 0)) * Math.sign(newOffsetX);
344
+ latest.current.offsetY = Math.min(Math.abs(newOffsetY), Math.max(maxOffsetY, 0)) * Math.sign(newOffsetY);
345
+ setOffsetX(latest.current.offsetX);
346
+ setOffsetY(latest.current.offsetY);
347
+ }, [slideRect, imageRect.width, imageRect.height]);
335
348
  const changeZoom = React.useCallback((targetZoom, rapid, dx, dy) => {
336
349
  const newZoom = round(targetZoom + 0.01 < maxZoom ? (targetZoom - 0.01 > minZoom ? targetZoom : minZoom) : maxZoom, 5);
337
350
  if (!rapid) {
338
351
  animate();
339
352
  }
340
- changeOffsets(dx ? dx * (1 / zoom - 1 / newZoom) : 0, dy ? dy * (1 / zoom - 1 / newZoom) : 0, newZoom);
353
+ const { zoom: currentZoom } = latest.current;
354
+ changeOffsets(dx ? dx * (1 / currentZoom - 1 / newZoom) : 0, dy ? dy * (1 / currentZoom - 1 / newZoom) : 0, newZoom);
355
+ latest.current.zoom = newZoom;
341
356
  setZoom(newZoom);
342
- }, [zoom, minZoom, maxZoom, changeOffsets, animate]);
357
+ }, [minZoom, maxZoom, changeOffsets, animate]);
358
+ const getZoom = React.useCallback(() => latest.current.zoom, []);
343
359
  const handleControllerRectChange = useEventCallback(() => {
344
- if (zoom > 1) {
345
- if (zoom > maxZoom) {
360
+ const currentZoom = getZoom();
361
+ if (currentZoom > 1) {
362
+ if (currentZoom > maxZoom) {
346
363
  changeZoom(maxZoom, true);
347
364
  }
348
365
  changeOffsets();
@@ -350,14 +367,16 @@ function useZoomState(imageRect, maxZoom, zoomWrapperRef) {
350
367
  });
351
368
  useLayoutEffect(handleControllerRectChange, [containerRect.width, containerRect.height, handleControllerRectChange]);
352
369
  const zoomIn = React.useCallback(() => {
353
- const targetZoom = zoom * zoomInMultiplier;
354
- changeZoom(zoom < 1 && targetZoom > 1 ? 1 : targetZoom);
355
- }, [zoom, zoomInMultiplier, changeZoom]);
370
+ const currentZoom = getZoom();
371
+ const targetZoom = currentZoom * zoomInMultiplier;
372
+ changeZoom(currentZoom < 1 && targetZoom > 1 ? 1 : targetZoom);
373
+ }, [zoomInMultiplier, getZoom, changeZoom]);
356
374
  const zoomOut = React.useCallback(() => {
357
- const targetZoom = zoom / zoomInMultiplier;
358
- changeZoom(zoom > 1 && targetZoom < 1 ? 1 : targetZoom);
359
- }, [zoom, zoomInMultiplier, changeZoom]);
360
- return { zoom, offsetX, offsetY, disabled, changeOffsets, changeZoom, zoomIn, zoomOut };
375
+ const currentZoom = getZoom();
376
+ const targetZoom = currentZoom / zoomInMultiplier;
377
+ changeZoom(currentZoom > 1 && targetZoom < 1 ? 1 : targetZoom);
378
+ }, [zoomInMultiplier, getZoom, changeZoom]);
379
+ return { zoom, offsetX, offsetY, disabled, getZoom, changeOffsets, changeZoom, zoomIn, zoomOut };
361
380
  }
362
381
 
363
382
  const ZoomControllerContext = React.createContext(null);
@@ -367,9 +386,9 @@ function ZoomContextProvider({ children }) {
367
386
  const { slideRect } = useController();
368
387
  const { ref, minZoom } = useZoomProps();
369
388
  const { imageRect, maxZoom } = useZoomImageRect(slideRect, zoomWrapper === null || zoomWrapper === void 0 ? void 0 : zoomWrapper.imageDimensions);
370
- const { zoom, offsetX, offsetY, disabled, changeZoom, changeOffsets, zoomIn, zoomOut } = useZoomState(imageRect, maxZoom, zoomWrapper === null || zoomWrapper === void 0 ? void 0 : zoomWrapper.zoomWrapperRef);
389
+ const { zoom, offsetX, offsetY, disabled, getZoom, changeZoom, changeOffsets, zoomIn, zoomOut } = useZoomState(imageRect, maxZoom, zoomWrapper === null || zoomWrapper === void 0 ? void 0 : zoomWrapper.zoomWrapperRef);
371
390
  useZoomCallback(zoom, disabled);
372
- useZoomSensors(zoom, minZoom, maxZoom, disabled, zoomIn, zoomOut, changeZoom, changeOffsets, zoomWrapper === null || zoomWrapper === void 0 ? void 0 : zoomWrapper.zoomWrapperRef);
391
+ useZoomSensors(getZoom, minZoom, maxZoom, disabled, zoomIn, zoomOut, changeZoom, changeOffsets, zoomWrapper === null || zoomWrapper === void 0 ? void 0 : zoomWrapper.zoomWrapperRef);
373
392
  const zoomRef = React.useMemo(() => ({ zoom, minZoom, maxZoom, offsetX, offsetY, disabled, zoomIn, zoomOut, changeZoom }), [zoom, minZoom, maxZoom, offsetX, offsetY, disabled, zoomIn, zoomOut, changeZoom]);
374
393
  React.useImperativeHandle(ref, () => zoomRef, [zoomRef]);
375
394
  const context = React.useMemo(() => ({ ...zoomRef, setZoomWrapper }), [zoomRef, setZoomWrapper]);
@@ -453,13 +472,15 @@ function reducer({ current, preload }, { type, source }) {
453
472
  function ResponsiveImage(props) {
454
473
  var _a, _b;
455
474
  const [{ current, preload }, dispatch] = React.useReducer(reducer, {});
456
- const { slide: image, rect, imageFit, render, interactive } = props;
475
+ const { slide: image, rect, rotation = 0, imageFit, render, interactive, zoom = 1 } = props;
476
+ const rotated = rotation % 180 !== 0;
477
+ const imageRect = rotated ? { width: rect.height, height: rect.width } : rect;
457
478
  const srcSet = image.srcSet.sort((a, b) => a.width - b.width);
458
479
  const width = (_a = image.width) !== null && _a !== void 0 ? _a : srcSet[srcSet.length - 1].width;
459
480
  const height = (_b = image.height) !== null && _b !== void 0 ? _b : srcSet[srcSet.length - 1].height;
460
481
  const cover = isImageFitCover(image, imageFit);
461
482
  const maxWidth = Math.max(...srcSet.map((x) => x.width));
462
- const targetWidth = Math.min((cover ? Math.max : Math.min)(rect.width, width * (rect.height / height)), maxWidth);
483
+ const targetWidth = Math.min((cover ? Math.max : Math.min)(imageRect.width, width * (imageRect.height / height)) * zoom, maxWidth);
463
484
  const pixelDensity = devicePixelRatio();
464
485
  const handleResize = useEventCallback(() => {
465
486
  var _a;
@@ -468,13 +489,15 @@ function ResponsiveImage(props) {
468
489
  dispatch({ type: "fetch", source: targetSource.src });
469
490
  }
470
491
  });
471
- useLayoutEffect(handleResize, [rect.width, rect.height, pixelDensity, handleResize]);
492
+ useLayoutEffect(handleResize, [targetWidth, pixelDensity, handleResize]);
472
493
  const handlePreload = useEventCallback((currentPreload) => dispatch({ type: "done", source: currentPreload }));
473
494
  const style = {
474
495
  WebkitTransform: !interactive ? "translateZ(0)" : "initial",
475
496
  };
476
497
  if (!cover) {
477
- Object.assign(style, rect.width / rect.height < width / height ? { width: "100%", height: "auto" } : { width: "auto", height: "100%" });
498
+ Object.assign(style, imageRect.width / imageRect.height < width / height
499
+ ? { width: rotated ? `${imageRect.width}px` : "100%", height: "auto" }
500
+ : { width: "auto", height: rotated ? `${imageRect.height}px` : "100%" });
478
501
  }
479
502
  return (React.createElement(React.Fragment, null,
480
503
  preload && preload !== current && (React.createElement(ImageSlide, { key: "preload", ...props, offset: undefined, slide: { ...image, src: preload, srcSet: undefined }, style: { position: "absolute", visibility: "hidden", ...style }, onLoad: () => handlePreload(preload), render: {
@@ -490,6 +513,7 @@ function ZoomWrapper({ render, slide, offset, rect }) {
490
513
  const [imageDimensions, setImageDimensions] = React.useState();
491
514
  const zoomWrapperRef = React.useRef(null);
492
515
  const isImage = isImageSlide(slide);
516
+ const rotation = useSlideRotation(slide);
493
517
  const { zoom, maxZoom, offsetX, offsetY, setZoomWrapper } = useZoom();
494
518
  const interactive = zoom > 1;
495
519
  const { carousel, on } = useLightboxProps();
@@ -533,12 +557,13 @@ function ZoomWrapper({ render, slide, offset, rect }) {
533
557
  slide,
534
558
  offset,
535
559
  rect,
560
+ rotation,
536
561
  render,
537
562
  imageFit: carousel.imageFit,
538
563
  imageProps: carousel.imageProps,
539
564
  onClick: offset === 0 ? () => { var _a; return (_a = on.click) === null || _a === void 0 ? void 0 : _a.call(on, { index: currentIndex }); } : undefined,
540
565
  };
541
- rendered = isResponsiveImageSlide(slide) ? (React.createElement(ResponsiveImage, { ...slideProps, slide: slide, interactive: interactive, rect: offset === 0 ? { width: rect.width * zoom, height: rect.height * zoom } : rect })) : (React.createElement(ImageSlide, { onLoad: (img) => setImageDimensions({ width: img.naturalWidth, height: img.naturalHeight }), ...slideProps }));
566
+ rendered = isResponsiveImageSlide(slide) ? (React.createElement(ResponsiveImage, { ...slideProps, slide: slide, interactive: interactive, zoom: offset === 0 ? zoom : 1 })) : (React.createElement(ImageSlide, { onLoad: (img) => setImageDimensions({ width: img.naturalWidth, height: img.naturalHeight }), ...slideProps }));
542
567
  }
543
568
  if (!rendered)
544
569
  return null;
package/dist/styles.css CHANGED
@@ -1 +1 @@
1
- .yarl__fullsize{width:100%;height:100%}.yarl__relative{position:relative}.yarl__portal{position:fixed;top:0;right:0;bottom:0;left:0;opacity:0;overflow:hidden;z-index:var(--yarl__portal_zindex,9999);transition:opacity var(--yarl__fade_animation_duration,.25s) var(--yarl__fade_animation_timing_function,ease);pointer-events:auto}.yarl__portal_open{opacity:1}.yarl__container{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden;background-color:var(--yarl__container_background_color,var(--yarl__color_backdrop,#000));outline:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:var(--yarl__controller_touch_action,none);overscroll-behavior:var(--yarl__controller_overscroll_behavior,contain)}.yarl__carousel{display:flex;flex:0 0 auto;height:100%;align-content:center;justify-content:center;align-items:stretch;width:calc(100% + (var(--yarl__carousel_slides_count) - 1)*(100% + var(--yarl__carousel_spacing_px, 0)*1px + var(--yarl__carousel_spacing_percent, 0)*1%));transform:translate(var(--yarl__swipe_offset,0),var(--yarl__pull_offset,0));opacity:var(--yarl__pull_opacity,1)}.yarl__carousel_with_slides{-moz-column-gap:calc(var(--yarl__carousel_spacing_px, 0)*1px + 100/(var(--yarl__carousel_slides_count)*100 + (var(--yarl__carousel_slides_count) - 1)*var(--yarl__carousel_spacing_percent, 0))*var(--yarl__carousel_spacing_percent, 0)*1%);column-gap:calc(var(--yarl__carousel_spacing_px, 0)*1px + 100/(var(--yarl__carousel_slides_count)*100 + (var(--yarl__carousel_slides_count) - 1)*var(--yarl__carousel_spacing_percent, 0))*var(--yarl__carousel_spacing_percent, 0)*1%)}.yarl__flex_center{display:flex;justify-content:center;align-content:center;align-items:center}.yarl__slide{flex:1;position:relative;overflow:hidden;padding:calc(var(--yarl__carousel_padding_px, 0)*1px + 100/(var(--yarl__carousel_slides_count)*100 + (var(--yarl__carousel_slides_count) - 1)*var(--yarl__carousel_spacing_percent, 0))*var(--yarl__carousel_padding_percent, 0)*1%)}[dir=rtl] .yarl__slide{--yarl__direction:-1}.yarl__slide_image{max-width:100%;max-height:100%;-o-object-fit:contain;object-fit:contain;touch-action:var(--yarl__controller_touch_action,none);-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-touch-callout:none}.yarl__slide_image_cover{width:100%;height:100%;-o-object-fit:cover;object-fit:cover}.yarl__slide_image_loading{opacity:0}@media screen and (min-width:800px){.yarl__slide_wrapper:not(.yarl__slide_wrapper_interactive) .yarl__slide_image{-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;-webkit-transform-style:preserve-3d}}.yarl__slide_placeholder{position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);line-height:0}.yarl__slide_loading{color:var(--yarl__slide_icon_loading_color,var(--yarl__color_button,hsla(0,0%,100%,.8)));animation:yarl__delayed_fadein 1s linear}.yarl__slide_loading line{animation:yarl__stroke_opacity 1s linear infinite}.yarl__slide_loading line:first-of-type{animation-delay:-1.875s}.yarl__slide_loading line:nth-of-type(2){animation-delay:-1.75s}.yarl__slide_loading line:nth-of-type(3){animation-delay:-1.625s}.yarl__slide_loading line:nth-of-type(4){animation-delay:-1.5s}.yarl__slide_loading line:nth-of-type(5){animation-delay:-1.375s}.yarl__slide_loading line:nth-of-type(6){animation-delay:-1.25s}.yarl__slide_loading line:nth-of-type(7){animation-delay:-1.125s}.yarl__slide_loading line:nth-of-type(8){animation-delay:-1s}.yarl__slide_error{width:var(--yarl__slide_icon_error_size,48px);height:var(--yarl__slide_icon_error_size,48px);color:var(--yarl__slide_icon_error_color,red)}@media (prefers-reduced-motion){.yarl__portal,.yarl__slide{transition:unset}.yarl__slide_loading,.yarl__slide_loading line{animation:unset}}.yarl__toolbar{position:absolute;top:0;right:0;bottom:auto;left:auto;display:flex;justify-content:flex-end;padding:var(--yarl__toolbar_padding,8px)}[dir=rtl] .yarl__toolbar{top:0;right:auto;bottom:auto;left:0}.yarl__icon{width:var(--yarl__icon_size,32px);height:var(--yarl__icon_size,32px)}.yarl__button{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--yarl__button_background_color,transparent);border:var(--yarl__button_border,0);margin:var(--yarl__button_margin,0);outline:none;line-height:0;padding:var(--yarl__button_padding,8px);color:var(--yarl__color_button,hsla(0,0%,100%,.8));filter:var(--yarl__button_filter,drop-shadow(2px 2px 2px rgba(0,0,0,.8)));-webkit-tap-highlight-color:transparent}.yarl__button:focus{color:var(--yarl__color_button_active,#fff)}.yarl__button:focus:not(:focus-visible){color:var(--yarl__color_button,hsla(0,0%,100%,.8))}.yarl__button:focus-visible{color:var(--yarl__color_button_active,#fff)}@media (hover:hover){.yarl__button:focus-visible:hover,.yarl__button:focus:hover,.yarl__button:hover{color:var(--yarl__color_button_active,#fff)}}.yarl__button:disabled{color:var(--yarl__color_button_disabled,hsla(0,0%,100%,.4));cursor:default}.yarl__navigation_next,.yarl__navigation_prev{position:absolute;top:50%;transform:translateY(-50%);padding:var(--yarl__navigation_button_padding,24px 16px)}.yarl__navigation_prev{left:0}[dir=rtl] .yarl__navigation_prev{left:unset;right:0;transform:translateY(-50%) rotate(180deg)}.yarl__navigation_next{right:0}[dir=rtl] .yarl__navigation_next{left:0;right:unset;transform:translateY(-50%) rotate(180deg)}.yarl__no_scroll{height:100%;overflow:hidden;overscroll-behavior:none}@keyframes yarl__delayed_fadein{0%{opacity:0}80%{opacity:0}to{opacity:1}}@keyframes yarl__stroke_opacity{0%{stroke-opacity:1}to{stroke-opacity:.125}}
1
+ .yarl__fullsize{width:100%;height:100%}.yarl__relative{position:relative}.yarl__portal{position:fixed;top:0;right:0;bottom:0;left:0;opacity:0;overflow:hidden;z-index:var(--yarl__portal_zindex,9999);transition:opacity var(--yarl__fade_animation_duration,.25s) var(--yarl__fade_animation_timing_function,ease);pointer-events:auto}.yarl__portal_open{opacity:1}.yarl__container{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden;background-color:var(--yarl__container_background_color,var(--yarl__color_backdrop,#000));outline:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:var(--yarl__controller_touch_action,none);overscroll-behavior:var(--yarl__controller_overscroll_behavior,contain)}.yarl__carousel{display:flex;flex:0 0 auto;height:100%;align-content:center;justify-content:center;align-items:stretch;width:calc(100% + (-1 + var(--yarl__carousel_slides_count)) * (100% + var(--yarl__carousel_spacing_px,0) * 1px + var(--yarl__carousel_spacing_percent,0) * 1%));transform:translate(var(--yarl__swipe_offset,0),var(--yarl__pull_offset,0));opacity:var(--yarl__pull_opacity,1)}.yarl__carousel_with_slides{-moz-column-gap:calc(var(--yarl__carousel_spacing_px,0) * 1px + 100 / (100 * var(--yarl__carousel_slides_count) + (-1 + var(--yarl__carousel_slides_count)) * var(--yarl__carousel_spacing_percent,0)) * var(--yarl__carousel_spacing_percent,0) * 1%);column-gap:calc(var(--yarl__carousel_spacing_px,0) * 1px + 100 / (100 * var(--yarl__carousel_slides_count) + (-1 + var(--yarl__carousel_slides_count)) * var(--yarl__carousel_spacing_percent,0)) * var(--yarl__carousel_spacing_percent,0) * 1%)}.yarl__flex_center{display:flex;justify-content:center;align-content:center;align-items:center}.yarl__slide{flex:1;position:relative;overflow:hidden;padding:calc(var(--yarl__carousel_padding_px,0) * 1px + 100 / (100 * var(--yarl__carousel_slides_count) + (-1 + var(--yarl__carousel_slides_count)) * var(--yarl__carousel_spacing_percent,0)) * var(--yarl__carousel_padding_percent,0) * 1%)}[dir=rtl] .yarl__slide{--yarl__direction:-1}.yarl__slide_image{max-width:100%;max-height:100%;-o-object-fit:contain;object-fit:contain;touch-action:var(--yarl__controller_touch_action,none);-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-touch-callout:none}.yarl__slide_image_cover{width:100%;height:100%;-o-object-fit:cover;object-fit:cover}.yarl__slide_image_loading{opacity:0}@media screen and (min-width:800px){.yarl__slide_wrapper:not(.yarl__slide_wrapper_interactive) .yarl__slide_image{-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;-webkit-transform-style:preserve-3d}}.yarl__slide_placeholder{position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);line-height:0}.yarl__slide_loading{color:var(--yarl__slide_icon_loading_color,var(--yarl__color_button,hsla(0,0%,100%,.8)));animation:yarl__delayed_fadein 1s linear}.yarl__slide_loading line{animation:yarl__stroke_opacity 1s linear infinite}.yarl__slide_loading line:first-of-type{animation-delay:-1.875s}.yarl__slide_loading line:nth-of-type(2){animation-delay:-1.75s}.yarl__slide_loading line:nth-of-type(3){animation-delay:-1.625s}.yarl__slide_loading line:nth-of-type(4){animation-delay:-1.5s}.yarl__slide_loading line:nth-of-type(5){animation-delay:-1.375s}.yarl__slide_loading line:nth-of-type(6){animation-delay:-1.25s}.yarl__slide_loading line:nth-of-type(7){animation-delay:-1.125s}.yarl__slide_loading line:nth-of-type(8){animation-delay:-1s}.yarl__slide_error{width:var(--yarl__slide_icon_error_size,48px);height:var(--yarl__slide_icon_error_size,48px);color:var(--yarl__slide_icon_error_color,red)}@media(prefers-reduced-motion){.yarl__portal,.yarl__slide{transition:unset}.yarl__slide_loading,.yarl__slide_loading line{animation:unset}}.yarl__toolbar{position:absolute;top:0;right:0;bottom:auto;left:auto;display:flex;justify-content:flex-end;padding:var(--yarl__toolbar_padding,8px)}[dir=rtl] .yarl__toolbar{top:0;right:auto;bottom:auto;left:0}.yarl__icon{width:var(--yarl__icon_size,32px);height:var(--yarl__icon_size,32px)}.yarl__button{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--yarl__button_background_color,transparent);border:var(--yarl__button_border,0);margin:var(--yarl__button_margin,0);outline:none;line-height:0;padding:var(--yarl__button_padding,8px);color:var(--yarl__color_button,hsla(0,0%,100%,.8));filter:var(--yarl__button_filter,drop-shadow(2px 2px 2px rgba(0,0,0,.8)));-webkit-tap-highlight-color:transparent}.yarl__button:focus{color:var(--yarl__color_button_active,#fff)}.yarl__button:focus:not(:focus-visible){color:var(--yarl__color_button,hsla(0,0%,100%,.8))}.yarl__button:focus-visible{color:var(--yarl__color_button_active,#fff)}@media(hover:hover){.yarl__button:focus-visible:hover,.yarl__button:focus:hover,.yarl__button:hover{color:var(--yarl__color_button_active,#fff)}}.yarl__button:disabled{color:var(--yarl__color_button_disabled,hsla(0,0%,100%,.4));cursor:default}.yarl__navigation_next,.yarl__navigation_prev{position:absolute;top:50%;transform:translateY(-50%);padding:var(--yarl__navigation_button_padding,24px 16px)}.yarl__navigation_prev{left:0}[dir=rtl] .yarl__navigation_prev{left:unset;right:0;transform:translateY(-50%) rotate(180deg)}.yarl__navigation_next{right:0}[dir=rtl] .yarl__navigation_next{left:0;right:unset;transform:translateY(-50%) rotate(180deg)}.yarl__no_scroll{height:100%;overflow:hidden;overscroll-behavior:none}@keyframes yarl__delayed_fadein{0%{opacity:0}80%{opacity:0}to{opacity:1}}@keyframes yarl__stroke_opacity{0%{stroke-opacity:1}to{stroke-opacity:.125}}
package/dist/types.d.ts CHANGED
@@ -12,6 +12,7 @@ declare const PLUGIN_COUNTER = "counter";
12
12
  declare const PLUGIN_DOWNLOAD = "download";
13
13
  declare const PLUGIN_FULLSCREEN = "fullscreen";
14
14
  declare const PLUGIN_INLINE = "inline";
15
+ declare const PLUGIN_ROTATE = "rotate";
15
16
  declare const PLUGIN_SHARE = "share";
16
17
  declare const PLUGIN_SLIDESHOW = "slideshow";
17
18
  declare const PLUGIN_THUMBNAILS = "thumbnails";
@@ -459,5 +460,5 @@ type DeepPartialValue<T, E extends string = never> = T extends readonly any[] ?
459
460
  [P in keyof T]?: P extends E ? T[P] : DeepPartialValue<T[P], E>;
460
461
  } : T;
461
462
 
462
- export { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, ACTIVE_SLIDE_COMPLETE, ACTIVE_SLIDE_ERROR, ACTIVE_SLIDE_LOADING, ACTIVE_SLIDE_PLAYING, CLASS_FLEX_CENTER, CLASS_FULLSIZE, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, CLASS_SLIDE, CLASS_SLIDE_WRAPPER, CLASS_SLIDE_WRAPPER_INTERACTIVE, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_KEY_DOWN, EVENT_ON_KEY_UP, EVENT_ON_POINTER_CANCEL, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_WHEEL, IMAGE_FIT_CONTAIN, IMAGE_FIT_COVER, MODULE_CAROUSEL, MODULE_CONTROLLER, MODULE_NAVIGATION, MODULE_NO_SCROLL, MODULE_PORTAL, MODULE_ROOT, MODULE_TOOLBAR, PLUGIN_CAPTIONS, PLUGIN_COUNTER, PLUGIN_DOWNLOAD, PLUGIN_FULLSCREEN, PLUGIN_INLINE, PLUGIN_SHARE, PLUGIN_SLIDESHOW, PLUGIN_THUMBNAILS, PLUGIN_ZOOM, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_LOADING, SLIDE_STATUS_PLACEHOLDER, SLIDE_STATUS_PLAYING, UNKNOWN_ACTION_TYPE, VK_ARROW_LEFT, VK_ARROW_RIGHT, VK_ESCAPE, activeSlideStatus };
463
+ export { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, ACTIVE_SLIDE_COMPLETE, ACTIVE_SLIDE_ERROR, ACTIVE_SLIDE_LOADING, ACTIVE_SLIDE_PLAYING, CLASS_FLEX_CENTER, CLASS_FULLSIZE, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, CLASS_SLIDE, CLASS_SLIDE_WRAPPER, CLASS_SLIDE_WRAPPER_INTERACTIVE, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_KEY_DOWN, EVENT_ON_KEY_UP, EVENT_ON_POINTER_CANCEL, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_WHEEL, IMAGE_FIT_CONTAIN, IMAGE_FIT_COVER, MODULE_CAROUSEL, MODULE_CONTROLLER, MODULE_NAVIGATION, MODULE_NO_SCROLL, MODULE_PORTAL, MODULE_ROOT, MODULE_TOOLBAR, PLUGIN_CAPTIONS, PLUGIN_COUNTER, PLUGIN_DOWNLOAD, PLUGIN_FULLSCREEN, PLUGIN_INLINE, PLUGIN_ROTATE, PLUGIN_SHARE, PLUGIN_SLIDESHOW, PLUGIN_THUMBNAILS, PLUGIN_ZOOM, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_LOADING, SLIDE_STATUS_PLACEHOLDER, SLIDE_STATUS_PLAYING, UNKNOWN_ACTION_TYPE, VK_ARROW_LEFT, VK_ARROW_RIGHT, VK_ESCAPE, activeSlideStatus };
463
464
  export type { AnimationSettings, Augmentation, Callback, Callbacks, CarouselSettings, ClickCallbackProps, Component, ComponentProps, ContainerRect, ControllerRef, ControllerSettings, DeepPartial, DeepPartialValue, EventTypes, GenericSlide, ImageFit, ImageProps, ImageSource, Label, Labels, LengthOrPercentage, LightboxExternalProps, LightboxProps, LightboxState, LightboxStateSwipeAction, LightboxStateUpdateAction, Module, NavigationAction, NoScrollSettings, Node, Plugin, PluginProps, PortalSettings, Render, RenderFunction, RenderSlideContainerProps, RenderSlideFooterProps, RenderSlideHeaderProps, RenderSlideProps, Slide, SlideImage, SlideStatus, SlideTypeKey, SlideTypes, Slot, SlotStyles, SlotType, ToolbarButtonKey, ToolbarButtonKeys, ToolbarSettings, ViewCallbackProps };
package/dist/types.js CHANGED
@@ -10,6 +10,7 @@ const PLUGIN_COUNTER = "counter";
10
10
  const PLUGIN_DOWNLOAD = "download";
11
11
  const PLUGIN_FULLSCREEN = "fullscreen";
12
12
  const PLUGIN_INLINE = "inline";
13
+ const PLUGIN_ROTATE = "rotate";
13
14
  const PLUGIN_SHARE = "share";
14
15
  const PLUGIN_SLIDESHOW = "slideshow";
15
16
  const PLUGIN_THUMBNAILS = "thumbnails";
@@ -52,4 +53,4 @@ const IMAGE_FIT_CONTAIN = "contain";
52
53
  const IMAGE_FIT_COVER = "cover";
53
54
  const UNKNOWN_ACTION_TYPE = "Unknown action type";
54
55
 
55
- export { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, ACTIVE_SLIDE_COMPLETE, ACTIVE_SLIDE_ERROR, ACTIVE_SLIDE_LOADING, ACTIVE_SLIDE_PLAYING, CLASS_FLEX_CENTER, CLASS_FULLSIZE, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, CLASS_SLIDE, CLASS_SLIDE_WRAPPER, CLASS_SLIDE_WRAPPER_INTERACTIVE, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_KEY_DOWN, EVENT_ON_KEY_UP, EVENT_ON_POINTER_CANCEL, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_WHEEL, IMAGE_FIT_CONTAIN, IMAGE_FIT_COVER, MODULE_CAROUSEL, MODULE_CONTROLLER, MODULE_NAVIGATION, MODULE_NO_SCROLL, MODULE_PORTAL, MODULE_ROOT, MODULE_TOOLBAR, PLUGIN_CAPTIONS, PLUGIN_COUNTER, PLUGIN_DOWNLOAD, PLUGIN_FULLSCREEN, PLUGIN_INLINE, PLUGIN_SHARE, PLUGIN_SLIDESHOW, PLUGIN_THUMBNAILS, PLUGIN_ZOOM, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_LOADING, SLIDE_STATUS_PLACEHOLDER, SLIDE_STATUS_PLAYING, UNKNOWN_ACTION_TYPE, VK_ARROW_LEFT, VK_ARROW_RIGHT, VK_ESCAPE, activeSlideStatus };
56
+ export { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, ACTIVE_SLIDE_COMPLETE, ACTIVE_SLIDE_ERROR, ACTIVE_SLIDE_LOADING, ACTIVE_SLIDE_PLAYING, CLASS_FLEX_CENTER, CLASS_FULLSIZE, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, CLASS_SLIDE, CLASS_SLIDE_WRAPPER, CLASS_SLIDE_WRAPPER_INTERACTIVE, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_KEY_DOWN, EVENT_ON_KEY_UP, EVENT_ON_POINTER_CANCEL, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_WHEEL, IMAGE_FIT_CONTAIN, IMAGE_FIT_COVER, MODULE_CAROUSEL, MODULE_CONTROLLER, MODULE_NAVIGATION, MODULE_NO_SCROLL, MODULE_PORTAL, MODULE_ROOT, MODULE_TOOLBAR, PLUGIN_CAPTIONS, PLUGIN_COUNTER, PLUGIN_DOWNLOAD, PLUGIN_FULLSCREEN, PLUGIN_INLINE, PLUGIN_ROTATE, PLUGIN_SHARE, PLUGIN_SLIDESHOW, PLUGIN_THUMBNAILS, PLUGIN_ZOOM, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_LOADING, SLIDE_STATUS_PLACEHOLDER, SLIDE_STATUS_PLAYING, UNKNOWN_ACTION_TYPE, VK_ARROW_LEFT, VK_ARROW_RIGHT, VK_ESCAPE, activeSlideStatus };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yet-another-react-lightbox",
3
- "version": "3.32.2",
3
+ "version": "3.33.0",
4
4
  "description": "Modern React lightbox component",
5
5
  "repository": "github:igordanchenko/yet-another-react-lightbox",
6
6
  "homepage": "https://yet-another-react-lightbox.com",
@@ -44,6 +44,10 @@
44
44
  "types": "./dist/plugins/inline/index.d.ts",
45
45
  "default": "./dist/plugins/inline/index.js"
46
46
  },
47
+ "./plugins/rotate": {
48
+ "types": "./dist/plugins/rotate/index.d.ts",
49
+ "default": "./dist/plugins/rotate/index.js"
50
+ },
47
51
  "./plugins/share": {
48
52
  "types": "./dist/plugins/share/index.d.ts",
49
53
  "default": "./dist/plugins/share/index.js"
@@ -95,6 +99,9 @@
95
99
  "plugins/inline": [
96
100
  "dist/plugins/inline/index.d.ts"
97
101
  ],
102
+ "plugins/rotate": [
103
+ "dist/plugins/rotate/index.d.ts"
104
+ ],
98
105
  "plugins/share": [
99
106
  "dist/plugins/share/index.d.ts"
100
107
  ],
@@ -144,5 +151,5 @@
144
151
  "react image lightbox",
145
152
  "react photo lightbox"
146
153
  ],
147
- "bundleSize": "10.6 kB"
154
+ "bundleSize": "11 kB"
148
155
  }