yet-another-react-lightbox 2.6.2 → 3.0.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.
Files changed (129) hide show
  1. package/dist/Lightbox.d.ts +1 -1
  2. package/dist/Lightbox.js +17 -13
  3. package/dist/core/components/IconButton.js +2 -2
  4. package/dist/core/components/ImageSlide.js +0 -3
  5. package/dist/core/config.d.ts +3 -3
  6. package/dist/core/config.js +18 -13
  7. package/dist/core/consts.d.ts +2 -4
  8. package/dist/core/consts.js +2 -4
  9. package/dist/core/contexts/Events.d.ts +3 -2
  10. package/dist/core/contexts/Events.js +3 -3
  11. package/dist/core/contexts/LightboxProps.d.ts +6 -0
  12. package/dist/core/contexts/LightboxProps.js +7 -0
  13. package/dist/core/contexts/LightboxState.d.ts +15 -15
  14. package/dist/core/contexts/LightboxState.js +33 -20
  15. package/dist/core/contexts/Timeouts.d.ts +1 -0
  16. package/dist/core/contexts/Timeouts.js +3 -3
  17. package/dist/core/contexts/index.d.ts +1 -0
  18. package/dist/core/contexts/index.js +1 -0
  19. package/dist/core/hooks/useAnimation.d.ts +4 -1
  20. package/dist/core/hooks/useAnimation.js +12 -3
  21. package/dist/core/hooks/useLoseFocus.js +3 -3
  22. package/dist/core/modules/Carousel.d.ts +1 -1
  23. package/dist/core/modules/Carousel.js +19 -24
  24. package/dist/core/modules/Controller.d.ts +15 -16
  25. package/dist/core/modules/Controller.js +68 -34
  26. package/dist/core/modules/Navigation.d.ts +4 -5
  27. package/dist/core/modules/Navigation.js +15 -12
  28. package/dist/core/modules/Portal.js +5 -4
  29. package/dist/core/modules/Root.d.ts +4 -0
  30. package/dist/core/modules/Root.js +7 -0
  31. package/dist/core/modules/Toolbar.d.ts +0 -6
  32. package/dist/core/modules/Toolbar.js +6 -8
  33. package/dist/core/modules/index.d.ts +1 -1
  34. package/dist/core/modules/index.js +1 -1
  35. package/dist/core/utils.d.ts +7 -10
  36. package/dist/core/utils.js +14 -14
  37. package/dist/plugins/captions/Captions.d.ts +2 -6
  38. package/dist/plugins/captions/Captions.js +17 -20
  39. package/dist/plugins/captions/Description.d.ts +2 -2
  40. package/dist/plugins/captions/Description.js +5 -3
  41. package/dist/plugins/captions/Title.js +2 -3
  42. package/dist/plugins/captions/captions.css +1 -0
  43. package/dist/plugins/captions/index.d.ts +2 -2
  44. package/dist/plugins/captions/props.d.ts +9 -0
  45. package/dist/plugins/captions/props.js +8 -0
  46. package/dist/plugins/captions/utils.d.ts +1 -1
  47. package/dist/plugins/captions/utils.js +1 -3
  48. package/dist/plugins/fullscreen/Fullscreen.d.ts +2 -2
  49. package/dist/plugins/fullscreen/Fullscreen.js +5 -3
  50. package/dist/plugins/fullscreen/FullscreenButton.js +8 -5
  51. package/dist/plugins/fullscreen/FullscreenContext.d.ts +5 -9
  52. package/dist/plugins/fullscreen/FullscreenContext.js +16 -26
  53. package/dist/plugins/fullscreen/index.d.ts +21 -10
  54. package/dist/plugins/fullscreen/props.d.ts +10 -0
  55. package/dist/plugins/fullscreen/props.js +8 -0
  56. package/dist/plugins/inline/Inline.d.ts +2 -2
  57. package/dist/plugins/inline/Inline.js +4 -7
  58. package/dist/plugins/inline/InlineContainer.d.ts +4 -0
  59. package/dist/plugins/inline/InlineContainer.js +5 -0
  60. package/dist/plugins/inline/index.d.ts +1 -1
  61. package/dist/plugins/slideshow/Slideshow.d.ts +2 -6
  62. package/dist/plugins/slideshow/Slideshow.js +7 -10
  63. package/dist/plugins/slideshow/SlideshowButton.js +7 -5
  64. package/dist/plugins/slideshow/SlideshowContext.d.ts +5 -9
  65. package/dist/plugins/slideshow/SlideshowContext.js +21 -12
  66. package/dist/plugins/slideshow/index.d.ts +16 -11
  67. package/dist/plugins/slideshow/props.d.ts +12 -0
  68. package/dist/plugins/slideshow/props.js +9 -0
  69. package/dist/plugins/thumbnails/Thumbnail.d.ts +3 -7
  70. package/dist/plugins/thumbnails/Thumbnail.js +7 -3
  71. package/dist/plugins/thumbnails/Thumbnails.d.ts +2 -13
  72. package/dist/plugins/thumbnails/Thumbnails.js +6 -19
  73. package/dist/plugins/thumbnails/ThumbnailsContainer.d.ts +1 -1
  74. package/dist/plugins/thumbnails/ThumbnailsContainer.js +10 -10
  75. package/dist/plugins/thumbnails/ThumbnailsTrack.d.ts +4 -6
  76. package/dist/plugins/thumbnails/ThumbnailsTrack.js +16 -14
  77. package/dist/plugins/thumbnails/index.d.ts +5 -5
  78. package/dist/plugins/thumbnails/props.d.ts +34 -0
  79. package/dist/plugins/thumbnails/props.js +20 -0
  80. package/dist/plugins/video/Video.d.ts +2 -6
  81. package/dist/plugins/video/Video.js +11 -11
  82. package/dist/plugins/video/VideoSlide.d.ts +1 -1
  83. package/dist/plugins/video/VideoSlide.js +3 -3
  84. package/dist/plugins/video/index.d.ts +39 -42
  85. package/dist/plugins/video/props.d.ts +29 -0
  86. package/dist/plugins/video/props.js +13 -0
  87. package/dist/plugins/zoom/ResponsiveImage.js +23 -15
  88. package/dist/plugins/zoom/Zoom.d.ts +0 -11
  89. package/dist/plugins/zoom/Zoom.js +11 -33
  90. package/dist/plugins/zoom/ZoomButton.d.ts +6 -5
  91. package/dist/plugins/zoom/ZoomButton.js +11 -33
  92. package/dist/plugins/zoom/ZoomButtonsGroup.d.ts +1 -4
  93. package/dist/plugins/zoom/ZoomButtonsGroup.js +6 -7
  94. package/dist/plugins/zoom/ZoomController.d.ts +12 -0
  95. package/dist/plugins/zoom/ZoomController.js +17 -0
  96. package/dist/plugins/zoom/ZoomToolbarControl.d.ts +2 -0
  97. package/dist/plugins/zoom/ZoomToolbarControl.js +12 -0
  98. package/dist/plugins/zoom/ZoomWrapper.d.ts +5 -0
  99. package/dist/plugins/zoom/ZoomWrapper.js +36 -0
  100. package/dist/plugins/zoom/hooks/index.d.ts +6 -0
  101. package/dist/plugins/zoom/hooks/index.js +6 -0
  102. package/dist/plugins/zoom/hooks/useZoomAnimation.d.ts +2 -0
  103. package/dist/plugins/zoom/hooks/useZoomAnimation.js +39 -0
  104. package/dist/plugins/zoom/hooks/useZoomCallback.d.ts +1 -0
  105. package/dist/plugins/zoom/hooks/useZoomCallback.js +12 -0
  106. package/dist/plugins/zoom/hooks/useZoomImageRect.d.ts +5 -0
  107. package/dist/plugins/zoom/hooks/useZoomImageRect.js +41 -0
  108. package/dist/plugins/zoom/hooks/useZoomProps.d.ts +13 -0
  109. package/dist/plugins/zoom/hooks/useZoomProps.js +6 -0
  110. package/dist/plugins/zoom/hooks/useZoomSensors.d.ts +3 -0
  111. package/dist/plugins/zoom/hooks/useZoomSensors.js +154 -0
  112. package/dist/plugins/zoom/hooks/useZoomState.d.ts +12 -0
  113. package/dist/plugins/zoom/hooks/useZoomState.js +63 -0
  114. package/dist/plugins/zoom/index.d.ts +37 -24
  115. package/dist/plugins/zoom/index.js +0 -2
  116. package/dist/plugins/zoom/props.d.ts +25 -0
  117. package/dist/plugins/zoom/props.js +15 -0
  118. package/dist/props.d.ts +0 -4
  119. package/dist/props.js +10 -5
  120. package/dist/types.d.ts +173 -117
  121. package/package.json +41 -11
  122. package/dist/core/modules/Core.d.ts +0 -4
  123. package/dist/core/modules/Core.js +0 -10
  124. package/dist/plugins/captions/CaptionsContext.d.ts +0 -7
  125. package/dist/plugins/captions/CaptionsContext.js +0 -11
  126. package/dist/plugins/zoom/ZoomContainer.d.ts +0 -9
  127. package/dist/plugins/zoom/ZoomContainer.js +0 -316
  128. package/dist/plugins/zoom/ZoomContext.d.ts +0 -11
  129. package/dist/plugins/zoom/ZoomContext.js +0 -20
@@ -1,15 +1,17 @@
1
1
  import * as React from "react";
2
2
  import { createModule } from "../config.js";
3
- import { cleanup, clsx, cssClass, cssVar, getAnimationEasing, getNavigationAnimationDuration, getSwipeAnimationDuration, isNumber, makeComposePrefix, makeUseContext, parseLengthPercentage, } from "../utils.js";
3
+ import { cleanup, clsx, computeSlideRect, cssClass, cssVar, makeComposePrefix, makeUseContext, parseLengthPercentage, } from "../utils.js";
4
4
  import { useAnimation, useContainerRect, useDelay, useEventCallback, useForkRef, useRTL, useSensors, } from "../hooks/index.js";
5
5
  import { useEvents, useLightboxState } from "../contexts/index.js";
6
6
  import { SwipeState, usePointerSwipe, usePreventSwipeNavigation, useWheelSwipe } from "./controller/index.js";
7
- import { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, CLASS_FLEX_CENTER, EVENT_ON_KEY_UP, MODULE_CONTROLLER, VK_ESCAPE, YARL_EVENT_BACKDROP_CLICK, } from "../consts.js";
7
+ import { ACTION_CLOSE, ACTION_NEXT, ACTION_PREV, ACTION_SWIPE, CLASS_FLEX_CENTER, EVENT_ON_KEY_UP, MODULE_CONTROLLER, VK_ESCAPE, } from "../consts.js";
8
8
  const cssContainerPrefix = makeComposePrefix("container");
9
- const ControllerContext = React.createContext(null);
9
+ export const ControllerContext = React.createContext(null);
10
10
  export const useController = makeUseContext("useController", "ControllerContext", ControllerContext);
11
11
  export function Controller({ children, ...props }) {
12
- const { carousel, slides, animation, controller, on, styles } = props;
12
+ var _a;
13
+ const { carousel, animation, controller, on, styles, render } = props;
14
+ const [toolbarWidth, setToolbarWidth] = React.useState();
13
15
  const { state, dispatch } = useLightboxState();
14
16
  const [swipeState, setSwipeState] = React.useState(SwipeState.NONE);
15
17
  const swipeOffset = React.useRef(0);
@@ -22,21 +24,28 @@ export function Controller({ children, ...props }) {
22
24
  const carouselRef = React.useRef(null);
23
25
  const setCarouselRef = useForkRef(carouselRef, undefined);
24
26
  const isRTL = useRTL();
25
- const rtl = (value) => (isRTL ? -1 : 1) * (isNumber(value) ? value : 1);
27
+ const rtl = (value) => (isRTL ? -1 : 1) * (typeof value === "number" ? value : 1);
28
+ const focus = useEventCallback(() => { var _a; return (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.focus(); });
29
+ const getLightboxProps = useEventCallback(() => props);
30
+ const getLightboxState = useEventCallback(() => state);
31
+ const prev = React.useCallback((params) => publish(ACTION_PREV, params), [publish]);
32
+ const next = React.useCallback((params) => publish(ACTION_NEXT, params), [publish]);
33
+ const close = React.useCallback(() => publish(ACTION_CLOSE), [publish]);
26
34
  const isSwipeValid = (offset) => !(carousel.finite &&
27
35
  ((rtl(offset) > 0 && state.currentIndex === 0) ||
28
- (rtl(offset) < 0 && state.currentIndex === slides.length - 1)));
36
+ (rtl(offset) < 0 && state.currentIndex === state.slides.length - 1)));
29
37
  const setSwipeOffset = (offset) => {
30
38
  var _a;
31
39
  swipeOffset.current = offset;
32
40
  (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.style.setProperty(cssVar("swipe_offset"), `${Math.round(offset)}px`);
33
41
  };
34
- const animate = useAnimation(carouselRef, (snapshot, rect, translate) => {
42
+ const { prepareAnimation, isAnimationPlaying } = useAnimation(carouselRef, (snapshot, rect, translate) => {
35
43
  var _a;
36
44
  if (carouselRef.current && containerRect && ((_a = state.animation) === null || _a === void 0 ? void 0 : _a.duration)) {
37
45
  const parsedSpacing = parseLengthPercentage(carousel.spacing);
38
- const spacingValue = (parsedSpacing.percent ? (parsedSpacing.percent * containerRect.width) / 100 : parsedSpacing.pixel) ||
39
- 0;
46
+ const spacingValue = (parsedSpacing.percent
47
+ ? (parsedSpacing.percent * containerRect.width) / 100
48
+ : parsedSpacing.pixel) || 0;
40
49
  return {
41
50
  keyframes: [
42
51
  {
@@ -54,14 +63,12 @@ export function Controller({ children, ...props }) {
54
63
  return undefined;
55
64
  });
56
65
  const swipe = useEventCallback((action) => {
57
- var _a;
66
+ var _a, _b;
58
67
  const currentSwipeOffset = action.offset || 0;
59
- const swipeDuration = !currentSwipeOffset
60
- ? getNavigationAnimationDuration(animation)
61
- : getSwipeAnimationDuration(animation);
62
- const swipeEasing = getAnimationEasing(!currentSwipeOffset ? animation.navigation : animation.swipe);
68
+ const swipeDuration = !currentSwipeOffset ? (_a = animation.navigation) !== null && _a !== void 0 ? _a : animation.swipe : animation.swipe;
69
+ const swipeEasing = !currentSwipeOffset && !isAnimationPlaying() ? animation.easing.navigation : animation.easing.swipe;
63
70
  let { direction } = action;
64
- const count = (_a = action.count) !== null && _a !== void 0 ? _a : 1;
71
+ const count = (_b = action.count) !== null && _b !== void 0 ? _b : 1;
65
72
  let newSwipeState = SwipeState.ANIMATION;
66
73
  let newSwipeAnimationDuration = swipeDuration * count;
67
74
  if (!direction) {
@@ -110,25 +117,30 @@ export function Controller({ children, ...props }) {
110
117
  setSwipeState(SwipeState.NONE);
111
118
  }, newSwipeAnimationDuration);
112
119
  if (carouselRef.current) {
113
- animate({
120
+ prepareAnimation({
114
121
  rect: carouselRef.current.getBoundingClientRect(),
115
122
  index: state.globalIndex,
116
123
  });
117
124
  }
118
125
  setSwipeState(newSwipeState);
119
- publish(ACTION_SWIPE, { increment, duration: newSwipeAnimationDuration, easing: swipeEasing });
126
+ publish(ACTION_SWIPE, {
127
+ type: "swipe",
128
+ increment,
129
+ duration: newSwipeAnimationDuration,
130
+ easing: swipeEasing,
131
+ });
120
132
  });
121
133
  React.useEffect(() => {
122
134
  var _a, _b;
123
135
  if (((_a = state.animation) === null || _a === void 0 ? void 0 : _a.increment) && ((_b = state.animation) === null || _b === void 0 ? void 0 : _b.duration)) {
124
- cleanupAnimationIncrement(() => dispatch({ increment: 0 }), state.animation.duration);
136
+ cleanupAnimationIncrement(() => dispatch({ type: "swipe", increment: 0 }), state.animation.duration);
125
137
  }
126
138
  }, [state.animation, dispatch, cleanupAnimationIncrement]);
127
139
  const swipeParams = [
128
140
  subscribeSensors,
129
141
  isSwipeValid,
130
142
  (containerRect === null || containerRect === void 0 ? void 0 : containerRect.width) || 0,
131
- getSwipeAnimationDuration(animation),
143
+ animation.swipe,
132
144
  () => setSwipeState(SwipeState.SWIPE),
133
145
  (offset) => setSwipeOffset(offset),
134
146
  (offset, duration) => swipe({ offset, duration, count: 1 }),
@@ -143,30 +155,50 @@ export function Controller({ children, ...props }) {
143
155
  }
144
156
  });
145
157
  React.useEffect(focusOnMount, [focusOnMount]);
146
- const handleIndexChange = useEventCallback(() => {
158
+ const onViewCallback = useEventCallback(() => {
147
159
  var _a;
148
- (_a = on.view) === null || _a === void 0 ? void 0 : _a.call(on, state.currentIndex);
160
+ (_a = on.view) === null || _a === void 0 ? void 0 : _a.call(on, { index: state.currentIndex });
149
161
  });
150
- React.useEffect(handleIndexChange, [state.currentIndex, handleIndexChange]);
162
+ React.useEffect(onViewCallback, [state.globalIndex, onViewCallback]);
151
163
  React.useEffect(() => cleanup(subscribe(ACTION_PREV, (action) => swipe({ direction: ACTION_PREV, ...action })), subscribe(ACTION_NEXT, (action) => swipe({ direction: ACTION_NEXT, ...action })), subscribe(ACTION_SWIPE, (action) => dispatch(action))), [subscribe, swipe, dispatch]);
152
164
  React.useEffect(() => subscribeSensors(EVENT_ON_KEY_UP, (event) => {
153
165
  if (event.code === VK_ESCAPE) {
154
- publish(ACTION_CLOSE);
166
+ close();
155
167
  }
156
- }), [subscribeSensors, publish]);
157
- React.useEffect(() => controller.closeOnBackdropClick
158
- ? subscribe(YARL_EVENT_BACKDROP_CLICK, () => publish(ACTION_CLOSE))
159
- : () => { }, [controller.closeOnBackdropClick, publish, subscribe]);
160
- const transferFocus = useEventCallback(() => { var _a; return (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.focus(); });
161
- const getLightboxProps = useEventCallback(() => props);
168
+ }), [subscribeSensors, close]);
162
169
  const context = React.useMemo(() => ({
163
- getLightboxProps,
164
- subscribeSensors,
165
- transferFocus,
170
+ prev,
171
+ next,
172
+ close,
173
+ focus,
174
+ slideRect: containerRect ? computeSlideRect(containerRect, carousel.padding) : { width: 0, height: 0 },
166
175
  containerRect: containerRect || { width: 0, height: 0 },
176
+ subscribeSensors,
167
177
  containerRef,
168
178
  setCarouselRef,
169
- }), [getLightboxProps, subscribeSensors, transferFocus, containerRect, containerRef, setCarouselRef]);
179
+ toolbarWidth,
180
+ setToolbarWidth,
181
+ }), [
182
+ prev,
183
+ next,
184
+ close,
185
+ focus,
186
+ subscribeSensors,
187
+ containerRect,
188
+ containerRef,
189
+ setCarouselRef,
190
+ toolbarWidth,
191
+ setToolbarWidth,
192
+ carousel.padding,
193
+ ]);
194
+ React.useImperativeHandle(controller.ref, () => ({
195
+ prev,
196
+ next,
197
+ close,
198
+ focus,
199
+ getLightboxProps,
200
+ getLightboxState,
201
+ }), [prev, next, close, focus, getLightboxProps, getLightboxState]);
170
202
  return (React.createElement("div", { ref: handleContainerRef, className: clsx(cssClass(cssContainerPrefix()), cssClass(CLASS_FLEX_CENTER)), style: {
171
203
  ...(swipeState === SwipeState.SWIPE
172
204
  ? { [cssVar("swipe_offset")]: `${Math.round(swipeOffset.current)}px` }
@@ -175,6 +207,8 @@ export function Controller({ children, ...props }) {
175
207
  ? { [cssVar("controller_touch_action")]: controller.touchAction }
176
208
  : null),
177
209
  ...styles.container,
178
- }, ...(controller.aria ? { role: "presentation", "aria-live": "polite" } : null), tabIndex: -1, ...registerSensors }, containerRect && React.createElement(ControllerContext.Provider, { value: context }, children)));
210
+ }, ...(controller.aria ? { role: "presentation", "aria-live": "polite" } : null), tabIndex: -1, ...registerSensors }, containerRect && (React.createElement(ControllerContext.Provider, { value: context },
211
+ children, (_a = render.controls) === null || _a === void 0 ? void 0 :
212
+ _a.call(render)))));
179
213
  }
180
214
  export const ControllerModule = createModule(MODULE_CONTROLLER, Controller);
@@ -1,14 +1,13 @@
1
1
  import * as React from "react";
2
- import { ComponentProps, Labels } from "../../types.js";
2
+ import { ComponentProps, RenderFunction } from "../../types.js";
3
3
  export type NavigationButtonProps = {
4
- labels?: Labels;
5
4
  label: string;
6
5
  icon: React.ElementType;
7
- renderIcon?: () => React.ReactNode;
6
+ renderIcon?: RenderFunction;
8
7
  action: "prev" | "next";
9
8
  onClick: () => void;
10
9
  disabled?: boolean;
11
10
  };
12
- export declare function NavigationButton({ labels, label, icon, renderIcon, action, onClick, disabled, }: NavigationButtonProps): JSX.Element;
13
- export declare function Navigation({ slides, carousel: { finite }, animation, labels, render: { buttonPrev, buttonNext, iconPrev, iconNext }, }: ComponentProps): JSX.Element;
11
+ export declare function NavigationButton({ label, icon, renderIcon, action, onClick, disabled }: NavigationButtonProps): JSX.Element;
12
+ export declare function Navigation({ carousel: { finite }, animation, render: { buttonPrev, buttonNext, iconPrev, iconNext }, }: ComponentProps): JSX.Element;
14
13
  export declare const NavigationModule: import("../../types.js").Module;
@@ -1,33 +1,36 @@
1
1
  import * as React from "react";
2
2
  import { createModule } from "../config.js";
3
3
  import { useEventCallback, useLoseFocus, useRTL, useThrottle } from "../hooks/index.js";
4
- import { cssClass, getNavigationAnimationDuration, label as translateLabel } from "../utils.js";
4
+ import { cssClass, label as translateLabel } from "../utils.js";
5
5
  import { IconButton, NextIcon, PreviousIcon } from "../components/index.js";
6
- import { useEvents, useLightboxState } from "../contexts/index.js";
6
+ import { useLightboxProps, useLightboxState } from "../contexts/index.js";
7
7
  import { useController } from "./Controller.js";
8
8
  import { ACTION_NEXT, ACTION_PREV, EVENT_ON_KEY_DOWN, MODULE_NAVIGATION, VK_ARROW_LEFT, VK_ARROW_RIGHT, } from "../consts.js";
9
- export function NavigationButton({ labels, label, icon, renderIcon, action, onClick, disabled, }) {
9
+ export function NavigationButton({ label, icon, renderIcon, action, onClick, disabled }) {
10
+ const { labels } = useLightboxProps();
10
11
  return (React.createElement(IconButton, { label: translateLabel(labels, label), icon: icon, renderIcon: renderIcon, className: cssClass(`navigation_${action}`), disabled: disabled, onClick: onClick, ...useLoseFocus(disabled) }));
11
12
  }
12
- export function Navigation({ slides, carousel: { finite }, animation, labels, render: { buttonPrev, buttonNext, iconPrev, iconNext }, }) {
13
- const { currentIndex } = useLightboxState().state;
14
- const { subscribeSensors } = useController();
15
- const { publish } = useEvents();
13
+ export function Navigation({ carousel: { finite }, animation, render: { buttonPrev, buttonNext, iconPrev, iconNext }, }) {
14
+ var _a;
15
+ const { slides, currentIndex } = useLightboxState().state;
16
+ const { prev, next, subscribeSensors } = useController();
16
17
  const isRTL = useRTL();
17
18
  const prevDisabled = slides.length === 0 || (finite && currentIndex === 0);
18
19
  const nextDisabled = slides.length === 0 || (finite && currentIndex === slides.length - 1);
19
- const publishThrottled = useThrottle((action) => publish(action), getNavigationAnimationDuration(animation) / 2);
20
+ const throttle = ((_a = animation.navigation) !== null && _a !== void 0 ? _a : animation.swipe) / 2;
21
+ const prevThrottled = useThrottle(prev, throttle);
22
+ const nextThrottled = useThrottle(next, throttle);
20
23
  const handleKeyDown = useEventCallback((event) => {
21
24
  if (event.key === VK_ARROW_LEFT && !(isRTL ? nextDisabled : prevDisabled)) {
22
- publishThrottled(isRTL ? ACTION_NEXT : ACTION_PREV);
25
+ (isRTL ? nextThrottled : prevThrottled)();
23
26
  }
24
27
  if (event.key === VK_ARROW_RIGHT && !(isRTL ? prevDisabled : nextDisabled)) {
25
- publishThrottled(isRTL ? ACTION_PREV : ACTION_NEXT);
28
+ (isRTL ? prevThrottled : nextThrottled)();
26
29
  }
27
30
  });
28
31
  React.useEffect(() => subscribeSensors(EVENT_ON_KEY_DOWN, handleKeyDown), [subscribeSensors, handleKeyDown]);
29
32
  return (React.createElement(React.Fragment, null,
30
- buttonPrev ? (buttonPrev()) : (React.createElement(NavigationButton, { label: "Previous", action: ACTION_PREV, icon: PreviousIcon, renderIcon: iconPrev, disabled: prevDisabled, labels: labels, onClick: () => publish(ACTION_PREV) })),
31
- buttonNext ? (buttonNext()) : (React.createElement(NavigationButton, { label: "Next", action: ACTION_NEXT, icon: NextIcon, renderIcon: iconNext, disabled: nextDisabled, labels: labels, onClick: () => publish(ACTION_NEXT) }))));
33
+ buttonPrev ? (buttonPrev()) : (React.createElement(NavigationButton, { label: "Previous", action: ACTION_PREV, icon: PreviousIcon, renderIcon: iconPrev, disabled: prevDisabled, onClick: prev })),
34
+ buttonNext ? (buttonNext()) : (React.createElement(NavigationButton, { label: "Next", action: ACTION_NEXT, icon: NextIcon, renderIcon: iconNext, disabled: nextDisabled, onClick: next }))));
32
35
  }
33
36
  export const NavigationModule = createModule(MODULE_NAVIGATION, Navigation);
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  import * as ReactDOM from "react-dom";
3
3
  import { LightboxDefaultProps } from "../../props.js";
4
4
  import { createModule } from "../config.js";
5
- import { clsx, composePrefix, cssClass, cssVar, getAnimationEasing, getFadeAnimationDuration } from "../utils.js";
5
+ import { clsx, composePrefix, cssClass, cssVar } from "../utils.js";
6
6
  import { useEventCallback, useMotionPreference } from "../hooks/index.js";
7
7
  import { useEvents, useTimeouts } from "../contexts/index.js";
8
8
  import { ACTION_CLOSE, CLASS_NO_SCROLL_PADDING, MODULE_PORTAL } from "../consts.js";
@@ -28,8 +28,7 @@ export function Portal({ children, animation, styles, className, on, close }) {
28
28
  const { setTimeout } = useTimeouts();
29
29
  const { subscribe } = useEvents();
30
30
  const reduceMotion = useMotionPreference();
31
- const animationDuration = !reduceMotion ? getFadeAnimationDuration(animation) : 0;
32
- const animationEasing = !reduceMotion ? getAnimationEasing(animation.fade) : undefined;
31
+ const animationDuration = !reduceMotion ? animation.fade : 0;
33
32
  React.useEffect(() => {
34
33
  setMounted(true);
35
34
  return () => {
@@ -83,7 +82,9 @@ export function Portal({ children, animation, styles, className, on, close }) {
83
82
  ...(animation.fade !== LightboxDefaultProps.animation.fade
84
83
  ? { [cssVar("fade_animation_duration")]: `${animationDuration}ms` }
85
84
  : null),
86
- ...(animationEasing ? { [cssVar("fade_animation_timing_function")]: animationEasing } : null),
85
+ ...(animation.easing.fade !== LightboxDefaultProps.animation.easing.fade
86
+ ? { [cssVar("fade_animation_timing_function")]: animation.easing.fade }
87
+ : null),
87
88
  ...styles.root,
88
89
  } }, children), document.body)
89
90
  : null;
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import { ComponentProps } from "../../types.js";
3
+ export declare function Root({ children }: ComponentProps): JSX.Element;
4
+ export declare const RootModule: import("../../types.js").Module;
@@ -0,0 +1,7 @@
1
+ import * as React from "react";
2
+ import { createModule } from "../config.js";
3
+ import { MODULE_ROOT } from "../consts.js";
4
+ export function Root({ children }) {
5
+ return React.createElement(React.Fragment, null, children);
6
+ }
7
+ export const RootModule = createModule(MODULE_ROOT, Root);
@@ -1,10 +1,4 @@
1
1
  /// <reference types="react" />
2
2
  import { ComponentProps } from "../../types.js";
3
- import { YARL_EVENT_TOOLBAR_WIDTH } from "../consts.js";
4
- declare module "../" {
5
- interface EventTypes {
6
- [YARL_EVENT_TOOLBAR_WIDTH]: number;
7
- }
8
- }
9
3
  export declare function Toolbar({ toolbar: { buttons }, labels, render: { buttonClose, iconClose } }: ComponentProps): JSX.Element;
10
4
  export declare const ToolbarModule: import("../../types.js").Module;
@@ -1,22 +1,20 @@
1
1
  import * as React from "react";
2
2
  import { createModule } from "../config.js";
3
3
  import { composePrefix, cssClass, label } from "../utils.js";
4
- import { useEvents } from "../contexts/index.js";
5
4
  import { CloseIcon, IconButton } from "../components/index.js";
6
5
  import { useContainerRect } from "../hooks/useContainerRect.js";
7
- import { ACTION_CLOSE, MODULE_TOOLBAR, YARL_EVENT_TOOLBAR_WIDTH } from "../consts.js";
6
+ import { useController } from "./Controller.js";
7
+ import { ACTION_CLOSE, MODULE_TOOLBAR } from "../consts.js";
8
8
  function cssPrefix(value) {
9
9
  return composePrefix(MODULE_TOOLBAR, value);
10
10
  }
11
11
  export function Toolbar({ toolbar: { buttons }, labels, render: { buttonClose, iconClose } }) {
12
- const { publish } = useEvents();
12
+ const { close, setToolbarWidth } = useController();
13
13
  const { setContainerRef, containerRect } = useContainerRect();
14
14
  React.useEffect(() => {
15
- if (containerRect === null || containerRect === void 0 ? void 0 : containerRect.width) {
16
- publish(YARL_EVENT_TOOLBAR_WIDTH, containerRect.width);
17
- }
18
- }, [publish, containerRect === null || containerRect === void 0 ? void 0 : containerRect.width]);
19
- const renderCloseButton = () => buttonClose ? (buttonClose()) : (React.createElement(IconButton, { key: ACTION_CLOSE, label: label(labels, "Close"), icon: CloseIcon, renderIcon: iconClose, onClick: () => publish(ACTION_CLOSE) }));
15
+ setToolbarWidth(containerRect === null || containerRect === void 0 ? void 0 : containerRect.width);
16
+ }, [setToolbarWidth, containerRect === null || containerRect === void 0 ? void 0 : containerRect.width]);
17
+ const renderCloseButton = () => buttonClose ? (buttonClose()) : (React.createElement(IconButton, { key: ACTION_CLOSE, label: label(labels, "Close"), icon: CloseIcon, renderIcon: iconClose, onClick: () => close() }));
20
18
  return (React.createElement("div", { ref: setContainerRef, className: cssClass(cssPrefix()) }, buttons === null || buttons === void 0 ? void 0 : buttons.map((button) => (button === ACTION_CLOSE ? renderCloseButton() : button))));
21
19
  }
22
20
  export const ToolbarModule = createModule(MODULE_TOOLBAR, Toolbar);
@@ -1,7 +1,7 @@
1
1
  export * from "./Carousel.js";
2
2
  export * from "./Controller.js";
3
- export * from "./Core.js";
4
3
  export * from "./Navigation.js";
5
4
  export * from "./NoScroll.js";
6
5
  export * from "./Portal.js";
6
+ export * from "./Root.js";
7
7
  export * from "./Toolbar.js";
@@ -1,7 +1,7 @@
1
1
  export * from "./Carousel.js";
2
2
  export * from "./Controller.js";
3
- export * from "./Core.js";
4
3
  export * from "./Navigation.js";
5
4
  export * from "./NoScroll.js";
6
5
  export * from "./Portal.js";
6
+ export * from "./Root.js";
7
7
  export * from "./Toolbar.js";
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { AnimationSettings, AnimationSpec, Labels, LightboxProps, Slide, SlideImage } from "../types.js";
2
+ import { ContainerRect, Labels, LengthOrPercentage, LightboxProps, Slide, SlideImage } from "../types.js";
3
3
  export declare const clsx: (...classes: (string | boolean | undefined)[]) => string;
4
4
  export declare const cssClass: (name: string) => string;
5
5
  export declare const cssVar: (name: string) => string;
@@ -9,23 +9,20 @@ export declare const label: (labels: Labels | undefined, lbl: string) => string;
9
9
  export declare const cleanup: (...cleaners: (() => void)[]) => () => void;
10
10
  export declare const makeUseContext: <T>(name: string, contextName: string, context: React.Context<T | null>) => () => NonNullable<T>;
11
11
  export declare const hasWindow: () => boolean;
12
- export declare const isDefined: <T = any>(x: T | undefined) => x is T;
13
- export declare const isNumber: (value: any) => value is number;
14
- export declare const round: (value: number, decimals?: number) => number;
12
+ export declare function round(value: number, decimals?: number): number;
15
13
  export declare const isImageSlide: (slide: Slide) => slide is SlideImage;
16
14
  export declare const isImageFitCover: (image: SlideImage, imageFit?: LightboxProps["carousel"]["imageFit"]) => boolean;
17
- export declare const parseLengthPercentage: (input: unknown) => {
15
+ export declare function parseLengthPercentage(input: LengthOrPercentage): {
18
16
  pixel: number;
19
17
  percent?: undefined;
20
18
  } | {
21
19
  percent: number;
22
20
  pixel?: undefined;
23
21
  };
22
+ export declare function computeSlideRect(containerRect: ContainerRect, padding: LengthOrPercentage): {
23
+ width: number;
24
+ height: number;
25
+ };
24
26
  export declare const devicePixelRatio: () => number;
25
27
  export declare const getSlideIndex: (index: number, slidesCount: number) => number;
26
28
  export declare const getSlide: (slides: Slide[], index: number) => Slide;
27
- export declare const getAnimationEasing: (animationSpec: AnimationSpec | undefined) => string | undefined;
28
- export declare const getAnimationDuration: (animationSpec: AnimationSpec | undefined, defaultDuration: number) => number;
29
- export declare const getFadeAnimationDuration: (animation: AnimationSettings) => number;
30
- export declare const getSwipeAnimationDuration: (animation: AnimationSettings) => number;
31
- export declare const getNavigationAnimationDuration: (animation: AnimationSettings) => number;
@@ -1,5 +1,4 @@
1
1
  import * as React from "react";
2
- import { AnimationDefaultProps } from "../props.js";
3
2
  import { IMAGE_FIT_CONTAIN, IMAGE_FIT_COVER } from "./consts.js";
4
3
  export const clsx = (...classes) => [...classes].filter((cls) => Boolean(cls)).join(" ");
5
4
  const cssPrefix = "yarl__";
@@ -21,15 +20,13 @@ export const makeUseContext = (name, contextName, context) => () => {
21
20
  return ctx;
22
21
  };
23
22
  export const hasWindow = () => typeof window !== "undefined";
24
- export const isDefined = (x) => typeof x !== "undefined";
25
- export const isNumber = (value) => typeof value === "number";
26
- export const round = (value, decimals = 0) => {
23
+ export function round(value, decimals = 0) {
27
24
  const factor = 10 ** decimals;
28
25
  return Math.round((value + Number.EPSILON) * factor) / factor;
29
- };
30
- export const isImageSlide = (slide) => !isDefined(slide.type) || slide.type === "image";
26
+ }
27
+ export const isImageSlide = (slide) => slide.type === undefined || slide.type === "image";
31
28
  export const isImageFitCover = (image, imageFit) => image.imageFit === IMAGE_FIT_COVER || (image.imageFit !== IMAGE_FIT_CONTAIN && imageFit === IMAGE_FIT_COVER);
32
- export const parseLengthPercentage = (input) => {
29
+ export function parseLengthPercentage(input) {
33
30
  if (typeof input === "number") {
34
31
  return { pixel: input };
35
32
  }
@@ -38,12 +35,15 @@ export const parseLengthPercentage = (input) => {
38
35
  return input.endsWith("%") ? { percent: value } : { pixel: value };
39
36
  }
40
37
  return { pixel: 0 };
41
- };
42
- export const devicePixelRatio = () => (typeof window !== "undefined" ? window === null || window === void 0 ? void 0 : window.devicePixelRatio : undefined) || 1;
38
+ }
39
+ export function computeSlideRect(containerRect, padding) {
40
+ const paddingValue = parseLengthPercentage(padding);
41
+ const paddingPixels = paddingValue.percent !== undefined ? (containerRect.width / 100) * paddingValue.percent : paddingValue.pixel;
42
+ return {
43
+ width: Math.max(containerRect.width - 2 * paddingPixels, 0),
44
+ height: Math.max(containerRect.height - 2 * paddingPixels, 0),
45
+ };
46
+ }
47
+ export const devicePixelRatio = () => (hasWindow() ? window === null || window === void 0 ? void 0 : window.devicePixelRatio : undefined) || 1;
43
48
  export const getSlideIndex = (index, slidesCount) => ((index % slidesCount) + slidesCount) % slidesCount;
44
49
  export const getSlide = (slides, index) => slides[getSlideIndex(index, slides.length)];
45
- export const getAnimationEasing = (animationSpec) => typeof animationSpec === "object" ? animationSpec.easing : undefined;
46
- export const getAnimationDuration = (animationSpec, defaultDuration) => { var _a; return (_a = (typeof animationSpec === "object" ? animationSpec.duration : animationSpec)) !== null && _a !== void 0 ? _a : defaultDuration; };
47
- export const getFadeAnimationDuration = (animation) => getAnimationDuration(animation.fade, AnimationDefaultProps.fade);
48
- export const getSwipeAnimationDuration = (animation) => getAnimationDuration(animation.swipe, AnimationDefaultProps.swipe);
49
- export const getNavigationAnimationDuration = (animation) => getAnimationDuration(animation.navigation, getSwipeAnimationDuration(animation));
@@ -1,7 +1,3 @@
1
- import { Plugin } from "../../types.js";
2
- export declare const defaultCaptionsProps: {
3
- descriptionTextAlign: "start";
4
- descriptionMaxLines: number;
5
- };
1
+ import { PluginProps } from "../../types.js";
6
2
  /** Captions plugin */
7
- export declare const Captions: Plugin;
3
+ export declare function Captions({ augment }: PluginProps): void;
@@ -1,23 +1,20 @@
1
1
  import * as React from "react";
2
- import { createModule, MODULE_CONTROLLER, PLUGIN_CAPTIONS } from "../../core/index.js";
3
- import { CaptionsContextProvider } from "./CaptionsContext.js";
2
+ import { resolveCaptionsProps } from "./props.js";
4
3
  import { Description } from "./Description.js";
5
4
  import { Title } from "./Title.js";
6
- export const defaultCaptionsProps = {
7
- descriptionTextAlign: "start",
8
- descriptionMaxLines: 3,
9
- };
10
- export const Captions = ({ augment, addParent }) => {
11
- addParent(MODULE_CONTROLLER, createModule(PLUGIN_CAPTIONS, CaptionsContextProvider));
12
- augment(({ render: { slideFooter: renderFooter, ...restRender }, captions, styles, ...restProps }) => ({
13
- render: {
14
- slideFooter: (slide) => (React.createElement(React.Fragment, null, renderFooter === null || renderFooter === void 0 ? void 0 :
15
- renderFooter(slide),
16
- slide.title && React.createElement(Title, { styles: styles, title: slide.title }),
17
- slide.description && (React.createElement(Description, { styles: styles, description: slide.description, ...{ ...defaultCaptionsProps, ...captions } })))),
18
- ...restRender,
19
- },
20
- styles,
21
- ...restProps,
22
- }));
23
- };
5
+ export function Captions({ augment }) {
6
+ augment(({ render: { slideFooter: renderFooter, ...restRender }, captions, styles, ...restProps }) => {
7
+ return {
8
+ render: {
9
+ slideFooter: ({ slide }) => (React.createElement(React.Fragment, null, renderFooter === null || renderFooter === void 0 ? void 0 :
10
+ renderFooter({ slide }),
11
+ slide.title && React.createElement(Title, { styles: styles, title: slide.title }),
12
+ slide.description && React.createElement(Description, { styles: styles, description: slide.description }))),
13
+ ...restRender,
14
+ },
15
+ captions: resolveCaptionsProps(captions),
16
+ styles,
17
+ ...restProps,
18
+ };
19
+ });
20
+ }
@@ -1,4 +1,4 @@
1
1
  /// <reference types="react" />
2
2
  import { LightboxProps, Slide } from "../../types.js";
3
- export type DescriptionProps = Pick<LightboxProps, "styles"> & Required<Pick<Slide, "description">> & Required<LightboxProps["captions"]>;
4
- export declare function Description({ description, descriptionTextAlign, descriptionMaxLines, styles }: DescriptionProps): JSX.Element;
3
+ export type DescriptionProps = Required<Pick<Slide, "description">> & Pick<LightboxProps, "styles">;
4
+ export declare function Description({ description, styles }: DescriptionProps): JSX.Element;
@@ -1,8 +1,10 @@
1
1
  import * as React from "react";
2
- import { clsx, cssVar } from "../../core/index.js";
3
- import { defaultCaptionsProps } from "./Captions.js";
2
+ import { clsx, cssVar, useLightboxProps } from "../../core/index.js";
3
+ import { defaultCaptionsProps, resolveCaptionsProps } from "./props.js";
4
4
  import { cssPrefix } from "./utils.js";
5
- export function Description({ description, descriptionTextAlign, descriptionMaxLines, styles }) {
5
+ export function Description({ description, styles }) {
6
+ const { captions } = useLightboxProps();
7
+ const { descriptionTextAlign, descriptionMaxLines } = resolveCaptionsProps(captions);
6
8
  return (React.createElement("div", { style: styles.captionsDescriptionContainer, className: clsx(cssPrefix("captions_container"), cssPrefix("description_container")) },
7
9
  React.createElement("div", { className: cssPrefix("description"), style: {
8
10
  ...(descriptionTextAlign !== defaultCaptionsProps.descriptionTextAlign ||
@@ -1,9 +1,8 @@
1
1
  import * as React from "react";
2
- import { clsx, cssVar } from "../../core/index.js";
3
- import { useCaptions } from "./CaptionsContext.js";
2
+ import { clsx, cssVar, useController } from "../../core/index.js";
4
3
  import { cssPrefix } from "./utils.js";
5
4
  export function Title({ title, styles }) {
6
- const { toolbarWidth } = useCaptions();
5
+ const { toolbarWidth } = useController();
7
6
  return (React.createElement("div", { style: styles.captionsTitleContainer, className: clsx(cssPrefix("captions_container"), cssPrefix("title_container")) },
8
7
  React.createElement("div", { style: styles.captionsTitle, className: cssPrefix("title"), ...(toolbarWidth ? { style: { [cssVar("toolbar_width")]: `${toolbarWidth}px` } } : null) }, title)));
9
8
  }
@@ -4,6 +4,7 @@
4
4
  right: var(--yarl__slide_captions_container_right, 0);
5
5
  padding: var(--yarl__slide_captions_container_padding, 16px);
6
6
  background: var(--yarl__slide_captions_container_background, rgba(0, 0, 0, 0.5));
7
+ -webkit-transform: translateZ(0);
7
8
  }
8
9
  .yarl__slide_title {
9
10
  color: var(--yarl__slide_title_color, #fff);
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { Captions } from "./Captions.js";
3
- type TextAlignment = "start" | "end" | "center";
4
- declare module "../../types" {
3
+ declare module "../../types.js" {
4
+ type TextAlignment = "start" | "end" | "center";
5
5
  interface GenericSlide {
6
6
  /** slide title */
7
7
  title?: React.ReactNode;
@@ -0,0 +1,9 @@
1
+ import { LightboxProps } from "../../types.js";
2
+ export declare const defaultCaptionsProps: {
3
+ descriptionTextAlign: "start";
4
+ descriptionMaxLines: number;
5
+ };
6
+ export declare const resolveCaptionsProps: (captions: LightboxProps["captions"]) => {
7
+ descriptionTextAlign: import("../../types.js").TextAlignment;
8
+ descriptionMaxLines: number;
9
+ };
@@ -0,0 +1,8 @@
1
+ export const defaultCaptionsProps = {
2
+ descriptionTextAlign: "start",
3
+ descriptionMaxLines: 3,
4
+ };
5
+ export const resolveCaptionsProps = (captions) => ({
6
+ ...defaultCaptionsProps,
7
+ ...captions,
8
+ });
@@ -1 +1 @@
1
- export declare function cssPrefix(className: string): string;
1
+ export declare const cssPrefix: (className: string) => string;
@@ -1,4 +1,2 @@
1
1
  import { cssClass } from "../../core/index.js";
2
- export function cssPrefix(className) {
3
- return cssClass(`slide_${className}`);
4
- }
2
+ export const cssPrefix = (className) => cssClass(`slide_${className}`);
@@ -1,3 +1,3 @@
1
- import { Plugin } from "../../types.js";
1
+ import { PluginProps } from "../../types.js";
2
2
  /** Fullscreen plugin */
3
- export declare const Fullscreen: Plugin;
3
+ export declare function Fullscreen({ augment, contains, addParent }: PluginProps): void;
@@ -1,11 +1,13 @@
1
1
  import * as React from "react";
2
2
  import { createModule, MODULE_CONTROLLER, PLUGIN_FULLSCREEN, PLUGIN_THUMBNAILS } from "../../core/index.js";
3
+ import { resolveFullscreenProps } from "./props.js";
3
4
  import { FullscreenButton } from "./FullscreenButton.js";
4
5
  import { FullscreenContextProvider } from "./FullscreenContext.js";
5
- export const Fullscreen = ({ augment, contains, addParent }) => {
6
- augment(({ toolbar: { buttons, ...restToolbar }, ...restProps }) => ({
6
+ export function Fullscreen({ augment, contains, addParent }) {
7
+ augment(({ fullscreen, toolbar: { buttons, ...restToolbar }, ...restProps }) => ({
7
8
  toolbar: { buttons: [React.createElement(FullscreenButton, { key: PLUGIN_FULLSCREEN }), ...buttons], ...restToolbar },
9
+ fullscreen: resolveFullscreenProps(fullscreen),
8
10
  ...restProps,
9
11
  }));
10
12
  addParent(contains(PLUGIN_THUMBNAILS) ? PLUGIN_THUMBNAILS : MODULE_CONTROLLER, createModule(PLUGIN_FULLSCREEN, FullscreenContextProvider));
11
- };
13
+ }