@arkyn/components 3.0.1-beta.22 → 3.0.1-beta.23

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.
Files changed (70) hide show
  1. package/README.md +264 -0
  2. package/dist/bundle.js +1485 -859
  3. package/dist/bundle.umd.cjs +1 -1
  4. package/dist/components/audioUpload/hasFileContent/index.d.ts +13 -0
  5. package/dist/components/audioUpload/hasFileContent/index.d.ts.map +1 -0
  6. package/dist/components/audioUpload/hasFileContent/index.js +26 -0
  7. package/dist/components/audioUpload/index.d.ts +82 -0
  8. package/dist/components/audioUpload/index.d.ts.map +1 -0
  9. package/dist/components/audioUpload/index.js +120 -0
  10. package/dist/components/audioUpload/noFileContent/index.d.ts +12 -0
  11. package/dist/components/audioUpload/noFileContent/index.d.ts.map +1 -0
  12. package/dist/components/audioUpload/noFileContent/index.js +29 -0
  13. package/dist/components/clientOnly.d.ts +86 -0
  14. package/dist/components/clientOnly.d.ts.map +1 -0
  15. package/dist/components/clientOnly.js +86 -0
  16. package/dist/components/fileUpload/hasFileContent/index.d.ts +13 -0
  17. package/dist/components/fileUpload/hasFileContent/index.d.ts.map +1 -0
  18. package/dist/components/fileUpload/hasFileContent/index.js +34 -0
  19. package/dist/components/fileUpload/index.d.ts +94 -0
  20. package/dist/components/fileUpload/index.d.ts.map +1 -0
  21. package/dist/components/fileUpload/index.js +127 -0
  22. package/dist/components/fileUpload/noFileContent/index.d.ts +12 -0
  23. package/dist/components/fileUpload/noFileContent/index.d.ts.map +1 -0
  24. package/dist/components/fileUpload/noFileContent/index.js +29 -0
  25. package/dist/components/imageUpload/hasFileContent/index.d.ts +13 -0
  26. package/dist/components/imageUpload/hasFileContent/index.d.ts.map +1 -0
  27. package/dist/components/imageUpload/hasFileContent/index.js +24 -0
  28. package/dist/components/imageUpload/index.d.ts +114 -0
  29. package/dist/components/imageUpload/index.d.ts.map +1 -0
  30. package/dist/components/imageUpload/index.js +148 -0
  31. package/dist/components/imageUpload/noFileContent/index.d.ts +12 -0
  32. package/dist/components/imageUpload/noFileContent/index.d.ts.map +1 -0
  33. package/dist/components/imageUpload/noFileContent/index.js +29 -0
  34. package/dist/components/table/tableBody/index.d.ts +67 -0
  35. package/dist/components/table/tableBody/index.d.ts.map +1 -0
  36. package/dist/components/table/tableBody/index.js +69 -0
  37. package/dist/components/table/tableCaption/index.d.ts +62 -0
  38. package/dist/components/table/tableCaption/index.d.ts.map +1 -0
  39. package/dist/components/table/tableCaption/index.js +64 -0
  40. package/dist/components/table/tableContainer/index.d.ts +64 -0
  41. package/dist/components/table/tableContainer/index.d.ts.map +1 -0
  42. package/dist/components/table/tableContainer/index.js +66 -0
  43. package/dist/components/table/tableFooter/index.d.ts +45 -0
  44. package/dist/components/table/tableFooter/index.d.ts.map +1 -0
  45. package/dist/components/table/tableFooter/index.js +47 -0
  46. package/dist/components/table/tableHeader/index.d.ts +44 -0
  47. package/dist/components/table/tableHeader/index.d.ts.map +1 -0
  48. package/dist/components/table/tableHeader/index.js +46 -0
  49. package/dist/components/tooltip/index.d.ts.map +1 -1
  50. package/dist/components/tooltip/index.js +1 -1
  51. package/dist/hooks/useDrawer.d.ts +86 -0
  52. package/dist/hooks/useDrawer.d.ts.map +1 -0
  53. package/dist/hooks/useDrawer.js +20 -0
  54. package/dist/hooks/useHydrated.d.ts +76 -0
  55. package/dist/hooks/useHydrated.d.ts.map +1 -0
  56. package/dist/hooks/useHydrated.js +81 -0
  57. package/dist/hooks/useModal.d.ts +81 -0
  58. package/dist/hooks/useModal.d.ts.map +1 -0
  59. package/dist/hooks/useModal.js +20 -0
  60. package/dist/index.d.ts +14 -0
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +14 -0
  63. package/dist/providers/drawerProvider.d.ts +106 -0
  64. package/dist/providers/drawerProvider.d.ts.map +1 -0
  65. package/dist/providers/drawerProvider.js +120 -0
  66. package/dist/providers/modalProvider.d.ts +103 -0
  67. package/dist/providers/modalProvider.d.ts.map +1 -0
  68. package/dist/providers/modalProvider.js +119 -0
  69. package/dist/style.css +1 -1
  70. package/package.json +19 -2
@@ -0,0 +1,120 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { useForm } from "../../hooks/useForm";
4
+ import { FieldError } from "../fieldError";
5
+ import { FieldLabel } from "../fieldLabel";
6
+ import { FieldWrapper } from "../fieldWrapper";
7
+ import { HasFileContent } from "./hasFileContent";
8
+ import { NoFileContent } from "./noFileContent";
9
+ import "./styles.css";
10
+ /**
11
+ * AudioUpload component - handles audio file upload with drag & drop functionality and server upload
12
+ *
13
+ * @param props - AudioUpload component properties
14
+ * @param props.name - Required field name for form handling
15
+ * @param props.action - Required server endpoint URL for file upload
16
+ * @param props.fileName - Name of the file field in FormData. Default: "file"
17
+ * @param props.method - HTTP method for upload request. Default: "POST"
18
+ * @param props.acceptAudio - Audio file types to accept. Default: "audio/*"
19
+ * @param props.dropAudioText - Text displayed in drop zone. Default: "Ou arraste e solte um arquivo de áudio aqui"
20
+ * @param props.selectAudioButtonText - Text for file selection button. Default: "Selecionar arquivo de áudio"
21
+ * @param props.changeAudioButtonText - Text for change file button. Default: "Trocar arquivo de áudio"
22
+ * @param props.onChange - Callback function called after successful upload with the file URL
23
+ * @param props.fileResponseName - Name of the URL field in server response. Default: "url"
24
+ * @param props.label - Optional label text to display above the upload area
25
+ * @param props.showAsterisk - Whether to show asterisk on label for required fields. Default: false
26
+ * @param props.disabled - Whether the upload is disabled. Default: false
27
+ * @param props.defaultValue - Default audio URL value
28
+ *
29
+ * @returns AudioUpload JSX element with drag & drop zone or audio preview
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * // Basic audio upload
34
+ * <AudioUpload
35
+ * name="audio"
36
+ * action="/api/upload"
37
+ * />
38
+ *
39
+ * // Audio upload with label and custom texts
40
+ * <AudioUpload
41
+ * name="podcast"
42
+ * action="/api/upload/podcast"
43
+ * label="Upload Podcast"
44
+ * showAsterisk
45
+ * selectAudioButtonText="Choose Audio File"
46
+ * dropAudioText="Drop your audio file here"
47
+ * changeAudioButtonText="Change Audio"
48
+ * />
49
+ *
50
+ * // Audio upload with callback and custom settings
51
+ * <AudioUpload
52
+ * name="recording"
53
+ * action="/api/upload"
54
+ * label="Voice Recording"
55
+ * acceptAudio="audio/mp3,audio/wav"
56
+ * onChange={(url) => console.log('Uploaded:', url)}
57
+ * fileResponseName="audioUrl"
58
+ * fileName="recording"
59
+ * method="PUT"
60
+ * />
61
+ *
62
+ * // Disabled audio upload with default value
63
+ * <AudioUpload
64
+ * name="preview"
65
+ * action="/api/upload"
66
+ * disabled
67
+ * defaultValue="/path/to/audio.mp3"
68
+ * label="Audio Preview"
69
+ * />
70
+ * ```
71
+ */
72
+ function AudioUpload(props) {
73
+ const { name, label, fileName = "file", method = "POST", onChange, fileResponseName = "url", selectAudioButtonText = "Selecionar arquivo de áudio", dropAudioText = "Ou arraste e solte um arquivo de áudio aqui", changeAudioButtonText = "Trocar arquivo de áudio", acceptAudio = "audio/*", action, defaultValue = "", showAsterisk = false, disabled = false, } = props;
74
+ const { fieldErrors } = useForm();
75
+ const fieldError = fieldErrors?.[name];
76
+ const [value, setValue] = useState(defaultValue);
77
+ const [error, setError] = useState("");
78
+ const [file, setFile] = useState(null);
79
+ const [filePath, setFilePath] = useState(defaultValue);
80
+ const [isLoading, setIsLoading] = useState(false);
81
+ async function handleUploadAudio(file) {
82
+ if (disabled)
83
+ return;
84
+ setIsLoading(true);
85
+ setFile(file);
86
+ setError("");
87
+ const formData = new FormData();
88
+ formData.append(fileName, file);
89
+ await fetch(action, { method: method, body: formData })
90
+ .then(async (response) => await response.json())
91
+ .then((response) => {
92
+ if (!!response?.error)
93
+ setError(response.error);
94
+ else
95
+ setValue(response?.[fileResponseName]);
96
+ onChange && onChange(response?.[fileResponseName]);
97
+ })
98
+ .catch((error) => {
99
+ console.error(error);
100
+ setError("Erro ao enviar audio");
101
+ })
102
+ .finally(() => setIsLoading(false));
103
+ }
104
+ function handleSelectFile(file) {
105
+ if (disabled)
106
+ return;
107
+ if (file.type.indexOf("audio") === -1) {
108
+ setError("O arquivo selecionado não é um arquivo de áudio");
109
+ return;
110
+ }
111
+ setFilePath(URL.createObjectURL(file));
112
+ handleUploadAudio(file);
113
+ }
114
+ const errorMessage = fieldError || error;
115
+ const hasErrorClassName = errorMessage ? "hasError" : "noHasError";
116
+ const hasImageClassName = filePath ? "hasAudio" : "noHasAudio";
117
+ const className = `arkynAudioUpload ${hasErrorClassName} ${hasImageClassName}`;
118
+ return (_jsxs(FieldWrapper, { children: [label && _jsx(FieldLabel, { showAsterisk: showAsterisk, children: label }), _jsxs("div", { className: className, children: [_jsx("input", { type: "hidden", name: name, value: value || "" }), !filePath && (_jsx(NoFileContent, { disabled: disabled, isLoading: isLoading, acceptAudio: acceptAudio, dropAudioText: dropAudioText, handleSelectFile: handleSelectFile, selectAudioButtonText: selectAudioButtonText })), filePath && (_jsx(HasFileContent, { filePath: filePath, acceptAudio: acceptAudio, changeAudioButtonText: changeAudioButtonText, disabled: disabled, handleSelectFile: handleSelectFile, isLoading: isLoading, reSendAudio: !!errorMessage && file ? () => handleUploadAudio(file) : undefined }))] }), errorMessage && _jsx(FieldError, { children: errorMessage })] }));
119
+ }
120
+ export { AudioUpload };
@@ -0,0 +1,12 @@
1
+ import "./styles.css";
2
+ type NoFileContentProps = {
3
+ disabled: boolean;
4
+ acceptAudio: string;
5
+ isLoading: boolean;
6
+ selectAudioButtonText: string;
7
+ dropAudioText: string;
8
+ handleSelectFile: (file: File) => void;
9
+ };
10
+ declare function NoFileContent(props: NoFileContentProps): import("react/jsx-runtime").JSX.Element;
11
+ export { NoFileContent };
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/audioUpload/noFileContent/index.tsx"],"names":[],"mappings":"AAGA,OAAO,cAAc,CAAC;AAEtB,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACxC,CAAC;AAEF,iBAAS,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CAkD/C;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from "../../button";
3
+ import "./styles.css";
4
+ function NoFileContent(props) {
5
+ const { dropAudioText, isLoading, acceptAudio, handleSelectFile, selectAudioButtonText, disabled, } = props;
6
+ function handleDrop(event) {
7
+ if (disabled)
8
+ return;
9
+ event.preventDefault();
10
+ const file = event.dataTransfer.files[0];
11
+ if (file)
12
+ handleSelectFile(file);
13
+ }
14
+ function handleClick() {
15
+ if (disabled)
16
+ return;
17
+ const input = document.createElement("input");
18
+ input.type = "file";
19
+ input.accept = acceptAudio;
20
+ input.onchange = (event) => {
21
+ const file = event.target.files?.[0];
22
+ if (file)
23
+ handleSelectFile(file);
24
+ };
25
+ input.click();
26
+ }
27
+ return (_jsxs("div", { onDrop: handleDrop, className: "arkynAudioUploadNoFileContent", children: [_jsx(Button, { isLoading: isLoading, onClick: handleClick, variant: "ghost", size: "sm", type: "button", disabled: disabled, children: selectAudioButtonText }), _jsx("p", { children: dropAudioText })] }));
28
+ }
29
+ export { NoFileContent };
@@ -0,0 +1,86 @@
1
+ type ClientOnlyProps = {
2
+ children(): React.ReactNode;
3
+ fallback?: React.ReactNode;
4
+ };
5
+ /**
6
+ * ClientOnly component - renders children only after hydration on the client side
7
+ *
8
+ * This component prevents hydration mismatches by rendering different content during SSR
9
+ * and after client-side hydration. It's useful for components that rely on browser APIs
10
+ * or need to render differently on server and client.
11
+ *
12
+ * @param props - ClientOnly component properties
13
+ * @param props.children - Function that returns React nodes to render after hydration
14
+ * @param props.fallback - Optional React node to render during SSR or before hydration
15
+ *
16
+ * @returns React fragment containing either fallback content or children based on hydration state
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * // Basic usage with loading fallback
21
+ * <ClientOnly fallback={<div>Loading...</div>}>
22
+ * {() => <InteractiveWidget />}
23
+ * </ClientOnly>
24
+ *
25
+ * // Client-only component without fallback
26
+ * <ClientOnly>
27
+ * {() => (
28
+ * <div>
29
+ * <p>This content only appears on the client</p>
30
+ * <p>Current time: {new Date().toLocaleString()}</p>
31
+ * </div>
32
+ * )}
33
+ * </ClientOnly>
34
+ *
35
+ * // Using with browser APIs
36
+ * <ClientOnly fallback={<div>Preparing location services...</div>}>
37
+ * {() => <GeolocationComponent />}
38
+ * </ClientOnly>
39
+ *
40
+ * // Complex interactive component
41
+ * <ClientOnly fallback={<StaticPlaceholder />}>
42
+ * {() => (
43
+ * <div>
44
+ * <Chart data={chartData} />
45
+ * <InteractiveControls />
46
+ * <RealtimeUpdates />
47
+ * </div>
48
+ * )}
49
+ * </ClientOnly>
50
+ *
51
+ * // Conditional rendering based on client capabilities
52
+ * <ClientOnly fallback={<BasicTable data={data} />}>
53
+ * {() => (
54
+ * <AdvancedDataGrid
55
+ * data={data}
56
+ * features={['sorting', 'filtering', 'virtualization']}
57
+ * />
58
+ * )}
59
+ * </ClientOnly>
60
+ *
61
+ * // Using with dynamic imports
62
+ * <ClientOnly fallback={<div>Loading editor...</div>}>
63
+ * {() => <LazyCodeEditor />}
64
+ * </ClientOnly>
65
+ *
66
+ * // Preventing layout shift
67
+ * <ClientOnly fallback={<div className="skeleton-loader" />}>
68
+ * {() => <UserDashboard />}
69
+ * </ClientOnly>
70
+ *
71
+ * // Multiple client-only sections
72
+ * <div>
73
+ * <Header />
74
+ * <ClientOnly fallback={<div>Loading navigation...</div>}>
75
+ * {() => <InteractiveNavigation />}
76
+ * </ClientOnly>
77
+ * <MainContent />
78
+ * <ClientOnly>
79
+ * {() => <ChatWidget />}
80
+ * </ClientOnly>
81
+ * </div>
82
+ * ```
83
+ */
84
+ declare function ClientOnly(props: ClientOnlyProps): import("react/jsx-runtime").JSX.Element;
85
+ export { ClientOnly };
86
+ //# sourceMappingURL=clientOnly.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clientOnly.d.ts","sourceRoot":"","sources":["../../src/components/clientOnly.tsx"],"names":[],"mappings":"AAEA,KAAK,eAAe,GAAG;IACrB,QAAQ,IAAI,KAAK,CAAC,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AAEH,iBAAS,UAAU,CAAC,KAAK,EAAE,eAAe,2CAGzC;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,86 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useHydrated } from "../hooks/useHydrated";
3
+ /**
4
+ * ClientOnly component - renders children only after hydration on the client side
5
+ *
6
+ * This component prevents hydration mismatches by rendering different content during SSR
7
+ * and after client-side hydration. It's useful for components that rely on browser APIs
8
+ * or need to render differently on server and client.
9
+ *
10
+ * @param props - ClientOnly component properties
11
+ * @param props.children - Function that returns React nodes to render after hydration
12
+ * @param props.fallback - Optional React node to render during SSR or before hydration
13
+ *
14
+ * @returns React fragment containing either fallback content or children based on hydration state
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * // Basic usage with loading fallback
19
+ * <ClientOnly fallback={<div>Loading...</div>}>
20
+ * {() => <InteractiveWidget />}
21
+ * </ClientOnly>
22
+ *
23
+ * // Client-only component without fallback
24
+ * <ClientOnly>
25
+ * {() => (
26
+ * <div>
27
+ * <p>This content only appears on the client</p>
28
+ * <p>Current time: {new Date().toLocaleString()}</p>
29
+ * </div>
30
+ * )}
31
+ * </ClientOnly>
32
+ *
33
+ * // Using with browser APIs
34
+ * <ClientOnly fallback={<div>Preparing location services...</div>}>
35
+ * {() => <GeolocationComponent />}
36
+ * </ClientOnly>
37
+ *
38
+ * // Complex interactive component
39
+ * <ClientOnly fallback={<StaticPlaceholder />}>
40
+ * {() => (
41
+ * <div>
42
+ * <Chart data={chartData} />
43
+ * <InteractiveControls />
44
+ * <RealtimeUpdates />
45
+ * </div>
46
+ * )}
47
+ * </ClientOnly>
48
+ *
49
+ * // Conditional rendering based on client capabilities
50
+ * <ClientOnly fallback={<BasicTable data={data} />}>
51
+ * {() => (
52
+ * <AdvancedDataGrid
53
+ * data={data}
54
+ * features={['sorting', 'filtering', 'virtualization']}
55
+ * />
56
+ * )}
57
+ * </ClientOnly>
58
+ *
59
+ * // Using with dynamic imports
60
+ * <ClientOnly fallback={<div>Loading editor...</div>}>
61
+ * {() => <LazyCodeEditor />}
62
+ * </ClientOnly>
63
+ *
64
+ * // Preventing layout shift
65
+ * <ClientOnly fallback={<div className="skeleton-loader" />}>
66
+ * {() => <UserDashboard />}
67
+ * </ClientOnly>
68
+ *
69
+ * // Multiple client-only sections
70
+ * <div>
71
+ * <Header />
72
+ * <ClientOnly fallback={<div>Loading navigation...</div>}>
73
+ * {() => <InteractiveNavigation />}
74
+ * </ClientOnly>
75
+ * <MainContent />
76
+ * <ClientOnly>
77
+ * {() => <ChatWidget />}
78
+ * </ClientOnly>
79
+ * </div>
80
+ * ```
81
+ */
82
+ function ClientOnly(props) {
83
+ const { children, fallback = null } = props;
84
+ return useHydrated() ? _jsx(_Fragment, { children: children() }) : _jsx(_Fragment, { children: fallback });
85
+ }
86
+ export { ClientOnly };
@@ -0,0 +1,13 @@
1
+ import "./styles.css";
2
+ type HasFileContentProps = {
3
+ disabled: boolean;
4
+ acceptFile: string;
5
+ isLoading: boolean;
6
+ changeFileButtonText: string;
7
+ file: File;
8
+ reSendFile?: () => void;
9
+ handleSelectFile: (file: File) => void;
10
+ };
11
+ declare function HasFileContent(props: HasFileContentProps): import("react/jsx-runtime").JSX.Element;
12
+ export { HasFileContent };
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/fileUpload/hasFileContent/index.tsx"],"names":[],"mappings":"AAaA,OAAO,cAAc,CAAC;AAEtB,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,gBAAgB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACxC,CAAC;AAEF,iBAAS,cAAc,CAAC,KAAK,EAAE,mBAAmB,2CAyEjD;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { File, FileArchive, FileAudio, FileImage, RefreshCw, } from "lucide-react";
3
+ import { Button } from "../../button";
4
+ import { Divider } from "../../divider";
5
+ import { IconButton } from "../../iconButton";
6
+ import { Tooltip } from "../../tooltip";
7
+ import "./styles.css";
8
+ function HasFileContent(props) {
9
+ const { disabled, file, isLoading, acceptFile, changeFileButtonText, handleSelectFile, reSendFile, } = props;
10
+ function handleClick() {
11
+ if (disabled)
12
+ return;
13
+ const input = document.createElement("input");
14
+ input.type = "file";
15
+ input.accept = acceptFile;
16
+ input.onchange = (event) => {
17
+ const file = event.target.files?.[0];
18
+ if (file)
19
+ handleSelectFile(file);
20
+ };
21
+ input.click();
22
+ }
23
+ function FileIcon() {
24
+ if (file.type.startsWith("image/"))
25
+ return _jsx(FileImage, {});
26
+ if (file.type.startsWith("audio/"))
27
+ return _jsx(FileAudio, {});
28
+ if (file.type.startsWith("application/zip"))
29
+ return _jsx(FileArchive, {});
30
+ return _jsx(File, {});
31
+ }
32
+ return (_jsxs("div", { className: "arkynFileUploadHasFileContent", children: [_jsxs("section", { className: "arkynFileUploadFileContainer", children: [_jsx(FileIcon, {}), _jsx("p", { children: file.name })] }), _jsx(Divider, {}), _jsxs("div", { className: "arkynFileUploadButtonsContainer", children: [!!reSendFile && (_jsx(Tooltip, { orientation: "bottom", text: "Reenviar arquivo", children: _jsx(IconButton, { type: "button", "aria-label": "resend file", variant: "outline", scheme: "danger", size: "sm", isLoading: isLoading, onClick: reSendFile, icon: RefreshCw, disabled: disabled }) })), _jsx(Button, { isLoading: isLoading, onClick: handleClick, variant: "outline", size: "sm", type: "button", disabled: disabled, children: changeFileButtonText })] })] }));
33
+ }
34
+ export { HasFileContent };
@@ -0,0 +1,94 @@
1
+ import "./styles.css";
2
+ type FileUploadProps = {
3
+ name: string;
4
+ action: string;
5
+ disabled?: boolean;
6
+ label?: string;
7
+ showAsterisk?: boolean;
8
+ changeFileButtonText?: string;
9
+ selectFileButtonText?: string;
10
+ dropFileText?: string;
11
+ method?: string;
12
+ fileName?: string;
13
+ fileResponseName?: string;
14
+ acceptFile?: string;
15
+ onChange?: (url?: string) => void;
16
+ };
17
+ /**
18
+ * FileUpload component - used for uploading files with drag and drop functionality
19
+ *
20
+ * @param props - FileUpload component properties
21
+ * @param props.name - Required field name for form handling
22
+ * @param props.action - Required endpoint URL where the file will be uploaded
23
+ * @param props.disabled - Whether the file upload is disabled. Default: false
24
+ * @param props.label - Optional label text to display above the file upload area
25
+ * @param props.showAsterisk - Whether to show asterisk on label for required fields. Default: false
26
+ * @param props.changeFileButtonText - Text for the button to change/replace an uploaded file. Default: "Alterar arquivo"
27
+ * @param props.selectFileButtonText - Text for the button to select a file. Default: "Selecionar arquivo"
28
+ * @param props.dropFileText - Text displayed in the drop zone area. Default: "Ou arraste e solte o arquivo aqui"
29
+ * @param props.method - HTTP method for the upload request. Default: "POST"
30
+ * @param props.fileName - Form data field name for the file. Default: "file"
31
+ * @param props.fileResponseName - Property name in the response object containing the file URL. Default: "url"
32
+ * @param props.acceptFile - File types accepted by the input (e.g., "image/*", ".pdf"). Default: "*"
33
+ * @param props.onChange - Callback function called when file upload completes successfully, receives the file URL
34
+ *
35
+ * @returns FileUpload JSX element wrapped in FieldGroup with optional label and error handling
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * // Basic file upload
40
+ * <FileUpload
41
+ * name="document"
42
+ * action="/api/upload"
43
+ * />
44
+ *
45
+ * // File upload with label and custom text
46
+ * <FileUpload
47
+ * name="avatar"
48
+ * action="/api/upload/avatar"
49
+ * label="Profile Picture"
50
+ * showAsterisk
51
+ * selectFileButtonText="Choose Image"
52
+ * changeFileButtonText="Change Image"
53
+ * dropFileText="Drop your image here"
54
+ * />
55
+ *
56
+ * // File upload with restrictions and callback
57
+ * <FileUpload
58
+ * name="pdf"
59
+ * action="/api/upload/document"
60
+ * label="Upload PDF Document"
61
+ * acceptFile=".pdf"
62
+ * fileName="document"
63
+ * fileResponseName="documentUrl"
64
+ * onChange={(url) => console.log('File uploaded:', url)}
65
+ * />
66
+ *
67
+ * // Disabled file upload
68
+ * <FileUpload
69
+ * name="attachment"
70
+ * action="/api/upload"
71
+ * label="Attachment"
72
+ * disabled
73
+ * />
74
+ *
75
+ * // File upload with custom HTTP method and response handling
76
+ * <FileUpload
77
+ * name="file"
78
+ * action="/api/files"
79
+ * method="PUT"
80
+ * fileName="uploadedFile"
81
+ * fileResponseName="fileUrl"
82
+ * label="Custom Upload"
83
+ * onChange={(url) => {
84
+ * if (url) {
85
+ * setFileUrl(url);
86
+ * console.log('Upload successful:', url);
87
+ * }
88
+ * }}
89
+ * />
90
+ * ```
91
+ */
92
+ declare function FileUpload(props: FileUploadProps): import("react/jsx-runtime").JSX.Element;
93
+ export { FileUpload };
94
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/fileUpload/index.tsx"],"names":[],"mappings":"AASA,OAAO,cAAc,CAAC;AAEtB,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IAEf,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AAEH,iBAAS,UAAU,CAAC,KAAK,EAAE,eAAe,2CAgGzC;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,127 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { useForm } from "../../hooks/useForm";
4
+ import { FieldError } from "../fieldError";
5
+ import { FieldLabel } from "../fieldLabel";
6
+ import { FieldWrapper } from "../fieldWrapper";
7
+ import { HasFileContent } from "./hasFileContent";
8
+ import { NoFileContent } from "./noFileContent";
9
+ import "./styles.css";
10
+ /**
11
+ * FileUpload component - used for uploading files with drag and drop functionality
12
+ *
13
+ * @param props - FileUpload component properties
14
+ * @param props.name - Required field name for form handling
15
+ * @param props.action - Required endpoint URL where the file will be uploaded
16
+ * @param props.disabled - Whether the file upload is disabled. Default: false
17
+ * @param props.label - Optional label text to display above the file upload area
18
+ * @param props.showAsterisk - Whether to show asterisk on label for required fields. Default: false
19
+ * @param props.changeFileButtonText - Text for the button to change/replace an uploaded file. Default: "Alterar arquivo"
20
+ * @param props.selectFileButtonText - Text for the button to select a file. Default: "Selecionar arquivo"
21
+ * @param props.dropFileText - Text displayed in the drop zone area. Default: "Ou arraste e solte o arquivo aqui"
22
+ * @param props.method - HTTP method for the upload request. Default: "POST"
23
+ * @param props.fileName - Form data field name for the file. Default: "file"
24
+ * @param props.fileResponseName - Property name in the response object containing the file URL. Default: "url"
25
+ * @param props.acceptFile - File types accepted by the input (e.g., "image/*", ".pdf"). Default: "*"
26
+ * @param props.onChange - Callback function called when file upload completes successfully, receives the file URL
27
+ *
28
+ * @returns FileUpload JSX element wrapped in FieldGroup with optional label and error handling
29
+ *
30
+ * @example
31
+ * ```tsx
32
+ * // Basic file upload
33
+ * <FileUpload
34
+ * name="document"
35
+ * action="/api/upload"
36
+ * />
37
+ *
38
+ * // File upload with label and custom text
39
+ * <FileUpload
40
+ * name="avatar"
41
+ * action="/api/upload/avatar"
42
+ * label="Profile Picture"
43
+ * showAsterisk
44
+ * selectFileButtonText="Choose Image"
45
+ * changeFileButtonText="Change Image"
46
+ * dropFileText="Drop your image here"
47
+ * />
48
+ *
49
+ * // File upload with restrictions and callback
50
+ * <FileUpload
51
+ * name="pdf"
52
+ * action="/api/upload/document"
53
+ * label="Upload PDF Document"
54
+ * acceptFile=".pdf"
55
+ * fileName="document"
56
+ * fileResponseName="documentUrl"
57
+ * onChange={(url) => console.log('File uploaded:', url)}
58
+ * />
59
+ *
60
+ * // Disabled file upload
61
+ * <FileUpload
62
+ * name="attachment"
63
+ * action="/api/upload"
64
+ * label="Attachment"
65
+ * disabled
66
+ * />
67
+ *
68
+ * // File upload with custom HTTP method and response handling
69
+ * <FileUpload
70
+ * name="file"
71
+ * action="/api/files"
72
+ * method="PUT"
73
+ * fileName="uploadedFile"
74
+ * fileResponseName="fileUrl"
75
+ * label="Custom Upload"
76
+ * onChange={(url) => {
77
+ * if (url) {
78
+ * setFileUrl(url);
79
+ * console.log('Upload successful:', url);
80
+ * }
81
+ * }}
82
+ * />
83
+ * ```
84
+ */
85
+ function FileUpload(props) {
86
+ const { name, label, showAsterisk = false, action, fileName = "file", method = "POST", acceptFile = "*", fileResponseName = "url", changeFileButtonText = "Alterar arquivo", selectFileButtonText = "Selecionar arquivo", dropFileText = "Ou arraste e solte o arquivo aqui", onChange, disabled = false, } = props;
87
+ const { fieldErrors } = useForm();
88
+ const fieldError = fieldErrors?.[name];
89
+ const [value, setValue] = useState("");
90
+ const [error, setError] = useState("");
91
+ const [file, setFile] = useState(null);
92
+ const [isLoading, setIsLoading] = useState(false);
93
+ async function handleUploadFile(file) {
94
+ if (disabled)
95
+ return;
96
+ setIsLoading(true);
97
+ setFile(file);
98
+ setError("");
99
+ const formData = new FormData();
100
+ formData.append(fileName, file);
101
+ await fetch(action, { method: method, body: formData })
102
+ .then(async (response) => await response.json())
103
+ .then((response) => {
104
+ if (!!response?.error)
105
+ setError(response.error);
106
+ else
107
+ setValue(response?.[fileResponseName]);
108
+ onChange && onChange(response?.[fileResponseName]);
109
+ })
110
+ .catch((error) => {
111
+ console.error(error);
112
+ setError("Erro ao enviar o arquivo");
113
+ })
114
+ .finally(() => setIsLoading(false));
115
+ }
116
+ function handleSelectFile(file) {
117
+ if (disabled)
118
+ return;
119
+ handleUploadFile(file);
120
+ }
121
+ const errorMessage = fieldError || error;
122
+ const hasErrorClassName = errorMessage ? "hasError" : "noHasError";
123
+ const hasFileClassName = file ? "hasFile" : "noHasFile";
124
+ const className = `arkynFileUpload ${hasErrorClassName} ${hasFileClassName}`;
125
+ return (_jsxs(FieldWrapper, { children: [label && _jsx(FieldLabel, { showAsterisk: showAsterisk, children: label }), _jsxs("div", { className: className, children: [_jsx("input", { type: "hidden", name: name, value: value || "" }), !file && (_jsx(NoFileContent, { disabled: disabled, isLoading: isLoading, acceptFile: acceptFile, dropFileText: dropFileText, handleSelectFile: handleSelectFile, selectFileButtonText: selectFileButtonText })), file && (_jsx(HasFileContent, { disabled: disabled, isLoading: isLoading, acceptFile: acceptFile, file: file, handleSelectFile: handleSelectFile, changeFileButtonText: changeFileButtonText, reSendFile: !!errorMessage && file ? () => handleUploadFile(file) : undefined }))] }), errorMessage && _jsx(FieldError, { children: errorMessage })] }));
126
+ }
127
+ export { FileUpload };
@@ -0,0 +1,12 @@
1
+ import "./styles.css";
2
+ type NoFileContentProps = {
3
+ disabled: boolean;
4
+ acceptFile: string;
5
+ isLoading: boolean;
6
+ selectFileButtonText: string;
7
+ dropFileText: string;
8
+ handleSelectFile: (file: File) => void;
9
+ };
10
+ declare function NoFileContent(props: NoFileContentProps): import("react/jsx-runtime").JSX.Element;
11
+ export { NoFileContent };
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/fileUpload/noFileContent/index.tsx"],"names":[],"mappings":"AAIA,OAAO,cAAc,CAAC;AAEtB,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACxC,CAAC;AAEF,iBAAS,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CAkD/C;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}