yet-another-react-lightbox 3.15.5 → 3.16.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.d.ts CHANGED
@@ -19,6 +19,7 @@ declare const hasWindow: () => boolean;
19
19
  declare function round(value: number, decimals?: number): number;
20
20
  declare const isImageSlide: (slide: Slide) => slide is SlideImage;
21
21
  declare const isImageFitCover: (image: SlideImage, imageFit?: LightboxProps["carousel"]["imageFit"]) => boolean;
22
+ declare function parseInt(value: string | number): number;
22
23
  declare function parseLengthPercentage(input: LengthOrPercentage): {
23
24
  pixel: number;
24
25
  percent?: undefined;
@@ -201,11 +202,11 @@ declare const CarouselModule: Module;
201
202
  declare enum SwipeState {
202
203
  NONE = 0,
203
204
  SWIPE = 1,
204
- PULL_DOWN = 2,
205
+ PULL = 2,
205
206
  ANIMATION = 3
206
207
  }
207
208
 
208
- declare function usePointerSwipe<T extends Element = Element>(subscribeSensors: UseSensors<T>["subscribeSensors"], isSwipeValid: (offset: number) => boolean, containerWidth: number, swipeAnimationDuration: number, onSwipeStart: () => void, onSwipeProgress: (offset: number) => void, onSwipeFinish: (offset: number, duration: number) => void, onSwipeCancel: (offset: number) => void, pullDownEnabled: boolean, onPullDownStart: () => void, onPullDownProgress: (offset: number) => void, onPullDownFinish: (offset: number, duration: number) => void, onPullDownCancel: (offset: number) => void): void;
209
+ declare function usePointerSwipe<T extends Element = Element>(subscribeSensors: UseSensors<T>["subscribeSensors"], isSwipeValid: (offset: number) => boolean, containerWidth: number, swipeAnimationDuration: number, onSwipeStart: () => void, onSwipeProgress: (offset: number) => void, onSwipeFinish: (offset: number, duration: number) => void, onSwipeCancel: (offset: number) => void, pullUpEnabled: boolean, pullDownEnabled: boolean, onPullStart: () => void, onPullProgress: (offset: number) => void, onPullFinish: (offset: number, duration: number) => void, onPullCancel: (offset: number) => void): void;
209
210
 
210
211
  /** prevent browser back/forward navigation on touchpad left/right swipe (especially noticeable in Safari)
211
212
  * this has to be done via non-passive native event handler */
@@ -260,4 +261,4 @@ declare const RootModule: Module;
260
261
  declare function Toolbar({ toolbar: { buttons }, render: { buttonClose, iconClose }, styles }: ComponentProps): React.JSX.Element;
261
262
  declare const ToolbarModule: Module;
262
263
 
263
- export { Augmentation, Callback, Carousel, CarouselModule, CarouselSettings, CloseIcon, Component, ComponentProps, type ComputeAnimation, ContainerRect, Controller, ControllerContext, type ControllerContextType, ControllerModule, ControllerRef, ErrorIcon, type Event, type EventCallback, EventTypes, EventsContext, type EventsContextType, EventsProvider, IconButton, type IconButtonProps, ImageSlide, type ImageSlideProps, type KeyboardEventType, Labels, LengthOrPercentage, Lightbox, LightboxDefaultProps, LightboxDispatchContext, type LightboxDispatchContextType, LightboxExternalProps, LightboxProps, LightboxPropsContext, type LightboxPropsContextType, LightboxPropsProvider, LightboxState, type LightboxStateAction, LightboxStateContext, type LightboxStateContextType, LightboxStateProvider, type LightboxStateProviderProps, LightboxStateSwipeAction, LightboxStateUpdateAction, LoadingIcon, Module, Navigation, NavigationButton, type NavigationButtonProps, NavigationModule, NextIcon, NoScroll, NoScrollModule, Node, Plugin, type PointerEventType, Portal, PortalModule, PreviousIcon, type Publish, type ReactEventType, type RegisterSensors, Render, RenderFunction, Root, RootModule, type SensorCallback, Slide, SlideImage, type Subscribe, type SubscribeSensors, type SupportedEventType, SwipeState, TimeoutsContext, type TimeoutsContextType, TimeoutsProvider, Toolbar, ToolbarModule, ToolbarSettings, type Topic, type Unsubscribe, type UseSensors, type WheelEventType, addToolbarButton, calculatePreload, cleanup, clsx, composePrefix, computeSlideRect, createIcon, createIconDisabled, createModule, createNode, cssClass, cssVar, Lightbox as default, devicePixelRatio, getSlide, getSlideIfPresent, getSlideIndex, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeUseContext, parseLengthPercentage, round, setRef, stopNavigationEventsPropagation, useAnimation, useContainerRect, useController, useDelay, useEventCallback, useEvents, useForkRef, useKeyboardNavigation, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useNavigationState, usePointerSwipe, usePreventSwipeNavigation, useRTL, useSensors, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
264
+ export { Augmentation, Callback, Carousel, CarouselModule, CarouselSettings, CloseIcon, Component, ComponentProps, type ComputeAnimation, ContainerRect, Controller, ControllerContext, type ControllerContextType, ControllerModule, ControllerRef, ErrorIcon, type Event, type EventCallback, EventTypes, EventsContext, type EventsContextType, EventsProvider, IconButton, type IconButtonProps, ImageSlide, type ImageSlideProps, type KeyboardEventType, Labels, LengthOrPercentage, Lightbox, LightboxDefaultProps, LightboxDispatchContext, type LightboxDispatchContextType, LightboxExternalProps, LightboxProps, LightboxPropsContext, type LightboxPropsContextType, LightboxPropsProvider, LightboxState, type LightboxStateAction, LightboxStateContext, type LightboxStateContextType, LightboxStateProvider, type LightboxStateProviderProps, LightboxStateSwipeAction, LightboxStateUpdateAction, LoadingIcon, Module, Navigation, NavigationButton, type NavigationButtonProps, NavigationModule, NextIcon, NoScroll, NoScrollModule, Node, Plugin, type PointerEventType, Portal, PortalModule, PreviousIcon, type Publish, type ReactEventType, type RegisterSensors, Render, RenderFunction, Root, RootModule, type SensorCallback, Slide, SlideImage, type Subscribe, type SubscribeSensors, type SupportedEventType, SwipeState, TimeoutsContext, type TimeoutsContextType, TimeoutsProvider, Toolbar, ToolbarModule, ToolbarSettings, type Topic, type Unsubscribe, type UseSensors, type WheelEventType, addToolbarButton, calculatePreload, cleanup, clsx, composePrefix, computeSlideRect, createIcon, createIconDisabled, createModule, createNode, cssClass, cssVar, Lightbox as default, devicePixelRatio, getSlide, getSlideIfPresent, getSlideIndex, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeUseContext, parseInt, parseLengthPercentage, round, setRef, stopNavigationEventsPropagation, useAnimation, useContainerRect, useController, useDelay, useEventCallback, useEvents, useForkRef, useKeyboardNavigation, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useNavigationState, usePointerSwipe, usePreventSwipeNavigation, useRTL, useSensors, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
package/dist/index.js CHANGED
@@ -1,9 +1,84 @@
1
1
  'use client';
2
2
  import * as React from 'react';
3
- import { ACTION_CLOSE, IMAGE_FIT_CONTAIN, MODULE_CONTROLLER, IMAGE_FIT_COVER, UNKNOWN_ACTION_TYPE, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_CANCEL, EVENT_ON_KEY_DOWN, EVENT_ON_KEY_UP, EVENT_ON_WHEEL, SLIDE_STATUS_LOADING, activeSlideStatus, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_PLACEHOLDER, ACTION_PREV, ACTION_NEXT, ACTION_SWIPE, MODULE_PORTAL, CLASS_FLEX_CENTER, MODULE_CAROUSEL, CLASS_SLIDE_WRAPPER, 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';
3
+ import { IMAGE_FIT_COVER, IMAGE_FIT_CONTAIN, ACTION_CLOSE, MODULE_CONTROLLER, UNKNOWN_ACTION_TYPE, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_CANCEL, EVENT_ON_KEY_DOWN, EVENT_ON_KEY_UP, EVENT_ON_WHEEL, SLIDE_STATUS_LOADING, activeSlideStatus, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_PLACEHOLDER, ACTION_PREV, ACTION_NEXT, ACTION_SWIPE, MODULE_PORTAL, CLASS_FLEX_CENTER, MODULE_CAROUSEL, CLASS_SLIDE_WRAPPER, 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
5
  export { ACTIVE_SLIDE_COMPLETE, ACTIVE_SLIDE_ERROR, ACTIVE_SLIDE_LOADING, ACTIVE_SLIDE_PLAYING, CLASS_FULLSIZE, PLUGIN_CAPTIONS, PLUGIN_COUNTER, PLUGIN_DOWNLOAD, PLUGIN_FULLSCREEN, PLUGIN_INLINE, PLUGIN_SHARE, PLUGIN_SLIDESHOW, PLUGIN_THUMBNAILS, PLUGIN_ZOOM, SLIDE_STATUS_PLAYING } from './types.js';
6
6
 
7
+ const clsx = (...classes) => [...classes].filter((cls) => Boolean(cls)).join(" ");
8
+ const cssPrefix$3 = "yarl__";
9
+ const cssClass = (name) => `${cssPrefix$3}${name}`;
10
+ const cssVar = (name) => `--${cssPrefix$3}${name}`;
11
+ const composePrefix = (base, prefix) => `${base}${prefix ? `_${prefix}` : ""}`;
12
+ const makeComposePrefix = (base) => (prefix) => composePrefix(base, prefix);
13
+ const label = (labels, lbl) => (labels && labels[lbl] ? labels[lbl] : lbl);
14
+ const cleanup = (...cleaners) => () => {
15
+ cleaners.forEach((cleaner) => {
16
+ cleaner();
17
+ });
18
+ };
19
+ const makeUseContext = (name, contextName, context) => () => {
20
+ const ctx = React.useContext(context);
21
+ if (!ctx) {
22
+ throw new Error(`${name} must be used within a ${contextName}.Provider`);
23
+ }
24
+ return ctx;
25
+ };
26
+ const hasWindow = () => typeof window !== "undefined";
27
+ function round(value, decimals = 0) {
28
+ const factor = 10 ** decimals;
29
+ return Math.round((value + Number.EPSILON) * factor) / factor;
30
+ }
31
+ const isImageSlide = (slide) => slide.type === undefined || slide.type === "image";
32
+ const isImageFitCover = (image, imageFit) => image.imageFit === IMAGE_FIT_COVER || (image.imageFit !== IMAGE_FIT_CONTAIN && imageFit === IMAGE_FIT_COVER);
33
+ function parseInt(value) {
34
+ return typeof value === "string" ? Number.parseInt(value, 10) : value;
35
+ }
36
+ function parseLengthPercentage(input) {
37
+ if (typeof input === "number") {
38
+ return { pixel: input };
39
+ }
40
+ if (typeof input === "string") {
41
+ const value = parseInt(input);
42
+ return input.endsWith("%") ? { percent: value } : { pixel: value };
43
+ }
44
+ return { pixel: 0 };
45
+ }
46
+ function computeSlideRect(containerRect, padding) {
47
+ const paddingValue = parseLengthPercentage(padding);
48
+ const paddingPixels = paddingValue.percent !== undefined ? (containerRect.width / 100) * paddingValue.percent : paddingValue.pixel;
49
+ return {
50
+ width: Math.max(containerRect.width - 2 * paddingPixels, 0),
51
+ height: Math.max(containerRect.height - 2 * paddingPixels, 0),
52
+ };
53
+ }
54
+ const devicePixelRatio = () => (hasWindow() ? window === null || window === void 0 ? void 0 : window.devicePixelRatio : undefined) || 1;
55
+ const getSlideIndex = (index, slidesCount) => slidesCount > 0 ? ((index % slidesCount) + slidesCount) % slidesCount : 0;
56
+ const hasSlides = (slides) => slides.length > 0;
57
+ const getSlide = (slides, index) => slides[getSlideIndex(index, slides.length)];
58
+ const getSlideIfPresent = (slides, index) => hasSlides(slides) ? getSlide(slides, index) : undefined;
59
+ function addToolbarButton(toolbar, key, button) {
60
+ if (!button)
61
+ return toolbar;
62
+ const { buttons, ...restToolbar } = toolbar;
63
+ const index = buttons.findIndex((item) => item === key);
64
+ const buttonWithKey = React.isValidElement(button) ? React.cloneElement(button, { key }, null) : button;
65
+ if (index >= 0) {
66
+ const result = [...buttons];
67
+ result.splice(index, 1, buttonWithKey);
68
+ return { buttons: result, ...restToolbar };
69
+ }
70
+ return { buttons: [buttonWithKey, ...buttons], ...restToolbar };
71
+ }
72
+ function stopNavigationEventsPropagation() {
73
+ const stopPropagation = (event) => {
74
+ event.stopPropagation();
75
+ };
76
+ return { onPointerDown: stopPropagation, onKeyDown: stopPropagation, onWheel: stopPropagation };
77
+ }
78
+ function calculatePreload(carousel, slides, minimum = 0) {
79
+ return Math.min(carousel.preload, Math.max(carousel.finite ? slides.length - 1 : Math.floor(slides.length / 2), minimum));
80
+ }
81
+
7
82
  const LightboxDefaultProps = {
8
83
  open: false,
9
84
  close: () => { },
@@ -35,6 +110,7 @@ const LightboxDefaultProps = {
35
110
  focus: true,
36
111
  aria: false,
37
112
  touchAction: "none",
113
+ closeOnPullUp: false,
38
114
  closeOnPullDown: false,
39
115
  closeOnBackdropClick: false,
40
116
  },
@@ -140,78 +216,6 @@ function withPlugins(root, plugins = [], augmentations = []) {
140
216
  };
141
217
  }
142
218
 
143
- const clsx = (...classes) => [...classes].filter((cls) => Boolean(cls)).join(" ");
144
- const cssPrefix$3 = "yarl__";
145
- const cssClass = (name) => `${cssPrefix$3}${name}`;
146
- const cssVar = (name) => `--${cssPrefix$3}${name}`;
147
- const composePrefix = (base, prefix) => `${base}${prefix ? `_${prefix}` : ""}`;
148
- const makeComposePrefix = (base) => (prefix) => composePrefix(base, prefix);
149
- const label = (labels, lbl) => (labels && labels[lbl] ? labels[lbl] : lbl);
150
- const cleanup = (...cleaners) => () => {
151
- cleaners.forEach((cleaner) => {
152
- cleaner();
153
- });
154
- };
155
- const makeUseContext = (name, contextName, context) => () => {
156
- const ctx = React.useContext(context);
157
- if (!ctx) {
158
- throw new Error(`${name} must be used within a ${contextName}.Provider`);
159
- }
160
- return ctx;
161
- };
162
- const hasWindow = () => typeof window !== "undefined";
163
- function round(value, decimals = 0) {
164
- const factor = 10 ** decimals;
165
- return Math.round((value + Number.EPSILON) * factor) / factor;
166
- }
167
- const isImageSlide = (slide) => slide.type === undefined || slide.type === "image";
168
- const isImageFitCover = (image, imageFit) => image.imageFit === IMAGE_FIT_COVER || (image.imageFit !== IMAGE_FIT_CONTAIN && imageFit === IMAGE_FIT_COVER);
169
- function parseLengthPercentage(input) {
170
- if (typeof input === "number") {
171
- return { pixel: input };
172
- }
173
- if (typeof input === "string") {
174
- const value = parseInt(input, 10);
175
- return input.endsWith("%") ? { percent: value } : { pixel: value };
176
- }
177
- return { pixel: 0 };
178
- }
179
- function computeSlideRect(containerRect, padding) {
180
- const paddingValue = parseLengthPercentage(padding);
181
- const paddingPixels = paddingValue.percent !== undefined ? (containerRect.width / 100) * paddingValue.percent : paddingValue.pixel;
182
- return {
183
- width: Math.max(containerRect.width - 2 * paddingPixels, 0),
184
- height: Math.max(containerRect.height - 2 * paddingPixels, 0),
185
- };
186
- }
187
- const devicePixelRatio = () => (hasWindow() ? window === null || window === void 0 ? void 0 : window.devicePixelRatio : undefined) || 1;
188
- const getSlideIndex = (index, slidesCount) => slidesCount > 0 ? ((index % slidesCount) + slidesCount) % slidesCount : 0;
189
- const hasSlides = (slides) => slides.length > 0;
190
- const getSlide = (slides, index) => slides[getSlideIndex(index, slides.length)];
191
- const getSlideIfPresent = (slides, index) => hasSlides(slides) ? getSlide(slides, index) : undefined;
192
- function addToolbarButton(toolbar, key, button) {
193
- if (!button)
194
- return toolbar;
195
- const { buttons, ...restToolbar } = toolbar;
196
- const index = buttons.findIndex((item) => item === key);
197
- const buttonWithKey = React.isValidElement(button) ? React.cloneElement(button, { key }, null) : button;
198
- if (index >= 0) {
199
- const result = [...buttons];
200
- result.splice(index, 1, buttonWithKey);
201
- return { buttons: result, ...restToolbar };
202
- }
203
- return { buttons: [buttonWithKey, ...buttons], ...restToolbar };
204
- }
205
- function stopNavigationEventsPropagation() {
206
- const stopPropagation = (event) => {
207
- event.stopPropagation();
208
- };
209
- return { onPointerDown: stopPropagation, onKeyDown: stopPropagation, onWheel: stopPropagation };
210
- }
211
- function calculatePreload(carousel, slides, minimum = 0) {
212
- return Math.min(carousel.preload, Math.max(carousel.finite ? slides.length - 1 : Math.floor(slides.length / 2), minimum));
213
- }
214
-
215
219
  const EventsContext = React.createContext(null);
216
220
  const useEvents = makeUseContext("useEvents", "EventsContext", EventsContext);
217
221
  function EventsProvider({ children }) {
@@ -381,7 +385,7 @@ function currentTransformation(node) {
381
385
  const matrix = window.getComputedStyle(node).transform;
382
386
  const matcher = matrix.match(/matrix.*\((.+)\)/);
383
387
  if (matcher) {
384
- const values = matcher[1].split(",").map((str) => Number.parseInt(str, 10));
388
+ const values = matcher[1].split(",").map(parseInt);
385
389
  if (values.length === 6) {
386
390
  x = values[4];
387
391
  y = values[5];
@@ -636,7 +640,7 @@ var SwipeState;
636
640
  (function (SwipeState) {
637
641
  SwipeState[SwipeState["NONE"] = 0] = "NONE";
638
642
  SwipeState[SwipeState["SWIPE"] = 1] = "SWIPE";
639
- SwipeState[SwipeState["PULL_DOWN"] = 2] = "PULL_DOWN";
643
+ SwipeState[SwipeState["PULL"] = 2] = "PULL";
640
644
  SwipeState[SwipeState["ANIMATION"] = 3] = "ANIMATION";
641
645
  })(SwipeState || (SwipeState = {}));
642
646
 
@@ -650,10 +654,10 @@ var Gesture;
650
654
  (function (Gesture) {
651
655
  Gesture[Gesture["NONE"] = 0] = "NONE";
652
656
  Gesture[Gesture["SWIPE"] = 1] = "SWIPE";
653
- Gesture[Gesture["PULL_DOWN"] = 2] = "PULL_DOWN";
657
+ Gesture[Gesture["PULL"] = 2] = "PULL";
654
658
  })(Gesture || (Gesture = {}));
655
659
  const SWIPE_THRESHOLD = 30;
656
- function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAnimationDuration, onSwipeStart, onSwipeProgress, onSwipeFinish, onSwipeCancel, pullDownEnabled, onPullDownStart, onPullDownProgress, onPullDownFinish, onPullDownCancel) {
660
+ function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAnimationDuration, onSwipeStart, onSwipeProgress, onSwipeFinish, onSwipeCancel, pullUpEnabled, pullDownEnabled, onPullStart, onPullProgress, onPullFinish, onPullCancel) {
657
661
  const offset = React.useRef(0);
658
662
  const pointers = React.useRef([]);
659
663
  const activePointer = React.useRef();
@@ -675,6 +679,7 @@ function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAn
675
679
  const onPointerDown = useEventCallback((event) => {
676
680
  addPointer(event);
677
681
  });
682
+ const exceedsPullThreshold = (value, threshold) => (pullDownEnabled && value > threshold) || (pullUpEnabled && value < -threshold);
678
683
  const onPointerUp = useEventCallback((event) => {
679
684
  if (pointers.current.find((x) => x.pointerId === event.pointerId) && activePointer.current === event.pointerId) {
680
685
  const duration = Date.now() - startTime.current;
@@ -688,12 +693,12 @@ function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAn
688
693
  onSwipeCancel(currentOffset);
689
694
  }
690
695
  }
691
- else if (gesture.current === Gesture.PULL_DOWN) {
692
- if (currentOffset > 2 * SWIPE_THRESHOLD) {
693
- onPullDownFinish(currentOffset, duration);
696
+ else if (gesture.current === Gesture.PULL) {
697
+ if (exceedsPullThreshold(currentOffset, 2 * SWIPE_THRESHOLD)) {
698
+ onPullFinish(currentOffset, duration);
694
699
  }
695
700
  else {
696
- onPullDownCancel(currentOffset);
701
+ onPullCancel(currentOffset);
697
702
  }
698
703
  }
699
704
  offset.current = 0;
@@ -727,9 +732,9 @@ function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAn
727
732
  startGesture(Gesture.SWIPE);
728
733
  onSwipeStart();
729
734
  }
730
- else if (pullDownEnabled && Math.abs(deltaY) > Math.abs(deltaX) && deltaY > SWIPE_THRESHOLD) {
731
- startGesture(Gesture.PULL_DOWN);
732
- onPullDownStart();
735
+ else if (Math.abs(deltaY) > Math.abs(deltaX) && exceedsPullThreshold(deltaY, SWIPE_THRESHOLD)) {
736
+ startGesture(Gesture.PULL);
737
+ onPullStart();
733
738
  }
734
739
  }
735
740
  else if (isCurrentPointer) {
@@ -737,9 +742,9 @@ function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAn
737
742
  offset.current = deltaX;
738
743
  onSwipeProgress(deltaX);
739
744
  }
740
- else if (gesture.current === Gesture.PULL_DOWN) {
745
+ else if (gesture.current === Gesture.PULL) {
741
746
  offset.current = deltaY;
742
- onPullDownProgress(deltaY);
747
+ onPullProgress(deltaY);
743
748
  }
744
749
  }
745
750
  }
@@ -866,13 +871,13 @@ function Controller({ children, ...props }) {
866
871
  const dispatch = useLightboxDispatch();
867
872
  const [swipeState, setSwipeState] = React.useState(SwipeState.NONE);
868
873
  const swipeOffset = React.useRef(0);
869
- const pullDownOffset = React.useRef(0);
870
- const pullDownOpacity = React.useRef(1);
874
+ const pullOffset = React.useRef(0);
875
+ const pullOpacity = React.useRef(1);
871
876
  const { registerSensors, subscribeSensors } = useSensors();
872
877
  const { subscribe, publish } = useEvents();
873
878
  const cleanupAnimationIncrement = useDelay();
874
879
  const cleanupSwipeOffset = useDelay();
875
- const cleanupPullDownOffset = useDelay();
880
+ const cleanupPullOffset = useDelay();
876
881
  const { containerRef, setContainerRef, containerRect } = useContainerRect();
877
882
  const handleContainerRef = useForkRef(usePreventSwipeNavigation(), setContainerRef);
878
883
  const carouselRef = React.useRef(null);
@@ -893,19 +898,26 @@ function Controller({ children, ...props }) {
893
898
  swipeOffset.current = offset;
894
899
  (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.style.setProperty(cssVar("swipe_offset"), `${Math.round(offset)}px`);
895
900
  };
896
- const { closeOnPullDown } = controller;
897
- const setPullDownOffset = (offset) => {
901
+ const { closeOnPullUp, closeOnPullDown } = controller;
902
+ const setPullOffset = (offset) => {
898
903
  var _a, _b;
899
- pullDownOffset.current = offset;
900
- pullDownOpacity.current = (() => {
904
+ pullOffset.current = offset;
905
+ pullOpacity.current = (() => {
901
906
  const threshold = 60;
902
907
  const minOpacity = 0.5;
903
- return Math.min(Math.max(round(1 - (offset / threshold) * (1 - minOpacity), 2), minOpacity), 1);
908
+ const offsetValue = (() => {
909
+ if (closeOnPullDown && offset > 0)
910
+ return offset;
911
+ if (closeOnPullUp && offset < 0)
912
+ return -offset;
913
+ return 0;
914
+ })();
915
+ return Math.min(Math.max(round(1 - (offsetValue / threshold) * (1 - minOpacity), 2), minOpacity), 1);
904
916
  })();
905
- (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.style.setProperty(cssVar("pull_down_offset"), `${Math.round(offset)}px`);
906
- (_b = containerRef.current) === null || _b === void 0 ? void 0 : _b.style.setProperty(cssVar("pull_down_opacity"), `${pullDownOpacity.current}`);
917
+ (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.style.setProperty(cssVar("pull_offset"), `${Math.round(offset)}px`);
918
+ (_b = containerRef.current) === null || _b === void 0 ? void 0 : _b.style.setProperty(cssVar("pull_opacity"), `${pullOpacity.current}`);
907
919
  };
908
- const { prepareAnimation: preparePullDownAnimation } = useAnimation(carouselRef, (snapshot, rect, translate) => {
920
+ const { prepareAnimation: preparePullAnimation } = useAnimation(carouselRef, (snapshot, rect, translate) => {
909
921
  if (carouselRef.current && containerRect) {
910
922
  return {
911
923
  keyframes: [
@@ -921,20 +933,20 @@ function Controller({ children, ...props }) {
921
933
  }
922
934
  return undefined;
923
935
  });
924
- const pullDown = (offset, cancel) => {
925
- if (closeOnPullDown) {
926
- setPullDownOffset(offset);
936
+ const pull = (offset, cancel) => {
937
+ if (closeOnPullUp || closeOnPullDown) {
938
+ setPullOffset(offset);
927
939
  let duration = 0;
928
940
  if (carouselRef.current) {
929
941
  duration = animation.fade * (cancel ? 2 : 1);
930
- preparePullDownAnimation({
942
+ preparePullAnimation({
931
943
  rect: carouselRef.current.getBoundingClientRect(),
932
- opacity: pullDownOpacity.current,
944
+ opacity: pullOpacity.current,
933
945
  duration,
934
946
  });
935
947
  }
936
- cleanupPullDownOffset(() => {
937
- setPullDownOffset(0);
948
+ cleanupPullOffset(() => {
949
+ setPullOffset(0);
938
950
  setSwipeState(SwipeState.NONE);
939
951
  }, duration);
940
952
  setSwipeState(SwipeState.ANIMATION);
@@ -1048,17 +1060,17 @@ function Controller({ children, ...props }) {
1048
1060
  (offset, duration) => swipe({ offset, duration, count: 1 }),
1049
1061
  (offset) => swipe({ offset, count: 0 }),
1050
1062
  ];
1051
- const pullDownParams = [
1063
+ const pullParams = [
1052
1064
  () => {
1053
1065
  if (closeOnPullDown) {
1054
- setSwipeState(SwipeState.PULL_DOWN);
1066
+ setSwipeState(SwipeState.PULL);
1055
1067
  }
1056
1068
  },
1057
- (offset) => setPullDownOffset(offset),
1058
- (offset) => pullDown(offset),
1059
- (offset) => pullDown(offset, true),
1069
+ (offset) => setPullOffset(offset),
1070
+ (offset) => pull(offset),
1071
+ (offset) => pull(offset, true),
1060
1072
  ];
1061
- usePointerSwipe(...swipeParams, closeOnPullDown, ...pullDownParams);
1073
+ usePointerSwipe(...swipeParams, closeOnPullUp, closeOnPullDown, ...pullParams);
1062
1074
  useWheelSwipe(swipeState, ...swipeParams);
1063
1075
  const focusOnMount = useEventCallback(() => {
1064
1076
  if (controller.focus) {
@@ -1111,10 +1123,10 @@ function Controller({ children, ...props }) {
1111
1123
  ...(swipeState === SwipeState.SWIPE
1112
1124
  ? { [cssVar("swipe_offset")]: `${Math.round(swipeOffset.current)}px` }
1113
1125
  : null),
1114
- ...(swipeState === SwipeState.PULL_DOWN
1126
+ ...(swipeState === SwipeState.PULL
1115
1127
  ? {
1116
- [cssVar("pull_down_offset")]: `${Math.round(pullDownOffset.current)}px`,
1117
- [cssVar("pull_down_opacity")]: `${pullDownOpacity.current}`,
1128
+ [cssVar("pull_offset")]: `${Math.round(pullOffset.current)}px`,
1129
+ [cssVar("pull_opacity")]: `${pullOpacity.current}`,
1118
1130
  }
1119
1131
  : null),
1120
1132
  ...(controller.touchAction !== "none" ? { [cssVar("controller_touch_action")]: controller.touchAction } : null),
@@ -1252,7 +1264,7 @@ function padScrollbar(element, padding, rtl) {
1252
1264
  const property = rtl ? "padding-left" : "padding-right";
1253
1265
  const computedValue = rtl ? styles.paddingLeft : styles.paddingRight;
1254
1266
  const originalValue = element.style.getPropertyValue(property);
1255
- element.style.setProperty(property, `${(parseInt(computedValue, 10) || 0) + padding}px`);
1267
+ element.style.setProperty(property, `${(parseInt(computedValue) || 0) + padding}px`);
1256
1268
  return () => {
1257
1269
  if (originalValue) {
1258
1270
  element.style.setProperty(property, originalValue);
@@ -1450,9 +1462,9 @@ function Lightbox({ carousel, animation, render, toolbar, controller, noScroll,
1450
1462
  if (!props.open)
1451
1463
  return null;
1452
1464
  return (React.createElement(LightboxPropsProvider, { ...props },
1453
- React.createElement(LightboxStateProvider, { slides: slides || defaultSlides, index: index || defaultIndex },
1465
+ React.createElement(LightboxStateProvider, { slides: slides || defaultSlides, index: parseInt(index || defaultIndex) },
1454
1466
  React.createElement(TimeoutsProvider, null,
1455
1467
  React.createElement(EventsProvider, null, renderNode(createNode(RootModule, config), props))))));
1456
1468
  }
1457
1469
 
1458
- export { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, CLASS_FLEX_CENTER, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, CLASS_SLIDE_WRAPPER, Carousel, CarouselModule, CloseIcon, Controller, ControllerContext, ControllerModule, 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, 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, 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, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeUseContext, parseLengthPercentage, round, setRef, stopNavigationEventsPropagation, useAnimation, useContainerRect, useController, useDelay, useEventCallback, useEvents, useForkRef, useKeyboardNavigation, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useNavigationState, usePointerEvents, usePointerSwipe, usePreventSwipeNavigation, useRTL, useSensors, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
1470
+ export { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, CLASS_FLEX_CENTER, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, CLASS_SLIDE_WRAPPER, Carousel, CarouselModule, CloseIcon, Controller, ControllerContext, ControllerModule, 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, 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, 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, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeUseContext, parseInt, parseLengthPercentage, round, setRef, stopNavigationEventsPropagation, useAnimation, useContainerRect, useController, useDelay, useEventCallback, useEvents, useForkRef, useKeyboardNavigation, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useNavigationState, usePointerEvents, usePointerSwipe, usePreventSwipeNavigation, useRTL, useSensors, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
@@ -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{-webkit-box-orient:vertical;-webkit-line-clamp:var(--yarl__slide_description_max_lines,3);color:var(--yarl__slide_description_color,#fff);display:-webkit-box;-webkit-hyphens:auto;hyphens:auto;overflow:hidden;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;-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 +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{-webkit-touch-callout:none;background-color:var(--yarl__thumbnails_container_background_color,var(--yarl__color_backdrop,#000));flex:0 0 auto;overflow:hidden;padding:var(--yarl__thumbnails_container_padding,16px);position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none}.yarl__thumbnails_vignette{--yarl__thumbnails_vignette_size:12%;pointer-events:none;position:absolute}@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{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%);height:100%;left:0;right:0}.yarl__thumbnails_end .yarl__thumbnails_vignette,.yarl__thumbnails_start .yarl__thumbnails_vignette{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%);bottom:0;top:0;width:100%}.yarl__thumbnails_track{gap:var(--yarl__thumbnails_thumbnail_gap,16px);outline:none}.yarl__thumbnails_thumbnail{-webkit-tap-highlight-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:var(--yarl__thumbnails_thumbnail_background,#000);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);border-style:var(--yarl__thumbnails_thumbnail_border_style,solid);border-width:var(--yarl__thumbnails_thumbnail_border,1px);box-sizing:content-box;cursor:pointer;flex:0 0 auto;height:var(--yarl__thumbnails_thumbnail_height,80px);outline:none;overflow:hidden;padding:var(--yarl__thumbnails_thumbnail_padding,4px);position:relative;width:var(--yarl__thumbnails_thumbnail_width,120px)}.yarl__thumbnails_thumbnail_active{border-color:var(--yarl__thumbnails_thumbnail_active_border_color,var(--yarl__color_button_active,#fff))}.yarl__thumbnails_thumbnail_fadein{animation:yarl__thumbnails_thumbnail_fadein var(--yarl__thumbnails_thumbnail_fadein_duration,.5s) ease-in-out var(--yarl__thumbnails_thumbnail_fadein_delay,0s) forwards;opacity:0}.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{cursor:unset;visibility:hidden}.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)));height:var(--yarl__thumbnails_thumbnail_icon_size,32px);left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:var(--yarl__thumbnails_thumbnail_icon_size,32px)}.yarl__thumbnails_contain_image{-o-object-fit:contain;object-fit:contain}@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{background-color:var(--yarl__thumbnails_container_background_color,var(--yarl__color_backdrop,#000));flex:0 0 auto;overflow:hidden;padding:var(--yarl__thumbnails_container_padding,16px);position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-touch-callout:none}.yarl__thumbnails_vignette{pointer-events:none;position:absolute;--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{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%);height:100%;left:0;right:0}.yarl__thumbnails_end .yarl__thumbnails_vignette,.yarl__thumbnails_start .yarl__thumbnails_vignette{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%);bottom:0;top:0;width:100%}.yarl__thumbnails_track{gap:var(--yarl__thumbnails_thumbnail_gap,16px);outline:none}.yarl__thumbnails_thumbnail{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:var(--yarl__thumbnails_thumbnail_background,#000);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);border-style:var(--yarl__thumbnails_thumbnail_border_style,solid);border-width:var(--yarl__thumbnails_thumbnail_border,1px);cursor:pointer;flex:0 0 auto;-webkit-tap-highlight-color:transparent;box-sizing:content-box;height:var(--yarl__thumbnails_thumbnail_height,80px);outline:none;overflow:hidden;padding:var(--yarl__thumbnails_thumbnail_padding,4px);position:relative;width:var(--yarl__thumbnails_thumbnail_width,120px)}.yarl__thumbnails_thumbnail_active{border-color:var(--yarl__thumbnails_thumbnail_active_border_color,var(--yarl__color_button_active,#fff))}.yarl__thumbnails_thumbnail_fadein{animation:yarl__thumbnails_thumbnail_fadein var(--yarl__thumbnails_thumbnail_fadein_duration,.5s) ease-in-out var(--yarl__thumbnails_thumbnail_fadein_delay,0s) forwards;opacity:0}.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{cursor:unset;visibility:hidden}.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)));height:var(--yarl__thumbnails_thumbnail_icon_size,32px);left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:var(--yarl__thumbnails_thumbnail_icon_size,32px)}.yarl__thumbnails_contain_image{-o-object-fit:contain;object-fit:contain}@keyframes yarl__thumbnails_thumbnail_fadein{0%{opacity:0}to{opacity:1}}@keyframes yarl__thumbnails_thumbnail_fadeout{0%{opacity:1}to{opacity:0}}
package/dist/styles.css CHANGED
@@ -1 +1 @@
1
- .yarl__fullsize{height:100%;width:100%}.yarl__relative{position:relative}.yarl__portal{bottom:0;left:0;opacity:0;overflow:hidden;position:fixed;right:0;top:0;transition:opacity var(--yarl__fade_animation_duration,.25s) var(--yarl__fade_animation_timing_function,ease);z-index:var(--yarl__portal_zindex,9999)}.yarl__portal_open{opacity:1}.yarl__container{background-color:var(--yarl__container_background_color,var(--yarl__color_backdrop,#000));bottom:0;left:0;outline:none;overflow:hidden;overscroll-behavior:var(--yarl__controller_overscroll-behavior,contain);position:absolute;right:0;top:0;touch-action:var(--yarl__controller_touch_action,none);-webkit-user-select:none;-moz-user-select:none;user-select:none}.yarl__carousel{align-content:center;align-items:stretch;display:flex;flex:0 0 auto;height:100%;justify-content:center;opacity:var(--yarl__pull_down_opacity,1);transform:translate(var(--yarl__swipe_offset,0),var(--yarl__pull_down_offset,0));width:calc(100% + (var(--yarl__carousel_slides_count) - 1)*(100% + var(--yarl__carousel_spacing_px, 0)*1px + var(--yarl__carousel_spacing_percent, 0)*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{align-content:center;align-items:center;display:flex;justify-content:center}.yarl__slide{flex:1;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%);position:relative}[dir=rtl] .yarl__slide{--yarl__direction:-1}.yarl__slide_image{-webkit-touch-callout:none;max-height:100%;max-width:100%;-o-object-fit:contain;object-fit:contain;touch-action:var(--yarl__controller_touch_action,none);-moz-user-select:none;user-select:none;-webkit-user-select:none}@media screen and (min-width:800px){.yarl__slide_image{-webkit-backface-visibility:hidden;-webkit-transform:translateZ(0);-webkit-transform-style:preserve-3d}}.yarl__slide_image_cover{height:100%;-o-object-fit:cover;object-fit:cover;width:100%}.yarl__slide_image_loading{opacity:0}.yarl__slide_placeholder{left:50%;line-height:0;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%)}.yarl__slide_loading{animation:yarl__delayed_fadein 1s linear;color:var(--yarl__slide_icon_loading_color,var(--yarl__color_button,hsla(0,0%,100%,.8)))}.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{color:var(--yarl__slide_icon_error_color,red);height:var(--yarl__slide_icon_error_size,48px);width:var(--yarl__slide_icon_error_size,48px)}@media (prefers-reduced-motion){.yarl__portal,.yarl__slide{transition:unset}.yarl__slide_loading,.yarl__slide_loading line{animation:unset}}.yarl__toolbar{bottom:auto;display:flex;justify-content:flex-end;left:auto;padding:var(--yarl__toolbar_padding,8px);position:absolute;right:0;top:0}[dir=rtl] .yarl__toolbar{bottom:auto;left:0;right:auto;top:0}.yarl__icon{height:var(--yarl__icon_size,32px);width:var(--yarl__icon_size,32px)}.yarl__button{-webkit-tap-highlight-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--yarl__button_background_color,transparent);border:var(--yarl__button_border,0);color:var(--yarl__color_button,hsla(0,0%,100%,.8));cursor:pointer;filter:var(--yarl__button_filter,drop-shadow(2px 2px 2px rgba(0,0,0,.8)));line-height:0;margin:var(--yarl__button_margin,0);outline:none;padding:var(--yarl__button_padding,8px)}.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{padding:var(--yarl__navigation_button_padding,24px 16px);position:absolute;top:50%;transform:translateY(-50%)}.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{height:100%;width:100%}.yarl__relative{position:relative}.yarl__portal{bottom:0;left:0;opacity:0;overflow:hidden;position:fixed;right:0;top:0;transition:opacity var(--yarl__fade_animation_duration,.25s) var(--yarl__fade_animation_timing_function,ease);z-index:var(--yarl__portal_zindex,9999)}.yarl__portal_open{opacity:1}.yarl__container{background-color:var(--yarl__container_background_color,var(--yarl__color_backdrop,#000));bottom:0;left:0;outline:none;overflow:hidden;overscroll-behavior:var(--yarl__controller_overscroll-behavior,contain);position:absolute;right:0;top:0;touch-action:var(--yarl__controller_touch_action,none);-webkit-user-select:none;-moz-user-select:none;user-select:none}.yarl__carousel{align-content:center;align-items:stretch;display:flex;flex:0 0 auto;height:100%;justify-content:center;opacity:var(--yarl__pull_opacity,1);transform:translate(var(--yarl__swipe_offset,0),var(--yarl__pull_offset,0));width:calc(100% + (var(--yarl__carousel_slides_count) - 1)*(100% + var(--yarl__carousel_spacing_px, 0)*1px + var(--yarl__carousel_spacing_percent, 0)*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{align-content:center;align-items:center;display:flex;justify-content:center}.yarl__slide{flex:1;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%);position:relative}[dir=rtl] .yarl__slide{--yarl__direction:-1}.yarl__slide_image{max-height:100%;max-width:100%;-o-object-fit:contain;object-fit:contain;touch-action:var(--yarl__controller_touch_action,none);-moz-user-select:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}@media screen and (min-width:800px){.yarl__slide_image{-webkit-backface-visibility:hidden;-webkit-transform:translateZ(0);-webkit-transform-style:preserve-3d}}.yarl__slide_image_cover{height:100%;-o-object-fit:cover;object-fit:cover;width:100%}.yarl__slide_image_loading{opacity:0}.yarl__slide_placeholder{left:50%;line-height:0;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%)}.yarl__slide_loading{animation:yarl__delayed_fadein 1s linear;color:var(--yarl__slide_icon_loading_color,var(--yarl__color_button,hsla(0,0%,100%,.8)))}.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{color:var(--yarl__slide_icon_error_color,red);height:var(--yarl__slide_icon_error_size,48px);width:var(--yarl__slide_icon_error_size,48px)}@media (prefers-reduced-motion){.yarl__portal,.yarl__slide{transition:unset}.yarl__slide_loading,.yarl__slide_loading line{animation:unset}}.yarl__toolbar{bottom:auto;display:flex;justify-content:flex-end;left:auto;padding:var(--yarl__toolbar_padding,8px);position:absolute;right:0;top:0}[dir=rtl] .yarl__toolbar{bottom:auto;left:0;right:auto;top:0}.yarl__icon{height:var(--yarl__icon_size,32px);width:var(--yarl__icon_size,32px)}.yarl__button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--yarl__button_background_color,transparent);border:var(--yarl__button_border,0);color:var(--yarl__color_button,hsla(0,0%,100%,.8));cursor:pointer;filter:var(--yarl__button_filter,drop-shadow(2px 2px 2px rgba(0,0,0,.8)));line-height:0;margin:var(--yarl__button_margin,0);outline:none;padding:var(--yarl__button_padding,8px);-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{padding:var(--yarl__navigation_button_padding,24px 16px);position:absolute;top:50%;transform:translateY(-50%)}.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
@@ -229,6 +229,8 @@ interface ControllerSettings {
229
229
  touchAction: "none" | "pan-y";
230
230
  /** if `true`, set ARIA attributes on the controller div */
231
231
  aria: boolean;
232
+ /** if `true`, close the lightbox on pull-up gesture */
233
+ closeOnPullUp: boolean;
232
234
  /** if `true`, close the lightbox on pull-down gesture */
233
235
  closeOnPullDown: boolean;
234
236
  /** if `true`, close the lightbox when the backdrop is clicked */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yet-another-react-lightbox",
3
- "version": "3.15.5",
3
+ "version": "3.16.0",
4
4
  "description": "Modern React lightbox component",
5
5
  "author": "Igor Danchenko",
6
6
  "license": "MIT",