@uxf/ui 11.70.0 → 11.71.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/button-list/button-list.d.ts +5 -2
- package/button-list/button-list.js +4 -5
- package/button-list/button-list.stories.js +2 -1
- package/components.d.ts +5 -0
- package/components.js +5 -0
- package/css/button-list.css +6 -0
- package/css/lightbox.css +103 -0
- package/dropzone/dropzone-input.d.ts +3 -4
- package/image-gallery/README.md +3 -1
- package/image-gallery/components/gallery.js +2 -2
- package/image-gallery/image-gallery.d.ts +3 -0
- package/image-gallery/image-gallery.js +3 -0
- package/lightbox/README.md +170 -0
- package/lightbox/components/lightbox-close-button.d.ts +6 -0
- package/lightbox/components/lightbox-close-button.js +14 -0
- package/lightbox/components/lightbox-dialog.d.ts +15 -0
- package/lightbox/components/lightbox-dialog.js +49 -0
- package/lightbox/components/lightbox-dot.d.ts +9 -0
- package/lightbox/components/lightbox-dot.js +13 -0
- package/lightbox/components/lightbox-next-button.d.ts +6 -0
- package/lightbox/components/lightbox-next-button.js +14 -0
- package/lightbox/components/lightbox-prev-button.d.ts +6 -0
- package/lightbox/components/lightbox-prev-button.js +14 -0
- package/lightbox/components/use-lightbox-dialog.d.ts +34 -0
- package/lightbox/components/use-lightbox-dialog.js +51 -0
- package/lightbox/context.d.ts +11 -0
- package/lightbox/context.js +17 -0
- package/lightbox/index.d.ts +4 -0
- package/lightbox/index.js +9 -0
- package/lightbox/lightbox.d.ts +14 -0
- package/lightbox/lightbox.js +27 -0
- package/lightbox/lightbox.spec.d.ts +1 -0
- package/lightbox/lightbox.spec.js +9 -0
- package/lightbox/lightbox.stories.d.ts +2 -0
- package/lightbox/lightbox.stories.js +43 -0
- package/lightbox/types.d.ts +20 -0
- package/lightbox/types.js +2 -0
- package/lightbox/use-lightbox-image.d.ts +2 -0
- package/lightbox/use-lightbox-image.js +17 -0
- package/lightbox/use-lightbox.d.ts +11 -0
- package/lightbox/use-lightbox.js +34 -0
- package/package.json +3 -4
- package/readmes.d.ts +1 -0
- package/readmes.js +50 -48
- package/tw-tokens/tw-z-index.d.ts +1 -0
- package/tw-tokens/tw-z-index.js +1 -0
- package/utils/tailwind-config.js +2 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Placement, Strategy } from "@floating-ui/react";
|
|
2
|
-
import {
|
|
2
|
+
import { JSX, ReactNode } from "react";
|
|
3
3
|
import { ButtonProps } from "../button";
|
|
4
4
|
import { IconName } from "../icon/types";
|
|
5
5
|
export type SingleButtonProps = Omit<ButtonProps, "children"> & {
|
|
@@ -19,4 +19,7 @@ export interface ButtonListProps {
|
|
|
19
19
|
menuPlacement?: Placement;
|
|
20
20
|
menuStrategy?: Strategy;
|
|
21
21
|
}
|
|
22
|
-
export declare
|
|
22
|
+
export declare function ButtonList(props: ButtonListProps): JSX.Element | null;
|
|
23
|
+
export declare namespace ButtonList {
|
|
24
|
+
var displayName: string;
|
|
25
|
+
}
|
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.ButtonList =
|
|
26
|
+
exports.ButtonList = ButtonList;
|
|
27
27
|
const react_1 = require("@floating-ui/react");
|
|
28
28
|
const react_2 = require("@headlessui/react");
|
|
29
29
|
const use_anchor_props_1 = require("@uxf/core-react/clickable/use-anchor-props");
|
|
@@ -47,7 +47,7 @@ const MenuButton = (0, react_3.forwardRef)((props, ref) => {
|
|
|
47
47
|
label && react_3.default.createElement("span", { className: "uxf-button-list__menu-button-label" }, label)));
|
|
48
48
|
});
|
|
49
49
|
MenuButton.displayName = "MenuButton";
|
|
50
|
-
|
|
50
|
+
function ButtonList(props) {
|
|
51
51
|
var _a, _b, _c, _d, _e, _f;
|
|
52
52
|
const buttonsToRender = props.buttons.slice(0, props.visibleButtonsCount);
|
|
53
53
|
const restButtons = props.buttons.slice(props.visibleButtonsCount, props.buttons.length);
|
|
@@ -80,6 +80,5 @@ const ButtonList = (props) => {
|
|
|
80
80
|
react_3.default.createElement(MenuButton, { ...button, color: (_a = button.color) !== null && _a !== void 0 ? _a : props.color, size: (_b = button.size) !== null && _b !== void 0 ? _b : props.size, variant: (_c = button.variant) !== null && _c !== void 0 ? _c : props.variant })));
|
|
81
81
|
}))))));
|
|
82
82
|
}))));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
exports.ButtonList.displayName = "UxfUiButtonList";
|
|
83
|
+
}
|
|
84
|
+
ButtonList.displayName = "UxfUiButtonList";
|
|
@@ -29,13 +29,14 @@ function Default() {
|
|
|
29
29
|
{ label: "Fourth item" },
|
|
30
30
|
], variant: "secondary", visibleButtonsCount: 4 }),
|
|
31
31
|
react_1.default.createElement(index_1.ButtonList, { buttons: [
|
|
32
|
+
{ label: "IconButton", isIconButton: true, icon: "camera" },
|
|
32
33
|
// eslint-disable-next-line no-console
|
|
33
34
|
{ label: "First item", onClick: console.log },
|
|
34
35
|
{ label: "Second item", color: "positive" },
|
|
35
36
|
{ label: "Third item" },
|
|
36
37
|
// eslint-disable-next-line no-console
|
|
37
38
|
{ label: "Fourth item", onClick: console.log },
|
|
38
|
-
], visibleButtonsCount:
|
|
39
|
+
], visibleButtonsCount: 3 }),
|
|
39
40
|
react_1.default.createElement(index_1.ButtonList, { buttons: [
|
|
40
41
|
// eslint-disable-next-line no-console
|
|
41
42
|
{ icon: "check", label: "First item", onClick: console.log },
|
package/components.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ import * as infoBoxStories from "./info-box/info-box.stories";
|
|
|
36
36
|
import * as inputStories from "./input/input.stories";
|
|
37
37
|
import * as labelStories from "./label/label.stories";
|
|
38
38
|
import * as layoutStories from "./layout/layout.stories";
|
|
39
|
+
import * as lightboxStories from "./lightbox/lightbox.stories";
|
|
39
40
|
import * as listItemStories from "./list-item/list-item.stories";
|
|
40
41
|
import * as loaderStories from "./loader/loader.stories";
|
|
41
42
|
import * as lozengeStories from "./lozenge/lozenge.stories";
|
|
@@ -213,6 +214,10 @@ export declare const components: {
|
|
|
213
214
|
readonly title: "Layout";
|
|
214
215
|
readonly stories: typeof layoutStories;
|
|
215
216
|
};
|
|
217
|
+
readonly lightbox: {
|
|
218
|
+
readonly title: "Lightbox";
|
|
219
|
+
readonly stories: typeof lightboxStories;
|
|
220
|
+
};
|
|
216
221
|
readonly "list-item": {
|
|
217
222
|
readonly title: "ListItem";
|
|
218
223
|
readonly stories: typeof listItemStories;
|
package/components.js
CHANGED
|
@@ -63,6 +63,7 @@ const infoBoxStories = __importStar(require("./info-box/info-box.stories"));
|
|
|
63
63
|
const inputStories = __importStar(require("./input/input.stories"));
|
|
64
64
|
const labelStories = __importStar(require("./label/label.stories"));
|
|
65
65
|
const layoutStories = __importStar(require("./layout/layout.stories"));
|
|
66
|
+
const lightboxStories = __importStar(require("./lightbox/lightbox.stories"));
|
|
66
67
|
const listItemStories = __importStar(require("./list-item/list-item.stories"));
|
|
67
68
|
const loaderStories = __importStar(require("./loader/loader.stories"));
|
|
68
69
|
const lozengeStories = __importStar(require("./lozenge/lozenge.stories"));
|
|
@@ -240,6 +241,10 @@ exports.components = {
|
|
|
240
241
|
title: "Layout",
|
|
241
242
|
stories: layoutStories
|
|
242
243
|
},
|
|
244
|
+
"lightbox": {
|
|
245
|
+
title: "Lightbox",
|
|
246
|
+
stories: lightboxStories
|
|
247
|
+
},
|
|
243
248
|
"list-item": {
|
|
244
249
|
title: "ListItem",
|
|
245
250
|
stories: listItemStories
|
package/css/button-list.css
CHANGED
package/css/lightbox.css
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
.uxf-lightbox {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
inset: 0;
|
|
5
|
+
position: fixed;
|
|
6
|
+
z-index: theme("zIndex.lightbox");
|
|
7
|
+
|
|
8
|
+
&__content {
|
|
9
|
+
flex-grow: 1;
|
|
10
|
+
margin: 0 auto;
|
|
11
|
+
max-height: calc(100% - 128px);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&__inner {
|
|
15
|
+
align-items: center;
|
|
16
|
+
display: flex;
|
|
17
|
+
height: 100%;
|
|
18
|
+
justify-content: center;
|
|
19
|
+
|
|
20
|
+
@apply container;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&__image {
|
|
24
|
+
object-fit: contain;
|
|
25
|
+
width: 100%;
|
|
26
|
+
z-index: 1;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&__buttons {
|
|
30
|
+
align-items: center;
|
|
31
|
+
display: flex;
|
|
32
|
+
inset: 0;
|
|
33
|
+
justify-content: space-between;
|
|
34
|
+
padding: 8px;
|
|
35
|
+
pointer-events: none;
|
|
36
|
+
position: absolute;
|
|
37
|
+
z-index: 10;
|
|
38
|
+
|
|
39
|
+
@apply container;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&__button {
|
|
43
|
+
background-color: rgb(0 0 0 / 50%);
|
|
44
|
+
border-radius: 9999px;
|
|
45
|
+
padding: 12px;
|
|
46
|
+
pointer-events: auto;
|
|
47
|
+
|
|
48
|
+
&-icon {
|
|
49
|
+
color: white;
|
|
50
|
+
height: 32px;
|
|
51
|
+
width: 32px;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&__dots {
|
|
56
|
+
align-items: center;
|
|
57
|
+
column-gap: 8px;
|
|
58
|
+
display: flex;
|
|
59
|
+
height: 64px;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
padding: 16px;
|
|
62
|
+
z-index: 1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
&__dot {
|
|
66
|
+
background-color: theme("colors.gray.500");
|
|
67
|
+
border-radius: 9999px;
|
|
68
|
+
height: 8px;
|
|
69
|
+
width: 8px;
|
|
70
|
+
|
|
71
|
+
&--active {
|
|
72
|
+
background-color: white;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
&__close-button {
|
|
77
|
+
background-color: rgb(0 0 0 / 50%);
|
|
78
|
+
padding: 20px;
|
|
79
|
+
position: absolute;
|
|
80
|
+
right: 0;
|
|
81
|
+
top: 0;
|
|
82
|
+
|
|
83
|
+
&-icon {
|
|
84
|
+
color: white;
|
|
85
|
+
height: 24px;
|
|
86
|
+
width: 24px;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
&__custom-content {
|
|
91
|
+
background-color: rgb(0 0 0 / 75%);
|
|
92
|
+
bottom: 0;
|
|
93
|
+
color: white;
|
|
94
|
+
position: absolute;
|
|
95
|
+
right: 0;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
&__backdrop {
|
|
99
|
+
background-color: rgb(0 0 0 / 75%);
|
|
100
|
+
inset: 0;
|
|
101
|
+
position: absolute;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { FileResponse } from "@uxf/core/types";
|
|
2
|
-
import { FormControlProps
|
|
1
|
+
import { FileResponse, FileUploadProps } from "@uxf/core/types";
|
|
2
|
+
import { FormControlProps } from "@uxf/ui/types";
|
|
3
3
|
import React, { CSSProperties, ReactNode } from "react";
|
|
4
4
|
import { FileRejection } from "react-dropzone";
|
|
5
5
|
import { IconName } from "../icon/types";
|
|
6
6
|
import { Accept, DropzoneFile } from "./types";
|
|
7
|
-
export interface DropzoneInputProps extends FormControlProps<DropzoneFile[] | undefined
|
|
7
|
+
export interface DropzoneInputProps extends FormControlProps<DropzoneFile[] | undefined>, FileUploadProps {
|
|
8
8
|
accept?: Accept;
|
|
9
9
|
className?: string;
|
|
10
10
|
helperText?: ReactNode;
|
|
@@ -19,7 +19,6 @@ export interface DropzoneInputProps extends FormControlProps<DropzoneFile[] | un
|
|
|
19
19
|
onDropRejected?: (fileRejections: FileRejection[]) => void;
|
|
20
20
|
onUploadComplete?: (files: FileResponse[]) => Promise<void>;
|
|
21
21
|
onUploadError?: (err: unknown) => void;
|
|
22
|
-
onUploadFile: (file: File, options?: UploadOptions) => Promise<FileResponse>;
|
|
23
22
|
style?: CSSProperties;
|
|
24
23
|
}
|
|
25
24
|
export declare const DropzoneInput: React.ForwardRefExoticComponent<DropzoneInputProps & React.RefAttributes<HTMLDivElement>>;
|
package/image-gallery/README.md
CHANGED
|
@@ -24,10 +24,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.Gallery = void 0;
|
|
27
|
+
const use_swipeable_1 = require("@uxf/core-react/swipeable/use-swipeable");
|
|
27
28
|
const image_1 = require("@uxf/core/utils/image");
|
|
28
29
|
const resizer_1 = require("@uxf/core/utils/resizer");
|
|
29
30
|
const react_1 = __importStar(require("react"));
|
|
30
|
-
const react_swipeable_1 = require("react-swipeable");
|
|
31
31
|
const close_button_1 = require("./close-button");
|
|
32
32
|
const dot_1 = require("./dot");
|
|
33
33
|
const next_button_1 = require("./next-button");
|
|
@@ -58,7 +58,7 @@ const Gallery = (props) => {
|
|
|
58
58
|
}, []);
|
|
59
59
|
const imageSrc = props.images[props.imageIndex].src;
|
|
60
60
|
const customContent = props.images[props.imageIndex].customContent;
|
|
61
|
-
const handlers = (0,
|
|
61
|
+
const handlers = (0, use_swipeable_1.useSwipeable)({
|
|
62
62
|
onSwipedLeft: () => props.onNext(),
|
|
63
63
|
onSwipedRight: () => props.onPrevious(),
|
|
64
64
|
swipeDuration: 500,
|
|
@@ -28,6 +28,9 @@ exports.ImageGallery = void 0;
|
|
|
28
28
|
const react_1 = __importStar(require("react"));
|
|
29
29
|
const gallery_1 = require("./components/gallery");
|
|
30
30
|
const context_1 = require("./context");
|
|
31
|
+
/**
|
|
32
|
+
* @deprecated use `Lightbox` instead
|
|
33
|
+
*/
|
|
31
34
|
const ImageGallery = (props) => {
|
|
32
35
|
const [images, setImages] = (0, react_1.useState)([]);
|
|
33
36
|
const [imageIndex, setImageIndex] = (0, react_1.useState)(null);
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Lightbox
|
|
2
|
+
|
|
3
|
+
Lightbox is a component that displays images in a modal dialog with navigation controls. It allows users to view images in a larger size and navigate through a collection of images.
|
|
4
|
+
|
|
5
|
+
## CSS dependencies
|
|
6
|
+
|
|
7
|
+
```css
|
|
8
|
+
@import url("@uxf/ui/css/icon.css");
|
|
9
|
+
@import url("@uxf/ui/css/lightbox.css");
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Basic Usage
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import { Lightbox, useLightboxImage } from "@uxf/ui/lightbox";
|
|
16
|
+
|
|
17
|
+
function ImageGallery() {
|
|
18
|
+
const images = [
|
|
19
|
+
{ src: "image1.jpg", title: "Image 1" },
|
|
20
|
+
{ src: "image2.jpg", title: "Image 2" },
|
|
21
|
+
{ src: "image3.jpg", title: "Image 3" },
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Lightbox>
|
|
26
|
+
<div className="flex gap-2">
|
|
27
|
+
{images.map((image) => (
|
|
28
|
+
<GalleryImage
|
|
29
|
+
key={image.src}
|
|
30
|
+
src={image.src}
|
|
31
|
+
title={image.title}
|
|
32
|
+
/>
|
|
33
|
+
))}
|
|
34
|
+
</div>
|
|
35
|
+
</Lightbox>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function GalleryImage(props: { src: string; title: string }) {
|
|
40
|
+
// useLightboxImage hook registers the image with the Lightbox context
|
|
41
|
+
const openLightbox = useLightboxImage({
|
|
42
|
+
src: props.src,
|
|
43
|
+
title: props.title,
|
|
44
|
+
// Optional custom content to display with the image
|
|
45
|
+
customContent: <div>Custom description for {props.title}</div>,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<img
|
|
50
|
+
src={props.src}
|
|
51
|
+
alt={props.title}
|
|
52
|
+
className="cursor-pointer"
|
|
53
|
+
onClick={openLightbox}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Custom Buttons
|
|
60
|
+
|
|
61
|
+
You can customize the navigation buttons by providing your own components:
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import { Lightbox, type LightboxButtonProps } from "@uxf/ui/lightbox";
|
|
65
|
+
|
|
66
|
+
function CustomCloseButton(props: LightboxButtonProps) {
|
|
67
|
+
return (
|
|
68
|
+
<button
|
|
69
|
+
className="my-custom-close-button"
|
|
70
|
+
onClick={props.onClick}
|
|
71
|
+
>
|
|
72
|
+
Close
|
|
73
|
+
</button>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function CustomNextButton(props: LightboxButtonProps) {
|
|
78
|
+
return (
|
|
79
|
+
<button
|
|
80
|
+
className="my-custom-next-button"
|
|
81
|
+
onClick={props.onClick}
|
|
82
|
+
>
|
|
83
|
+
Next →
|
|
84
|
+
</button>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function CustomPrevButton(props: LightboxButtonProps) {
|
|
89
|
+
return (
|
|
90
|
+
<button
|
|
91
|
+
className="my-custom-prev-button"
|
|
92
|
+
onClick={props.onClick}
|
|
93
|
+
>
|
|
94
|
+
← Prev
|
|
95
|
+
</button>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function CustomLightbox() {
|
|
100
|
+
return (
|
|
101
|
+
<Lightbox
|
|
102
|
+
CloseButtonElement={CustomCloseButton}
|
|
103
|
+
NextButtonElement={CustomNextButton}
|
|
104
|
+
PrevButtonElement={CustomPrevButton}
|
|
105
|
+
>
|
|
106
|
+
{/* Your gallery content */}
|
|
107
|
+
</Lightbox>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Custom Dialog
|
|
113
|
+
|
|
114
|
+
For complete customization, you can provide your own dialog component:
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
import {Lightbox, type LightboxCustomDialogProps} from "@uxf/ui/lightbox";
|
|
118
|
+
import {useLightboxDialog} from "@uxf/ui/lightbox/components/use-lightbox-dialog";
|
|
119
|
+
|
|
120
|
+
function CustomLightboxDialog(props: LightboxCustomDialogProps) {
|
|
121
|
+
const { imageSrc, imageCustomContent, swipableHandlers } = useLightboxDialog({
|
|
122
|
+
imageIndex: props.imageIndex,
|
|
123
|
+
images: props.images,
|
|
124
|
+
onClose: props.onClose,
|
|
125
|
+
onNext: props.onNext,
|
|
126
|
+
onPrev: props.onPrev,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<div className="my-custom-lightbox-dialog">
|
|
131
|
+
<button onClick={props.onClose}>Close</button>
|
|
132
|
+
|
|
133
|
+
<div className="image-container">
|
|
134
|
+
<img src={currentImage.src} alt={currentImage.title}/>
|
|
135
|
+
{currentImage.customContent && (
|
|
136
|
+
<div className="custom-content">
|
|
137
|
+
{currentImage.customContent}
|
|
138
|
+
</div>
|
|
139
|
+
)}
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<div className="navigation">
|
|
143
|
+
<button onClick={props.onPrev}>Previous</button>
|
|
144
|
+
<button onClick={props.onNext}>Next</button>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function CustomDialogLightbox() {
|
|
151
|
+
return (
|
|
152
|
+
<Lightbox DialogElement={CustomLightboxDialog}>
|
|
153
|
+
{/* Your gallery content */}
|
|
154
|
+
</Lightbox>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Props
|
|
160
|
+
|
|
161
|
+
### Lightbox Props
|
|
162
|
+
|
|
163
|
+
| Prop | Type | Description |
|
|
164
|
+
|------|------|-------------|
|
|
165
|
+
| `children` | ReactNode | Content to be rendered inside the Lightbox |
|
|
166
|
+
| `CloseButtonElement` | `FC<LightboxButtonProps>` | Custom close button component |
|
|
167
|
+
| `NextButtonElement` | `FC<LightboxButtonProps>` | Custom next button component |
|
|
168
|
+
| `PrevButtonElement` | `FC<LightboxButtonProps>` | Custom previous button component |
|
|
169
|
+
| `DialogElement` | `FC<LightboxCustomDialogProps>` | Custom dialog component |
|
|
170
|
+
| `isBackdropCloseDisabled` | `boolean` | Disables closing the lightbox when clicking on the backdrop |
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.LightboxCloseButton = LightboxCloseButton;
|
|
8
|
+
const icon_1 = require("@uxf/ui/icon");
|
|
9
|
+
const react_1 = __importDefault(require("react"));
|
|
10
|
+
function LightboxCloseButton(props) {
|
|
11
|
+
return (react_1.default.createElement("button", { className: "uxf-lightbox__close-button", onClick: props.onClick, title: "Zav\u0159\u00EDt" },
|
|
12
|
+
react_1.default.createElement(icon_1.Icon, { className: "uxf-lightbox__close-button-icon", name: "xmarkLarge" })));
|
|
13
|
+
}
|
|
14
|
+
LightboxCloseButton.displayName = "UxfUiLightboxCloseButton";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Noop } from "@uxf/core/types";
|
|
2
|
+
import React, { type FC } from "react";
|
|
3
|
+
import { type LightboxButtonProps, LightboxImageProps } from "../types";
|
|
4
|
+
export interface LightboxDialogProps {
|
|
5
|
+
CloseButtonElement?: FC<LightboxButtonProps>;
|
|
6
|
+
NextButtonElement?: FC<LightboxButtonProps>;
|
|
7
|
+
PrevButtonElement?: FC<LightboxButtonProps>;
|
|
8
|
+
imageIndex: number;
|
|
9
|
+
images: LightboxImageProps[];
|
|
10
|
+
isBackdropCloseDisabled?: boolean;
|
|
11
|
+
onClose: Noop;
|
|
12
|
+
onNext: Noop;
|
|
13
|
+
onPrev: Noop;
|
|
14
|
+
}
|
|
15
|
+
export declare function LightboxDialog(props: LightboxDialogProps): React.JSX.Element | null;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.LightboxDialog = LightboxDialog;
|
|
8
|
+
const react_1 = require("@floating-ui/react");
|
|
9
|
+
const show_1 = require("@uxf/core-react/components/show");
|
|
10
|
+
const image_1 = require("@uxf/core/utils/image");
|
|
11
|
+
const is_nil_1 = require("@uxf/core/utils/is-nil");
|
|
12
|
+
const is_not_nil_1 = require("@uxf/core/utils/is-not-nil");
|
|
13
|
+
const raster_image_1 = require("@uxf/ui/raster-image");
|
|
14
|
+
const react_2 = __importDefault(require("react"));
|
|
15
|
+
const lightbox_close_button_1 = require("./lightbox-close-button");
|
|
16
|
+
const lightbox_dot_1 = require("./lightbox-dot");
|
|
17
|
+
const lightbox_next_button_1 = require("./lightbox-next-button");
|
|
18
|
+
const lightbox_prev_button_1 = require("./lightbox-prev-button");
|
|
19
|
+
const use_lightbox_dialog_1 = require("./use-lightbox-dialog");
|
|
20
|
+
function LightboxDialog(props) {
|
|
21
|
+
var _a, _b;
|
|
22
|
+
const { imageCustomContent, imageSrc, swipableHandlers, getFloatingProps, setFloating, floatingContext } = (0, use_lightbox_dialog_1.useLightboxDialog)({
|
|
23
|
+
images: props.images,
|
|
24
|
+
imageIndex: props.imageIndex,
|
|
25
|
+
onClose: props.onClose,
|
|
26
|
+
onNext: props.onNext,
|
|
27
|
+
onPrev: props.onPrev,
|
|
28
|
+
});
|
|
29
|
+
if ((0, is_nil_1.isNil)(imageSrc)) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return (react_2.default.createElement(react_1.FloatingPortal, null,
|
|
33
|
+
react_2.default.createElement(react_1.FloatingOverlay, { lockScroll: true },
|
|
34
|
+
react_2.default.createElement(react_1.FloatingFocusManager, { context: floatingContext },
|
|
35
|
+
react_2.default.createElement("div", { ...getFloatingProps({ "aria-modal": true, className: "uxf-lightbox", ref: setFloating }) },
|
|
36
|
+
react_2.default.createElement("div", { "aria-hidden": true, className: "uxf-lightbox__backdrop", onClick: !props.isBackdropCloseDisabled ? props.onClose : undefined }),
|
|
37
|
+
(0, is_not_nil_1.isNotNil)(props.CloseButtonElement) ? (react_2.default.createElement(props.CloseButtonElement, { onClick: props.onClose })) : (react_2.default.createElement(lightbox_close_button_1.LightboxCloseButton, { onClick: props.onClose })),
|
|
38
|
+
props.images.length > 1 && (react_2.default.createElement("div", { className: "uxf-lightbox__buttons" },
|
|
39
|
+
(0, is_not_nil_1.isNotNil)(props.PrevButtonElement) ? (react_2.default.createElement(props.PrevButtonElement, { onClick: props.onPrev })) : (react_2.default.createElement(lightbox_prev_button_1.LightboxPrevButton, { onClick: props.onPrev })),
|
|
40
|
+
(0, is_not_nil_1.isNotNil)(props.NextButtonElement) ? (react_2.default.createElement(props.NextButtonElement, { onClick: props.onNext })) : (react_2.default.createElement(lightbox_next_button_1.LightboxNextButton, { onClick: props.onNext })))),
|
|
41
|
+
react_2.default.createElement("div", { className: "uxf-lightbox__content", ...swipableHandlers },
|
|
42
|
+
react_2.default.createElement("div", { className: "uxf-lightbox__inner" },
|
|
43
|
+
react_2.default.createElement(raster_image_1.RasterImage, { alt: "", className: "uxf-lightbox__image", height: typeof imageSrc !== "string" && "height" in imageSrc
|
|
44
|
+
? ((_a = imageSrc.height) !== null && _a !== void 0 ? _a : 0)
|
|
45
|
+
: 0, key: (0, image_1.getImgUniqueIdentifier)(imageSrc), src: imageSrc, width: typeof imageSrc !== "string" && "width" in imageSrc ? ((_b = imageSrc.width) !== null && _b !== void 0 ? _b : 0) : 0 }),
|
|
46
|
+
react_2.default.createElement(show_1.Show, { when: (0, is_not_nil_1.isNotNil)(imageCustomContent) },
|
|
47
|
+
react_2.default.createElement("div", { className: "uxf-lightbox__custom-content" }, imageCustomContent))),
|
|
48
|
+
props.images.length > 1 && (react_2.default.createElement("div", { className: "uxf-lightbox__dots" }, props.images.map((img, index) => (react_2.default.createElement(lightbox_dot_1.LightboxDot, { isActive: index === props.imageIndex, key: (0, image_1.getImgUniqueIdentifier)(img.src) || index })))))))))));
|
|
49
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LightboxDot = LightboxDot;
|
|
7
|
+
const cx_1 = require("@uxf/core/utils/cx");
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
function LightboxDot(props) {
|
|
10
|
+
const className = (0, cx_1.cx)("uxf-lightbox__dot", props.isActive && "uxf-lightbox__dot--active");
|
|
11
|
+
return react_1.default.createElement("div", { className: className });
|
|
12
|
+
}
|
|
13
|
+
LightboxDot.displayName = "UxfUiLightboxDot";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.LightboxNextButton = LightboxNextButton;
|
|
8
|
+
const icon_1 = require("@uxf/ui/icon");
|
|
9
|
+
const react_1 = __importDefault(require("react"));
|
|
10
|
+
function LightboxNextButton(props) {
|
|
11
|
+
return (react_1.default.createElement("button", { className: "uxf-lightbox__button uxf-lightbox__button--next", onClick: props.onClick, title: "Dal\u0161\u00ED" },
|
|
12
|
+
react_1.default.createElement(icon_1.Icon, { className: "uxf-lightbox__button-icon", name: "chevronRight" })));
|
|
13
|
+
}
|
|
14
|
+
LightboxNextButton.displayName = "UxfUiLightboxNextButton";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.LightboxPrevButton = LightboxPrevButton;
|
|
8
|
+
const icon_1 = require("@uxf/ui/icon");
|
|
9
|
+
const react_1 = __importDefault(require("react"));
|
|
10
|
+
function LightboxPrevButton(props) {
|
|
11
|
+
return (react_1.default.createElement("button", { className: "uxf-lightbox__button uxf-lightbox__button--prev", onClick: props.onClick, title: "P\u0159edchoz\u00ED" },
|
|
12
|
+
react_1.default.createElement(icon_1.Icon, { className: "uxf-lightbox__button-icon", name: "chevronLeft" })));
|
|
13
|
+
}
|
|
14
|
+
LightboxPrevButton.displayName = "UxfUiLightboxPrevButton";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Noop } from "@uxf/core/types";
|
|
2
|
+
import { LightboxImageProps } from "../types";
|
|
3
|
+
export interface UseLightboxDialogProps {
|
|
4
|
+
imageIndex: number;
|
|
5
|
+
images: LightboxImageProps[];
|
|
6
|
+
onClose: Noop;
|
|
7
|
+
onNext: Noop;
|
|
8
|
+
onPrev: Noop;
|
|
9
|
+
}
|
|
10
|
+
export declare function useLightboxDialog(props: UseLightboxDialogProps): {
|
|
11
|
+
floatingContext: {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
placement: import("@floating-ui/utils").Placement;
|
|
15
|
+
strategy: import("@floating-ui/utils").Strategy;
|
|
16
|
+
middlewareData: import("@floating-ui/core").MiddlewareData;
|
|
17
|
+
isPositioned: boolean;
|
|
18
|
+
update: () => void;
|
|
19
|
+
floatingStyles: React.CSSProperties;
|
|
20
|
+
open: boolean;
|
|
21
|
+
onOpenChange: (open: boolean, event?: Event, reason?: import("@floating-ui/react").OpenChangeReason) => void;
|
|
22
|
+
events: import("@floating-ui/react").FloatingEvents;
|
|
23
|
+
dataRef: React.MutableRefObject<import("@floating-ui/react").ContextData>;
|
|
24
|
+
nodeId: string | undefined;
|
|
25
|
+
floatingId: string;
|
|
26
|
+
refs: import("@floating-ui/react").ExtendedRefs<import("@floating-ui/react").ReferenceType>;
|
|
27
|
+
elements: import("@floating-ui/react").ExtendedElements<import("@floating-ui/react").ReferenceType>;
|
|
28
|
+
};
|
|
29
|
+
getFloatingProps: (userProps?: React.HTMLProps<HTMLElement>) => Record<string, unknown>;
|
|
30
|
+
imageCustomContent: import("react").ReactNode;
|
|
31
|
+
imageSrc: import("@uxf/core/utils/resizer").ImageSource | undefined;
|
|
32
|
+
setFloating: ((node: HTMLElement | null) => void) & ((node: HTMLElement | null) => void);
|
|
33
|
+
swipableHandlers: import("@uxf/core-react/swipeable/types").SwipeableHandlers;
|
|
34
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useLightboxDialog = useLightboxDialog;
|
|
5
|
+
const react_1 = require("@floating-ui/react");
|
|
6
|
+
const use_on_mount_1 = require("@uxf/core-react/hooks/use-on-mount");
|
|
7
|
+
const use_swipeable_1 = require("@uxf/core-react/swipeable/use-swipeable");
|
|
8
|
+
function useLightboxDialog(props) {
|
|
9
|
+
const { refs, context } = (0, react_1.useFloating)();
|
|
10
|
+
const click = (0, react_1.useClick)(context);
|
|
11
|
+
const role = (0, react_1.useRole)(context);
|
|
12
|
+
const dismiss = (0, react_1.useDismiss)(context, { outsidePressEvent: "mousedown" });
|
|
13
|
+
const { getFloatingProps } = (0, react_1.useInteractions)([click, role, dismiss]);
|
|
14
|
+
(0, use_on_mount_1.useOnMount)(() => {
|
|
15
|
+
const onKeyDown = (event) => {
|
|
16
|
+
switch (event.key) {
|
|
17
|
+
case "ArrowRight":
|
|
18
|
+
props.onNext();
|
|
19
|
+
break;
|
|
20
|
+
case "ArrowLeft":
|
|
21
|
+
props.onPrev();
|
|
22
|
+
break;
|
|
23
|
+
case "Escape":
|
|
24
|
+
props.onClose();
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
document.body.style.overflow = "hidden";
|
|
29
|
+
window.addEventListener("keydown", onKeyDown);
|
|
30
|
+
return () => {
|
|
31
|
+
document.body.style.overflow = "auto";
|
|
32
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
const image = props.images.at(props.imageIndex);
|
|
36
|
+
const imageSrc = image === null || image === void 0 ? void 0 : image.src;
|
|
37
|
+
const imageCustomContent = image === null || image === void 0 ? void 0 : image.customContent;
|
|
38
|
+
const swipableHandlers = (0, use_swipeable_1.useSwipeable)({
|
|
39
|
+
onSwipedLeft: () => props.onNext(),
|
|
40
|
+
onSwipedRight: () => props.onPrev(),
|
|
41
|
+
swipeDuration: 500,
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
floatingContext: context,
|
|
45
|
+
getFloatingProps,
|
|
46
|
+
imageCustomContent,
|
|
47
|
+
imageSrc,
|
|
48
|
+
setFloating: refs.setFloating,
|
|
49
|
+
swipableHandlers,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LightboxImageProps } from "./types";
|
|
2
|
+
type ContextType = {
|
|
3
|
+
registerImage: (props: LightboxImageProps) => void;
|
|
4
|
+
unregisterImage: (props: LightboxImageProps) => void;
|
|
5
|
+
openLightbox: (props: LightboxImageProps) => void;
|
|
6
|
+
images: LightboxImageProps[];
|
|
7
|
+
currentImageIndex: number | null;
|
|
8
|
+
};
|
|
9
|
+
export declare const LightboxProvider: import("react").Provider<ContextType>;
|
|
10
|
+
export declare const useLightboxContext: () => ContextType;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useLightboxContext = exports.LightboxProvider = void 0;
|
|
5
|
+
const empty_array_1 = require("@uxf/core/constants/empty-array");
|
|
6
|
+
const noop_1 = require("@uxf/core/utils/noop");
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const LightboxContext = (0, react_1.createContext)({
|
|
9
|
+
registerImage: noop_1.noop,
|
|
10
|
+
unregisterImage: noop_1.noop,
|
|
11
|
+
openLightbox: noop_1.noop,
|
|
12
|
+
images: empty_array_1.EMPTY_ARRAY,
|
|
13
|
+
currentImageIndex: null,
|
|
14
|
+
});
|
|
15
|
+
exports.LightboxProvider = LightboxContext.Provider;
|
|
16
|
+
const useLightboxContext = () => (0, react_1.useContext)(LightboxContext);
|
|
17
|
+
exports.useLightboxContext = useLightboxContext;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useLightboxImage = exports.useLightbox = exports.Lightbox = void 0;
|
|
4
|
+
var lightbox_1 = require("./lightbox");
|
|
5
|
+
Object.defineProperty(exports, "Lightbox", { enumerable: true, get: function () { return lightbox_1.Lightbox; } });
|
|
6
|
+
var use_lightbox_1 = require("./use-lightbox");
|
|
7
|
+
Object.defineProperty(exports, "useLightbox", { enumerable: true, get: function () { return use_lightbox_1.useLightbox; } });
|
|
8
|
+
var use_lightbox_image_1 = require("./use-lightbox-image");
|
|
9
|
+
Object.defineProperty(exports, "useLightboxImage", { enumerable: true, get: function () { return use_lightbox_image_1.useLightboxImage; } });
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React, { type FC, ReactNode } from "react";
|
|
2
|
+
import { type LightboxButtonProps, type LightboxCustomDialogProps } from "./types";
|
|
3
|
+
export interface LightboxProps {
|
|
4
|
+
CloseButtonElement?: FC<LightboxButtonProps>;
|
|
5
|
+
DialogElement?: FC<LightboxCustomDialogProps>;
|
|
6
|
+
NextButtonElement?: FC<LightboxButtonProps>;
|
|
7
|
+
PrevButtonElement?: FC<LightboxButtonProps>;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
isBackdropCloseDisabled?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function Lightbox(props: LightboxProps): React.JSX.Element;
|
|
12
|
+
export declare namespace Lightbox {
|
|
13
|
+
var displayName: string;
|
|
14
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.Lightbox = Lightbox;
|
|
8
|
+
const is_not_nil_1 = require("@uxf/core/utils/is-not-nil");
|
|
9
|
+
const react_1 = __importDefault(require("react"));
|
|
10
|
+
const lightbox_dialog_1 = require("./components/lightbox-dialog");
|
|
11
|
+
const context_1 = require("./context");
|
|
12
|
+
const use_lightbox_1 = require("./use-lightbox");
|
|
13
|
+
function Lightbox(props) {
|
|
14
|
+
const { images, unregisterImage, openLightbox, imageIndex, registerImage, onNextImage, onPrevImage, onClose } = (0, use_lightbox_1.useLightbox)();
|
|
15
|
+
const contextValue = {
|
|
16
|
+
registerImage,
|
|
17
|
+
unregisterImage,
|
|
18
|
+
openLightbox,
|
|
19
|
+
images,
|
|
20
|
+
currentImageIndex: imageIndex,
|
|
21
|
+
};
|
|
22
|
+
return (react_1.default.createElement(context_1.LightboxProvider, { value: contextValue },
|
|
23
|
+
props.children,
|
|
24
|
+
(0, is_not_nil_1.isNotNil)(imageIndex) &&
|
|
25
|
+
((0, is_not_nil_1.isNotNil)(props.DialogElement) ? (react_1.default.createElement(props.DialogElement, { imageIndex: imageIndex, images: images, onClose: onClose, onNext: onNextImage, onPrev: onPrevImage })) : (react_1.default.createElement(lightbox_dialog_1.LightboxDialog, { CloseButtonElement: props.CloseButtonElement, NextButtonElement: props.NextButtonElement, PrevButtonElement: props.PrevButtonElement, imageIndex: imageIndex, images: images, isBackdropCloseDisabled: props.isBackdropCloseDisabled, onClose: onClose, onNext: onNextImage, onPrev: onPrevImage })))));
|
|
26
|
+
}
|
|
27
|
+
Lightbox.displayName = "UxfUiLightbox";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const snap_test_1 = require("../utils/snap-test");
|
|
8
|
+
const lightbox_stories_1 = require("./lightbox.stories");
|
|
9
|
+
(0, snap_test_1.snapTest)("render stories", react_1.default.createElement(lightbox_stories_1.Default, null));
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Default = Default;
|
|
7
|
+
const image_1 = require("@uxf/core/utils/image");
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const raster_image_1 = require("../raster-image");
|
|
10
|
+
const index_1 = require("./index");
|
|
11
|
+
const IMAGES = [
|
|
12
|
+
{
|
|
13
|
+
src: "/sample-images/sample-1.jpeg",
|
|
14
|
+
title: "Obr. 1",
|
|
15
|
+
customContent: "hello world 1",
|
|
16
|
+
width: 500,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
src: "/sample-images/sample-2.jpg",
|
|
20
|
+
title: "Obr. 2",
|
|
21
|
+
customContent: "hello world 2",
|
|
22
|
+
width: 500,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
src: "/sample-images/sample-3.jpg",
|
|
26
|
+
title: "Obr. 3",
|
|
27
|
+
customContent: "hello world 3",
|
|
28
|
+
width: 500,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
function Image(props) {
|
|
32
|
+
const openLightbox = (0, index_1.useLightboxImage)({
|
|
33
|
+
src: props.src,
|
|
34
|
+
title: props.title,
|
|
35
|
+
customContent: props.customContent,
|
|
36
|
+
});
|
|
37
|
+
return (react_1.default.createElement("button", { onClick: openLightbox },
|
|
38
|
+
react_1.default.createElement(raster_image_1.RasterImage, { alt: "", className: "size-56 cursor-pointer object-cover transition-transform hover:scale-105", src: props.src, width: props.width })));
|
|
39
|
+
}
|
|
40
|
+
function Default() {
|
|
41
|
+
return (react_1.default.createElement(index_1.Lightbox, null,
|
|
42
|
+
react_1.default.createElement("div", { className: "flex-direction flex gap-2" }, IMAGES.map((image) => (react_1.default.createElement(Image, { customContent: image.customContent, key: (0, image_1.getImgUniqueIdentifier)(image.src), src: image.src, title: image.title, width: image.width }))))));
|
|
43
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Noop } from "@uxf/core/types";
|
|
2
|
+
import { ImageSource } from "@uxf/core/utils/resizer";
|
|
3
|
+
import { type MouseEventHandler, ReactNode } from "react";
|
|
4
|
+
export interface LightboxImageProps {
|
|
5
|
+
alt?: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
customContent?: ReactNode;
|
|
8
|
+
src: ImageSource;
|
|
9
|
+
title?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface LightboxButtonProps {
|
|
12
|
+
onClick: MouseEventHandler;
|
|
13
|
+
}
|
|
14
|
+
export interface LightboxCustomDialogProps {
|
|
15
|
+
imageIndex: number;
|
|
16
|
+
images: LightboxImageProps[];
|
|
17
|
+
onClose: Noop;
|
|
18
|
+
onNext: Noop;
|
|
19
|
+
onPrev: Noop;
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useLightboxImage = useLightboxImage;
|
|
5
|
+
const use_on_mount_1 = require("@uxf/core-react/hooks/use-on-mount");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const context_1 = require("./context");
|
|
8
|
+
function useLightboxImage(props) {
|
|
9
|
+
const { registerImage, unregisterImage, openLightbox } = (0, context_1.useLightboxContext)();
|
|
10
|
+
(0, use_on_mount_1.useOnMount)(() => {
|
|
11
|
+
registerImage(props);
|
|
12
|
+
return () => {
|
|
13
|
+
unregisterImage(props);
|
|
14
|
+
};
|
|
15
|
+
});
|
|
16
|
+
return (0, react_1.useCallback)(() => openLightbox(props), [props, openLightbox]);
|
|
17
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LightboxImageProps } from "./types";
|
|
2
|
+
export declare function useLightbox(): {
|
|
3
|
+
onPrevImage: () => void;
|
|
4
|
+
onNextImage: () => void;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
registerImage: (image: LightboxImageProps) => void;
|
|
7
|
+
unregisterImage: (image: LightboxImageProps) => void;
|
|
8
|
+
openLightbox: (image: LightboxImageProps) => void;
|
|
9
|
+
images: LightboxImageProps[];
|
|
10
|
+
imageIndex: number | null;
|
|
11
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useLightbox = useLightbox;
|
|
5
|
+
const empty_array_1 = require("@uxf/core/constants/empty-array");
|
|
6
|
+
const image_1 = require("@uxf/core/utils/image");
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
function getModuloIndex(index, length) {
|
|
9
|
+
return index < 0 ? ((index % length) + length) % length : index % length;
|
|
10
|
+
}
|
|
11
|
+
function useLightbox() {
|
|
12
|
+
const [images, setImages] = (0, react_1.useState)(empty_array_1.EMPTY_ARRAY);
|
|
13
|
+
const [imageIndex, setImageIndex] = (0, react_1.useState)(null);
|
|
14
|
+
const registerImageHandler = (0, react_1.useCallback)((image) => setImages((v) => [...v, image]), []);
|
|
15
|
+
const unregisterImageHandler = (0, react_1.useCallback)((image) => setImages((v) => v.filter((u) => (0, image_1.getImgUniqueIdentifier)(u.src) !== (0, image_1.getImgUniqueIdentifier)(image.src))), []);
|
|
16
|
+
const openLightboxHandler = (0, react_1.useCallback)((image) => setImageIndex(images.findIndex((i) => (0, image_1.getImgUniqueIdentifier)(i.src) === (0, image_1.getImgUniqueIdentifier)(image.src))), [images]);
|
|
17
|
+
const showPrevImageHandler = (0, react_1.useCallback)(() => {
|
|
18
|
+
setImageIndex((v) => (v === null ? null : getModuloIndex(v - 1, images.length)));
|
|
19
|
+
}, [images.length]);
|
|
20
|
+
const showNextImageHandler = (0, react_1.useCallback)(() => {
|
|
21
|
+
setImageIndex((v) => (v === null ? null : getModuloIndex(v + 1, images.length)));
|
|
22
|
+
}, [images.length]);
|
|
23
|
+
const closeHandler = (0, react_1.useCallback)(() => setImageIndex(null), []);
|
|
24
|
+
return {
|
|
25
|
+
onPrevImage: showPrevImageHandler,
|
|
26
|
+
onNextImage: showNextImageHandler,
|
|
27
|
+
onClose: closeHandler,
|
|
28
|
+
registerImage: registerImageHandler,
|
|
29
|
+
unregisterImage: unregisterImageHandler,
|
|
30
|
+
openLightbox: openLightboxHandler,
|
|
31
|
+
images,
|
|
32
|
+
imageIndex,
|
|
33
|
+
};
|
|
34
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uxf/ui",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.71.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -24,14 +24,13 @@
|
|
|
24
24
|
"@floating-ui/react": "0.26.28",
|
|
25
25
|
"@headlessui/react": "1.7.19",
|
|
26
26
|
"@uxf/core": "11.70.0",
|
|
27
|
-
"@uxf/core-react": "11.
|
|
27
|
+
"@uxf/core-react": "11.71.0",
|
|
28
28
|
"@uxf/datepicker": "11.61.0",
|
|
29
29
|
"@uxf/styles": "11.70.0",
|
|
30
30
|
"color2k": "2.0.3",
|
|
31
31
|
"dayjs": "1.11.13",
|
|
32
32
|
"jump.js": "1.0.2",
|
|
33
|
-
"react-dropzone": "14.2.3"
|
|
34
|
-
"react-swipeable": "7.0.1"
|
|
33
|
+
"react-dropzone": "14.2.3"
|
|
35
34
|
},
|
|
36
35
|
"peerDependencies": {
|
|
37
36
|
"react": ">= 18.2.0",
|
package/readmes.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ export declare const readmes: {
|
|
|
38
38
|
readonly input: typeof accordionReadme;
|
|
39
39
|
readonly label: typeof accordionReadme;
|
|
40
40
|
readonly layout: typeof accordionReadme;
|
|
41
|
+
readonly lightbox: typeof accordionReadme;
|
|
41
42
|
readonly "list-item": typeof accordionReadme;
|
|
42
43
|
readonly loader: typeof accordionReadme;
|
|
43
44
|
readonly lozenge: typeof accordionReadme;
|
package/readmes.js
CHANGED
|
@@ -43,30 +43,31 @@ const README_md_35 = __importDefault(require("./info-box/README.md"));
|
|
|
43
43
|
const README_md_36 = __importDefault(require("./input/README.md"));
|
|
44
44
|
const README_md_37 = __importDefault(require("./label/README.md"));
|
|
45
45
|
const README_md_38 = __importDefault(require("./layout/README.md"));
|
|
46
|
-
const README_md_39 = __importDefault(require("./
|
|
47
|
-
const README_md_40 = __importDefault(require("./
|
|
48
|
-
const README_md_41 = __importDefault(require("./
|
|
49
|
-
const README_md_42 = __importDefault(require("./
|
|
50
|
-
const README_md_43 = __importDefault(require("./
|
|
51
|
-
const README_md_44 = __importDefault(require("./modal
|
|
52
|
-
const README_md_45 = __importDefault(require("./modal-
|
|
53
|
-
const README_md_46 = __importDefault(require("./
|
|
54
|
-
const README_md_47 = __importDefault(require("./multi-
|
|
55
|
-
const README_md_48 = __importDefault(require("./
|
|
56
|
-
const README_md_49 = __importDefault(require("./
|
|
57
|
-
const README_md_50 = __importDefault(require("./
|
|
58
|
-
const README_md_51 = __importDefault(require("./radio
|
|
59
|
-
const README_md_52 = __importDefault(require("./
|
|
60
|
-
const README_md_53 = __importDefault(require("./
|
|
61
|
-
const README_md_54 = __importDefault(require("./
|
|
62
|
-
const README_md_55 = __importDefault(require("./
|
|
63
|
-
const README_md_56 = __importDefault(require("./text-
|
|
64
|
-
const README_md_57 = __importDefault(require("./
|
|
65
|
-
const README_md_58 = __importDefault(require("./
|
|
66
|
-
const README_md_59 = __importDefault(require("./time-picker
|
|
67
|
-
const README_md_60 = __importDefault(require("./
|
|
68
|
-
const README_md_61 = __importDefault(require("./
|
|
69
|
-
const README_md_62 = __importDefault(require("./
|
|
46
|
+
const README_md_39 = __importDefault(require("./lightbox/README.md"));
|
|
47
|
+
const README_md_40 = __importDefault(require("./list-item/README.md"));
|
|
48
|
+
const README_md_41 = __importDefault(require("./loader/README.md"));
|
|
49
|
+
const README_md_42 = __importDefault(require("./lozenge/README.md"));
|
|
50
|
+
const README_md_43 = __importDefault(require("./message/README.md"));
|
|
51
|
+
const README_md_44 = __importDefault(require("./modal/README.md"));
|
|
52
|
+
const README_md_45 = __importDefault(require("./modal-dialog/README.md"));
|
|
53
|
+
const README_md_46 = __importDefault(require("./modal-header/README.md"));
|
|
54
|
+
const README_md_47 = __importDefault(require("./multi-combobox/README.md"));
|
|
55
|
+
const README_md_48 = __importDefault(require("./multi-select/README.md"));
|
|
56
|
+
const README_md_49 = __importDefault(require("./pagination/README.md"));
|
|
57
|
+
const README_md_50 = __importDefault(require("./paper/README.md"));
|
|
58
|
+
const README_md_51 = __importDefault(require("./radio/README.md"));
|
|
59
|
+
const README_md_52 = __importDefault(require("./radio-group/README.md"));
|
|
60
|
+
const README_md_53 = __importDefault(require("./raster-image/README.md"));
|
|
61
|
+
const README_md_54 = __importDefault(require("./select/README.md"));
|
|
62
|
+
const README_md_55 = __importDefault(require("./tabs/README.md"));
|
|
63
|
+
const README_md_56 = __importDefault(require("./text-input/README.md"));
|
|
64
|
+
const README_md_57 = __importDefault(require("./text-link/README.md"));
|
|
65
|
+
const README_md_58 = __importDefault(require("./textarea/README.md"));
|
|
66
|
+
const README_md_59 = __importDefault(require("./time-picker/README.md"));
|
|
67
|
+
const README_md_60 = __importDefault(require("./time-picker-input/README.md"));
|
|
68
|
+
const README_md_61 = __importDefault(require("./toggle/README.md"));
|
|
69
|
+
const README_md_62 = __importDefault(require("./tooltip/README.md"));
|
|
70
|
+
const README_md_63 = __importDefault(require("./typography/README.md"));
|
|
70
71
|
exports.readmes = {
|
|
71
72
|
"accordion": README_md_1.default,
|
|
72
73
|
"alert-bubble": README_md_2.default,
|
|
@@ -106,28 +107,29 @@ exports.readmes = {
|
|
|
106
107
|
"input": README_md_36.default,
|
|
107
108
|
"label": README_md_37.default,
|
|
108
109
|
"layout": README_md_38.default,
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
"modal
|
|
115
|
-
"modal-
|
|
116
|
-
"
|
|
117
|
-
"multi-
|
|
118
|
-
"
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
"radio
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"
|
|
126
|
-
"text-
|
|
127
|
-
"
|
|
128
|
-
"
|
|
129
|
-
"time-picker
|
|
130
|
-
"
|
|
131
|
-
"
|
|
132
|
-
"
|
|
110
|
+
"lightbox": README_md_39.default,
|
|
111
|
+
"list-item": README_md_40.default,
|
|
112
|
+
"loader": README_md_41.default,
|
|
113
|
+
"lozenge": README_md_42.default,
|
|
114
|
+
"message": README_md_43.default,
|
|
115
|
+
"modal": README_md_44.default,
|
|
116
|
+
"modal-dialog": README_md_45.default,
|
|
117
|
+
"modal-header": README_md_46.default,
|
|
118
|
+
"multi-combobox": README_md_47.default,
|
|
119
|
+
"multi-select": README_md_48.default,
|
|
120
|
+
"pagination": README_md_49.default,
|
|
121
|
+
"paper": README_md_50.default,
|
|
122
|
+
"radio": README_md_51.default,
|
|
123
|
+
"radio-group": README_md_52.default,
|
|
124
|
+
"raster-image": README_md_53.default,
|
|
125
|
+
"select": README_md_54.default,
|
|
126
|
+
"tabs": README_md_55.default,
|
|
127
|
+
"text-input": README_md_56.default,
|
|
128
|
+
"text-link": README_md_57.default,
|
|
129
|
+
"textarea": README_md_58.default,
|
|
130
|
+
"time-picker": README_md_59.default,
|
|
131
|
+
"time-picker-input": README_md_60.default,
|
|
132
|
+
"toggle": README_md_61.default,
|
|
133
|
+
"tooltip": README_md_62.default,
|
|
134
|
+
"typography": README_md_63.default,
|
|
133
135
|
};
|
package/tw-tokens/tw-z-index.js
CHANGED