react-artasys-ui 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/lib/Button/Button.d.ts +6 -0
- package/lib/Button/index.d.ts +2 -0
- package/lib/UploadImages/Image.d.ts +16 -0
- package/lib/UploadImages/UploadImages.d.ts +9 -0
- package/lib/UploadImages/index.d.ts +5 -0
- package/lib/index.d.ts +6 -3
- package/package.json +1 -1
- package/src/Button/Button.tsx +19 -0
- package/src/Button/index.tsx +3 -0
- package/src/Button/style.module.css +45 -0
- package/src/UploadImages/Image.tsx +86 -0
- package/src/UploadImages/UploadImages.tsx +57 -0
- package/src/UploadImages/index.tsx +13 -0
- package/src/UploadImages/style.module.css +108 -0
- package/src/index.ts +21 -3
- package/webpack.config.js +1 -2
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { TFileData } from "../File";
|
|
2
|
+
export type TImageData = TFileData & {
|
|
3
|
+
id?: string | number;
|
|
4
|
+
setWait: (status: boolean) => void;
|
|
5
|
+
setId: (id: string | number) => void;
|
|
6
|
+
};
|
|
7
|
+
export interface IImage extends TFileData {
|
|
8
|
+
onChange?: (data: TImageData) => void;
|
|
9
|
+
onId?: (id: string | number) => void;
|
|
10
|
+
onRemove?: () => void;
|
|
11
|
+
onClick?: (data: TImageData) => void;
|
|
12
|
+
id?: string | number;
|
|
13
|
+
src?: string;
|
|
14
|
+
}
|
|
15
|
+
declare const Image: ({ onChange, onClick, onId, onRemove, ...props }: IImage) => JSX.Element;
|
|
16
|
+
export default Image;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TImageData, IImage } from "./Image";
|
|
2
|
+
export interface IUploadImages {
|
|
3
|
+
onChange?: (data: TImageData) => void;
|
|
4
|
+
onChangeArray?: (data: IImage[]) => void;
|
|
5
|
+
onClick?: (data: TImageData) => void;
|
|
6
|
+
imagesArray?: TImageData[];
|
|
7
|
+
}
|
|
8
|
+
declare const UploadImages: ({ imagesArray, onChange, onChangeArray, onClick }: IUploadImages) => JSX.Element;
|
|
9
|
+
export default UploadImages;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import Form, { useForm } from "./Form";
|
|
1
|
+
import Form, { useForm, FormElement } from "./Form";
|
|
2
|
+
import Element, { IElement } from "./Form/Element";
|
|
2
3
|
import Input from "./Input";
|
|
3
4
|
import TextArea from "./TextArea";
|
|
4
5
|
import Spinner from "./Spinner";
|
|
5
6
|
import File, { TFileData, TFileMime } from "./File";
|
|
7
|
+
import Button from "./Button";
|
|
8
|
+
import UploadImages, { IUploadImages, TImageData, IImage } from "./UploadImages";
|
|
6
9
|
declare const UI: {};
|
|
7
|
-
export { Form, useForm, Input, TextArea, Spinner, File };
|
|
8
|
-
export type { TFileData, TFileMime };
|
|
10
|
+
export { Form, FormElement, Element, useForm, Input, TextArea, Spinner, File, Button, UploadImages };
|
|
11
|
+
export type { TFileData, TFileMime, IUploadImages, IImage, TImageData, IElement };
|
|
9
12
|
export default UI;
|
package/package.json
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import styles from "./style.module.css";
|
|
3
|
+
import Spinner from "../Spinner";
|
|
4
|
+
|
|
5
|
+
interface IButton extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
6
|
+
wait?: boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const Button = ({children, wait = false, ...props}: IButton) => {
|
|
10
|
+
|
|
11
|
+
return(<div className={styles['container']}>
|
|
12
|
+
<button {...props}>{children}</button>
|
|
13
|
+
<div className={styles['wait-indicator'] + (wait ? ' ' + styles['active'] : '')}>
|
|
14
|
+
<Spinner size="small" color="contrast"/>
|
|
15
|
+
</div>
|
|
16
|
+
</div>)
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default Button;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/* Button */
|
|
2
|
+
|
|
3
|
+
.container {
|
|
4
|
+
position: relative;
|
|
5
|
+
border: 1px solid #5EBED6;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.container button {
|
|
9
|
+
display: block;
|
|
10
|
+
width: 100%;
|
|
11
|
+
height: 100%;
|
|
12
|
+
background-color: #BED4DB;
|
|
13
|
+
border: 0;
|
|
14
|
+
padding: 5px 8px;
|
|
15
|
+
font-size: 1.1em;
|
|
16
|
+
color: #1D1D1B;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
border-radius: 0.1em;
|
|
19
|
+
transition: background-color 0.3s;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.container button:hover {
|
|
23
|
+
background-color: #ADCED8;
|
|
24
|
+
color: #1D1D1B;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.container > .wait-indicator {
|
|
28
|
+
position: absolute;
|
|
29
|
+
display: flex;
|
|
30
|
+
top: 0;
|
|
31
|
+
left: 0;
|
|
32
|
+
width: 100%;
|
|
33
|
+
height: 100%;
|
|
34
|
+
justify-content: center;
|
|
35
|
+
align-items: center;
|
|
36
|
+
background-color: #BED4DB;
|
|
37
|
+
z-index: -1;
|
|
38
|
+
opacity: 0;
|
|
39
|
+
transition: opacity 0.3s;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.container > .wait-indicator.active {
|
|
43
|
+
opacity: 1;
|
|
44
|
+
z-index: 1;
|
|
45
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
import Spinner from "../Spinner";
|
|
3
|
+
import type { TFileData } from "../File";
|
|
4
|
+
import styles from "./style.module.css";
|
|
5
|
+
|
|
6
|
+
export type TImageData = TFileData & {
|
|
7
|
+
id?: string | number;
|
|
8
|
+
setWait: (status: boolean) => void;
|
|
9
|
+
setId: (id: string | number) => void;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export interface IImage extends TFileData {
|
|
13
|
+
onChange?: (data: TImageData) => void;
|
|
14
|
+
onId?: (id: string | number) => void;
|
|
15
|
+
onRemove?: () => void;
|
|
16
|
+
onClick?: (data: TImageData) => void;
|
|
17
|
+
id?: string | number;
|
|
18
|
+
src?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const Image = ({onChange, onClick, onId, onRemove, ...props}: IImage) => {
|
|
22
|
+
const { base64, src } = props;
|
|
23
|
+
const [wait, setWait] = useState(true);
|
|
24
|
+
const confirmRemove = useRef(false);
|
|
25
|
+
const currentId = useRef<string | number | undefined>();
|
|
26
|
+
const setId = (id: string | number) => {
|
|
27
|
+
currentId.current = id;
|
|
28
|
+
if (typeof onId !== 'function') return;
|
|
29
|
+
onId(id);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const handleClick = () => {
|
|
33
|
+
if (typeof onClick === 'function') {
|
|
34
|
+
onClick({
|
|
35
|
+
...props,
|
|
36
|
+
setWait,
|
|
37
|
+
setId,
|
|
38
|
+
id: currentId.current
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const handleLoad = () => {
|
|
44
|
+
setWait(false);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handleRemove = (e: React.MouseEvent<HTMLSpanElement>) => {
|
|
48
|
+
if (!e.target) return;
|
|
49
|
+
const element = (e.target as HTMLSpanElement);
|
|
50
|
+
|
|
51
|
+
const remove = () => {
|
|
52
|
+
if (!confirmRemove.current) return;
|
|
53
|
+
confirmRemove.current = false;
|
|
54
|
+
element.blur();
|
|
55
|
+
if (typeof onRemove === 'function') {
|
|
56
|
+
onRemove();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
remove();
|
|
60
|
+
confirmRemove.current = true;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const handleCancelRemove = () => {
|
|
64
|
+
confirmRemove.current = false;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (typeof onChange !== 'function' || src) return;
|
|
69
|
+
onChange({
|
|
70
|
+
...props,
|
|
71
|
+
setWait,
|
|
72
|
+
setId,
|
|
73
|
+
id: currentId.current
|
|
74
|
+
});
|
|
75
|
+
}, []);
|
|
76
|
+
|
|
77
|
+
return(<span className={styles['image']} onClick={handleClick}>
|
|
78
|
+
<span className={styles['close']} onClick={handleRemove} onBlur={handleCancelRemove} tabIndex={1}/>
|
|
79
|
+
<img src={src ?? base64?.toString()} onLoad={handleLoad}/>
|
|
80
|
+
{wait && <span className={styles['wait']}>
|
|
81
|
+
<Spinner size="small" color="contrast"/>
|
|
82
|
+
</span>}
|
|
83
|
+
</span>);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export default Image;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import File,{
|
|
3
|
+
TFileData
|
|
4
|
+
} from "../File";
|
|
5
|
+
import styles from "./style.module.css";
|
|
6
|
+
|
|
7
|
+
import Image,{
|
|
8
|
+
TImageData,
|
|
9
|
+
IImage
|
|
10
|
+
} from "./Image";
|
|
11
|
+
|
|
12
|
+
export interface IUploadImages {
|
|
13
|
+
onChange?: (data: TImageData) => void;
|
|
14
|
+
onChangeArray?: (data: IImage[]) => void;
|
|
15
|
+
onClick?: (data: TImageData) => void;
|
|
16
|
+
imagesArray?: TImageData[];
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const UploadImages = ({imagesArray, onChange, onChangeArray, onClick}: IUploadImages) => {
|
|
20
|
+
const [images, setImages] = useState<IImage[]>([]);
|
|
21
|
+
|
|
22
|
+
const handleChange = (image: TFileData) => {
|
|
23
|
+
setImages((images) => [...images, {...image}]);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const handleChangeId = (image: IImage) => {
|
|
27
|
+
return (id: string | number) => {
|
|
28
|
+
setImages((images) => images.map((currentImage) => {
|
|
29
|
+
if (image === currentImage) {
|
|
30
|
+
currentImage.id = id;
|
|
31
|
+
}
|
|
32
|
+
return currentImage;
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const handleRemove = (image: IImage) => {
|
|
38
|
+
return () => setImages((images) => images.filter((currentImage) => currentImage !== image));
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (typeof onChangeArray !== 'function') return;
|
|
43
|
+
onChangeArray(images);
|
|
44
|
+
}, [images]);
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (!imagesArray) return;
|
|
48
|
+
setImages(imagesArray);
|
|
49
|
+
}, [imagesArray]);
|
|
50
|
+
|
|
51
|
+
return(<div className={styles['container']}>
|
|
52
|
+
{images.map((image, index) => <Image key={(image.name + index)} {...image} onChange={onChange} onClick={onClick} onRemove={handleRemove(image)} onId={handleChangeId(image)}/>)}
|
|
53
|
+
<File onChange={handleChange} accept={['image/png']} className={styles['new']} multiple/>
|
|
54
|
+
</div>);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default UploadImages;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/* UploadImages */
|
|
2
|
+
|
|
3
|
+
.container {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: row;
|
|
6
|
+
justify-content: flex-start;
|
|
7
|
+
flex-wrap: wrap;
|
|
8
|
+
width: 100%;
|
|
9
|
+
gap: 10px;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.image, .new {
|
|
13
|
+
position: relative;
|
|
14
|
+
display: flex;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
align-items: center;
|
|
17
|
+
width: 80px;
|
|
18
|
+
height: 80px;
|
|
19
|
+
border: 1px solid #b1b0b0;
|
|
20
|
+
background-color: #BED4DB;
|
|
21
|
+
border-radius: 3px;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
transition: scale 0.3s, box-shadow 0.3s;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.image:hover, .new:hover {
|
|
27
|
+
scale: 1.03;
|
|
28
|
+
box-shadow: 0px 0px 6px 2px rgb(0 0 0 / 10%);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.image:active, .new:active {
|
|
32
|
+
scale: 0.99;
|
|
33
|
+
box-shadow: unset
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.image > img {
|
|
37
|
+
width: 100%;
|
|
38
|
+
object-fit: cover;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* Close */
|
|
42
|
+
.image .close {
|
|
43
|
+
display: flex;
|
|
44
|
+
position: absolute;
|
|
45
|
+
top: 0;
|
|
46
|
+
right: 0;
|
|
47
|
+
justify-content: center;
|
|
48
|
+
align-items: center;
|
|
49
|
+
width: 20px;
|
|
50
|
+
height: 20px;
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
opacity: 0.7;
|
|
53
|
+
transition: transform 0.3s, opacity 0.3s;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.image .close::before, .image .close::after {
|
|
57
|
+
content: "";
|
|
58
|
+
display: block;
|
|
59
|
+
position: absolute;
|
|
60
|
+
width: 100%;
|
|
61
|
+
height: 3px;
|
|
62
|
+
background-color: #1D1D1B;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.image .close::before {
|
|
66
|
+
transform: rotate(45deg);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.image .close::after {
|
|
70
|
+
transform: rotate(-45deg);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.image .close:focus {
|
|
74
|
+
background-color: red;
|
|
75
|
+
width: 100%;
|
|
76
|
+
height: 100%;
|
|
77
|
+
transition: width 0.1s, height 0.3s;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.image .close:focus::before, .image .close:focus::after {
|
|
81
|
+
background-color: #FFFFFF;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.new {
|
|
85
|
+
display: flex;
|
|
86
|
+
justify-content: center;
|
|
87
|
+
align-items: center;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.new::after {
|
|
91
|
+
content: "+";
|
|
92
|
+
font-size: 1.9em;
|
|
93
|
+
color: #777777;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.wait {
|
|
97
|
+
display: flex;
|
|
98
|
+
position: absolute;
|
|
99
|
+
justify-content: center;
|
|
100
|
+
align-items: center;
|
|
101
|
+
width: 100%;
|
|
102
|
+
height: 100%;
|
|
103
|
+
top: 0;
|
|
104
|
+
left: 0;
|
|
105
|
+
backdrop-filter: blur(2px);
|
|
106
|
+
background-color: #BED4DB9F;
|
|
107
|
+
z-index: 1;
|
|
108
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import Form,{
|
|
2
|
-
useForm
|
|
2
|
+
useForm,
|
|
3
|
+
FormElement
|
|
3
4
|
} from "./Form";
|
|
5
|
+
import Element,{
|
|
6
|
+
IElement
|
|
7
|
+
} from "./Form/Element";
|
|
4
8
|
import Input from "./Input";
|
|
5
9
|
import TextArea from "./TextArea";
|
|
6
10
|
import Spinner from "./Spinner";
|
|
@@ -8,6 +12,12 @@ import File,{
|
|
|
8
12
|
TFileData,
|
|
9
13
|
TFileMime
|
|
10
14
|
} from "./File";
|
|
15
|
+
import Button from "./Button";
|
|
16
|
+
import UploadImages,{
|
|
17
|
+
IUploadImages,
|
|
18
|
+
TImageData,
|
|
19
|
+
IImage
|
|
20
|
+
} from "./UploadImages";
|
|
11
21
|
|
|
12
22
|
const UI = {
|
|
13
23
|
|
|
@@ -15,14 +25,22 @@ const UI = {
|
|
|
15
25
|
|
|
16
26
|
export {
|
|
17
27
|
Form,
|
|
28
|
+
FormElement,
|
|
29
|
+
Element,
|
|
18
30
|
useForm,
|
|
19
31
|
Input,
|
|
20
32
|
TextArea,
|
|
21
33
|
Spinner,
|
|
22
|
-
File
|
|
34
|
+
File,
|
|
35
|
+
Button,
|
|
36
|
+
UploadImages
|
|
23
37
|
};
|
|
24
38
|
export type {
|
|
25
39
|
TFileData,
|
|
26
|
-
TFileMime
|
|
40
|
+
TFileMime,
|
|
41
|
+
IUploadImages,
|
|
42
|
+
IImage,
|
|
43
|
+
TImageData,
|
|
44
|
+
IElement
|
|
27
45
|
};
|
|
28
46
|
export default UI;
|
package/webpack.config.js
CHANGED
|
@@ -2,7 +2,7 @@ const path = require('path');
|
|
|
2
2
|
|
|
3
3
|
module.exports = {
|
|
4
4
|
entry: {
|
|
5
|
-
index: '/src/index.ts'
|
|
5
|
+
index: '/src/index.ts'
|
|
6
6
|
},
|
|
7
7
|
target: 'web',
|
|
8
8
|
mode: 'production', //production | development
|
|
@@ -46,7 +46,6 @@ module.exports = {
|
|
|
46
46
|
path: path.resolve(__dirname, 'dist'),
|
|
47
47
|
library: 'UI',
|
|
48
48
|
libraryTarget: 'umd',
|
|
49
|
-
chunkFilename: '[name].chunk.js',
|
|
50
49
|
auxiliaryComment: 'Arta System UI'
|
|
51
50
|
},
|
|
52
51
|
externals: {
|