forstok-ui-lib 5.1.5 → 5.1.7
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.d.ts +16 -1
- package/dist/index.js +134 -43
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +132 -41
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/assets/images/icons/arrow-red-upload.svg +48 -0
- package/src/assets/images/icons/arrow-upload.svg +47 -0
- package/src/assets/javascripts/function.ts +12 -1
- package/src/components/icon/styles.ts +8 -0
- package/src/components/index.ts +2 -0
- package/src/components/upload/drag_drop.tsx +85 -0
- package/src/components/upload/index.tsx +31 -0
- package/src/components/upload/styles.tsx +127 -0
package/package.json
CHANGED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
2
|
+
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
3
|
+
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
4
|
+
viewBox="0 0 491.95 491.95" style="enable-background:new 0 0 491.95 491.95; fill:#D80027;" xml:space="preserve">
|
|
5
|
+
<g>
|
|
6
|
+
<g>
|
|
7
|
+
<path d="M365.675,112.25l-107-107c-7-7-18.4-7-25.5,0l-107,107c-7,7-7,18.4,0,25.5c7.1,7,18.5,7,25.5-0.1l76.3-76.2v310.6
|
|
8
|
+
c0,9.9,8.1,18,18,18c9.9,0,18-8.1,18-18V61.45l76.3,76.3c3.5,3.5,8.1,5.3,12.7,5.3c4.6,0,9.2-1.8,12.7-5.3
|
|
9
|
+
C372.675,130.75,372.675,119.35,365.675,112.25z"/>
|
|
10
|
+
</g>
|
|
11
|
+
</g>
|
|
12
|
+
<g>
|
|
13
|
+
<g>
|
|
14
|
+
<path d="M439.975,336.35c-9.9,0-18,8.1-18,18v101.6h-352v-101.6c0-9.9-8.1-18-18-18s-18,8.1-18,18v119.6c0,9.9,8,18,18,18h388
|
|
15
|
+
c9.9,0,18-8.1,18-18v-119.6C457.975,344.45,449.875,336.35,439.975,336.35z"/>
|
|
16
|
+
</g>
|
|
17
|
+
</g>
|
|
18
|
+
<g>
|
|
19
|
+
</g>
|
|
20
|
+
<g>
|
|
21
|
+
</g>
|
|
22
|
+
<g>
|
|
23
|
+
</g>
|
|
24
|
+
<g>
|
|
25
|
+
</g>
|
|
26
|
+
<g>
|
|
27
|
+
</g>
|
|
28
|
+
<g>
|
|
29
|
+
</g>
|
|
30
|
+
<g>
|
|
31
|
+
</g>
|
|
32
|
+
<g>
|
|
33
|
+
</g>
|
|
34
|
+
<g>
|
|
35
|
+
</g>
|
|
36
|
+
<g>
|
|
37
|
+
</g>
|
|
38
|
+
<g>
|
|
39
|
+
</g>
|
|
40
|
+
<g>
|
|
41
|
+
</g>
|
|
42
|
+
<g>
|
|
43
|
+
</g>
|
|
44
|
+
<g>
|
|
45
|
+
</g>
|
|
46
|
+
<g>
|
|
47
|
+
</g>
|
|
48
|
+
</svg>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
2
|
+
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
3
|
+
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
4
|
+
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
|
5
|
+
<g>
|
|
6
|
+
<g>
|
|
7
|
+
<path d="M472,312.642v139c0,11.028-8.972,20-20,20H60c-11.028,0-20-8.972-20-20v-139H0v139c0,33.084,26.916,60,60,60h392
|
|
8
|
+
c33.084,0,60-26.916,60-60v-139H472z"/>
|
|
9
|
+
</g>
|
|
10
|
+
</g>
|
|
11
|
+
<g>
|
|
12
|
+
<g>
|
|
13
|
+
<polygon points="256,0.358 131.716,124.642 160,152.926 236,76.926 236,388.642 276,388.642 276,76.926 352,152.926
|
|
14
|
+
380.284,124.642 "/>
|
|
15
|
+
</g>
|
|
16
|
+
</g>
|
|
17
|
+
<g>
|
|
18
|
+
</g>
|
|
19
|
+
<g>
|
|
20
|
+
</g>
|
|
21
|
+
<g>
|
|
22
|
+
</g>
|
|
23
|
+
<g>
|
|
24
|
+
</g>
|
|
25
|
+
<g>
|
|
26
|
+
</g>
|
|
27
|
+
<g>
|
|
28
|
+
</g>
|
|
29
|
+
<g>
|
|
30
|
+
</g>
|
|
31
|
+
<g>
|
|
32
|
+
</g>
|
|
33
|
+
<g>
|
|
34
|
+
</g>
|
|
35
|
+
<g>
|
|
36
|
+
</g>
|
|
37
|
+
<g>
|
|
38
|
+
</g>
|
|
39
|
+
<g>
|
|
40
|
+
</g>
|
|
41
|
+
<g>
|
|
42
|
+
</g>
|
|
43
|
+
<g>
|
|
44
|
+
</g>
|
|
45
|
+
<g>
|
|
46
|
+
</g>
|
|
47
|
+
</svg>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { TMessage, TMessageQuestion } from '../../components/message/typed';
|
|
2
3
|
|
|
3
4
|
export const formatNumber = (n?: string | number, flag?: boolean) => {
|
|
4
5
|
const _flag = flag === undefined ? true : flag
|
|
@@ -15,6 +16,16 @@ export const formatNumber = (n?: string | number, flag?: boolean) => {
|
|
|
15
16
|
return result
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
export const generateMessage = (type: string, value: string | ReactNode, callback?: () => void, timer?: number) => {
|
|
20
|
+
let result: TMessage = {
|
|
21
|
+
$type: type,
|
|
22
|
+
message: value,
|
|
23
|
+
timer: timer || (type === 'warning' ? 3000 : 2000)
|
|
24
|
+
}
|
|
25
|
+
callback && (result.callback = () => { callback() })
|
|
26
|
+
return result
|
|
27
|
+
}
|
|
28
|
+
|
|
18
29
|
export const generateMessageQuestion = (type: string, title: string, subtitle: string, callback?: () => void, buttonSubmit?: string, cancelCallback?: () => void) => {
|
|
19
30
|
let result: TMessageQuestion = {
|
|
20
31
|
$type: type,
|
|
@@ -6,6 +6,7 @@ import IconCheckGrey from '../../assets/images/icons/checkmark-tick-grey.svg';
|
|
|
6
6
|
import IconCheck from '../../assets/images/icons/checkmark-tick.svg';
|
|
7
7
|
import IconEdit from '../../assets/images/icons/edit.svg';
|
|
8
8
|
import IconArrow from '../../assets/images/icons/arrow.svg';
|
|
9
|
+
import IconArrowUpload from '../../assets/images/icons/arrow-upload.svg'
|
|
9
10
|
import IconDiscount from '../../assets/images/icons/discount.svg';
|
|
10
11
|
import IconCash from '../../assets/images/icons/cash.svg';
|
|
11
12
|
import IconCredit from '../../assets/images/icons/credit.svg';
|
|
@@ -156,6 +157,13 @@ const getIconContainerStyled = ({ $mode, $name, $width, onClick }:{ $mode?: stri
|
|
|
156
157
|
}
|
|
157
158
|
`
|
|
158
159
|
break;
|
|
160
|
+
case 'arrow-upload':
|
|
161
|
+
style += `
|
|
162
|
+
&:before {
|
|
163
|
+
content: url(${IconArrowUpload});
|
|
164
|
+
}
|
|
165
|
+
`
|
|
166
|
+
break;
|
|
159
167
|
default:
|
|
160
168
|
break;
|
|
161
169
|
}
|
package/src/components/index.ts
CHANGED
|
@@ -15,6 +15,8 @@ export { default as ReactPortalComponent } from './portal';
|
|
|
15
15
|
export { default as ImageComponent } from './image';
|
|
16
16
|
export { default as SelectComponent } from './select';
|
|
17
17
|
export { default as ErrorComponent } from './error';
|
|
18
|
+
export { default as UploadComponent } from './upload';
|
|
19
|
+
export { default as UploadDragDropComponent } from './upload/drag_drop';
|
|
18
20
|
|
|
19
21
|
export * from './dropdown/typed';
|
|
20
22
|
export * from './message/typed';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { type InputHTMLAttributes, type ReactNode, useState } from 'react';
|
|
2
|
+
import { generateMessage } from '../../assets/javascripts/function';
|
|
3
|
+
import { UploadDragDropContainer, UploadDragDropFileHelper, UploadDragDropFileContainer, UploadInput, UploadDragDropLabel, UploadDragDropFileName, UploadDragDropFileNamePlaceholder, UploadDragDropIcon } from './styles';
|
|
4
|
+
import type { TChangeEvent, TDragEvent } from '../../typeds/base.typed';
|
|
5
|
+
import type { TMessageFunction } from '../message/typed';
|
|
6
|
+
|
|
7
|
+
type TUpload = InputHTMLAttributes<HTMLInputElement> & {
|
|
8
|
+
children?: ReactNode
|
|
9
|
+
evChange?: (arg0: FileList) => void
|
|
10
|
+
evCreateMessage?: TMessageFunction
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const UploadDragDropComponent = ({ children, id, name, evChange, evCreateMessage, ...props }: TUpload) => {
|
|
14
|
+
const { accept } = props;
|
|
15
|
+
|
|
16
|
+
const [dragActive, setDragActive] = useState<boolean>(false);
|
|
17
|
+
|
|
18
|
+
const handleDrag: TDragEvent = e => {
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
e.stopPropagation();
|
|
21
|
+
if (e.type === "dragenter" || e.type === "dragover") {
|
|
22
|
+
setDragActive(true);
|
|
23
|
+
}
|
|
24
|
+
else if (e.type === "dragleave") {
|
|
25
|
+
setDragActive(false);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const handleDrop: TDragEvent = e => {
|
|
30
|
+
e.preventDefault();
|
|
31
|
+
e.stopPropagation();
|
|
32
|
+
setDragActive(false);
|
|
33
|
+
if (e.dataTransfer.files[0]) {
|
|
34
|
+
const acceptedFormat = accept ? accept.split(',').map(_accept => _accept.trim().replace('.', '')) : null;
|
|
35
|
+
for (let x= 0; x < e.dataTransfer.files.length; x++) {
|
|
36
|
+
const curFile = e.dataTransfer.files[x];
|
|
37
|
+
const curFormat = curFile.name.split('.').pop();
|
|
38
|
+
if (acceptedFormat?.length && curFormat) {
|
|
39
|
+
if (!acceptedFormat.includes(curFormat)) {
|
|
40
|
+
const _failed_props = generateMessage('failed', 'File type is not allowed. Please check again');
|
|
41
|
+
evCreateMessage && evCreateMessage(_failed_props);
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
evChange && evChange(e.dataTransfer.files);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const handleChange: TChangeEvent = e => {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
const target = e.target as HTMLInputElement;
|
|
53
|
+
if (target.files && target.files[0]) {
|
|
54
|
+
evChange && evChange(target.files);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<UploadDragDropContainer onDragEnter={handleDrag} className={dragActive ? "drag-active" : "" }>
|
|
60
|
+
<UploadInput id={id} name={name} onChange={handleChange} {...props} />
|
|
61
|
+
<UploadDragDropLabel id="label-file-dragdrop-upload" htmlFor={id}>
|
|
62
|
+
<UploadDragDropFileContainer>
|
|
63
|
+
{
|
|
64
|
+
children ? (
|
|
65
|
+
<UploadDragDropFileName>
|
|
66
|
+
<UploadDragDropIcon />
|
|
67
|
+
<span>
|
|
68
|
+
{children}
|
|
69
|
+
</span>
|
|
70
|
+
</UploadDragDropFileName>
|
|
71
|
+
) :
|
|
72
|
+
(
|
|
73
|
+
<UploadDragDropFileNamePlaceholder>
|
|
74
|
+
Drag & Drop file here to upload, or <span>browse</span>.
|
|
75
|
+
</UploadDragDropFileNamePlaceholder>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
</UploadDragDropFileContainer>
|
|
79
|
+
</UploadDragDropLabel>
|
|
80
|
+
{ dragActive && <UploadDragDropFileHelper onDragEnter={handleDrag} onDragLeave={handleDrag} onDragOver={handleDrag} onDrop={handleDrop} /> }
|
|
81
|
+
</UploadDragDropContainer>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export default UploadDragDropComponent
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { InputHTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { UploadContainer, UploadInput, UploadLabel, UploadIcon, UploadSpan } from './styles';
|
|
3
|
+
|
|
4
|
+
type TUpload = InputHTMLAttributes<HTMLInputElement> & {
|
|
5
|
+
children?: ReactNode
|
|
6
|
+
mode?: string
|
|
7
|
+
'data-idx'?: number
|
|
8
|
+
'data-detail'?: any
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const UploadComponent = ({ children, mode, ...props }: TUpload) => {
|
|
12
|
+
const { id, width } = props;
|
|
13
|
+
return (
|
|
14
|
+
mode === 'image' ? (
|
|
15
|
+
<>
|
|
16
|
+
{children}
|
|
17
|
+
<UploadInput {...('data-idx' in props) && {'data-idx': props['data-idx']}} {...props['data-detail'] && { 'data-detail': props['data-detail'] }} {...props} />
|
|
18
|
+
</>
|
|
19
|
+
) : (
|
|
20
|
+
<UploadContainer $width={width}>
|
|
21
|
+
<UploadLabel htmlFor={id}>
|
|
22
|
+
<UploadIcon></UploadIcon>
|
|
23
|
+
<UploadSpan>{children}</UploadSpan>
|
|
24
|
+
</UploadLabel>
|
|
25
|
+
<UploadInput {...('data-idx' in props) && {'data-idx': props['data-idx']}} {...props['data-detail'] && { 'data-detail': props['data-detail'] }} {...props} />
|
|
26
|
+
</UploadContainer>
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default UploadComponent;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components';
|
|
2
|
+
import IconRedUpload from '../../assets/images/icons/arrow-red-upload.svg';
|
|
3
|
+
|
|
4
|
+
const IconStyles = css`
|
|
5
|
+
display: inline-block;
|
|
6
|
+
pointer-events: none;
|
|
7
|
+
`
|
|
8
|
+
|
|
9
|
+
const getUploadContainerModifiedStyled = ({ $width }: { $width?: string | number }) => {
|
|
10
|
+
let style = ''
|
|
11
|
+
if ($width) {
|
|
12
|
+
style += `
|
|
13
|
+
&, & ${UploadLabel} {
|
|
14
|
+
width: ${$width};
|
|
15
|
+
display: block;
|
|
16
|
+
}
|
|
17
|
+
& ${UploadSpan} {
|
|
18
|
+
width: calc(width - 15);
|
|
19
|
+
display: block;
|
|
20
|
+
}
|
|
21
|
+
`
|
|
22
|
+
}
|
|
23
|
+
return style
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const UploadContainer = styled.div<{ $width?: string | number }>`
|
|
27
|
+
cursor: pointer;
|
|
28
|
+
${getUploadContainerModifiedStyled}
|
|
29
|
+
`
|
|
30
|
+
export const UploadLabel = styled.label`
|
|
31
|
+
padding: 5px 10px 5px 25px;
|
|
32
|
+
color: var(--sta-clr);
|
|
33
|
+
border: 1px solid var(--err-clr-ln);
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
white-space: nowrap;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
position: relative;
|
|
38
|
+
font-weight: 600;
|
|
39
|
+
border-radius: var(--ter-rd);
|
|
40
|
+
`
|
|
41
|
+
export const UploadSpan = styled.span`
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
text-overflow: ellipsis;
|
|
44
|
+
white-space: nowrap;
|
|
45
|
+
`
|
|
46
|
+
export const UploadIcon = styled.i`
|
|
47
|
+
position: absolute;
|
|
48
|
+
left: 10px;
|
|
49
|
+
&:before {
|
|
50
|
+
${IconStyles}
|
|
51
|
+
content: url(${IconRedUpload});
|
|
52
|
+
width: 12px;
|
|
53
|
+
}
|
|
54
|
+
`
|
|
55
|
+
export const UploadInput = styled.input.attrs(({ type }:{ type?: string }) => ({
|
|
56
|
+
type: type || 'file'
|
|
57
|
+
}))`
|
|
58
|
+
opacity: 0;
|
|
59
|
+
position: absolute;
|
|
60
|
+
left: 0;
|
|
61
|
+
`
|
|
62
|
+
export const UploadDragDropContainer = styled.div`
|
|
63
|
+
display: grid;
|
|
64
|
+
position: relative;
|
|
65
|
+
align-items: center;
|
|
66
|
+
text-align: center;
|
|
67
|
+
min-height: 150px;
|
|
68
|
+
border: 1.25px dashed rgba(163, 163, 163, 0.5);
|
|
69
|
+
border-radius: 4px;
|
|
70
|
+
background-color: #EFEFEF;
|
|
71
|
+
&.drag-active {
|
|
72
|
+
background-color: #EFEFEF50;
|
|
73
|
+
}
|
|
74
|
+
${UploadInput} {
|
|
75
|
+
z-index: -10;
|
|
76
|
+
}
|
|
77
|
+
`
|
|
78
|
+
export const UploadDragDropLabel = styled.label`
|
|
79
|
+
padding: 5px 10px;
|
|
80
|
+
overflow: hidden;
|
|
81
|
+
white-space: nowrap;
|
|
82
|
+
cursor: pointer;
|
|
83
|
+
position: relative;
|
|
84
|
+
`
|
|
85
|
+
export const UploadDragDropFileHelper = styled.div`
|
|
86
|
+
position: absolute;
|
|
87
|
+
width: 100%;
|
|
88
|
+
height: 100%;
|
|
89
|
+
top: 0px;
|
|
90
|
+
right: 0px;
|
|
91
|
+
bottom: 0px;
|
|
92
|
+
left: 0px;
|
|
93
|
+
`
|
|
94
|
+
export const UploadDragDropFileContainer = styled.div`
|
|
95
|
+
overflow: hidden;
|
|
96
|
+
text-overflow: ellipsis;
|
|
97
|
+
white-space: nowrap;
|
|
98
|
+
`
|
|
99
|
+
export const UploadDragDropFileNamePlaceholder = styled.div`
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
text-overflow: ellipsis;
|
|
102
|
+
white-space: nowrap;
|
|
103
|
+
> span {
|
|
104
|
+
color: #FF585C;
|
|
105
|
+
font-weight: 600;
|
|
106
|
+
}
|
|
107
|
+
`
|
|
108
|
+
export const UploadDragDropFileName = styled.div`
|
|
109
|
+
display: grid;
|
|
110
|
+
grid-auto-flow: column;
|
|
111
|
+
justify-content: center;
|
|
112
|
+
grid-gap: 6px
|
|
113
|
+
font-weight: 600;
|
|
114
|
+
color: #FF585C;
|
|
115
|
+
> span {
|
|
116
|
+
overflow: hidden;
|
|
117
|
+
text-overflow: ellipsis;
|
|
118
|
+
white-space: nowrap;
|
|
119
|
+
}
|
|
120
|
+
`
|
|
121
|
+
export const UploadDragDropIcon = styled.i`
|
|
122
|
+
&:before {
|
|
123
|
+
content: url(${IconRedUpload});
|
|
124
|
+
width: 14px;
|
|
125
|
+
${IconStyles}
|
|
126
|
+
}
|
|
127
|
+
`
|