yet-another-react-lightbox 3.2.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/components/IconButton.js +4 -5
- package/dist/core/consts.d.ts +1 -0
- package/dist/core/consts.js +1 -0
- package/dist/core/contexts/LightboxState.d.ts +7 -2
- package/dist/core/contexts/LightboxState.js +15 -5
- package/dist/core/modules/Carousel.js +2 -2
- package/dist/core/modules/Controller.js +3 -2
- package/dist/core/modules/Navigation.js +4 -5
- package/dist/core/modules/Toolbar.d.ts +1 -1
- package/dist/core/modules/Toolbar.js +9 -4
- package/dist/core/utils.d.ts +5 -2
- package/dist/core/utils.js +16 -1
- package/dist/plugins/captions/Captions.js +3 -6
- package/dist/plugins/captions/CaptionsButton.js +3 -3
- package/dist/plugins/captions/index.d.ts +4 -0
- package/dist/plugins/captions/index.js +1 -0
- package/dist/plugins/counter/Counter.js +1 -1
- package/dist/plugins/download/Download.d.ts +2 -0
- package/dist/plugins/download/Download.js +9 -0
- package/dist/plugins/download/DownloadButton.d.ts +2 -0
- package/dist/plugins/download/DownloadButton.js +17 -0
- package/dist/plugins/download/FileSaver.d.ts +1 -0
- package/dist/plugins/download/FileSaver.js +60 -0
- package/dist/plugins/download/index.d.ts +20 -0
- package/dist/plugins/download/index.js +3 -0
- package/dist/plugins/fullscreen/Fullscreen.js +3 -3
- package/dist/plugins/fullscreen/FullscreenButton.js +3 -3
- package/dist/plugins/fullscreen/index.d.ts +4 -0
- package/dist/plugins/fullscreen/index.js +1 -0
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.js +1 -0
- package/dist/plugins/slideshow/Slideshow.js +3 -3
- package/dist/plugins/slideshow/SlideshowButton.js +3 -3
- package/dist/plugins/slideshow/SlideshowContext.js +1 -1
- package/dist/plugins/slideshow/index.d.ts +4 -0
- package/dist/plugins/slideshow/index.js +1 -0
- package/dist/plugins/thumbnails/Thumbnails.js +3 -6
- package/dist/plugins/thumbnails/ThumbnailsButton.js +3 -3
- package/dist/plugins/thumbnails/ThumbnailsTrack.js +3 -3
- package/dist/plugins/thumbnails/index.d.ts +4 -0
- package/dist/plugins/thumbnails/index.js +1 -0
- package/dist/plugins/zoom/Zoom.js +3 -3
- package/dist/plugins/zoom/ZoomButton.js +4 -5
- package/dist/plugins/zoom/ZoomWrapper.js +1 -1
- package/dist/plugins/zoom/hooks/useZoomImageRect.js +1 -1
- package/dist/plugins/zoom/hooks/useZoomSensors.js +1 -1
- package/dist/plugins/zoom/hooks/useZoomState.js +1 -1
- package/dist/plugins/zoom/index.d.ts +4 -0
- package/dist/plugins/zoom/index.js +1 -0
- package/dist/types.d.ts +7 -1
- package/package.json +8 -1
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { clsx, cssClass } from "../utils.js";
|
|
2
|
+
import { clsx, cssClass, label as translateLabel } from "../utils.js";
|
|
3
3
|
import { useLightboxProps } from "../contexts/index.js";
|
|
4
4
|
import { ELEMENT_BUTTON, ELEMENT_ICON } from "../consts.js";
|
|
5
|
-
export const IconButton = React.forwardRef(({ label, className, icon: Icon, renderIcon, onClick, style, ...rest }, ref)
|
|
6
|
-
const { styles } = useLightboxProps();
|
|
7
|
-
return (React.createElement("button", { ref: ref, type: "button", "aria-label": label, className: clsx(cssClass(ELEMENT_BUTTON), className), onClick: onClick, style: { ...style, ...styles.button }, ...rest }, renderIcon ? renderIcon() : React.createElement(Icon, { className: cssClass(ELEMENT_ICON), style: styles.icon })));
|
|
5
|
+
export const IconButton = React.forwardRef(function IconButton({ label, className, icon: Icon, renderIcon, onClick, style, ...rest }, ref) {
|
|
6
|
+
const { styles, labels } = useLightboxProps();
|
|
7
|
+
return (React.createElement("button", { ref: ref, type: "button", "aria-label": translateLabel(labels, label), className: clsx(cssClass(ELEMENT_BUTTON), className), onClick: onClick, style: { ...style, ...styles.button }, ...rest }, renderIcon ? renderIcon() : React.createElement(Icon, { className: cssClass(ELEMENT_ICON), style: styles.icon })));
|
|
8
8
|
});
|
|
9
|
-
IconButton.displayName = "IconButton";
|
package/dist/core/consts.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export declare const MODULE_ROOT = "root";
|
|
|
7
7
|
export declare const MODULE_TOOLBAR = "toolbar";
|
|
8
8
|
export declare const PLUGIN_CAPTIONS = "captions";
|
|
9
9
|
export declare const PLUGIN_COUNTER = "counter";
|
|
10
|
+
export declare const PLUGIN_DOWNLOAD = "download";
|
|
10
11
|
export declare const PLUGIN_FULLSCREEN = "fullscreen";
|
|
11
12
|
export declare const PLUGIN_INLINE = "inline";
|
|
12
13
|
export declare const PLUGIN_SLIDESHOW = "slideshow";
|
package/dist/core/consts.js
CHANGED
|
@@ -7,6 +7,7 @@ export const MODULE_ROOT = "root";
|
|
|
7
7
|
export const MODULE_TOOLBAR = "toolbar";
|
|
8
8
|
export const PLUGIN_CAPTIONS = "captions";
|
|
9
9
|
export const PLUGIN_COUNTER = "counter";
|
|
10
|
+
export const PLUGIN_DOWNLOAD = "download";
|
|
10
11
|
export const PLUGIN_FULLSCREEN = "fullscreen";
|
|
11
12
|
export const PLUGIN_INLINE = "inline";
|
|
12
13
|
export const PLUGIN_SLIDESHOW = "slideshow";
|
|
@@ -12,11 +12,16 @@ export type LightboxStateUpdateAction = {
|
|
|
12
12
|
index: number;
|
|
13
13
|
};
|
|
14
14
|
export type LightboxStateAction = LightboxStateSwipeAction | LightboxStateUpdateAction;
|
|
15
|
-
export type LightboxStateContextType = {
|
|
15
|
+
export type LightboxStateContextType = LightboxState & {
|
|
16
|
+
/** @deprecated - use `useLightboxState` props directly */
|
|
16
17
|
state: LightboxState;
|
|
18
|
+
/** @deprecated - use `useLightboxDispatch` instead */
|
|
17
19
|
dispatch: React.Dispatch<LightboxStateAction>;
|
|
18
20
|
};
|
|
19
21
|
export declare const LightboxStateContext: React.Context<LightboxStateContextType | null>;
|
|
20
|
-
export declare const useLightboxState: () => LightboxStateContextType
|
|
22
|
+
export declare const useLightboxState: () => NonNullable<LightboxStateContextType>;
|
|
23
|
+
export type LightboxDispatchContextType = React.Dispatch<LightboxStateAction>;
|
|
24
|
+
export declare const LightboxDispatchContext: React.Context<LightboxDispatchContextType | null>;
|
|
25
|
+
export declare const useLightboxDispatch: () => LightboxDispatchContextType;
|
|
21
26
|
export type LightboxStateProviderProps = React.PropsWithChildren<Pick<LightboxProps, "slides" | "index">>;
|
|
22
27
|
export declare function LightboxStateProvider({ slides, index, children }: LightboxStateProviderProps): JSX.Element;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { getSlideIndex, makeUseContext } from "../utils.js";
|
|
2
|
+
import { getSlideIfPresent, getSlideIndex, makeUseContext } from "../utils.js";
|
|
3
3
|
import { UNKNOWN_ACTION_TYPE } from "../consts.js";
|
|
4
4
|
export const LightboxStateContext = React.createContext(null);
|
|
5
5
|
export const useLightboxState = makeUseContext("useLightboxState", "LightboxStateContext", LightboxStateContext);
|
|
6
|
+
export const LightboxDispatchContext = React.createContext(null);
|
|
7
|
+
export const useLightboxDispatch = makeUseContext("useLightboxDispatch", "LightboxDispatchContext", LightboxDispatchContext);
|
|
6
8
|
function reducer(state, action) {
|
|
7
9
|
switch (action.type) {
|
|
8
10
|
case "swipe": {
|
|
@@ -10,6 +12,7 @@ function reducer(state, action) {
|
|
|
10
12
|
const increment = (action === null || action === void 0 ? void 0 : action.increment) || 0;
|
|
11
13
|
const globalIndex = state.globalIndex + increment;
|
|
12
14
|
const currentIndex = getSlideIndex(globalIndex, slides.length);
|
|
15
|
+
const currentSlide = getSlideIfPresent(slides, currentIndex);
|
|
13
16
|
const animation = increment || action.duration
|
|
14
17
|
? {
|
|
15
18
|
increment,
|
|
@@ -17,23 +20,30 @@ function reducer(state, action) {
|
|
|
17
20
|
easing: action.easing,
|
|
18
21
|
}
|
|
19
22
|
: undefined;
|
|
20
|
-
return { slides, currentIndex, globalIndex, animation };
|
|
23
|
+
return { slides, currentIndex, globalIndex, currentSlide, animation };
|
|
21
24
|
}
|
|
22
25
|
case "update":
|
|
23
26
|
return {
|
|
24
27
|
slides: action.slides,
|
|
25
28
|
currentIndex: action.index,
|
|
26
29
|
globalIndex: action.index,
|
|
30
|
+
currentSlide: getSlideIfPresent(action.slides, action.index),
|
|
27
31
|
};
|
|
28
32
|
default:
|
|
29
33
|
throw new Error(UNKNOWN_ACTION_TYPE);
|
|
30
34
|
}
|
|
31
35
|
}
|
|
32
36
|
export function LightboxStateProvider({ slides, index, children }) {
|
|
33
|
-
const [state, dispatch] = React.useReducer(reducer, {
|
|
37
|
+
const [state, dispatch] = React.useReducer(reducer, {
|
|
38
|
+
slides,
|
|
39
|
+
currentIndex: index,
|
|
40
|
+
globalIndex: index,
|
|
41
|
+
currentSlide: getSlideIfPresent(slides, index),
|
|
42
|
+
});
|
|
34
43
|
React.useEffect(() => {
|
|
35
44
|
dispatch({ type: "update", slides, index });
|
|
36
45
|
}, [slides, index]);
|
|
37
|
-
const context = React.useMemo(() => ({ state, dispatch }), [state, dispatch]);
|
|
38
|
-
return React.createElement(
|
|
46
|
+
const context = React.useMemo(() => ({ ...state, state, dispatch }), [state, dispatch]);
|
|
47
|
+
return (React.createElement(LightboxDispatchContext.Provider, { value: dispatch },
|
|
48
|
+
React.createElement(LightboxStateContext.Provider, { value: context }, children)));
|
|
39
49
|
}
|
|
@@ -13,7 +13,7 @@ function cssSlidePrefix(value) {
|
|
|
13
13
|
}
|
|
14
14
|
function CarouselSlide({ slide, offset }) {
|
|
15
15
|
const containerRef = React.useRef(null);
|
|
16
|
-
const { currentIndex } = useLightboxState()
|
|
16
|
+
const { currentIndex } = useLightboxState();
|
|
17
17
|
const { slideRect, close } = useController();
|
|
18
18
|
const { render, carousel: { imageFit }, on: { click: onClick }, controller: { closeOnBackdropClick }, } = useLightboxProps();
|
|
19
19
|
const renderSlide = () => {
|
|
@@ -45,7 +45,7 @@ function Placeholder() {
|
|
|
45
45
|
return React.createElement("div", { className: cssClass("slide") });
|
|
46
46
|
}
|
|
47
47
|
export function Carousel({ carousel: { finite, preload, padding, spacing } }) {
|
|
48
|
-
const { slides, currentIndex, globalIndex } = useLightboxState()
|
|
48
|
+
const { slides, currentIndex, globalIndex } = useLightboxState();
|
|
49
49
|
const { setCarouselRef } = useController();
|
|
50
50
|
const spacingValue = parseLengthPercentage(spacing);
|
|
51
51
|
const paddingValue = parseLengthPercentage(padding);
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import { createModule } from "../config.js";
|
|
3
3
|
import { cleanup, clsx, computeSlideRect, cssClass, cssVar, makeComposePrefix, makeUseContext, parseLengthPercentage, } from "../utils.js";
|
|
4
4
|
import { useAnimation, useContainerRect, useDelay, useEventCallback, useForkRef, useRTL, useSensors, } from "../hooks/index.js";
|
|
5
|
-
import { useEvents, useLightboxState } from "../contexts/index.js";
|
|
5
|
+
import { useEvents, useLightboxDispatch, useLightboxState } from "../contexts/index.js";
|
|
6
6
|
import { SwipeState, usePointerSwipe, usePreventSwipeNavigation, useWheelSwipe } from "./controller/index.js";
|
|
7
7
|
import { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, ACTIVE_SLIDE_COMPLETE, ACTIVE_SLIDE_ERROR, ACTIVE_SLIDE_LOADING, ACTIVE_SLIDE_PLAYING, CLASS_FLEX_CENTER, EVENT_ON_KEY_UP, MODULE_CONTROLLER, VK_ESCAPE, } from "../consts.js";
|
|
8
8
|
const cssContainerPrefix = makeComposePrefix("container");
|
|
@@ -12,7 +12,8 @@ export function Controller({ children, ...props }) {
|
|
|
12
12
|
var _a;
|
|
13
13
|
const { carousel, animation, controller, on, styles, render } = props;
|
|
14
14
|
const [toolbarWidth, setToolbarWidth] = React.useState();
|
|
15
|
-
const { state
|
|
15
|
+
const { state } = useLightboxState();
|
|
16
|
+
const dispatch = useLightboxDispatch();
|
|
16
17
|
const [swipeState, setSwipeState] = React.useState(SwipeState.NONE);
|
|
17
18
|
const swipeOffset = React.useRef(0);
|
|
18
19
|
const { registerSensors, subscribeSensors } = useSensors();
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { createModule } from "../config.js";
|
|
3
3
|
import { useEventCallback, useLoseFocus, useRTL, useThrottle } from "../hooks/index.js";
|
|
4
|
-
import { cssClass
|
|
4
|
+
import { cssClass } from "../utils.js";
|
|
5
5
|
import { IconButton, NextIcon, PreviousIcon } from "../components/index.js";
|
|
6
|
-
import {
|
|
6
|
+
import { useLightboxState } from "../contexts/index.js";
|
|
7
7
|
import { useController } from "./Controller.js";
|
|
8
8
|
import { ACTION_NEXT, ACTION_PREV, EVENT_ON_KEY_DOWN, MODULE_NAVIGATION, VK_ARROW_LEFT, VK_ARROW_RIGHT, } from "../consts.js";
|
|
9
9
|
export function NavigationButton({ label, icon, renderIcon, action, onClick, disabled }) {
|
|
10
|
-
|
|
11
|
-
return (React.createElement(IconButton, { label: translateLabel(labels, label), icon: icon, renderIcon: renderIcon, className: cssClass(`navigation_${action}`), disabled: disabled, onClick: onClick, ...useLoseFocus(disabled) }));
|
|
10
|
+
return (React.createElement(IconButton, { label: label, icon: icon, renderIcon: renderIcon, className: cssClass(`navigation_${action}`), disabled: disabled, onClick: onClick, ...useLoseFocus(disabled) }));
|
|
12
11
|
}
|
|
13
12
|
export function Navigation({ carousel: { finite }, animation, render: { buttonPrev, buttonNext, iconPrev, iconNext }, }) {
|
|
14
13
|
var _a;
|
|
15
|
-
const { slides, currentIndex } = useLightboxState()
|
|
14
|
+
const { slides, currentIndex } = useLightboxState();
|
|
16
15
|
const { prev, next, subscribeSensors } = useController();
|
|
17
16
|
const isRTL = useRTL();
|
|
18
17
|
const prevDisabled = slides.length === 0 || (finite && currentIndex === 0);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { ComponentProps } from "../../types.js";
|
|
3
|
-
export declare function Toolbar({ toolbar: { buttons },
|
|
3
|
+
export declare function Toolbar({ toolbar: { buttons }, render: { buttonClose, iconClose } }: ComponentProps): JSX.Element;
|
|
4
4
|
export declare const ToolbarModule: import("../../types.js").Module;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { createModule } from "../config.js";
|
|
3
|
-
import {
|
|
3
|
+
import { useLayoutEffect } from "../hooks/index.js";
|
|
4
|
+
import { composePrefix, cssClass } from "../utils.js";
|
|
4
5
|
import { CloseIcon, IconButton } from "../components/index.js";
|
|
5
6
|
import { useContainerRect } from "../hooks/useContainerRect.js";
|
|
6
7
|
import { useController } from "./Controller.js";
|
|
@@ -8,13 +9,17 @@ import { ACTION_CLOSE, MODULE_TOOLBAR } from "../consts.js";
|
|
|
8
9
|
function cssPrefix(value) {
|
|
9
10
|
return composePrefix(MODULE_TOOLBAR, value);
|
|
10
11
|
}
|
|
11
|
-
export function Toolbar({ toolbar: { buttons },
|
|
12
|
+
export function Toolbar({ toolbar: { buttons }, render: { buttonClose, iconClose } }) {
|
|
12
13
|
const { close, setToolbarWidth } = useController();
|
|
13
14
|
const { setContainerRef, containerRect } = useContainerRect();
|
|
14
|
-
|
|
15
|
+
useLayoutEffect(() => {
|
|
15
16
|
setToolbarWidth(containerRect === null || containerRect === void 0 ? void 0 : containerRect.width);
|
|
16
17
|
}, [setToolbarWidth, containerRect === null || containerRect === void 0 ? void 0 : containerRect.width]);
|
|
17
|
-
const renderCloseButton = () =>
|
|
18
|
+
const renderCloseButton = () => {
|
|
19
|
+
if (buttonClose)
|
|
20
|
+
return buttonClose();
|
|
21
|
+
return React.createElement(IconButton, { key: ACTION_CLOSE, label: "Close", icon: CloseIcon, renderIcon: iconClose, onClick: close });
|
|
22
|
+
};
|
|
18
23
|
return (React.createElement("div", { ref: setContainerRef, className: cssClass(cssPrefix()) }, buttons === null || buttons === void 0 ? void 0 : buttons.map((button) => (button === ACTION_CLOSE ? renderCloseButton() : button))));
|
|
19
24
|
}
|
|
20
25
|
export const ToolbarModule = createModule(MODULE_TOOLBAR, Toolbar);
|
package/dist/core/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { ContainerRect, Labels, LengthOrPercentage, LightboxProps, Slide, SlideImage } from "../types.js";
|
|
2
|
+
import { ContainerRect, Labels, LengthOrPercentage, LightboxProps, Slide, SlideImage, ToolbarSettings } from "../types.js";
|
|
3
3
|
export declare const clsx: (...classes: (string | boolean | undefined)[]) => string;
|
|
4
4
|
export declare const cssClass: (name: string) => string;
|
|
5
5
|
export declare const cssVar: (name: string) => string;
|
|
@@ -25,4 +25,7 @@ export declare function computeSlideRect(containerRect: ContainerRect, padding:
|
|
|
25
25
|
};
|
|
26
26
|
export declare const devicePixelRatio: () => number;
|
|
27
27
|
export declare const getSlideIndex: (index: number, slidesCount: number) => number;
|
|
28
|
-
export declare const
|
|
28
|
+
export declare const hasSlides: (slides: Slide[]) => slides is [Slide, ...Slide[]];
|
|
29
|
+
export declare const getSlide: (slides: [Slide, ...Slide[]], index: number) => Slide;
|
|
30
|
+
export declare const getSlideIfPresent: (slides: Slide[], index: number) => Slide | undefined;
|
|
31
|
+
export declare function addToolbarButton(toolbar: ToolbarSettings, key: string, button: React.ReactNode): ToolbarSettings;
|
package/dist/core/utils.js
CHANGED
|
@@ -45,5 +45,20 @@ export function computeSlideRect(containerRect, padding) {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
export const devicePixelRatio = () => (hasWindow() ? window === null || window === void 0 ? void 0 : window.devicePixelRatio : undefined) || 1;
|
|
48
|
-
export const getSlideIndex = (index, slidesCount) => ((index % slidesCount) + slidesCount) % slidesCount;
|
|
48
|
+
export const getSlideIndex = (index, slidesCount) => slidesCount > 0 ? ((index % slidesCount) + slidesCount) % slidesCount : 0;
|
|
49
|
+
export const hasSlides = (slides) => slides.length > 0;
|
|
49
50
|
export const getSlide = (slides, index) => slides[getSlideIndex(index, slides.length)];
|
|
51
|
+
export const getSlideIfPresent = (slides, index) => hasSlides(slides) ? getSlide(slides, index) : undefined;
|
|
52
|
+
export function addToolbarButton(toolbar, key, button) {
|
|
53
|
+
if (!button)
|
|
54
|
+
return toolbar;
|
|
55
|
+
const { buttons, ...restToolbar } = toolbar;
|
|
56
|
+
const index = buttons.findIndex((item) => item === key);
|
|
57
|
+
const buttonWithKey = React.isValidElement(button) ? React.cloneElement(button, { key }, null) : button;
|
|
58
|
+
if (index >= 0) {
|
|
59
|
+
const result = [...buttons];
|
|
60
|
+
result.splice(index, 1, buttonWithKey);
|
|
61
|
+
return { buttons: result, ...restToolbar };
|
|
62
|
+
}
|
|
63
|
+
return { buttons: [buttonWithKey, ...buttons], ...restToolbar };
|
|
64
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { createModule, PLUGIN_CAPTIONS } from "../../core/index.js";
|
|
2
|
+
import { addToolbarButton, createModule, PLUGIN_CAPTIONS } from "../../core/index.js";
|
|
3
3
|
import { Title } from "./Title.js";
|
|
4
4
|
import { Description } from "./Description.js";
|
|
5
5
|
import { CaptionsButton } from "./CaptionsButton.js";
|
|
6
6
|
import { CaptionsContextProvider } from "./CaptionsContext.js";
|
|
7
7
|
import { resolveCaptionsProps } from "./props.js";
|
|
8
8
|
export function Captions({ augment, addModule }) {
|
|
9
|
-
augment(({ render: { slideFooter: renderFooter, ...restRender }, toolbar
|
|
9
|
+
augment(({ captions: captionsProps, render: { slideFooter: renderFooter, ...restRender }, toolbar, ...restProps }) => {
|
|
10
10
|
const captions = resolveCaptionsProps(captionsProps);
|
|
11
11
|
return {
|
|
12
12
|
render: {
|
|
@@ -16,10 +16,7 @@ export function Captions({ augment, addModule }) {
|
|
|
16
16
|
slide.description && React.createElement(Description, { description: slide.description }))),
|
|
17
17
|
...restRender,
|
|
18
18
|
},
|
|
19
|
-
toolbar:
|
|
20
|
-
buttons: [...(captions.showToggle ? [React.createElement(CaptionsButton, { key: PLUGIN_CAPTIONS })] : []), ...buttons],
|
|
21
|
-
...restToolbar,
|
|
22
|
-
},
|
|
19
|
+
toolbar: addToolbarButton(toolbar, PLUGIN_CAPTIONS, captions.showToggle ? React.createElement(CaptionsButton, null) : null),
|
|
23
20
|
captions,
|
|
24
21
|
...restProps,
|
|
25
22
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { createIcon, createIconDisabled, IconButton,
|
|
2
|
+
import { createIcon, createIconDisabled, IconButton, useLightboxProps } from "../../core/index.js";
|
|
3
3
|
import { useCaptions } from "./CaptionsContext.js";
|
|
4
4
|
const captionsIcon = () => (React.createElement(React.Fragment, null,
|
|
5
5
|
React.createElement("path", { strokeWidth: 2, stroke: "currentColor", strokeLinejoin: "round", fill: "none", d: "M3 5l18 0l0 14l-18 0l0-14z" }),
|
|
@@ -8,9 +8,9 @@ const CaptionsVisible = createIcon("CaptionsVisible", captionsIcon());
|
|
|
8
8
|
const CaptionsHidden = createIconDisabled("CaptionsVisible", captionsIcon());
|
|
9
9
|
export function CaptionsButton() {
|
|
10
10
|
const { visible, show, hide } = useCaptions();
|
|
11
|
-
const { render
|
|
11
|
+
const { render } = useLightboxProps();
|
|
12
12
|
if (render.buttonCaptions) {
|
|
13
13
|
return React.createElement(React.Fragment, null, render.buttonCaptions({ visible, show, hide }));
|
|
14
14
|
}
|
|
15
|
-
return (React.createElement(IconButton, { label:
|
|
15
|
+
return (React.createElement(IconButton, { label: visible ? "Hide captions" : "Show captions", icon: visible ? CaptionsVisible : CaptionsHidden, renderIcon: visible ? render.iconCaptionsVisible : render.iconCaptionsHidden, onClick: visible ? hide : show }));
|
|
16
16
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import { PLUGIN_CAPTIONS } from "../../core/index.js";
|
|
2
3
|
import { Captions } from "./Captions.js";
|
|
3
4
|
declare module "../../types.js" {
|
|
4
5
|
type TextAlignment = "start" | "end" | "center";
|
|
@@ -8,6 +9,9 @@ declare module "../../types.js" {
|
|
|
8
9
|
/** slide description */
|
|
9
10
|
description?: React.ReactNode;
|
|
10
11
|
}
|
|
12
|
+
interface ToolbarButtonKeys {
|
|
13
|
+
[PLUGIN_CAPTIONS]: null;
|
|
14
|
+
}
|
|
11
15
|
interface LightboxProps {
|
|
12
16
|
/** Captions plugin settings */
|
|
13
17
|
captions?: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { clsx, createModule, cssClass, MODULE_CONTROLLER, PLUGIN_COUNTER, useLightboxState } from "../../core/index.js";
|
|
3
3
|
export function CounterComponent({ counter: { className, ...rest } = {} }) {
|
|
4
|
-
const { slides, currentIndex } = useLightboxState()
|
|
4
|
+
const { slides, currentIndex } = useLightboxState();
|
|
5
5
|
if (slides.length === 0)
|
|
6
6
|
return null;
|
|
7
7
|
return (React.createElement("div", { className: clsx(cssClass("counter"), className), ...rest },
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { addToolbarButton, PLUGIN_DOWNLOAD } from "../../core/index.js";
|
|
3
|
+
import { DownloadButton } from "./DownloadButton.js";
|
|
4
|
+
export function Download({ augment }) {
|
|
5
|
+
augment(({ toolbar, ...restProps }) => ({
|
|
6
|
+
toolbar: addToolbarButton(toolbar, PLUGIN_DOWNLOAD, React.createElement(DownloadButton, null)),
|
|
7
|
+
...restProps,
|
|
8
|
+
}));
|
|
9
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { createIcon, IconButton, isImageSlide, useLightboxProps, useLightboxState } from "../../core/index.js";
|
|
3
|
+
import { saveAs } from "./FileSaver.js";
|
|
4
|
+
const DownloadIcon = createIcon("DownloadIcon", React.createElement("path", { d: "M18 15v3H6v-3H4v3c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-3h-2zm-1-4-1.41-1.41L13 12.17V4h-2v8.17L8.41 9.59 7 11l5 5 5-5z" }));
|
|
5
|
+
export function DownloadButton() {
|
|
6
|
+
const { render } = useLightboxProps();
|
|
7
|
+
const { currentSlide } = useLightboxState();
|
|
8
|
+
if (render.buttonDownload) {
|
|
9
|
+
return React.createElement(React.Fragment, null, render.buttonDownload());
|
|
10
|
+
}
|
|
11
|
+
const downloadUrl = (currentSlide === null || currentSlide === void 0 ? void 0 : currentSlide.downloadUrl) || (currentSlide && isImageSlide(currentSlide) ? currentSlide.src : undefined);
|
|
12
|
+
return (React.createElement(IconButton, { label: "Download", icon: DownloadIcon, renderIcon: render.iconDownload, disabled: !downloadUrl, onClick: () => {
|
|
13
|
+
if (downloadUrl) {
|
|
14
|
+
saveAs(downloadUrl, currentSlide === null || currentSlide === void 0 ? void 0 : currentSlide.downloadFilename);
|
|
15
|
+
}
|
|
16
|
+
} }));
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function saveAs(source: string | Blob, name?: string): void;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
function download(url, name) {
|
|
2
|
+
const xhr = new XMLHttpRequest();
|
|
3
|
+
xhr.open("GET", url);
|
|
4
|
+
xhr.responseType = "blob";
|
|
5
|
+
xhr.onload = () => {
|
|
6
|
+
saveAs(xhr.response, name);
|
|
7
|
+
};
|
|
8
|
+
xhr.onerror = () => {
|
|
9
|
+
console.error("Failed to download file");
|
|
10
|
+
};
|
|
11
|
+
xhr.send();
|
|
12
|
+
}
|
|
13
|
+
function corsEnabled(url) {
|
|
14
|
+
const xhr = new XMLHttpRequest();
|
|
15
|
+
xhr.open("HEAD", url, false);
|
|
16
|
+
try {
|
|
17
|
+
xhr.send();
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
}
|
|
21
|
+
return xhr.status >= 200 && xhr.status <= 299;
|
|
22
|
+
}
|
|
23
|
+
function click(link) {
|
|
24
|
+
try {
|
|
25
|
+
link.dispatchEvent(new MouseEvent("click"));
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
const event = document.createEvent("MouseEvents");
|
|
29
|
+
event.initMouseEvent("click", true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
|
|
30
|
+
link.dispatchEvent(event);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function saveAs(source, name) {
|
|
34
|
+
const link = document.createElement("a");
|
|
35
|
+
link.rel = "noopener";
|
|
36
|
+
link.download = name || "";
|
|
37
|
+
if (!link.download) {
|
|
38
|
+
link.target = "_blank";
|
|
39
|
+
}
|
|
40
|
+
if (typeof source === "string") {
|
|
41
|
+
link.href = source;
|
|
42
|
+
if (link.origin !== window.location.origin) {
|
|
43
|
+
if (corsEnabled(link.href)) {
|
|
44
|
+
download(source, name);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
link.target = "_blank";
|
|
48
|
+
click(link);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
click(link);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
link.href = URL.createObjectURL(source);
|
|
57
|
+
setTimeout(() => URL.revokeObjectURL(link.href), 30000);
|
|
58
|
+
setTimeout(() => click(link), 0);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { PLUGIN_DOWNLOAD } from "../../core/index.js";
|
|
2
|
+
import { Download } from "./Download.js";
|
|
3
|
+
declare module "../../types.js" {
|
|
4
|
+
interface GenericSlide {
|
|
5
|
+
/** download url */
|
|
6
|
+
downloadUrl?: string;
|
|
7
|
+
/** download filename override */
|
|
8
|
+
downloadFilename?: string;
|
|
9
|
+
}
|
|
10
|
+
interface Render {
|
|
11
|
+
/** render custom Download button */
|
|
12
|
+
buttonDownload?: RenderFunction;
|
|
13
|
+
/** render custom Download icon */
|
|
14
|
+
iconDownload?: RenderFunction;
|
|
15
|
+
}
|
|
16
|
+
interface ToolbarButtonKeys {
|
|
17
|
+
[PLUGIN_DOWNLOAD]: null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export default Download;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { createModule, MODULE_CONTROLLER, PLUGIN_FULLSCREEN, PLUGIN_THUMBNAILS } from "../../core/index.js";
|
|
2
|
+
import { addToolbarButton, createModule, MODULE_CONTROLLER, PLUGIN_FULLSCREEN, PLUGIN_THUMBNAILS, } from "../../core/index.js";
|
|
3
3
|
import { resolveFullscreenProps } from "./props.js";
|
|
4
4
|
import { FullscreenButton } from "./FullscreenButton.js";
|
|
5
5
|
import { FullscreenContextProvider } from "./FullscreenContext.js";
|
|
6
6
|
export function Fullscreen({ augment, contains, addParent }) {
|
|
7
|
-
augment(({ fullscreen, toolbar
|
|
8
|
-
toolbar:
|
|
7
|
+
augment(({ fullscreen, toolbar, ...restProps }) => ({
|
|
8
|
+
toolbar: addToolbarButton(toolbar, PLUGIN_FULLSCREEN, React.createElement(FullscreenButton, null)),
|
|
9
9
|
fullscreen: resolveFullscreenProps(fullscreen),
|
|
10
10
|
...restProps,
|
|
11
11
|
}));
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { createIcon, IconButton,
|
|
2
|
+
import { createIcon, IconButton, useLightboxProps } from "../../core/index.js";
|
|
3
3
|
import { useFullscreen } from "./FullscreenContext.js";
|
|
4
4
|
const EnterFullscreenIcon = createIcon("EnterFullscreen", React.createElement("path", { d: "M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z" }));
|
|
5
5
|
const ExitFullscreenIcon = createIcon("ExitFullscreen", React.createElement("path", { d: "M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z" }));
|
|
6
6
|
export function FullscreenButton() {
|
|
7
7
|
var _a;
|
|
8
8
|
const { fullscreen, disabled, enter, exit } = useFullscreen();
|
|
9
|
-
const {
|
|
9
|
+
const { render } = useLightboxProps();
|
|
10
10
|
if (disabled)
|
|
11
11
|
return null;
|
|
12
12
|
if (render.buttonFullscreen) {
|
|
13
13
|
return React.createElement(React.Fragment, null, (_a = render.buttonFullscreen) === null || _a === void 0 ? void 0 : _a.call(render, { fullscreen, disabled, enter, exit }));
|
|
14
14
|
}
|
|
15
|
-
return (React.createElement(IconButton, { disabled: disabled, label:
|
|
15
|
+
return (React.createElement(IconButton, { disabled: disabled, label: fullscreen ? "Exit Fullscreen" : "Enter Fullscreen", icon: fullscreen ? ExitFullscreenIcon : EnterFullscreenIcon, renderIcon: fullscreen ? render.iconExitFullscreen : render.iconEnterFullscreen, onClick: fullscreen ? exit : enter }));
|
|
16
16
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import { PLUGIN_FULLSCREEN } from "../../core/index.js";
|
|
2
3
|
import { Fullscreen } from "./Fullscreen.js";
|
|
3
4
|
declare module "../../types.js" {
|
|
4
5
|
interface LightboxProps {
|
|
@@ -18,6 +19,9 @@ declare module "../../types.js" {
|
|
|
18
19
|
/** render custom Exit Fullscreen icon */
|
|
19
20
|
iconExitFullscreen?: RenderFunction;
|
|
20
21
|
}
|
|
22
|
+
interface ToolbarButtonKeys {
|
|
23
|
+
[PLUGIN_FULLSCREEN]: null;
|
|
24
|
+
}
|
|
21
25
|
/** Fullscreen plugin ref */
|
|
22
26
|
interface FullscreenRef {
|
|
23
27
|
/** current fullscreen status */
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as Captions } from "./captions/index.js";
|
|
2
2
|
export { default as Counter } from "./counter/index.js";
|
|
3
|
+
export { default as Download } from "./download/index.js";
|
|
3
4
|
export { default as Fullscreen } from "./fullscreen/index.js";
|
|
4
5
|
export { default as Inline } from "./inline/index.js";
|
|
5
6
|
export { default as Slideshow } from "./slideshow/index.js";
|
package/dist/plugins/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as Captions } from "./captions/index.js";
|
|
2
2
|
export { default as Counter } from "./counter/index.js";
|
|
3
|
+
export { default as Download } from "./download/index.js";
|
|
3
4
|
export { default as Fullscreen } from "./fullscreen/index.js";
|
|
4
5
|
export { default as Inline } from "./inline/index.js";
|
|
5
6
|
export { default as Slideshow } from "./slideshow/index.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { createModule, PLUGIN_SLIDESHOW } from "../../core/index.js";
|
|
2
|
+
import { addToolbarButton, createModule, PLUGIN_SLIDESHOW } from "../../core/index.js";
|
|
3
3
|
import { resolveSlideshowProps } from "./props.js";
|
|
4
4
|
import { SlideshowContextProvider } from "./SlideshowContext.js";
|
|
5
5
|
import { SlideshowButton } from "./SlideshowButton.js";
|
|
6
6
|
export function Slideshow({ augment, addModule }) {
|
|
7
|
-
augment(({ slideshow, toolbar
|
|
8
|
-
toolbar:
|
|
7
|
+
augment(({ slideshow, toolbar, ...restProps }) => ({
|
|
8
|
+
toolbar: addToolbarButton(toolbar, PLUGIN_SLIDESHOW, React.createElement(SlideshowButton, null)),
|
|
9
9
|
slideshow: resolveSlideshowProps(slideshow),
|
|
10
10
|
...restProps,
|
|
11
11
|
}));
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { createIcon, IconButton,
|
|
2
|
+
import { createIcon, IconButton, useLightboxProps, useLoseFocus } from "../../core/index.js";
|
|
3
3
|
import { useSlideshow } from "./SlideshowContext.js";
|
|
4
4
|
const PlayIcon = createIcon("Play", React.createElement("path", { d: "M8 5v14l11-7z" }));
|
|
5
5
|
const PauseIcon = createIcon("Pause", React.createElement("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }));
|
|
6
6
|
export function SlideshowButton() {
|
|
7
7
|
const { playing, disabled, play, pause } = useSlideshow();
|
|
8
|
-
const { render
|
|
8
|
+
const { render } = useLightboxProps();
|
|
9
9
|
const focusListeners = useLoseFocus(disabled);
|
|
10
10
|
if (render.buttonSlideshow) {
|
|
11
11
|
return React.createElement(React.Fragment, null, render.buttonSlideshow({ playing, disabled, play, pause }));
|
|
12
12
|
}
|
|
13
|
-
return (React.createElement(IconButton, { label:
|
|
13
|
+
return (React.createElement(IconButton, { label: playing ? "Pause" : "Play", icon: playing ? PauseIcon : PlayIcon, renderIcon: playing ? render.iconSlideshowPause : render.iconSlideshowPlay, onClick: playing ? pause : play, disabled: disabled, ...focusListeners }));
|
|
14
14
|
}
|
|
@@ -8,7 +8,7 @@ export function SlideshowContextProvider({ slideshow, carousel: { finite }, chil
|
|
|
8
8
|
const [playing, setPlaying] = React.useState(autoplay);
|
|
9
9
|
const scheduler = React.useRef();
|
|
10
10
|
const slideStatus = React.useRef();
|
|
11
|
-
const { slides, currentIndex } = useLightboxState()
|
|
11
|
+
const { slides, currentIndex } = useLightboxState();
|
|
12
12
|
const { setTimeout, clearTimeout } = useTimeouts();
|
|
13
13
|
const { subscribe } = useEvents();
|
|
14
14
|
const { next } = useController();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
import { PLUGIN_SLIDESHOW } from "../../core/index.js";
|
|
2
3
|
import { Slideshow } from "./Slideshow.js";
|
|
3
4
|
declare module "../../types.js" {
|
|
4
5
|
interface LightboxProps {
|
|
@@ -20,6 +21,9 @@ declare module "../../types.js" {
|
|
|
20
21
|
/** render custom Slideshow button */
|
|
21
22
|
buttonSlideshow?: RenderFunction<SlideshowRef>;
|
|
22
23
|
}
|
|
24
|
+
interface ToolbarButtonKeys {
|
|
25
|
+
[PLUGIN_SLIDESHOW]: null;
|
|
26
|
+
}
|
|
23
27
|
/** Slideshow plugin ref */
|
|
24
28
|
interface SlideshowRef {
|
|
25
29
|
/** current slideshow playback status */
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { createModule, MODULE_CONTROLLER, PLUGIN_FULLSCREEN, PLUGIN_THUMBNAILS } from "../../core/index.js";
|
|
2
|
+
import { addToolbarButton, createModule, MODULE_CONTROLLER, PLUGIN_FULLSCREEN, PLUGIN_THUMBNAILS, } from "../../core/index.js";
|
|
3
3
|
import { resolveThumbnailsProps } from "./props.js";
|
|
4
4
|
import { ThumbnailsContextProvider } from "./ThumbnailsContext.js";
|
|
5
5
|
import { ThumbnailsButton } from "./ThumbnailsButton.js";
|
|
6
6
|
export function Thumbnails({ augment, contains, append, addParent }) {
|
|
7
|
-
augment(({ thumbnails: thumbnailsProps, toolbar
|
|
7
|
+
augment(({ thumbnails: thumbnailsProps, toolbar, ...restProps }) => {
|
|
8
8
|
const thumbnails = resolveThumbnailsProps(thumbnailsProps);
|
|
9
9
|
return {
|
|
10
|
-
toolbar:
|
|
11
|
-
buttons: [...(thumbnails.showToggle ? [React.createElement(ThumbnailsButton, { key: PLUGIN_THUMBNAILS })] : []), ...buttons],
|
|
12
|
-
...restToolbar,
|
|
13
|
-
},
|
|
10
|
+
toolbar: addToolbarButton(toolbar, PLUGIN_THUMBNAILS, thumbnails.showToggle ? React.createElement(ThumbnailsButton, null) : null),
|
|
14
11
|
thumbnails,
|
|
15
12
|
...restProps,
|
|
16
13
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { createIcon, createIconDisabled, IconButton,
|
|
2
|
+
import { createIcon, createIconDisabled, IconButton, useLightboxProps } from "../../core/index.js";
|
|
3
3
|
import { useThumbnails } from "./ThumbnailsContext.js";
|
|
4
4
|
const thumbnailsIcon = () => (React.createElement(React.Fragment, null,
|
|
5
5
|
React.createElement("path", { strokeWidth: 2, stroke: "currentColor", strokeLinejoin: "round", fill: "none", d: "M3 5l18 0l0 14l-18 0l0-14z" }),
|
|
@@ -8,9 +8,9 @@ const ThumbnailsVisible = createIcon("ThumbnailsVisible", thumbnailsIcon());
|
|
|
8
8
|
const ThumbnailsHidden = createIconDisabled("ThumbnailsHidden", thumbnailsIcon());
|
|
9
9
|
export function ThumbnailsButton() {
|
|
10
10
|
const { visible, show, hide } = useThumbnails();
|
|
11
|
-
const { render
|
|
11
|
+
const { render } = useLightboxProps();
|
|
12
12
|
if (render.buttonThumbnails) {
|
|
13
13
|
return React.createElement(React.Fragment, null, render.buttonThumbnails({ visible, show, hide }));
|
|
14
14
|
}
|
|
15
|
-
return (React.createElement(IconButton, { label:
|
|
15
|
+
return (React.createElement(IconButton, { label: visible ? "Hide thumbnails" : "Show thumbnails", icon: visible ? ThumbnailsVisible : ThumbnailsHidden, renderIcon: visible ? render.iconThumbnailsVisible : render.iconThumbnailsHidden, onClick: visible ? hide : show }));
|
|
16
16
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, CLASS_FLEX_CENTER, cleanup, clsx, cssClass, cssVar, getSlide, useAnimation, useEventCallback, useEvents, useLightboxProps, useLightboxState, useRTL, } from "../../core/index.js";
|
|
2
|
+
import { ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, CLASS_FLEX_CENTER, cleanup, clsx, cssClass, cssVar, getSlide, hasSlides, useAnimation, useEventCallback, useEvents, useLightboxProps, useLightboxState, useRTL, } from "../../core/index.js";
|
|
3
3
|
import { cssPrefix, cssThumbnailPrefix } from "./utils.js";
|
|
4
4
|
import { Thumbnail } from "./Thumbnail.js";
|
|
5
5
|
import { defaultThumbnailsProps, useThumbnailsProps } from "./props.js";
|
|
@@ -14,7 +14,7 @@ export function ThumbnailsTrack({ containerRef }) {
|
|
|
14
14
|
const track = React.useRef(null);
|
|
15
15
|
const { visible } = useThumbnails();
|
|
16
16
|
const { carousel, styles } = useLightboxProps();
|
|
17
|
-
const { slides, globalIndex, animation } = useLightboxState()
|
|
17
|
+
const { slides, globalIndex, animation } = useLightboxState();
|
|
18
18
|
const { publish, subscribe } = useEvents();
|
|
19
19
|
const isRTL = useRTL();
|
|
20
20
|
const thumbnails = useThumbnailsProps();
|
|
@@ -57,7 +57,7 @@ export function ThumbnailsTrack({ containerRef }) {
|
|
|
57
57
|
const { finite } = carousel;
|
|
58
58
|
const preload = Math.max(Math.min(carousel.preload, slides.length - 1), 0);
|
|
59
59
|
const items = [];
|
|
60
|
-
if (slides
|
|
60
|
+
if (hasSlides(slides)) {
|
|
61
61
|
if (offset < 0) {
|
|
62
62
|
for (let i = index - preload + offset; i < index - preload; i += 1) {
|
|
63
63
|
items.push({ slide: null, index: i, placeholder: true });
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
import { PLUGIN_THUMBNAILS } from "../../core/index.js";
|
|
2
3
|
import { Thumbnails } from "./Thumbnails.js";
|
|
3
4
|
type Position = "top" | "bottom" | "start" | "end";
|
|
4
5
|
declare module "../../types.js" {
|
|
@@ -54,6 +55,9 @@ declare module "../../types.js" {
|
|
|
54
55
|
/** thumbnails container customization slot */
|
|
55
56
|
thumbnailsContainer: "thumbnailsContainer";
|
|
56
57
|
}
|
|
58
|
+
interface ToolbarButtonKeys {
|
|
59
|
+
[PLUGIN_THUMBNAILS]: null;
|
|
60
|
+
}
|
|
57
61
|
/** Thumbnails plugin ref */
|
|
58
62
|
interface ThumbnailsRef {
|
|
59
63
|
/** if `true`, thumbnails are visible */
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { createModule, isImageSlide, PLUGIN_ZOOM } from "../../core/index.js";
|
|
2
|
+
import { addToolbarButton, createModule, isImageSlide, PLUGIN_ZOOM } from "../../core/index.js";
|
|
3
3
|
import { resolveZoomProps } from "./props.js";
|
|
4
4
|
import { ZoomContextProvider } from "./ZoomController.js";
|
|
5
5
|
import { ZoomToolbarControl } from "./ZoomToolbarControl.js";
|
|
6
6
|
import { ZoomWrapper } from "./ZoomWrapper.js";
|
|
7
7
|
export const Zoom = ({ augment, addModule }) => {
|
|
8
|
-
augment(({ toolbar
|
|
8
|
+
augment(({ toolbar, render, zoom, ...restProps }) => ({
|
|
9
9
|
zoom: resolveZoomProps(zoom),
|
|
10
|
-
toolbar:
|
|
10
|
+
toolbar: addToolbarButton(toolbar, PLUGIN_ZOOM, React.createElement(ZoomToolbarControl, null)),
|
|
11
11
|
render: {
|
|
12
12
|
...render,
|
|
13
13
|
slide: (props) => { var _a; return isImageSlide(props.slide) ? React.createElement(ZoomWrapper, { render: render, ...props }) : (_a = render.slide) === null || _a === void 0 ? void 0 : _a.call(render, props); },
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { createIcon, IconButton,
|
|
2
|
+
import { createIcon, IconButton, useLightboxProps } from "../../core/index.js";
|
|
3
3
|
import { useZoom } from "./ZoomController.js";
|
|
4
4
|
const ZoomInIcon = createIcon("ZoomIn", React.createElement(React.Fragment, null,
|
|
5
5
|
React.createElement("path", { d: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" }),
|
|
6
6
|
React.createElement("path", { d: "M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z" })));
|
|
7
7
|
const ZoomOutIcon = createIcon("ZoomOut", React.createElement("path", { d: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14zM7 9h5v1H7z" }));
|
|
8
|
-
export const ZoomButton = React.forwardRef(({ zoomIn, onLoseFocus }, ref)
|
|
8
|
+
export const ZoomButton = React.forwardRef(function ZoomButton({ zoomIn, onLoseFocus }, ref) {
|
|
9
9
|
const wasEnabled = React.useRef(false);
|
|
10
10
|
const wasFocused = React.useRef(false);
|
|
11
11
|
const { zoom, maxZoom, zoomIn: zoomInCallback, zoomOut: zoomOutCallback, disabled: zoomDisabled } = useZoom();
|
|
12
|
-
const { render
|
|
12
|
+
const { render } = useLightboxProps();
|
|
13
13
|
const disabled = zoomDisabled || (zoomIn ? zoom >= maxZoom : zoom <= 1);
|
|
14
14
|
React.useEffect(() => {
|
|
15
15
|
if (disabled && wasEnabled.current && wasFocused.current) {
|
|
@@ -19,10 +19,9 @@ export const ZoomButton = React.forwardRef(({ zoomIn, onLoseFocus }, ref) => {
|
|
|
19
19
|
wasEnabled.current = true;
|
|
20
20
|
}
|
|
21
21
|
}, [disabled, onLoseFocus]);
|
|
22
|
-
return (React.createElement(IconButton, { ref: ref, disabled: disabled, label:
|
|
22
|
+
return (React.createElement(IconButton, { ref: ref, disabled: disabled, label: zoomIn ? "Zoom in" : "Zoom out", icon: zoomIn ? ZoomInIcon : ZoomOutIcon, renderIcon: zoomIn ? render.iconZoomIn : render.iconZoomOut, onClick: zoomIn ? zoomInCallback : zoomOutCallback, onFocus: () => {
|
|
23
23
|
wasFocused.current = true;
|
|
24
24
|
}, onBlur: () => {
|
|
25
25
|
wasFocused.current = false;
|
|
26
26
|
} }));
|
|
27
27
|
});
|
|
28
|
-
ZoomButton.displayName = "ZoomButton";
|
|
@@ -8,7 +8,7 @@ export function ZoomWrapper({ render, slide, offset, rect }) {
|
|
|
8
8
|
const zoomWrapperRef = React.useRef(null);
|
|
9
9
|
const { zoom, maxZoom, offsetX, offsetY, setZoomWrapper } = useZoom();
|
|
10
10
|
const { carousel, on } = useLightboxProps();
|
|
11
|
-
const { currentIndex } = useLightboxState()
|
|
11
|
+
const { currentIndex } = useLightboxState();
|
|
12
12
|
useLayoutEffect(() => {
|
|
13
13
|
if (offset === 0) {
|
|
14
14
|
setZoomWrapper({ zoomWrapperRef, imageDimensions });
|
|
@@ -4,7 +4,7 @@ export function useZoomImageRect(slideRect, imageDimensions) {
|
|
|
4
4
|
var _a, _b;
|
|
5
5
|
let imageRect = { width: 0, height: 0 };
|
|
6
6
|
let maxImageRect = { width: 0, height: 0 };
|
|
7
|
-
const { slides, currentIndex } = useLightboxState()
|
|
7
|
+
const { slides, currentIndex } = useLightboxState();
|
|
8
8
|
const { imageFit } = useLightboxProps().carousel;
|
|
9
9
|
const { maxZoomPixelRatio } = useZoomProps();
|
|
10
10
|
if (slideRect && currentIndex < slides.length) {
|
|
@@ -8,7 +8,7 @@ export function useZoomSensors(zoom, maxZoom, disabled, changeZoom, changeOffset
|
|
|
8
8
|
const activePointers = React.useRef([]);
|
|
9
9
|
const lastPointerDown = React.useRef(0);
|
|
10
10
|
const pinchZoomDistance = React.useRef();
|
|
11
|
-
const { globalIndex } = useLightboxState()
|
|
11
|
+
const { globalIndex } = useLightboxState();
|
|
12
12
|
const { containerRef, subscribeSensors } = useController();
|
|
13
13
|
const { keyboardMoveDistance, zoomInMultiplier, wheelZoomDistanceFactor, scrollToZoom, doubleTapDelay, doubleClickDelay, doubleClickMaxStops, pinchZoomDistanceFactor, } = useZoomProps();
|
|
14
14
|
const translateCoordinates = React.useCallback((event) => {
|
|
@@ -15,7 +15,7 @@ export function useZoomState(imageRect, maxZoom, zoomWrapperRef) {
|
|
|
15
15
|
const [offsetX, setOffsetX] = React.useState(0);
|
|
16
16
|
const [offsetY, setOffsetY] = React.useState(0);
|
|
17
17
|
const animate = useZoomAnimation(zoom, offsetX, offsetY, zoomWrapperRef);
|
|
18
|
-
const { slides, currentIndex, globalIndex } = useLightboxState()
|
|
18
|
+
const { slides, currentIndex, globalIndex } = useLightboxState();
|
|
19
19
|
const { containerRect, slideRect } = useController();
|
|
20
20
|
const { zoomInMultiplier } = useZoomProps();
|
|
21
21
|
const currentSource = getCurrentSource(slides, currentIndex);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
import { PLUGIN_ZOOM } from "../../core/index.js";
|
|
2
3
|
import { Zoom } from "./Zoom.js";
|
|
3
4
|
declare module "../../types.js" {
|
|
4
5
|
interface LightboxProps {
|
|
@@ -53,6 +54,9 @@ declare module "../../types.js" {
|
|
|
53
54
|
/** current zoom level */
|
|
54
55
|
zoom: number;
|
|
55
56
|
}
|
|
57
|
+
interface ToolbarButtonKeys {
|
|
58
|
+
[PLUGIN_ZOOM]: null;
|
|
59
|
+
}
|
|
56
60
|
/** Zoom plugin ref */
|
|
57
61
|
interface ZoomRef {
|
|
58
62
|
/** current zoom level */
|
package/dist/types.d.ts
CHANGED
|
@@ -190,6 +190,8 @@ export interface LightboxState {
|
|
|
190
190
|
currentIndex: number;
|
|
191
191
|
/** current slide index in the (-∞, +∞) range */
|
|
192
192
|
globalIndex: number;
|
|
193
|
+
/** current slide */
|
|
194
|
+
currentSlide: Slide | undefined;
|
|
193
195
|
/** current animation */
|
|
194
196
|
animation?: {
|
|
195
197
|
increment?: number;
|
|
@@ -278,7 +280,11 @@ export type Labels = {
|
|
|
278
280
|
/** Toolbar settings */
|
|
279
281
|
export interface ToolbarSettings {
|
|
280
282
|
/** buttons to render in the toolbar */
|
|
281
|
-
buttons: (
|
|
283
|
+
buttons: (ToolbarButtonKey | React.ReactNode)[];
|
|
284
|
+
}
|
|
285
|
+
export type ToolbarButtonKey = keyof ToolbarButtonKeys;
|
|
286
|
+
export interface ToolbarButtonKeys {
|
|
287
|
+
close: null;
|
|
282
288
|
}
|
|
283
289
|
/** Plugin methods */
|
|
284
290
|
export interface PluginProps {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yet-another-react-lightbox",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Modern React lightbox component",
|
|
5
5
|
"author": "Igor Danchenko",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
"types": "./dist/plugins/counter/index.d.ts",
|
|
31
31
|
"default": "./dist/plugins/counter/index.js"
|
|
32
32
|
},
|
|
33
|
+
"./plugins/download": {
|
|
34
|
+
"types": "./dist/plugins/download/index.d.ts",
|
|
35
|
+
"default": "./dist/plugins/download/index.js"
|
|
36
|
+
},
|
|
33
37
|
"./plugins/fullscreen": {
|
|
34
38
|
"types": "./dist/plugins/fullscreen/index.d.ts",
|
|
35
39
|
"default": "./dist/plugins/fullscreen/index.js"
|
|
@@ -74,6 +78,9 @@
|
|
|
74
78
|
"plugins/counter": [
|
|
75
79
|
"dist/plugins/counter/index.d.ts"
|
|
76
80
|
],
|
|
81
|
+
"plugins/download": [
|
|
82
|
+
"dist/plugins/download/index.d.ts"
|
|
83
|
+
],
|
|
77
84
|
"plugins/fullscreen": [
|
|
78
85
|
"dist/plugins/fullscreen/index.d.ts"
|
|
79
86
|
],
|