siam-ui-utils 2.2.18 → 2.2.20
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/eslint.config.mjs +45 -45
- package/package.json +1 -2
- package/src/dropzone/Dropzone.tsx +816 -0
- package/src/dropzone/Input.tsx +76 -0
- package/src/dropzone/Layout.tsx +57 -0
- package/src/dropzone/Preview.tsx +139 -0
- package/src/dropzone/SubmitButton.tsx +47 -0
- package/src/dropzone/assets/cancel.svg +1 -0
- package/src/dropzone/assets/remove.svg +1 -0
- package/src/dropzone/assets/restart.svg +1 -0
- package/src/dropzone/styles.css +140 -0
- package/src/dropzone/utils.ts +113 -0
- package/src/{archivos-adjuntos → dropzone-uploader}/dropzone-uploader-dni-digital/index.jsx +4 -5
- package/src/{archivos-adjuntos → dropzone-uploader}/index.jsx +4 -5
- package/src/index.js +2 -2
- /package/src/{archivos-adjuntos → dropzone-uploader}/dropzone-uploader.css +0 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import { IInputProps } from './Dropzone'
|
|
5
|
+
|
|
6
|
+
const Input = (props: IInputProps) => {
|
|
7
|
+
const {
|
|
8
|
+
className,
|
|
9
|
+
labelClassName,
|
|
10
|
+
labelWithFilesClassName,
|
|
11
|
+
style,
|
|
12
|
+
labelStyle,
|
|
13
|
+
labelWithFilesStyle,
|
|
14
|
+
getFilesFromEvent,
|
|
15
|
+
accept,
|
|
16
|
+
multiple,
|
|
17
|
+
disabled,
|
|
18
|
+
content,
|
|
19
|
+
withFilesContent,
|
|
20
|
+
onFiles,
|
|
21
|
+
files,
|
|
22
|
+
} = props
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<label
|
|
26
|
+
className={files.length > 0 ? labelWithFilesClassName : labelClassName}
|
|
27
|
+
style={files.length > 0 ? labelWithFilesStyle : labelStyle}
|
|
28
|
+
>
|
|
29
|
+
{files.length > 0 ? withFilesContent : content}
|
|
30
|
+
<input
|
|
31
|
+
className={className}
|
|
32
|
+
style={style}
|
|
33
|
+
type="file"
|
|
34
|
+
accept={accept}
|
|
35
|
+
multiple={multiple}
|
|
36
|
+
disabled={disabled}
|
|
37
|
+
onChange={async e => {
|
|
38
|
+
const target = e.target
|
|
39
|
+
const chosenFiles = await getFilesFromEvent(e)
|
|
40
|
+
onFiles(chosenFiles)
|
|
41
|
+
//@ts-ignore
|
|
42
|
+
target.value = null
|
|
43
|
+
}}
|
|
44
|
+
/>
|
|
45
|
+
</label>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
Input.propTypes = {
|
|
50
|
+
className: PropTypes.string,
|
|
51
|
+
labelClassName: PropTypes.string,
|
|
52
|
+
labelWithFilesClassName: PropTypes.string,
|
|
53
|
+
style: PropTypes.object,
|
|
54
|
+
labelStyle: PropTypes.object,
|
|
55
|
+
labelWithFilesStyle: PropTypes.object,
|
|
56
|
+
getFilesFromEvent: PropTypes.func.isRequired,
|
|
57
|
+
accept: PropTypes.string.isRequired,
|
|
58
|
+
multiple: PropTypes.bool.isRequired,
|
|
59
|
+
disabled: PropTypes.bool.isRequired,
|
|
60
|
+
content: PropTypes.node,
|
|
61
|
+
withFilesContent: PropTypes.node,
|
|
62
|
+
onFiles: PropTypes.func.isRequired,
|
|
63
|
+
files: PropTypes.arrayOf(PropTypes.any).isRequired,
|
|
64
|
+
extra: PropTypes.shape({
|
|
65
|
+
active: PropTypes.bool.isRequired,
|
|
66
|
+
reject: PropTypes.bool.isRequired,
|
|
67
|
+
dragged: PropTypes.arrayOf(PropTypes.any).isRequired,
|
|
68
|
+
accept: PropTypes.string.isRequired,
|
|
69
|
+
multiple: PropTypes.bool.isRequired,
|
|
70
|
+
minSizeBytes: PropTypes.number.isRequired,
|
|
71
|
+
maxSizeBytes: PropTypes.number.isRequired,
|
|
72
|
+
maxFiles: PropTypes.number.isRequired,
|
|
73
|
+
}).isRequired,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default Input
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import { ILayoutProps } from './Dropzone'
|
|
5
|
+
|
|
6
|
+
const Layout = (props: ILayoutProps) => {
|
|
7
|
+
const {
|
|
8
|
+
input,
|
|
9
|
+
previews,
|
|
10
|
+
submitButton,
|
|
11
|
+
dropzoneProps,
|
|
12
|
+
files,
|
|
13
|
+
extra: { maxFiles },
|
|
14
|
+
} = props
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div {...dropzoneProps}>
|
|
18
|
+
{previews}
|
|
19
|
+
|
|
20
|
+
{files.length < maxFiles && input}
|
|
21
|
+
|
|
22
|
+
{files.length > 0 && submitButton}
|
|
23
|
+
</div>
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Layout.propTypes = {
|
|
28
|
+
input: PropTypes.node,
|
|
29
|
+
previews: PropTypes.arrayOf(PropTypes.node),
|
|
30
|
+
submitButton: PropTypes.node,
|
|
31
|
+
dropzoneProps: PropTypes.shape({
|
|
32
|
+
ref: PropTypes.any.isRequired,
|
|
33
|
+
className: PropTypes.string.isRequired,
|
|
34
|
+
style: PropTypes.object,
|
|
35
|
+
onDragEnter: PropTypes.func.isRequired,
|
|
36
|
+
onDragOver: PropTypes.func.isRequired,
|
|
37
|
+
onDragLeave: PropTypes.func.isRequired,
|
|
38
|
+
onDrop: PropTypes.func.isRequired,
|
|
39
|
+
}).isRequired,
|
|
40
|
+
files: PropTypes.arrayOf(PropTypes.any).isRequired,
|
|
41
|
+
extra: PropTypes.shape({
|
|
42
|
+
active: PropTypes.bool.isRequired,
|
|
43
|
+
reject: PropTypes.bool.isRequired,
|
|
44
|
+
dragged: PropTypes.arrayOf(PropTypes.any).isRequired,
|
|
45
|
+
accept: PropTypes.string.isRequired,
|
|
46
|
+
multiple: PropTypes.bool.isRequired,
|
|
47
|
+
minSizeBytes: PropTypes.number.isRequired,
|
|
48
|
+
maxSizeBytes: PropTypes.number.isRequired,
|
|
49
|
+
maxFiles: PropTypes.number.isRequired,
|
|
50
|
+
onFiles: PropTypes.func.isRequired,
|
|
51
|
+
onCancelFile: PropTypes.func.isRequired,
|
|
52
|
+
onRemoveFile: PropTypes.func.isRequired,
|
|
53
|
+
onRestartFile: PropTypes.func.isRequired,
|
|
54
|
+
}).isRequired,
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default Layout
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import { formatBytes, formatDuration } from './utils'
|
|
5
|
+
import { IPreviewProps } from './Dropzone'
|
|
6
|
+
//@ts-ignore
|
|
7
|
+
import cancelImg from './assets/cancel.svg'
|
|
8
|
+
//@ts-ignore
|
|
9
|
+
import removeImg from './assets/remove.svg'
|
|
10
|
+
//@ts-ignore
|
|
11
|
+
import restartImg from './assets/restart.svg'
|
|
12
|
+
|
|
13
|
+
const iconByFn = {
|
|
14
|
+
cancel: { backgroundImage: `url(${cancelImg})` },
|
|
15
|
+
remove: { backgroundImage: `url(${removeImg})` },
|
|
16
|
+
restart: { backgroundImage: `url(${restartImg})` },
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
class Preview extends React.PureComponent<IPreviewProps> {
|
|
20
|
+
render() {
|
|
21
|
+
const {
|
|
22
|
+
className,
|
|
23
|
+
imageClassName,
|
|
24
|
+
style,
|
|
25
|
+
imageStyle,
|
|
26
|
+
fileWithMeta: { cancel, remove, restart },
|
|
27
|
+
meta: { name = '', percent = 0, size = 0, previewUrl, status, duration, validationError },
|
|
28
|
+
isUpload,
|
|
29
|
+
canCancel,
|
|
30
|
+
canRemove,
|
|
31
|
+
canRestart,
|
|
32
|
+
extra: { minSizeBytes },
|
|
33
|
+
} = this.props
|
|
34
|
+
|
|
35
|
+
let title = `${name || '?'}, ${formatBytes(size)}`
|
|
36
|
+
if (duration) title = `${title}, ${formatDuration(duration)}`
|
|
37
|
+
|
|
38
|
+
if (status === 'error_file_size' || status === 'error_validation') {
|
|
39
|
+
return (
|
|
40
|
+
<div className={className} style={style}>
|
|
41
|
+
<span className="dzu-previewFileNameError">{title}</span>
|
|
42
|
+
{status === 'error_file_size' && <span>{size < minSizeBytes ? 'File too small' : 'File too big'}</span>}
|
|
43
|
+
{status === 'error_validation' && <span>{String(validationError)}</span>}
|
|
44
|
+
{canRemove && <span className="dzu-previewButton" style={iconByFn.remove} onClick={remove} />}
|
|
45
|
+
</div>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (status === 'error_upload_params' || status === 'exception_upload' || status === 'error_upload') {
|
|
50
|
+
title = `${title} (upload failed)`
|
|
51
|
+
}
|
|
52
|
+
if (status === 'aborted') title = `${title} (cancelled)`
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div className={className} style={style}>
|
|
56
|
+
{previewUrl && <img className={imageClassName} style={imageStyle} src={previewUrl} alt={title} title={title} />}
|
|
57
|
+
{!previewUrl && <span className="dzu-previewFileName">{title}</span>}
|
|
58
|
+
|
|
59
|
+
<div className="dzu-previewStatusContainer">
|
|
60
|
+
{isUpload && (
|
|
61
|
+
<progress max={100} value={status === 'done' || status === 'headers_received' ? 100 : percent} />
|
|
62
|
+
)}
|
|
63
|
+
|
|
64
|
+
{status === 'uploading' && canCancel && (
|
|
65
|
+
<span className="dzu-previewButton" style={iconByFn.cancel} onClick={cancel} />
|
|
66
|
+
)}
|
|
67
|
+
{status !== 'preparing' && status !== 'getting_upload_params' && status !== 'uploading' && canRemove && (
|
|
68
|
+
<span className="dzu-previewButton" style={iconByFn.remove} onClick={remove} />
|
|
69
|
+
)}
|
|
70
|
+
{['error_upload_params', 'exception_upload', 'error_upload', 'aborted', 'ready'].includes(status) &&
|
|
71
|
+
canRestart && <span className="dzu-previewButton" style={iconByFn.restart} onClick={restart} />}
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
Preview.propTypes = {
|
|
80
|
+
className: PropTypes.string,
|
|
81
|
+
imageClassName: PropTypes.string,
|
|
82
|
+
style: PropTypes.object,
|
|
83
|
+
imageStyle: PropTypes.object,
|
|
84
|
+
fileWithMeta: PropTypes.shape({
|
|
85
|
+
file: PropTypes.any.isRequired,
|
|
86
|
+
meta: PropTypes.object.isRequired,
|
|
87
|
+
cancel: PropTypes.func.isRequired,
|
|
88
|
+
restart: PropTypes.func.isRequired,
|
|
89
|
+
remove: PropTypes.func.isRequired,
|
|
90
|
+
xhr: PropTypes.any,
|
|
91
|
+
}).isRequired,
|
|
92
|
+
// copy of fileWithMeta.meta, won't be mutated
|
|
93
|
+
meta: PropTypes.shape({
|
|
94
|
+
status: PropTypes.oneOf([
|
|
95
|
+
'preparing',
|
|
96
|
+
'error_file_size',
|
|
97
|
+
'error_validation',
|
|
98
|
+
'ready',
|
|
99
|
+
'getting_upload_params',
|
|
100
|
+
'error_upload_params',
|
|
101
|
+
'uploading',
|
|
102
|
+
'exception_upload',
|
|
103
|
+
'aborted',
|
|
104
|
+
'error_upload',
|
|
105
|
+
'headers_received',
|
|
106
|
+
'done',
|
|
107
|
+
]).isRequired,
|
|
108
|
+
type: PropTypes.string.isRequired,
|
|
109
|
+
name: PropTypes.string,
|
|
110
|
+
uploadedDate: PropTypes.string.isRequired,
|
|
111
|
+
percent: PropTypes.number,
|
|
112
|
+
size: PropTypes.number,
|
|
113
|
+
lastModifiedDate: PropTypes.string,
|
|
114
|
+
previewUrl: PropTypes.string,
|
|
115
|
+
duration: PropTypes.number,
|
|
116
|
+
width: PropTypes.number,
|
|
117
|
+
height: PropTypes.number,
|
|
118
|
+
videoWidth: PropTypes.number,
|
|
119
|
+
videoHeight: PropTypes.number,
|
|
120
|
+
validationError: PropTypes.any,
|
|
121
|
+
}).isRequired,
|
|
122
|
+
isUpload: PropTypes.bool.isRequired,
|
|
123
|
+
canCancel: PropTypes.bool.isRequired,
|
|
124
|
+
canRemove: PropTypes.bool.isRequired,
|
|
125
|
+
canRestart: PropTypes.bool.isRequired,
|
|
126
|
+
files: PropTypes.arrayOf(PropTypes.any).isRequired, // eslint-disable-line react/no-unused-prop-types
|
|
127
|
+
extra: PropTypes.shape({
|
|
128
|
+
active: PropTypes.bool.isRequired,
|
|
129
|
+
reject: PropTypes.bool.isRequired,
|
|
130
|
+
dragged: PropTypes.arrayOf(PropTypes.any).isRequired,
|
|
131
|
+
accept: PropTypes.string.isRequired,
|
|
132
|
+
multiple: PropTypes.bool.isRequired,
|
|
133
|
+
minSizeBytes: PropTypes.number.isRequired,
|
|
134
|
+
maxSizeBytes: PropTypes.number.isRequired,
|
|
135
|
+
maxFiles: PropTypes.number.isRequired,
|
|
136
|
+
}).isRequired,
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export default Preview
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import { ISubmitButtonProps } from './Dropzone'
|
|
5
|
+
|
|
6
|
+
const SubmitButton = (props: ISubmitButtonProps) => {
|
|
7
|
+
const { className, buttonClassName, style, buttonStyle, disabled, content, onSubmit, files } = props
|
|
8
|
+
|
|
9
|
+
const _disabled =
|
|
10
|
+
files.some(f => ['preparing', 'getting_upload_params', 'uploading'].includes(f.meta.status)) ||
|
|
11
|
+
!files.some(f => ['headers_received', 'done'].includes(f.meta.status))
|
|
12
|
+
|
|
13
|
+
const handleSubmit = () => {
|
|
14
|
+
onSubmit(files.filter(f => ['headers_received', 'done'].includes(f.meta.status)))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div className={className} style={style}>
|
|
19
|
+
<button className={buttonClassName} style={buttonStyle} onClick={handleSubmit} disabled={disabled || _disabled}>
|
|
20
|
+
{content}
|
|
21
|
+
</button>
|
|
22
|
+
</div>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
SubmitButton.propTypes = {
|
|
27
|
+
className: PropTypes.string,
|
|
28
|
+
buttonClassName: PropTypes.string,
|
|
29
|
+
style: PropTypes.object,
|
|
30
|
+
buttonStyle: PropTypes.object,
|
|
31
|
+
disabled: PropTypes.bool.isRequired,
|
|
32
|
+
content: PropTypes.node,
|
|
33
|
+
onSubmit: PropTypes.func.isRequired,
|
|
34
|
+
files: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
35
|
+
extra: PropTypes.shape({
|
|
36
|
+
active: PropTypes.bool.isRequired,
|
|
37
|
+
reject: PropTypes.bool.isRequired,
|
|
38
|
+
dragged: PropTypes.arrayOf(PropTypes.any).isRequired,
|
|
39
|
+
accept: PropTypes.string.isRequired,
|
|
40
|
+
multiple: PropTypes.bool.isRequired,
|
|
41
|
+
minSizeBytes: PropTypes.number.isRequired,
|
|
42
|
+
maxSizeBytes: PropTypes.number.isRequired,
|
|
43
|
+
maxFiles: PropTypes.number.isRequired,
|
|
44
|
+
}).isRequired,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default SubmitButton
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg viewBox="0 0 8 14" xmlns="http://www.w3.org/2000/svg"><g fill="#333333"><path d="M1,14 C0.4,14 0,13.6 0,13 L0,1 C0,0.4 0.4,0 1,0 C1.6,0 2,0.4 2,1 L2,13 C2,13.6 1.6,14 1,14 Z" id="Path"></path><path d="M7,14 C6.4,14 6,13.6 6,13 L6,1 C6,0.4 6.4,0 7,0 C7.6,0 8,0.4 8,1 L8,13 C8,13.6 7.6,14 7,14 Z" id="Path"></path></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-5.0, 0.0)" fill="#333333"><g transform="translate(4.0, 0.0)"><polygon points="7.719 4.964 12.692 0.017 14.389 1.715 9.412 6.666 14.354 11.634 12.657 13.331 6.017 6.657 7.715 4.960"></polygon><polygon points="7.612 4.964 7.616 4.960 9.313 6.657 2.674 13.331 0.977 11.634 5.919 6.666 0.942 1.715 2.639 0.017"></polygon></g></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg viewBox="0 0 11 15" xmlns="http://www.w3.org/2000/svg"><g><path d="M0.5,14.9 C0.2,14.7 0,14.4 0,14 L0,2 C0,1.6 0.2,1.3 0.5,1.1 C0.8,0.9 1.2,0.9 1.5,1.1 L10.5,7.1 C10.8,7.3 10.9,7.6 10.9,7.9 C10.9,8.2 10.7,8.5 10.5,8.7 L1.5,14.7 C1.4,14.9 0.8,15.1 0.5,14.9 Z M2,3.9 L2,12.2 L8.2,8.1 L2,3.9 Z"></path></g></svg>
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
.dzu-dropzone {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
align-items: center;
|
|
5
|
+
width: 100%;
|
|
6
|
+
min-height: 120px;
|
|
7
|
+
overflow: scroll;
|
|
8
|
+
margin: 0 auto;
|
|
9
|
+
position: relative;
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
transition: all .15s linear;
|
|
12
|
+
border: 2px solid #d9d9d9;
|
|
13
|
+
border-radius: 4px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.dzu-dropzoneActive {
|
|
17
|
+
background-color: #DEEBFF;
|
|
18
|
+
border-color: #2484FF;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.dzu-dropzoneDisabled {
|
|
22
|
+
opacity: 0.5;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.dzu-dropzoneDisabled *:hover {
|
|
26
|
+
cursor: unset;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.dzu-input {
|
|
30
|
+
display: none;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.dzu-inputLabel {
|
|
34
|
+
display: flex;
|
|
35
|
+
justify-content: center;
|
|
36
|
+
align-items: center;
|
|
37
|
+
position: absolute;
|
|
38
|
+
top: 0;
|
|
39
|
+
bottom: 0;
|
|
40
|
+
left: 0;
|
|
41
|
+
right: 0;
|
|
42
|
+
font-family: 'Helvetica', sans-serif;
|
|
43
|
+
font-size: 20px;
|
|
44
|
+
font-weight: 600;
|
|
45
|
+
color: #2484FF;
|
|
46
|
+
-moz-osx-font-smoothing: grayscale;
|
|
47
|
+
-webkit-font-smoothing: antialiased;
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.dzu-inputLabelWithFiles {
|
|
52
|
+
display: flex;
|
|
53
|
+
justify-content: center;
|
|
54
|
+
align-items: center;
|
|
55
|
+
align-self: flex-start;
|
|
56
|
+
padding: 0 14px;
|
|
57
|
+
min-height: 32px;
|
|
58
|
+
background-color: #E6E6E6;
|
|
59
|
+
color: #2484FF;
|
|
60
|
+
border: none;
|
|
61
|
+
font-family: 'Helvetica', sans-serif;
|
|
62
|
+
border-radius: 4px;
|
|
63
|
+
font-size: 14px;
|
|
64
|
+
font-weight: 600;
|
|
65
|
+
margin-top: 20px;
|
|
66
|
+
margin-left: 3%;
|
|
67
|
+
-moz-osx-font-smoothing: grayscale;
|
|
68
|
+
-webkit-font-smoothing: antialiased;
|
|
69
|
+
cursor: pointer;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.dzu-previewContainer {
|
|
73
|
+
padding: 40px 3%;
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-direction: row;
|
|
76
|
+
align-items: center;
|
|
77
|
+
justify-content: space-between;
|
|
78
|
+
position: relative;
|
|
79
|
+
width: 100%;
|
|
80
|
+
min-height: 60px;
|
|
81
|
+
z-index: 1;
|
|
82
|
+
border-bottom: 1px solid #ECECEC;
|
|
83
|
+
box-sizing: border-box;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.dzu-previewStatusContainer {
|
|
87
|
+
display: flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.dzu-previewFileName {
|
|
92
|
+
font-family: 'Helvetica', sans-serif;
|
|
93
|
+
font-size: 14px;
|
|
94
|
+
font-weight: 400;
|
|
95
|
+
color: #333333;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.dzu-previewImage {
|
|
99
|
+
width: auto;
|
|
100
|
+
max-height: 40px;
|
|
101
|
+
max-width: 140px;
|
|
102
|
+
border-radius: 4px;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.dzu-previewButton {
|
|
106
|
+
background-size: 14px 14px;
|
|
107
|
+
background-position: center;
|
|
108
|
+
background-repeat: no-repeat;
|
|
109
|
+
width: 14px;
|
|
110
|
+
height: 14px;
|
|
111
|
+
cursor: pointer;
|
|
112
|
+
opacity: 0.9;
|
|
113
|
+
margin: 0 0 2px 10px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.dzu-submitButtonContainer {
|
|
117
|
+
margin: 24px 0;
|
|
118
|
+
z-index: 1;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.dzu-submitButton {
|
|
122
|
+
padding: 0 14px;
|
|
123
|
+
min-height: 32px;
|
|
124
|
+
background-color: #2484FF;
|
|
125
|
+
border: none;
|
|
126
|
+
border-radius: 4px;
|
|
127
|
+
font-family: 'Helvetica', sans-serif;
|
|
128
|
+
font-size: 14px;
|
|
129
|
+
font-weight: 600;
|
|
130
|
+
color: #FFF;
|
|
131
|
+
-moz-osx-font-smoothing: grayscale;
|
|
132
|
+
-webkit-font-smoothing: antialiased;
|
|
133
|
+
cursor: pointer;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.dzu-submitButton:disabled {
|
|
137
|
+
background-color: #E6E6E6;
|
|
138
|
+
color: #333333;
|
|
139
|
+
cursor: unset;
|
|
140
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { IStyleCustomization } from './Dropzone'
|
|
3
|
+
|
|
4
|
+
export const formatBytes = (b: number) => {
|
|
5
|
+
const units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
|
6
|
+
let l = 0
|
|
7
|
+
let n = b
|
|
8
|
+
|
|
9
|
+
while (n >= 1024) {
|
|
10
|
+
n /= 1024
|
|
11
|
+
l += 1
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return `${n.toFixed(n >= 10 || l < 1 ? 0 : 1)}${units[l]}`
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const formatDuration = (seconds: number) => {
|
|
18
|
+
const date = new Date(0)
|
|
19
|
+
date.setSeconds(seconds)
|
|
20
|
+
const dateString = date.toISOString().slice(11, 19)
|
|
21
|
+
if (seconds < 3600) return dateString.slice(3)
|
|
22
|
+
return dateString
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// adapted from: https://github.com/okonet/attr-accept/blob/master/src/index.js
|
|
26
|
+
// returns true if file.name is empty and accept string is something like ".csv",
|
|
27
|
+
// because file comes from dataTransferItem for drag events, and
|
|
28
|
+
// dataTransferItem.name is always empty
|
|
29
|
+
export const accepts = (file: File, accept: string) => {
|
|
30
|
+
if (!accept || accept === '*') return true
|
|
31
|
+
|
|
32
|
+
const mimeType = file.type || ''
|
|
33
|
+
const baseMimeType = mimeType.replace(/\/.*$/, '')
|
|
34
|
+
|
|
35
|
+
return accept
|
|
36
|
+
.split(',')
|
|
37
|
+
.map(t => t.trim())
|
|
38
|
+
.some(type => {
|
|
39
|
+
if (type.charAt(0) === '.') {
|
|
40
|
+
return file.name === undefined || file.name.toLowerCase().endsWith(type.toLowerCase())
|
|
41
|
+
} else if (type.endsWith('/*')) {
|
|
42
|
+
// this is something like an image/* mime type
|
|
43
|
+
return baseMimeType === type.replace(/\/.*$/, '')
|
|
44
|
+
}
|
|
45
|
+
return mimeType === type
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type ResolveFn<T> = (...args: any[]) => T
|
|
50
|
+
|
|
51
|
+
export const resolveValue = <T = any>(value: ResolveFn<T> | T, ...args: any[]) => {
|
|
52
|
+
if (typeof value === 'function') return (value as ResolveFn<T>)(...args)
|
|
53
|
+
return value
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const defaultClassNames = {
|
|
57
|
+
dropzone: 'dzu-dropzone',
|
|
58
|
+
dropzoneActive: 'dzu-dropzoneActive',
|
|
59
|
+
dropzoneReject: 'dzu-dropzoneActive',
|
|
60
|
+
dropzoneDisabled: 'dzu-dropzoneDisabled',
|
|
61
|
+
input: 'dzu-input',
|
|
62
|
+
inputLabel: 'dzu-inputLabel',
|
|
63
|
+
inputLabelWithFiles: 'dzu-inputLabelWithFiles',
|
|
64
|
+
preview: 'dzu-previewContainer',
|
|
65
|
+
previewImage: 'dzu-previewImage',
|
|
66
|
+
submitButtonContainer: 'dzu-submitButtonContainer',
|
|
67
|
+
submitButton: 'dzu-submitButton',
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const mergeStyles = (
|
|
71
|
+
classNames: IStyleCustomization<string>,
|
|
72
|
+
styles: IStyleCustomization<React.CSSProperties>,
|
|
73
|
+
addClassNames: IStyleCustomization<string>,
|
|
74
|
+
...args: any[]
|
|
75
|
+
) => {
|
|
76
|
+
const resolvedClassNames: { [property: string]: string } = { ...defaultClassNames }
|
|
77
|
+
const resolvedStyles = { ...styles } as { [property: string]: string }
|
|
78
|
+
|
|
79
|
+
for (const [key, value] of Object.entries(classNames)) {
|
|
80
|
+
resolvedClassNames[key] = resolveValue(value, ...args)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
for (const [key, value] of Object.entries(addClassNames)) {
|
|
84
|
+
resolvedClassNames[key] = `${resolvedClassNames[key]} ${resolveValue(value, ...args)}`
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
for (const [key, value] of Object.entries(styles)) {
|
|
88
|
+
resolvedStyles[key] = resolveValue(value, ...args)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { classNames: resolvedClassNames, styles: resolvedStyles as IStyleCustomization<React.CSSProperties> }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const getFilesFromEvent = (
|
|
95
|
+
event: React.DragEvent<HTMLElement> | React.ChangeEvent<HTMLInputElement>,
|
|
96
|
+
): Array<File | DataTransferItem> => {
|
|
97
|
+
let items = null
|
|
98
|
+
|
|
99
|
+
if ('dataTransfer' in event) {
|
|
100
|
+
const dt = event.dataTransfer
|
|
101
|
+
|
|
102
|
+
// NOTE: Only the 'drop' event has access to DataTransfer.files, otherwise it will always be empty
|
|
103
|
+
if ('files' in dt && dt.files.length) {
|
|
104
|
+
items = dt.files
|
|
105
|
+
} else if (dt.items && dt.items.length) {
|
|
106
|
+
items = dt.items
|
|
107
|
+
}
|
|
108
|
+
} else if (event.target && event.target.files) {
|
|
109
|
+
items = event.target.files
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return Array.prototype.slice.call(items)
|
|
113
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { getDroppedOrSelectedFiles } from 'html5-file-selector';
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { Button } from 'reactstrap';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import '
|
|
7
|
-
import { pdfImage, IconButtonSvg } from '../../iconos';
|
|
4
|
+
import Dropzone from '../../dropzone/Dropzone';
|
|
5
|
+
import '../../dropzone/styles.css';
|
|
6
|
+
import { IconButtonSvg, pdfImage } from '../../iconos';
|
|
8
7
|
import '../dropzone-uploader.css';
|
|
9
8
|
|
|
10
9
|
export const DropzoneUploaderDniDigital = ({
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
import { useEffect, useState } from 'react';
|
|
3
1
|
import { getDroppedOrSelectedFiles } from 'html5-file-selector';
|
|
4
|
-
import
|
|
5
|
-
import '
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import Dropzone from '../dropzone/Dropzone';
|
|
4
|
+
import '../dropzone/styles.css';
|
|
6
5
|
import { IconButtonSvg, pdfImage } from '../iconos';
|
|
7
6
|
import './dropzone-uploader.css';
|
|
8
7
|
|
|
@@ -88,7 +87,7 @@ export const DropzoneUploader = ({
|
|
|
88
87
|
<p>{(meta.size / 1024).toFixed(2)} .Kb</p>
|
|
89
88
|
<button
|
|
90
89
|
onClick={remove}
|
|
91
|
-
className="dropzone-upload-delete-btn
|
|
90
|
+
className="dropzone-upload-delete-btn icon-trash"
|
|
92
91
|
></button>
|
|
93
92
|
</div>
|
|
94
93
|
);
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
1
|
+
export * from './dropzone-uploader';
|
|
2
|
+
export * from './dropzone-uploader/dropzone-uploader-dni-digital';
|
|
3
3
|
export * from './bridges';
|
|
4
4
|
export * from './CustomBootstrap';
|
|
5
5
|
export * from './custom-input';
|
|
File without changes
|