@arkyn/components 1.4.16 → 1.4.18
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/bundle.js +56012 -32504
- package/dist/bundle.umd.cjs +953 -433
- package/dist/components/AudioUpload/HasFileContent/index.js +1 -1
- package/dist/components/FileUpload/FileUploadError/index.d.ts +5 -0
- package/dist/components/FileUpload/FileUploadError/index.d.ts.map +1 -0
- package/dist/components/FileUpload/FileUploadError/index.js +10 -0
- package/dist/components/FileUpload/FileUploadLabel/index.d.ts +5 -0
- package/dist/components/FileUpload/FileUploadLabel/index.d.ts.map +1 -0
- package/dist/components/FileUpload/FileUploadLabel/index.js +9 -0
- package/dist/components/FileUpload/HasFileContent/index.d.ts +5 -0
- package/dist/components/FileUpload/HasFileContent/index.d.ts.map +1 -0
- package/dist/components/FileUpload/HasFileContent/index.js +34 -0
- package/dist/components/FileUpload/NoFileContent/index.d.ts +5 -0
- package/dist/components/FileUpload/NoFileContent/index.d.ts.map +1 -0
- package/dist/components/FileUpload/NoFileContent/index.js +29 -0
- package/dist/components/FileUpload/index.d.ts +5 -0
- package/dist/components/FileUpload/index.d.ts.map +1 -0
- package/dist/components/FileUpload/index.js +51 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/AudioUpload/HasFileContent/index.tsx +1 -1
- package/src/components/Drawer/Container/styles.css +5 -0
- package/src/components/FileUpload/FileUploadError/index.tsx +12 -0
- package/src/components/FileUpload/FileUploadError/styles.css +6 -0
- package/src/components/FileUpload/FileUploadLabel/index.tsx +13 -0
- package/src/components/FileUpload/FileUploadLabel/styles.css +15 -0
- package/src/components/FileUpload/HasFileContent/index.tsx +92 -0
- package/src/components/FileUpload/HasFileContent/styles.css +40 -0
- package/src/components/FileUpload/NoFileContent/index.tsx +59 -0
- package/src/components/FileUpload/NoFileContent/styles.css +19 -0
- package/src/components/FileUpload/index.tsx +111 -0
- package/src/components/FileUpload/styles.css +32 -0
- package/src/components/ImageUpload/styles.css +3 -0
- package/src/index.ts +1 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
import { FileUploadHasFileContentProps } from "@arkyn/types";
|
2
|
+
import {
|
3
|
+
File,
|
4
|
+
FileArchive,
|
5
|
+
FileAudio,
|
6
|
+
FileImage,
|
7
|
+
RefreshCw,
|
8
|
+
} from "lucide-react";
|
9
|
+
|
10
|
+
import { Button } from "../../Button";
|
11
|
+
import { Divider } from "../../Divider";
|
12
|
+
import { IconButton } from "../../IconButton";
|
13
|
+
import { Tooltip } from "../../Tooltip";
|
14
|
+
|
15
|
+
import "./styles.css";
|
16
|
+
|
17
|
+
function HasFileContent(props: FileUploadHasFileContentProps) {
|
18
|
+
const {
|
19
|
+
disabled,
|
20
|
+
file,
|
21
|
+
isLoading,
|
22
|
+
acceptFile,
|
23
|
+
changeFileButtonText,
|
24
|
+
handleSelectFile,
|
25
|
+
reSendFile,
|
26
|
+
} = props;
|
27
|
+
|
28
|
+
function handleClick() {
|
29
|
+
if (disabled) return;
|
30
|
+
|
31
|
+
const input = document.createElement("input");
|
32
|
+
|
33
|
+
input.type = "file";
|
34
|
+
input.accept = acceptFile;
|
35
|
+
|
36
|
+
input.onchange = (event) => {
|
37
|
+
const file = (event.target as HTMLInputElement).files?.[0];
|
38
|
+
if (file) handleSelectFile(file);
|
39
|
+
};
|
40
|
+
|
41
|
+
input.click();
|
42
|
+
}
|
43
|
+
|
44
|
+
function FileIcon() {
|
45
|
+
if (file.type.startsWith("image/")) return <FileImage />;
|
46
|
+
if (file.type.startsWith("audio/")) return <FileAudio />;
|
47
|
+
if (file.type.startsWith("application/zip")) return <FileArchive />;
|
48
|
+
return <File />;
|
49
|
+
}
|
50
|
+
|
51
|
+
return (
|
52
|
+
<div className="arkynFileUploadHasFileContent">
|
53
|
+
<section className="arkynFileUploadFileContainer">
|
54
|
+
<FileIcon />
|
55
|
+
<p>{file.name}</p>
|
56
|
+
</section>
|
57
|
+
|
58
|
+
<Divider />
|
59
|
+
|
60
|
+
<div className="arkynFileUploadButtonsContainer">
|
61
|
+
{!!reSendFile && (
|
62
|
+
<Tooltip orientation="bottom" text="Reenviar arquivo">
|
63
|
+
<IconButton
|
64
|
+
type="button"
|
65
|
+
aria-label="resend file"
|
66
|
+
variant="outline"
|
67
|
+
scheme="danger"
|
68
|
+
size="sm"
|
69
|
+
isLoading={isLoading}
|
70
|
+
onClick={reSendFile}
|
71
|
+
icon={RefreshCw}
|
72
|
+
disabled={disabled}
|
73
|
+
/>
|
74
|
+
</Tooltip>
|
75
|
+
)}
|
76
|
+
|
77
|
+
<Button
|
78
|
+
isLoading={isLoading}
|
79
|
+
onClick={handleClick}
|
80
|
+
variant="outline"
|
81
|
+
size="sm"
|
82
|
+
type="button"
|
83
|
+
disabled={disabled}
|
84
|
+
>
|
85
|
+
{changeFileButtonText}
|
86
|
+
</Button>
|
87
|
+
</div>
|
88
|
+
</div>
|
89
|
+
);
|
90
|
+
}
|
91
|
+
|
92
|
+
export { HasFileContent };
|
@@ -0,0 +1,40 @@
|
|
1
|
+
.arkynFileUploadHasFileContent {
|
2
|
+
display: flex;
|
3
|
+
flex-direction: column;
|
4
|
+
padding: 16px;
|
5
|
+
gap: 16px;
|
6
|
+
|
7
|
+
height: 100%;
|
8
|
+
width: 100%;
|
9
|
+
}
|
10
|
+
|
11
|
+
.arkynFileUploadFileContainer {
|
12
|
+
display: flex;
|
13
|
+
align-items: center;
|
14
|
+
gap: 8px;
|
15
|
+
}
|
16
|
+
|
17
|
+
.arkynFileUploadFileContainer svg {
|
18
|
+
min-width: 26px;
|
19
|
+
min-height: 26px;
|
20
|
+
|
21
|
+
color: var(--text-heading);
|
22
|
+
}
|
23
|
+
|
24
|
+
.arkynFileUploadFileContainer p {
|
25
|
+
white-space: nowrap;
|
26
|
+
overflow: hidden;
|
27
|
+
text-overflow: ellipsis;
|
28
|
+
|
29
|
+
font-size: 14px;
|
30
|
+
font-weight: 400;
|
31
|
+
text-align: left;
|
32
|
+
color: var(--text-body);
|
33
|
+
}
|
34
|
+
|
35
|
+
.arkynFileUploadButtonsContainer {
|
36
|
+
display: flex;
|
37
|
+
align-items: center;
|
38
|
+
justify-content: end;
|
39
|
+
gap: 8px;
|
40
|
+
}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import { Button } from "@arkyn/components";
|
2
|
+
import { FileUploadNoFileContentProps } from "@arkyn/types";
|
3
|
+
import { DragEvent } from "react";
|
4
|
+
|
5
|
+
import "./styles.css";
|
6
|
+
|
7
|
+
function NoFileContent(props: FileUploadNoFileContentProps) {
|
8
|
+
const {
|
9
|
+
dropFileText,
|
10
|
+
isLoading,
|
11
|
+
acceptFile,
|
12
|
+
handleSelectFile,
|
13
|
+
selectFileButtonText,
|
14
|
+
disabled,
|
15
|
+
} = props;
|
16
|
+
|
17
|
+
function handleDrop(event: DragEvent<HTMLDivElement>) {
|
18
|
+
if (disabled) return;
|
19
|
+
|
20
|
+
event.preventDefault();
|
21
|
+
const file = event.dataTransfer.files[0];
|
22
|
+
if (file) handleSelectFile(file);
|
23
|
+
}
|
24
|
+
|
25
|
+
function handleClick() {
|
26
|
+
if (disabled) return;
|
27
|
+
|
28
|
+
const input = document.createElement("input");
|
29
|
+
|
30
|
+
input.type = "file";
|
31
|
+
input.accept = acceptFile;
|
32
|
+
|
33
|
+
input.onchange = (event) => {
|
34
|
+
const file = (event.target as HTMLInputElement).files?.[0];
|
35
|
+
if (file) handleSelectFile(file);
|
36
|
+
};
|
37
|
+
|
38
|
+
input.click();
|
39
|
+
}
|
40
|
+
|
41
|
+
return (
|
42
|
+
<div onDrop={handleDrop} className="arkynFileUploadNoFileContent">
|
43
|
+
<Button
|
44
|
+
isLoading={isLoading}
|
45
|
+
onClick={handleClick}
|
46
|
+
variant="ghost"
|
47
|
+
size="sm"
|
48
|
+
type="button"
|
49
|
+
disabled={disabled}
|
50
|
+
>
|
51
|
+
{selectFileButtonText}
|
52
|
+
</Button>
|
53
|
+
|
54
|
+
<p>{dropFileText}</p>
|
55
|
+
</div>
|
56
|
+
);
|
57
|
+
}
|
58
|
+
|
59
|
+
export { NoFileContent };
|
@@ -0,0 +1,19 @@
|
|
1
|
+
.arkynFileUploadNoFileContent {
|
2
|
+
display: flex;
|
3
|
+
flex-direction: column;
|
4
|
+
align-items: center;
|
5
|
+
justify-content: center;
|
6
|
+
gap: 8px;
|
7
|
+
|
8
|
+
height: 100%;
|
9
|
+
width: 100%;
|
10
|
+
}
|
11
|
+
|
12
|
+
.arkynFileUploadNoFileContent > p {
|
13
|
+
font-size: 12px;
|
14
|
+
font-weight: 400;
|
15
|
+
line-height: 12px;
|
16
|
+
text-align: center;
|
17
|
+
white-space: nowrap;
|
18
|
+
color: var(--text-body);
|
19
|
+
}
|
@@ -0,0 +1,111 @@
|
|
1
|
+
import { FileUploadProps } from "@arkyn/types";
|
2
|
+
import { useState } from "react";
|
3
|
+
|
4
|
+
import { FileUploadError } from "./FileUploadError";
|
5
|
+
import { FileUploadLabel } from "./FileUploadLabel";
|
6
|
+
import { HasFileContent } from "./HasFileContent";
|
7
|
+
import { NoFileContent } from "./NoFileContent";
|
8
|
+
|
9
|
+
import { useFieldErrors } from "../../hooks/useFieldErrors";
|
10
|
+
|
11
|
+
import "./styles.css";
|
12
|
+
|
13
|
+
function FileUpload(props: FileUploadProps) {
|
14
|
+
const {
|
15
|
+
name,
|
16
|
+
label,
|
17
|
+
showAsterisk = false,
|
18
|
+
action,
|
19
|
+
fileName = "file",
|
20
|
+
method = "POST",
|
21
|
+
acceptFile = "*",
|
22
|
+
fileResponseName = "url",
|
23
|
+
changeFileButtonText = "Alterar arquivo",
|
24
|
+
selectFileButtonText = "Selecionar arquivo",
|
25
|
+
dropFileText = "Ou arraste e solte o arquivo aqui",
|
26
|
+
onUpload,
|
27
|
+
disabled = false,
|
28
|
+
} = props;
|
29
|
+
|
30
|
+
const fieldErrors = useFieldErrors();
|
31
|
+
const fieldError = fieldErrors[name];
|
32
|
+
|
33
|
+
const [value, setValue] = useState("");
|
34
|
+
const [error, setError] = useState("");
|
35
|
+
const [file, setFile] = useState<File | null>(null);
|
36
|
+
const [isLoading, setIsLoading] = useState(false);
|
37
|
+
|
38
|
+
async function handleUploadFile(file: File) {
|
39
|
+
if (disabled) return;
|
40
|
+
|
41
|
+
setIsLoading(true);
|
42
|
+
setFile(file);
|
43
|
+
setError("");
|
44
|
+
|
45
|
+
const formData = new FormData();
|
46
|
+
formData.append(fileName, file);
|
47
|
+
|
48
|
+
await fetch(action, { method: method, body: formData })
|
49
|
+
.then(async (response) => await response.json())
|
50
|
+
.then((response) => {
|
51
|
+
if (!!response?.error) setError(response.error);
|
52
|
+
else setValue(response?.[fileResponseName]);
|
53
|
+
onUpload && onUpload(response?.[fileResponseName]);
|
54
|
+
})
|
55
|
+
.catch((error) => {
|
56
|
+
console.error(error);
|
57
|
+
setError("Erro ao enviar o arquivo");
|
58
|
+
})
|
59
|
+
.finally(() => setIsLoading(false));
|
60
|
+
}
|
61
|
+
|
62
|
+
function handleSelectFile(file: File) {
|
63
|
+
if (disabled) return;
|
64
|
+
handleUploadFile(file);
|
65
|
+
}
|
66
|
+
|
67
|
+
const errorMessage = fieldError || error;
|
68
|
+
|
69
|
+
const hasErrorClassName = errorMessage ? "hasError" : "noHasError";
|
70
|
+
const hasFileClassName = file ? "hasFile" : "noHasFile";
|
71
|
+
const className = `arkynFileUpload ${hasErrorClassName} ${hasFileClassName}`;
|
72
|
+
|
73
|
+
return (
|
74
|
+
<div className="arkynFileUploadContainer">
|
75
|
+
{label && <FileUploadLabel label={label} showAsterisk={showAsterisk} />}
|
76
|
+
|
77
|
+
<div className={className}>
|
78
|
+
<input type="hidden" name={name} value={value || ""} />
|
79
|
+
|
80
|
+
{!file && (
|
81
|
+
<NoFileContent
|
82
|
+
disabled={disabled}
|
83
|
+
isLoading={isLoading}
|
84
|
+
acceptFile={acceptFile}
|
85
|
+
dropFileText={dropFileText}
|
86
|
+
handleSelectFile={handleSelectFile}
|
87
|
+
selectFileButtonText={selectFileButtonText}
|
88
|
+
/>
|
89
|
+
)}
|
90
|
+
|
91
|
+
{file && (
|
92
|
+
<HasFileContent
|
93
|
+
disabled={disabled}
|
94
|
+
isLoading={isLoading}
|
95
|
+
acceptFile={acceptFile}
|
96
|
+
file={file}
|
97
|
+
handleSelectFile={handleSelectFile}
|
98
|
+
changeFileButtonText={changeFileButtonText}
|
99
|
+
reSendFile={
|
100
|
+
!!errorMessage && file ? () => handleUploadFile(file) : undefined
|
101
|
+
}
|
102
|
+
/>
|
103
|
+
)}
|
104
|
+
</div>
|
105
|
+
|
106
|
+
{errorMessage && <FileUploadError error={errorMessage} />}
|
107
|
+
</div>
|
108
|
+
);
|
109
|
+
}
|
110
|
+
|
111
|
+
export { FileUpload };
|
@@ -0,0 +1,32 @@
|
|
1
|
+
.arkynFileUploadContainer {
|
2
|
+
display: flex;
|
3
|
+
flex-direction: column;
|
4
|
+
gap: 6px;
|
5
|
+
}
|
6
|
+
|
7
|
+
.arkynFileUpload {
|
8
|
+
outline: 1px solid transparent;
|
9
|
+
|
10
|
+
border-width: 1px;
|
11
|
+
border-color: var(--border);
|
12
|
+
border-radius: var(--rounded-inputs);
|
13
|
+
|
14
|
+
width: 100%;
|
15
|
+
height: 127px;
|
16
|
+
max-width: 475px;
|
17
|
+
|
18
|
+
background: rgba(var(--input-background), 1);
|
19
|
+
}
|
20
|
+
|
21
|
+
.arkynFileUpload.hasFile {
|
22
|
+
border-style: solid;
|
23
|
+
}
|
24
|
+
|
25
|
+
.arkynFileUpload.noHasFile {
|
26
|
+
border-style: dashed;
|
27
|
+
}
|
28
|
+
|
29
|
+
.arkynFileUpload.hasError {
|
30
|
+
border-color: rgb(var(--spotlight-danger));
|
31
|
+
outline-color: rgb(var(--spotlight-danger));
|
32
|
+
}
|
@@ -5,6 +5,8 @@
|
|
5
5
|
}
|
6
6
|
|
7
7
|
.arkynImageUpload {
|
8
|
+
outline: 1px solid transparent;
|
9
|
+
|
8
10
|
border-width: 1px;
|
9
11
|
border-color: var(--border);
|
10
12
|
border-radius: var(--rounded-inputs);
|
@@ -26,4 +28,5 @@
|
|
26
28
|
|
27
29
|
.arkynImageUpload.hasError {
|
28
30
|
border-color: rgb(var(--spotlight-danger));
|
31
|
+
outline-color: Ørgb(var(--spotlight-danger));
|
29
32
|
}
|
package/src/index.ts
CHANGED
@@ -22,6 +22,7 @@ export {
|
|
22
22
|
export { AudioUpload } from "./components/AudioUpload";
|
23
23
|
export { Button } from "./components/Button";
|
24
24
|
export { Checkbox } from "./components/Checkbox";
|
25
|
+
export { FileUpload } from "./components/FileUpload";
|
25
26
|
export { FormController, FormError, FormLabel } from "./components/Form";
|
26
27
|
export { IconButton } from "./components/IconButton";
|
27
28
|
export { ImageUpload } from "./components/ImageUpload";
|