yet-another-react-lightbox 3.23.4 → 3.24.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/index.d.ts +20 -4
- package/dist/index.js +52 -17
- package/dist/plugins/captions/index.d.ts +4 -0
- package/dist/plugins/captions/index.js +4 -4
- package/dist/plugins/counter/index.js +1 -1
- package/dist/plugins/download/index.d.ts +1 -0
- package/dist/plugins/fullscreen/index.d.ts +2 -0
- package/dist/plugins/share/index.d.ts +1 -0
- package/dist/plugins/slideshow/index.d.ts +2 -0
- package/dist/plugins/slideshow/index.js +3 -1
- package/dist/plugins/thumbnails/index.d.ts +4 -0
- package/dist/plugins/thumbnails/index.js +9 -7
- package/dist/plugins/zoom/index.d.ts +2 -0
- package/dist/types.d.ts +21 -2
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,10 @@ declare function cssClass(name: string): string;
|
|
|
12
12
|
declare function cssVar(name: string): string;
|
|
13
13
|
declare function composePrefix(base: string, prefix?: string): string;
|
|
14
14
|
declare function makeComposePrefix(base: string): (prefix?: string) => string;
|
|
15
|
+
declare function translateLabel(labels: Labels | undefined, defaultLabel: Label): string;
|
|
16
|
+
/** @deprecated - use `translateLabel` instead */
|
|
15
17
|
declare function label(labels: Labels | undefined, defaultLabel: Label): string;
|
|
18
|
+
declare function translateSlideCounter(labels: Labels | undefined, slides: Slide[], index: number): string;
|
|
16
19
|
declare function cleanup(...cleaners: (() => void)[]): () => void;
|
|
17
20
|
declare function makeUseContext<T>(name: string, contextName: string, context: React.Context<T | null>): () => NonNullable<T>;
|
|
18
21
|
declare function hasWindow(): boolean;
|
|
@@ -111,6 +114,19 @@ declare function useSensors<T extends Element>(): UseSensors<T>;
|
|
|
111
114
|
|
|
112
115
|
declare function useThrottle(callback: (...args: unknown[]) => void, delay: number): (...args: unknown[]) => void;
|
|
113
116
|
|
|
117
|
+
type A11yContextType = {
|
|
118
|
+
focusWithin: boolean;
|
|
119
|
+
trackFocusWithin: (onFocus?: React.FocusEventHandler, onBlur?: React.FocusEventHandler) => {
|
|
120
|
+
onFocus: React.FocusEventHandler;
|
|
121
|
+
onBlur: React.FocusEventHandler;
|
|
122
|
+
};
|
|
123
|
+
autoPlaying: boolean;
|
|
124
|
+
setAutoPlaying: (value: boolean) => void;
|
|
125
|
+
};
|
|
126
|
+
declare const A11yContext: React.Context<A11yContextType | null>;
|
|
127
|
+
declare const useA11yContext: () => A11yContextType;
|
|
128
|
+
declare function A11yContextProvider({ children }: React.PropsWithChildren): React.JSX.Element;
|
|
129
|
+
|
|
114
130
|
type DocumentContextType = {
|
|
115
131
|
getOwnerDocument: (node?: Node | null) => Document;
|
|
116
132
|
getOwnerWindow: (node?: Node | null) => Window;
|
|
@@ -215,7 +231,7 @@ declare function ImageSlide({ slide: image, offset, render, rect, imageFit, imag
|
|
|
215
231
|
|
|
216
232
|
declare const LightboxRoot: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
217
233
|
|
|
218
|
-
declare function Carousel({ carousel }: ComponentProps): React.JSX.Element;
|
|
234
|
+
declare function Carousel({ carousel, labels }: ComponentProps): React.JSX.Element;
|
|
219
235
|
declare const CarouselModule: Module;
|
|
220
236
|
|
|
221
237
|
declare enum SwipeState {
|
|
@@ -275,7 +291,7 @@ declare function useNavigationState(): {
|
|
|
275
291
|
declare function NoScroll({ noScroll: { disabled }, children }: ComponentProps): React.JSX.Element;
|
|
276
292
|
declare const NoScrollModule: Module;
|
|
277
293
|
|
|
278
|
-
declare function Portal({ children, animation, styles, className, on, portal, close }: ComponentProps): React.ReactPortal | null;
|
|
294
|
+
declare function Portal({ children, animation, styles, className, on, portal, close, labels }: ComponentProps): React.ReactPortal | null;
|
|
279
295
|
declare const PortalModule: Module;
|
|
280
296
|
|
|
281
297
|
declare function Root({ children }: ComponentProps): React.JSX.Element;
|
|
@@ -284,5 +300,5 @@ declare const RootModule: Module;
|
|
|
284
300
|
declare function Toolbar({ toolbar: { buttons }, render: { buttonClose, iconClose }, styles }: ComponentProps): React.JSX.Element;
|
|
285
301
|
declare const ToolbarModule: Module;
|
|
286
302
|
|
|
287
|
-
export { Augmentation, Callback, Carousel, CarouselModule, CarouselSettings, CloseIcon, Component, ComponentProps, ContainerRect, Controller, ControllerContext, ControllerModule, ControllerRef, ControllerSettings, DocumentContext, DocumentContextProvider, ErrorIcon, EventTypes, EventsContext, EventsProvider, IconButton, ImageSlide, Label, Labels, LengthOrPercentage, Lightbox, LightboxDefaultProps, LightboxDispatchContext, LightboxExternalProps, LightboxProps, LightboxPropsContext, LightboxPropsProvider, LightboxRoot, LightboxState, LightboxStateContext, LightboxStateProvider, LightboxStateSwipeAction, LightboxStateUpdateAction, LoadingIcon, Module, Navigation, NavigationButton, NavigationModule, NextIcon, NoScroll, NoScrollModule, Node$1 as Node, Plugin, Portal, PortalModule, PreviousIcon, Render, RenderFunction, Root, RootModule, Slide, SlideImage, SwipeState, TimeoutsContext, TimeoutsProvider, Toolbar, ToolbarModule, ToolbarSettings, addToolbarButton, calculatePreload, cleanup, clsx, composePrefix, computeSlideRect, createIcon, createIconDisabled, createModule, createNode, cssClass, cssVar, Lightbox as default, devicePixelRatio, getSlide, getSlideIfPresent, getSlideIndex, getSlideKey, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeInertWhen, makeUseContext, parseInt, parseLengthPercentage, reflow, round, setRef, stopNavigationEventsPropagation, useAnimation, useContainerRect, useController, useDelay, useDocumentContext, useEventCallback, useEvents, useForkRef, useKeyboardNavigation, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useNavigationState, usePointerSwipe, usePreventWheelDefaults, useRTL, useSensors, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
|
|
288
|
-
export type { ComputeAnimation, ControllerContextType, DocumentContextProviderProps, DocumentContextType, Event, EventCallback, EventsContextType, IconButtonProps, ImageSlideProps, KeyboardEventType, LightboxDispatchContextType, LightboxPropsContextType, LightboxStateAction, LightboxStateContextType, LightboxStateProviderProps, NavigationButtonProps, PointerEventType, Publish, ReactEventType, RegisterSensors, SensorCallback, Subscribe, SubscribeSensors, SupportedEventType, TimeoutsContextType, Topic, Unsubscribe, UseSensors, WheelEventType };
|
|
303
|
+
export { A11yContext, A11yContextProvider, Augmentation, Callback, Carousel, CarouselModule, CarouselSettings, CloseIcon, Component, ComponentProps, ContainerRect, Controller, ControllerContext, ControllerModule, ControllerRef, ControllerSettings, DocumentContext, DocumentContextProvider, ErrorIcon, EventTypes, EventsContext, EventsProvider, IconButton, ImageSlide, Label, Labels, LengthOrPercentage, Lightbox, LightboxDefaultProps, LightboxDispatchContext, LightboxExternalProps, LightboxProps, LightboxPropsContext, LightboxPropsProvider, LightboxRoot, LightboxState, LightboxStateContext, LightboxStateProvider, LightboxStateSwipeAction, LightboxStateUpdateAction, LoadingIcon, Module, Navigation, NavigationButton, NavigationModule, NextIcon, NoScroll, NoScrollModule, Node$1 as Node, Plugin, Portal, PortalModule, PreviousIcon, Render, RenderFunction, Root, RootModule, Slide, SlideImage, SwipeState, TimeoutsContext, TimeoutsProvider, Toolbar, ToolbarModule, ToolbarSettings, addToolbarButton, calculatePreload, cleanup, clsx, composePrefix, computeSlideRect, createIcon, createIconDisabled, createModule, createNode, cssClass, cssVar, Lightbox as default, devicePixelRatio, getSlide, getSlideIfPresent, getSlideIndex, getSlideKey, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeInertWhen, makeUseContext, parseInt, parseLengthPercentage, reflow, round, setRef, stopNavigationEventsPropagation, translateLabel, translateSlideCounter, useA11yContext, useAnimation, useContainerRect, useController, useDelay, useDocumentContext, useEventCallback, useEvents, useForkRef, useKeyboardNavigation, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useNavigationState, usePointerSwipe, usePreventWheelDefaults, useRTL, useSensors, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
|
|
304
|
+
export type { A11yContextType, ComputeAnimation, ControllerContextType, DocumentContextProviderProps, DocumentContextType, Event, EventCallback, EventsContextType, IconButtonProps, ImageSlideProps, KeyboardEventType, LightboxDispatchContextType, LightboxPropsContextType, LightboxStateAction, LightboxStateContextType, LightboxStateProviderProps, NavigationButtonProps, PointerEventType, Publish, ReactEventType, RegisterSensors, SensorCallback, Subscribe, SubscribeSensors, SupportedEventType, TimeoutsContextType, Topic, Unsubscribe, UseSensors, WheelEventType };
|
package/dist/index.js
CHANGED
|
@@ -20,10 +20,18 @@ function composePrefix(base, prefix) {
|
|
|
20
20
|
function makeComposePrefix(base) {
|
|
21
21
|
return (prefix) => composePrefix(base, prefix);
|
|
22
22
|
}
|
|
23
|
-
function
|
|
23
|
+
function translateLabel(labels, defaultLabel) {
|
|
24
24
|
var _a;
|
|
25
25
|
return (_a = labels === null || labels === void 0 ? void 0 : labels[defaultLabel]) !== null && _a !== void 0 ? _a : defaultLabel;
|
|
26
26
|
}
|
|
27
|
+
function label(labels, defaultLabel) {
|
|
28
|
+
return translateLabel(labels, defaultLabel);
|
|
29
|
+
}
|
|
30
|
+
function translateSlideCounter(labels, slides, index) {
|
|
31
|
+
return translateLabel(labels, "{index} of {total}")
|
|
32
|
+
.replace(/\{index}/g, `${getSlideIndex(index, slides.length) + 1}`)
|
|
33
|
+
.replace(/\{total}/g, `${slides.length}`);
|
|
34
|
+
}
|
|
27
35
|
function cleanup(...cleaners) {
|
|
28
36
|
return () => {
|
|
29
37
|
cleaners.forEach((cleaner) => {
|
|
@@ -263,6 +271,30 @@ function withPlugins(root, plugins = [], augmentations = []) {
|
|
|
263
271
|
};
|
|
264
272
|
}
|
|
265
273
|
|
|
274
|
+
const A11yContext = React.createContext(null);
|
|
275
|
+
const useA11yContext = makeUseContext("useA11yContext", "A11yContext", A11yContext);
|
|
276
|
+
function A11yContextProvider({ children }) {
|
|
277
|
+
const [focusWithin, setFocusWithin] = React.useState(false);
|
|
278
|
+
const [autoPlaying, setAutoPlaying] = React.useState(false);
|
|
279
|
+
const context = React.useMemo(() => {
|
|
280
|
+
const trackFocusWithin = (onFocus, onBlur) => {
|
|
281
|
+
const trackAndDelegate = (focusWithinValue) => (event) => {
|
|
282
|
+
var _a;
|
|
283
|
+
if (!event.currentTarget.contains(event.relatedTarget)) {
|
|
284
|
+
setFocusWithin(focusWithinValue);
|
|
285
|
+
}
|
|
286
|
+
(_a = (focusWithinValue ? onFocus : onBlur)) === null || _a === void 0 ? void 0 : _a(event);
|
|
287
|
+
};
|
|
288
|
+
return {
|
|
289
|
+
onFocus: trackAndDelegate(true),
|
|
290
|
+
onBlur: trackAndDelegate(false),
|
|
291
|
+
};
|
|
292
|
+
};
|
|
293
|
+
return { focusWithin, trackFocusWithin, autoPlaying, setAutoPlaying };
|
|
294
|
+
}, [focusWithin, autoPlaying]);
|
|
295
|
+
return React.createElement(A11yContext.Provider, { value: context }, children);
|
|
296
|
+
}
|
|
297
|
+
|
|
266
298
|
const DocumentContext = React.createContext(null);
|
|
267
299
|
const useDocumentContext = makeUseContext("useDocument", "DocumentContext", DocumentContext);
|
|
268
300
|
function DocumentContextProvider({ nodeRef, children }) {
|
|
@@ -389,9 +421,9 @@ function TimeoutsProvider({ children }) {
|
|
|
389
421
|
return React.createElement(TimeoutsContext.Provider, { value: context }, children);
|
|
390
422
|
}
|
|
391
423
|
|
|
392
|
-
const IconButton = React.forwardRef(function IconButton({ label
|
|
424
|
+
const IconButton = React.forwardRef(function IconButton({ label, className, icon: Icon, renderIcon, onClick, style, ...rest }, ref) {
|
|
393
425
|
const { styles, labels } = useLightboxProps();
|
|
394
|
-
const buttonLabel =
|
|
426
|
+
const buttonLabel = translateLabel(labels, label);
|
|
395
427
|
return (React.createElement("button", { ref: ref, type: "button", title: buttonLabel, "aria-label": buttonLabel, 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 })));
|
|
396
428
|
});
|
|
397
429
|
|
|
@@ -634,7 +666,7 @@ function useThrottle(callback, delay) {
|
|
|
634
666
|
const slidePrefix = makeComposePrefix("slide");
|
|
635
667
|
const slideImagePrefix = makeComposePrefix("slide_image");
|
|
636
668
|
function ImageSlide({ slide: image, offset, render, rect, imageFit, imageProps, onClick, onLoad, onError, style, }) {
|
|
637
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
669
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
638
670
|
const [status, setStatus] = React.useState(SLIDE_STATUS_LOADING);
|
|
639
671
|
const { publish } = useEvents();
|
|
640
672
|
const { setTimeout } = useTimeouts();
|
|
@@ -688,7 +720,7 @@ function ImageSlide({ slide: image, offset, render, rect, imageFit, imageProps,
|
|
|
688
720
|
const sizes = srcSet && rect && hasWindow() ? `${Math.round(Math.min(estimateActualWidth(), rect.width))}px` : undefined;
|
|
689
721
|
const { style: imagePropsStyle, className: imagePropsClassName, ...restImageProps } = imageProps || {};
|
|
690
722
|
return (React.createElement(React.Fragment, null,
|
|
691
|
-
React.createElement("img", { ref: setImageRef, onLoad: handleOnLoad, onError: handleOnError, onClick: onClick, draggable: false, className: clsx(cssClass(slideImagePrefix()), cover && cssClass(slideImagePrefix("cover")), status !== SLIDE_STATUS_COMPLETE && cssClass(slideImagePrefix("loading")), imagePropsClassName), style: { ...defaultStyle, ...style, ...imagePropsStyle }, ...restImageProps, alt: image.alt, sizes: sizes, srcSet: srcSet, src: image.src }),
|
|
723
|
+
React.createElement("img", { ref: setImageRef, onLoad: handleOnLoad, onError: handleOnError, onClick: onClick, draggable: false, className: clsx(cssClass(slideImagePrefix()), cover && cssClass(slideImagePrefix("cover")), status !== SLIDE_STATUS_COMPLETE && cssClass(slideImagePrefix("loading")), imagePropsClassName), style: { ...defaultStyle, ...style, ...imagePropsStyle }, ...restImageProps, alt: (_h = image.alt) !== null && _h !== void 0 ? _h : "", sizes: sizes, srcSet: srcSet, src: image.src }),
|
|
692
724
|
status !== SLIDE_STATUS_COMPLETE && (React.createElement("div", { className: cssClass(slidePrefix(SLIDE_STATUS_PLACEHOLDER)) },
|
|
693
725
|
status === SLIDE_STATUS_LOADING &&
|
|
694
726
|
((render === null || render === void 0 ? void 0 : render.iconLoading) ? (render.iconLoading()) : (React.createElement(LoadingIcon, { className: clsx(cssClass(ELEMENT_ICON), cssClass(slidePrefix(SLIDE_STATUS_LOADING))) }))),
|
|
@@ -696,10 +728,11 @@ function ImageSlide({ slide: image, offset, render, rect, imageFit, imageProps,
|
|
|
696
728
|
((render === null || render === void 0 ? void 0 : render.iconError) ? (render.iconError()) : (React.createElement(ErrorIcon, { className: clsx(cssClass(ELEMENT_ICON), cssClass(slidePrefix(SLIDE_STATUS_ERROR))) })))))));
|
|
697
729
|
}
|
|
698
730
|
|
|
699
|
-
const LightboxRoot = React.forwardRef(function LightboxRoot({ className, children, ...rest }, ref) {
|
|
731
|
+
const LightboxRoot = React.forwardRef(function LightboxRoot({ className, children, onFocus, onBlur, ...rest }, ref) {
|
|
700
732
|
const nodeRef = React.useRef(null);
|
|
733
|
+
const { trackFocusWithin } = useA11yContext();
|
|
701
734
|
return (React.createElement(DocumentContextProvider, { nodeRef: nodeRef },
|
|
702
|
-
React.createElement("div", { ref: useForkRef(ref, nodeRef), className: clsx(cssClass("root"), className), ...rest }, children)));
|
|
735
|
+
React.createElement("div", { ref: useForkRef(ref, nodeRef), className: clsx(cssClass("root"), className), ...trackFocusWithin(onFocus, onBlur), ...rest }, children)));
|
|
703
736
|
});
|
|
704
737
|
|
|
705
738
|
var SwipeState;
|
|
@@ -1224,7 +1257,7 @@ function Controller({ children, ...props }) {
|
|
|
1224
1257
|
: null),
|
|
1225
1258
|
...(controller.touchAction !== "none" ? { [cssVar("controller_touch_action")]: controller.touchAction } : null),
|
|
1226
1259
|
...styles.container,
|
|
1227
|
-
},
|
|
1260
|
+
}, tabIndex: -1, ...registerSensors }, containerRect && (React.createElement(ControllerContext.Provider, { value: context },
|
|
1228
1261
|
children, (_a = render.controls) === null || _a === void 0 ? void 0 :
|
|
1229
1262
|
_a.call(render)))));
|
|
1230
1263
|
}
|
|
@@ -1238,9 +1271,9 @@ function cssSlidePrefix(value) {
|
|
|
1238
1271
|
}
|
|
1239
1272
|
function CarouselSlide({ slide, offset }) {
|
|
1240
1273
|
const containerRef = React.useRef(null);
|
|
1241
|
-
const { currentIndex } = useLightboxState();
|
|
1274
|
+
const { currentIndex, slides } = useLightboxState();
|
|
1242
1275
|
const { slideRect, focus } = useController();
|
|
1243
|
-
const { render, carousel: { imageFit, imageProps }, on: { click: onClick }, styles: { slide: style }, } = useLightboxProps();
|
|
1276
|
+
const { render, carousel: { imageFit, imageProps }, on: { click: onClick }, styles: { slide: style }, labels, } = useLightboxProps();
|
|
1244
1277
|
const { getOwnerDocument } = useDocumentContext();
|
|
1245
1278
|
const offscreen = offset !== 0;
|
|
1246
1279
|
React.useEffect(() => {
|
|
@@ -1260,15 +1293,16 @@ function CarouselSlide({ slide, offset }) {
|
|
|
1260
1293
|
((_c = render.slideContainer) !== null && _c !== void 0 ? _c : (({ children }) => children))({ slide, children: rendered }), (_d = render.slideFooter) === null || _d === void 0 ? void 0 :
|
|
1261
1294
|
_d.call(render, { slide }))) : null;
|
|
1262
1295
|
};
|
|
1263
|
-
return (React.createElement("div", { ref: containerRef, className: clsx(cssClass(cssSlidePrefix()), !offscreen && cssClass(cssSlidePrefix("current")), cssClass(CLASS_FLEX_CENTER)), ...makeInertWhen(offscreen), style: style, role: "
|
|
1296
|
+
return (React.createElement("div", { ref: containerRef, className: clsx(cssClass(cssSlidePrefix()), !offscreen && cssClass(cssSlidePrefix("current")), cssClass(CLASS_FLEX_CENTER)), ...makeInertWhen(offscreen), style: style, role: "group", "aria-roledescription": translateLabel(labels, "Slide"), "aria-label": translateSlideCounter(labels, slides, currentIndex + offset) }, renderSlide()));
|
|
1264
1297
|
}
|
|
1265
1298
|
function Placeholder() {
|
|
1266
1299
|
const style = useLightboxProps().styles.slide;
|
|
1267
1300
|
return React.createElement("div", { className: cssClass(CLASS_SLIDE), style: style });
|
|
1268
1301
|
}
|
|
1269
|
-
function Carousel({ carousel }) {
|
|
1302
|
+
function Carousel({ carousel, labels }) {
|
|
1270
1303
|
const { slides, currentIndex, globalIndex } = useLightboxState();
|
|
1271
1304
|
const { setCarouselRef } = useController();
|
|
1305
|
+
const { autoPlaying, focusWithin } = useA11yContext();
|
|
1272
1306
|
const spacingValue = parseLengthPercentage(carousel.spacing);
|
|
1273
1307
|
const paddingValue = parseLengthPercentage(carousel.padding);
|
|
1274
1308
|
const preload = calculatePreload(carousel, slides, 1);
|
|
@@ -1293,7 +1327,7 @@ function Carousel({ carousel }) {
|
|
|
1293
1327
|
[`${cssVar(cssPrefix$2("spacing_percent"))}`]: spacingValue.percent || 0,
|
|
1294
1328
|
[`${cssVar(cssPrefix$2("padding_px"))}`]: paddingValue.pixel || 0,
|
|
1295
1329
|
[`${cssVar(cssPrefix$2("padding_percent"))}`]: paddingValue.percent || 0,
|
|
1296
|
-
} }, items.map(({ key, slide, offset }) => slide ? React.createElement(CarouselSlide, { key: key, slide: slide, offset: offset }) : React.createElement(Placeholder, { key: key }))));
|
|
1330
|
+
}, role: "region", "aria-live": autoPlaying && !focusWithin ? "off" : "polite", "aria-roledescription": translateLabel(labels, "Carousel"), "aria-label": translateLabel(labels, "Photo gallery") }, items.map(({ key, slide, offset }) => slide ? React.createElement(CarouselSlide, { key: key, slide: slide, offset: offset }) : React.createElement(Placeholder, { key: key }))));
|
|
1297
1331
|
}
|
|
1298
1332
|
const CarouselModule = createModule(MODULE_CAROUSEL, Carousel);
|
|
1299
1333
|
|
|
@@ -1413,7 +1447,7 @@ function setAttribute(element, attribute, value) {
|
|
|
1413
1447
|
}
|
|
1414
1448
|
};
|
|
1415
1449
|
}
|
|
1416
|
-
function Portal({ children, animation, styles, className, on, portal, close }) {
|
|
1450
|
+
function Portal({ children, animation, styles, className, on, portal, close, labels }) {
|
|
1417
1451
|
const [mounted, setMounted] = React.useState(false);
|
|
1418
1452
|
const [visible, setVisible] = React.useState(false);
|
|
1419
1453
|
const cleanup = React.useRef([]);
|
|
@@ -1476,7 +1510,7 @@ function Portal({ children, animation, styles, className, on, portal, close }) {
|
|
|
1476
1510
|
}
|
|
1477
1511
|
}, [handleEnter, handleCleanup]);
|
|
1478
1512
|
return mounted
|
|
1479
|
-
? createPortal(React.createElement(LightboxRoot, { ref: handleRef, className: clsx(className, cssClass(cssPrefix$1()), cssClass(CLASS_NO_SCROLL_PADDING), visible && cssClass(cssPrefix$1("open"))), "aria-modal": true, role: "dialog", "aria-
|
|
1513
|
+
? createPortal(React.createElement(LightboxRoot, { ref: handleRef, className: clsx(className, cssClass(cssPrefix$1()), cssClass(CLASS_NO_SCROLL_PADDING), visible && cssClass(cssPrefix$1("open"))), "aria-modal": true, role: "dialog", "aria-label": translateLabel(labels, "Lightbox"), style: {
|
|
1480
1514
|
...(animation.fade !== LightboxDefaultProps.animation.fade
|
|
1481
1515
|
? { [cssVar("fade_animation_duration")]: `${animationDuration}ms` }
|
|
1482
1516
|
: null),
|
|
@@ -1558,7 +1592,8 @@ function Lightbox({ carousel, animation, render, toolbar, controller, noScroll,
|
|
|
1558
1592
|
return (React.createElement(LightboxPropsProvider, { ...props },
|
|
1559
1593
|
React.createElement(LightboxStateProvider, { slides: slides || defaultSlides, index: parseInt(index || defaultIndex) },
|
|
1560
1594
|
React.createElement(TimeoutsProvider, null,
|
|
1561
|
-
React.createElement(EventsProvider, null,
|
|
1595
|
+
React.createElement(EventsProvider, null,
|
|
1596
|
+
React.createElement(A11yContextProvider, null, renderNode(createNode(RootModule, config), props)))))));
|
|
1562
1597
|
}
|
|
1563
1598
|
|
|
1564
|
-
export { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, CLASS_FLEX_CENTER, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, CLASS_SLIDE, CLASS_SLIDE_WRAPPER, Carousel, CarouselModule, CloseIcon, Controller, ControllerContext, ControllerModule, DocumentContext, DocumentContextProvider, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_KEY_DOWN, EVENT_ON_KEY_UP, EVENT_ON_POINTER_CANCEL, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_WHEEL, ErrorIcon, EventsContext, EventsProvider, IMAGE_FIT_CONTAIN, IMAGE_FIT_COVER, IconButton, ImageSlide, Lightbox, LightboxDefaultProps, LightboxDispatchContext, LightboxPropsContext, LightboxPropsProvider, LightboxRoot, LightboxStateContext, LightboxStateProvider, LoadingIcon, MODULE_CAROUSEL, MODULE_CONTROLLER, MODULE_NAVIGATION, MODULE_NO_SCROLL, MODULE_PORTAL, MODULE_ROOT, MODULE_TOOLBAR, Navigation, NavigationButton, NavigationModule, NextIcon, NoScroll, NoScrollModule, Portal, PortalModule, PreviousIcon, Root, RootModule, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_LOADING, SLIDE_STATUS_PLACEHOLDER, SwipeState, TimeoutsContext, TimeoutsProvider, Toolbar, ToolbarModule, UNKNOWN_ACTION_TYPE, VK_ARROW_LEFT, VK_ARROW_RIGHT, VK_ESCAPE, activeSlideStatus, addToolbarButton, calculatePreload, cleanup, clsx, composePrefix, computeSlideRect, createIcon, createIconDisabled, createModule, createNode, cssClass, cssVar, Lightbox as default, devicePixelRatio, getSlide, getSlideIfPresent, getSlideIndex, getSlideKey, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeInertWhen, makeUseContext, parseInt, parseLengthPercentage, reflow, round, setRef, stopNavigationEventsPropagation, useAnimation, useContainerRect, useController, useDelay, useDocumentContext, useEventCallback, useEvents, useForkRef, useKeyboardNavigation, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useNavigationState, usePointerEvents, usePointerSwipe, usePreventWheelDefaults, useRTL, useSensors, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
|
|
1599
|
+
export { A11yContext, A11yContextProvider, ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, CLASS_FLEX_CENTER, CLASS_NO_SCROLL, CLASS_NO_SCROLL_PADDING, CLASS_SLIDE, CLASS_SLIDE_WRAPPER, Carousel, CarouselModule, CloseIcon, Controller, ControllerContext, ControllerModule, DocumentContext, DocumentContextProvider, ELEMENT_BUTTON, ELEMENT_ICON, EVENT_ON_KEY_DOWN, EVENT_ON_KEY_UP, EVENT_ON_POINTER_CANCEL, EVENT_ON_POINTER_DOWN, EVENT_ON_POINTER_LEAVE, EVENT_ON_POINTER_MOVE, EVENT_ON_POINTER_UP, EVENT_ON_WHEEL, ErrorIcon, EventsContext, EventsProvider, IMAGE_FIT_CONTAIN, IMAGE_FIT_COVER, IconButton, ImageSlide, Lightbox, LightboxDefaultProps, LightboxDispatchContext, LightboxPropsContext, LightboxPropsProvider, LightboxRoot, LightboxStateContext, LightboxStateProvider, LoadingIcon, MODULE_CAROUSEL, MODULE_CONTROLLER, MODULE_NAVIGATION, MODULE_NO_SCROLL, MODULE_PORTAL, MODULE_ROOT, MODULE_TOOLBAR, Navigation, NavigationButton, NavigationModule, NextIcon, NoScroll, NoScrollModule, Portal, PortalModule, PreviousIcon, Root, RootModule, SLIDE_STATUS_COMPLETE, SLIDE_STATUS_ERROR, SLIDE_STATUS_LOADING, SLIDE_STATUS_PLACEHOLDER, SwipeState, TimeoutsContext, TimeoutsProvider, Toolbar, ToolbarModule, UNKNOWN_ACTION_TYPE, VK_ARROW_LEFT, VK_ARROW_RIGHT, VK_ESCAPE, activeSlideStatus, addToolbarButton, calculatePreload, cleanup, clsx, composePrefix, computeSlideRect, createIcon, createIconDisabled, createModule, createNode, cssClass, cssVar, Lightbox as default, devicePixelRatio, getSlide, getSlideIfPresent, getSlideIndex, getSlideKey, hasSlides, hasWindow, isImageFitCover, isImageSlide, label, makeComposePrefix, makeInertWhen, makeUseContext, parseInt, parseLengthPercentage, reflow, round, setRef, stopNavigationEventsPropagation, translateLabel, translateSlideCounter, useA11yContext, useAnimation, useContainerRect, useController, useDelay, useDocumentContext, useEventCallback, useEvents, useForkRef, useKeyboardNavigation, useLayoutEffect, useLightboxDispatch, useLightboxProps, useLightboxState, useLoseFocus, useMotionPreference, useNavigationState, usePointerEvents, usePointerSwipe, usePreventWheelDefaults, useRTL, useSensors, useThrottle, useTimeouts, useWheelSwipe, withPlugins };
|
|
@@ -48,7 +48,11 @@ declare module "yet-another-react-lightbox" {
|
|
|
48
48
|
buttonCaptions?: RenderFunction<CaptionsRef>;
|
|
49
49
|
}
|
|
50
50
|
interface Labels {
|
|
51
|
+
/** Slide description ARIA role description */
|
|
52
|
+
Caption?: string;
|
|
53
|
+
/** `Show captions` button title */
|
|
51
54
|
"Show captions"?: string;
|
|
55
|
+
/** `Hide captions` button title */
|
|
52
56
|
"Hide captions"?: string;
|
|
53
57
|
}
|
|
54
58
|
/** Captions plugin ref */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { cssClass, useLightboxProps, makeUseContext, useController, clsx, cssVar, createIcon, createIconDisabled, IconButton, addToolbarButton, createModule } from '../../index.js';
|
|
2
|
+
import { cssClass, useLightboxProps, makeUseContext, useController, clsx, cssVar, translateLabel, createIcon, createIconDisabled, IconButton, addToolbarButton, createModule } from '../../index.js';
|
|
3
3
|
import { PLUGIN_CAPTIONS } from '../../types.js';
|
|
4
4
|
|
|
5
5
|
const cssPrefix = (className) => cssClass(`slide_${className}`);
|
|
@@ -39,7 +39,7 @@ function Title({ title }) {
|
|
|
39
39
|
const { visible } = useCaptions();
|
|
40
40
|
if (!visible)
|
|
41
41
|
return null;
|
|
42
|
-
return (React.createElement("div", { style: styles.captionsTitleContainer, className: clsx(cssPrefix("captions_container"), cssPrefix("title_container")) },
|
|
42
|
+
return (React.createElement("div", { role: "heading", "aria-level": 2, style: styles.captionsTitleContainer, className: clsx(cssPrefix("captions_container"), cssPrefix("title_container")) },
|
|
43
43
|
React.createElement("div", { className: cssPrefix("title"), style: {
|
|
44
44
|
...(toolbarWidth ? { [cssVar("toolbar_width")]: `${toolbarWidth}px` } : null),
|
|
45
45
|
...styles.captionsTitle,
|
|
@@ -48,7 +48,7 @@ function Title({ title }) {
|
|
|
48
48
|
|
|
49
49
|
function Description({ description }) {
|
|
50
50
|
const { descriptionTextAlign, descriptionMaxLines } = useCaptionsProps();
|
|
51
|
-
const { styles } = useLightboxProps();
|
|
51
|
+
const { styles, labels } = useLightboxProps();
|
|
52
52
|
const { visible } = useCaptions();
|
|
53
53
|
if (!visible)
|
|
54
54
|
return null;
|
|
@@ -62,7 +62,7 @@ function Description({ description }) {
|
|
|
62
62
|
}
|
|
63
63
|
: null),
|
|
64
64
|
...styles.captionsDescription,
|
|
65
|
-
} }, typeof description === "string"
|
|
65
|
+
}, role: "paragraph", "aria-roledescription": translateLabel(labels, "Caption") }, typeof description === "string"
|
|
66
66
|
? description.split("\n").flatMap((line, index) => [...(index > 0 ? [React.createElement("br", { key: index })] : []), line])
|
|
67
67
|
: description)));
|
|
68
68
|
}
|
|
@@ -16,7 +16,7 @@ function CounterComponent({ counter }) {
|
|
|
16
16
|
const { separator, container: { className, ...rest }, className: legacyClassName, ...legacyRest } = resolveCounterProps(counter);
|
|
17
17
|
if (slides.length === 0)
|
|
18
18
|
return null;
|
|
19
|
-
return (React.createElement("div", { className: clsx(cssClass("counter"), className || legacyClassName), ...legacyRest, ...rest },
|
|
19
|
+
return (React.createElement("div", { className: clsx(cssClass("counter"), className || legacyClassName), ...legacyRest, ...rest, "aria-hidden": true },
|
|
20
20
|
currentIndex + 1,
|
|
21
21
|
" ",
|
|
22
22
|
separator,
|
|
@@ -23,7 +23,9 @@ declare module "yet-another-react-lightbox" {
|
|
|
23
23
|
iconExitFullscreen?: RenderFunction;
|
|
24
24
|
}
|
|
25
25
|
interface Labels {
|
|
26
|
+
/** `Enter Fullscreen` button title */
|
|
26
27
|
"Enter Fullscreen"?: string;
|
|
28
|
+
/** `Exit Fullscreen` button title */
|
|
27
29
|
"Exit Fullscreen"?: string;
|
|
28
30
|
}
|
|
29
31
|
interface Callbacks {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { makeUseContext, useLightboxState, useTimeouts, useEvents, useController, useEventCallback, cleanup, createIcon, useLightboxProps, useLoseFocus, IconButton, addToolbarButton, createModule } from '../../index.js';
|
|
2
|
+
import { makeUseContext, useLightboxState, useTimeouts, useEvents, useController, useA11yContext, useEventCallback, cleanup, createIcon, useLightboxProps, useLoseFocus, IconButton, addToolbarButton, createModule } from '../../index.js';
|
|
3
3
|
import { SLIDE_STATUS_LOADING, SLIDE_STATUS_PLAYING, ACTIVE_SLIDE_LOADING, ACTIVE_SLIDE_PLAYING, ACTIVE_SLIDE_ERROR, SLIDE_STATUS_ERROR, ACTIVE_SLIDE_COMPLETE, SLIDE_STATUS_COMPLETE, PLUGIN_SLIDESHOW } from '../../types.js';
|
|
4
4
|
|
|
5
5
|
const defaultSlideshowProps = {
|
|
@@ -24,6 +24,8 @@ function SlideshowContextProvider({ slideshow, carousel: { finite }, on, childre
|
|
|
24
24
|
const { setTimeout, clearTimeout } = useTimeouts();
|
|
25
25
|
const { subscribe } = useEvents();
|
|
26
26
|
const { next } = useController();
|
|
27
|
+
const { setAutoPlaying } = useA11yContext();
|
|
28
|
+
React.useEffect(() => setAutoPlaying(playing), [playing, setAutoPlaying]);
|
|
27
29
|
const disabled = slides.length === 0 || (finite && currentIndex === slides.length - 1);
|
|
28
30
|
const play = React.useCallback(() => {
|
|
29
31
|
if (!playing && !disabled) {
|
|
@@ -53,7 +53,11 @@ declare module "yet-another-react-lightbox" {
|
|
|
53
53
|
buttonThumbnails?: RenderFunction<ThumbnailsRef>;
|
|
54
54
|
}
|
|
55
55
|
interface Labels {
|
|
56
|
+
/** Thumbnails ARIA label */
|
|
57
|
+
Thumbnails?: string;
|
|
58
|
+
/** `Show thumbnails` button title */
|
|
56
59
|
"Show thumbnails"?: string;
|
|
60
|
+
/** `Hide thumbnails` button title */
|
|
57
61
|
"Hide thumbnails"?: string;
|
|
58
62
|
}
|
|
59
63
|
/** `render.thumbnail` render function props */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useLightboxProps, composePrefix, createIcon, ImageSlide, isImageSlide, cssClass, makeComposePrefix, useDocumentContext, useEventCallback, cssVar, clsx, getSlideKey, useRTL, useEvents,
|
|
2
|
+
import { useLightboxProps, composePrefix, createIcon, ImageSlide, isImageSlide, cssClass, makeComposePrefix, useLightboxState, useDocumentContext, useEventCallback, translateSlideCounter, cssVar, clsx, getSlideKey, useRTL, useEvents, useSensors, useKeyboardNavigation, useAnimation, cleanup, calculatePreload, hasSlides, getSlide, translateLabel, makeUseContext, LightboxPropsProvider, createIconDisabled, IconButton, addToolbarButton, createModule } from '../../index.js';
|
|
3
3
|
import { PLUGIN_THUMBNAILS, ELEMENT_ICON, CLASS_FLEX_CENTER, ACTION_SWIPE, ACTION_NEXT, ACTION_PREV, PLUGIN_FULLSCREEN, MODULE_CONTROLLER } from '../../types.js';
|
|
4
4
|
|
|
5
5
|
const defaultThumbnailsProps = {
|
|
@@ -57,12 +57,14 @@ const fadeOutPrefix = makeComposePrefix("fadeout");
|
|
|
57
57
|
const placeholderPrefix = makeComposePrefix("placeholder");
|
|
58
58
|
const DELAY = "delay";
|
|
59
59
|
const DURATION = "duration";
|
|
60
|
-
function Thumbnail({ slide,
|
|
60
|
+
function Thumbnail({ slide, index, onClick, fadeIn, fadeOut, placeholder, onLoseFocus }) {
|
|
61
61
|
const ref = React.useRef(null);
|
|
62
|
-
const { render, styles } = useLightboxProps();
|
|
62
|
+
const { render, styles, labels } = useLightboxProps();
|
|
63
|
+
const { slides, globalIndex } = useLightboxState();
|
|
63
64
|
const { getOwnerDocument } = useDocumentContext();
|
|
64
65
|
const { width, height, imageFit } = useThumbnailsProps();
|
|
65
66
|
const rect = { width, height };
|
|
67
|
+
const active = index === globalIndex;
|
|
66
68
|
const onLoseFocusCallback = useEventCallback(onLoseFocus);
|
|
67
69
|
React.useEffect(() => {
|
|
68
70
|
if (fadeOut && getOwnerDocument().activeElement === ref.current) {
|
|
@@ -83,7 +85,7 @@ function Thumbnail({ slide, onClick, active, fadeIn, fadeOut, placeholder, onLos
|
|
|
83
85
|
}
|
|
84
86
|
: null),
|
|
85
87
|
...styles.thumbnail,
|
|
86
|
-
}, onClick: onClick }, slide && renderThumbnail({ slide, render, rect, imageFit })));
|
|
88
|
+
}, onClick: onClick, "aria-current": active ? true : undefined, "aria-label": translateSlideCounter(labels, slides, index) }, slide && renderThumbnail({ slide, render, rect, imageFit })));
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
function isHorizontal(position) {
|
|
@@ -103,7 +105,7 @@ function ThumbnailsTrack({ visible, containerRef }) {
|
|
|
103
105
|
const track = React.useRef(null);
|
|
104
106
|
const isRTL = useRTL();
|
|
105
107
|
const { publish, subscribe } = useEvents();
|
|
106
|
-
const { carousel, styles } = useLightboxProps();
|
|
108
|
+
const { carousel, styles, labels } = useLightboxProps();
|
|
107
109
|
const { slides, globalIndex, animation } = useLightboxState();
|
|
108
110
|
const { registerSensors, subscribeSensors } = useSensors();
|
|
109
111
|
useKeyboardNavigation(subscribeSensors);
|
|
@@ -180,7 +182,7 @@ function ThumbnailsTrack({ visible, containerRef }) {
|
|
|
180
182
|
...(gap !== defaultThumbnailsProps.gap ? { [cssVar(cssThumbnailPrefix("gap"))]: `${gap}px` } : null),
|
|
181
183
|
...styles.thumbnailsContainer,
|
|
182
184
|
} },
|
|
183
|
-
React.createElement("nav", { ref: track, style: styles.thumbnailsTrack, className: clsx(cssClass(cssPrefix("track")), cssClass(CLASS_FLEX_CENTER)), tabIndex: -1, ...registerSensors }, items.map(({ key, index, slide }) => {
|
|
185
|
+
React.createElement("nav", { ref: track, style: styles.thumbnailsTrack, className: clsx(cssClass(cssPrefix("track")), cssClass(CLASS_FLEX_CENTER)), "aria-label": translateLabel(labels, "Thumbnails"), tabIndex: -1, ...registerSensors }, items.map(({ key, index, slide }) => {
|
|
184
186
|
const fadeAnimationDuration = animationDuration / Math.abs(offset || 1);
|
|
185
187
|
const fadeIn = (offset > 0 && index > globalIndex + preload - offset && index <= globalIndex + preload) ||
|
|
186
188
|
(offset < 0 && index < globalIndex - preload - offset && index >= globalIndex - preload)
|
|
@@ -199,7 +201,7 @@ function ThumbnailsTrack({ visible, containerRef }) {
|
|
|
199
201
|
: -offset - (index - (globalIndex + preload))) * fadeAnimationDuration,
|
|
200
202
|
}
|
|
201
203
|
: undefined;
|
|
202
|
-
return (React.createElement(Thumbnail, { key: key,
|
|
204
|
+
return (React.createElement(Thumbnail, { key: key, index: index, slide: slide, fadeIn: fadeIn, fadeOut: fadeOut, placeholder: !slide, onClick: handleClick(index), onLoseFocus: () => { var _a; return (_a = track.current) === null || _a === void 0 ? void 0 : _a.focus(); } }));
|
|
203
205
|
})),
|
|
204
206
|
vignette && React.createElement("div", { className: cssClass(cssPrefix("vignette")) })));
|
|
205
207
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -229,7 +229,7 @@ interface ControllerSettings {
|
|
|
229
229
|
focus: boolean;
|
|
230
230
|
/** @deprecated for internal use only */
|
|
231
231
|
touchAction: "none" | "pan-y";
|
|
232
|
-
/**
|
|
232
|
+
/** @deprecated for internal use only */
|
|
233
233
|
aria: boolean;
|
|
234
234
|
/** if `true`, close the lightbox on pull-up gesture */
|
|
235
235
|
closeOnPullUp: boolean;
|
|
@@ -378,11 +378,30 @@ interface Callbacks {
|
|
|
378
378
|
/** a callback called when the portal closes */
|
|
379
379
|
exited?: Callback;
|
|
380
380
|
}
|
|
381
|
-
/** Custom UI labels / translations */
|
|
381
|
+
/** Custom UI labels / translations / localization */
|
|
382
382
|
interface Labels {
|
|
383
|
+
/** `Previous` button title */
|
|
383
384
|
Previous?: string;
|
|
385
|
+
/** `Next` button title */
|
|
384
386
|
Next?: string;
|
|
387
|
+
/** `Close` button title */
|
|
385
388
|
Close?: string;
|
|
389
|
+
/** Slide ARIA role description */
|
|
390
|
+
Slide?: string;
|
|
391
|
+
/** Carousel ARIA role description */
|
|
392
|
+
Carousel?: string;
|
|
393
|
+
/** Lightbox ARIA label */
|
|
394
|
+
Lightbox?: string;
|
|
395
|
+
/** Carousel ARIA label */
|
|
396
|
+
"Photo gallery"?: string;
|
|
397
|
+
/**
|
|
398
|
+
* Slide ARIA label
|
|
399
|
+
*
|
|
400
|
+
* The value is a template string supporting the following placeholders:
|
|
401
|
+
* - {index} - current slide index
|
|
402
|
+
* - {total} - total number of slides
|
|
403
|
+
*/
|
|
404
|
+
"{index} of {total}"?: string;
|
|
386
405
|
}
|
|
387
406
|
type Label = keyof Labels;
|
|
388
407
|
/** Toolbar settings */
|