yet-another-react-lightbox 3.11.4 → 3.12.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 +69 -73
- package/dist/index.d.ts +5 -4
- package/dist/index.js +14 -13
- package/dist/plugins/thumbnails/index.js +3 -3
- package/dist/plugins/video/index.js +1 -1
- package/dist/types.d.ts +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,19 +6,19 @@ Modern React lightbox component. Performant, easy to use, customizable and exten
|
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/yet-another-react-lightbox)
|
|
8
8
|
[](https://bundlephobia.com/package/yet-another-react-lightbox)
|
|
9
|
-
[](LICENSE)
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
9
|
+
[](https://github.com/igordanchenko/yet-another-react-lightbox/blob/main/LICENSE)
|
|
10
|
+
|
|
11
|
+
- **Built for React:** works with React 18, 17 and 16.8.0+
|
|
12
|
+
- **UX:** supports keyboard, mouse, touchpad and touchscreen navigation
|
|
13
|
+
- **Preloading:** never displays partially downloaded images
|
|
14
|
+
- **Performance:** preloads limited number of images without compromising performance or UX
|
|
15
|
+
- **Responsive:** responsive images with automatic resolution switching are supported out of the box
|
|
16
|
+
- **Video:** video slides are supported via an optional plugin
|
|
17
|
+
- **Zoom:** image zoom is supported via an optional plugin
|
|
18
|
+
- **Customization:** customize any UI element or add your own custom slides
|
|
19
|
+
- **No bloat:** never bundle rarely used features; add optional features via plugins
|
|
20
|
+
- **TypeScript:** type definitions come built-in in the package
|
|
21
|
+
- **RTL:** compatible with RTL layout
|
|
22
22
|
|
|
23
23
|

|
|
24
24
|
|
|
@@ -50,25 +50,21 @@ import Lightbox from "yet-another-react-lightbox";
|
|
|
50
50
|
import "yet-another-react-lightbox/styles.css";
|
|
51
51
|
|
|
52
52
|
export default function App() {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
]}
|
|
69
|
-
/>
|
|
70
|
-
</>
|
|
71
|
-
);
|
|
53
|
+
const [open, setOpen] = React.useState(false);
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<>
|
|
57
|
+
<button type="button" onClick={() => setOpen(true)}>
|
|
58
|
+
Open Lightbox
|
|
59
|
+
</button>
|
|
60
|
+
|
|
61
|
+
<Lightbox
|
|
62
|
+
open={open}
|
|
63
|
+
close={() => setOpen(false)}
|
|
64
|
+
slides={[{ src: "/image1.jpg" }, { src: "/image2.jpg" }, { src: "/image3.jpg" }]}
|
|
65
|
+
/>
|
|
66
|
+
</>
|
|
67
|
+
);
|
|
72
68
|
}
|
|
73
69
|
```
|
|
74
70
|
|
|
@@ -85,36 +81,36 @@ import Lightbox from "yet-another-react-lightbox";
|
|
|
85
81
|
import "yet-another-react-lightbox/styles.css";
|
|
86
82
|
|
|
87
83
|
export default function App() {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
84
|
+
const [open, setOpen] = React.useState(false);
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<>
|
|
88
|
+
<button type="button" onClick={() => setOpen(true)}>
|
|
89
|
+
Open Lightbox
|
|
90
|
+
</button>
|
|
91
|
+
|
|
92
|
+
<Lightbox
|
|
93
|
+
open={open}
|
|
94
|
+
close={() => setOpen(false)}
|
|
95
|
+
slides={[
|
|
96
|
+
{
|
|
97
|
+
src: "/image1x3840.jpg",
|
|
98
|
+
alt: "image 1",
|
|
99
|
+
width: 3840,
|
|
100
|
+
height: 2560,
|
|
101
|
+
srcSet: [
|
|
102
|
+
{ src: "/image1x320.jpg", width: 320, height: 213 },
|
|
103
|
+
{ src: "/image1x640.jpg", width: 640, height: 427 },
|
|
104
|
+
{ src: "/image1x1200.jpg", width: 1200, height: 800 },
|
|
105
|
+
{ src: "/image1x2048.jpg", width: 2048, height: 1365 },
|
|
106
|
+
{ src: "/image1x3840.jpg", width: 3840, height: 2560 },
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
// ...
|
|
110
|
+
]}
|
|
111
|
+
/>
|
|
112
|
+
</>
|
|
113
|
+
);
|
|
118
114
|
}
|
|
119
115
|
```
|
|
120
116
|
|
|
@@ -127,17 +123,17 @@ Yet Another React Lightbox allows you to add optional features to your project b
|
|
|
127
123
|
|
|
128
124
|
The following plugins are bundled in the package:
|
|
129
125
|
|
|
130
|
-
-
|
|
131
|
-
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
-
|
|
135
|
-
-
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
-
|
|
126
|
+
- [Captions](https://yet-another-react-lightbox.com/plugins/captions) - adds support for slide title and
|
|
127
|
+
description
|
|
128
|
+
- [Counter](https://yet-another-react-lightbox.com/plugins/counter) - adds slides counter
|
|
129
|
+
- [Download](https://yet-another-react-lightbox.com/plugins/download) - adds download button
|
|
130
|
+
- [Fullscreen](https://yet-another-react-lightbox.com/plugins/fullscreen) - adds support for fullscreen mode
|
|
131
|
+
- [Inline](https://yet-another-react-lightbox.com/plugins/inline) - transforms the lightbox into an image carousel
|
|
132
|
+
- [Share](https://yet-another-react-lightbox.com/plugins/share) - adds sharing button
|
|
133
|
+
- [Slideshow](https://yet-another-react-lightbox.com/plugins/slideshow) - adds slideshow button
|
|
134
|
+
- [Thumbnails](https://yet-another-react-lightbox.com/plugins/thumbnails) - adds thumbnails track
|
|
135
|
+
- [Video](https://yet-another-react-lightbox.com/plugins/video) - adds support for video slides
|
|
136
|
+
- [Zoom](https://yet-another-react-lightbox.com/plugins/zoom) - adds image zoom feature
|
|
141
137
|
|
|
142
138
|
## License
|
|
143
139
|
|
package/dist/index.d.ts
CHANGED
|
@@ -194,7 +194,7 @@ type ImageSlideProps = Partial<Pick<CarouselSettings, "imageFit" | "imageProps">
|
|
|
194
194
|
};
|
|
195
195
|
declare function ImageSlide({ slide: image, offset, render, rect, imageFit, imageProps, onClick, onLoad, style, }: ImageSlideProps): React.JSX.Element;
|
|
196
196
|
|
|
197
|
-
declare function Carousel({ carousel
|
|
197
|
+
declare function Carousel({ carousel }: ComponentProps): React.JSX.Element;
|
|
198
198
|
declare const CarouselModule: Module;
|
|
199
199
|
|
|
200
200
|
declare enum SwipeState {
|
|
@@ -234,9 +234,10 @@ type NavigationButtonProps = {
|
|
|
234
234
|
action: "prev" | "next";
|
|
235
235
|
onClick: () => void;
|
|
236
236
|
disabled?: boolean;
|
|
237
|
+
style?: React.CSSProperties;
|
|
237
238
|
};
|
|
238
|
-
declare function NavigationButton({ label, icon, renderIcon, action, onClick, disabled }: NavigationButtonProps): React.JSX.Element;
|
|
239
|
-
declare function Navigation({ carousel: { finite }, animation, render: { buttonPrev, buttonNext, iconPrev, iconNext }, }: ComponentProps): React.JSX.Element;
|
|
239
|
+
declare function NavigationButton({ label, icon, renderIcon, action, onClick, disabled, style }: NavigationButtonProps): React.JSX.Element;
|
|
240
|
+
declare function Navigation({ carousel: { finite }, animation, render: { buttonPrev, buttonNext, iconPrev, iconNext }, styles, }: ComponentProps): React.JSX.Element;
|
|
240
241
|
declare const NavigationModule: Module;
|
|
241
242
|
|
|
242
243
|
declare function NoScroll({ children }: ComponentProps): React.JSX.Element;
|
|
@@ -248,7 +249,7 @@ declare const PortalModule: Module;
|
|
|
248
249
|
declare function Root({ children }: ComponentProps): React.JSX.Element;
|
|
249
250
|
declare const RootModule: Module;
|
|
250
251
|
|
|
251
|
-
declare function Toolbar({ toolbar: { buttons }, render: { buttonClose, iconClose } }: ComponentProps): React.JSX.Element;
|
|
252
|
+
declare function Toolbar({ toolbar: { buttons }, render: { buttonClose, iconClose }, styles }: ComponentProps): React.JSX.Element;
|
|
252
253
|
declare const ToolbarModule: Module;
|
|
253
254
|
|
|
254
255
|
export { Augmentation, Callback, Carousel, CarouselModule, CarouselSettings, CloseIcon, Component, ComponentProps, ComputeAnimation, ContainerRect, Controller, ControllerContext, ControllerContextType, ControllerModule, ControllerRef, ErrorIcon, Event, EventCallback, EventTypes, EventsContext, EventsContextType, EventsProvider, IconButton, IconButtonProps, ImageSlide, ImageSlideProps, KeyboardEventType, Labels, LengthOrPercentage, Lightbox, LightboxDefaultProps, LightboxDispatchContext, LightboxDispatchContextType, LightboxExternalProps, LightboxProps, LightboxPropsContext, LightboxPropsContextType, LightboxPropsProvider, LightboxState, LightboxStateAction, LightboxStateContext, LightboxStateContextType, LightboxStateProvider, LightboxStateProviderProps, LightboxStateSwipeAction, LightboxStateUpdateAction, LoadingIcon, Module, Navigation, NavigationButton, NavigationButtonProps, NavigationModule, NextIcon, NoScroll, NoScrollModule, Node, Plugin, PointerEventType, Portal, PortalModule, PreviousIcon, Publish, ReactEventType, RegisterSensors, Render, RenderFunction, Root, RootModule, SensorCallback, Slide, SlideImage, Subscribe, SubscribeSensors, SupportedEventType, SwipeState, TimeoutsContext, TimeoutsContextType, TimeoutsProvider, Toolbar, ToolbarModule, ToolbarSettings, Topic, Unsubscribe, UseSensors, WheelEventType, addToolbarButton, cleanup, clsx, composePrefix, computeSlideRect, createIcon, createIconDisabled, createModule, createNode, cssClass, cssVar, Lightbox as default, devicePixelRatio, getSlide, getSlideIfPresent, getSlideIndex, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeUseContext, parseLengthPercentage, round, setRef, stopNavigationEventsPropagation, useAnimation, useContainerRect, useController, useDelay, useEventCallback, useEvents, useForkRef, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, usePointerSwipe, usePreventSwipeNavigation, useRTL, useSensors, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
|
package/dist/index.js
CHANGED
|
@@ -1174,21 +1174,22 @@ function Placeholder() {
|
|
|
1174
1174
|
const style = useLightboxProps().styles.slide;
|
|
1175
1175
|
return React.createElement("div", { className: cssClass("slide"), style: style });
|
|
1176
1176
|
}
|
|
1177
|
-
function Carousel({ carousel
|
|
1177
|
+
function Carousel({ carousel }) {
|
|
1178
1178
|
const { slides, currentIndex, globalIndex } = useLightboxState();
|
|
1179
1179
|
const { setCarouselRef } = useController();
|
|
1180
|
-
const spacingValue = parseLengthPercentage(spacing);
|
|
1181
|
-
const paddingValue = parseLengthPercentage(padding);
|
|
1180
|
+
const spacingValue = parseLengthPercentage(carousel.spacing);
|
|
1181
|
+
const paddingValue = parseLengthPercentage(carousel.padding);
|
|
1182
1182
|
const items = [];
|
|
1183
|
-
|
|
1183
|
+
const preload = Math.min(carousel.preload, Math.max(Math.floor(slides.length / 2), 1));
|
|
1184
|
+
if (hasSlides(slides)) {
|
|
1184
1185
|
for (let i = currentIndex - preload; i < currentIndex; i += 1) {
|
|
1185
1186
|
const key = globalIndex + i - currentIndex;
|
|
1186
|
-
items.push(!finite || i >= 0 ? (React.createElement(CarouselSlide, { key: key, slide: slides[(i + preload * slides.length) % slides.length], offset: i - currentIndex })) : (React.createElement(Placeholder, { key: key })));
|
|
1187
|
+
items.push(!carousel.finite || i >= 0 ? (React.createElement(CarouselSlide, { key: key, slide: slides[(i + preload * slides.length) % slides.length], offset: i - currentIndex })) : (React.createElement(Placeholder, { key: key })));
|
|
1187
1188
|
}
|
|
1188
1189
|
items.push(React.createElement(CarouselSlide, { key: globalIndex, slide: slides[currentIndex], offset: 0 }));
|
|
1189
1190
|
for (let i = currentIndex + 1; i <= currentIndex + preload; i += 1) {
|
|
1190
1191
|
const key = globalIndex + i - currentIndex;
|
|
1191
|
-
items.push(!finite || i <= slides.length - 1 ? (React.createElement(CarouselSlide, { key: key, slide: slides[i % slides.length], offset: i - currentIndex })) : (React.createElement(Placeholder, { key: key })));
|
|
1192
|
+
items.push(!carousel.finite || i <= slides.length - 1 ? (React.createElement(CarouselSlide, { key: key, slide: slides[i % slides.length], offset: i - currentIndex })) : (React.createElement(Placeholder, { key: key })));
|
|
1192
1193
|
}
|
|
1193
1194
|
}
|
|
1194
1195
|
return (React.createElement("div", { ref: setCarouselRef, className: clsx(cssClass(cssPrefix$2()), items.length > 0 && cssClass(cssPrefix$2("with_slides"))), style: {
|
|
@@ -1201,10 +1202,10 @@ function Carousel({ carousel: { finite, preload, padding, spacing } }) {
|
|
|
1201
1202
|
}
|
|
1202
1203
|
const CarouselModule = createModule(MODULE_CAROUSEL, Carousel);
|
|
1203
1204
|
|
|
1204
|
-
function NavigationButton({ label, icon, renderIcon, action, onClick, disabled }) {
|
|
1205
|
-
return (React.createElement(IconButton, { label: label, icon: icon, renderIcon: renderIcon, className: cssClass(`navigation_${action}`), disabled: disabled, onClick: onClick, ...useLoseFocus(useController().focus, disabled) }));
|
|
1205
|
+
function NavigationButton({ label, icon, renderIcon, action, onClick, disabled, style }) {
|
|
1206
|
+
return (React.createElement(IconButton, { label: label, icon: icon, renderIcon: renderIcon, className: cssClass(`navigation_${action}`), disabled: disabled, onClick: onClick, style: style, ...useLoseFocus(useController().focus, disabled) }));
|
|
1206
1207
|
}
|
|
1207
|
-
function Navigation({ carousel: { finite }, animation, render: { buttonPrev, buttonNext, iconPrev, iconNext }, }) {
|
|
1208
|
+
function Navigation({ carousel: { finite }, animation, render: { buttonPrev, buttonNext, iconPrev, iconNext }, styles, }) {
|
|
1208
1209
|
var _a;
|
|
1209
1210
|
const { slides, currentIndex } = useLightboxState();
|
|
1210
1211
|
const { prev, next, subscribeSensors } = useController();
|
|
@@ -1224,8 +1225,8 @@ function Navigation({ carousel: { finite }, animation, render: { buttonPrev, but
|
|
|
1224
1225
|
});
|
|
1225
1226
|
React.useEffect(() => subscribeSensors(EVENT_ON_KEY_DOWN, handleKeyDown), [subscribeSensors, handleKeyDown]);
|
|
1226
1227
|
return (React.createElement(React.Fragment, null,
|
|
1227
|
-
buttonPrev ? (buttonPrev()) : (React.createElement(NavigationButton, { label: "Previous", action: ACTION_PREV, icon: PreviousIcon, renderIcon: iconPrev, disabled: prevDisabled, onClick: prev })),
|
|
1228
|
-
buttonNext ? (buttonNext()) : (React.createElement(NavigationButton, { label: "Next", action: ACTION_NEXT, icon: NextIcon, renderIcon: iconNext, disabled: nextDisabled, onClick: next }))));
|
|
1228
|
+
buttonPrev ? (buttonPrev()) : (React.createElement(NavigationButton, { label: "Previous", action: ACTION_PREV, icon: PreviousIcon, renderIcon: iconPrev, style: styles.navigationPrev, disabled: prevDisabled, onClick: prev })),
|
|
1229
|
+
buttonNext ? (buttonNext()) : (React.createElement(NavigationButton, { label: "Next", action: ACTION_NEXT, icon: NextIcon, renderIcon: iconNext, style: styles.navigationNext, disabled: nextDisabled, onClick: next }))));
|
|
1229
1230
|
}
|
|
1230
1231
|
const NavigationModule = createModule(MODULE_NAVIGATION, Navigation);
|
|
1231
1232
|
|
|
@@ -1370,7 +1371,7 @@ const RootModule = createModule(MODULE_ROOT, Root);
|
|
|
1370
1371
|
function cssPrefix(value) {
|
|
1371
1372
|
return composePrefix(MODULE_TOOLBAR, value);
|
|
1372
1373
|
}
|
|
1373
|
-
function Toolbar({ toolbar: { buttons }, render: { buttonClose, iconClose } }) {
|
|
1374
|
+
function Toolbar({ toolbar: { buttons }, render: { buttonClose, iconClose }, styles }) {
|
|
1374
1375
|
const { close, setToolbarWidth } = useController();
|
|
1375
1376
|
const { setContainerRef, containerRect } = useContainerRect();
|
|
1376
1377
|
useLayoutEffect(() => {
|
|
@@ -1381,7 +1382,7 @@ function Toolbar({ toolbar: { buttons }, render: { buttonClose, iconClose } }) {
|
|
|
1381
1382
|
return buttonClose();
|
|
1382
1383
|
return React.createElement(IconButton, { key: ACTION_CLOSE, label: "Close", icon: CloseIcon, renderIcon: iconClose, onClick: close });
|
|
1383
1384
|
};
|
|
1384
|
-
return (React.createElement("div", { ref: setContainerRef, className: cssClass(cssPrefix()), ...stopNavigationEventsPropagation() }, buttons === null || buttons === void 0 ? void 0 : buttons.map((button) => (button === ACTION_CLOSE ? renderCloseButton() : button))));
|
|
1385
|
+
return (React.createElement("div", { ref: setContainerRef, style: styles.toolbar, className: cssClass(cssPrefix()), ...stopNavigationEventsPropagation() }, buttons === null || buttons === void 0 ? void 0 : buttons.map((button) => (button === ACTION_CLOSE ? renderCloseButton() : button))));
|
|
1385
1386
|
}
|
|
1386
1387
|
const ToolbarModule = createModule(MODULE_TOOLBAR, Toolbar);
|
|
1387
1388
|
|
|
@@ -121,7 +121,7 @@ function ThumbnailsTrack({ visible, containerRef }) {
|
|
|
121
121
|
});
|
|
122
122
|
React.useEffect(() => cleanup(subscribe(ACTION_SWIPE, handleControllerSwipe)), [subscribe, handleControllerSwipe]);
|
|
123
123
|
const { finite } = carousel;
|
|
124
|
-
const preload = Math.
|
|
124
|
+
const preload = Math.min(carousel.preload, Math.floor(slides.length / 2));
|
|
125
125
|
const items = [];
|
|
126
126
|
if (hasSlides(slides)) {
|
|
127
127
|
if (offset < 0) {
|
|
@@ -129,7 +129,7 @@ function ThumbnailsTrack({ visible, containerRef }) {
|
|
|
129
129
|
items.push({ slide: null, index: i, placeholder: true });
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
for (let i = index - preload - (offset
|
|
132
|
+
for (let i = index - preload - Math.max(offset, 0); i < index; i += 1) {
|
|
133
133
|
if (!(finite && i < 0)) {
|
|
134
134
|
items.push({ slide: getSlide(slides, i), index: i });
|
|
135
135
|
}
|
|
@@ -138,7 +138,7 @@ function ThumbnailsTrack({ visible, containerRef }) {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
items.push({ slide: getSlide(slides, index), index });
|
|
141
|
-
for (let i = index + 1; i <= index + preload - (offset
|
|
141
|
+
for (let i = index + 1; i <= index + preload - Math.min(offset, 0); i += 1) {
|
|
142
142
|
if (!finite || i <= slides.length - 1) {
|
|
143
143
|
items.push({ slide: getSlide(slides, i), index: i });
|
|
144
144
|
}
|
|
@@ -96,7 +96,7 @@ function Video({ augment }) {
|
|
|
96
96
|
slide: ({ slide, offset, rect }) => {
|
|
97
97
|
var _a;
|
|
98
98
|
if (isVideoSlide(slide)) {
|
|
99
|
-
return (React.createElement(VideoSlide, { key:
|
|
99
|
+
return (React.createElement(VideoSlide, { key: (_a = slide.sources) === null || _a === void 0 ? void 0 : _a.map((source) => source.src).join(" "), slide: slide, offset: offset }));
|
|
100
100
|
}
|
|
101
101
|
return renderSlide === null || renderSlide === void 0 ? void 0 : renderSlide({ slide, offset, rect });
|
|
102
102
|
},
|
package/dist/types.d.ts
CHANGED
|
@@ -167,6 +167,12 @@ interface SlotType {
|
|
|
167
167
|
button: "button";
|
|
168
168
|
/** lightbox icon customization slot */
|
|
169
169
|
icon: "icon";
|
|
170
|
+
/** lightbox toolbar customization slot */
|
|
171
|
+
toolbar: "toolbar";
|
|
172
|
+
/** lightbox Prev navigation button customization slot */
|
|
173
|
+
navigationPrev: "navigationPrev";
|
|
174
|
+
/** lightbox Next navigation button customization slot */
|
|
175
|
+
navigationNext: "navigationNext";
|
|
170
176
|
}
|
|
171
177
|
/** Customization slot CSS properties */
|
|
172
178
|
interface SlotCSSProperties extends React.CSSProperties {
|