yet-another-react-lightbox 1.8.0 → 1.9.1
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 +10 -7
- package/dist/core/components/IconButton.d.ts +1 -1
- package/dist/core/components/IconButton.js +2 -1
- package/dist/core/components/ImageSlide.js +23 -27
- package/dist/core/contexts/Timeouts.js +2 -2
- package/dist/core/hooks/index.d.ts +2 -0
- package/dist/core/hooks/index.js +2 -0
- package/dist/core/hooks/useMotionPreference.d.ts +1 -0
- package/dist/core/hooks/useMotionPreference.js +12 -0
- package/dist/core/hooks/useRTL.d.ts +1 -0
- package/dist/core/hooks/useRTL.js +9 -0
- package/dist/core/hooks/useSensors.js +5 -2
- package/dist/core/modules/Controller.d.ts +4 -2
- package/dist/core/modules/Controller.js +20 -16
- package/dist/core/modules/Navigation.js +8 -6
- package/dist/core/utils.d.ts +2 -1
- package/dist/core/utils.js +5 -1
- package/dist/plugins/Captions.js +2 -2
- package/dist/plugins/Fullscreen.d.ts +2 -3
- package/dist/plugins/Thumbnails.d.ts +7 -6
- package/dist/plugins/Thumbnails.js +30 -33
- package/dist/plugins/Zoom.d.ts +51 -0
- package/dist/plugins/Zoom.js +423 -0
- package/dist/plugins/captions.css +0 -1
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.js +1 -0
- package/dist/plugins/thumbnails.css +0 -1
- package/dist/styles.css +1 -3
- package/dist/types.d.ts +11 -1
- package/package.json +17 -13
package/README.md
CHANGED
|
@@ -14,10 +14,11 @@ Modern React lightbox component. Performant, easy to use, customizable and exten
|
|
|
14
14
|
- **Performance:** preloads limited number of images without compromising performance or UX
|
|
15
15
|
- **Responsive:** responsive images with automatic resolution switching are supported out of the box
|
|
16
16
|
- **Video:** video slides are supported via an optional plugin
|
|
17
|
+
- **Zoom:** image zoom is supported via an optional plugin
|
|
17
18
|
- **Customization:** customize any UI element or add your own custom slides
|
|
18
19
|
- **No bloat:** never bundle rarely used features; add optional features via plugins
|
|
19
|
-
- **RTL:** compatible with RTL layout
|
|
20
20
|
- **TypeScript:** type definitions come built-in in the package
|
|
21
|
+
- **RTL:** compatible with RTL layout
|
|
21
22
|
|
|
22
23
|
## Documentation
|
|
23
24
|
|
|
@@ -99,13 +100,14 @@ const App = () => {
|
|
|
99
100
|
{
|
|
100
101
|
src: "/image1x3840.jpg",
|
|
101
102
|
alt: "image 1",
|
|
102
|
-
|
|
103
|
+
width: 3840,
|
|
104
|
+
height: 2560,
|
|
103
105
|
srcSet: [
|
|
104
|
-
{ src: "/image1x320.jpg", width: 320 },
|
|
105
|
-
{ src: "/image1x640.jpg", width: 640 },
|
|
106
|
-
{ src: "/image1x1200.jpg", width: 1200 },
|
|
107
|
-
{ src: "/image1x2048.jpg", width: 2048 },
|
|
108
|
-
{ src: "/image1x3840.jpg", width: 3840 },
|
|
106
|
+
{ src: "/image1x320.jpg", width: 320, height: 213 },
|
|
107
|
+
{ src: "/image1x640.jpg", width: 640, height: 427 },
|
|
108
|
+
{ src: "/image1x1200.jpg", width: 1200, height: 800 },
|
|
109
|
+
{ src: "/image1x2048.jpg", width: 2048, height: 1365 },
|
|
110
|
+
{ src: "/image1x3840.jpg", width: 3840, height: 2560 },
|
|
109
111
|
]
|
|
110
112
|
},
|
|
111
113
|
// ...
|
|
@@ -134,6 +136,7 @@ The following plugins come bundled in the package:
|
|
|
134
136
|
- [Slideshow](https://yet-another-react-lightbox.vercel.app/plugins/slideshow) - adds slideshow autoplay feature
|
|
135
137
|
- [Thumbnails](https://yet-another-react-lightbox.vercel.app/plugins/thumbnails) - adds thumbnails track
|
|
136
138
|
- [Video](https://yet-another-react-lightbox.vercel.app/plugins/video) - adds support for video slides
|
|
139
|
+
- [Zoom](https://yet-another-react-lightbox.vercel.app/plugins/zoom) - adds image zoom feature
|
|
137
140
|
|
|
138
141
|
## License
|
|
139
142
|
|
|
@@ -4,4 +4,4 @@ export declare type IconButtonProps = Omit<React.DetailedHTMLProps<React.ButtonH
|
|
|
4
4
|
icon: React.ElementType;
|
|
5
5
|
renderIcon?: () => React.ReactNode;
|
|
6
6
|
};
|
|
7
|
-
export declare const IconButton: React.
|
|
7
|
+
export declare const IconButton: React.ForwardRefExoticComponent<Pick<IconButtonProps, "value" | "children" | "onPointerDown" | "onPointerMove" | "onPointerUp" | "onPointerLeave" | "onPointerCancel" | "onTouchStart" | "onTouchMove" | "onTouchEnd" | "onTouchCancel" | "onKeyDown" | "onKeyUp" | "onWheel" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "id" | "lang" | "placeholder" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancelCapture" | "onTouchEndCapture" | "onTouchMoveCapture" | "onTouchStartCapture" | "onPointerDownCapture" | "onPointerMoveCapture" | "onPointerUpCapture" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "form" | "label" | "autoFocus" | "disabled" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "name" | "icon" | "renderIcon"> & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { clsx, cssClass } from "../utils.js";
|
|
3
|
-
export const IconButton = ({ label, className, icon: Icon, renderIcon, onClick, ...rest }) => (React.createElement("button", { type: "button", "aria-label": label, className: clsx(cssClass("button"), className), onClick: onClick, ...rest }, renderIcon ? renderIcon() : React.createElement(Icon, { className: cssClass("icon") })));
|
|
3
|
+
export const IconButton = React.forwardRef(({ label, className, icon: Icon, renderIcon, onClick, ...rest }, ref) => (React.createElement("button", { ref: ref, type: "button", "aria-label": label, className: clsx(cssClass("button"), className), onClick: onClick, ...rest }, renderIcon ? renderIcon() : React.createElement(Icon, { className: cssClass("icon") }))));
|
|
4
|
+
IconButton.displayName = "IconButton";
|
|
@@ -3,9 +3,9 @@ import { adjustDevicePixelRatio, clsx, cssClass, hasWindow } from "../utils.js";
|
|
|
3
3
|
import { useLatest } from "../hooks/index.js";
|
|
4
4
|
import { useEvents } from "../contexts/index.js";
|
|
5
5
|
import { ErrorIcon, LoadingIcon } from "./Icons.js";
|
|
6
|
-
import { activeSlideStatus, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_LOADING } from "../consts.js";
|
|
6
|
+
import { activeSlideStatus, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_LOADING, } from "../consts.js";
|
|
7
7
|
export const ImageSlide = ({ slide: image, offset, render, rect, imageFit }) => {
|
|
8
|
-
var _a;
|
|
8
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
9
9
|
const [status, setStatus] = React.useState(SLIDE_STATUS_LOADING);
|
|
10
10
|
const latestStatus = useLatest(status);
|
|
11
11
|
const { publish } = useEvents();
|
|
@@ -40,32 +40,28 @@ export const ImageSlide = ({ slide: image, offset, render, rect, imageFit }) =>
|
|
|
40
40
|
const onError = React.useCallback(() => {
|
|
41
41
|
setStatus(SLIDE_STATUS_ERROR);
|
|
42
42
|
}, []);
|
|
43
|
+
const cover = image.imageFit === "cover" || (image.imageFit !== "contain" && imageFit === "cover");
|
|
44
|
+
const nonInfinite = (value, fallback) => (Number.isFinite(value) ? value : fallback);
|
|
45
|
+
const maxWidth = adjustDevicePixelRatio(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));
|
|
46
|
+
const maxHeight = adjustDevicePixelRatio(nonInfinite(Math.max(...((_e = (_d = image.srcSet) === null || _d === void 0 ? void 0 : _d.map((x) => x.height).filter((x) => Boolean(x))) !== null && _e !== void 0 ? _e : []).concat(image.height ? [image.height] : [])), (image.aspectRatio && maxWidth ? maxWidth / image.aspectRatio : (_f = imageRef.current) === null || _f === void 0 ? void 0 : _f.naturalHeight) || 0));
|
|
47
|
+
const style = maxWidth && maxHeight ? { maxWidth, maxHeight } : undefined;
|
|
48
|
+
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(", ");
|
|
49
|
+
const estimateActualWidth = () => {
|
|
50
|
+
if (rect && !cover) {
|
|
51
|
+
if (image.width && image.height) {
|
|
52
|
+
return (rect.height / image.height) * image.width;
|
|
53
|
+
}
|
|
54
|
+
if (image.aspectRatio) {
|
|
55
|
+
return rect.height * image.aspectRatio;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return Number.MAX_VALUE;
|
|
59
|
+
};
|
|
60
|
+
const sizes = srcSet && rect && hasWindow()
|
|
61
|
+
? `${Math.ceil((Math.min(estimateActualWidth(), rect.width) / window.innerWidth) * 100)}vw`
|
|
62
|
+
: undefined;
|
|
43
63
|
return (React.createElement(React.Fragment, null,
|
|
44
|
-
React.createElement("img", { ref: setImageRef, onLoad: onLoad, onError: onError, className: clsx(cssClass("slide_image"), cssClass("fullsize"), (
|
|
45
|
-
cssClass("slide_image_cover"), status !== SLIDE_STATUS_COMPLETE && cssClass("slide_image_loading")), draggable: false, alt: image.alt, ...(image.srcSet
|
|
46
|
-
? {
|
|
47
|
-
...(rect && hasWindow()
|
|
48
|
-
? {
|
|
49
|
-
sizes: `${Math.ceil((Math.min(image.aspectRatio ? rect.height * image.aspectRatio : Number.MAX_VALUE, rect.width) /
|
|
50
|
-
window.innerWidth) *
|
|
51
|
-
100)}vw`,
|
|
52
|
-
}
|
|
53
|
-
: null),
|
|
54
|
-
srcSet: image.srcSet
|
|
55
|
-
.sort((a, b) => a.width - b.width)
|
|
56
|
-
.map((item) => `${item.src} ${item.width}w`)
|
|
57
|
-
.join(", "),
|
|
58
|
-
style: {
|
|
59
|
-
maxWidth: `${adjustDevicePixelRatio(Math.max(...image.srcSet.map((x) => x.width)))}px`,
|
|
60
|
-
},
|
|
61
|
-
}
|
|
62
|
-
: {
|
|
63
|
-
style: imageRef.current && ((_a = imageRef.current) === null || _a === void 0 ? void 0 : _a.naturalWidth) > 0
|
|
64
|
-
? {
|
|
65
|
-
maxWidth: `${adjustDevicePixelRatio(imageRef.current.naturalWidth)}px`,
|
|
66
|
-
}
|
|
67
|
-
: undefined,
|
|
68
|
-
}), src: image.src }),
|
|
64
|
+
React.createElement("img", { ref: setImageRef, onLoad: onLoad, onError: onError, className: clsx(cssClass("slide_image"), cssClass("fullsize"), cover && cssClass("slide_image_cover"), status !== SLIDE_STATUS_COMPLETE && cssClass("slide_image_loading")), draggable: false, alt: image.alt, style: style, sizes: sizes, srcSet: srcSet, src: image.src }),
|
|
69
65
|
status !== SLIDE_STATUS_COMPLETE && (React.createElement("div", { className: cssClass("slide_placeholder") },
|
|
70
66
|
status === SLIDE_STATUS_LOADING &&
|
|
71
67
|
((render === null || render === void 0 ? void 0 : render.iconLoading) ? (render.iconLoading()) : (React.createElement(LoadingIcon, { className: clsx(cssClass("icon"), cssClass("slide_loading")) }))),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { makeUseContext } from "../utils.js";
|
|
2
|
+
import { isDefined, makeUseContext } from "../utils.js";
|
|
3
3
|
const TimeoutsContext = React.createContext(null);
|
|
4
4
|
export const useTimeouts = makeUseContext("useTimeouts", "TimeoutsContext", TimeoutsContext);
|
|
5
5
|
export const TimeoutsProvider = ({ children }) => {
|
|
@@ -16,7 +16,7 @@ export const TimeoutsProvider = ({ children }) => {
|
|
|
16
16
|
return id;
|
|
17
17
|
};
|
|
18
18
|
const clearTimeout = (id) => {
|
|
19
|
-
if (
|
|
19
|
+
if (isDefined(id)) {
|
|
20
20
|
removeTimeout(id);
|
|
21
21
|
window.clearTimeout(id);
|
|
22
22
|
}
|
package/dist/core/hooks/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useMotionPreference: () => boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useEnhancedEffect } from "./useEnhancedEffect.js";
|
|
3
|
+
export const useMotionPreference = () => {
|
|
4
|
+
const [reduceMotion, setReduceMotion] = React.useState(false);
|
|
5
|
+
useEnhancedEffect(() => {
|
|
6
|
+
var _a;
|
|
7
|
+
const mediaQuery = (_a = window.matchMedia) === null || _a === void 0 ? void 0 : _a.call(window, "(prefers-reduced-motion: reduce)");
|
|
8
|
+
mediaQuery === null || mediaQuery === void 0 ? void 0 : mediaQuery.addEventListener("change", () => setReduceMotion(mediaQuery.matches));
|
|
9
|
+
setReduceMotion(mediaQuery === null || mediaQuery === void 0 ? void 0 : mediaQuery.matches);
|
|
10
|
+
}, []);
|
|
11
|
+
return reduceMotion;
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useRTL: () => boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useEnhancedEffect } from "./useEnhancedEffect.js";
|
|
3
|
+
export const useRTL = () => {
|
|
4
|
+
const [isRTL, setIsRTL] = React.useState(false);
|
|
5
|
+
useEnhancedEffect(() => {
|
|
6
|
+
setIsRTL(window.getComputedStyle(window.document.documentElement).direction === "rtl");
|
|
7
|
+
}, []);
|
|
8
|
+
return isRTL;
|
|
9
|
+
};
|
|
@@ -4,7 +4,10 @@ export const useSensors = () => {
|
|
|
4
4
|
return React.useMemo(() => {
|
|
5
5
|
const notifySubscribers = (type, event) => {
|
|
6
6
|
var _a;
|
|
7
|
-
(_a = subscribers[type]) === null || _a === void 0 ? void 0 : _a.forEach((listener) =>
|
|
7
|
+
(_a = subscribers[type]) === null || _a === void 0 ? void 0 : _a.forEach((listener) => {
|
|
8
|
+
if (!event.isPropagationStopped())
|
|
9
|
+
listener(event);
|
|
10
|
+
});
|
|
8
11
|
};
|
|
9
12
|
return {
|
|
10
13
|
registerSensors: {
|
|
@@ -25,7 +28,7 @@ export const useSensors = () => {
|
|
|
25
28
|
if (!subscribers[type]) {
|
|
26
29
|
subscribers[type] = [];
|
|
27
30
|
}
|
|
28
|
-
subscribers[type].
|
|
31
|
+
subscribers[type].unshift(callback);
|
|
29
32
|
return () => {
|
|
30
33
|
const listeners = subscribers[type];
|
|
31
34
|
if (listeners) {
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { Component, ComponentProps } from "../../types.js";
|
|
3
|
-
import { SubscribeSensors } from "../hooks/index.js";
|
|
3
|
+
import { ContainerRect, SubscribeSensors } from "../hooks/index.js";
|
|
4
4
|
declare type ControllerState = {
|
|
5
5
|
currentIndex: number;
|
|
6
6
|
globalIndex: number;
|
|
7
|
-
isRTL: boolean;
|
|
8
7
|
};
|
|
9
8
|
export declare type ControllerContextType = ControllerState & {
|
|
10
9
|
latestProps: React.MutableRefObject<ComponentProps>;
|
|
11
10
|
subscribeSensors: SubscribeSensors<HTMLDivElement>;
|
|
11
|
+
transferFocus: () => void;
|
|
12
|
+
containerRect: ContainerRect;
|
|
13
|
+
containerRef: React.RefObject<HTMLDivElement>;
|
|
12
14
|
};
|
|
13
15
|
export declare const useController: () => ControllerContextType;
|
|
14
16
|
export declare const Controller: Component;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { LightboxDefaultProps } from "../../types.js";
|
|
3
|
-
import { cleanup, clsx, cssClass, cssVar,
|
|
3
|
+
import { cleanup, clsx, cssClass, cssVar, makeUseContext } from "../utils.js";
|
|
4
4
|
import { createModule } from "../config.js";
|
|
5
|
-
import { useContainerRect, useEnhancedEffect, useLatest, useSensors } from "../hooks/index.js";
|
|
5
|
+
import { useContainerRect, useEnhancedEffect, useLatest, useRTL, useSensors, } from "../hooks/index.js";
|
|
6
6
|
import { useEvents, useTimeouts } from "../contexts/index.js";
|
|
7
7
|
const SWIPE_OFFSET_THRESHOLD = 30;
|
|
8
8
|
const ControllerContext = React.createContext(null);
|
|
9
9
|
export const useController = makeUseContext("useController", "ControllerContext", ControllerContext);
|
|
10
10
|
export const Controller = ({ children, ...props }) => {
|
|
11
|
-
const { containerRef, setContainerRef } = useContainerRect();
|
|
11
|
+
const { containerRef, setContainerRef, containerRect } = useContainerRect();
|
|
12
12
|
const { registerSensors, subscribeSensors } = useSensors();
|
|
13
13
|
const { subscribe, publish } = useEvents();
|
|
14
14
|
const { setTimeout, clearTimeout } = useTimeouts();
|
|
15
|
+
const isRTL = useLatest(useRTL());
|
|
15
16
|
const [state, setState] = React.useState({
|
|
16
17
|
currentIndex: props.index,
|
|
17
18
|
globalIndex: props.index,
|
|
18
|
-
isRTL: false,
|
|
19
19
|
});
|
|
20
20
|
const latestProps = useLatest(props);
|
|
21
21
|
const refs = React.useRef({
|
|
@@ -31,7 +31,7 @@ export const Controller = ({ children, ...props }) => {
|
|
|
31
31
|
refs.current.props = props;
|
|
32
32
|
useEnhancedEffect(() => {
|
|
33
33
|
const preventDefault = (event) => {
|
|
34
|
-
if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) {
|
|
34
|
+
if (Math.abs(event.deltaX) > Math.abs(event.deltaY) || event.ctrlKey) {
|
|
35
35
|
event.preventDefault();
|
|
36
36
|
}
|
|
37
37
|
};
|
|
@@ -45,12 +45,6 @@ export const Controller = ({ children, ...props }) => {
|
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
47
|
}, [containerRef]);
|
|
48
|
-
useEnhancedEffect(() => {
|
|
49
|
-
const node = containerRef.current;
|
|
50
|
-
if (node) {
|
|
51
|
-
setState((prev) => ({ ...prev, isRTL: isRTL(node) }));
|
|
52
|
-
}
|
|
53
|
-
}, [containerRef]);
|
|
54
48
|
React.useEffect(() => {
|
|
55
49
|
var _a;
|
|
56
50
|
if (refs.current.props.controller.focus) {
|
|
@@ -87,7 +81,7 @@ export const Controller = ({ children, ...props }) => {
|
|
|
87
81
|
clearTimeout(current.swipeIntentCleanup);
|
|
88
82
|
current.swipeIntentCleanup = undefined;
|
|
89
83
|
}, [clearTimeout]);
|
|
90
|
-
const rtl = React.useCallback((value) => (
|
|
84
|
+
const rtl = React.useCallback((value) => (isRTL.current ? -1 : 1) * (typeof value === "number" ? value : 1), [isRTL]);
|
|
91
85
|
const isSwipeValid = React.useCallback((offset) => {
|
|
92
86
|
const { state: { currentIndex }, props: { carousel, slides }, } = refs.current;
|
|
93
87
|
return !(carousel.finite &&
|
|
@@ -275,13 +269,24 @@ export const Controller = ({ children, ...props }) => {
|
|
|
275
269
|
}
|
|
276
270
|
}, [updateSwipeOffset, setTimeout, clearTimeout, swipe, resetSwipe, rerender, isSwipeValid, containerRef]);
|
|
277
271
|
React.useEffect(() => subscribeSensors("onWheel", onWheel), [subscribeSensors, onWheel]);
|
|
272
|
+
const transferFocus = React.useCallback(() => { var _a; return (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, [containerRef]);
|
|
278
273
|
const context = React.useMemo(() => ({
|
|
279
274
|
latestProps,
|
|
280
275
|
currentIndex: state.currentIndex,
|
|
281
276
|
globalIndex: state.globalIndex,
|
|
282
|
-
isRTL: state.isRTL,
|
|
283
277
|
subscribeSensors,
|
|
284
|
-
|
|
278
|
+
transferFocus,
|
|
279
|
+
containerRect,
|
|
280
|
+
containerRef,
|
|
281
|
+
}), [
|
|
282
|
+
latestProps,
|
|
283
|
+
state.currentIndex,
|
|
284
|
+
state.globalIndex,
|
|
285
|
+
subscribeSensors,
|
|
286
|
+
transferFocus,
|
|
287
|
+
containerRect,
|
|
288
|
+
containerRef,
|
|
289
|
+
]);
|
|
285
290
|
return (React.createElement("div", { ref: setContainerRef, className: clsx(cssClass("container"), cssClass("fullsize"), refs.current.swipeState === "swipe" && cssClass("container_swipe")), style: {
|
|
286
291
|
...(refs.current.swipeAnimationDuration !== LightboxDefaultProps.animation.swipe
|
|
287
292
|
? {
|
|
@@ -293,7 +298,6 @@ export const Controller = ({ children, ...props }) => {
|
|
|
293
298
|
[cssVar("controller_touch_action")]: props.controller.touchAction,
|
|
294
299
|
}
|
|
295
300
|
: null),
|
|
296
|
-
}, role: "presentation", "aria-live": "polite", tabIndex: -1, ...registerSensors },
|
|
297
|
-
React.createElement(ControllerContext.Provider, { value: context }, children)));
|
|
301
|
+
}, role: "presentation", "aria-live": "polite", tabIndex: -1, ...registerSensors }, containerRect && (React.createElement(ControllerContext.Provider, { value: context }, children))));
|
|
298
302
|
};
|
|
299
303
|
export const ControllerModule = createModule("controller", Controller);
|
|
@@ -4,18 +4,20 @@ import { cssClass, label as translateLabel } from "../utils.js";
|
|
|
4
4
|
import { IconButton, NextIcon, PreviousIcon } from "../components/index.js";
|
|
5
5
|
import { useEvents } from "../contexts/index.js";
|
|
6
6
|
import { useController } from "./Controller.js";
|
|
7
|
+
import { useLatest, useRTL } from "../hooks/index.js";
|
|
7
8
|
export const NavigationButton = ({ publish, labels, label, icon, renderIcon, action, disabled, }) => (React.createElement(IconButton, { label: translateLabel(labels, label), icon: icon, renderIcon: renderIcon, className: cssClass(`navigation_${action}`), disabled: disabled, "aria-disabled": disabled, onClick: () => {
|
|
8
9
|
publish(action);
|
|
9
10
|
} }));
|
|
10
11
|
export const Navigation = ({ slides, carousel: { finite }, labels, render: { buttonPrev, buttonNext, iconPrev, iconNext }, }) => {
|
|
11
|
-
const { currentIndex, subscribeSensors
|
|
12
|
+
const { currentIndex, subscribeSensors } = useController();
|
|
12
13
|
const { publish } = useEvents();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const isRTL = useLatest(useRTL());
|
|
15
|
+
React.useEffect(() => subscribeSensors("onKeyDown", (event) => {
|
|
16
|
+
if (event.key === "ArrowLeft") {
|
|
17
|
+
publish(isRTL.current ? "next" : "prev");
|
|
16
18
|
}
|
|
17
|
-
else if (event.
|
|
18
|
-
publish(isRTL ? "prev" : "next");
|
|
19
|
+
else if (event.key === "ArrowRight") {
|
|
20
|
+
publish(isRTL.current ? "prev" : "next");
|
|
19
21
|
}
|
|
20
22
|
}), [subscribeSensors, publish, isRTL]);
|
|
21
23
|
return (React.createElement(React.Fragment, null,
|
package/dist/core/utils.d.ts
CHANGED
|
@@ -7,5 +7,6 @@ export declare const label: (labels: Labels | undefined, lbl: string) => string;
|
|
|
7
7
|
export declare const cleanup: (...cleaners: (() => void)[]) => () => void;
|
|
8
8
|
export declare const makeUseContext: <T>(name: string, contextName: string, context: React.Context<T | null>) => () => T;
|
|
9
9
|
export declare const hasWindow: () => boolean;
|
|
10
|
+
export declare const isDefined: <T = any>(x: T | undefined) => x is T;
|
|
10
11
|
export declare const adjustDevicePixelRatio: (value: number) => number;
|
|
11
|
-
export declare const
|
|
12
|
+
export declare const round: (value: number, decimals?: number) => number;
|
package/dist/core/utils.js
CHANGED
|
@@ -17,5 +17,9 @@ export const makeUseContext = (name, contextName, context) => () => {
|
|
|
17
17
|
return ctx;
|
|
18
18
|
};
|
|
19
19
|
export const hasWindow = () => typeof window !== "undefined";
|
|
20
|
+
export const isDefined = (x) => typeof x !== "undefined";
|
|
20
21
|
export const adjustDevicePixelRatio = (value) => hasWindow() ? Math.round(value / (window.devicePixelRatio || 1)) : value;
|
|
21
|
-
export const
|
|
22
|
+
export const round = (value, decimals = 0) => {
|
|
23
|
+
const factor = 10 ** decimals;
|
|
24
|
+
return Math.round((value + Number.EPSILON) * factor) / factor;
|
|
25
|
+
};
|
package/dist/plugins/Captions.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { cssClass, cssVar, makeUseContext } from "../core/utils.js";
|
|
2
|
+
import { cssClass, cssVar, isDefined, makeUseContext } from "../core/utils.js";
|
|
3
3
|
import { useEvents } from "../core/contexts/Events.js";
|
|
4
4
|
import { createModule } from "../core/index.js";
|
|
5
5
|
const defaultTextAlign = "start";
|
|
@@ -27,7 +27,7 @@ export const CaptionsComponent = ({ children }) => {
|
|
|
27
27
|
const { subscribe } = useEvents();
|
|
28
28
|
const [toolbarWidth, setToolbarWidth] = React.useState();
|
|
29
29
|
React.useEffect(() => subscribe("toolbar-width", (topic, event) => {
|
|
30
|
-
if (
|
|
30
|
+
if (!isDefined(event) || typeof event === "number") {
|
|
31
31
|
setToolbarWidth(event);
|
|
32
32
|
}
|
|
33
33
|
}), [subscribe]);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { Component, LightboxProps, Plugin
|
|
2
|
+
import { Component, LightboxProps, Plugin } from "../types.js";
|
|
3
3
|
declare module "../types.js" {
|
|
4
4
|
interface LightboxProps {
|
|
5
5
|
/** if `true`, enter fullscreen mode automatically when the lightbox opens */
|
|
@@ -37,9 +37,8 @@ declare global {
|
|
|
37
37
|
}
|
|
38
38
|
export declare const FullscreenContainer: Component;
|
|
39
39
|
/** Fullscreen button props */
|
|
40
|
-
export declare type FullscreenButtonProps = Pick<LightboxProps, "labels"> & {
|
|
40
|
+
export declare type FullscreenButtonProps = Pick<LightboxProps, "labels" | "render"> & {
|
|
41
41
|
auto: boolean;
|
|
42
|
-
render: Render;
|
|
43
42
|
};
|
|
44
43
|
/** Fullscreen button */
|
|
45
44
|
export declare const FullscreenButton: React.FC<FullscreenButtonProps>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { Component, LightboxProps, Plugin } from "../types.js";
|
|
2
|
+
import { Component, DeepNonNullable, LightboxProps, Plugin } from "../types.js";
|
|
3
3
|
import { ContainerRect } from "../core/index.js";
|
|
4
|
-
declare type Position = "top" | "bottom" | "start" | "end";
|
|
4
|
+
export declare type Position = "top" | "bottom" | "start" | "end";
|
|
5
5
|
declare module "../types.js" {
|
|
6
6
|
interface LightboxProps {
|
|
7
7
|
/** Thumbnails plugin settings */
|
|
@@ -20,18 +20,19 @@ declare module "../types.js" {
|
|
|
20
20
|
padding?: number;
|
|
21
21
|
/** gap between thumbnails */
|
|
22
22
|
gap?: number;
|
|
23
|
+
/** `object-fit` setting */
|
|
24
|
+
imageFit?: ImageFit;
|
|
23
25
|
};
|
|
24
26
|
}
|
|
25
27
|
interface Render {
|
|
26
|
-
thumbnail
|
|
28
|
+
thumbnail?: ({ slide, rect, render, imageFit, }: {
|
|
27
29
|
slide: Slide;
|
|
28
30
|
rect: ContainerRect;
|
|
31
|
+
render: Render;
|
|
32
|
+
imageFit: ImageFit;
|
|
29
33
|
}) => React.ReactNode;
|
|
30
34
|
}
|
|
31
35
|
}
|
|
32
|
-
declare type DeepNonNullable<T> = NonNullable<{
|
|
33
|
-
[K in keyof T]-?: NonNullable<T[K]>;
|
|
34
|
-
}>;
|
|
35
36
|
declare type ThumbnailsInternal = DeepNonNullable<LightboxProps["thumbnails"]>;
|
|
36
37
|
declare type ThumbnailsTrackProps = Pick<LightboxProps, "slides" | "carousel" | "animation" | "render"> & {
|
|
37
38
|
container: React.RefObject<HTMLDivElement>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { clsx, createIcon, createModule, cssClass, cssVar, ImageSlide,
|
|
2
|
+
import { clsx, createIcon, createModule, cssClass, cssVar, ImageSlide, useEnhancedEffect, useEvents, useLatest, useMotionPreference, useRTL, } from "../core/index.js";
|
|
3
3
|
const defaultThumbnailsProps = {
|
|
4
4
|
position: "bottom",
|
|
5
5
|
width: 120,
|
|
@@ -8,6 +8,7 @@ const defaultThumbnailsProps = {
|
|
|
8
8
|
borderRadius: 4,
|
|
9
9
|
padding: 4,
|
|
10
10
|
gap: 16,
|
|
11
|
+
imageFit: "contain",
|
|
11
12
|
};
|
|
12
13
|
const VideoThumbnailIcon = createIcon("VideoThumbnail", React.createElement("path", { d: "M10 16.5l6-4.5-6-4.5v9zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" }));
|
|
13
14
|
const UnknownThumbnailIcon = createIcon("UnknownThumbnail", React.createElement("path", { d: "M23 18V6c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zM8.5 12.5l2.5 3.01L14.5 11l4.5 6H5l3.5-4.5z" }));
|
|
@@ -16,9 +17,9 @@ const cssThumbnailPrefix = (value) => cssPrefix(`thumbnail${value ? `_${value}`
|
|
|
16
17
|
const getSlide = (slides, index) => slides[((index % slides.length) + slides.length) % slides.length];
|
|
17
18
|
const isHorizontal = (position) => ["top", "bottom"].includes(position);
|
|
18
19
|
const boxSize = (thumbnails, dimension, includeGap) => dimension + 2 * (thumbnails.border + thumbnails.padding) + (includeGap ? thumbnails.gap : 0);
|
|
19
|
-
const renderThumbnail = ({ slide, render, rect }) => {
|
|
20
|
+
const renderThumbnail = ({ slide, render, rect, imageFit }) => {
|
|
20
21
|
var _a;
|
|
21
|
-
const customThumbnail = (_a = render.thumbnail) === null || _a === void 0 ? void 0 : _a.call(render, { slide, rect });
|
|
22
|
+
const customThumbnail = (_a = render.thumbnail) === null || _a === void 0 ? void 0 : _a.call(render, { slide, render, rect, imageFit });
|
|
22
23
|
if (customThumbnail) {
|
|
23
24
|
return customThumbnail;
|
|
24
25
|
}
|
|
@@ -31,11 +32,11 @@ const renderThumbnail = ({ slide, render, rect }) => {
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
else if ("src" in slide) {
|
|
34
|
-
return React.createElement(ImageSlide, { slide: slide, rect: rect });
|
|
35
|
+
return React.createElement(ImageSlide, { slide: slide, render: render, rect: rect, imageFit: imageFit });
|
|
35
36
|
}
|
|
36
37
|
return React.createElement(UnknownThumbnailIcon, { className: thumbnailIconClass });
|
|
37
38
|
};
|
|
38
|
-
const Thumbnail = ({ rect, slide, onClick, active, fadeIn, fadeOut, placeholder, render, }) => (React.createElement("button", { type: "button", className: clsx(cssClass(cssThumbnailPrefix()), active && cssClass(cssThumbnailPrefix("active")), fadeIn && cssClass(cssThumbnailPrefix("fadein")), fadeOut && cssClass(cssThumbnailPrefix("fadeout")), placeholder && cssClass(cssThumbnailPrefix("placeholder"))), style: {
|
|
39
|
+
const Thumbnail = ({ rect, slide, onClick, active, fadeIn, fadeOut, placeholder, render, imageFit, }) => (React.createElement("button", { type: "button", className: clsx(cssClass(cssThumbnailPrefix()), active && cssClass(cssThumbnailPrefix("active")), fadeIn && cssClass(cssThumbnailPrefix("fadein")), fadeOut && cssClass(cssThumbnailPrefix("fadeout")), placeholder && cssClass(cssThumbnailPrefix("placeholder"))), style: {
|
|
39
40
|
...(fadeIn
|
|
40
41
|
? {
|
|
41
42
|
[cssVar(cssThumbnailPrefix("fadein_duration"))]: `${fadeIn.duration}ms`,
|
|
@@ -48,13 +49,16 @@ const Thumbnail = ({ rect, slide, onClick, active, fadeIn, fadeOut, placeholder,
|
|
|
48
49
|
[cssVar(cssThumbnailPrefix("fadeout_delay"))]: `${fadeOut.delay}ms`,
|
|
49
50
|
}
|
|
50
51
|
: null),
|
|
51
|
-
}, onClick: onClick }, slide && renderThumbnail({ slide, render, rect })));
|
|
52
|
+
}, onClick: onClick }, slide && renderThumbnail({ slide, render, rect, imageFit })));
|
|
52
53
|
export const ThumbnailsTrack = ({ container, startingIndex, slides, carousel, animation, render, thumbnails, thumbnailRect, }) => {
|
|
53
54
|
const track = React.useRef(null);
|
|
54
55
|
const [state, setState] = React.useState({
|
|
55
56
|
index: startingIndex,
|
|
56
57
|
offset: 0,
|
|
57
58
|
});
|
|
59
|
+
const { publish, subscribe } = useEvents();
|
|
60
|
+
const reduceMotion = useLatest(useMotionPreference());
|
|
61
|
+
const isRTL = useLatest(useRTL());
|
|
58
62
|
const refs = React.useRef({
|
|
59
63
|
state,
|
|
60
64
|
thumbnails,
|
|
@@ -67,12 +71,6 @@ export const ThumbnailsTrack = ({ container, startingIndex, slides, carousel, an
|
|
|
67
71
|
refs.current.carousel = carousel;
|
|
68
72
|
refs.current.animation = animation;
|
|
69
73
|
const animationRef = React.useRef();
|
|
70
|
-
const { publish, subscribe } = useEvents();
|
|
71
|
-
React.useEffect(() => {
|
|
72
|
-
if (track.current) {
|
|
73
|
-
refs.current.isRTL = isRTL(track.current);
|
|
74
|
-
}
|
|
75
|
-
}, []);
|
|
76
74
|
React.useEffect(() => subscribe("controller-swipe", (_, event) => {
|
|
77
75
|
if (event && typeof event === "object" && "globalIndex" in event) {
|
|
78
76
|
const { current } = refs;
|
|
@@ -106,7 +104,7 @@ export const ThumbnailsTrack = ({ container, startingIndex, slides, carousel, an
|
|
|
106
104
|
animationRef.current = (_d = (_c = track.current).animate) === null || _d === void 0 ? void 0 : _d.call(_c, isHorizontal(current.thumbnails.position)
|
|
107
105
|
? [
|
|
108
106
|
{
|
|
109
|
-
transform: `translate3d(${(current
|
|
107
|
+
transform: `translate3d(${(isRTL.current ? -1 : 1) *
|
|
110
108
|
boxSize(current.thumbnails, current.thumbnails.width, true) *
|
|
111
109
|
state.offset +
|
|
112
110
|
current.animationOffset}px, 0, 0)`,
|
|
@@ -119,7 +117,7 @@ export const ThumbnailsTrack = ({ container, startingIndex, slides, carousel, an
|
|
|
119
117
|
current.animationOffset}px, 0)`,
|
|
120
118
|
},
|
|
121
119
|
{ transform: "translate3d(0, 0, 0)" },
|
|
122
|
-
], animationDuration);
|
|
120
|
+
], reduceMotion.current ? 0 : animationDuration);
|
|
123
121
|
if (animationRef.current) {
|
|
124
122
|
animationRef.current.onfinish = () => {
|
|
125
123
|
animationRef.current = undefined;
|
|
@@ -130,7 +128,7 @@ export const ThumbnailsTrack = ({ container, startingIndex, slides, carousel, an
|
|
|
130
128
|
}
|
|
131
129
|
current.animationOffset = 0;
|
|
132
130
|
}
|
|
133
|
-
}, [state.index, state.offset]);
|
|
131
|
+
}, [state.index, state.offset, isRTL, reduceMotion]);
|
|
134
132
|
const { index, offset } = state;
|
|
135
133
|
const { finite, preload } = carousel;
|
|
136
134
|
const items = [];
|
|
@@ -171,25 +169,24 @@ export const ThumbnailsTrack = ({ container, startingIndex, slides, carousel, an
|
|
|
171
169
|
publish("prev", index - slideIndex);
|
|
172
170
|
}
|
|
173
171
|
};
|
|
172
|
+
const { width, height, border, borderRadius, padding, gap, imageFit } = thumbnails;
|
|
174
173
|
return (React.createElement("div", { className: clsx(cssClass(cssPrefix("container")), cssClass("flex_center")), style: {
|
|
175
|
-
...(
|
|
176
|
-
? { [cssVar(cssThumbnailPrefix("width"))]: `${boxSize(thumbnails,
|
|
177
|
-
: null),
|
|
178
|
-
...(thumbnails.height !== defaultThumbnailsProps.height
|
|
179
|
-
? { [cssVar(cssThumbnailPrefix("height"))]: `${boxSize(thumbnails, thumbnails.height)}px` }
|
|
174
|
+
...(width !== defaultThumbnailsProps.width
|
|
175
|
+
? { [cssVar(cssThumbnailPrefix("width"))]: `${boxSize(thumbnails, width)}px` }
|
|
180
176
|
: null),
|
|
181
|
-
...(
|
|
182
|
-
? { [cssVar(cssThumbnailPrefix("
|
|
177
|
+
...(height !== defaultThumbnailsProps.height
|
|
178
|
+
? { [cssVar(cssThumbnailPrefix("height"))]: `${boxSize(thumbnails, height)}px` }
|
|
183
179
|
: null),
|
|
184
|
-
...(
|
|
185
|
-
? { [cssVar(cssThumbnailPrefix("
|
|
180
|
+
...(border !== defaultThumbnailsProps.border
|
|
181
|
+
? { [cssVar(cssThumbnailPrefix("border"))]: `${border}px` }
|
|
186
182
|
: null),
|
|
187
|
-
...(
|
|
188
|
-
? { [cssVar(cssThumbnailPrefix("
|
|
183
|
+
...(borderRadius !== defaultThumbnailsProps.borderRadius
|
|
184
|
+
? { [cssVar(cssThumbnailPrefix("border_radius"))]: `${borderRadius}px` }
|
|
189
185
|
: null),
|
|
190
|
-
...(
|
|
191
|
-
? { [cssVar(cssThumbnailPrefix("
|
|
186
|
+
...(padding !== defaultThumbnailsProps.padding
|
|
187
|
+
? { [cssVar(cssThumbnailPrefix("padding"))]: `${padding}px` }
|
|
192
188
|
: null),
|
|
189
|
+
...(gap !== defaultThumbnailsProps.gap ? { [cssVar(cssThumbnailPrefix("gap"))]: `${gap}px` } : null),
|
|
193
190
|
} },
|
|
194
191
|
React.createElement("nav", { ref: track, className: cssClass(cssPrefix("track")) }, items.map(({ slide, index: slideIndex, placeholder }) => {
|
|
195
192
|
var _a;
|
|
@@ -213,11 +210,11 @@ export const ThumbnailsTrack = ({ container, startingIndex, slides, carousel, an
|
|
|
213
210
|
: -offset - (slideIndex - (index + preload))) * fadeAnimationDuration,
|
|
214
211
|
}
|
|
215
212
|
: undefined;
|
|
216
|
-
return (React.createElement(Thumbnail, { key: slideIndex, rect: thumbnailRect, slide: slide, render: render, active: slideIndex === index, fadeIn: fadeIn, fadeOut: fadeOut, placeholder: Boolean(placeholder), onClick: handleClick(slideIndex) }));
|
|
213
|
+
return (React.createElement(Thumbnail, { key: slideIndex, rect: thumbnailRect, slide: slide, imageFit: imageFit, render: render, active: slideIndex === index, fadeIn: fadeIn, fadeOut: fadeOut, placeholder: Boolean(placeholder), onClick: handleClick(slideIndex) }));
|
|
217
214
|
}))));
|
|
218
215
|
};
|
|
219
|
-
export const ThumbnailsComponent = ({ thumbnails:
|
|
220
|
-
const thumbnails = { ...defaultThumbnailsProps, ...
|
|
216
|
+
export const ThumbnailsComponent = ({ thumbnails: thumbnailsProps, slides, index, carousel, animation, render, children, }) => {
|
|
217
|
+
const thumbnails = { ...defaultThumbnailsProps, ...thumbnailsProps };
|
|
221
218
|
const ref = React.useRef(null);
|
|
222
219
|
const track = (React.createElement(ThumbnailsTrack, { container: ref, slides: slides, thumbnails: thumbnails, carousel: carousel, animation: animation, render: render, startingIndex: index, thumbnailRect: { width: thumbnails.width, height: thumbnails.height } }));
|
|
223
220
|
return (React.createElement("div", { ref: ref, className: clsx(cssClass(cssPrefix()), cssClass(cssPrefix(`${thumbnails.position}`)), cssClass("fullsize")) },
|
|
@@ -226,10 +223,10 @@ export const ThumbnailsComponent = ({ thumbnails: originalThumbnails, slides, in
|
|
|
226
223
|
(thumbnails.position === "end" || thumbnails.position === "bottom") && track));
|
|
227
224
|
};
|
|
228
225
|
export const Thumbnails = ({ augment, contains, append, addParent }) => {
|
|
229
|
-
augment(({ thumbnails
|
|
226
|
+
augment(({ thumbnails, ...restProps }) => ({
|
|
230
227
|
thumbnails: {
|
|
231
228
|
...defaultThumbnailsProps,
|
|
232
|
-
...
|
|
229
|
+
...thumbnails,
|
|
233
230
|
},
|
|
234
231
|
...restProps,
|
|
235
232
|
}));
|