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.
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ interface IButton extends React.ButtonHTMLAttributes<HTMLButtonElement> {
3
+ wait?: boolean;
4
+ }
5
+ declare const Button: ({ children, wait, ...props }: IButton) => JSX.Element;
6
+ export default Button;
@@ -0,0 +1,2 @@
1
+ import Button from "./Button";
2
+ export default Button;
@@ -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;
@@ -0,0 +1,5 @@
1
+ import UploadImages, { IUploadImages } from "./UploadImages";
2
+ import type { IImage } from "./Image";
3
+ import { TImageData } from "./Image";
4
+ export type { IUploadImages, TImageData, IImage };
5
+ 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-artasys-ui",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -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,3 @@
1
+ import Button from "./Button";
2
+
3
+ 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,13 @@
1
+ import UploadImages,{
2
+ IUploadImages
3
+ } from "./UploadImages";
4
+ import type { IImage } from "./Image";
5
+ import {
6
+ TImageData
7
+ } from "./Image";
8
+ export type {
9
+ IUploadImages,
10
+ TImageData,
11
+ IImage
12
+ };
13
+ 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: {