yet-another-react-lightbox 1.0.0 → 1.1.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 +1 -1
- package/dist/Lightbox.d.ts +5 -5
- package/dist/Lightbox.js +7 -4
- package/dist/core/components/IconButton.d.ts +2 -1
- package/dist/core/components/IconButton.js +1 -2
- package/dist/core/components/ImageSlide.d.ts +5 -3
- package/dist/core/components/ImageSlide.js +9 -6
- package/dist/core/config.js +13 -10
- package/dist/core/contexts/Events.js +2 -1
- package/dist/core/hooks/useContainerRect.js +2 -2
- package/dist/core/hooks/useSensors.js +4 -2
- package/dist/core/modules/Carousel.js +9 -6
- package/dist/core/modules/Controller.js +13 -8
- package/dist/core/modules/Navigation.d.ts +5 -4
- package/dist/core/modules/Navigation.js +5 -5
- package/dist/core/modules/Portal.js +24 -7
- package/dist/core/modules/Toolbar.js +3 -2
- package/dist/core/utils.js +3 -2
- package/dist/plugins/Fullscreen.d.ts +12 -3
- package/dist/plugins/Fullscreen.js +13 -15
- package/dist/plugins/Video.js +1 -1
- package/dist/types.d.ts +21 -5
- package/dist/types.js +4 -6
- package/package.json +5 -5
package/README.md
CHANGED
package/dist/Lightbox.d.ts
CHANGED
|
@@ -7,9 +7,7 @@ declare const LightboxComponent: {
|
|
|
7
7
|
close: import("prop-types").Validator<(...args: any[]) => any>;
|
|
8
8
|
index: import("prop-types").Validator<number>;
|
|
9
9
|
slides: import("prop-types").Validator<any[]>;
|
|
10
|
-
render: import("prop-types").Validator<import("prop-types").InferProps<{
|
|
11
|
-
slide: import("prop-types").Validator<(...args: any[]) => any>;
|
|
12
|
-
}>>;
|
|
10
|
+
render: import("prop-types").Validator<import("prop-types").InferProps<{}>>;
|
|
13
11
|
plugins: import("prop-types").Validator<((...args: any[]) => any)[]>;
|
|
14
12
|
toolbar: import("prop-types").Validator<import("prop-types").InferProps<{
|
|
15
13
|
buttons: import("prop-types").Validator<(string | number | boolean | import("prop-types").ReactElementLike | import("prop-types").ReactNodeArray | null | undefined)[]>;
|
|
@@ -25,6 +23,7 @@ declare const LightboxComponent: {
|
|
|
25
23
|
fade: import("prop-types").Validator<number>;
|
|
26
24
|
swipe: import("prop-types").Validator<number>;
|
|
27
25
|
}>>;
|
|
26
|
+
on: import("prop-types").Validator<import("prop-types").InferProps<{}>>;
|
|
28
27
|
};
|
|
29
28
|
defaultProps: {
|
|
30
29
|
open: boolean;
|
|
@@ -34,9 +33,10 @@ declare const LightboxComponent: {
|
|
|
34
33
|
render: import("./types.js").Render;
|
|
35
34
|
plugins: import("./types.js").Plugin[];
|
|
36
35
|
toolbar: import("./types.js").Toolbar;
|
|
37
|
-
labels:
|
|
36
|
+
labels: import("./types.js").Labels;
|
|
38
37
|
animation: import("./types.js").Animation;
|
|
39
38
|
carousel: import("./types.js").Carousel;
|
|
39
|
+
on: import("./types.js").Callbacks;
|
|
40
40
|
};
|
|
41
41
|
};
|
|
42
42
|
declare type ComponentProps<T> = T extends React.ComponentType<infer P> | React.Component<infer P> ? JSX.LibraryManagedAttributes<T, P> : never;
|
|
@@ -45,5 +45,5 @@ declare type NestedPartial<T extends object> = {
|
|
|
45
45
|
[P in keyof T]?: MakePartial<T[P]>;
|
|
46
46
|
};
|
|
47
47
|
declare type NestedOptional<T, K extends keyof T> = Omit<T, K> & NestedPartial<Pick<T, K>>;
|
|
48
|
-
export declare const Lightbox: (props: NestedOptional<ComponentProps<typeof LightboxComponent>, "carousel" | "animation"
|
|
48
|
+
export declare const Lightbox: (props: NestedOptional<ComponentProps<typeof LightboxComponent>, "carousel" | "animation">) => JSX.Element;
|
|
49
49
|
export {};
|
package/dist/Lightbox.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { LightboxDefaultProps, LightboxPropTypes } from "./types.js";
|
|
3
3
|
import { CarouselModule, ControllerModule, CoreModule, createNode, NavigationModule, NoScrollModule, PortalModule, ToolbarModule, withPlugins, } from "./core/index.js";
|
|
4
|
-
const renderNode = (node, props) =>
|
|
4
|
+
const renderNode = (node, props) => {
|
|
5
|
+
var _a;
|
|
6
|
+
return React.createElement(node.module.component, { key: node.module.name, ...props }, (_a = node.children) === null || _a === void 0 ? void 0 : _a.map((child) => renderNode(child, props)));
|
|
7
|
+
};
|
|
5
8
|
const LightboxComponent = (props) => {
|
|
6
9
|
const { plugins } = props;
|
|
7
10
|
const { config, augmentation } = withPlugins([
|
|
@@ -23,7 +26,7 @@ const LightboxComponent = (props) => {
|
|
|
23
26
|
LightboxComponent.propTypes = LightboxPropTypes;
|
|
24
27
|
LightboxComponent.defaultProps = LightboxDefaultProps;
|
|
25
28
|
export const Lightbox = (props) => {
|
|
26
|
-
const { carousel, animation,
|
|
27
|
-
const { carousel: defaultCarousel, animation: defaultAnimation,
|
|
28
|
-
return (React.createElement(LightboxComponent, { carousel: { ...defaultCarousel, ...carousel }, animation: { ...defaultAnimation, ...animation },
|
|
29
|
+
const { carousel, animation, ...restProps } = props;
|
|
30
|
+
const { carousel: defaultCarousel, animation: defaultAnimation, ...restDefaultProps } = LightboxDefaultProps;
|
|
31
|
+
return (React.createElement(LightboxComponent, { carousel: { ...defaultCarousel, ...carousel }, animation: { ...defaultAnimation, ...animation }, ...restDefaultProps, ...restProps }));
|
|
29
32
|
};
|
|
@@ -2,5 +2,6 @@ import * as React from "react";
|
|
|
2
2
|
export declare type IconButtonProps = Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "type" | "aria-label"> & {
|
|
3
3
|
label: string;
|
|
4
4
|
icon: React.ElementType;
|
|
5
|
+
renderIcon?: () => React.ReactNode;
|
|
5
6
|
};
|
|
6
|
-
export declare const IconButton:
|
|
7
|
+
export declare const IconButton: React.FC<IconButtonProps>;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { clsx, cssClass } from "../utils.js";
|
|
3
|
-
export const IconButton = ({ label, className, icon: Icon, onClick, ...rest }) => (React.createElement("button", { type: "button", "aria-label": label, className: clsx(cssClass("button"), className), onClick: onClick
|
|
4
|
-
React.createElement(Icon, { className: cssClass("icon") })));
|
|
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") })));
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import { SlideImage } from "../../types.js";
|
|
3
|
-
export declare
|
|
2
|
+
import { Render, SlideImage } from "../../types.js";
|
|
3
|
+
export declare type ImageSlideProps = {
|
|
4
4
|
slide: SlideImage;
|
|
5
|
-
|
|
5
|
+
render: Render;
|
|
6
|
+
};
|
|
7
|
+
export declare const ImageSlide: ({ slide: image, render }: ImageSlideProps) => JSX.Element;
|
|
@@ -3,7 +3,8 @@ import { clsx, cssClass } from "../utils.js";
|
|
|
3
3
|
import { useLatest } from "../hooks/index.js";
|
|
4
4
|
import { ErrorIcon, LoadingIcon } from "./Icons.js";
|
|
5
5
|
import { useController } from "../modules/Controller.js";
|
|
6
|
-
export const ImageSlide = ({ slide: image }) => {
|
|
6
|
+
export const ImageSlide = ({ slide: image, render }) => {
|
|
7
|
+
var _a, _b, _c;
|
|
7
8
|
const [state, setState] = React.useState("loading");
|
|
8
9
|
const latestState = useLatest(state);
|
|
9
10
|
const imageRef = React.useRef(null);
|
|
@@ -23,7 +24,7 @@ export const ImageSlide = ({ slide: image }) => {
|
|
|
23
24
|
}, [latestState]);
|
|
24
25
|
const setImageRef = React.useCallback((img) => {
|
|
25
26
|
imageRef.current = img;
|
|
26
|
-
if (img
|
|
27
|
+
if (img === null || img === void 0 ? void 0 : img.complete) {
|
|
27
28
|
handleLoading(img);
|
|
28
29
|
}
|
|
29
30
|
}, [handleLoading]);
|
|
@@ -48,13 +49,15 @@ export const ImageSlide = ({ slide: image }) => {
|
|
|
48
49
|
},
|
|
49
50
|
}
|
|
50
51
|
: {
|
|
51
|
-
style: (imageRef.current
|
|
52
|
+
style: ((_b = (_a = imageRef.current) === null || _a === void 0 ? void 0 : _a.naturalWidth) !== null && _b !== void 0 ? _b : 0) > 0
|
|
52
53
|
? {
|
|
53
|
-
maxWidth: `${imageRef.current
|
|
54
|
+
maxWidth: `${(_c = imageRef.current) === null || _c === void 0 ? void 0 : _c.naturalWidth}px`,
|
|
54
55
|
}
|
|
55
56
|
: undefined,
|
|
56
57
|
}), src: image.src }),
|
|
57
58
|
state !== "complete" && (React.createElement("div", { className: cssClass("slide_placeholder") },
|
|
58
|
-
state === "loading" &&
|
|
59
|
-
|
|
59
|
+
state === "loading" &&
|
|
60
|
+
(render.iconLoading ? (render.iconLoading()) : (React.createElement(LoadingIcon, { className: clsx(cssClass("icon"), cssClass("slide_loading")) }))),
|
|
61
|
+
state === "error" &&
|
|
62
|
+
(render.iconError ? (render.iconError()) : (React.createElement(ErrorIcon, { className: clsx(cssClass("icon"), cssClass("slide_error")) })))))));
|
|
60
63
|
};
|
package/dist/core/config.js
CHANGED
|
@@ -12,12 +12,12 @@ const traverseNode = (node, target, apply) => {
|
|
|
12
12
|
}
|
|
13
13
|
if (node.children) {
|
|
14
14
|
return [
|
|
15
|
-
createNode(node.module, node.children.flatMap((n) => traverseNode(n, target, apply)
|
|
15
|
+
createNode(node.module, node.children.flatMap((n) => { var _a; return (_a = traverseNode(n, target, apply)) !== null && _a !== void 0 ? _a : []; })),
|
|
16
16
|
];
|
|
17
17
|
}
|
|
18
18
|
return [node];
|
|
19
19
|
};
|
|
20
|
-
const traverse = (nodes, target, apply) => nodes.flatMap((node) => traverseNode(node, target, apply)
|
|
20
|
+
const traverse = (nodes, target, apply) => nodes.flatMap((node) => { var _a; return (_a = traverseNode(node, target, apply)) !== null && _a !== void 0 ? _a : []; });
|
|
21
21
|
export const withPlugins = (root, plugins) => {
|
|
22
22
|
let config = root;
|
|
23
23
|
const augmentations = [];
|
|
@@ -29,13 +29,16 @@ export const withPlugins = (root, plugins) => {
|
|
|
29
29
|
config = traverse(config, target, (node) => [createNode(module, [node])]);
|
|
30
30
|
};
|
|
31
31
|
const addChild = (target, module, precede) => {
|
|
32
|
-
config = traverse(config, target, (node) =>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
config = traverse(config, target, (node) => {
|
|
33
|
+
var _a;
|
|
34
|
+
return [
|
|
35
|
+
createNode(node.module, [
|
|
36
|
+
...(precede ? [createNode(module)] : []),
|
|
37
|
+
...((_a = node.children) !== null && _a !== void 0 ? _a : []),
|
|
38
|
+
...(!precede ? [createNode(module)] : []),
|
|
39
|
+
]),
|
|
40
|
+
];
|
|
41
|
+
});
|
|
39
42
|
};
|
|
40
43
|
const addSibling = (target, module, precede) => {
|
|
41
44
|
config = traverse(config, target, (node) => [
|
|
@@ -53,7 +56,7 @@ export const withPlugins = (root, plugins) => {
|
|
|
53
56
|
const augment = (augmentation) => {
|
|
54
57
|
augmentations.push(augmentation);
|
|
55
58
|
};
|
|
56
|
-
plugins
|
|
59
|
+
plugins === null || plugins === void 0 ? void 0 : plugins.forEach((plugin) => {
|
|
57
60
|
plugin({
|
|
58
61
|
addParent,
|
|
59
62
|
addChild,
|
|
@@ -17,7 +17,8 @@ export const EventsProvider = ({ children }) => {
|
|
|
17
17
|
return () => unsubscribe(topic, callback);
|
|
18
18
|
};
|
|
19
19
|
const publish = (topic, event) => {
|
|
20
|
-
|
|
20
|
+
var _a;
|
|
21
|
+
(_a = subscriptions.current[topic]) === null || _a === void 0 ? void 0 : _a.forEach((callback) => callback(topic, event));
|
|
21
22
|
};
|
|
22
23
|
React.useEffect(() => () => {
|
|
23
24
|
subscriptions.current = {};
|
|
@@ -10,8 +10,8 @@ export const useContainerRect = () => {
|
|
|
10
10
|
observerRef.current = undefined;
|
|
11
11
|
}
|
|
12
12
|
const updateContainerRect = () => {
|
|
13
|
-
const width = node
|
|
14
|
-
const height = node
|
|
13
|
+
const width = node === null || node === void 0 ? void 0 : node.clientWidth;
|
|
14
|
+
const height = node === null || node === void 0 ? void 0 : node.clientHeight;
|
|
15
15
|
setContainerRect(width !== undefined && height !== undefined
|
|
16
16
|
? {
|
|
17
17
|
width,
|
|
@@ -3,7 +3,8 @@ export const useSensors = () => {
|
|
|
3
3
|
const [subscribers] = React.useState({});
|
|
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) => listener(event));
|
|
7
8
|
};
|
|
8
9
|
return {
|
|
9
10
|
registerSensors: {
|
|
@@ -21,10 +22,11 @@ export const useSensors = () => {
|
|
|
21
22
|
onWheel: (event) => notifySubscribers("onWheel", event),
|
|
22
23
|
},
|
|
23
24
|
subscribeSensors: (type, callback) => {
|
|
25
|
+
var _a;
|
|
24
26
|
if (!subscribers[type]) {
|
|
25
27
|
subscribers[type] = [];
|
|
26
28
|
}
|
|
27
|
-
subscribers[type]
|
|
29
|
+
(_a = subscribers[type]) === null || _a === void 0 ? void 0 : _a.push(callback);
|
|
28
30
|
return () => {
|
|
29
31
|
const listeners = subscribers[type];
|
|
30
32
|
if (listeners) {
|
|
@@ -4,21 +4,24 @@ import { createModule } from "../config.js";
|
|
|
4
4
|
import { clsx, cssClass, cssVar } from "../utils.js";
|
|
5
5
|
import { ImageSlide } from "../components/index.js";
|
|
6
6
|
import { useController } from "./Controller.js";
|
|
7
|
-
const CarouselSlide = ({ slide, offset,
|
|
7
|
+
const CarouselSlide = ({ slide, offset, render }) => {
|
|
8
|
+
var _a;
|
|
9
|
+
return (React.createElement("div", { className: clsx(cssClass("slide"), cssClass("flex_center")), style: { [cssVar("slide_offset")]: offset } }, ((_a = render.slide) === null || _a === void 0 ? void 0 : _a.call(render, slide)) || ("src" in slide && React.createElement(ImageSlide, { slide: slide, render: render }))));
|
|
10
|
+
};
|
|
8
11
|
export const Carousel = (props) => {
|
|
9
|
-
const { slides, carousel: { finite, preload, padding, spacing }, render
|
|
12
|
+
const { slides, carousel: { finite, preload, padding, spacing }, render, } = props;
|
|
10
13
|
const { currentIndex, globalIndex } = useController();
|
|
11
14
|
const items = [];
|
|
12
|
-
if (slides
|
|
15
|
+
if ((slides === null || slides === void 0 ? void 0 : slides.length) > 0) {
|
|
13
16
|
for (let i = currentIndex - preload; i < currentIndex; i += 1) {
|
|
14
17
|
if (!finite || i >= 0) {
|
|
15
|
-
items.push(React.createElement(CarouselSlide, { key: globalIndex + i - currentIndex, slide: slides[(i + preload * slides.length) % slides.length], offset: i - currentIndex,
|
|
18
|
+
items.push(React.createElement(CarouselSlide, { key: globalIndex + i - currentIndex, slide: slides[(i + preload * slides.length) % slides.length], offset: i - currentIndex, render: render }));
|
|
16
19
|
}
|
|
17
20
|
}
|
|
18
|
-
items.push(React.createElement(CarouselSlide, { key: globalIndex, slide: slides[currentIndex], offset: 0,
|
|
21
|
+
items.push(React.createElement(CarouselSlide, { key: globalIndex, slide: slides[currentIndex], offset: 0, render: render }));
|
|
19
22
|
for (let i = currentIndex + 1; i <= currentIndex + preload; i += 1) {
|
|
20
23
|
if (!finite || i <= slides.length - 1) {
|
|
21
|
-
items.push(React.createElement(CarouselSlide, { key: globalIndex + i - currentIndex, slide: slides[i % slides.length], offset: i - currentIndex,
|
|
24
|
+
items.push(React.createElement(CarouselSlide, { key: globalIndex + i - currentIndex, slide: slides[i % slides.length], offset: i - currentIndex, render: render }));
|
|
22
25
|
}
|
|
23
26
|
}
|
|
24
27
|
}
|
|
@@ -41,18 +41,21 @@ export const Controller = ({ children, ...props }) => {
|
|
|
41
41
|
};
|
|
42
42
|
}, [containerRef]);
|
|
43
43
|
React.useEffect(() => {
|
|
44
|
-
|
|
44
|
+
var _a;
|
|
45
|
+
(_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
45
46
|
}, [containerRef]);
|
|
46
|
-
React.useEffect(() =>
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
React.useEffect(() => {
|
|
48
|
+
var _a, _b;
|
|
49
|
+
(_b = (_a = refs.current.props.on).view) === null || _b === void 0 ? void 0 : _b.call(_a, state.currentIndex);
|
|
50
|
+
}, [state.currentIndex]);
|
|
49
51
|
const updateSwipeOffset = React.useCallback(() => {
|
|
52
|
+
var _a, _b;
|
|
50
53
|
const offsetVar = cssVar("swipe_offset");
|
|
51
54
|
if (refs.current.swipeOffset !== 0) {
|
|
52
|
-
containerRef.current
|
|
55
|
+
(_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.style.setProperty(offsetVar, `${Math.round(refs.current.swipeOffset)}px`);
|
|
53
56
|
}
|
|
54
57
|
else {
|
|
55
|
-
containerRef.current
|
|
58
|
+
(_b = containerRef.current) === null || _b === void 0 ? void 0 : _b.style.removeProperty(offsetVar);
|
|
56
59
|
}
|
|
57
60
|
}, [containerRef]);
|
|
58
61
|
useEnhancedEffect(() => {
|
|
@@ -77,6 +80,7 @@ export const Controller = ({ children, ...props }) => {
|
|
|
77
80
|
((offset > 0 && currentIndex === 0) || (offset < 0 && currentIndex === slides.length - 1)));
|
|
78
81
|
}, []);
|
|
79
82
|
const swipe = React.useCallback((direction) => {
|
|
83
|
+
var _a;
|
|
80
84
|
const { current } = refs;
|
|
81
85
|
const slidesCount = current.props.slides.length;
|
|
82
86
|
const swipeAnimationDuration = current.props.animation.swipe;
|
|
@@ -85,7 +89,7 @@ export const Controller = ({ children, ...props }) => {
|
|
|
85
89
|
let newSwipeState = "swipe-animation";
|
|
86
90
|
let newSwipeAnimationDuration = swipeAnimationDuration;
|
|
87
91
|
if (!direction) {
|
|
88
|
-
const containerWidth = current.containerRect
|
|
92
|
+
const containerWidth = (_a = current.containerRect) === null || _a === void 0 ? void 0 : _a.width;
|
|
89
93
|
const elapsedTime = current.swipeStartTime ? Date.now() - current.swipeStartTime : 0;
|
|
90
94
|
const expectedTime = containerWidth
|
|
91
95
|
? (swipeAnimationDuration / containerWidth) * Math.abs(swipeOffset)
|
|
@@ -194,6 +198,7 @@ export const Controller = ({ children, ...props }) => {
|
|
|
194
198
|
}, [clearPointer, swipe]);
|
|
195
199
|
React.useEffect(() => cleanup(subscribeSensors("onPointerDown", onPointerDown), subscribeSensors("onPointerMove", onPointerMove), subscribeSensors("onPointerUp", onPointerUp), subscribeSensors("onPointerLeave", onPointerUp), subscribeSensors("onPointerCancel", onPointerUp)), [subscribeSensors, onPointerDown, onPointerMove, onPointerUp]);
|
|
196
200
|
const onWheel = React.useCallback((event) => {
|
|
201
|
+
var _a;
|
|
197
202
|
if (event.ctrlKey) {
|
|
198
203
|
return;
|
|
199
204
|
}
|
|
@@ -223,7 +228,7 @@ export const Controller = ({ children, ...props }) => {
|
|
|
223
228
|
}
|
|
224
229
|
}
|
|
225
230
|
else if (current.swipeState === "swipe") {
|
|
226
|
-
const containerWidth = current.containerRect
|
|
231
|
+
const containerWidth = (_a = current.containerRect) === null || _a === void 0 ? void 0 : _a.width;
|
|
227
232
|
if (containerWidth) {
|
|
228
233
|
current.swipeOffset -= event.deltaX;
|
|
229
234
|
current.swipeOffset =
|
|
@@ -3,12 +3,13 @@ import { Component, Labels } from "../../types.js";
|
|
|
3
3
|
import { Publish } from "../contexts/index.js";
|
|
4
4
|
export declare type NavigationButtonProps = {
|
|
5
5
|
publish: Publish;
|
|
6
|
-
labels
|
|
7
|
-
|
|
6
|
+
labels?: Labels;
|
|
7
|
+
label: string;
|
|
8
8
|
icon: React.ElementType;
|
|
9
|
+
renderIcon?: () => React.ReactNode;
|
|
9
10
|
action: "prev" | "next";
|
|
10
|
-
disabled
|
|
11
|
+
disabled?: boolean;
|
|
11
12
|
};
|
|
12
|
-
export declare const NavigationButton: ({ publish, labels,
|
|
13
|
+
export declare const NavigationButton: ({ publish, labels, label, icon, renderIcon, action, disabled, }: NavigationButtonProps) => JSX.Element;
|
|
13
14
|
export declare const Navigation: Component;
|
|
14
15
|
export declare const NavigationModule: import("../../types.js").Module;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { createModule } from "../config.js";
|
|
3
|
-
import { cssClass, label } from "../utils.js";
|
|
3
|
+
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
|
-
export const NavigationButton = ({ publish, labels,
|
|
7
|
+
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
8
|
publish(action);
|
|
9
9
|
} }));
|
|
10
|
-
export const Navigation = ({ slides, carousel: { finite }, labels }) => {
|
|
10
|
+
export const Navigation = ({ slides, carousel: { finite }, labels, render: { buttonPrev, buttonNext, iconPrev, iconNext }, }) => {
|
|
11
11
|
const { currentIndex, subscribeSensors } = useController();
|
|
12
12
|
const { publish } = useEvents();
|
|
13
13
|
React.useEffect(() => subscribeSensors("onKeyUp", (event) => {
|
|
@@ -19,7 +19,7 @@ export const Navigation = ({ slides, carousel: { finite }, labels }) => {
|
|
|
19
19
|
}
|
|
20
20
|
}), [subscribeSensors, publish]);
|
|
21
21
|
return (React.createElement(React.Fragment, null,
|
|
22
|
-
React.createElement(NavigationButton, {
|
|
23
|
-
React.createElement(NavigationButton, {
|
|
22
|
+
buttonPrev ? (buttonPrev()) : (React.createElement(NavigationButton, { label: "Previous Image", action: "prev", icon: PreviousIcon, renderIcon: iconPrev, disabled: finite && currentIndex === 0, labels: labels, publish: publish })),
|
|
23
|
+
buttonNext ? (buttonNext()) : (React.createElement(NavigationButton, { label: "Next Image", action: "next", icon: NextIcon, renderIcon: iconNext, disabled: finite && currentIndex === slides.length - 1, labels: labels, publish: publish }))));
|
|
24
24
|
};
|
|
25
25
|
export const NavigationModule = createModule("navigation", Navigation);
|
|
@@ -3,32 +3,49 @@ import * as ReactDOM from "react-dom";
|
|
|
3
3
|
import { LightboxDefaultProps } from "../../types.js";
|
|
4
4
|
import { createModule } from "../config.js";
|
|
5
5
|
import { cssClass, cssVar } from "../utils.js";
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import { useLatest } from "../hooks/useLatest.js";
|
|
7
|
+
import { useEvents, useTimeouts } from "../contexts/index.js";
|
|
8
|
+
export const Portal = ({ children, ...props }) => {
|
|
8
9
|
const [mounted, setMounted] = React.useState(false);
|
|
10
|
+
const latestProps = useLatest(props);
|
|
11
|
+
const { setTimeout } = useTimeouts();
|
|
12
|
+
const { subscribe } = useEvents();
|
|
9
13
|
const [portal] = React.useState(() => {
|
|
10
14
|
const div = document.createElement("div");
|
|
11
15
|
div.className = cssClass("portal");
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
const fadeAnimation = latestProps.current.animation.fade;
|
|
17
|
+
if (fadeAnimation !== LightboxDefaultProps.animation.fade) {
|
|
18
|
+
div.style.setProperty(cssVar("fade_animation_duration"), `${Math.round(fadeAnimation)}ms`);
|
|
14
19
|
}
|
|
15
20
|
return div;
|
|
16
21
|
});
|
|
17
|
-
const { subscribe } = useEvents();
|
|
18
22
|
React.useEffect(() => subscribe("close", () => {
|
|
23
|
+
var _a, _b;
|
|
24
|
+
(_b = (_a = latestProps.current.on).exiting) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
19
25
|
portal.classList.remove(cssClass("portal_open"));
|
|
20
|
-
|
|
26
|
+
setTimeout(() => {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
(_b = (_a = latestProps.current.on).exited) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
29
|
+
latestProps.current.close();
|
|
30
|
+
}, latestProps.current.animation.fade);
|
|
31
|
+
}), [portal, setTimeout, subscribe, latestProps]);
|
|
21
32
|
React.useEffect(() => {
|
|
33
|
+
var _a, _b;
|
|
22
34
|
document.body.appendChild(portal);
|
|
23
35
|
setMounted(true);
|
|
36
|
+
(_b = (_a = latestProps.current.on).entering) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
24
37
|
setTimeout(() => {
|
|
25
38
|
portal.classList.add(cssClass("portal_open"));
|
|
26
39
|
}, 0);
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
var _a, _b;
|
|
42
|
+
(_b = (_a = latestProps.current.on).entered) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
43
|
+
}, latestProps.current.animation.fade);
|
|
27
44
|
return () => {
|
|
28
45
|
document.body.removeChild(portal);
|
|
29
46
|
setMounted(false);
|
|
30
47
|
};
|
|
31
|
-
}, [portal]);
|
|
48
|
+
}, [portal, setTimeout, latestProps]);
|
|
32
49
|
return ReactDOM.createPortal(mounted ? children : null, portal);
|
|
33
50
|
};
|
|
34
51
|
export const PortalModule = createModule("portal", Portal);
|
|
@@ -3,8 +3,9 @@ import { createModule } from "../config.js";
|
|
|
3
3
|
import { cssClass, label } from "../utils.js";
|
|
4
4
|
import { useEvents } from "../contexts/index.js";
|
|
5
5
|
import { CloseIcon, IconButton } from "../components/index.js";
|
|
6
|
-
export const Toolbar = ({ toolbar: { buttons }, labels }) => {
|
|
6
|
+
export const Toolbar = ({ toolbar: { buttons }, labels, render: { buttonClose, iconClose } }) => {
|
|
7
7
|
const { publish } = useEvents();
|
|
8
|
-
|
|
8
|
+
const renderCloseButton = () => buttonClose ? (buttonClose()) : (React.createElement(IconButton, { key: "close", label: label(labels, "Close"), icon: CloseIcon, renderIcon: iconClose, onClick: () => publish("close") }));
|
|
9
|
+
return (React.createElement("div", { className: cssClass("toolbar") }, buttons === null || buttons === void 0 ? void 0 : buttons.map((button) => (button === "close" ? renderCloseButton() : button))));
|
|
9
10
|
};
|
|
10
11
|
export const ToolbarModule = createModule("toolbar", Toolbar);
|
package/dist/core/utils.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
export const clsx = (...classes) => [...classes].filter((cls) => Boolean(cls)).join(" ");
|
|
3
|
-
|
|
4
|
-
export const
|
|
3
|
+
const cssPrefix = "yarl__";
|
|
4
|
+
export const cssClass = (name) => `${cssPrefix}${name}`;
|
|
5
|
+
export const cssVar = (name) => `--${cssPrefix}${name}`;
|
|
5
6
|
export const label = (labels, lbl) => (labels && labels[lbl] ? labels[lbl] : lbl);
|
|
6
7
|
export const cleanup = (...cleaners) => () => {
|
|
7
8
|
cleaners.forEach((cleaner) => {
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
import { LightboxProps, Plugin } from "../types.js";
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { LightboxProps, Plugin, Render } from "../types.js";
|
|
3
3
|
declare module "../types.js" {
|
|
4
4
|
interface LightboxProps {
|
|
5
5
|
fullscreen?: boolean;
|
|
6
6
|
}
|
|
7
|
+
interface Render {
|
|
8
|
+
buttonFullscreen?: ({ fullscreen, toggleFullscreen, }: {
|
|
9
|
+
fullscreen: boolean;
|
|
10
|
+
toggleFullscreen: () => void;
|
|
11
|
+
}) => React.ReactNode;
|
|
12
|
+
iconEnterFullscreen?: () => React.ReactNode;
|
|
13
|
+
iconExitFullscreen?: () => React.ReactNode;
|
|
14
|
+
}
|
|
7
15
|
}
|
|
8
16
|
declare global {
|
|
9
17
|
interface Document {
|
|
@@ -25,6 +33,7 @@ declare global {
|
|
|
25
33
|
}
|
|
26
34
|
export declare type FullscreenButtonProps = Pick<LightboxProps, "labels"> & {
|
|
27
35
|
auto: boolean;
|
|
36
|
+
render: Render;
|
|
28
37
|
};
|
|
29
|
-
export declare const FullscreenButton: ({ auto, labels }: FullscreenButtonProps) => JSX.Element | null;
|
|
38
|
+
export declare const FullscreenButton: ({ auto, labels, render }: FullscreenButtonProps) => JSX.Element | null;
|
|
30
39
|
export declare const Fullscreen: Plugin;
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { createIcon, IconButton, label, useController } from "../core/index.js";
|
|
2
|
+
import { createIcon, IconButton, label, useController, useLatest } from "../core/index.js";
|
|
3
3
|
const EnterFullscreenIcon = createIcon("EnterFullscreen", React.createElement("path", { d: "M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z" }));
|
|
4
4
|
const ExitFullscreenIcon = createIcon("ExitFullscreen", React.createElement("path", { d: "M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z" }));
|
|
5
|
-
export const FullscreenButton = ({ auto, labels }) => {
|
|
5
|
+
export const FullscreenButton = ({ auto, labels, render }) => {
|
|
6
6
|
const [fullscreen, setFullscreen] = React.useState(false);
|
|
7
|
+
const latestAuto = useLatest(auto);
|
|
7
8
|
const { containerRef } = useController();
|
|
8
9
|
const isFullscreenEnabled = () => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
document.mozFullScreenEnabled ??
|
|
12
|
-
document.msFullscreenEnabled ??
|
|
13
|
-
false);
|
|
10
|
+
var _a, _b, _c, _d;
|
|
11
|
+
return (_d = (_c = (_b = (_a = document.fullscreenEnabled) !== null && _a !== void 0 ? _a : document.webkitFullscreenEnabled) !== null && _b !== void 0 ? _b : document.mozFullScreenEnabled) !== null && _c !== void 0 ? _c : document.msFullscreenEnabled) !== null && _d !== void 0 ? _d : false;
|
|
14
12
|
};
|
|
15
|
-
const getFullscreenElement = React.useCallback(() =>
|
|
16
|
-
|
|
17
|
-
document.mozFullScreenElement
|
|
18
|
-
|
|
13
|
+
const getFullscreenElement = React.useCallback(() => {
|
|
14
|
+
var _a, _b, _c;
|
|
15
|
+
return (_c = (_b = (_a = document.fullscreenElement) !== null && _a !== void 0 ? _a : document.webkitFullscreenElement) !== null && _b !== void 0 ? _b : document.mozFullScreenElement) !== null && _c !== void 0 ? _c : document.msFullscreenElement;
|
|
16
|
+
}, []);
|
|
19
17
|
const requestFullscreen = React.useCallback(() => {
|
|
20
18
|
const container = containerRef.current;
|
|
21
19
|
if (container) {
|
|
@@ -86,19 +84,19 @@ export const FullscreenButton = ({ auto, labels }) => {
|
|
|
86
84
|
}, [fullscreenChangeListener]);
|
|
87
85
|
React.useEffect(() => () => exitFullscreen(), [exitFullscreen]);
|
|
88
86
|
React.useEffect(() => {
|
|
89
|
-
if (
|
|
87
|
+
if (latestAuto.current) {
|
|
90
88
|
requestFullscreen();
|
|
91
89
|
}
|
|
92
|
-
}, [
|
|
90
|
+
}, [latestAuto, requestFullscreen]);
|
|
93
91
|
if (!isFullscreenEnabled())
|
|
94
92
|
return null;
|
|
95
|
-
return (React.createElement(IconButton, { label: fullscreen ? label(labels, "Exit Fullscreen") : label(labels, "Enter Fullscreen"), icon: fullscreen ? ExitFullscreenIcon : EnterFullscreenIcon, onClick: toggleFullscreen }));
|
|
93
|
+
return render.buttonFullscreen ? (React.createElement(React.Fragment, null, render.buttonFullscreen({ fullscreen, toggleFullscreen }))) : (React.createElement(IconButton, { label: fullscreen ? label(labels, "Exit Fullscreen") : label(labels, "Enter Fullscreen"), icon: fullscreen ? ExitFullscreenIcon : EnterFullscreenIcon, renderIcon: fullscreen ? render.iconExitFullscreen : render.iconEnterFullscreen, onClick: toggleFullscreen }));
|
|
96
94
|
};
|
|
97
95
|
export const Fullscreen = ({ augment }) => {
|
|
98
96
|
augment(({ toolbar: { buttons, ...restToolbar }, ...restProps }) => ({
|
|
99
97
|
toolbar: {
|
|
100
98
|
buttons: [
|
|
101
|
-
React.createElement(FullscreenButton, { key: "fullscreen", auto: Boolean(restProps.fullscreen), labels: restProps.labels }),
|
|
99
|
+
React.createElement(FullscreenButton, { key: "fullscreen", auto: Boolean(restProps.fullscreen), labels: restProps.labels, render: restProps.render }),
|
|
102
100
|
...buttons,
|
|
103
101
|
],
|
|
104
102
|
...restToolbar,
|
package/dist/plugins/Video.js
CHANGED
|
@@ -35,7 +35,7 @@ export const Video = ({ augment }) => {
|
|
|
35
35
|
if ("type" in slide && slide.type === "video") {
|
|
36
36
|
return React.createElement(VideoSlide, { slide: slide });
|
|
37
37
|
}
|
|
38
|
-
return renderSlide(slide);
|
|
38
|
+
return renderSlide === null || renderSlide === void 0 ? void 0 : renderSlide(slide);
|
|
39
39
|
},
|
|
40
40
|
...restRender,
|
|
41
41
|
},
|
package/dist/types.d.ts
CHANGED
|
@@ -24,7 +24,22 @@ export interface Animation {
|
|
|
24
24
|
swipe: number;
|
|
25
25
|
}
|
|
26
26
|
export interface Render {
|
|
27
|
-
slide
|
|
27
|
+
slide?: (slide: Slide) => React.ReactNode;
|
|
28
|
+
iconPrev?: () => React.ReactNode;
|
|
29
|
+
iconNext?: () => React.ReactNode;
|
|
30
|
+
iconClose?: () => React.ReactNode;
|
|
31
|
+
iconLoading?: () => React.ReactNode;
|
|
32
|
+
iconError?: () => React.ReactNode;
|
|
33
|
+
buttonPrev?: () => React.ReactNode;
|
|
34
|
+
buttonNext?: () => React.ReactNode;
|
|
35
|
+
buttonClose?: () => React.ReactNode;
|
|
36
|
+
}
|
|
37
|
+
export interface Callbacks {
|
|
38
|
+
view?: (index: number) => void;
|
|
39
|
+
entering?: () => void;
|
|
40
|
+
entered?: () => void;
|
|
41
|
+
exiting?: () => void;
|
|
42
|
+
exited?: () => void;
|
|
28
43
|
}
|
|
29
44
|
export interface LightboxProps {
|
|
30
45
|
open: boolean;
|
|
@@ -37,6 +52,7 @@ export interface LightboxProps {
|
|
|
37
52
|
toolbar: Toolbar;
|
|
38
53
|
carousel: Carousel;
|
|
39
54
|
animation: Animation;
|
|
55
|
+
on: Callbacks;
|
|
40
56
|
}
|
|
41
57
|
export declare const SlideTypesPropTypes: PropTypes.Validator<any>[];
|
|
42
58
|
export declare const LightboxPropTypes: {
|
|
@@ -44,9 +60,7 @@ export declare const LightboxPropTypes: {
|
|
|
44
60
|
close: PropTypes.Validator<(...args: any[]) => any>;
|
|
45
61
|
index: PropTypes.Validator<number>;
|
|
46
62
|
slides: PropTypes.Validator<any[]>;
|
|
47
|
-
render: PropTypes.Validator<PropTypes.InferProps<{
|
|
48
|
-
slide: PropTypes.Validator<(...args: any[]) => any>;
|
|
49
|
-
}>>;
|
|
63
|
+
render: PropTypes.Validator<PropTypes.InferProps<{}>>;
|
|
50
64
|
plugins: PropTypes.Validator<((...args: any[]) => any)[]>;
|
|
51
65
|
toolbar: PropTypes.Validator<PropTypes.InferProps<{
|
|
52
66
|
buttons: PropTypes.Validator<(string | number | boolean | PropTypes.ReactElementLike | PropTypes.ReactNodeArray | null | undefined)[]>;
|
|
@@ -62,6 +76,7 @@ export declare const LightboxPropTypes: {
|
|
|
62
76
|
fade: PropTypes.Validator<number>;
|
|
63
77
|
swipe: PropTypes.Validator<number>;
|
|
64
78
|
}>>;
|
|
79
|
+
on: PropTypes.Validator<PropTypes.InferProps<{}>>;
|
|
65
80
|
};
|
|
66
81
|
export declare const LightboxDefaultProps: {
|
|
67
82
|
open: boolean;
|
|
@@ -71,9 +86,10 @@ export declare const LightboxDefaultProps: {
|
|
|
71
86
|
render: Render;
|
|
72
87
|
plugins: Plugin[];
|
|
73
88
|
toolbar: Toolbar;
|
|
74
|
-
labels:
|
|
89
|
+
labels: Labels;
|
|
75
90
|
animation: Animation;
|
|
76
91
|
carousel: Carousel;
|
|
92
|
+
on: Callbacks;
|
|
77
93
|
};
|
|
78
94
|
export declare type Labels = {
|
|
79
95
|
[key: string]: string;
|
package/dist/types.js
CHANGED
|
@@ -18,9 +18,7 @@ export const LightboxPropTypes = {
|
|
|
18
18
|
close: PropTypes.func.isRequired,
|
|
19
19
|
index: PropTypes.number.isRequired,
|
|
20
20
|
slides: PropTypes.arrayOf(PropTypes.oneOfType(SlideTypesPropTypes).isRequired).isRequired,
|
|
21
|
-
render: PropTypes.shape({
|
|
22
|
-
slide: PropTypes.func.isRequired,
|
|
23
|
-
}).isRequired,
|
|
21
|
+
render: PropTypes.shape({}).isRequired,
|
|
24
22
|
plugins: PropTypes.arrayOf(PropTypes.func.isRequired).isRequired,
|
|
25
23
|
toolbar: PropTypes.shape({
|
|
26
24
|
buttons: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.oneOf(["close"]), PropTypes.node])).isRequired,
|
|
@@ -36,15 +34,14 @@ export const LightboxPropTypes = {
|
|
|
36
34
|
fade: PropTypes.number.isRequired,
|
|
37
35
|
swipe: PropTypes.number.isRequired,
|
|
38
36
|
}).isRequired,
|
|
37
|
+
on: PropTypes.shape({}).isRequired,
|
|
39
38
|
};
|
|
40
39
|
export const LightboxDefaultProps = {
|
|
41
40
|
open: false,
|
|
42
41
|
close: () => { },
|
|
43
42
|
index: 0,
|
|
44
43
|
slides: [],
|
|
45
|
-
render: {
|
|
46
|
-
slide: () => null,
|
|
47
|
-
},
|
|
44
|
+
render: {},
|
|
48
45
|
plugins: [],
|
|
49
46
|
toolbar: { buttons: ["close"] },
|
|
50
47
|
labels: {},
|
|
@@ -58,4 +55,5 @@ export const LightboxDefaultProps = {
|
|
|
58
55
|
padding: "16px",
|
|
59
56
|
spacing: "30%",
|
|
60
57
|
},
|
|
58
|
+
on: {},
|
|
61
59
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yet-another-react-lightbox",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Modern lightbox component for React",
|
|
5
5
|
"author": "Igor Danchenko",
|
|
6
6
|
"license": "MIT",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"prop-types": "^15.8.1"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"react": ">=16.
|
|
60
|
-
"react-dom": ">=16.
|
|
59
|
+
"react": ">=16.8.0",
|
|
60
|
+
"react-dom": ">=16.8.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@commitlint/cli": "^17.0.0",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"eslint-plugin-import": "^2.26.0",
|
|
81
81
|
"eslint-plugin-jsx-a11y": "^6.5.1",
|
|
82
82
|
"eslint-plugin-prettier": "^4.0.0",
|
|
83
|
-
"eslint-plugin-react": "^7.
|
|
83
|
+
"eslint-plugin-react": "^7.30.0",
|
|
84
84
|
"eslint-plugin-react-hooks": "^4.5.0",
|
|
85
85
|
"husky": "^8.0.1",
|
|
86
86
|
"jest": "^28.1.0",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"react": "^18.1.0",
|
|
94
94
|
"react-dom": "^18.1.0",
|
|
95
95
|
"rimraf": "^3.0.2",
|
|
96
|
-
"sass": "^1.
|
|
96
|
+
"sass": "^1.52.0",
|
|
97
97
|
"ts-jest": "^28.0.2",
|
|
98
98
|
"typescript": "^4.6.4"
|
|
99
99
|
},
|