yet-another-react-lightbox 3.6.0 → 3.7.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 +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +218 -167
- package/dist/plugins/slideshow/index.js +1 -1
- package/dist/plugins/thumbnails/index.js +3 -4
- package/dist/plugins/zoom/index.js +5 -4
- package/dist/types.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -123,16 +123,16 @@ See [examples](https://yet-another-react-lightbox.com/examples) on the documenta
|
|
|
123
123
|
|
|
124
124
|
## Plugins
|
|
125
125
|
|
|
126
|
-
Yet Another React Lightbox allows you to add optional features based on your requirements via plugins.
|
|
126
|
+
Yet Another React Lightbox allows you to add optional features to your project based on your requirements via plugins.
|
|
127
127
|
|
|
128
|
-
The following plugins
|
|
128
|
+
The following plugins are bundled in the package:
|
|
129
129
|
|
|
130
130
|
- [Captions](https://yet-another-react-lightbox.com/plugins/captions) - adds support for slide title and
|
|
131
131
|
description
|
|
132
132
|
- [Counter](https://yet-another-react-lightbox.com/plugins/counter) - adds slides counter
|
|
133
133
|
- [Download](https://yet-another-react-lightbox.com/plugins/download) - adds download button
|
|
134
134
|
- [Fullscreen](https://yet-another-react-lightbox.com/plugins/fullscreen) - adds support for fullscreen mode
|
|
135
|
-
- [Inline](https://yet-another-react-lightbox.com/plugins/inline) -
|
|
135
|
+
- [Inline](https://yet-another-react-lightbox.com/plugins/inline) - transforms the lightbox into an image carousel
|
|
136
136
|
- [Slideshow](https://yet-another-react-lightbox.com/plugins/slideshow) - adds slideshow autoplay feature
|
|
137
137
|
- [Thumbnails](https://yet-another-react-lightbox.com/plugins/thumbnails) - adds thumbnails track
|
|
138
138
|
- [Video](https://yet-another-react-lightbox.com/plugins/video) - adds support for video slides
|
package/dist/index.d.ts
CHANGED
|
@@ -79,7 +79,7 @@ declare function useForkRef<InstanceA, InstanceB>(refA: React.Ref<InstanceA> | n
|
|
|
79
79
|
|
|
80
80
|
declare const useLayoutEffect: typeof React.useEffect;
|
|
81
81
|
|
|
82
|
-
declare function useLoseFocus(disabled?: boolean): {
|
|
82
|
+
declare function useLoseFocus(focus: () => void, disabled?: boolean): {
|
|
83
83
|
onFocus: () => void;
|
|
84
84
|
onBlur: () => void;
|
|
85
85
|
};
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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,
|
|
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, VK_ESCAPE, CLASS_FLEX_CENTER, MODULE_CAROUSEL, CLASS_FULLSIZE, VK_ARROW_LEFT, VK_ARROW_RIGHT, MODULE_NAVIGATION, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, MODULE_NO_SCROLL, MODULE_PORTAL, 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, PLUGIN_CAPTIONS, PLUGIN_COUNTER, PLUGIN_DOWNLOAD, PLUGIN_FULLSCREEN, PLUGIN_INLINE, PLUGIN_SLIDESHOW, PLUGIN_THUMBNAILS, PLUGIN_ZOOM, SLIDE_STATUS_PLAYING } from './types.js';
|
|
6
6
|
|
|
@@ -34,6 +34,7 @@ const LightboxDefaultProps = {
|
|
|
34
34
|
focus: true,
|
|
35
35
|
aria: false,
|
|
36
36
|
touchAction: "none",
|
|
37
|
+
closeOnPullDown: false,
|
|
37
38
|
closeOnBackdropClick: false,
|
|
38
39
|
},
|
|
39
40
|
portal: {},
|
|
@@ -488,14 +489,176 @@ function useForkRef(refA, refB) {
|
|
|
488
489
|
}, [refA, refB]);
|
|
489
490
|
}
|
|
490
491
|
|
|
491
|
-
function
|
|
492
|
+
function useLoseFocus(focus, disabled = false) {
|
|
493
|
+
const focused = React.useRef(disabled);
|
|
494
|
+
useLayoutEffect(() => {
|
|
495
|
+
if (disabled) {
|
|
496
|
+
focus();
|
|
497
|
+
}
|
|
498
|
+
}, [disabled, focus]);
|
|
499
|
+
const onFocus = React.useCallback(() => {
|
|
500
|
+
focused.current = true;
|
|
501
|
+
}, []);
|
|
502
|
+
const onBlur = React.useCallback(() => {
|
|
503
|
+
focused.current = false;
|
|
504
|
+
}, []);
|
|
505
|
+
return { onFocus, onBlur };
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
function useRTL() {
|
|
509
|
+
const [isRTL, setIsRTL] = React.useState(false);
|
|
510
|
+
useLayoutEffect(() => {
|
|
511
|
+
setIsRTL(window.getComputedStyle(window.document.documentElement).direction === "rtl");
|
|
512
|
+
}, []);
|
|
513
|
+
return isRTL;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
function useSensors() {
|
|
517
|
+
const [subscribers] = React.useState({});
|
|
518
|
+
return React.useMemo(() => {
|
|
519
|
+
const notifySubscribers = (type, event) => {
|
|
520
|
+
var _a;
|
|
521
|
+
(_a = subscribers[type]) === null || _a === void 0 ? void 0 : _a.forEach((listener) => {
|
|
522
|
+
if (!event.isPropagationStopped())
|
|
523
|
+
listener(event);
|
|
524
|
+
});
|
|
525
|
+
};
|
|
526
|
+
return {
|
|
527
|
+
registerSensors: {
|
|
528
|
+
onPointerDown: (event) => notifySubscribers(EVENT_ON_POINTER_DOWN, event),
|
|
529
|
+
onPointerMove: (event) => notifySubscribers(EVENT_ON_POINTER_MOVE, event),
|
|
530
|
+
onPointerUp: (event) => notifySubscribers(EVENT_ON_POINTER_UP, event),
|
|
531
|
+
onPointerLeave: (event) => notifySubscribers(EVENT_ON_POINTER_LEAVE, event),
|
|
532
|
+
onPointerCancel: (event) => notifySubscribers(EVENT_ON_POINTER_CANCEL, event),
|
|
533
|
+
onKeyDown: (event) => notifySubscribers(EVENT_ON_KEY_DOWN, event),
|
|
534
|
+
onKeyUp: (event) => notifySubscribers(EVENT_ON_KEY_UP, event),
|
|
535
|
+
onWheel: (event) => notifySubscribers(EVENT_ON_WHEEL, event),
|
|
536
|
+
},
|
|
537
|
+
subscribeSensors: (type, callback) => {
|
|
538
|
+
if (!subscribers[type]) {
|
|
539
|
+
subscribers[type] = [];
|
|
540
|
+
}
|
|
541
|
+
subscribers[type].unshift(callback);
|
|
542
|
+
return () => {
|
|
543
|
+
const listeners = subscribers[type];
|
|
544
|
+
if (listeners) {
|
|
545
|
+
listeners.splice(0, listeners.length, ...listeners.filter((el) => el !== callback));
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
},
|
|
549
|
+
};
|
|
550
|
+
}, [subscribers]);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
function useThrottle(callback, delay) {
|
|
554
|
+
const lastCallbackTime = React.useRef(0);
|
|
555
|
+
const delayCallback = useDelay();
|
|
556
|
+
const executeCallback = useEventCallback((...args) => {
|
|
557
|
+
lastCallbackTime.current = Date.now();
|
|
558
|
+
callback(args);
|
|
559
|
+
});
|
|
560
|
+
return React.useCallback((...args) => {
|
|
561
|
+
delayCallback(() => {
|
|
562
|
+
executeCallback(args);
|
|
563
|
+
}, delay - (Date.now() - lastCallbackTime.current));
|
|
564
|
+
}, [delay, executeCallback, delayCallback]);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
const slidePrefix = makeComposePrefix("slide");
|
|
568
|
+
const slideImagePrefix = makeComposePrefix("slide_image");
|
|
569
|
+
function ImageSlide({ slide: image, offset, render, rect, imageFit, onClick, onLoad, style }) {
|
|
570
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
571
|
+
const [status, setStatus] = React.useState(SLIDE_STATUS_LOADING);
|
|
572
|
+
const { publish } = useEvents();
|
|
573
|
+
const { setTimeout } = useTimeouts();
|
|
574
|
+
const imageRef = React.useRef(null);
|
|
575
|
+
React.useEffect(() => {
|
|
576
|
+
if (offset === 0) {
|
|
577
|
+
publish(activeSlideStatus(status));
|
|
578
|
+
}
|
|
579
|
+
}, [offset, status, publish]);
|
|
580
|
+
const handleLoading = useEventCallback((img) => {
|
|
581
|
+
("decode" in img ? img.decode() : Promise.resolve())
|
|
582
|
+
.catch(() => { })
|
|
583
|
+
.then(() => {
|
|
584
|
+
if (!img.parentNode) {
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
setStatus(SLIDE_STATUS_COMPLETE);
|
|
588
|
+
setTimeout(() => {
|
|
589
|
+
onLoad === null || onLoad === void 0 ? void 0 : onLoad(img);
|
|
590
|
+
}, 0);
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
const setImageRef = React.useCallback((img) => {
|
|
594
|
+
imageRef.current = img;
|
|
595
|
+
if (img === null || img === void 0 ? void 0 : img.complete) {
|
|
596
|
+
handleLoading(img);
|
|
597
|
+
}
|
|
598
|
+
}, [handleLoading]);
|
|
599
|
+
const handleOnLoad = React.useCallback((event) => {
|
|
600
|
+
handleLoading(event.currentTarget);
|
|
601
|
+
}, [handleLoading]);
|
|
602
|
+
const onError = React.useCallback(() => {
|
|
603
|
+
setStatus(SLIDE_STATUS_ERROR);
|
|
604
|
+
}, []);
|
|
605
|
+
const cover = isImageFitCover(image, imageFit);
|
|
606
|
+
const nonInfinite = (value, fallback) => (Number.isFinite(value) ? value : fallback);
|
|
607
|
+
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] : [])), ((_c = imageRef.current) === null || _c === void 0 ? void 0 : _c.naturalWidth) || 0);
|
|
608
|
+
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] : [])), ((_f = imageRef.current) === null || _f === void 0 ? void 0 : _f.naturalHeight) || 0);
|
|
609
|
+
const defaultStyle = maxWidth && maxHeight
|
|
610
|
+
? {
|
|
611
|
+
maxWidth: `min(${maxWidth}px, 100%)`,
|
|
612
|
+
maxHeight: `min(${maxHeight}px, 100%)`,
|
|
613
|
+
}
|
|
614
|
+
: {
|
|
615
|
+
maxWidth: "100%",
|
|
616
|
+
maxHeight: "100%",
|
|
617
|
+
};
|
|
618
|
+
const srcSet = (_g = image.srcSet) === null || _g === void 0 ? void 0 : _g.sort((a, b) => a.width - b.width).map((item) => `${item.src} ${item.width}w`).join(", ");
|
|
619
|
+
const estimateActualWidth = () => rect && !cover && image.width && image.height ? (rect.height / image.height) * image.width : Number.MAX_VALUE;
|
|
620
|
+
const sizes = srcSet && rect && hasWindow() ? `${Math.round(Math.min(estimateActualWidth(), rect.width))}px` : undefined;
|
|
621
|
+
return (React.createElement(React.Fragment, null,
|
|
622
|
+
React.createElement("img", { ref: setImageRef, onLoad: handleOnLoad, onError: onError, onClick: onClick, className: clsx(cssClass(slideImagePrefix()), cover && cssClass(slideImagePrefix("cover")), status !== SLIDE_STATUS_COMPLETE && cssClass(slideImagePrefix("loading"))), draggable: false, alt: image.alt, style: { ...defaultStyle, ...style }, sizes: sizes, srcSet: srcSet, src: image.src }),
|
|
623
|
+
status !== SLIDE_STATUS_COMPLETE && (React.createElement("div", { className: cssClass(slidePrefix(SLIDE_STATUS_PLACEHOLDER)) },
|
|
624
|
+
status === SLIDE_STATUS_LOADING &&
|
|
625
|
+
((render === null || render === void 0 ? void 0 : render.iconLoading) ? (render.iconLoading()) : (React.createElement(LoadingIcon, { className: clsx(cssClass(ELEMENT_ICON), cssClass(slidePrefix(SLIDE_STATUS_LOADING))) }))),
|
|
626
|
+
status === SLIDE_STATUS_ERROR &&
|
|
627
|
+
((render === null || render === void 0 ? void 0 : render.iconError) ? (render.iconError()) : (React.createElement(ErrorIcon, { className: clsx(cssClass(ELEMENT_ICON), cssClass(slidePrefix(SLIDE_STATUS_ERROR))) })))))));
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
var SwipeState;
|
|
631
|
+
(function (SwipeState) {
|
|
632
|
+
SwipeState[SwipeState["NONE"] = 0] = "NONE";
|
|
633
|
+
SwipeState[SwipeState["SWIPE"] = 1] = "SWIPE";
|
|
634
|
+
SwipeState[SwipeState["ANIMATION"] = 2] = "ANIMATION";
|
|
635
|
+
})(SwipeState || (SwipeState = {}));
|
|
636
|
+
|
|
637
|
+
function usePointerEvents(subscribeSensors, onPointerDown, onPointerMove, onPointerUp, disabled) {
|
|
638
|
+
React.useEffect(() => {
|
|
639
|
+
if (disabled)
|
|
640
|
+
return () => { };
|
|
641
|
+
return cleanup(subscribeSensors(EVENT_ON_POINTER_DOWN, onPointerDown), subscribeSensors(EVENT_ON_POINTER_MOVE, onPointerMove), subscribeSensors(EVENT_ON_POINTER_UP, onPointerUp), subscribeSensors(EVENT_ON_POINTER_LEAVE, onPointerUp), subscribeSensors(EVENT_ON_POINTER_CANCEL, onPointerUp));
|
|
642
|
+
}, [subscribeSensors, onPointerDown, onPointerMove, onPointerUp, disabled]);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
var Gesture;
|
|
646
|
+
(function (Gesture) {
|
|
647
|
+
Gesture[Gesture["NONE"] = 0] = "NONE";
|
|
648
|
+
Gesture[Gesture["SWIPE"] = 1] = "SWIPE";
|
|
649
|
+
Gesture[Gesture["PULL_DOWN"] = 2] = "PULL_DOWN";
|
|
650
|
+
})(Gesture || (Gesture = {}));
|
|
651
|
+
const SWIPE_THRESHOLD = 30;
|
|
652
|
+
function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAnimationDuration, onSwipeStart, onSwipeProgress, onSwipeFinish, onSwipeCancel, onPullDownStart, onPullDownProgress, onPullDownFinish, onPullDownCancel) {
|
|
492
653
|
const offset = React.useRef(0);
|
|
493
654
|
const pointers = React.useRef([]);
|
|
494
655
|
const activePointer = React.useRef();
|
|
495
656
|
const startTime = React.useRef(0);
|
|
657
|
+
const gesture = React.useRef(Gesture.NONE);
|
|
496
658
|
const clearPointer = React.useCallback((event) => {
|
|
497
659
|
if (activePointer.current === event.pointerId) {
|
|
498
660
|
activePointer.current = undefined;
|
|
661
|
+
gesture.current = Gesture.NONE;
|
|
499
662
|
}
|
|
500
663
|
const currentPointers = pointers.current;
|
|
501
664
|
currentPointers.splice(0, currentPointers.length, ...currentPointers.filter((p) => p.pointerId !== event.pointerId));
|
|
@@ -513,14 +676,25 @@ function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAn
|
|
|
513
676
|
activePointer.current === event.pointerId) {
|
|
514
677
|
const duration = Date.now() - startTime.current;
|
|
515
678
|
const currentOffset = offset.current;
|
|
516
|
-
if (
|
|
517
|
-
(Math.abs(currentOffset) >
|
|
518
|
-
|
|
679
|
+
if (gesture.current === Gesture.SWIPE) {
|
|
680
|
+
if (Math.abs(currentOffset) > 0.3 * containerWidth ||
|
|
681
|
+
(Math.abs(currentOffset) > 5 && duration < swipeAnimationDuration)) {
|
|
682
|
+
onSwipeFinish(currentOffset, duration);
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
onSwipeCancel(currentOffset);
|
|
686
|
+
}
|
|
519
687
|
}
|
|
520
|
-
else {
|
|
521
|
-
|
|
688
|
+
else if (gesture.current === Gesture.PULL_DOWN) {
|
|
689
|
+
if (currentOffset > 2 * SWIPE_THRESHOLD) {
|
|
690
|
+
onPullDownFinish(currentOffset, duration);
|
|
691
|
+
}
|
|
692
|
+
else {
|
|
693
|
+
onPullDownCancel(currentOffset);
|
|
694
|
+
}
|
|
522
695
|
}
|
|
523
696
|
offset.current = 0;
|
|
697
|
+
gesture.current = Gesture.NONE;
|
|
524
698
|
}
|
|
525
699
|
clearPointer(event);
|
|
526
700
|
});
|
|
@@ -539,22 +713,35 @@ function usePointerSwipe(subscribeSensors, isSwipeValid, containerWidth, swipeAn
|
|
|
539
713
|
}
|
|
540
714
|
const deltaX = event.clientX - pointer.clientX;
|
|
541
715
|
const deltaY = event.clientY - pointer.clientY;
|
|
542
|
-
if (activePointer.current === undefined
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
716
|
+
if (activePointer.current === undefined) {
|
|
717
|
+
const startGesture = (newGesture) => {
|
|
718
|
+
addPointer(event);
|
|
719
|
+
activePointer.current = event.pointerId;
|
|
720
|
+
startTime.current = Date.now();
|
|
721
|
+
gesture.current = newGesture;
|
|
722
|
+
};
|
|
723
|
+
if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > SWIPE_THRESHOLD && isSwipeValid(deltaX)) {
|
|
724
|
+
startGesture(Gesture.SWIPE);
|
|
725
|
+
onSwipeStart();
|
|
726
|
+
}
|
|
727
|
+
else if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaY) > SWIPE_THRESHOLD) {
|
|
728
|
+
startGesture(Gesture.PULL_DOWN);
|
|
729
|
+
onPullDownStart();
|
|
730
|
+
}
|
|
550
731
|
}
|
|
551
732
|
else if (isCurrentPointer) {
|
|
552
|
-
|
|
553
|
-
|
|
733
|
+
if (gesture.current === Gesture.SWIPE) {
|
|
734
|
+
offset.current = deltaX;
|
|
735
|
+
onSwipeProgress(deltaX);
|
|
736
|
+
}
|
|
737
|
+
else if (gesture.current === Gesture.PULL_DOWN) {
|
|
738
|
+
offset.current = deltaY;
|
|
739
|
+
onPullDownProgress(deltaY);
|
|
740
|
+
}
|
|
554
741
|
}
|
|
555
742
|
}
|
|
556
743
|
});
|
|
557
|
-
|
|
744
|
+
usePointerEvents(subscribeSensors, onPointerDown, onPointerMove, onPointerUp);
|
|
558
745
|
}
|
|
559
746
|
|
|
560
747
|
const WHEEL = "wheel";
|
|
@@ -665,13 +852,6 @@ function useWheelSwipe(swipeState, subscribeSensors, isSwipeValid, containerWidt
|
|
|
665
852
|
React.useEffect(() => subscribeSensors(EVENT_ON_WHEEL, onWheel), [subscribeSensors, onWheel]);
|
|
666
853
|
}
|
|
667
854
|
|
|
668
|
-
var SwipeState;
|
|
669
|
-
(function (SwipeState) {
|
|
670
|
-
SwipeState[SwipeState["NONE"] = 0] = "NONE";
|
|
671
|
-
SwipeState[SwipeState["SWIPE"] = 1] = "SWIPE";
|
|
672
|
-
SwipeState[SwipeState["ANIMATION"] = 2] = "ANIMATION";
|
|
673
|
-
})(SwipeState || (SwipeState = {}));
|
|
674
|
-
|
|
675
855
|
const cssContainerPrefix = makeComposePrefix("container");
|
|
676
856
|
const ControllerContext = React.createContext(null);
|
|
677
857
|
const useController = makeUseContext("useController", "ControllerContext", ControllerContext);
|
|
@@ -814,7 +994,17 @@ function Controller({ children, ...props }) {
|
|
|
814
994
|
(offset, duration) => swipe({ offset, duration, count: 1 }),
|
|
815
995
|
(offset) => swipe({ offset, count: 0 }),
|
|
816
996
|
];
|
|
817
|
-
|
|
997
|
+
const pullDownParams = [
|
|
998
|
+
() => { },
|
|
999
|
+
() => { },
|
|
1000
|
+
() => {
|
|
1001
|
+
if (controller.closeOnPullDown) {
|
|
1002
|
+
close();
|
|
1003
|
+
}
|
|
1004
|
+
},
|
|
1005
|
+
() => { },
|
|
1006
|
+
];
|
|
1007
|
+
usePointerSwipe(...swipeParams, ...pullDownParams);
|
|
818
1008
|
useWheelSwipe(swipeState, ...swipeParams);
|
|
819
1009
|
const focusOnMount = useEventCallback(() => {
|
|
820
1010
|
var _a;
|
|
@@ -881,145 +1071,6 @@ function Controller({ children, ...props }) {
|
|
|
881
1071
|
}
|
|
882
1072
|
const ControllerModule = createModule(MODULE_CONTROLLER, Controller);
|
|
883
1073
|
|
|
884
|
-
function useLoseFocus(disabled = false) {
|
|
885
|
-
const focused = React.useRef(disabled);
|
|
886
|
-
const { focus } = useController();
|
|
887
|
-
useLayoutEffect(() => {
|
|
888
|
-
if (disabled) {
|
|
889
|
-
focus();
|
|
890
|
-
}
|
|
891
|
-
}, [disabled, focus]);
|
|
892
|
-
const onFocus = React.useCallback(() => {
|
|
893
|
-
focused.current = true;
|
|
894
|
-
}, []);
|
|
895
|
-
const onBlur = React.useCallback(() => {
|
|
896
|
-
focused.current = false;
|
|
897
|
-
}, []);
|
|
898
|
-
return { onFocus, onBlur };
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
function useRTL() {
|
|
902
|
-
const [isRTL, setIsRTL] = React.useState(false);
|
|
903
|
-
useLayoutEffect(() => {
|
|
904
|
-
setIsRTL(window.getComputedStyle(window.document.documentElement).direction === "rtl");
|
|
905
|
-
}, []);
|
|
906
|
-
return isRTL;
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
function useSensors() {
|
|
910
|
-
const [subscribers] = React.useState({});
|
|
911
|
-
return React.useMemo(() => {
|
|
912
|
-
const notifySubscribers = (type, event) => {
|
|
913
|
-
var _a;
|
|
914
|
-
(_a = subscribers[type]) === null || _a === void 0 ? void 0 : _a.forEach((listener) => {
|
|
915
|
-
if (!event.isPropagationStopped())
|
|
916
|
-
listener(event);
|
|
917
|
-
});
|
|
918
|
-
};
|
|
919
|
-
return {
|
|
920
|
-
registerSensors: {
|
|
921
|
-
onPointerDown: (event) => notifySubscribers(EVENT_ON_POINTER_DOWN, event),
|
|
922
|
-
onPointerMove: (event) => notifySubscribers(EVENT_ON_POINTER_MOVE, event),
|
|
923
|
-
onPointerUp: (event) => notifySubscribers(EVENT_ON_POINTER_UP, event),
|
|
924
|
-
onPointerLeave: (event) => notifySubscribers(EVENT_ON_POINTER_LEAVE, event),
|
|
925
|
-
onPointerCancel: (event) => notifySubscribers(EVENT_ON_POINTER_CANCEL, event),
|
|
926
|
-
onKeyDown: (event) => notifySubscribers(EVENT_ON_KEY_DOWN, event),
|
|
927
|
-
onKeyUp: (event) => notifySubscribers(EVENT_ON_KEY_UP, event),
|
|
928
|
-
onWheel: (event) => notifySubscribers(EVENT_ON_WHEEL, event),
|
|
929
|
-
},
|
|
930
|
-
subscribeSensors: (type, callback) => {
|
|
931
|
-
if (!subscribers[type]) {
|
|
932
|
-
subscribers[type] = [];
|
|
933
|
-
}
|
|
934
|
-
subscribers[type].unshift(callback);
|
|
935
|
-
return () => {
|
|
936
|
-
const listeners = subscribers[type];
|
|
937
|
-
if (listeners) {
|
|
938
|
-
listeners.splice(0, listeners.length, ...listeners.filter((el) => el !== callback));
|
|
939
|
-
}
|
|
940
|
-
};
|
|
941
|
-
},
|
|
942
|
-
};
|
|
943
|
-
}, [subscribers]);
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
function useThrottle(callback, delay) {
|
|
947
|
-
const lastCallbackTime = React.useRef(0);
|
|
948
|
-
const delayCallback = useDelay();
|
|
949
|
-
const executeCallback = useEventCallback((...args) => {
|
|
950
|
-
lastCallbackTime.current = Date.now();
|
|
951
|
-
callback(args);
|
|
952
|
-
});
|
|
953
|
-
return React.useCallback((...args) => {
|
|
954
|
-
delayCallback(() => {
|
|
955
|
-
executeCallback(args);
|
|
956
|
-
}, delay - (Date.now() - lastCallbackTime.current));
|
|
957
|
-
}, [delay, executeCallback, delayCallback]);
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
const slidePrefix = makeComposePrefix("slide");
|
|
961
|
-
const slideImagePrefix = makeComposePrefix("slide_image");
|
|
962
|
-
function ImageSlide({ slide: image, offset, render, rect, imageFit, onClick, onLoad, style }) {
|
|
963
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
964
|
-
const [status, setStatus] = React.useState(SLIDE_STATUS_LOADING);
|
|
965
|
-
const { publish } = useEvents();
|
|
966
|
-
const { setTimeout } = useTimeouts();
|
|
967
|
-
const imageRef = React.useRef(null);
|
|
968
|
-
React.useEffect(() => {
|
|
969
|
-
if (offset === 0) {
|
|
970
|
-
publish(activeSlideStatus(status));
|
|
971
|
-
}
|
|
972
|
-
}, [offset, status, publish]);
|
|
973
|
-
const handleLoading = useEventCallback((img) => {
|
|
974
|
-
("decode" in img ? img.decode() : Promise.resolve())
|
|
975
|
-
.catch(() => { })
|
|
976
|
-
.then(() => {
|
|
977
|
-
if (!img.parentNode) {
|
|
978
|
-
return;
|
|
979
|
-
}
|
|
980
|
-
setStatus(SLIDE_STATUS_COMPLETE);
|
|
981
|
-
setTimeout(() => {
|
|
982
|
-
onLoad === null || onLoad === void 0 ? void 0 : onLoad(img);
|
|
983
|
-
}, 0);
|
|
984
|
-
});
|
|
985
|
-
});
|
|
986
|
-
const setImageRef = React.useCallback((img) => {
|
|
987
|
-
imageRef.current = img;
|
|
988
|
-
if (img === null || img === void 0 ? void 0 : img.complete) {
|
|
989
|
-
handleLoading(img);
|
|
990
|
-
}
|
|
991
|
-
}, [handleLoading]);
|
|
992
|
-
const handleOnLoad = React.useCallback((event) => {
|
|
993
|
-
handleLoading(event.currentTarget);
|
|
994
|
-
}, [handleLoading]);
|
|
995
|
-
const onError = React.useCallback(() => {
|
|
996
|
-
setStatus(SLIDE_STATUS_ERROR);
|
|
997
|
-
}, []);
|
|
998
|
-
const cover = isImageFitCover(image, imageFit);
|
|
999
|
-
const nonInfinite = (value, fallback) => (Number.isFinite(value) ? value : fallback);
|
|
1000
|
-
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] : [])), ((_c = imageRef.current) === null || _c === void 0 ? void 0 : _c.naturalWidth) || 0);
|
|
1001
|
-
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] : [])), ((_f = imageRef.current) === null || _f === void 0 ? void 0 : _f.naturalHeight) || 0);
|
|
1002
|
-
const defaultStyle = maxWidth && maxHeight
|
|
1003
|
-
? {
|
|
1004
|
-
maxWidth: `min(${maxWidth}px, 100%)`,
|
|
1005
|
-
maxHeight: `min(${maxHeight}px, 100%)`,
|
|
1006
|
-
}
|
|
1007
|
-
: {
|
|
1008
|
-
maxWidth: "100%",
|
|
1009
|
-
maxHeight: "100%",
|
|
1010
|
-
};
|
|
1011
|
-
const srcSet = (_g = image.srcSet) === null || _g === void 0 ? void 0 : _g.sort((a, b) => a.width - b.width).map((item) => `${item.src} ${item.width}w`).join(", ");
|
|
1012
|
-
const estimateActualWidth = () => rect && !cover && image.width && image.height ? (rect.height / image.height) * image.width : Number.MAX_VALUE;
|
|
1013
|
-
const sizes = srcSet && rect && hasWindow() ? `${Math.round(Math.min(estimateActualWidth(), rect.width))}px` : undefined;
|
|
1014
|
-
return (React.createElement(React.Fragment, null,
|
|
1015
|
-
React.createElement("img", { ref: setImageRef, onLoad: handleOnLoad, onError: onError, onClick: onClick, className: clsx(cssClass(slideImagePrefix()), cover && cssClass(slideImagePrefix("cover")), status !== SLIDE_STATUS_COMPLETE && cssClass(slideImagePrefix("loading"))), draggable: false, alt: image.alt, style: { ...defaultStyle, ...style }, sizes: sizes, srcSet: srcSet, src: image.src }),
|
|
1016
|
-
status !== SLIDE_STATUS_COMPLETE && (React.createElement("div", { className: cssClass(slidePrefix(SLIDE_STATUS_PLACEHOLDER)) },
|
|
1017
|
-
status === SLIDE_STATUS_LOADING &&
|
|
1018
|
-
((render === null || render === void 0 ? void 0 : render.iconLoading) ? (render.iconLoading()) : (React.createElement(LoadingIcon, { className: clsx(cssClass(ELEMENT_ICON), cssClass(slidePrefix(SLIDE_STATUS_LOADING))) }))),
|
|
1019
|
-
status === SLIDE_STATUS_ERROR &&
|
|
1020
|
-
((render === null || render === void 0 ? void 0 : render.iconError) ? (render.iconError()) : (React.createElement(ErrorIcon, { className: clsx(cssClass(ELEMENT_ICON), cssClass(slidePrefix(SLIDE_STATUS_ERROR))) })))))));
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
1074
|
function cssPrefix$2(value) {
|
|
1024
1075
|
return composePrefix(MODULE_CAROUSEL, value);
|
|
1025
1076
|
}
|
|
@@ -1087,7 +1138,7 @@ function Carousel({ carousel: { finite, preload, padding, spacing } }) {
|
|
|
1087
1138
|
const CarouselModule = createModule(MODULE_CAROUSEL, Carousel);
|
|
1088
1139
|
|
|
1089
1140
|
function NavigationButton({ label, icon, renderIcon, action, onClick, disabled }) {
|
|
1090
|
-
return (React.createElement(IconButton, { label: label, icon: icon, renderIcon: renderIcon, className: cssClass(`navigation_${action}`), disabled: disabled, onClick: onClick, ...useLoseFocus(disabled) }));
|
|
1141
|
+
return (React.createElement(IconButton, { label: label, icon: icon, renderIcon: renderIcon, className: cssClass(`navigation_${action}`), disabled: disabled, onClick: onClick, ...useLoseFocus(useController().focus, disabled) }));
|
|
1091
1142
|
}
|
|
1092
1143
|
function Navigation({ carousel: { finite }, animation, render: { buttonPrev, buttonNext, iconPrev, iconNext }, }) {
|
|
1093
1144
|
var _a;
|
|
@@ -1314,4 +1365,4 @@ function Lightbox({ carousel, animation, render, toolbar, controller, on, plugin
|
|
|
1314
1365
|
React.createElement(EventsProvider, null, renderNode(createNode(RootModule, config), props))))));
|
|
1315
1366
|
}
|
|
1316
1367
|
|
|
1317
|
-
export { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, CLASS_FLEX_CENTER, CLASS_FULLSIZE, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, 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, TimeoutsContext, TimeoutsProvider, Toolbar, ToolbarModule, UNKNOWN_ACTION_TYPE, VK_ARROW_LEFT, VK_ARROW_RIGHT, VK_ESCAPE, activeSlideStatus, addToolbarButton, 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, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useRTL, useSensors, useThrottle, useTimeouts, withPlugins };
|
|
1368
|
+
export { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, CLASS_FLEX_CENTER, CLASS_FULLSIZE, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, 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, TimeoutsContext, TimeoutsProvider, Toolbar, ToolbarModule, UNKNOWN_ACTION_TYPE, VK_ARROW_LEFT, VK_ARROW_RIGHT, VK_ESCAPE, activeSlideStatus, addToolbarButton, 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, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, usePointerEvents, useRTL, useSensors, useThrottle, useTimeouts, withPlugins };
|
|
@@ -94,7 +94,7 @@ const PauseIcon = createIcon("Pause", React.createElement("path", { d: "M6 19h4V
|
|
|
94
94
|
function SlideshowButton() {
|
|
95
95
|
const { playing, disabled, play, pause } = useSlideshow();
|
|
96
96
|
const { render } = useLightboxProps();
|
|
97
|
-
const focusListeners = useLoseFocus(disabled);
|
|
97
|
+
const focusListeners = useLoseFocus(useController().focus, disabled);
|
|
98
98
|
if (render.buttonSlideshow) {
|
|
99
99
|
return React.createElement(React.Fragment, null, render.buttonSlideshow({ playing, disabled, play, pause }));
|
|
100
100
|
}
|
|
@@ -80,9 +80,8 @@ function isHorizontal(position) {
|
|
|
80
80
|
function boxSize(thumbnails, dimension, includeGap) {
|
|
81
81
|
return dimension + 2 * (thumbnails.border + thumbnails.padding) + (includeGap ? thumbnails.gap : 0);
|
|
82
82
|
}
|
|
83
|
-
function ThumbnailsTrack({ containerRef }) {
|
|
83
|
+
function ThumbnailsTrack({ visible, containerRef }) {
|
|
84
84
|
const track = React.useRef(null);
|
|
85
|
-
const { visible } = useThumbnails();
|
|
86
85
|
const { carousel, styles } = useLightboxProps();
|
|
87
86
|
const { slides, globalIndex, animation } = useLightboxState();
|
|
88
87
|
const { publish, subscribe } = useEvents();
|
|
@@ -222,9 +221,9 @@ function ThumbnailsContextProvider({ children, ...props }) {
|
|
|
222
221
|
return (React.createElement(LightboxPropsProvider, { ...props },
|
|
223
222
|
React.createElement(ThumbnailsContext.Provider, { value: context },
|
|
224
223
|
React.createElement("div", { ref: containerRef, className: clsx(cssClass(cssPrefix()), cssClass(cssPrefix(`${position}`))) },
|
|
225
|
-
["start", "top"].includes(position) && React.createElement(ThumbnailsTrack, { containerRef: containerRef }),
|
|
224
|
+
["start", "top"].includes(position) && (React.createElement(ThumbnailsTrack, { containerRef: containerRef, visible: visible })),
|
|
226
225
|
React.createElement("div", { className: cssClass(cssPrefix("wrapper")) }, children),
|
|
227
|
-
["end", "bottom"].includes(position) && React.createElement(ThumbnailsTrack, { containerRef: containerRef })))));
|
|
226
|
+
["end", "bottom"].includes(position) && (React.createElement(ThumbnailsTrack, { containerRef: containerRef, visible: visible }))))));
|
|
228
227
|
}
|
|
229
228
|
|
|
230
229
|
const thumbnailsIcon = () => (React.createElement(React.Fragment, null,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useLightboxProps, useMotionPreference, useEventCallback, useLayoutEffect, useLightboxState, isImageSlide, isImageFitCover, round, useController, cleanup, makeUseContext, createIcon, IconButton, devicePixelRatio, ImageSlide, clsx, cssClass, addToolbarButton, createModule } from '../../index.js';
|
|
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
|
-
import { EVENT_ON_KEY_DOWN, EVENT_ON_WHEEL,
|
|
3
|
+
import { EVENT_ON_KEY_DOWN, EVENT_ON_WHEEL, UNKNOWN_ACTION_TYPE, CLASS_FULLSIZE, CLASS_FLEX_CENTER, PLUGIN_ZOOM } from '../../types.js';
|
|
4
4
|
|
|
5
5
|
const defaultZoomProps = {
|
|
6
6
|
maxZoomPixelRatio: 1,
|
|
@@ -255,13 +255,14 @@ function useZoomSensors(zoom, maxZoom, disabled, changeZoom, changeOffsets, zoom
|
|
|
255
255
|
lastPointerDown.current = 0;
|
|
256
256
|
pinchZoomDistance.current = undefined;
|
|
257
257
|
}, []);
|
|
258
|
+
usePointerEvents(subscribeSensors, onPointerDown, onPointerMove, onPointerUp, disabled);
|
|
258
259
|
React.useEffect(cleanupSensors, [globalIndex, cleanupSensors]);
|
|
259
260
|
React.useEffect(() => {
|
|
260
261
|
if (!disabled) {
|
|
261
|
-
return cleanup(cleanupSensors, subscribeSensors(EVENT_ON_KEY_DOWN, onKeyDown), subscribeSensors(EVENT_ON_WHEEL, onWheel)
|
|
262
|
+
return cleanup(cleanupSensors, subscribeSensors(EVENT_ON_KEY_DOWN, onKeyDown), subscribeSensors(EVENT_ON_WHEEL, onWheel));
|
|
262
263
|
}
|
|
263
264
|
return () => { };
|
|
264
|
-
}, [disabled, subscribeSensors, cleanupSensors, onKeyDown, onWheel
|
|
265
|
+
}, [disabled, subscribeSensors, cleanupSensors, onKeyDown, onWheel]);
|
|
265
266
|
}
|
|
266
267
|
|
|
267
268
|
function getCurrentSource(slides, currentIndex) {
|
package/dist/types.d.ts
CHANGED
|
@@ -213,6 +213,8 @@ interface ControllerSettings {
|
|
|
213
213
|
touchAction: "none" | "pan-y";
|
|
214
214
|
/** if `true`, set ARIA attributes on the controller div */
|
|
215
215
|
aria: boolean;
|
|
216
|
+
/** if `true`, close the lightbox on pull-down gesture */
|
|
217
|
+
closeOnPullDown: boolean;
|
|
216
218
|
/** if `true`, close the lightbox when the backdrop is clicked */
|
|
217
219
|
closeOnBackdropClick: boolean;
|
|
218
220
|
}
|