@jobber/components 6.113.1 → 6.114.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/Gallery/index.cjs +2 -2
- package/dist/Gallery/index.mjs +2 -2
- package/dist/LightBox/LightBox.constants.d.ts +22 -0
- package/dist/LightBox/LightBox.d.ts +118 -54
- package/dist/LightBox/LightBox.types.d.ts +94 -0
- package/dist/LightBox/LightBoxContext.d.ts +5 -0
- package/dist/LightBox/index.cjs +3 -1
- package/dist/LightBox/index.d.ts +2 -0
- package/dist/LightBox/index.mjs +3 -2
- package/dist/LightBox-cjs.js +245 -57
- package/dist/LightBox-es.js +246 -59
- package/dist/index.cjs +1 -0
- package/dist/index.mjs +1 -1
- package/dist/utils/meta/meta.json +9 -0
- package/package.json +2 -2
package/dist/Gallery/index.cjs
CHANGED
|
@@ -8,6 +8,8 @@ require('../LightBox-cjs.js');
|
|
|
8
8
|
require('framer-motion');
|
|
9
9
|
require('react-dom');
|
|
10
10
|
require('@jobber/hooks');
|
|
11
|
+
require('../noop-cjs.js');
|
|
12
|
+
require('../_commonjsHelpers-cjs.js');
|
|
11
13
|
require('../ButtonDismiss-cjs.js');
|
|
12
14
|
require('../Button-cjs.js');
|
|
13
15
|
require('react-router-dom');
|
|
@@ -17,7 +19,6 @@ require('../Typography-cjs.js');
|
|
|
17
19
|
require('../Text-cjs.js');
|
|
18
20
|
require('../Heading-cjs.js');
|
|
19
21
|
require('../AtlantisThemeContext-cjs.js');
|
|
20
|
-
require('../_commonjsHelpers-cjs.js');
|
|
21
22
|
require('../identity-cjs.js');
|
|
22
23
|
require('../isTypedArray-cjs.js');
|
|
23
24
|
require('../isObjectLike-cjs.js');
|
|
@@ -34,7 +35,6 @@ require('../Content-cjs.js');
|
|
|
34
35
|
require('../ProgressBar-cjs.js');
|
|
35
36
|
require('../ConfirmationModal-cjs.js');
|
|
36
37
|
require('../Modal/index.cjs');
|
|
37
|
-
require('../noop-cjs.js');
|
|
38
38
|
require('../floating-ui.react-cjs.js');
|
|
39
39
|
require('react/jsx-runtime');
|
|
40
40
|
require('../AtlantisPortalContent-cjs.js');
|
package/dist/Gallery/index.mjs
CHANGED
|
@@ -6,6 +6,8 @@ import '../LightBox-es.js';
|
|
|
6
6
|
import 'framer-motion';
|
|
7
7
|
import 'react-dom';
|
|
8
8
|
import '@jobber/hooks';
|
|
9
|
+
import '../noop-es.js';
|
|
10
|
+
import '../_commonjsHelpers-es.js';
|
|
9
11
|
import '../ButtonDismiss-es.js';
|
|
10
12
|
import '../Button-es.js';
|
|
11
13
|
import 'react-router-dom';
|
|
@@ -15,7 +17,6 @@ import '../Typography-es.js';
|
|
|
15
17
|
import '../Text-es.js';
|
|
16
18
|
import '../Heading-es.js';
|
|
17
19
|
import '../AtlantisThemeContext-es.js';
|
|
18
|
-
import '../_commonjsHelpers-es.js';
|
|
19
20
|
import '../identity-es.js';
|
|
20
21
|
import '../isTypedArray-es.js';
|
|
21
22
|
import '../isObjectLike-es.js';
|
|
@@ -32,7 +33,6 @@ import '../Content-es.js';
|
|
|
32
33
|
import '../ProgressBar-es.js';
|
|
33
34
|
import '../ConfirmationModal-es.js';
|
|
34
35
|
import '../Modal/index.mjs';
|
|
35
|
-
import '../noop-es.js';
|
|
36
36
|
import '../floating-ui.react-es.js';
|
|
37
37
|
import 'react/jsx-runtime';
|
|
38
38
|
import '../AtlantisPortalContent-es.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { RefObject } from "react";
|
|
2
|
+
export declare const BUTTON_DEBOUNCE_DELAY = 250;
|
|
3
|
+
export declare const MOVEMENT_DEBOUNCE_DELAY = 1000;
|
|
4
|
+
export declare const swipeConfidenceThreshold = 10000;
|
|
5
|
+
export declare const swipePower: (offset: number, velocity: number) => number;
|
|
6
|
+
export declare const slideVariants: {
|
|
7
|
+
enter: (directionRef: RefObject<number>) => {
|
|
8
|
+
x: string;
|
|
9
|
+
};
|
|
10
|
+
center: {
|
|
11
|
+
x: number;
|
|
12
|
+
};
|
|
13
|
+
exit: (directionRef: RefObject<number>) => {
|
|
14
|
+
x: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export declare const imageTransition: {
|
|
18
|
+
x: {
|
|
19
|
+
duration: number;
|
|
20
|
+
ease: number[];
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -1,56 +1,120 @@
|
|
|
1
|
-
import type { CSSProperties } from "react";
|
|
2
1
|
import React from "react";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import type { LightBoxNavigationProps, LightBoxProps } from "./LightBox.types";
|
|
3
|
+
import { LightBoxProvider } from "./LightBoxContext";
|
|
4
|
+
export declare function LightBoxContent(): React.JSX.Element;
|
|
5
|
+
/**
|
|
6
|
+
* Blurred, desaturated copy of the current image rendered as a full-bleed
|
|
7
|
+
* background behind the lightbox. Pass `className` to apply additional styles.
|
|
8
|
+
*/
|
|
9
|
+
declare function LightBoxBackground({ className }: {
|
|
10
|
+
readonly className?: string;
|
|
11
|
+
}): React.JSX.Element;
|
|
12
|
+
/**
|
|
13
|
+
* Semi-transparent blur backdrop. Clicking it calls `onRequestClose`.
|
|
14
|
+
* Pass `className` to apply additional styles.
|
|
15
|
+
*/
|
|
16
|
+
declare function LightBoxOverlay({ className }: {
|
|
17
|
+
readonly className?: string;
|
|
18
|
+
}): React.JSX.Element;
|
|
19
|
+
/**
|
|
20
|
+
* Top bar showing the current image counter (`1/3`) and a close button.
|
|
21
|
+
* Styled for dark backgrounds.
|
|
22
|
+
*/
|
|
23
|
+
declare function LightBoxToolbar(): React.JSX.Element;
|
|
24
|
+
/**
|
|
25
|
+
* The animated hero image with swipe-to-navigate and slide animation.
|
|
26
|
+
*
|
|
27
|
+
* Pass `className` to add styles to the image wrapper. Supports
|
|
28
|
+
* swipe-to-navigate (drag). Keyboard arrow navigation is handled by
|
|
29
|
+
* `LightBox.Provider`.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* <LightBox.Slides className={styles.imageArea} />
|
|
34
|
+
* <LightBox.Navigation
|
|
35
|
+
* prevButtonClassName={styles.prev}
|
|
36
|
+
* nextButtonClassName={styles.next}
|
|
37
|
+
* />
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare function LightBoxSlides({ className }: {
|
|
41
|
+
readonly className?: string;
|
|
42
|
+
}): React.JSX.Element;
|
|
43
|
+
/**
|
|
44
|
+
* Previous and next navigation buttons. Returns `null` when the image set
|
|
45
|
+
* has only one image.
|
|
46
|
+
*
|
|
47
|
+
* Use `prevButtonClassName` and `nextButtonClassName` to override the styles
|
|
48
|
+
* on each button's wrapper for custom layouts.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```tsx
|
|
52
|
+
* <LightBox.Navigation
|
|
53
|
+
* prevButtonClassName={styles.prev}
|
|
54
|
+
* nextButtonClassName={styles.next}
|
|
55
|
+
* />
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
declare function LightBoxNavigation({ prevButtonClassName, nextButtonClassName, }: LightBoxNavigationProps): React.JSX.Element | null;
|
|
59
|
+
/**
|
|
60
|
+
* Title and caption text for the current image. Only renders when the current
|
|
61
|
+
* image has a `title` or `caption`. Styled for dark backgrounds.
|
|
62
|
+
*/
|
|
63
|
+
declare function LightBoxCaption(): React.JSX.Element | null;
|
|
64
|
+
/**
|
|
65
|
+
* Scrollable thumbnail strip. Only renders when there are two or more images.
|
|
66
|
+
*/
|
|
67
|
+
declare function LightBoxThumbnails(): React.JSX.Element | null;
|
|
68
|
+
/**
|
|
69
|
+
* LightBox displays images in a fullscreen overlay.
|
|
70
|
+
*
|
|
71
|
+
* **Self-contained (legacy) usage:**
|
|
72
|
+
* ```tsx
|
|
73
|
+
* <LightBox
|
|
74
|
+
* open={isOpen}
|
|
75
|
+
* images={images}
|
|
76
|
+
* imageIndex={imageIndex}
|
|
77
|
+
* onRequestClose={({ lastPosition }) => { setIsOpen(false); }}
|
|
78
|
+
* />
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* **Full composable (fullscreen) usage:**
|
|
82
|
+
* ```tsx
|
|
83
|
+
* <LightBox.Provider open={isOpen} images={images} onRequestClose={onClose}>
|
|
84
|
+
* <LightBox.Content />
|
|
85
|
+
* </LightBox.Provider>
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* **Inline gallery usage (no overlay, no close):**
|
|
89
|
+
* ```tsx
|
|
90
|
+
* <LightBox.Provider
|
|
91
|
+
* open={true}
|
|
92
|
+
* images={images}
|
|
93
|
+
* imageIndex={activeIndex}
|
|
94
|
+
* onImageChange={onImageChange}
|
|
95
|
+
* >
|
|
96
|
+
* <div className={styles.lightboxWrapper} onMouseMove={handleMouseMove}>
|
|
97
|
+
* <LightBox.Background className={styles.backgroundImage} />
|
|
98
|
+
* <LightBox.Overlay className={styles.blurOverlay} />
|
|
99
|
+
* <LightBox.Slides className={styles.imageArea} />
|
|
100
|
+
* <LightBox.Navigation
|
|
101
|
+
* prevButtonClassName={styles.prev}
|
|
102
|
+
* nextButtonClassName={styles.next}
|
|
103
|
+
* />
|
|
104
|
+
* </div>
|
|
105
|
+
* </LightBox.Provider>
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
declare function LightBox(props: LightBoxProps): React.JSX.Element;
|
|
109
|
+
declare namespace LightBox {
|
|
110
|
+
var Provider: typeof LightBoxProvider;
|
|
111
|
+
var Content: typeof LightBoxContent;
|
|
112
|
+
var Background: typeof LightBoxBackground;
|
|
113
|
+
var Overlay: typeof LightBoxOverlay;
|
|
114
|
+
var Toolbar: typeof LightBoxToolbar;
|
|
115
|
+
var Slides: typeof LightBoxSlides;
|
|
116
|
+
var Navigation: typeof LightBoxNavigation;
|
|
117
|
+
var Caption: typeof LightBoxCaption;
|
|
118
|
+
var Thumbnails: typeof LightBoxThumbnails;
|
|
8
119
|
}
|
|
9
|
-
|
|
10
|
-
lastPosition: number;
|
|
11
|
-
}
|
|
12
|
-
interface LightBoxProps {
|
|
13
|
-
/**
|
|
14
|
-
* Specify if the Lightbox is open or closed.
|
|
15
|
-
*/
|
|
16
|
-
readonly open: boolean;
|
|
17
|
-
/**
|
|
18
|
-
* Images is an array of objects defining a LightBox image. This object consists of
|
|
19
|
-
* `title`, `caption`, `alt` and `url`. `title`, `alt` and `caption` are optional, `url` is
|
|
20
|
-
* required, for each image.
|
|
21
|
-
*/
|
|
22
|
-
readonly images: PresentedImage[];
|
|
23
|
-
/**
|
|
24
|
-
* Use this to specify which image in `images` to initialize the lightbox with.
|
|
25
|
-
* This is useful when you have a collection of thumbnails as you only need one
|
|
26
|
-
* collection of image urls, order doesn't matter.
|
|
27
|
-
*/
|
|
28
|
-
readonly imageIndex?: number;
|
|
29
|
-
/**
|
|
30
|
-
* This function must set open to false in order to close the lightbox. Note there
|
|
31
|
-
* is a 300ms easing animation on lightbox close that occurs before this function
|
|
32
|
-
* is called.
|
|
33
|
-
* This function receives an object as an argument with the key `lastPosition`
|
|
34
|
-
* that has the index of the image the user was on when LightBox was closed.
|
|
35
|
-
*/
|
|
36
|
-
onRequestClose(options: RequestCloseOptions): void;
|
|
37
|
-
/**
|
|
38
|
-
* Sets the box-sizing for the thumbnails in the lightbox. This is a solution for a problem where
|
|
39
|
-
* tailwind was setting the box-sizing to `border-box` and causing issues with the lightbox.
|
|
40
|
-
* @default "content-box"
|
|
41
|
-
*/
|
|
42
|
-
readonly boxSizing?: CSSProperties["boxSizing"];
|
|
43
|
-
}
|
|
44
|
-
export declare const slideVariants: {
|
|
45
|
-
enter: (directionRef: React.RefObject<number>) => {
|
|
46
|
-
x: string;
|
|
47
|
-
};
|
|
48
|
-
center: {
|
|
49
|
-
x: number;
|
|
50
|
-
};
|
|
51
|
-
exit: (directionRef: React.RefObject<number>) => {
|
|
52
|
-
x: string;
|
|
53
|
-
};
|
|
54
|
-
};
|
|
55
|
-
export declare function LightBox({ boxSizing, open, images, imageIndex, onRequestClose, }: LightBoxProps): React.JSX.Element;
|
|
56
|
-
export {};
|
|
120
|
+
export { LightBox };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode, RefObject } from "react";
|
|
2
|
+
import type { PanInfo } from "framer-motion";
|
|
3
|
+
export interface PresentedImage {
|
|
4
|
+
title?: string;
|
|
5
|
+
caption?: string;
|
|
6
|
+
alt?: string;
|
|
7
|
+
url: string;
|
|
8
|
+
}
|
|
9
|
+
export interface RequestCloseOptions {
|
|
10
|
+
lastPosition: number;
|
|
11
|
+
}
|
|
12
|
+
export interface LightBoxContextType {
|
|
13
|
+
readonly open: boolean;
|
|
14
|
+
readonly images: PresentedImage[];
|
|
15
|
+
readonly currentImageIndex: number;
|
|
16
|
+
readonly mouseIsStationary: boolean;
|
|
17
|
+
readonly boxSizing: CSSProperties["boxSizing"];
|
|
18
|
+
readonly directionRef: RefObject<number>;
|
|
19
|
+
readonly selectedThumbnailRef: RefObject<HTMLDivElement | null>;
|
|
20
|
+
readonly lightboxRef: RefObject<HTMLDivElement | null>;
|
|
21
|
+
readonly mounted: RefObject<boolean>;
|
|
22
|
+
handleMouseMove(): void;
|
|
23
|
+
handleRequestClose(): void;
|
|
24
|
+
handleOnDragEnd(event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void;
|
|
25
|
+
handleThumbnailClick(index: number): void;
|
|
26
|
+
debouncedHandleNext(): void;
|
|
27
|
+
debouncedHandlePrevious(): void;
|
|
28
|
+
}
|
|
29
|
+
export interface NavButtonProps {
|
|
30
|
+
readonly onClick: () => void;
|
|
31
|
+
readonly hideButton: boolean;
|
|
32
|
+
readonly className: string;
|
|
33
|
+
}
|
|
34
|
+
export interface LightBoxProps {
|
|
35
|
+
/**
|
|
36
|
+
* Specify if the Lightbox is open or closed.
|
|
37
|
+
*/
|
|
38
|
+
readonly open: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Images is an array of objects defining a LightBox image. This object consists of
|
|
41
|
+
* `title`, `caption`, `alt` and `url`. `title`, `alt` and `caption` are optional, `url` is
|
|
42
|
+
* required, for each image.
|
|
43
|
+
*/
|
|
44
|
+
readonly images: PresentedImage[];
|
|
45
|
+
/**
|
|
46
|
+
* Use this to specify which image in `images` to initialize the lightbox with.
|
|
47
|
+
* This is useful when you have a collection of thumbnails as you only need one
|
|
48
|
+
* collection of image urls, order doesn't matter.
|
|
49
|
+
*/
|
|
50
|
+
readonly imageIndex?: number;
|
|
51
|
+
/**
|
|
52
|
+
* This function must set open to false in order to close the lightbox. Note there
|
|
53
|
+
* is a 300ms easing animation on lightbox close that occurs before this function
|
|
54
|
+
* is called.
|
|
55
|
+
* This function receives an object as an argument with the key `lastPosition`
|
|
56
|
+
* that has the index of the image the user was on when LightBox was closed.
|
|
57
|
+
*/
|
|
58
|
+
onRequestClose(options: RequestCloseOptions): void;
|
|
59
|
+
/**
|
|
60
|
+
* Sets the box-sizing for the thumbnails in the lightbox. This is a solution for a problem where
|
|
61
|
+
* tailwind was setting the box-sizing to `border-box` and causing issues with the lightbox.
|
|
62
|
+
* @default "content-box"
|
|
63
|
+
*/
|
|
64
|
+
readonly boxSizing?: CSSProperties["boxSizing"];
|
|
65
|
+
}
|
|
66
|
+
export type LightBoxProviderProps = Omit<LightBoxProps, "onRequestClose"> & {
|
|
67
|
+
/**
|
|
68
|
+
* This function must set open to false in order to close the lightbox. Note there
|
|
69
|
+
* is a 300ms easing animation on lightbox close that occurs before this function
|
|
70
|
+
* is called.
|
|
71
|
+
* This function receives an object as an argument with the key `lastPosition`
|
|
72
|
+
* that has the index of the image the user was on when LightBox was closed.
|
|
73
|
+
*/
|
|
74
|
+
onRequestClose?(options: RequestCloseOptions): void;
|
|
75
|
+
/**
|
|
76
|
+
* Callback function that is invoked whenever the current image index changes.
|
|
77
|
+
* This includes when the user navigates to a different image (via arrow keys,
|
|
78
|
+
* navigation buttons, or swipe gestures) or when clicking a thumbnail.
|
|
79
|
+
*
|
|
80
|
+
* @param index - The new current image index (0-based)
|
|
81
|
+
*/
|
|
82
|
+
onImageChange?(index: number): void;
|
|
83
|
+
readonly children: ReactNode;
|
|
84
|
+
};
|
|
85
|
+
export interface LightBoxNavigationProps {
|
|
86
|
+
/**
|
|
87
|
+
* The class name to apply to the previous button wrapper.
|
|
88
|
+
*/
|
|
89
|
+
readonly prevButtonClassName?: string;
|
|
90
|
+
/**
|
|
91
|
+
* The class name to apply to the next button wrapper.
|
|
92
|
+
*/
|
|
93
|
+
readonly nextButtonClassName?: string;
|
|
94
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { LightBoxContextType, LightBoxProviderProps } from "./LightBox.types";
|
|
3
|
+
export declare const LightBoxContext: React.Context<LightBoxContextType>;
|
|
4
|
+
export declare function LightBoxProvider({ open, images, imageIndex, onRequestClose, onImageChange, boxSizing, children, }: LightBoxProviderProps): React.JSX.Element;
|
|
5
|
+
export declare function useLightBoxContext(): LightBoxContextType;
|
package/dist/LightBox/index.cjs
CHANGED
|
@@ -6,6 +6,8 @@ require('framer-motion');
|
|
|
6
6
|
require('react-dom');
|
|
7
7
|
require('@jobber/hooks');
|
|
8
8
|
require('classnames');
|
|
9
|
+
require('../noop-cjs.js');
|
|
10
|
+
require('../_commonjsHelpers-cjs.js');
|
|
9
11
|
require('../ButtonDismiss-cjs.js');
|
|
10
12
|
require('../Button-cjs.js');
|
|
11
13
|
require('react-router-dom');
|
|
@@ -16,7 +18,6 @@ require('../Typography-cjs.js');
|
|
|
16
18
|
require('../Text-cjs.js');
|
|
17
19
|
require('../Heading-cjs.js');
|
|
18
20
|
require('../AtlantisThemeContext-cjs.js');
|
|
19
|
-
require('../_commonjsHelpers-cjs.js');
|
|
20
21
|
require('../identity-cjs.js');
|
|
21
22
|
require('../isTypedArray-cjs.js');
|
|
22
23
|
require('../isObjectLike-cjs.js');
|
|
@@ -29,3 +30,4 @@ require('../_setToString-cjs.js');
|
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
exports.LightBox = LightBox.LightBox;
|
|
33
|
+
exports.useLightBoxContext = LightBox.useLightBoxContext;
|
package/dist/LightBox/index.d.ts
CHANGED
package/dist/LightBox/index.mjs
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
export { L as LightBox } from '../LightBox-es.js';
|
|
1
|
+
export { L as LightBox, u as useLightBoxContext } from '../LightBox-es.js';
|
|
2
2
|
import 'react';
|
|
3
3
|
import 'framer-motion';
|
|
4
4
|
import 'react-dom';
|
|
5
5
|
import '@jobber/hooks';
|
|
6
6
|
import 'classnames';
|
|
7
|
+
import '../noop-es.js';
|
|
8
|
+
import '../_commonjsHelpers-es.js';
|
|
7
9
|
import '../ButtonDismiss-es.js';
|
|
8
10
|
import '../Button-es.js';
|
|
9
11
|
import 'react-router-dom';
|
|
@@ -14,7 +16,6 @@ import '../Typography-es.js';
|
|
|
14
16
|
import '../Text-es.js';
|
|
15
17
|
import '../Heading-es.js';
|
|
16
18
|
import '../AtlantisThemeContext-es.js';
|
|
17
|
-
import '../_commonjsHelpers-es.js';
|
|
18
19
|
import '../identity-es.js';
|
|
19
20
|
import '../isTypedArray-es.js';
|
|
20
21
|
import '../isObjectLike-es.js';
|
package/dist/LightBox-cjs.js
CHANGED
|
@@ -5,6 +5,7 @@ var framerMotion = require('framer-motion');
|
|
|
5
5
|
var ReactDOM = require('react-dom');
|
|
6
6
|
var jobberHooks = require('@jobber/hooks');
|
|
7
7
|
var classnames = require('classnames');
|
|
8
|
+
var noop = require('./noop-cjs.js');
|
|
8
9
|
var ButtonDismiss = require('./ButtonDismiss-cjs.js');
|
|
9
10
|
var Text = require('./Text-cjs.js');
|
|
10
11
|
var Button = require('./Button-cjs.js');
|
|
@@ -13,6 +14,11 @@ var AtlantisThemeContext = require('./AtlantisThemeContext-cjs.js');
|
|
|
13
14
|
|
|
14
15
|
var styles = {"backgroundImage":"i9Tw1T65W-k-","next":"Q8amcRaTGf0-","prev":"W9FVb24yJrk-","buttonHidden":"nsN0TPWsBXI-","buttonVisible":"dkLYp7AD2jE-","lightboxWrapper":"_5p2iAj4JfoE-","toolbar":"rMK4cKdOxFw-","closeButton":"_0m6vb11DgiA-","slideNumber":"kCc68gGuTgg-","image":"yYFVVScosfQ-","imageArea":"UskuwLHR6fg-","captionWrapper":"OGjhge-r-U4-","title":"tZU2g-NYdIs-","blurOverlay":"GKIdLTmvcvQ-","thumbnailBar":"_3TfQLQEE3GQ-","thumbnailImage":"eBMzUOlcfQ4-","thumbnail":"eapm2zruLn8-","selected":"PeLn2u-QB0k-","spinning":"_8tDoqjgfLcw-"};
|
|
15
16
|
|
|
17
|
+
// A little bit more than the transition's duration
|
|
18
|
+
// We're doing this to prevent a bug from framer-motion
|
|
19
|
+
// https://github.com/framer/motion/issues/1769
|
|
20
|
+
const BUTTON_DEBOUNCE_DELAY = 250;
|
|
21
|
+
const MOVEMENT_DEBOUNCE_DELAY = 1000;
|
|
16
22
|
const swipeConfidenceThreshold = 10000;
|
|
17
23
|
const swipePower = (offset, velocity) => {
|
|
18
24
|
return Math.abs(offset) * velocity;
|
|
@@ -31,12 +37,26 @@ const slideVariants = {
|
|
|
31
37
|
const imageTransition = {
|
|
32
38
|
x: { duration: 0.65, ease: [0.42, 0, 0, 1.03] },
|
|
33
39
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
|
|
41
|
+
/* eslint-disable max-statements */
|
|
42
|
+
const LightBoxContext = React.createContext({
|
|
43
|
+
open: false,
|
|
44
|
+
images: [],
|
|
45
|
+
currentImageIndex: 0,
|
|
46
|
+
mouseIsStationary: true,
|
|
47
|
+
boxSizing: "content-box",
|
|
48
|
+
directionRef: { current: 0 },
|
|
49
|
+
selectedThumbnailRef: { current: null },
|
|
50
|
+
lightboxRef: { current: null },
|
|
51
|
+
mounted: { current: false },
|
|
52
|
+
handleMouseMove: noop.noop,
|
|
53
|
+
handleRequestClose: noop.noop,
|
|
54
|
+
handleOnDragEnd: noop.noop,
|
|
55
|
+
handleThumbnailClick: noop.noop,
|
|
56
|
+
debouncedHandleNext: noop.noop,
|
|
57
|
+
debouncedHandlePrevious: noop.noop,
|
|
58
|
+
});
|
|
59
|
+
function LightBoxProvider({ open = true, images, imageIndex = 0, onRequestClose = noop.noop, onImageChange = noop.noop, boxSizing = "content-box", children, }) {
|
|
40
60
|
const [currentImageIndex, setCurrentImageIndex] = React.useState(imageIndex);
|
|
41
61
|
const directionRef = React.useRef(0);
|
|
42
62
|
const [mouseIsStationary, setMouseIsStationary] = React.useState(true);
|
|
@@ -59,6 +79,7 @@ function LightBox({ boxSizing = "content-box", open, images, imageIndex = 0, onR
|
|
|
59
79
|
});
|
|
60
80
|
React.useEffect(() => {
|
|
61
81
|
setCurrentImageIndex(imageIndex);
|
|
82
|
+
onImageChange(imageIndex);
|
|
62
83
|
}, [imageIndex, open]);
|
|
63
84
|
if (prevOpen.current !== open) {
|
|
64
85
|
prevOpen.current = open;
|
|
@@ -72,57 +93,28 @@ function LightBox({ boxSizing = "content-box", open, images, imageIndex = 0, onR
|
|
|
72
93
|
inline: "center",
|
|
73
94
|
});
|
|
74
95
|
}, [currentImageIndex]);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
React.createElement("div", { className: styles.backgroundImage, style: {
|
|
82
|
-
backgroundImage: `url("${images[currentImageIndex].url}")`,
|
|
83
|
-
} }),
|
|
84
|
-
React.createElement("div", { className: styles.blurOverlay, onClick: handleRequestClose }),
|
|
85
|
-
React.createElement(AtlantisThemeContext.AtlantisThemeContextProvider, { dangerouslyOverrideTheme: "dark" },
|
|
86
|
-
React.createElement("div", { className: styles.toolbar },
|
|
87
|
-
React.createElement("div", { className: styles.slideNumber },
|
|
88
|
-
React.createElement(Text.Text, null, `${currentImageIndex + 1}/${images.length}`)),
|
|
89
|
-
React.createElement("div", { className: styles.closeButton },
|
|
90
|
-
React.createElement(ButtonDismiss.ButtonDismiss, { ariaLabel: "Close", onClick: handleRequestClose })))),
|
|
91
|
-
React.createElement("div", { className: styles.imageArea },
|
|
92
|
-
React.createElement(framerMotion.AnimatePresence, { initial: false },
|
|
93
|
-
React.createElement(framerMotion.motion.img, { key: currentImageIndex, variants: slideVariants, src: images[currentImageIndex].url, custom: directionRef, className: styles.image, initial: "enter", alt: images[currentImageIndex].alt ||
|
|
94
|
-
images[currentImageIndex].title ||
|
|
95
|
-
"", animate: "center", exit: "exit", transition: imageTransition, drag: "x", dragConstraints: { left: 0, right: 0 }, dragElastic: 1, onDragEnd: handleOnDragEnd }))),
|
|
96
|
-
images.length > 1 && (React.createElement(React.Fragment, null,
|
|
97
|
-
React.createElement(PreviousButton, { onClick: debouncedHandlePrevious, hideButton: mouseIsStationary }),
|
|
98
|
-
React.createElement(NextButton, { onClick: debouncedHandleNext, hideButton: mouseIsStationary }))),
|
|
99
|
-
(images[currentImageIndex].title ||
|
|
100
|
-
images[currentImageIndex].caption) && (React.createElement("div", { className: styles.captionWrapper },
|
|
101
|
-
React.createElement(AtlantisThemeContext.AtlantisThemeContextProvider, { dangerouslyOverrideTheme: "dark" },
|
|
102
|
-
images[currentImageIndex].title && (React.createElement("div", { className: styles.title },
|
|
103
|
-
React.createElement(Heading.Heading, { level: 4 }, images[currentImageIndex].title))),
|
|
104
|
-
images[currentImageIndex].caption && (React.createElement(Text.Text, { size: "large" }, images[currentImageIndex].caption))))),
|
|
105
|
-
images.length > 1 && (React.createElement("div", { className: styles.thumbnailBar, style: {
|
|
106
|
-
"--lightbox--box-sizing": boxSizing,
|
|
107
|
-
}, "data-testid": "ATL-Thumbnail-Bar" }, images.map((image, index) => (React.createElement("div", { key: index, className: classnames(styles.thumbnail, {
|
|
108
|
-
[styles.selected]: index === currentImageIndex,
|
|
109
|
-
}), onClick: () => handleThumbnailClick(index), ref: index === currentImageIndex ? selectedThumbnailRef : null },
|
|
110
|
-
React.createElement("img", { key: index, src: image.url, alt: image.alt || image.title || "", className: styles.thumbnailImage }))))))))));
|
|
111
|
-
return mounted.current
|
|
112
|
-
? ReactDOM.createPortal(template, document.body)
|
|
113
|
-
: template;
|
|
96
|
+
function handleMouseMove() {
|
|
97
|
+
if (mouseIsStationary) {
|
|
98
|
+
setMouseIsStationary(false);
|
|
99
|
+
}
|
|
100
|
+
handleMouseMovement();
|
|
101
|
+
}
|
|
114
102
|
function handleMovePrevious() {
|
|
115
103
|
directionRef.current = -1;
|
|
116
|
-
|
|
104
|
+
const newIndex = (currentImageIndex + images.length - 1) % images.length;
|
|
105
|
+
setCurrentImageIndex(newIndex);
|
|
106
|
+
onImageChange(newIndex);
|
|
117
107
|
}
|
|
118
108
|
function handleMoveNext() {
|
|
119
109
|
directionRef.current = 1;
|
|
120
|
-
|
|
110
|
+
const newIndex = (currentImageIndex + 1) % images.length;
|
|
111
|
+
setCurrentImageIndex(newIndex);
|
|
112
|
+
onImageChange(newIndex);
|
|
121
113
|
}
|
|
122
114
|
function handleRequestClose() {
|
|
123
115
|
onRequestClose({ lastPosition: currentImageIndex });
|
|
124
116
|
}
|
|
125
|
-
function handleOnDragEnd(
|
|
117
|
+
function handleOnDragEnd(_event, { offset, velocity }) {
|
|
126
118
|
const swipe = swipePower(offset.x, velocity.x);
|
|
127
119
|
if (swipe < -swipeConfidenceThreshold) {
|
|
128
120
|
handleMoveNext();
|
|
@@ -139,17 +131,28 @@ function LightBox({ boxSizing = "content-box", open, images, imageIndex = 0, onR
|
|
|
139
131
|
directionRef.current = 1;
|
|
140
132
|
}
|
|
141
133
|
setCurrentImageIndex(index);
|
|
134
|
+
onImageChange(index);
|
|
142
135
|
}
|
|
136
|
+
return (React.createElement(LightBoxContext.Provider, { value: {
|
|
137
|
+
open,
|
|
138
|
+
images,
|
|
139
|
+
currentImageIndex,
|
|
140
|
+
mouseIsStationary,
|
|
141
|
+
boxSizing,
|
|
142
|
+
directionRef,
|
|
143
|
+
selectedThumbnailRef,
|
|
144
|
+
lightboxRef,
|
|
145
|
+
mounted,
|
|
146
|
+
handleMouseMove,
|
|
147
|
+
handleRequestClose,
|
|
148
|
+
handleOnDragEnd,
|
|
149
|
+
handleThumbnailClick,
|
|
150
|
+
debouncedHandleNext,
|
|
151
|
+
debouncedHandlePrevious,
|
|
152
|
+
} }, children));
|
|
143
153
|
}
|
|
144
|
-
function
|
|
145
|
-
|
|
146
|
-
return (React.createElement("div", { className: `${styles.prev} ${hideButton ? styles.buttonHidden : styles.buttonVisible}` },
|
|
147
|
-
React.createElement(Button.Button, { size: mediumAndUp ? "large" : "small", variation: "subtle", type: "secondary", icon: "arrowLeft", ariaLabel: "Previous image", onClick: onClick })));
|
|
148
|
-
}
|
|
149
|
-
function NextButton({ onClick, hideButton }) {
|
|
150
|
-
const { mediumAndUp } = jobberHooks.useBreakpoints();
|
|
151
|
-
return (React.createElement("div", { className: `${styles.next} ${hideButton ? styles.buttonHidden : styles.buttonVisible}` },
|
|
152
|
-
React.createElement(Button.Button, { size: mediumAndUp ? "large" : "small", variation: "subtle", type: "secondary", icon: "arrowRight", ariaLabel: "Next image", onClick: onClick })));
|
|
154
|
+
function useLightBoxContext() {
|
|
155
|
+
return React.useContext(LightBoxContext);
|
|
153
156
|
}
|
|
154
157
|
function togglePrintStyles(open) {
|
|
155
158
|
try {
|
|
@@ -165,4 +168,189 @@ function togglePrintStyles(open) {
|
|
|
165
168
|
}
|
|
166
169
|
}
|
|
167
170
|
|
|
171
|
+
function LightBoxContent() {
|
|
172
|
+
const { open, lightboxRef, handleMouseMove } = useLightBoxContext();
|
|
173
|
+
const mounted = jobberHooks.useIsMounted();
|
|
174
|
+
const template = (React.createElement(React.Fragment, null, open && (React.createElement("div", { className: styles.lightboxWrapper, tabIndex: 0, "aria-label": "Lightbox", key: "Lightbox", ref: lightboxRef, onMouseMove: handleMouseMove },
|
|
175
|
+
React.createElement(LightBoxBackground, null),
|
|
176
|
+
React.createElement(LightBoxOverlay, null),
|
|
177
|
+
React.createElement(LightBoxToolbar, null),
|
|
178
|
+
React.createElement(LightBoxSlides, null),
|
|
179
|
+
React.createElement(LightBoxNavigation, null),
|
|
180
|
+
React.createElement(LightBoxCaption, null),
|
|
181
|
+
React.createElement(LightBoxThumbnails, null)))));
|
|
182
|
+
return mounted.current
|
|
183
|
+
? ReactDOM.createPortal(template, document.body)
|
|
184
|
+
: template;
|
|
185
|
+
}
|
|
186
|
+
function PreviousButton({ onClick, hideButton, className }) {
|
|
187
|
+
const { mediumAndUp } = jobberHooks.useBreakpoints();
|
|
188
|
+
return (React.createElement("div", { className: `${className} ${hideButton ? styles.buttonHidden : styles.buttonVisible}` },
|
|
189
|
+
React.createElement(Button.Button, { size: mediumAndUp ? "large" : "small", variation: "subtle", type: "secondary", icon: "arrowLeft", ariaLabel: "Previous image", onClick: onClick })));
|
|
190
|
+
}
|
|
191
|
+
function NextButton({ onClick, hideButton, className }) {
|
|
192
|
+
const { mediumAndUp } = jobberHooks.useBreakpoints();
|
|
193
|
+
return (React.createElement("div", { className: `${className} ${hideButton ? styles.buttonHidden : styles.buttonVisible}` },
|
|
194
|
+
React.createElement(Button.Button, { size: mediumAndUp ? "large" : "small", variation: "subtle", type: "secondary", icon: "arrowRight", ariaLabel: "Next image", onClick: onClick })));
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Blurred, desaturated copy of the current image rendered as a full-bleed
|
|
198
|
+
* background behind the lightbox. Pass `className` to apply additional styles.
|
|
199
|
+
*/
|
|
200
|
+
function LightBoxBackground({ className }) {
|
|
201
|
+
const { images, currentImageIndex } = useLightBoxContext();
|
|
202
|
+
return (React.createElement("div", { className: classnames(styles.backgroundImage, className), style: {
|
|
203
|
+
backgroundImage: `url("${images[currentImageIndex].url}")`,
|
|
204
|
+
} }));
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Semi-transparent blur backdrop. Clicking it calls `onRequestClose`.
|
|
208
|
+
* Pass `className` to apply additional styles.
|
|
209
|
+
*/
|
|
210
|
+
function LightBoxOverlay({ className }) {
|
|
211
|
+
const { handleRequestClose } = useLightBoxContext();
|
|
212
|
+
return (React.createElement("div", { className: classnames(styles.blurOverlay, className), onClick: handleRequestClose }));
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Top bar showing the current image counter (`1/3`) and a close button.
|
|
216
|
+
* Styled for dark backgrounds.
|
|
217
|
+
*/
|
|
218
|
+
function LightBoxToolbar() {
|
|
219
|
+
const { images, currentImageIndex, handleRequestClose } = useLightBoxContext();
|
|
220
|
+
return (React.createElement(AtlantisThemeContext.AtlantisThemeContextProvider, { dangerouslyOverrideTheme: "dark" },
|
|
221
|
+
React.createElement("div", { className: styles.toolbar },
|
|
222
|
+
React.createElement("div", { className: styles.slideNumber },
|
|
223
|
+
React.createElement(Text.Text, null, `${currentImageIndex + 1}/${images.length}`)),
|
|
224
|
+
React.createElement("div", { className: styles.closeButton },
|
|
225
|
+
React.createElement(ButtonDismiss.ButtonDismiss, { ariaLabel: "Close", onClick: handleRequestClose })))));
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* The animated hero image with swipe-to-navigate and slide animation.
|
|
229
|
+
*
|
|
230
|
+
* Pass `className` to add styles to the image wrapper. Supports
|
|
231
|
+
* swipe-to-navigate (drag). Keyboard arrow navigation is handled by
|
|
232
|
+
* `LightBox.Provider`.
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```tsx
|
|
236
|
+
* <LightBox.Slides className={styles.imageArea} />
|
|
237
|
+
* <LightBox.Navigation
|
|
238
|
+
* prevButtonClassName={styles.prev}
|
|
239
|
+
* nextButtonClassName={styles.next}
|
|
240
|
+
* />
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
function LightBoxSlides({ className }) {
|
|
244
|
+
const { images, currentImageIndex, directionRef, handleOnDragEnd } = useLightBoxContext();
|
|
245
|
+
return (React.createElement("div", { className: classnames(styles.imageArea, className) },
|
|
246
|
+
React.createElement(framerMotion.AnimatePresence, { initial: false },
|
|
247
|
+
React.createElement(framerMotion.motion.img, { key: currentImageIndex, variants: slideVariants, src: images[currentImageIndex].url, custom: directionRef, className: styles.image, initial: "enter", alt: images[currentImageIndex].alt ||
|
|
248
|
+
images[currentImageIndex].title ||
|
|
249
|
+
"", animate: "center", exit: "exit", transition: imageTransition, drag: "x", dragConstraints: { left: 0, right: 0 }, dragElastic: 1, onDragEnd: handleOnDragEnd }))));
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Previous and next navigation buttons. Returns `null` when the image set
|
|
253
|
+
* has only one image.
|
|
254
|
+
*
|
|
255
|
+
* Use `prevButtonClassName` and `nextButtonClassName` to override the styles
|
|
256
|
+
* on each button's wrapper for custom layouts.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```tsx
|
|
260
|
+
* <LightBox.Navigation
|
|
261
|
+
* prevButtonClassName={styles.prev}
|
|
262
|
+
* nextButtonClassName={styles.next}
|
|
263
|
+
* />
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
function LightBoxNavigation({ prevButtonClassName, nextButtonClassName, }) {
|
|
267
|
+
const { images, mouseIsStationary, debouncedHandleNext, debouncedHandlePrevious, } = useLightBoxContext();
|
|
268
|
+
if (images.length <= 1)
|
|
269
|
+
return null;
|
|
270
|
+
return (React.createElement(React.Fragment, null,
|
|
271
|
+
React.createElement(PreviousButton, { onClick: debouncedHandlePrevious, hideButton: mouseIsStationary, className: classnames(styles.prev, prevButtonClassName) }),
|
|
272
|
+
React.createElement(NextButton, { onClick: debouncedHandleNext, hideButton: mouseIsStationary, className: classnames(styles.next, nextButtonClassName) })));
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Title and caption text for the current image. Only renders when the current
|
|
276
|
+
* image has a `title` or `caption`. Styled for dark backgrounds.
|
|
277
|
+
*/
|
|
278
|
+
function LightBoxCaption() {
|
|
279
|
+
const { images, currentImageIndex } = useLightBoxContext();
|
|
280
|
+
const { title, caption } = images[currentImageIndex];
|
|
281
|
+
if (!title && !caption)
|
|
282
|
+
return null;
|
|
283
|
+
return (React.createElement("div", { className: styles.captionWrapper },
|
|
284
|
+
React.createElement(AtlantisThemeContext.AtlantisThemeContextProvider, { dangerouslyOverrideTheme: "dark" },
|
|
285
|
+
title && (React.createElement("div", { className: styles.title },
|
|
286
|
+
React.createElement(Heading.Heading, { level: 4 }, title))),
|
|
287
|
+
caption && React.createElement(Text.Text, { size: "large" }, caption))));
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Scrollable thumbnail strip. Only renders when there are two or more images.
|
|
291
|
+
*/
|
|
292
|
+
function LightBoxThumbnails() {
|
|
293
|
+
const { images, currentImageIndex, boxSizing, selectedThumbnailRef, handleThumbnailClick, } = useLightBoxContext();
|
|
294
|
+
if (images.length <= 1)
|
|
295
|
+
return null;
|
|
296
|
+
return (React.createElement("div", { className: styles.thumbnailBar, style: { "--lightbox--box-sizing": boxSizing }, "data-testid": "ATL-Thumbnail-Bar" }, images.map((image, index) => (React.createElement("div", { key: index, className: classnames(styles.thumbnail, {
|
|
297
|
+
[styles.selected]: index === currentImageIndex,
|
|
298
|
+
}), onClick: () => handleThumbnailClick(index), ref: index === currentImageIndex ? selectedThumbnailRef : null },
|
|
299
|
+
React.createElement("img", { key: index, src: image.url, alt: image.alt || image.title || "", className: styles.thumbnailImage }))))));
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* LightBox displays images in a fullscreen overlay.
|
|
303
|
+
*
|
|
304
|
+
* **Self-contained (legacy) usage:**
|
|
305
|
+
* ```tsx
|
|
306
|
+
* <LightBox
|
|
307
|
+
* open={isOpen}
|
|
308
|
+
* images={images}
|
|
309
|
+
* imageIndex={imageIndex}
|
|
310
|
+
* onRequestClose={({ lastPosition }) => { setIsOpen(false); }}
|
|
311
|
+
* />
|
|
312
|
+
* ```
|
|
313
|
+
*
|
|
314
|
+
* **Full composable (fullscreen) usage:**
|
|
315
|
+
* ```tsx
|
|
316
|
+
* <LightBox.Provider open={isOpen} images={images} onRequestClose={onClose}>
|
|
317
|
+
* <LightBox.Content />
|
|
318
|
+
* </LightBox.Provider>
|
|
319
|
+
* ```
|
|
320
|
+
*
|
|
321
|
+
* **Inline gallery usage (no overlay, no close):**
|
|
322
|
+
* ```tsx
|
|
323
|
+
* <LightBox.Provider
|
|
324
|
+
* open={true}
|
|
325
|
+
* images={images}
|
|
326
|
+
* imageIndex={activeIndex}
|
|
327
|
+
* onImageChange={onImageChange}
|
|
328
|
+
* >
|
|
329
|
+
* <div className={styles.lightboxWrapper} onMouseMove={handleMouseMove}>
|
|
330
|
+
* <LightBox.Background className={styles.backgroundImage} />
|
|
331
|
+
* <LightBox.Overlay className={styles.blurOverlay} />
|
|
332
|
+
* <LightBox.Slides className={styles.imageArea} />
|
|
333
|
+
* <LightBox.Navigation
|
|
334
|
+
* prevButtonClassName={styles.prev}
|
|
335
|
+
* nextButtonClassName={styles.next}
|
|
336
|
+
* />
|
|
337
|
+
* </div>
|
|
338
|
+
* </LightBox.Provider>
|
|
339
|
+
* ```
|
|
340
|
+
*/
|
|
341
|
+
function LightBox(props) {
|
|
342
|
+
return (React.createElement(LightBoxProvider, Object.assign({}, props),
|
|
343
|
+
React.createElement(LightBoxContent, null)));
|
|
344
|
+
}
|
|
345
|
+
LightBox.Provider = LightBoxProvider;
|
|
346
|
+
LightBox.Content = LightBoxContent;
|
|
347
|
+
LightBox.Background = LightBoxBackground;
|
|
348
|
+
LightBox.Overlay = LightBoxOverlay;
|
|
349
|
+
LightBox.Toolbar = LightBoxToolbar;
|
|
350
|
+
LightBox.Slides = LightBoxSlides;
|
|
351
|
+
LightBox.Navigation = LightBoxNavigation;
|
|
352
|
+
LightBox.Caption = LightBoxCaption;
|
|
353
|
+
LightBox.Thumbnails = LightBoxThumbnails;
|
|
354
|
+
|
|
168
355
|
exports.LightBox = LightBox;
|
|
356
|
+
exports.useLightBoxContext = useLightBoxContext;
|
package/dist/LightBox-es.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React__default, { useState, useRef, useEffect } from 'react';
|
|
1
|
+
import React__default, { createContext, useContext, useState, useRef, useEffect } from 'react';
|
|
2
2
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
3
3
|
import ReactDOM__default from 'react-dom';
|
|
4
4
|
import { useFocusTrap, useDebounce, useIsMounted, useRefocusOnActivator, useOnKeyDown, useBreakpoints } from '@jobber/hooks';
|
|
5
5
|
import classnames from 'classnames';
|
|
6
|
+
import { n as noop } from './noop-es.js';
|
|
6
7
|
import { B as ButtonDismiss } from './ButtonDismiss-es.js';
|
|
7
8
|
import { T as Text } from './Text-es.js';
|
|
8
9
|
import { B as Button } from './Button-es.js';
|
|
@@ -11,6 +12,11 @@ import { A as AtlantisThemeContextProvider } from './AtlantisThemeContext-es.js'
|
|
|
11
12
|
|
|
12
13
|
var styles = {"backgroundImage":"i9Tw1T65W-k-","next":"Q8amcRaTGf0-","prev":"W9FVb24yJrk-","buttonHidden":"nsN0TPWsBXI-","buttonVisible":"dkLYp7AD2jE-","lightboxWrapper":"_5p2iAj4JfoE-","toolbar":"rMK4cKdOxFw-","closeButton":"_0m6vb11DgiA-","slideNumber":"kCc68gGuTgg-","image":"yYFVVScosfQ-","imageArea":"UskuwLHR6fg-","captionWrapper":"OGjhge-r-U4-","title":"tZU2g-NYdIs-","blurOverlay":"GKIdLTmvcvQ-","thumbnailBar":"_3TfQLQEE3GQ-","thumbnailImage":"eBMzUOlcfQ4-","thumbnail":"eapm2zruLn8-","selected":"PeLn2u-QB0k-","spinning":"_8tDoqjgfLcw-"};
|
|
13
14
|
|
|
15
|
+
// A little bit more than the transition's duration
|
|
16
|
+
// We're doing this to prevent a bug from framer-motion
|
|
17
|
+
// https://github.com/framer/motion/issues/1769
|
|
18
|
+
const BUTTON_DEBOUNCE_DELAY = 250;
|
|
19
|
+
const MOVEMENT_DEBOUNCE_DELAY = 1000;
|
|
14
20
|
const swipeConfidenceThreshold = 10000;
|
|
15
21
|
const swipePower = (offset, velocity) => {
|
|
16
22
|
return Math.abs(offset) * velocity;
|
|
@@ -29,12 +35,26 @@ const slideVariants = {
|
|
|
29
35
|
const imageTransition = {
|
|
30
36
|
x: { duration: 0.65, ease: [0.42, 0, 0, 1.03] },
|
|
31
37
|
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
|
|
39
|
+
/* eslint-disable max-statements */
|
|
40
|
+
const LightBoxContext = createContext({
|
|
41
|
+
open: false,
|
|
42
|
+
images: [],
|
|
43
|
+
currentImageIndex: 0,
|
|
44
|
+
mouseIsStationary: true,
|
|
45
|
+
boxSizing: "content-box",
|
|
46
|
+
directionRef: { current: 0 },
|
|
47
|
+
selectedThumbnailRef: { current: null },
|
|
48
|
+
lightboxRef: { current: null },
|
|
49
|
+
mounted: { current: false },
|
|
50
|
+
handleMouseMove: noop,
|
|
51
|
+
handleRequestClose: noop,
|
|
52
|
+
handleOnDragEnd: noop,
|
|
53
|
+
handleThumbnailClick: noop,
|
|
54
|
+
debouncedHandleNext: noop,
|
|
55
|
+
debouncedHandlePrevious: noop,
|
|
56
|
+
});
|
|
57
|
+
function LightBoxProvider({ open = true, images, imageIndex = 0, onRequestClose = noop, onImageChange = noop, boxSizing = "content-box", children, }) {
|
|
38
58
|
const [currentImageIndex, setCurrentImageIndex] = useState(imageIndex);
|
|
39
59
|
const directionRef = useRef(0);
|
|
40
60
|
const [mouseIsStationary, setMouseIsStationary] = useState(true);
|
|
@@ -57,6 +77,7 @@ function LightBox({ boxSizing = "content-box", open, images, imageIndex = 0, onR
|
|
|
57
77
|
});
|
|
58
78
|
useEffect(() => {
|
|
59
79
|
setCurrentImageIndex(imageIndex);
|
|
80
|
+
onImageChange(imageIndex);
|
|
60
81
|
}, [imageIndex, open]);
|
|
61
82
|
if (prevOpen.current !== open) {
|
|
62
83
|
prevOpen.current = open;
|
|
@@ -70,57 +91,28 @@ function LightBox({ boxSizing = "content-box", open, images, imageIndex = 0, onR
|
|
|
70
91
|
inline: "center",
|
|
71
92
|
});
|
|
72
93
|
}, [currentImageIndex]);
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
React__default.createElement("div", { className: styles.backgroundImage, style: {
|
|
80
|
-
backgroundImage: `url("${images[currentImageIndex].url}")`,
|
|
81
|
-
} }),
|
|
82
|
-
React__default.createElement("div", { className: styles.blurOverlay, onClick: handleRequestClose }),
|
|
83
|
-
React__default.createElement(AtlantisThemeContextProvider, { dangerouslyOverrideTheme: "dark" },
|
|
84
|
-
React__default.createElement("div", { className: styles.toolbar },
|
|
85
|
-
React__default.createElement("div", { className: styles.slideNumber },
|
|
86
|
-
React__default.createElement(Text, null, `${currentImageIndex + 1}/${images.length}`)),
|
|
87
|
-
React__default.createElement("div", { className: styles.closeButton },
|
|
88
|
-
React__default.createElement(ButtonDismiss, { ariaLabel: "Close", onClick: handleRequestClose })))),
|
|
89
|
-
React__default.createElement("div", { className: styles.imageArea },
|
|
90
|
-
React__default.createElement(AnimatePresence, { initial: false },
|
|
91
|
-
React__default.createElement(motion.img, { key: currentImageIndex, variants: slideVariants, src: images[currentImageIndex].url, custom: directionRef, className: styles.image, initial: "enter", alt: images[currentImageIndex].alt ||
|
|
92
|
-
images[currentImageIndex].title ||
|
|
93
|
-
"", animate: "center", exit: "exit", transition: imageTransition, drag: "x", dragConstraints: { left: 0, right: 0 }, dragElastic: 1, onDragEnd: handleOnDragEnd }))),
|
|
94
|
-
images.length > 1 && (React__default.createElement(React__default.Fragment, null,
|
|
95
|
-
React__default.createElement(PreviousButton, { onClick: debouncedHandlePrevious, hideButton: mouseIsStationary }),
|
|
96
|
-
React__default.createElement(NextButton, { onClick: debouncedHandleNext, hideButton: mouseIsStationary }))),
|
|
97
|
-
(images[currentImageIndex].title ||
|
|
98
|
-
images[currentImageIndex].caption) && (React__default.createElement("div", { className: styles.captionWrapper },
|
|
99
|
-
React__default.createElement(AtlantisThemeContextProvider, { dangerouslyOverrideTheme: "dark" },
|
|
100
|
-
images[currentImageIndex].title && (React__default.createElement("div", { className: styles.title },
|
|
101
|
-
React__default.createElement(Heading, { level: 4 }, images[currentImageIndex].title))),
|
|
102
|
-
images[currentImageIndex].caption && (React__default.createElement(Text, { size: "large" }, images[currentImageIndex].caption))))),
|
|
103
|
-
images.length > 1 && (React__default.createElement("div", { className: styles.thumbnailBar, style: {
|
|
104
|
-
"--lightbox--box-sizing": boxSizing,
|
|
105
|
-
}, "data-testid": "ATL-Thumbnail-Bar" }, images.map((image, index) => (React__default.createElement("div", { key: index, className: classnames(styles.thumbnail, {
|
|
106
|
-
[styles.selected]: index === currentImageIndex,
|
|
107
|
-
}), onClick: () => handleThumbnailClick(index), ref: index === currentImageIndex ? selectedThumbnailRef : null },
|
|
108
|
-
React__default.createElement("img", { key: index, src: image.url, alt: image.alt || image.title || "", className: styles.thumbnailImage }))))))))));
|
|
109
|
-
return mounted.current
|
|
110
|
-
? ReactDOM__default.createPortal(template, document.body)
|
|
111
|
-
: template;
|
|
94
|
+
function handleMouseMove() {
|
|
95
|
+
if (mouseIsStationary) {
|
|
96
|
+
setMouseIsStationary(false);
|
|
97
|
+
}
|
|
98
|
+
handleMouseMovement();
|
|
99
|
+
}
|
|
112
100
|
function handleMovePrevious() {
|
|
113
101
|
directionRef.current = -1;
|
|
114
|
-
|
|
102
|
+
const newIndex = (currentImageIndex + images.length - 1) % images.length;
|
|
103
|
+
setCurrentImageIndex(newIndex);
|
|
104
|
+
onImageChange(newIndex);
|
|
115
105
|
}
|
|
116
106
|
function handleMoveNext() {
|
|
117
107
|
directionRef.current = 1;
|
|
118
|
-
|
|
108
|
+
const newIndex = (currentImageIndex + 1) % images.length;
|
|
109
|
+
setCurrentImageIndex(newIndex);
|
|
110
|
+
onImageChange(newIndex);
|
|
119
111
|
}
|
|
120
112
|
function handleRequestClose() {
|
|
121
113
|
onRequestClose({ lastPosition: currentImageIndex });
|
|
122
114
|
}
|
|
123
|
-
function handleOnDragEnd(
|
|
115
|
+
function handleOnDragEnd(_event, { offset, velocity }) {
|
|
124
116
|
const swipe = swipePower(offset.x, velocity.x);
|
|
125
117
|
if (swipe < -swipeConfidenceThreshold) {
|
|
126
118
|
handleMoveNext();
|
|
@@ -137,17 +129,28 @@ function LightBox({ boxSizing = "content-box", open, images, imageIndex = 0, onR
|
|
|
137
129
|
directionRef.current = 1;
|
|
138
130
|
}
|
|
139
131
|
setCurrentImageIndex(index);
|
|
132
|
+
onImageChange(index);
|
|
140
133
|
}
|
|
134
|
+
return (React__default.createElement(LightBoxContext.Provider, { value: {
|
|
135
|
+
open,
|
|
136
|
+
images,
|
|
137
|
+
currentImageIndex,
|
|
138
|
+
mouseIsStationary,
|
|
139
|
+
boxSizing,
|
|
140
|
+
directionRef,
|
|
141
|
+
selectedThumbnailRef,
|
|
142
|
+
lightboxRef,
|
|
143
|
+
mounted,
|
|
144
|
+
handleMouseMove,
|
|
145
|
+
handleRequestClose,
|
|
146
|
+
handleOnDragEnd,
|
|
147
|
+
handleThumbnailClick,
|
|
148
|
+
debouncedHandleNext,
|
|
149
|
+
debouncedHandlePrevious,
|
|
150
|
+
} }, children));
|
|
141
151
|
}
|
|
142
|
-
function
|
|
143
|
-
|
|
144
|
-
return (React__default.createElement("div", { className: `${styles.prev} ${hideButton ? styles.buttonHidden : styles.buttonVisible}` },
|
|
145
|
-
React__default.createElement(Button, { size: mediumAndUp ? "large" : "small", variation: "subtle", type: "secondary", icon: "arrowLeft", ariaLabel: "Previous image", onClick: onClick })));
|
|
146
|
-
}
|
|
147
|
-
function NextButton({ onClick, hideButton }) {
|
|
148
|
-
const { mediumAndUp } = useBreakpoints();
|
|
149
|
-
return (React__default.createElement("div", { className: `${styles.next} ${hideButton ? styles.buttonHidden : styles.buttonVisible}` },
|
|
150
|
-
React__default.createElement(Button, { size: mediumAndUp ? "large" : "small", variation: "subtle", type: "secondary", icon: "arrowRight", ariaLabel: "Next image", onClick: onClick })));
|
|
152
|
+
function useLightBoxContext() {
|
|
153
|
+
return useContext(LightBoxContext);
|
|
151
154
|
}
|
|
152
155
|
function togglePrintStyles(open) {
|
|
153
156
|
try {
|
|
@@ -163,4 +166,188 @@ function togglePrintStyles(open) {
|
|
|
163
166
|
}
|
|
164
167
|
}
|
|
165
168
|
|
|
166
|
-
|
|
169
|
+
function LightBoxContent() {
|
|
170
|
+
const { open, lightboxRef, handleMouseMove } = useLightBoxContext();
|
|
171
|
+
const mounted = useIsMounted();
|
|
172
|
+
const template = (React__default.createElement(React__default.Fragment, null, open && (React__default.createElement("div", { className: styles.lightboxWrapper, tabIndex: 0, "aria-label": "Lightbox", key: "Lightbox", ref: lightboxRef, onMouseMove: handleMouseMove },
|
|
173
|
+
React__default.createElement(LightBoxBackground, null),
|
|
174
|
+
React__default.createElement(LightBoxOverlay, null),
|
|
175
|
+
React__default.createElement(LightBoxToolbar, null),
|
|
176
|
+
React__default.createElement(LightBoxSlides, null),
|
|
177
|
+
React__default.createElement(LightBoxNavigation, null),
|
|
178
|
+
React__default.createElement(LightBoxCaption, null),
|
|
179
|
+
React__default.createElement(LightBoxThumbnails, null)))));
|
|
180
|
+
return mounted.current
|
|
181
|
+
? ReactDOM__default.createPortal(template, document.body)
|
|
182
|
+
: template;
|
|
183
|
+
}
|
|
184
|
+
function PreviousButton({ onClick, hideButton, className }) {
|
|
185
|
+
const { mediumAndUp } = useBreakpoints();
|
|
186
|
+
return (React__default.createElement("div", { className: `${className} ${hideButton ? styles.buttonHidden : styles.buttonVisible}` },
|
|
187
|
+
React__default.createElement(Button, { size: mediumAndUp ? "large" : "small", variation: "subtle", type: "secondary", icon: "arrowLeft", ariaLabel: "Previous image", onClick: onClick })));
|
|
188
|
+
}
|
|
189
|
+
function NextButton({ onClick, hideButton, className }) {
|
|
190
|
+
const { mediumAndUp } = useBreakpoints();
|
|
191
|
+
return (React__default.createElement("div", { className: `${className} ${hideButton ? styles.buttonHidden : styles.buttonVisible}` },
|
|
192
|
+
React__default.createElement(Button, { size: mediumAndUp ? "large" : "small", variation: "subtle", type: "secondary", icon: "arrowRight", ariaLabel: "Next image", onClick: onClick })));
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Blurred, desaturated copy of the current image rendered as a full-bleed
|
|
196
|
+
* background behind the lightbox. Pass `className` to apply additional styles.
|
|
197
|
+
*/
|
|
198
|
+
function LightBoxBackground({ className }) {
|
|
199
|
+
const { images, currentImageIndex } = useLightBoxContext();
|
|
200
|
+
return (React__default.createElement("div", { className: classnames(styles.backgroundImage, className), style: {
|
|
201
|
+
backgroundImage: `url("${images[currentImageIndex].url}")`,
|
|
202
|
+
} }));
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Semi-transparent blur backdrop. Clicking it calls `onRequestClose`.
|
|
206
|
+
* Pass `className` to apply additional styles.
|
|
207
|
+
*/
|
|
208
|
+
function LightBoxOverlay({ className }) {
|
|
209
|
+
const { handleRequestClose } = useLightBoxContext();
|
|
210
|
+
return (React__default.createElement("div", { className: classnames(styles.blurOverlay, className), onClick: handleRequestClose }));
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Top bar showing the current image counter (`1/3`) and a close button.
|
|
214
|
+
* Styled for dark backgrounds.
|
|
215
|
+
*/
|
|
216
|
+
function LightBoxToolbar() {
|
|
217
|
+
const { images, currentImageIndex, handleRequestClose } = useLightBoxContext();
|
|
218
|
+
return (React__default.createElement(AtlantisThemeContextProvider, { dangerouslyOverrideTheme: "dark" },
|
|
219
|
+
React__default.createElement("div", { className: styles.toolbar },
|
|
220
|
+
React__default.createElement("div", { className: styles.slideNumber },
|
|
221
|
+
React__default.createElement(Text, null, `${currentImageIndex + 1}/${images.length}`)),
|
|
222
|
+
React__default.createElement("div", { className: styles.closeButton },
|
|
223
|
+
React__default.createElement(ButtonDismiss, { ariaLabel: "Close", onClick: handleRequestClose })))));
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* The animated hero image with swipe-to-navigate and slide animation.
|
|
227
|
+
*
|
|
228
|
+
* Pass `className` to add styles to the image wrapper. Supports
|
|
229
|
+
* swipe-to-navigate (drag). Keyboard arrow navigation is handled by
|
|
230
|
+
* `LightBox.Provider`.
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```tsx
|
|
234
|
+
* <LightBox.Slides className={styles.imageArea} />
|
|
235
|
+
* <LightBox.Navigation
|
|
236
|
+
* prevButtonClassName={styles.prev}
|
|
237
|
+
* nextButtonClassName={styles.next}
|
|
238
|
+
* />
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
241
|
+
function LightBoxSlides({ className }) {
|
|
242
|
+
const { images, currentImageIndex, directionRef, handleOnDragEnd } = useLightBoxContext();
|
|
243
|
+
return (React__default.createElement("div", { className: classnames(styles.imageArea, className) },
|
|
244
|
+
React__default.createElement(AnimatePresence, { initial: false },
|
|
245
|
+
React__default.createElement(motion.img, { key: currentImageIndex, variants: slideVariants, src: images[currentImageIndex].url, custom: directionRef, className: styles.image, initial: "enter", alt: images[currentImageIndex].alt ||
|
|
246
|
+
images[currentImageIndex].title ||
|
|
247
|
+
"", animate: "center", exit: "exit", transition: imageTransition, drag: "x", dragConstraints: { left: 0, right: 0 }, dragElastic: 1, onDragEnd: handleOnDragEnd }))));
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Previous and next navigation buttons. Returns `null` when the image set
|
|
251
|
+
* has only one image.
|
|
252
|
+
*
|
|
253
|
+
* Use `prevButtonClassName` and `nextButtonClassName` to override the styles
|
|
254
|
+
* on each button's wrapper for custom layouts.
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* ```tsx
|
|
258
|
+
* <LightBox.Navigation
|
|
259
|
+
* prevButtonClassName={styles.prev}
|
|
260
|
+
* nextButtonClassName={styles.next}
|
|
261
|
+
* />
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
264
|
+
function LightBoxNavigation({ prevButtonClassName, nextButtonClassName, }) {
|
|
265
|
+
const { images, mouseIsStationary, debouncedHandleNext, debouncedHandlePrevious, } = useLightBoxContext();
|
|
266
|
+
if (images.length <= 1)
|
|
267
|
+
return null;
|
|
268
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
269
|
+
React__default.createElement(PreviousButton, { onClick: debouncedHandlePrevious, hideButton: mouseIsStationary, className: classnames(styles.prev, prevButtonClassName) }),
|
|
270
|
+
React__default.createElement(NextButton, { onClick: debouncedHandleNext, hideButton: mouseIsStationary, className: classnames(styles.next, nextButtonClassName) })));
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Title and caption text for the current image. Only renders when the current
|
|
274
|
+
* image has a `title` or `caption`. Styled for dark backgrounds.
|
|
275
|
+
*/
|
|
276
|
+
function LightBoxCaption() {
|
|
277
|
+
const { images, currentImageIndex } = useLightBoxContext();
|
|
278
|
+
const { title, caption } = images[currentImageIndex];
|
|
279
|
+
if (!title && !caption)
|
|
280
|
+
return null;
|
|
281
|
+
return (React__default.createElement("div", { className: styles.captionWrapper },
|
|
282
|
+
React__default.createElement(AtlantisThemeContextProvider, { dangerouslyOverrideTheme: "dark" },
|
|
283
|
+
title && (React__default.createElement("div", { className: styles.title },
|
|
284
|
+
React__default.createElement(Heading, { level: 4 }, title))),
|
|
285
|
+
caption && React__default.createElement(Text, { size: "large" }, caption))));
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Scrollable thumbnail strip. Only renders when there are two or more images.
|
|
289
|
+
*/
|
|
290
|
+
function LightBoxThumbnails() {
|
|
291
|
+
const { images, currentImageIndex, boxSizing, selectedThumbnailRef, handleThumbnailClick, } = useLightBoxContext();
|
|
292
|
+
if (images.length <= 1)
|
|
293
|
+
return null;
|
|
294
|
+
return (React__default.createElement("div", { className: styles.thumbnailBar, style: { "--lightbox--box-sizing": boxSizing }, "data-testid": "ATL-Thumbnail-Bar" }, images.map((image, index) => (React__default.createElement("div", { key: index, className: classnames(styles.thumbnail, {
|
|
295
|
+
[styles.selected]: index === currentImageIndex,
|
|
296
|
+
}), onClick: () => handleThumbnailClick(index), ref: index === currentImageIndex ? selectedThumbnailRef : null },
|
|
297
|
+
React__default.createElement("img", { key: index, src: image.url, alt: image.alt || image.title || "", className: styles.thumbnailImage }))))));
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* LightBox displays images in a fullscreen overlay.
|
|
301
|
+
*
|
|
302
|
+
* **Self-contained (legacy) usage:**
|
|
303
|
+
* ```tsx
|
|
304
|
+
* <LightBox
|
|
305
|
+
* open={isOpen}
|
|
306
|
+
* images={images}
|
|
307
|
+
* imageIndex={imageIndex}
|
|
308
|
+
* onRequestClose={({ lastPosition }) => { setIsOpen(false); }}
|
|
309
|
+
* />
|
|
310
|
+
* ```
|
|
311
|
+
*
|
|
312
|
+
* **Full composable (fullscreen) usage:**
|
|
313
|
+
* ```tsx
|
|
314
|
+
* <LightBox.Provider open={isOpen} images={images} onRequestClose={onClose}>
|
|
315
|
+
* <LightBox.Content />
|
|
316
|
+
* </LightBox.Provider>
|
|
317
|
+
* ```
|
|
318
|
+
*
|
|
319
|
+
* **Inline gallery usage (no overlay, no close):**
|
|
320
|
+
* ```tsx
|
|
321
|
+
* <LightBox.Provider
|
|
322
|
+
* open={true}
|
|
323
|
+
* images={images}
|
|
324
|
+
* imageIndex={activeIndex}
|
|
325
|
+
* onImageChange={onImageChange}
|
|
326
|
+
* >
|
|
327
|
+
* <div className={styles.lightboxWrapper} onMouseMove={handleMouseMove}>
|
|
328
|
+
* <LightBox.Background className={styles.backgroundImage} />
|
|
329
|
+
* <LightBox.Overlay className={styles.blurOverlay} />
|
|
330
|
+
* <LightBox.Slides className={styles.imageArea} />
|
|
331
|
+
* <LightBox.Navigation
|
|
332
|
+
* prevButtonClassName={styles.prev}
|
|
333
|
+
* nextButtonClassName={styles.next}
|
|
334
|
+
* />
|
|
335
|
+
* </div>
|
|
336
|
+
* </LightBox.Provider>
|
|
337
|
+
* ```
|
|
338
|
+
*/
|
|
339
|
+
function LightBox(props) {
|
|
340
|
+
return (React__default.createElement(LightBoxProvider, Object.assign({}, props),
|
|
341
|
+
React__default.createElement(LightBoxContent, null)));
|
|
342
|
+
}
|
|
343
|
+
LightBox.Provider = LightBoxProvider;
|
|
344
|
+
LightBox.Content = LightBoxContent;
|
|
345
|
+
LightBox.Background = LightBoxBackground;
|
|
346
|
+
LightBox.Overlay = LightBoxOverlay;
|
|
347
|
+
LightBox.Toolbar = LightBoxToolbar;
|
|
348
|
+
LightBox.Slides = LightBoxSlides;
|
|
349
|
+
LightBox.Navigation = LightBoxNavigation;
|
|
350
|
+
LightBox.Caption = LightBoxCaption;
|
|
351
|
+
LightBox.Thumbnails = LightBoxThumbnails;
|
|
352
|
+
|
|
353
|
+
export { LightBox as L, useLightBoxContext as u };
|
package/dist/index.cjs
CHANGED
|
@@ -293,6 +293,7 @@ exports.InputText = InputText_index.InputText;
|
|
|
293
293
|
exports.InputTime = InputTime_index.InputTime;
|
|
294
294
|
exports.InputValidation = InputValidation.InputValidation;
|
|
295
295
|
exports.LightBox = LightBox.LightBox;
|
|
296
|
+
exports.useLightBoxContext = LightBox.useLightBoxContext;
|
|
296
297
|
exports.Link = Link.Link;
|
|
297
298
|
exports.List = List.List;
|
|
298
299
|
exports.ListItem = List.ListItem;
|
package/dist/index.mjs
CHANGED
|
@@ -63,7 +63,7 @@ export { InputPhoneNumber } from './InputPhoneNumber/index.mjs';
|
|
|
63
63
|
export { InputText } from './InputText/index.mjs';
|
|
64
64
|
export { InputTime } from './InputTime/index.mjs';
|
|
65
65
|
export { I as InputValidation } from './InputValidation-es.js';
|
|
66
|
-
export { L as LightBox } from './LightBox-es.js';
|
|
66
|
+
export { L as LightBox, u as useLightBoxContext } from './LightBox-es.js';
|
|
67
67
|
export { L as Link } from './Link-es.js';
|
|
68
68
|
export { L as List, a as ListItem } from './List-es.js';
|
|
69
69
|
export { M as Markdown } from './Markdown-es.js';
|
|
@@ -135,6 +135,15 @@
|
|
|
135
135
|
"InputTime",
|
|
136
136
|
"InputValidation",
|
|
137
137
|
"LightBox",
|
|
138
|
+
"LightBox.Background",
|
|
139
|
+
"LightBox.Caption",
|
|
140
|
+
"LightBox.Content",
|
|
141
|
+
"LightBox.Navigation",
|
|
142
|
+
"LightBox.Overlay",
|
|
143
|
+
"LightBox.Provider",
|
|
144
|
+
"LightBox.Slides",
|
|
145
|
+
"LightBox.Thumbnails",
|
|
146
|
+
"LightBox.Toolbar",
|
|
138
147
|
"Link",
|
|
139
148
|
"List",
|
|
140
149
|
"ListItem",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.114.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -538,5 +538,5 @@
|
|
|
538
538
|
"> 1%",
|
|
539
539
|
"IE 10"
|
|
540
540
|
],
|
|
541
|
-
"gitHead": "
|
|
541
|
+
"gitHead": "fa776129b22e49b376813fafbbfdfe3d48ea88e4"
|
|
542
542
|
}
|