yet-another-react-lightbox 3.15.6 → 3.17.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 +4 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +48 -39
- package/dist/plugins/captions/captions.css +1 -1
- package/dist/plugins/counter/index.js +1 -1
- package/dist/plugins/fullscreen/index.d.ts +6 -0
- package/dist/plugins/fullscreen/index.js +18 -12
- package/dist/plugins/inline/index.js +1 -1
- package/dist/plugins/thumbnails/thumbnails.css +1 -1
- package/dist/plugins/video/index.js +1 -1
- package/dist/plugins/zoom/index.js +6 -14
- package/dist/styles.css +1 -1
- package/dist/types.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,6 +34,10 @@ extendable.
|
|
|
34
34
|
|
|
35
35
|
[https://yet-another-react-lightbox.com/examples](https://yet-another-react-lightbox.com/examples)
|
|
36
36
|
|
|
37
|
+
## Changelog
|
|
38
|
+
|
|
39
|
+
[https://github.com/igordanchenko/yet-another-react-lightbox/releases](https://github.com/igordanchenko/yet-another-react-lightbox/releases)
|
|
40
|
+
|
|
37
41
|
## Installation
|
|
38
42
|
|
|
39
43
|
```shell
|
package/dist/index.d.ts
CHANGED
|
@@ -202,11 +202,11 @@ declare const CarouselModule: Module;
|
|
|
202
202
|
declare enum SwipeState {
|
|
203
203
|
NONE = 0,
|
|
204
204
|
SWIPE = 1,
|
|
205
|
-
|
|
205
|
+
PULL = 2,
|
|
206
206
|
ANIMATION = 3
|
|
207
207
|
}
|
|
208
208
|
|
|
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, pullDownEnabled: boolean,
|
|
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;
|
|
210
210
|
|
|
211
211
|
/** prevent browser back/forward navigation on touchpad left/right swipe (especially noticeable in Safari)
|
|
212
212
|
* this has to be done via non-passive native event handler */
|
package/dist/index.js
CHANGED
|
@@ -110,6 +110,7 @@ const LightboxDefaultProps = {
|
|
|
110
110
|
focus: true,
|
|
111
111
|
aria: false,
|
|
112
112
|
touchAction: "none",
|
|
113
|
+
closeOnPullUp: false,
|
|
113
114
|
closeOnPullDown: false,
|
|
114
115
|
closeOnBackdropClick: false,
|
|
115
116
|
},
|
|
@@ -639,7 +640,7 @@ var SwipeState;
|
|
|
639
640
|
(function (SwipeState) {
|
|
640
641
|
SwipeState[SwipeState["NONE"] = 0] = "NONE";
|
|
641
642
|
SwipeState[SwipeState["SWIPE"] = 1] = "SWIPE";
|
|
642
|
-
SwipeState[SwipeState["
|
|
643
|
+
SwipeState[SwipeState["PULL"] = 2] = "PULL";
|
|
643
644
|
SwipeState[SwipeState["ANIMATION"] = 3] = "ANIMATION";
|
|
644
645
|
})(SwipeState || (SwipeState = {}));
|
|
645
646
|
|
|
@@ -653,10 +654,10 @@ var Gesture;
|
|
|
653
654
|
(function (Gesture) {
|
|
654
655
|
Gesture[Gesture["NONE"] = 0] = "NONE";
|
|
655
656
|
Gesture[Gesture["SWIPE"] = 1] = "SWIPE";
|
|
656
|
-
Gesture[Gesture["
|
|
657
|
+
Gesture[Gesture["PULL"] = 2] = "PULL";
|
|
657
658
|
})(Gesture || (Gesture = {}));
|
|
658
659
|
const SWIPE_THRESHOLD = 30;
|
|
659
|
-
function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAnimationDuration, onSwipeStart, onSwipeProgress, onSwipeFinish, onSwipeCancel, pullDownEnabled,
|
|
660
|
+
function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAnimationDuration, onSwipeStart, onSwipeProgress, onSwipeFinish, onSwipeCancel, pullUpEnabled, pullDownEnabled, onPullStart, onPullProgress, onPullFinish, onPullCancel) {
|
|
660
661
|
const offset = React.useRef(0);
|
|
661
662
|
const pointers = React.useRef([]);
|
|
662
663
|
const activePointer = React.useRef();
|
|
@@ -678,6 +679,7 @@ function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAn
|
|
|
678
679
|
const onPointerDown = useEventCallback((event) => {
|
|
679
680
|
addPointer(event);
|
|
680
681
|
});
|
|
682
|
+
const exceedsPullThreshold = (value, threshold) => (pullDownEnabled && value > threshold) || (pullUpEnabled && value < -threshold);
|
|
681
683
|
const onPointerUp = useEventCallback((event) => {
|
|
682
684
|
if (pointers.current.find((x) => x.pointerId === event.pointerId) && activePointer.current === event.pointerId) {
|
|
683
685
|
const duration = Date.now() - startTime.current;
|
|
@@ -691,12 +693,12 @@ function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAn
|
|
|
691
693
|
onSwipeCancel(currentOffset);
|
|
692
694
|
}
|
|
693
695
|
}
|
|
694
|
-
else if (gesture.current === Gesture.
|
|
695
|
-
if (currentOffset
|
|
696
|
-
|
|
696
|
+
else if (gesture.current === Gesture.PULL) {
|
|
697
|
+
if (exceedsPullThreshold(currentOffset, 2 * SWIPE_THRESHOLD)) {
|
|
698
|
+
onPullFinish(currentOffset, duration);
|
|
697
699
|
}
|
|
698
700
|
else {
|
|
699
|
-
|
|
701
|
+
onPullCancel(currentOffset);
|
|
700
702
|
}
|
|
701
703
|
}
|
|
702
704
|
offset.current = 0;
|
|
@@ -730,9 +732,9 @@ function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAn
|
|
|
730
732
|
startGesture(Gesture.SWIPE);
|
|
731
733
|
onSwipeStart();
|
|
732
734
|
}
|
|
733
|
-
else if (
|
|
734
|
-
startGesture(Gesture.
|
|
735
|
-
|
|
735
|
+
else if (Math.abs(deltaY) > Math.abs(deltaX) && exceedsPullThreshold(deltaY, SWIPE_THRESHOLD)) {
|
|
736
|
+
startGesture(Gesture.PULL);
|
|
737
|
+
onPullStart();
|
|
736
738
|
}
|
|
737
739
|
}
|
|
738
740
|
else if (isCurrentPointer) {
|
|
@@ -740,9 +742,9 @@ function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAn
|
|
|
740
742
|
offset.current = deltaX;
|
|
741
743
|
onSwipeProgress(deltaX);
|
|
742
744
|
}
|
|
743
|
-
else if (gesture.current === Gesture.
|
|
745
|
+
else if (gesture.current === Gesture.PULL) {
|
|
744
746
|
offset.current = deltaY;
|
|
745
|
-
|
|
747
|
+
onPullProgress(deltaY);
|
|
746
748
|
}
|
|
747
749
|
}
|
|
748
750
|
}
|
|
@@ -869,13 +871,13 @@ function Controller({ children, ...props }) {
|
|
|
869
871
|
const dispatch = useLightboxDispatch();
|
|
870
872
|
const [swipeState, setSwipeState] = React.useState(SwipeState.NONE);
|
|
871
873
|
const swipeOffset = React.useRef(0);
|
|
872
|
-
const
|
|
873
|
-
const
|
|
874
|
+
const pullOffset = React.useRef(0);
|
|
875
|
+
const pullOpacity = React.useRef(1);
|
|
874
876
|
const { registerSensors, subscribeSensors } = useSensors();
|
|
875
877
|
const { subscribe, publish } = useEvents();
|
|
876
878
|
const cleanupAnimationIncrement = useDelay();
|
|
877
879
|
const cleanupSwipeOffset = useDelay();
|
|
878
|
-
const
|
|
880
|
+
const cleanupPullOffset = useDelay();
|
|
879
881
|
const { containerRef, setContainerRef, containerRect } = useContainerRect();
|
|
880
882
|
const handleContainerRef = useForkRef(usePreventSwipeNavigation(), setContainerRef);
|
|
881
883
|
const carouselRef = React.useRef(null);
|
|
@@ -896,19 +898,26 @@ function Controller({ children, ...props }) {
|
|
|
896
898
|
swipeOffset.current = offset;
|
|
897
899
|
(_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.style.setProperty(cssVar("swipe_offset"), `${Math.round(offset)}px`);
|
|
898
900
|
};
|
|
899
|
-
const { closeOnPullDown } = controller;
|
|
900
|
-
const
|
|
901
|
+
const { closeOnPullUp, closeOnPullDown } = controller;
|
|
902
|
+
const setPullOffset = (offset) => {
|
|
901
903
|
var _a, _b;
|
|
902
|
-
|
|
903
|
-
|
|
904
|
+
pullOffset.current = offset;
|
|
905
|
+
pullOpacity.current = (() => {
|
|
904
906
|
const threshold = 60;
|
|
905
907
|
const minOpacity = 0.5;
|
|
906
|
-
|
|
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);
|
|
907
916
|
})();
|
|
908
|
-
(_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.style.setProperty(cssVar("
|
|
909
|
-
(_b = containerRef.current) === null || _b === void 0 ? void 0 : _b.style.setProperty(cssVar("
|
|
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}`);
|
|
910
919
|
};
|
|
911
|
-
const { prepareAnimation:
|
|
920
|
+
const { prepareAnimation: preparePullAnimation } = useAnimation(carouselRef, (snapshot, rect, translate) => {
|
|
912
921
|
if (carouselRef.current && containerRect) {
|
|
913
922
|
return {
|
|
914
923
|
keyframes: [
|
|
@@ -924,20 +933,20 @@ function Controller({ children, ...props }) {
|
|
|
924
933
|
}
|
|
925
934
|
return undefined;
|
|
926
935
|
});
|
|
927
|
-
const
|
|
928
|
-
if (closeOnPullDown) {
|
|
929
|
-
|
|
936
|
+
const pull = (offset, cancel) => {
|
|
937
|
+
if (closeOnPullUp || closeOnPullDown) {
|
|
938
|
+
setPullOffset(offset);
|
|
930
939
|
let duration = 0;
|
|
931
940
|
if (carouselRef.current) {
|
|
932
941
|
duration = animation.fade * (cancel ? 2 : 1);
|
|
933
|
-
|
|
942
|
+
preparePullAnimation({
|
|
934
943
|
rect: carouselRef.current.getBoundingClientRect(),
|
|
935
|
-
opacity:
|
|
944
|
+
opacity: pullOpacity.current,
|
|
936
945
|
duration,
|
|
937
946
|
});
|
|
938
947
|
}
|
|
939
|
-
|
|
940
|
-
|
|
948
|
+
cleanupPullOffset(() => {
|
|
949
|
+
setPullOffset(0);
|
|
941
950
|
setSwipeState(SwipeState.NONE);
|
|
942
951
|
}, duration);
|
|
943
952
|
setSwipeState(SwipeState.ANIMATION);
|
|
@@ -1051,17 +1060,17 @@ function Controller({ children, ...props }) {
|
|
|
1051
1060
|
(offset, duration) => swipe({ offset, duration, count: 1 }),
|
|
1052
1061
|
(offset) => swipe({ offset, count: 0 }),
|
|
1053
1062
|
];
|
|
1054
|
-
const
|
|
1063
|
+
const pullParams = [
|
|
1055
1064
|
() => {
|
|
1056
1065
|
if (closeOnPullDown) {
|
|
1057
|
-
setSwipeState(SwipeState.
|
|
1066
|
+
setSwipeState(SwipeState.PULL);
|
|
1058
1067
|
}
|
|
1059
1068
|
},
|
|
1060
|
-
(offset) =>
|
|
1061
|
-
(offset) =>
|
|
1062
|
-
(offset) =>
|
|
1069
|
+
(offset) => setPullOffset(offset),
|
|
1070
|
+
(offset) => pull(offset),
|
|
1071
|
+
(offset) => pull(offset, true),
|
|
1063
1072
|
];
|
|
1064
|
-
usePointerSwipe(...swipeParams, closeOnPullDown, ...
|
|
1073
|
+
usePointerSwipe(...swipeParams, closeOnPullUp, closeOnPullDown, ...pullParams);
|
|
1065
1074
|
useWheelSwipe(swipeState, ...swipeParams);
|
|
1066
1075
|
const focusOnMount = useEventCallback(() => {
|
|
1067
1076
|
if (controller.focus) {
|
|
@@ -1114,10 +1123,10 @@ function Controller({ children, ...props }) {
|
|
|
1114
1123
|
...(swipeState === SwipeState.SWIPE
|
|
1115
1124
|
? { [cssVar("swipe_offset")]: `${Math.round(swipeOffset.current)}px` }
|
|
1116
1125
|
: null),
|
|
1117
|
-
...(swipeState === SwipeState.
|
|
1126
|
+
...(swipeState === SwipeState.PULL
|
|
1118
1127
|
? {
|
|
1119
|
-
[cssVar("
|
|
1120
|
-
[cssVar("
|
|
1128
|
+
[cssVar("pull_offset")]: `${Math.round(pullOffset.current)}px`,
|
|
1129
|
+
[cssVar("pull_opacity")]: `${pullOpacity.current}`,
|
|
1121
1130
|
}
|
|
1122
1131
|
: null),
|
|
1123
1132
|
...(controller.touchAction !== "none" ? { [cssVar("controller_touch_action")]: controller.touchAction } : null),
|
|
@@ -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);
|
|
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,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useLightboxState,
|
|
2
|
+
import { useLightboxState, clsx, cssClass, createModule } from '../../index.js';
|
|
3
3
|
import { MODULE_CONTROLLER, PLUGIN_COUNTER } from '../../types.js';
|
|
4
4
|
|
|
5
5
|
const defaultCounterProps = {
|
|
@@ -22,6 +22,12 @@ declare module "yet-another-react-lightbox" {
|
|
|
22
22
|
/** render custom Exit Fullscreen icon */
|
|
23
23
|
iconExitFullscreen?: RenderFunction;
|
|
24
24
|
}
|
|
25
|
+
interface Callbacks {
|
|
26
|
+
/** a callback called when the lightbox enters fullscreen mode */
|
|
27
|
+
enterFullscreen?: Callback;
|
|
28
|
+
/** a callback called when the lightbox exits fullscreen mode */
|
|
29
|
+
exitFullscreen?: Callback;
|
|
30
|
+
}
|
|
25
31
|
interface ToolbarButtonKeys {
|
|
26
32
|
[PLUGIN_FULLSCREEN]: null;
|
|
27
33
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { makeUseContext, useLayoutEffect, useEventCallback,
|
|
1
|
+
import { makeUseContext, useLayoutEffect, useEventCallback, clsx, cssClass, createIcon, useLightboxProps, IconButton, addToolbarButton, createModule } from '../../index.js';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { PLUGIN_FULLSCREEN, CLASS_FULLSIZE, PLUGIN_THUMBNAILS, MODULE_CONTROLLER } from '../../types.js';
|
|
4
4
|
|
|
@@ -13,11 +13,12 @@ const resolveFullscreenProps = (fullscreen) => ({
|
|
|
13
13
|
|
|
14
14
|
const FullscreenContext = React.createContext(null);
|
|
15
15
|
const useFullscreen = makeUseContext("useFullscreen", "FullscreenContext", FullscreenContext);
|
|
16
|
-
function FullscreenContextProvider({ fullscreen: fullscreenProps, children }) {
|
|
16
|
+
function FullscreenContextProvider({ fullscreen: fullscreenProps, on, children }) {
|
|
17
17
|
const { auto, ref } = resolveFullscreenProps(fullscreenProps);
|
|
18
18
|
const containerRef = React.useRef(null);
|
|
19
|
-
const [fullscreen, setFullscreen] = React.useState(false);
|
|
20
19
|
const [disabled, setDisabled] = React.useState();
|
|
20
|
+
const [fullscreen, setFullscreen] = React.useState(false);
|
|
21
|
+
const wasFullscreen = React.useRef(false);
|
|
21
22
|
useLayoutEffect(() => {
|
|
22
23
|
var _a, _b, _c, _d;
|
|
23
24
|
setDisabled(!((_d = (_c = (_b = (_a = document.fullscreenEnabled) !== null && _a !== void 0 ? _a : document.webkitFullscreenEnabled) !== null && _b !== void 0 ? _b : document.mozFullScreenEnabled) !== null && _c !== void 0 ? _c : document.msFullscreenEnabled) !== null && _d !== void 0 ? _d : false));
|
|
@@ -67,16 +68,11 @@ function FullscreenContextProvider({ fullscreen: fullscreenProps, children }) {
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
}, [getFullscreenElement]);
|
|
70
|
-
const fullscreenChangeListener = React.useCallback(() => {
|
|
71
|
-
if (getFullscreenElement() === containerRef.current) {
|
|
72
|
-
setFullscreen(true);
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
setFullscreen(false);
|
|
76
|
-
}
|
|
77
|
-
}, [getFullscreenElement]);
|
|
78
71
|
React.useEffect(() => {
|
|
79
72
|
const events = ["fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "MSFullscreenChange"];
|
|
73
|
+
const fullscreenChangeListener = () => {
|
|
74
|
+
setFullscreen(getFullscreenElement() === containerRef.current);
|
|
75
|
+
};
|
|
80
76
|
events.forEach((event) => {
|
|
81
77
|
document.addEventListener(event, fullscreenChangeListener);
|
|
82
78
|
});
|
|
@@ -85,7 +81,17 @@ function FullscreenContextProvider({ fullscreen: fullscreenProps, children }) {
|
|
|
85
81
|
document.removeEventListener(event, fullscreenChangeListener);
|
|
86
82
|
});
|
|
87
83
|
};
|
|
88
|
-
}, [
|
|
84
|
+
}, [getFullscreenElement]);
|
|
85
|
+
const onEnterFullscreen = useEventCallback(() => { var _a; return (_a = on.enterFullscreen) === null || _a === void 0 ? void 0 : _a.call(on); });
|
|
86
|
+
const onExitFullscreen = useEventCallback(() => { var _a; return (_a = on.exitFullscreen) === null || _a === void 0 ? void 0 : _a.call(on); });
|
|
87
|
+
React.useEffect(() => {
|
|
88
|
+
if (fullscreen) {
|
|
89
|
+
wasFullscreen.current = true;
|
|
90
|
+
}
|
|
91
|
+
if (wasFullscreen.current) {
|
|
92
|
+
(fullscreen ? onEnterFullscreen : onExitFullscreen)();
|
|
93
|
+
}
|
|
94
|
+
}, [fullscreen, onEnterFullscreen, onExitFullscreen]);
|
|
89
95
|
const handleAutoFullscreen = useEventCallback(() => { var _a; return (_a = (auto ? enter : null)) === null || _a === void 0 ? void 0 : _a(); });
|
|
90
96
|
React.useEffect(() => {
|
|
91
97
|
handleAutoFullscreen();
|
|
@@ -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{
|
|
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}}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useLightboxProps, useEvents, useContainerRect, useEventCallback,
|
|
2
|
+
import { useLightboxProps, useEvents, useContainerRect, useEventCallback, clsx, cssClass } from '../../index.js';
|
|
3
3
|
import { ACTIVE_SLIDE_LOADING, CLASS_FLEX_CENTER, CLASS_SLIDE_WRAPPER, ACTIVE_SLIDE_PLAYING, ACTIVE_SLIDE_COMPLETE } from '../../types.js';
|
|
4
4
|
|
|
5
5
|
const defaultVideoProps = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useLightboxProps, useMotionPreference, useEventCallback, useLayoutEffect, useLightboxState, isImageSlide, isImageFitCover, round, useController, usePointerEvents, cleanup, makeUseContext, createIcon, IconButton, devicePixelRatio, ImageSlide,
|
|
1
|
+
import { useLightboxProps, useMotionPreference, useEventCallback, useLayoutEffect, useLightboxState, isImageSlide, isImageFitCover, round, useController, usePointerEvents, cleanup, makeUseContext, createIcon, IconButton, devicePixelRatio, ImageSlide, clsx, cssClass, addToolbarButton, createModule } from '../../index.js';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { EVENT_ON_KEY_DOWN, EVENT_ON_WHEEL, UNKNOWN_ACTION_TYPE, CLASS_FULLSIZE, CLASS_FLEX_CENTER, CLASS_SLIDE_WRAPPER, PLUGIN_ZOOM } from '../../types.js';
|
|
4
4
|
|
|
@@ -76,11 +76,11 @@ function useZoomImageRect(slideRect, imageDimensions) {
|
|
|
76
76
|
var _a, _b;
|
|
77
77
|
let imageRect = { width: 0, height: 0 };
|
|
78
78
|
let maxImageRect = { width: 0, height: 0 };
|
|
79
|
-
const {
|
|
79
|
+
const { currentSlide } = useLightboxState();
|
|
80
80
|
const { imageFit } = useLightboxProps().carousel;
|
|
81
81
|
const { maxZoomPixelRatio } = useZoomProps();
|
|
82
|
-
if (slideRect &&
|
|
83
|
-
const slide = { ...
|
|
82
|
+
if (slideRect && currentSlide) {
|
|
83
|
+
const slide = { ...currentSlide, ...imageDimensions };
|
|
84
84
|
if (isImageSlide(slide)) {
|
|
85
85
|
const cover = isImageFitCover(slide, imageFit);
|
|
86
86
|
const width = Math.max(...(((_a = slide.srcSet) === null || _a === void 0 ? void 0 : _a.map((x) => x.width)) || []).concat(slide.width ? [slide.width] : []));
|
|
@@ -265,23 +265,15 @@ function useZoomSensors(zoom, maxZoom, disabled, changeZoom, changeOffsets, zoom
|
|
|
265
265
|
}, [disabled, subscribeSensors, cleanupSensors, onKeyDown, onWheel]);
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
-
function getCurrentSource(slides, currentIndex) {
|
|
269
|
-
if (currentIndex < slides.length) {
|
|
270
|
-
const slide = slides[currentIndex];
|
|
271
|
-
if (isImageSlide(slide))
|
|
272
|
-
return slide.src;
|
|
273
|
-
}
|
|
274
|
-
return undefined;
|
|
275
|
-
}
|
|
276
268
|
function useZoomState(imageRect, maxZoom, zoomWrapperRef) {
|
|
277
269
|
const [zoom, setZoom] = React.useState(1);
|
|
278
270
|
const [offsetX, setOffsetX] = React.useState(0);
|
|
279
271
|
const [offsetY, setOffsetY] = React.useState(0);
|
|
280
272
|
const animate = useZoomAnimation(zoom, offsetX, offsetY, zoomWrapperRef);
|
|
281
|
-
const {
|
|
273
|
+
const { currentSlide, globalIndex } = useLightboxState();
|
|
282
274
|
const { containerRect, slideRect } = useController();
|
|
283
275
|
const { zoomInMultiplier } = useZoomProps();
|
|
284
|
-
const currentSource =
|
|
276
|
+
const currentSource = currentSlide && isImageSlide(currentSlide) ? currentSlide.src : undefined;
|
|
285
277
|
const disabled = !currentSource || !(zoomWrapperRef === null || zoomWrapperRef === void 0 ? void 0 : zoomWrapperRef.current);
|
|
286
278
|
useLayoutEffect(() => {
|
|
287
279
|
setZoom(1);
|
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(--
|
|
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 */
|