@mailstep/design-system 0.13.2 → 0.13.4
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/package.json +1 -1
- package/ui/Blocks/ImageList/ImageList.js +13 -6
- package/ui/Blocks/ImageList/components/AddPhoto/index.d.ts +0 -1
- package/ui/Blocks/ImageList/components/AddPhoto/index.js +5 -9
- package/ui/Blocks/ImageList/components/AddPhoto/styles.d.ts +1 -4
- package/ui/Blocks/ImageList/components/AddPhoto/styles.js +2 -2
- package/ui/Blocks/ImageList/components/CloseButton/index.js +2 -2
- package/ui/Blocks/ImageList/components/CloseButton/styles.js +12 -7
- package/ui/Blocks/ImageList/components/ImageElement/index.d.ts +2 -0
- package/ui/Blocks/ImageList/components/ImageElement/index.js +9 -7
- package/ui/Blocks/ImageList/components/ImageElement/styles.d.ts +3 -5
- package/ui/Blocks/ImageList/components/ImageElement/styles.js +23 -15
- package/ui/Blocks/ImageList/styles.d.ts +0 -1
- package/ui/Blocks/ImageList/styles.js +1 -1
- package/ui/Blocks/ImageList/types.d.ts +3 -0
- package/ui/Blocks/LightBox/LightBox.js +38 -20
- package/ui/Blocks/LightBox/components/DownloadButton/index.d.ts +8 -0
- package/ui/Blocks/LightBox/components/DownloadButton/index.js +21 -0
- package/ui/Blocks/LightBox/components/DownloadButton/styles.d.ts +3 -0
- package/ui/Blocks/LightBox/components/DownloadButton/styles.js +22 -0
- package/ui/Blocks/LightBox/hooks/useImageDownload.d.ts +10 -0
- package/ui/Blocks/LightBox/hooks/useImageDownload.js +19 -0
- package/ui/Blocks/LightBox/styles.d.ts +1 -0
- package/ui/Blocks/LightBox/styles.js +6 -1
- package/ui/Blocks/LightBox/types.d.ts +4 -0
- package/ui/Blocks/LightBox/utils/downloadImage.d.ts +7 -0
- package/ui/Blocks/LightBox/utils/downloadImage.js +21 -0
- package/ui/Blocks/LightBox/utils/getImageFileName.d.ts +7 -0
- package/ui/Blocks/LightBox/utils/getImageFileName.js +8 -0
- package/ui/Forms/DatePicker/Datetime/components/DateRepeater.js +9 -3
- package/ui/Forms/DatePicker/styles.js +4 -0
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Icon from "../../Elements/Icon/Icon.js";
|
|
2
|
+
import { useImageDownload } from "../LightBox/hooks/useImageDownload.js";
|
|
2
3
|
import { useLightBox } from "../LightBox/hooks/useLightBox.js";
|
|
3
4
|
import LightBox_default from "../LightBox/index.js";
|
|
4
5
|
import { AddPhoto } from "./components/AddPhoto/index.js";
|
|
@@ -11,7 +12,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
11
12
|
import { x } from "@xstyled/styled-components";
|
|
12
13
|
import { useDraggable } from "react-use-draggable-scroll";
|
|
13
14
|
//#region packages/ui/Blocks/ImageList/ImageList.tsx
|
|
14
|
-
const ImageList = ({ onImageUpload, onImageRemove, onImageClick, lightBoxAction, lightBoxActionTitle, images, isDisabled, selectable, max }) => {
|
|
15
|
+
const ImageList = ({ onImageUpload, onImageRemove, onImageClick, lightBoxAction, lightBoxActionTitle, images, isDisabled, selectable, max, downloadable, onImageDownload, downloadTitle }) => {
|
|
15
16
|
const ref = useRef(null);
|
|
16
17
|
const { events } = useDraggable(ref, { isMounted: !!images?.length });
|
|
17
18
|
const { isLightBoxOpen, onCloseLightBox, onOpenLightBox, lightBoxData } = useLightBox();
|
|
@@ -24,20 +25,22 @@ const ImageList = ({ onImageUpload, onImageRemove, onImageClick, lightBoxAction,
|
|
|
24
25
|
max,
|
|
25
26
|
total: images?.length
|
|
26
27
|
});
|
|
28
|
+
const { getDownloadHandler } = useImageDownload({
|
|
29
|
+
downloadable,
|
|
30
|
+
onImageDownload
|
|
31
|
+
});
|
|
27
32
|
return /* @__PURE__ */ jsxs(x.div, {
|
|
28
33
|
display: "flex",
|
|
29
34
|
alignItems: "center",
|
|
30
35
|
children: [
|
|
31
36
|
/* @__PURE__ */ jsx(AddPhoto, {
|
|
32
37
|
onImageUpload,
|
|
33
|
-
isDisabled
|
|
34
|
-
hasRemove: !!onImageRemove
|
|
38
|
+
isDisabled
|
|
35
39
|
}),
|
|
36
40
|
hasControls && /* @__PURE__ */ jsx(Control, {
|
|
37
41
|
onClick: moveList(-1),
|
|
38
42
|
isLeft: true,
|
|
39
43
|
isDisabled: position === 0,
|
|
40
|
-
hasRemove: !!onImageRemove,
|
|
41
44
|
children: /* @__PURE__ */ jsx(Icon, {
|
|
42
45
|
icon: "lessThen",
|
|
43
46
|
size: "24px"
|
|
@@ -49,6 +52,8 @@ const ImageList = ({ onImageUpload, onImageRemove, onImageClick, lightBoxAction,
|
|
|
49
52
|
children: images.map((item, index) => /* @__PURE__ */ jsx(ImageElement, {
|
|
50
53
|
imageUrl: item.smallUrl ?? item.url,
|
|
51
54
|
onImageRemove: onImageRemove?.(item.id),
|
|
55
|
+
onImageDownload: getDownloadHandler(item),
|
|
56
|
+
downloadTitle,
|
|
52
57
|
onClick: handleOnClick(item, index),
|
|
53
58
|
isDisabled,
|
|
54
59
|
label: item?.label,
|
|
@@ -59,7 +64,6 @@ const ImageList = ({ onImageUpload, onImageRemove, onImageClick, lightBoxAction,
|
|
|
59
64
|
hasControls && /* @__PURE__ */ jsx(Control, {
|
|
60
65
|
onClick: moveList(1),
|
|
61
66
|
isDisabled: !!images && !!max && position >= images?.length - max,
|
|
62
|
-
hasRemove: !!onImageRemove,
|
|
63
67
|
children: /* @__PURE__ */ jsx(Icon, {
|
|
64
68
|
icon: "greaterThan",
|
|
65
69
|
size: "24px"
|
|
@@ -71,7 +75,10 @@ const ImageList = ({ onImageUpload, onImageRemove, onImageClick, lightBoxAction,
|
|
|
71
75
|
onCloseLightBox,
|
|
72
76
|
lightBoxAction,
|
|
73
77
|
lightBoxActionTitle,
|
|
74
|
-
images
|
|
78
|
+
images,
|
|
79
|
+
downloadable,
|
|
80
|
+
onImageDownload,
|
|
81
|
+
downloadTitle
|
|
75
82
|
})
|
|
76
83
|
]
|
|
77
84
|
});
|
|
@@ -6,12 +6,11 @@ import { useImageUpload } from "./hooks/useImageUpload.js";
|
|
|
6
6
|
import { Container, ErrorWrapper, HiddenInput, Wrapper } from "./styles.js";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
//#region packages/ui/Blocks/ImageList/components/AddPhoto/index.tsx
|
|
9
|
-
const AddPhoto = ({ onImageUpload, isDisabled
|
|
9
|
+
const AddPhoto = ({ onImageUpload, isDisabled }) => {
|
|
10
10
|
const { handleImageUpload, hasInvalidFormat } = useImageUpload({ onImageUpload });
|
|
11
11
|
if (!onImageUpload) return null;
|
|
12
12
|
return /* @__PURE__ */ jsxs(Wrapper, { children: [/* @__PURE__ */ jsxs(Container, {
|
|
13
13
|
isDisabled,
|
|
14
|
-
hasRemove,
|
|
15
14
|
children: [/* @__PURE__ */ jsx(HiddenInput, {
|
|
16
15
|
disabled: isDisabled,
|
|
17
16
|
onChange: handleImageUpload,
|
|
@@ -22,13 +21,10 @@ const AddPhoto = ({ onImageUpload, isDisabled, hasRemove }) => {
|
|
|
22
21
|
width: "36",
|
|
23
22
|
height: "36"
|
|
24
23
|
})]
|
|
25
|
-
}), hasInvalidFormat && /* @__PURE__ */ jsx(ErrorWrapper, {
|
|
26
|
-
|
|
27
|
-
children:
|
|
28
|
-
|
|
29
|
-
children: "Unsupported file format"
|
|
30
|
-
})
|
|
31
|
-
})] });
|
|
24
|
+
}), hasInvalidFormat && /* @__PURE__ */ jsx(ErrorWrapper, { children: /* @__PURE__ */ jsx(ErrorMessage, {
|
|
25
|
+
appearance: "inline",
|
|
26
|
+
children: "Unsupported file format"
|
|
27
|
+
}) })] });
|
|
32
28
|
};
|
|
33
29
|
//#endregion
|
|
34
30
|
export { AddPhoto };
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
export declare const Container: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {
|
|
2
2
|
isDisabled?: boolean;
|
|
3
|
-
hasRemove?: boolean;
|
|
4
3
|
}, never>;
|
|
5
4
|
export declare const HiddenInput: import("styled-components").StyledComponent<"input", import("@xstyled/styled-components").Theme, {}, never>;
|
|
6
5
|
export declare const Wrapper: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {}, never>;
|
|
7
|
-
export declare const ErrorWrapper: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {
|
|
8
|
-
hasRemove?: boolean;
|
|
9
|
-
}, never>;
|
|
6
|
+
export declare const ErrorWrapper: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {}, never>;
|
|
@@ -3,6 +3,7 @@ import styled$1, { th } from "@xstyled/styled-components";
|
|
|
3
3
|
const Container = styled$1.div`
|
|
4
4
|
position: relative;
|
|
5
5
|
flex-shrink: 0;
|
|
6
|
+
box-sizing: border-box;
|
|
6
7
|
transition: all 0.2s linear;
|
|
7
8
|
height: 85px !important;
|
|
8
9
|
width: 85px !important;
|
|
@@ -15,7 +16,6 @@ const Container = styled$1.div`
|
|
|
15
16
|
cursor: pointer;
|
|
16
17
|
margin-right: 15px;
|
|
17
18
|
opacity: ${({ isDisabled }) => isDisabled ? .6 : 1};
|
|
18
|
-
margin-top: ${({ hasRemove }) => hasRemove ? "15px" : ""};
|
|
19
19
|
`;
|
|
20
20
|
const HiddenInput = styled$1.input`
|
|
21
21
|
opacity: 0;
|
|
@@ -32,7 +32,7 @@ const Wrapper = styled$1.div`
|
|
|
32
32
|
`;
|
|
33
33
|
const ErrorWrapper = styled$1.div`
|
|
34
34
|
position: absolute;
|
|
35
|
-
top:
|
|
35
|
+
top: 85px;
|
|
36
36
|
left: 0;
|
|
37
37
|
width: 85px;
|
|
38
38
|
line-height: 1.2;
|
|
@@ -2,17 +2,22 @@ import styled$1, { th } from "@xstyled/styled-components";
|
|
|
2
2
|
//#region packages/ui/Blocks/ImageList/components/CloseButton/styles.ts
|
|
3
3
|
const Container = styled$1.div`
|
|
4
4
|
position: absolute;
|
|
5
|
-
top:
|
|
6
|
-
right:
|
|
7
|
-
width:
|
|
8
|
-
height:
|
|
9
|
-
background-color: ${
|
|
5
|
+
top: 2px;
|
|
6
|
+
right: 2px;
|
|
7
|
+
width: 24px;
|
|
8
|
+
height: 24px;
|
|
9
|
+
background-color: ${th.color("bgLightGray1")};
|
|
10
10
|
border-radius: 50%;
|
|
11
11
|
display: flex;
|
|
12
12
|
align-items: center;
|
|
13
13
|
justify-content: center;
|
|
14
|
-
cursor: pointer;
|
|
15
|
-
|
|
14
|
+
cursor: ${({ isDisabled }) => isDisabled ? "default" : "pointer"};
|
|
15
|
+
opacity: ${({ isDisabled }) => isDisabled ? .5 : .8};
|
|
16
|
+
transition: opacity 0.2s linear;
|
|
17
|
+
|
|
18
|
+
&:hover {
|
|
19
|
+
opacity: ${({ isDisabled }) => isDisabled ? .5 : 1};
|
|
20
|
+
}
|
|
16
21
|
`;
|
|
17
22
|
//#endregion
|
|
18
23
|
export { Container };
|
|
@@ -1,26 +1,28 @@
|
|
|
1
|
+
import { DownloadButton } from "../../../LightBox/components/DownloadButton/index.js";
|
|
1
2
|
import { CloseButton } from "../CloseButton/index.js";
|
|
2
3
|
import { ImageTag } from "../ImageTag/index.js";
|
|
3
|
-
import { Image, ImageWrapper } from "./styles.js";
|
|
4
|
+
import { DownloadButtonWrapper, Image, ImageWrapper } from "./styles.js";
|
|
4
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
//#region packages/ui/Blocks/ImageList/components/ImageElement/index.tsx
|
|
6
|
-
const ImageElement = ({ label, onImageRemove, isDisabled, onClick, imageUrl, selected, visible }) => {
|
|
7
|
+
const ImageElement = ({ label, onImageRemove, onImageDownload, downloadTitle, isDisabled, onClick, imageUrl, selected, visible }) => {
|
|
7
8
|
if (!imageUrl) return null;
|
|
8
9
|
return /* @__PURE__ */ jsxs(ImageWrapper, {
|
|
9
10
|
visible,
|
|
10
|
-
|
|
11
|
+
selected,
|
|
11
12
|
children: [
|
|
12
13
|
/* @__PURE__ */ jsx(Image, {
|
|
13
14
|
src: imageUrl,
|
|
14
15
|
alt: "",
|
|
15
|
-
|
|
16
|
-
height: "85px",
|
|
17
|
-
onClick,
|
|
18
|
-
selected
|
|
16
|
+
onClick
|
|
19
17
|
}),
|
|
20
18
|
onImageRemove && /* @__PURE__ */ jsx(CloseButton, {
|
|
21
19
|
onImageRemove,
|
|
22
20
|
isDisabled
|
|
23
21
|
}),
|
|
22
|
+
onImageDownload && /* @__PURE__ */ jsx(DownloadButtonWrapper, { children: /* @__PURE__ */ jsx(DownloadButton, {
|
|
23
|
+
onImageDownload,
|
|
24
|
+
title: downloadTitle
|
|
25
|
+
}) }),
|
|
24
26
|
/* @__PURE__ */ jsx(ImageTag, { label })
|
|
25
27
|
]
|
|
26
28
|
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
export declare const Container: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {}, never>;
|
|
2
|
-
export declare const Image: import("styled-components").StyledComponent<"img", import("@xstyled/styled-components").Theme, {
|
|
3
|
-
selected?: boolean;
|
|
4
|
-
}, never>;
|
|
5
1
|
export declare const ImageWrapper: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {
|
|
6
2
|
visible: boolean;
|
|
7
|
-
|
|
3
|
+
selected?: boolean;
|
|
8
4
|
}, never>;
|
|
5
|
+
export declare const Image: import("styled-components").StyledComponent<"img", import("@xstyled/styled-components").Theme, {}, never>;
|
|
6
|
+
export declare const DownloadButtonWrapper: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {}, never>;
|
|
@@ -1,22 +1,30 @@
|
|
|
1
|
-
import styled$1 from "@xstyled/styled-components";
|
|
2
|
-
import { th as th$1 } from "@xstyled/system";
|
|
1
|
+
import styled$1, { th } from "@xstyled/styled-components";
|
|
3
2
|
//#region packages/ui/Blocks/ImageList/components/ImageElement/styles.ts
|
|
4
|
-
const Container = styled$1.div``;
|
|
5
|
-
const Image = styled$1.img`
|
|
6
|
-
border-radius: ${th$1.radius("lg")};
|
|
7
|
-
border: ${({ selected }) => selected ? `3px solid` : "0"};
|
|
8
|
-
border-color: red1;
|
|
9
|
-
cursor: pointer;
|
|
10
|
-
transition: all 0.2s;
|
|
11
|
-
`;
|
|
12
3
|
const ImageWrapper = styled$1.div`
|
|
13
4
|
position: relative;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
width:
|
|
17
|
-
height:
|
|
5
|
+
flex-shrink: 0;
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
width: 85px;
|
|
8
|
+
height: 85px;
|
|
9
|
+
border: ${({ selected }) => th.border(selected ? "mediumSlim" : "slim")};
|
|
10
|
+
border-color: ${({ selected }) => th.color(selected ? "red1" : "lightGray6")};
|
|
11
|
+
border-radius: ${th.radius("lg")};
|
|
12
|
+
overflow: hidden;
|
|
18
13
|
display: ${({ visible }) => visible ? "block" : "none"};
|
|
19
14
|
user-select: none;
|
|
15
|
+
transition: border-color 0.2s;
|
|
16
|
+
`;
|
|
17
|
+
const Image = styled$1.img`
|
|
18
|
+
display: block;
|
|
19
|
+
width: 100%;
|
|
20
|
+
height: 100%;
|
|
21
|
+
object-fit: cover;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
`;
|
|
24
|
+
const DownloadButtonWrapper = styled$1.div`
|
|
25
|
+
position: absolute;
|
|
26
|
+
right: 2px;
|
|
27
|
+
bottom: 2px;
|
|
20
28
|
`;
|
|
21
29
|
//#endregion
|
|
22
|
-
export {
|
|
30
|
+
export { DownloadButtonWrapper, Image, ImageWrapper };
|
|
@@ -2,5 +2,4 @@ export declare const ImageListContainer: import("styled-components").StyledCompo
|
|
|
2
2
|
export declare const Control: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {
|
|
3
3
|
isLeft?: boolean;
|
|
4
4
|
isDisabled: boolean;
|
|
5
|
-
hasRemove?: boolean;
|
|
6
5
|
}, never>;
|
|
@@ -6,6 +6,7 @@ const ImageListContainer = styled$1.div`
|
|
|
6
6
|
-ms-overflow-style: none;
|
|
7
7
|
scrollbar-width: none;
|
|
8
8
|
position: relative;
|
|
9
|
+
gap: 15px;
|
|
9
10
|
|
|
10
11
|
&::-webkit-scrollbar {
|
|
11
12
|
display: none;
|
|
@@ -14,7 +15,6 @@ const ImageListContainer = styled$1.div`
|
|
|
14
15
|
const Control = styled$1.div`
|
|
15
16
|
width: 24px;
|
|
16
17
|
margin-right: ${({ isLeft }) => isLeft ? "15px" : 0};
|
|
17
|
-
margin-top: ${({ hasRemove }) => hasRemove ? "15px" : 0};
|
|
18
18
|
cursor: pointer;
|
|
19
19
|
display: flex;
|
|
20
20
|
transition: all 0.4s;
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import Button from "../../Elements/Button/Button.js";
|
|
2
2
|
import "../../Elements/Button/index.js";
|
|
3
3
|
import Modal_default from "../Modal/index.js";
|
|
4
|
-
import {
|
|
4
|
+
import { DownloadButton } from "./components/DownloadButton/index.js";
|
|
5
|
+
import { useImageDownload } from "./hooks/useImageDownload.js";
|
|
6
|
+
import { ButtonContainer, Container, Description, DownloadButtonWrapper, Image } from "./styles.js";
|
|
7
|
+
import { useCallback } from "react";
|
|
5
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
9
|
import { Swiper, SwiperSlide } from "swiper/react";
|
|
7
10
|
//#region packages/ui/Blocks/LightBox/LightBox.tsx
|
|
8
|
-
const LightBox = ({ isLightBoxOpen, onCloseLightBox, lightBoxAction, lightBoxActionTitle, images, initialSlide = 0 }) => {
|
|
11
|
+
const LightBox = ({ isLightBoxOpen, onCloseLightBox, lightBoxAction, lightBoxActionTitle, images, initialSlide = 0, downloadable, onImageDownload, downloadTitle }) => {
|
|
12
|
+
const { getDownloadHandler } = useImageDownload({
|
|
13
|
+
downloadable,
|
|
14
|
+
onImageDownload
|
|
15
|
+
});
|
|
16
|
+
const handleLightBoxAction = useCallback((id) => () => {
|
|
17
|
+
lightBoxAction?.(id)();
|
|
18
|
+
}, [lightBoxAction]);
|
|
9
19
|
if (!images?.length) return null;
|
|
10
20
|
return /* @__PURE__ */ jsx(Modal_default, {
|
|
11
21
|
isShown: isLightBoxOpen,
|
|
@@ -16,24 +26,32 @@ const LightBox = ({ isLightBoxOpen, onCloseLightBox, lightBoxAction, lightBoxAct
|
|
|
16
26
|
initialSlide,
|
|
17
27
|
slidesPerView: 1,
|
|
18
28
|
autoHeight: true,
|
|
19
|
-
children: images.map((item) =>
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
children: images.map((item) => {
|
|
30
|
+
const handleImageDownload = getDownloadHandler(item);
|
|
31
|
+
return /* @__PURE__ */ jsx(SwiperSlide, { children: /* @__PURE__ */ jsxs(Container, { children: [
|
|
32
|
+
/* @__PURE__ */ jsx(Image, {
|
|
33
|
+
src: item.originalUrl ?? item.url,
|
|
34
|
+
loading: "lazy",
|
|
35
|
+
alt: ""
|
|
36
|
+
}),
|
|
37
|
+
handleImageDownload && /* @__PURE__ */ jsx(DownloadButtonWrapper, { children: /* @__PURE__ */ jsx(DownloadButton, {
|
|
38
|
+
onImageDownload: handleImageDownload,
|
|
39
|
+
title: downloadTitle,
|
|
40
|
+
isLarge: true
|
|
41
|
+
}) }),
|
|
42
|
+
(item.date || item.description) && /* @__PURE__ */ jsxs(Description, { children: [
|
|
43
|
+
item.date,
|
|
44
|
+
" ",
|
|
45
|
+
item.description
|
|
46
|
+
] }),
|
|
47
|
+
!!item.withLightBoxAction && lightBoxAction && lightBoxActionTitle && /* @__PURE__ */ jsx(ButtonContainer, { children: /* @__PURE__ */ jsx(Button, {
|
|
48
|
+
onClick: handleLightBoxAction(item.id),
|
|
49
|
+
appearance: "primary",
|
|
50
|
+
variant: "default",
|
|
51
|
+
children: lightBoxActionTitle
|
|
52
|
+
}) })
|
|
53
|
+
] }) }, item.id);
|
|
54
|
+
})
|
|
37
55
|
})
|
|
38
56
|
});
|
|
39
57
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Icon from "../../../../Elements/Icon/Icon.js";
|
|
2
|
+
import "../../../../Elements/Icon/index.js";
|
|
3
|
+
import { Container } from "./styles.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region packages/ui/Blocks/LightBox/components/DownloadButton/index.tsx
|
|
6
|
+
const DownloadButton = ({ onImageDownload, title = "Download", isLarge }) => {
|
|
7
|
+
return /* @__PURE__ */ jsx(Container, {
|
|
8
|
+
type: "button",
|
|
9
|
+
isLarge,
|
|
10
|
+
onClick: onImageDownload,
|
|
11
|
+
title,
|
|
12
|
+
"aria-label": title,
|
|
13
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
14
|
+
icon: "download",
|
|
15
|
+
size: isLarge ? "18px" : "14px",
|
|
16
|
+
fill: "gray1"
|
|
17
|
+
})
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
export { DownloadButton };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import styled$1, { th } from "@xstyled/styled-components";
|
|
2
|
+
//#region packages/ui/Blocks/LightBox/components/DownloadButton/styles.ts
|
|
3
|
+
const Container = styled$1.button`
|
|
4
|
+
width: ${({ isLarge }) => isLarge ? "34px" : "24px"};
|
|
5
|
+
height: ${({ isLarge }) => isLarge ? "34px" : "24px"};
|
|
6
|
+
padding: 0;
|
|
7
|
+
border: 0;
|
|
8
|
+
border-radius: 50%;
|
|
9
|
+
background-color: ${({ isLarge }) => th.color(isLarge ? "bgLightGray2" : "bgLightGray1")};
|
|
10
|
+
display: flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
cursor: pointer;
|
|
14
|
+
opacity: 0.8;
|
|
15
|
+
transition: opacity 0.2s linear;
|
|
16
|
+
|
|
17
|
+
&:hover {
|
|
18
|
+
opacity: 1;
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { Container };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ImageData } from '../types';
|
|
2
|
+
type Props = {
|
|
3
|
+
downloadable?: boolean;
|
|
4
|
+
onImageDownload?: (item: ImageData) => () => void;
|
|
5
|
+
};
|
|
6
|
+
type HookType = (props: Props) => {
|
|
7
|
+
getDownloadHandler: (item: ImageData) => (() => void) | undefined;
|
|
8
|
+
};
|
|
9
|
+
export declare const useImageDownload: HookType;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { downloadImage } from "../utils/downloadImage.js";
|
|
2
|
+
import { useCallback } from "react";
|
|
3
|
+
//#region packages/ui/Blocks/LightBox/hooks/useImageDownload.ts
|
|
4
|
+
const useImageDownload = ({ downloadable, onImageDownload }) => {
|
|
5
|
+
return { getDownloadHandler: useCallback((item) => {
|
|
6
|
+
if (onImageDownload) return onImageDownload(item);
|
|
7
|
+
if (!downloadable) return void 0;
|
|
8
|
+
const url = item.originalUrl ?? item.url;
|
|
9
|
+
if (!url) return void 0;
|
|
10
|
+
return () => {
|
|
11
|
+
downloadImage({
|
|
12
|
+
url,
|
|
13
|
+
fileName: item.originalName
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
}, [downloadable, onImageDownload]) };
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { useImageDownload };
|
|
@@ -2,3 +2,4 @@ export declare const Container: import("styled-components").StyledComponent<"div
|
|
|
2
2
|
export declare const Image: import("styled-components").StyledComponent<"img", import("@xstyled/styled-components").Theme, {}, never>;
|
|
3
3
|
export declare const ButtonContainer: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {}, never>;
|
|
4
4
|
export declare const Description: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {}, never>;
|
|
5
|
+
export declare const DownloadButtonWrapper: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {}, never>;
|
|
@@ -24,5 +24,10 @@ const Description = styled$1.div`
|
|
|
24
24
|
bottom: 0px;
|
|
25
25
|
background: rgba(255, 255, 255, 0.8);
|
|
26
26
|
`;
|
|
27
|
+
const DownloadButtonWrapper = styled$1.div`
|
|
28
|
+
position: absolute;
|
|
29
|
+
top: 10px;
|
|
30
|
+
left: 10px;
|
|
31
|
+
`;
|
|
27
32
|
//#endregion
|
|
28
|
-
export { ButtonContainer, Container, Description, Image };
|
|
33
|
+
export { ButtonContainer, Container, Description, DownloadButtonWrapper, Image };
|
|
@@ -14,6 +14,7 @@ export interface ImageData {
|
|
|
14
14
|
date?: string;
|
|
15
15
|
smallUrl?: string;
|
|
16
16
|
originalUrl?: string;
|
|
17
|
+
originalName?: string | null;
|
|
17
18
|
description?: string | null;
|
|
18
19
|
withLightBoxAction?: boolean;
|
|
19
20
|
}
|
|
@@ -24,4 +25,7 @@ export interface LightBoxProps {
|
|
|
24
25
|
lightBoxAction?: (id?: string) => () => Promise<void>;
|
|
25
26
|
lightBoxActionTitle?: string;
|
|
26
27
|
initialSlide?: number;
|
|
28
|
+
downloadable?: boolean;
|
|
29
|
+
onImageDownload?: (item: ImageData) => () => void;
|
|
30
|
+
downloadTitle?: string;
|
|
27
31
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getImageFileName } from "./getImageFileName.js";
|
|
2
|
+
//#region packages/ui/Blocks/LightBox/utils/downloadImage.ts
|
|
3
|
+
const downloadImage = async ({ url, fileName }) => {
|
|
4
|
+
try {
|
|
5
|
+
const response = await fetch(url);
|
|
6
|
+
if (!response.ok) throw new Error(`Image download failed with status ${response.status}`);
|
|
7
|
+
const objectUrl = URL.createObjectURL(await response.blob());
|
|
8
|
+
const link = document.createElement("a");
|
|
9
|
+
link.href = objectUrl;
|
|
10
|
+
link.download = getImageFileName({
|
|
11
|
+
url,
|
|
12
|
+
fileName
|
|
13
|
+
});
|
|
14
|
+
link.click();
|
|
15
|
+
URL.revokeObjectURL(objectUrl);
|
|
16
|
+
} catch {
|
|
17
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
export { downloadImage };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region packages/ui/Blocks/LightBox/utils/getImageFileName.ts
|
|
2
|
+
const getImageFileName = ({ url, fileName }) => {
|
|
3
|
+
if (fileName) return fileName;
|
|
4
|
+
const lastSegment = new URL(url, window.location.href).pathname.split("/").pop();
|
|
5
|
+
return lastSegment ? decodeURIComponent(lastSegment) : "image";
|
|
6
|
+
};
|
|
7
|
+
//#endregion
|
|
8
|
+
export { getImageFileName };
|
|
@@ -44,18 +44,24 @@ const DateRepeater = ({ onChangeOthers, others, reset }) => {
|
|
|
44
44
|
cursor: "pointer",
|
|
45
45
|
border: "none",
|
|
46
46
|
children: [
|
|
47
|
-
/* @__PURE__ */ jsx(
|
|
47
|
+
/* @__PURE__ */ jsx(x.option, {
|
|
48
|
+
color: "#333",
|
|
49
|
+
backgroundColor: "#fff",
|
|
48
50
|
value: "",
|
|
49
51
|
children: i18n._({
|
|
50
52
|
id: "dataGrid.noRepeat",
|
|
51
53
|
message: "No repeat"
|
|
52
54
|
})
|
|
53
55
|
}),
|
|
54
|
-
/* @__PURE__ */ jsx(
|
|
56
|
+
/* @__PURE__ */ jsx(x.option, {
|
|
57
|
+
color: "#333",
|
|
58
|
+
backgroundColor: "#fff",
|
|
55
59
|
value: "every-today",
|
|
56
60
|
children: DatePickerRepeatTrans()["every-today"]
|
|
57
61
|
}),
|
|
58
|
-
/* @__PURE__ */ jsx(
|
|
62
|
+
/* @__PURE__ */ jsx(x.option, {
|
|
63
|
+
color: "#333",
|
|
64
|
+
backgroundColor: "#fff",
|
|
59
65
|
value: "every-yesterday",
|
|
60
66
|
children: DatePickerRepeatTrans()["every-yesterday"]
|
|
61
67
|
})
|
|
@@ -199,6 +199,10 @@ const DatePickerBase = styled$1(x.div)`
|
|
|
199
199
|
background-color: blue10;
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
+
.rdtPicker .rdtActiveRange:hover {
|
|
203
|
+
border-radius: 0.5rem;
|
|
204
|
+
}
|
|
205
|
+
|
|
202
206
|
.rdtPicker .rdtCounters > div :first-child {
|
|
203
207
|
visibility: hidden;
|
|
204
208
|
transform: rotate(-90deg);
|