@nolwenture/formik-jsonschema-form 1.0.0-beta.50 → 1.0.0-beta.52

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 (27) hide show
  1. package/dist/cjs/Form/fields/FilesUploadField/FilesUploadField.js +64 -0
  2. package/dist/cjs/Form/fields/FilesUploadField/FilesUploadFieldInput.js +75 -0
  3. package/dist/cjs/Form/fields/FilesUploadField/index.js +41 -0
  4. package/dist/cjs/Form/fields/FilesUploadField/styledComponents.js +197 -0
  5. package/dist/cjs/Form/fields/index.js +3 -0
  6. package/dist/cjs/FormView/components/Field.js +1 -1
  7. package/dist/cjs/FormView/fields/FilesUploadField.js +7 -0
  8. package/dist/cjs/FormView/fields/index.js +2 -0
  9. package/dist/cjs/common/FilesUploadContext.js +14 -0
  10. package/dist/esm/Form/fields/FilesUploadField/FilesUploadField.js +60 -0
  11. package/dist/esm/Form/fields/FilesUploadField/FilesUploadFieldInput.js +71 -0
  12. package/dist/esm/Form/fields/FilesUploadField/index.js +5 -0
  13. package/dist/esm/Form/fields/FilesUploadField/styledComponents.js +191 -0
  14. package/dist/esm/Form/fields/index.js +3 -0
  15. package/dist/esm/FormView/components/Field.js +1 -1
  16. package/dist/esm/FormView/fields/FilesUploadField.js +3 -0
  17. package/dist/esm/FormView/fields/index.js +2 -0
  18. package/dist/esm/common/FilesUploadContext.js +11 -0
  19. package/dist/types/Form/components/index.d.ts +26 -1
  20. package/dist/types/Form/fields/FilesUploadField/FilesUploadField.d.ts +2 -0
  21. package/dist/types/Form/fields/FilesUploadField/FilesUploadFieldInput.d.ts +37 -0
  22. package/dist/types/Form/fields/FilesUploadField/index.d.ts +31 -0
  23. package/dist/types/Form/fields/FilesUploadField/styledComponents.d.ts +26 -0
  24. package/dist/types/Form/fields/index.d.ts +28 -1
  25. package/dist/types/FormView/fields/FilesUploadField.d.ts +2 -0
  26. package/dist/types/common/FilesUploadContext.d.ts +12 -0
  27. package/package.json +1 -1
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FilesUploadField = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const formik_1 = require("formik");
7
+ const utils_1 = require("../../../utils");
8
+ const FilesUploadContext_1 = require("../../../common/FilesUploadContext");
9
+ const hooks_1 = require("../../hooks");
10
+ const FormRegistry_1 = require("../../FormRegistry");
11
+ const FilesUploadField = (props) => {
12
+ const { templates, components: { FilesUploadFieldInput }, } = (0, react_1.useContext)(FormRegistry_1.FormRegistry);
13
+ (0, hooks_1.useSetDefault)(props);
14
+ const { name, uiSchema } = props;
15
+ const { props: inputProps } = (0, react_1.useMemo)(() => (0, utils_1.extractUiSchema)(uiSchema), [uiSchema]);
16
+ const { setFieldValue, values } = (0, formik_1.useFormikContext)();
17
+ const value = (0, formik_1.getIn)(values, name);
18
+ const { uploadFiles, removeFile } = (0, react_1.useContext)(FilesUploadContext_1.FilesUploadContext);
19
+ const [uploadedFiles, setUploadedFiles] = (0, react_1.useState)([]);
20
+ (0, react_1.useEffect)(() => {
21
+ (async () => setUploadedFiles(value))();
22
+ }, [value]);
23
+ const [uploadProgress, setUploadProgress] = (0, react_1.useState)({});
24
+ const handleFileUpload = async (files, setFieldValue) => {
25
+ const formData = new FormData();
26
+ for (const file of files) {
27
+ formData.append("files", file);
28
+ }
29
+ try {
30
+ const result = await uploadFiles({
31
+ data: formData,
32
+ onUploadProgress: (progressEvent, id) => {
33
+ const totalLength = progressEvent.total;
34
+ if (totalLength !== null && totalLength !== undefined) {
35
+ const progress = Math.round((progressEvent.loaded * 100) / totalLength);
36
+ setUploadProgress((prev) => ({ ...prev, [id]: progress }));
37
+ }
38
+ },
39
+ });
40
+ setFieldValue(name, (currentValue) => {
41
+ const existingFiles = Array.isArray(currentValue) ? currentValue : [];
42
+ return [...existingFiles, ...result];
43
+ });
44
+ }
45
+ catch (error) {
46
+ console.error("File upload failed", error);
47
+ }
48
+ };
49
+ const handleRemoveFile = async (file, setFieldValue) => {
50
+ if (file.id) {
51
+ await removeFile(file);
52
+ setUploadProgress((prev) => {
53
+ const { [file.id]: _, ...rest } = prev;
54
+ return rest;
55
+ });
56
+ setFieldValue(name, (currentValue) => (currentValue || []).filter((f) => f.id !== file.id));
57
+ }
58
+ };
59
+ const SelectedFieldTemplate = (props.uiSchema?.["ui:template"] &&
60
+ templates[props.uiSchema?.["ui:template"]]) ??
61
+ templates.FieldTemplate;
62
+ return ((0, jsx_runtime_1.jsx)(SelectedFieldTemplate, { ...props, "data-fjsf-object": name, children: (0, jsx_runtime_1.jsx)(FilesUploadFieldInput, { ...inputProps, deleteFileAriaLabel: uiSchema["ui:deleteFileAriaLabel"], fileInfoText: uiSchema["ui:fileInfoText"], handleFileUpload: handleFileUpload, handleRemoveFile: handleRemoveFile, hideFileTypeIcon: inputProps?.fileTypeIcon.hidden, hideFileSize: inputProps?.fileSize.hidden, hideRemoveButton: inputProps?.removeButton.hidden, hideUploadIcon: inputProps?.uploadIcon.hidden, infoText: uiSchema["ui:infoText"], name: name, orText: uiSchema["ui:orText"], removeButton: uiSchema["ui:removeButton"], renderFile: inputProps?.renderFile, setFieldValue: setFieldValue, uploadButtonText: uiSchema["ui:uploadButtonText"], uploadedFiles: uploadedFiles, uploadProgress: uploadProgress, value: value }) }));
63
+ };
64
+ exports.FilesUploadField = FilesUploadField;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FilesUploadFieldInput = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const fa_1 = require("react-icons/fa");
7
+ const FormRegistry_1 = require("../../FormRegistry");
8
+ const mimeTypeToIcon = {
9
+ 'pdf': fa_1.FaFilePdf,
10
+ 'audio': fa_1.FaFileAudio,
11
+ 'image': fa_1.FaFileImage,
12
+ 'csv': fa_1.FaFileCsv,
13
+ 'wordprocessingml.document': fa_1.FaFileWord,
14
+ 'msword': fa_1.FaFileWord,
15
+ 'vnd.ms-excel': fa_1.FaFileExcel,
16
+ 'vnd.openxmlformats-officedocument.spreadsheetml.sheet': fa_1.FaFileExcel,
17
+ 'vnd.ms-powerpoint': fa_1.FaFilePowerpoint,
18
+ 'vnd.openxmlformats-officedocument.presentationml.presentation': fa_1.FaFilePowerpoint,
19
+ 'javascript': fa_1.FaFileCode,
20
+ 'html': fa_1.FaFileCode,
21
+ 'css': fa_1.FaFileCode,
22
+ };
23
+ const getFileIcon = (mimeType) => {
24
+ for (const key in mimeTypeToIcon) {
25
+ if (mimeType.includes(key)) {
26
+ const IconComponent = mimeTypeToIcon[key];
27
+ return (0, jsx_runtime_1.jsx)(IconComponent, {});
28
+ }
29
+ }
30
+ return (0, jsx_runtime_1.jsx)(fa_1.FaFile, {});
31
+ };
32
+ const FilesUploadFieldInput = ({ className, deleteFileAriaLabel, fileInfoText, handleFileUpload, handleRemoveFile, hideFileTypeIcon, hideFileSize, hideRemoveButton, hideUploadIcon, infoText, name, orText, removeButton, renderFile, setFieldValue, uploadButtonText, uploadedFiles, uploadProgress, value, }) => {
33
+ const { components: { Divider, DividerText, DragOverlay, FileInfoText, FileInfoTextMinimized, FileItemContainer, FileSize, FileTypeIcon, FileUploadButton, FileUploadFieldContainer, FileUploadText, HiddenFileInput, InfoText, ProgressBar, ProgressBarContainer, RemoveButton, RemoveButtonIcon, UploadedFileInfoContainer, UploadedFileItemContainer, UploadedFileName, UploadedFileWrapper, UploadIcon, UploadingFileName, }, } = (0, react_1.useContext)(FormRegistry_1.FormRegistry);
34
+ const [isDragging, setIsDragging] = (0, react_1.useState)(false);
35
+ const dragCounter = (0, react_1.useRef)(0);
36
+ const handleDragEnter = (e) => {
37
+ e.preventDefault();
38
+ e.stopPropagation();
39
+ dragCounter.current++;
40
+ if (e.dataTransfer?.items && e.dataTransfer.items.length > 0) {
41
+ setIsDragging(true);
42
+ }
43
+ };
44
+ const handleDragLeave = (e) => {
45
+ e.preventDefault();
46
+ e.stopPropagation();
47
+ dragCounter.current--;
48
+ if (dragCounter.current === 0) {
49
+ setIsDragging(false);
50
+ }
51
+ };
52
+ const handleDragOver = (e) => {
53
+ e.preventDefault();
54
+ e.stopPropagation();
55
+ };
56
+ const handleDrop = (e) => {
57
+ e.preventDefault();
58
+ e.stopPropagation();
59
+ setIsDragging(false);
60
+ dragCounter.current = 0;
61
+ if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {
62
+ handleFileUpload(e.dataTransfer.files, setFieldValue);
63
+ e.dataTransfer.clearData();
64
+ }
65
+ };
66
+ const defaultRenderFile = (file, progress, onDelete) => ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: progress === 100 ? ((0, jsx_runtime_1.jsxs)(UploadedFileItemContainer, { children: [(0, jsx_runtime_1.jsxs)(UploadedFileInfoContainer, { children: [!hideFileTypeIcon && ((0, jsx_runtime_1.jsx)(FileTypeIcon, { children: getFileIcon(file.mimeType) })), (0, jsx_runtime_1.jsxs)(UploadedFileName, { children: [file.name, !hideFileSize && ((0, jsx_runtime_1.jsx)(FileSize, { children: ` | ${(file.size / (1024 * 1024)).toFixed(3)} MB` }))] })] }), !hideRemoveButton && ((0, jsx_runtime_1.jsx)(RemoveButton, { "aria-label": deleteFileAriaLabel ?? "Delete file", type: "button", onClick: () => onDelete(), ...removeButton?.props, children: removeButton?.content ?? (0, jsx_runtime_1.jsx)(RemoveButtonIcon, {}) }))] })) : ((0, jsx_runtime_1.jsxs)(FileItemContainer, { children: [(0, jsx_runtime_1.jsx)(UploadingFileName, { children: file.name }), (0, jsx_runtime_1.jsx)(ProgressBarContainer, { children: (0, jsx_runtime_1.jsx)(ProgressBar, { "$progress": progress }) })] })) }));
67
+ const uploadedFile = renderFile ?? defaultRenderFile;
68
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)(FileUploadFieldContainer, { className: className, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragOver: handleDragOver, onDrop: handleDrop, children: [isDragging && ((0, jsx_runtime_1.jsx)(DragOverlay, { children: infoText })), Array.isArray(uploadedFiles) && uploadedFiles.map(file => ((0, jsx_runtime_1.jsx)(UploadedFileWrapper, { children: uploadedFile(file, uploadProgress[file.id], () => handleRemoveFile(file, setFieldValue)) }, file.id))), !uploadedFiles || uploadedFiles.length === 0 ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [!hideUploadIcon && (0, jsx_runtime_1.jsx)(UploadIcon, {}), infoText && (0, jsx_runtime_1.jsx)(InfoText, { children: infoText }), (0, jsx_runtime_1.jsx)(Divider, { children: (0, jsx_runtime_1.jsx)(DividerText, { children: orText ?? "or" }) }), (0, jsx_runtime_1.jsx)(FileUploadButton, { "aria-label": uploadButtonText ?? "Browse files", type: "button", onClick: () => document.getElementById(name)?.click(), children: uploadButtonText ?? "Browse files" }), fileInfoText && (0, jsx_runtime_1.jsx)(FileInfoText, { children: fileInfoText })] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [infoText && ((0, jsx_runtime_1.jsxs)(InfoText, { children: [`${infoText} ${orText ?? 'or'} `, (0, jsx_runtime_1.jsx)(FileUploadText, { "aria-label": uploadButtonText ?? 'Browse files', onClick: () => document.getElementById(name)?.click(), children: uploadButtonText ?? 'Browse files' })] })), fileInfoText && (0, jsx_runtime_1.jsx)(FileInfoTextMinimized, { children: fileInfoText })] })), (0, jsx_runtime_1.jsx)(HiddenFileInput, { multiple: true, id: name, name: name, type: "file", onChange: (event) => {
69
+ const files = event.target.files;
70
+ if (files) {
71
+ handleFileUpload(files, setFieldValue);
72
+ }
73
+ } })] }) }));
74
+ };
75
+ exports.FilesUploadFieldInput = FilesUploadFieldInput;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.components = exports.fields = void 0;
37
+ const FilesUploadFieldInput_1 = require("./FilesUploadFieldInput");
38
+ const styledComponents = __importStar(require("./styledComponents"));
39
+ exports.fields = __importStar(require("./FilesUploadField"));
40
+ const components = { ...styledComponents, FilesUploadFieldInput: FilesUploadFieldInput_1.FilesUploadFieldInput };
41
+ exports.components = components;
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DragOverlay = exports.ProgressBar = exports.ProgressBarContainer = exports.RemoveButtonIcon = exports.RemoveButton = exports.FileSize = exports.UploadedFileName = exports.UploadingFileName = exports.FileTypeIcon = exports.UploadedFileWrapper = exports.UploadedFileInfoContainer = exports.UploadedFileItemContainer = exports.FileItemContainer = exports.FileUploadText = exports.FileUploadButton = exports.FileInfoTextMinimized = exports.FileInfoText = exports.DividerText = exports.Divider = exports.InfoText = exports.UploadIcon = exports.HiddenFileInput = exports.FileUploadFieldContainer = void 0;
7
+ const styled_components_1 = __importDefault(require("styled-components"));
8
+ const polished_1 = require("polished");
9
+ const fa_1 = require("react-icons/fa");
10
+ const component_library_1 = require("@nolwenture/component-library");
11
+ exports.FileUploadFieldContainer = styled_components_1.default.div `
12
+ align-items: center;
13
+ background-color: ${(props) => props.theme.color.background.input};
14
+ border: ${(props) => `${props.theme.strokeWidth.thin} solid ${props.theme.color.border.default}`};
15
+ display: flex;
16
+ flex-direction: column;
17
+ gap: ${(props) => props.theme.spacing.m};
18
+ justify-content: center;
19
+ padding: ${(props) => props.theme.spacing.xxl};
20
+ position: relative;
21
+ transition: 0.3s filter ease;
22
+
23
+ &:hover {
24
+ filter: brightness(110%);
25
+ }
26
+ `;
27
+ exports.HiddenFileInput = styled_components_1.default.input `
28
+ cursor: pointer;
29
+ height: 100%;
30
+ opacity: 0;
31
+ position: absolute;
32
+ width: 100%;
33
+ z-index: 1;
34
+ `;
35
+ exports.UploadIcon = (0, styled_components_1.default)(fa_1.FaCloudUploadAlt) `
36
+ color: ${(props) => props.theme.color.palette.neutral[500]};
37
+ height: auto;
38
+ width: 5rem;
39
+ `;
40
+ exports.InfoText = styled_components_1.default.p `
41
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
42
+ font-size: ${(props) => props.theme.typography.size.base};
43
+ margin: 0;
44
+ `;
45
+ exports.Divider = styled_components_1.default.div `
46
+ background: linear-gradient(180deg, transparent calc(50% - 2px), ${(props) => props.theme.color.palette.neutral[500]} calc(50%), transparent 50%);
47
+ color: ${(props) => props.theme.color.palette.neutral[500]};
48
+ display: flex;
49
+ flex-direction: row;
50
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
51
+ font-size: ${(props) => props.theme.typography.size.large};
52
+ gap: ${(props) => props.theme.spacing.m};
53
+ justify-content: center;
54
+ margin: 0;
55
+ text-transform: uppercase;
56
+ width: 70%;
57
+ `;
58
+ exports.DividerText = styled_components_1.default.p `
59
+ background-color: ${(props) => props.theme.color.background.input};
60
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
61
+ font-size: ${(props) => props.theme.typography.size.large};
62
+ margin: 0;
63
+ padding: 0 ${(props) => props.theme.spacing.m};
64
+ text-transform: uppercase;
65
+ `;
66
+ exports.FileInfoText = styled_components_1.default.p `
67
+ color: ${(props) => props.theme.color.text.default};
68
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
69
+ font-size: ${(props) => props.theme.typography.size.base};
70
+ margin-bottom: 0;
71
+ text-align: center;
72
+ `;
73
+ exports.FileInfoTextMinimized = styled_components_1.default.p `
74
+ color: ${(props) => props.theme.color.text.default};
75
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
76
+ font-size: ${(props) => props.theme.typography.size.base};
77
+ margin: 0;
78
+ text-align: center;
79
+ `;
80
+ exports.FileUploadButton = (0, styled_components_1.default)(component_library_1.Button) `
81
+ z-index: 2;
82
+ `;
83
+ exports.FileUploadText = styled_components_1.default.a `
84
+ z-index: 2;
85
+ color: ${(props) => props.theme.color.intent.default.primary};
86
+ text-decoration: underline;
87
+
88
+ &:hover {
89
+ color: ${(props) => (0, polished_1.darken)(0.3, props.theme.color.intent.default.primary)};
90
+ }
91
+ `;
92
+ exports.FileItemContainer = styled_components_1.default.div `
93
+ display: flex;
94
+ flex-direction: column;
95
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
96
+ margin: ${(props) => props.theme.spacing.m} 0;
97
+ width: 100%;
98
+ `;
99
+ exports.UploadedFileItemContainer = styled_components_1.default.div `
100
+ align-items: center;
101
+ background-color: ${(props) => props.theme.color.background.default};
102
+ border: ${(props) => `${props.theme.strokeWidth.thin} solid ${props.theme.color.border.default}`};
103
+ display: flex;
104
+ flex-direction: row;
105
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
106
+ gap: ${(props) => props.theme.spacing.m};
107
+ justify-content: space-between;
108
+ margin: 0;
109
+ padding: ${(props) => `${props.theme.spacing.m} ${props.theme.spacing.l}`};
110
+ width: 100%;
111
+ `;
112
+ exports.UploadedFileInfoContainer = styled_components_1.default.div `
113
+ align-items: center;
114
+ display: flex;
115
+ gap: ${(props) => props.theme.spacing.xs};
116
+ `;
117
+ exports.UploadedFileWrapper = styled_components_1.default.div `
118
+ display: flex;
119
+ justify-content: left;
120
+ width: 100%;
121
+ z-index: 2;
122
+ `;
123
+ exports.FileTypeIcon = styled_components_1.default.div `
124
+ align-items: center;
125
+ display: flex;
126
+
127
+ svg {
128
+ color: ${(props) => props.theme.color.intent.default.primary};
129
+ }
130
+ `;
131
+ exports.UploadingFileName = styled_components_1.default.div `
132
+ color: ${(props) => props.theme.color.text.default};
133
+ display: block;
134
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
135
+ font-size: ${(props) => props.theme.typography.size.base};
136
+ margin-bottom: 0;
137
+ `;
138
+ exports.UploadedFileName = styled_components_1.default.div `
139
+ color: ${(props) => props.theme.color.text.default};
140
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
141
+ font-size: ${(props) => props.theme.typography.size.base};
142
+ margin-bottom: 0;
143
+ word-break: break-word;
144
+ `;
145
+ exports.FileSize = styled_components_1.default.span `
146
+ color: ${(props) => props.theme.color.text.muted};
147
+ `;
148
+ exports.RemoveButton = styled_components_1.default.button `
149
+ background-color: transparent;
150
+ border: none;
151
+ cursor: pointer;
152
+ padding: 0;
153
+ `;
154
+ exports.RemoveButtonIcon = (0, styled_components_1.default)(fa_1.FaTrash) `
155
+ color: ${(props) => props.theme.color.intent.default.danger};
156
+ font-size: 1;
157
+ height: auto;
158
+ margin-top: ${(props) => props.theme.spacing.xs};
159
+ transition: 0.3s color ease;
160
+ width: 1rem;
161
+
162
+ &:hover {
163
+ color: ${(props) => props.theme.color.palette.danger[700]};
164
+ }
165
+ `;
166
+ exports.ProgressBarContainer = styled_components_1.default.div `
167
+ background-color: ${(props) => props.theme.color.palette.neutral[300]};
168
+ height: ${(props) => props.theme.spacing.s};
169
+ margin-top: ${(props) => props.theme.spacing.xs};
170
+ width: 100%;
171
+ `;
172
+ exports.ProgressBar = styled_components_1.default.div `
173
+ background-color: ${(props) => props.theme.color.palette.primary[600]};
174
+ border-radius: ${(props) => props.theme.strokeWidth.thick};
175
+ height: 100%;
176
+ transition: width 0.2s ease;
177
+ width: 0;
178
+ width: ${(props) => props.$progress}%;
179
+ `;
180
+ exports.DragOverlay = styled_components_1.default.div `
181
+ align-items: center;
182
+ background-color: ${(props) => props.theme.color.overlay[80]};
183
+ border: 4px dashed ${(props) => props.theme.color.intent.default.none};
184
+ bottom: 0;
185
+ color: ${(props) => props.theme.color.palette.primary[100]};
186
+ display: flex;
187
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
188
+ font-size: ${(props) => props.theme.typography.size.h1};
189
+ font-weight: ${(props) => props.theme.typography.weight.bold};
190
+ justify-content: center;
191
+ left: 0;
192
+ pointer-events: none;
193
+ position: absolute;
194
+ right: 0;
195
+ top: 0;
196
+ z-index: 3;
197
+ `;
@@ -39,6 +39,7 @@ const ArrayField = __importStar(require("./ArrayField"));
39
39
  const BooleanField = __importStar(require("./BooleanField"));
40
40
  const DateField = __importStar(require("./DateField"));
41
41
  const FileUploadField = __importStar(require("./FileUploadField"));
42
+ const FilesUploadField = __importStar(require("./FilesUploadField"));
42
43
  const MultipleChoiceField = __importStar(require("./MultipleChoiceField"));
43
44
  const NullField = __importStar(require("./NullField"));
44
45
  const NumberField = __importStar(require("./NumberField"));
@@ -57,6 +58,7 @@ exports.fieldComponents = {
57
58
  ...BooleanField.components,
58
59
  //...DateField.components, // DateField uses FieldInput (maybe it should wrap it)
59
60
  ...FileUploadField.components,
61
+ ...FilesUploadField.components,
60
62
  ...MultipleChoiceField.components,
61
63
  //...NullField.components, // NullField doesn't have components
62
64
  //...NumberField.components, // NumberField uses StringField (maybe bit too directly)
@@ -76,6 +78,7 @@ exports.fields = {
76
78
  ...BooleanField.fields,
77
79
  ...DateField.fields,
78
80
  ...FileUploadField.fields,
81
+ ...FilesUploadField.fields,
79
82
  ...MultipleChoiceField.fields,
80
83
  ...NullField.fields,
81
84
  ...NumberField.fields,
@@ -23,7 +23,7 @@ exports.FieldTitle = styled_components_1.default.label `
23
23
  font-family: ${(props) => props.theme.typography.fontFamily.heading};
24
24
  font-size: ${(props) => props.theme.typography.size.base};
25
25
  font-weight: ${(props) => props.theme.typography.weight.bold};
26
- margin: ${(props) => `${props.theme.spacing.xs} 0`};
26
+ margin: ${(props) => `${props.theme.spacing.xs} 0 ${props.theme.spacing.s} 0`};
27
27
  width: 100%;
28
28
  `;
29
29
  exports.FieldDescription = styled_components_1.default.div `
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FilesUploadField = void 0;
4
+ const FilesUploadField = (props) => {
5
+ return "TODO";
6
+ };
7
+ exports.FilesUploadField = FilesUploadField;
@@ -40,6 +40,7 @@ const ArrayField_1 = require("./ArrayField");
40
40
  const BooleanField_1 = require("./BooleanField");
41
41
  const DateField_1 = require("./DateField");
42
42
  const FileUploadField_1 = require("./FileUploadField");
43
+ const FilesUploadField_1 = require("./FilesUploadField");
43
44
  const MultipleChoiceField_1 = require("./MultipleChoiceField");
44
45
  const NullField_1 = require("./NullField");
45
46
  const NumberField_1 = require("./NumberField");
@@ -65,6 +66,7 @@ exports.fields /*& { EJSField: typeof EJSField }*/ = {
65
66
  BooleanField: BooleanField_1.BooleanField,
66
67
  DateField: DateField_1.DateField,
67
68
  // EJSField,
69
+ FilesUploadField: FilesUploadField_1.FilesUploadField,
68
70
  FileUploadField: FileUploadField_1.FileUploadField,
69
71
  NullField: NullField_1.NullField,
70
72
  NumberField: NumberField_1.NumberField,
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FilesUploadContext = void 0;
4
+ const react_1 = require("react");
5
+ exports.FilesUploadContext = (0, react_1.createContext)({
6
+ uploadFiles: () => {
7
+ console.error("Lacking upload from FilesUploadContext");
8
+ return Promise.reject();
9
+ },
10
+ removeFile: () => {
11
+ console.error("Lacking remove from FileUploadContext");
12
+ return Promise.reject();
13
+ },
14
+ });
@@ -0,0 +1,60 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useContext, useEffect, useMemo, useState } from "react";
3
+ import { getIn, useFormikContext } from "formik";
4
+ import { extractUiSchema } from "../../../utils";
5
+ import { FilesUploadContext } from "../../../common/FilesUploadContext";
6
+ import { useSetDefault } from "../../hooks";
7
+ import { FormRegistry } from "../../FormRegistry";
8
+ export const FilesUploadField = (props) => {
9
+ const { templates, components: { FilesUploadFieldInput }, } = useContext(FormRegistry);
10
+ useSetDefault(props);
11
+ const { name, uiSchema } = props;
12
+ const { props: inputProps } = useMemo(() => extractUiSchema(uiSchema), [uiSchema]);
13
+ const { setFieldValue, values } = useFormikContext();
14
+ const value = getIn(values, name);
15
+ const { uploadFiles, removeFile } = useContext(FilesUploadContext);
16
+ const [uploadedFiles, setUploadedFiles] = useState([]);
17
+ useEffect(() => {
18
+ (async () => setUploadedFiles(value))();
19
+ }, [value]);
20
+ const [uploadProgress, setUploadProgress] = useState({});
21
+ const handleFileUpload = async (files, setFieldValue) => {
22
+ const formData = new FormData();
23
+ for (const file of files) {
24
+ formData.append("files", file);
25
+ }
26
+ try {
27
+ const result = await uploadFiles({
28
+ data: formData,
29
+ onUploadProgress: (progressEvent, id) => {
30
+ const totalLength = progressEvent.total;
31
+ if (totalLength !== null && totalLength !== undefined) {
32
+ const progress = Math.round((progressEvent.loaded * 100) / totalLength);
33
+ setUploadProgress((prev) => ({ ...prev, [id]: progress }));
34
+ }
35
+ },
36
+ });
37
+ setFieldValue(name, (currentValue) => {
38
+ const existingFiles = Array.isArray(currentValue) ? currentValue : [];
39
+ return [...existingFiles, ...result];
40
+ });
41
+ }
42
+ catch (error) {
43
+ console.error("File upload failed", error);
44
+ }
45
+ };
46
+ const handleRemoveFile = async (file, setFieldValue) => {
47
+ if (file.id) {
48
+ await removeFile(file);
49
+ setUploadProgress((prev) => {
50
+ const { [file.id]: _, ...rest } = prev;
51
+ return rest;
52
+ });
53
+ setFieldValue(name, (currentValue) => (currentValue || []).filter((f) => f.id !== file.id));
54
+ }
55
+ };
56
+ const SelectedFieldTemplate = (props.uiSchema?.["ui:template"] &&
57
+ templates[props.uiSchema?.["ui:template"]]) ??
58
+ templates.FieldTemplate;
59
+ return (_jsx(SelectedFieldTemplate, { ...props, "data-fjsf-object": name, children: _jsx(FilesUploadFieldInput, { ...inputProps, deleteFileAriaLabel: uiSchema["ui:deleteFileAriaLabel"], fileInfoText: uiSchema["ui:fileInfoText"], handleFileUpload: handleFileUpload, handleRemoveFile: handleRemoveFile, hideFileTypeIcon: inputProps?.fileTypeIcon.hidden, hideFileSize: inputProps?.fileSize.hidden, hideRemoveButton: inputProps?.removeButton.hidden, hideUploadIcon: inputProps?.uploadIcon.hidden, infoText: uiSchema["ui:infoText"], name: name, orText: uiSchema["ui:orText"], removeButton: uiSchema["ui:removeButton"], renderFile: inputProps?.renderFile, setFieldValue: setFieldValue, uploadButtonText: uiSchema["ui:uploadButtonText"], uploadedFiles: uploadedFiles, uploadProgress: uploadProgress, value: value }) }));
60
+ };
@@ -0,0 +1,71 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useContext, useState, useRef } from "react";
3
+ import { FaFile, FaFilePdf, FaFileAudio, FaFileCode, FaFileCsv, FaFileExcel, FaFileImage, FaFilePowerpoint, FaFileWord } from "react-icons/fa";
4
+ import { FormRegistry } from "../../FormRegistry";
5
+ const mimeTypeToIcon = {
6
+ 'pdf': FaFilePdf,
7
+ 'audio': FaFileAudio,
8
+ 'image': FaFileImage,
9
+ 'csv': FaFileCsv,
10
+ 'wordprocessingml.document': FaFileWord,
11
+ 'msword': FaFileWord,
12
+ 'vnd.ms-excel': FaFileExcel,
13
+ 'vnd.openxmlformats-officedocument.spreadsheetml.sheet': FaFileExcel,
14
+ 'vnd.ms-powerpoint': FaFilePowerpoint,
15
+ 'vnd.openxmlformats-officedocument.presentationml.presentation': FaFilePowerpoint,
16
+ 'javascript': FaFileCode,
17
+ 'html': FaFileCode,
18
+ 'css': FaFileCode,
19
+ };
20
+ const getFileIcon = (mimeType) => {
21
+ for (const key in mimeTypeToIcon) {
22
+ if (mimeType.includes(key)) {
23
+ const IconComponent = mimeTypeToIcon[key];
24
+ return _jsx(IconComponent, {});
25
+ }
26
+ }
27
+ return _jsx(FaFile, {});
28
+ };
29
+ export const FilesUploadFieldInput = ({ className, deleteFileAriaLabel, fileInfoText, handleFileUpload, handleRemoveFile, hideFileTypeIcon, hideFileSize, hideRemoveButton, hideUploadIcon, infoText, name, orText, removeButton, renderFile, setFieldValue, uploadButtonText, uploadedFiles, uploadProgress, value, }) => {
30
+ const { components: { Divider, DividerText, DragOverlay, FileInfoText, FileInfoTextMinimized, FileItemContainer, FileSize, FileTypeIcon, FileUploadButton, FileUploadFieldContainer, FileUploadText, HiddenFileInput, InfoText, ProgressBar, ProgressBarContainer, RemoveButton, RemoveButtonIcon, UploadedFileInfoContainer, UploadedFileItemContainer, UploadedFileName, UploadedFileWrapper, UploadIcon, UploadingFileName, }, } = useContext(FormRegistry);
31
+ const [isDragging, setIsDragging] = useState(false);
32
+ const dragCounter = useRef(0);
33
+ const handleDragEnter = (e) => {
34
+ e.preventDefault();
35
+ e.stopPropagation();
36
+ dragCounter.current++;
37
+ if (e.dataTransfer?.items && e.dataTransfer.items.length > 0) {
38
+ setIsDragging(true);
39
+ }
40
+ };
41
+ const handleDragLeave = (e) => {
42
+ e.preventDefault();
43
+ e.stopPropagation();
44
+ dragCounter.current--;
45
+ if (dragCounter.current === 0) {
46
+ setIsDragging(false);
47
+ }
48
+ };
49
+ const handleDragOver = (e) => {
50
+ e.preventDefault();
51
+ e.stopPropagation();
52
+ };
53
+ const handleDrop = (e) => {
54
+ e.preventDefault();
55
+ e.stopPropagation();
56
+ setIsDragging(false);
57
+ dragCounter.current = 0;
58
+ if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {
59
+ handleFileUpload(e.dataTransfer.files, setFieldValue);
60
+ e.dataTransfer.clearData();
61
+ }
62
+ };
63
+ const defaultRenderFile = (file, progress, onDelete) => (_jsx(_Fragment, { children: progress === 100 ? (_jsxs(UploadedFileItemContainer, { children: [_jsxs(UploadedFileInfoContainer, { children: [!hideFileTypeIcon && (_jsx(FileTypeIcon, { children: getFileIcon(file.mimeType) })), _jsxs(UploadedFileName, { children: [file.name, !hideFileSize && (_jsx(FileSize, { children: ` | ${(file.size / (1024 * 1024)).toFixed(3)} MB` }))] })] }), !hideRemoveButton && (_jsx(RemoveButton, { "aria-label": deleteFileAriaLabel ?? "Delete file", type: "button", onClick: () => onDelete(), ...removeButton?.props, children: removeButton?.content ?? _jsx(RemoveButtonIcon, {}) }))] })) : (_jsxs(FileItemContainer, { children: [_jsx(UploadingFileName, { children: file.name }), _jsx(ProgressBarContainer, { children: _jsx(ProgressBar, { "$progress": progress }) })] })) }));
64
+ const uploadedFile = renderFile ?? defaultRenderFile;
65
+ return (_jsx(_Fragment, { children: _jsxs(FileUploadFieldContainer, { className: className, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragOver: handleDragOver, onDrop: handleDrop, children: [isDragging && (_jsx(DragOverlay, { children: infoText })), Array.isArray(uploadedFiles) && uploadedFiles.map(file => (_jsx(UploadedFileWrapper, { children: uploadedFile(file, uploadProgress[file.id], () => handleRemoveFile(file, setFieldValue)) }, file.id))), !uploadedFiles || uploadedFiles.length === 0 ? (_jsxs(_Fragment, { children: [!hideUploadIcon && _jsx(UploadIcon, {}), infoText && _jsx(InfoText, { children: infoText }), _jsx(Divider, { children: _jsx(DividerText, { children: orText ?? "or" }) }), _jsx(FileUploadButton, { "aria-label": uploadButtonText ?? "Browse files", type: "button", onClick: () => document.getElementById(name)?.click(), children: uploadButtonText ?? "Browse files" }), fileInfoText && _jsx(FileInfoText, { children: fileInfoText })] })) : (_jsxs(_Fragment, { children: [infoText && (_jsxs(InfoText, { children: [`${infoText} ${orText ?? 'or'} `, _jsx(FileUploadText, { "aria-label": uploadButtonText ?? 'Browse files', onClick: () => document.getElementById(name)?.click(), children: uploadButtonText ?? 'Browse files' })] })), fileInfoText && _jsx(FileInfoTextMinimized, { children: fileInfoText })] })), _jsx(HiddenFileInput, { multiple: true, id: name, name: name, type: "file", onChange: (event) => {
66
+ const files = event.target.files;
67
+ if (files) {
68
+ handleFileUpload(files, setFieldValue);
69
+ }
70
+ } })] }) }));
71
+ };
@@ -0,0 +1,5 @@
1
+ import { FilesUploadFieldInput } from "./FilesUploadFieldInput";
2
+ import * as styledComponents from "./styledComponents";
3
+ export * as fields from "./FilesUploadField";
4
+ const components = { ...styledComponents, FilesUploadFieldInput };
5
+ export { components };
@@ -0,0 +1,191 @@
1
+ import styled from "styled-components";
2
+ import { darken } from "polished";
3
+ import { FaCloudUploadAlt, FaTrash } from "react-icons/fa";
4
+ import { Button } from "@nolwenture/component-library";
5
+ export const FileUploadFieldContainer = styled.div `
6
+ align-items: center;
7
+ background-color: ${(props) => props.theme.color.background.input};
8
+ border: ${(props) => `${props.theme.strokeWidth.thin} solid ${props.theme.color.border.default}`};
9
+ display: flex;
10
+ flex-direction: column;
11
+ gap: ${(props) => props.theme.spacing.m};
12
+ justify-content: center;
13
+ padding: ${(props) => props.theme.spacing.xxl};
14
+ position: relative;
15
+ transition: 0.3s filter ease;
16
+
17
+ &:hover {
18
+ filter: brightness(110%);
19
+ }
20
+ `;
21
+ export const HiddenFileInput = styled.input `
22
+ cursor: pointer;
23
+ height: 100%;
24
+ opacity: 0;
25
+ position: absolute;
26
+ width: 100%;
27
+ z-index: 1;
28
+ `;
29
+ export const UploadIcon = styled(FaCloudUploadAlt) `
30
+ color: ${(props) => props.theme.color.palette.neutral[500]};
31
+ height: auto;
32
+ width: 5rem;
33
+ `;
34
+ export const InfoText = styled.p `
35
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
36
+ font-size: ${(props) => props.theme.typography.size.base};
37
+ margin: 0;
38
+ `;
39
+ export const Divider = styled.div `
40
+ background: linear-gradient(180deg, transparent calc(50% - 2px), ${(props) => props.theme.color.palette.neutral[500]} calc(50%), transparent 50%);
41
+ color: ${(props) => props.theme.color.palette.neutral[500]};
42
+ display: flex;
43
+ flex-direction: row;
44
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
45
+ font-size: ${(props) => props.theme.typography.size.large};
46
+ gap: ${(props) => props.theme.spacing.m};
47
+ justify-content: center;
48
+ margin: 0;
49
+ text-transform: uppercase;
50
+ width: 70%;
51
+ `;
52
+ export const DividerText = styled.p `
53
+ background-color: ${(props) => props.theme.color.background.input};
54
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
55
+ font-size: ${(props) => props.theme.typography.size.large};
56
+ margin: 0;
57
+ padding: 0 ${(props) => props.theme.spacing.m};
58
+ text-transform: uppercase;
59
+ `;
60
+ export const FileInfoText = styled.p `
61
+ color: ${(props) => props.theme.color.text.default};
62
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
63
+ font-size: ${(props) => props.theme.typography.size.base};
64
+ margin-bottom: 0;
65
+ text-align: center;
66
+ `;
67
+ export const FileInfoTextMinimized = styled.p `
68
+ color: ${(props) => props.theme.color.text.default};
69
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
70
+ font-size: ${(props) => props.theme.typography.size.base};
71
+ margin: 0;
72
+ text-align: center;
73
+ `;
74
+ export const FileUploadButton = styled(Button) `
75
+ z-index: 2;
76
+ `;
77
+ export const FileUploadText = styled.a `
78
+ z-index: 2;
79
+ color: ${(props) => props.theme.color.intent.default.primary};
80
+ text-decoration: underline;
81
+
82
+ &:hover {
83
+ color: ${(props) => darken(0.3, props.theme.color.intent.default.primary)};
84
+ }
85
+ `;
86
+ export const FileItemContainer = styled.div `
87
+ display: flex;
88
+ flex-direction: column;
89
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
90
+ margin: ${(props) => props.theme.spacing.m} 0;
91
+ width: 100%;
92
+ `;
93
+ export const UploadedFileItemContainer = styled.div `
94
+ align-items: center;
95
+ background-color: ${(props) => props.theme.color.background.default};
96
+ border: ${(props) => `${props.theme.strokeWidth.thin} solid ${props.theme.color.border.default}`};
97
+ display: flex;
98
+ flex-direction: row;
99
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
100
+ gap: ${(props) => props.theme.spacing.m};
101
+ justify-content: space-between;
102
+ margin: 0;
103
+ padding: ${(props) => `${props.theme.spacing.m} ${props.theme.spacing.l}`};
104
+ width: 100%;
105
+ `;
106
+ export const UploadedFileInfoContainer = styled.div `
107
+ align-items: center;
108
+ display: flex;
109
+ gap: ${(props) => props.theme.spacing.xs};
110
+ `;
111
+ export const UploadedFileWrapper = styled.div `
112
+ display: flex;
113
+ justify-content: left;
114
+ width: 100%;
115
+ z-index: 2;
116
+ `;
117
+ export const FileTypeIcon = styled.div `
118
+ align-items: center;
119
+ display: flex;
120
+
121
+ svg {
122
+ color: ${(props) => props.theme.color.intent.default.primary};
123
+ }
124
+ `;
125
+ export const UploadingFileName = styled.div `
126
+ color: ${(props) => props.theme.color.text.default};
127
+ display: block;
128
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
129
+ font-size: ${(props) => props.theme.typography.size.base};
130
+ margin-bottom: 0;
131
+ `;
132
+ export const UploadedFileName = styled.div `
133
+ color: ${(props) => props.theme.color.text.default};
134
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
135
+ font-size: ${(props) => props.theme.typography.size.base};
136
+ margin-bottom: 0;
137
+ word-break: break-word;
138
+ `;
139
+ export const FileSize = styled.span `
140
+ color: ${(props) => props.theme.color.text.muted};
141
+ `;
142
+ export const RemoveButton = styled.button `
143
+ background-color: transparent;
144
+ border: none;
145
+ cursor: pointer;
146
+ padding: 0;
147
+ `;
148
+ export const RemoveButtonIcon = styled(FaTrash) `
149
+ color: ${(props) => props.theme.color.intent.default.danger};
150
+ font-size: 1;
151
+ height: auto;
152
+ margin-top: ${(props) => props.theme.spacing.xs};
153
+ transition: 0.3s color ease;
154
+ width: 1rem;
155
+
156
+ &:hover {
157
+ color: ${(props) => props.theme.color.palette.danger[700]};
158
+ }
159
+ `;
160
+ export const ProgressBarContainer = styled.div `
161
+ background-color: ${(props) => props.theme.color.palette.neutral[300]};
162
+ height: ${(props) => props.theme.spacing.s};
163
+ margin-top: ${(props) => props.theme.spacing.xs};
164
+ width: 100%;
165
+ `;
166
+ export const ProgressBar = styled.div `
167
+ background-color: ${(props) => props.theme.color.palette.primary[600]};
168
+ border-radius: ${(props) => props.theme.strokeWidth.thick};
169
+ height: 100%;
170
+ transition: width 0.2s ease;
171
+ width: 0;
172
+ width: ${(props) => props.$progress}%;
173
+ `;
174
+ export const DragOverlay = styled.div `
175
+ align-items: center;
176
+ background-color: ${(props) => props.theme.color.overlay[80]};
177
+ border: 4px dashed ${(props) => props.theme.color.intent.default.none};
178
+ bottom: 0;
179
+ color: ${(props) => props.theme.color.palette.primary[100]};
180
+ display: flex;
181
+ font-family: ${(props) => props.theme.typography.fontFamily.base};
182
+ font-size: ${(props) => props.theme.typography.size.h1};
183
+ font-weight: ${(props) => props.theme.typography.weight.bold};
184
+ justify-content: center;
185
+ left: 0;
186
+ pointer-events: none;
187
+ position: absolute;
188
+ right: 0;
189
+ top: 0;
190
+ z-index: 3;
191
+ `;
@@ -3,6 +3,7 @@ import * as ArrayField from "./ArrayField";
3
3
  import * as BooleanField from "./BooleanField";
4
4
  import * as DateField from "./DateField";
5
5
  import * as FileUploadField from "./FileUploadField";
6
+ import * as FilesUploadField from "./FilesUploadField";
6
7
  import * as MultipleChoiceField from "./MultipleChoiceField";
7
8
  import * as NullField from "./NullField";
8
9
  import * as NumberField from "./NumberField";
@@ -21,6 +22,7 @@ export const fieldComponents = {
21
22
  ...BooleanField.components,
22
23
  //...DateField.components, // DateField uses FieldInput (maybe it should wrap it)
23
24
  ...FileUploadField.components,
25
+ ...FilesUploadField.components,
24
26
  ...MultipleChoiceField.components,
25
27
  //...NullField.components, // NullField doesn't have components
26
28
  //...NumberField.components, // NumberField uses StringField (maybe bit too directly)
@@ -40,6 +42,7 @@ export const fields = {
40
42
  ...BooleanField.fields,
41
43
  ...DateField.fields,
42
44
  ...FileUploadField.fields,
45
+ ...FilesUploadField.fields,
43
46
  ...MultipleChoiceField.fields,
44
47
  ...NullField.fields,
45
48
  ...NumberField.fields,
@@ -17,7 +17,7 @@ export const FieldTitle = styled.label `
17
17
  font-family: ${(props) => props.theme.typography.fontFamily.heading};
18
18
  font-size: ${(props) => props.theme.typography.size.base};
19
19
  font-weight: ${(props) => props.theme.typography.weight.bold};
20
- margin: ${(props) => `${props.theme.spacing.xs} 0`};
20
+ margin: ${(props) => `${props.theme.spacing.xs} 0 ${props.theme.spacing.s} 0`};
21
21
  width: 100%;
22
22
  `;
23
23
  export const FieldDescription = styled.div `
@@ -0,0 +1,3 @@
1
+ export const FilesUploadField = (props) => {
2
+ return "TODO";
3
+ };
@@ -4,6 +4,7 @@ import { ArrayField } from "./ArrayField";
4
4
  import { BooleanField } from "./BooleanField";
5
5
  import { DateField } from "./DateField";
6
6
  import { FileUploadField } from "./FileUploadField";
7
+ import { FilesUploadField } from "./FilesUploadField";
7
8
  import { MultipleChoiceField } from "./MultipleChoiceField";
8
9
  import { NullField } from "./NullField";
9
10
  import { NumberField } from "./NumberField";
@@ -29,6 +30,7 @@ export const fields /*& { EJSField: typeof EJSField }*/ = {
29
30
  BooleanField,
30
31
  DateField,
31
32
  // EJSField,
33
+ FilesUploadField,
32
34
  FileUploadField,
33
35
  NullField,
34
36
  NumberField,
@@ -0,0 +1,11 @@
1
+ import { createContext } from "react";
2
+ export const FilesUploadContext = createContext({
3
+ uploadFiles: () => {
4
+ console.error("Lacking upload from FilesUploadContext");
5
+ return Promise.reject();
6
+ },
7
+ removeFile: () => {
8
+ console.error("Lacking remove from FileUploadContext");
9
+ return Promise.reject();
10
+ },
11
+ });
@@ -175,6 +175,32 @@ export declare const components: {
175
175
  MultipleChoiceFieldLabel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>, "ref"> & {
176
176
  ref?: ((instance: HTMLSpanElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLSpanElement> | null | undefined;
177
177
  }, never>> & string;
178
+ FilesUploadFieldInput: ({ className, deleteFileAriaLabel, fileInfoText, handleFileUpload, handleRemoveFile, hideFileTypeIcon, hideFileSize, hideRemoveButton, hideUploadIcon, infoText, name, orText, removeButton, renderFile, setFieldValue, uploadButtonText, uploadedFiles, uploadProgress, value, }: import("../fields/FilesUploadField").FilesUploadFieldInputProps) => import("react/jsx-runtime").JSX.Element;
179
+ FileUploadFieldContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
180
+ HiddenFileInput: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
181
+ UploadIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react-icons").IconBaseProps, never>> & string & Omit<import("react-icons").IconType, keyof import("react").Component<any, {}, any>>;
182
+ InfoText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
183
+ Divider: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
184
+ DividerText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
185
+ FileInfoText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
186
+ FileInfoTextMinimized: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
187
+ FileUploadButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Readonly<import("@nolwenture/component-library").ButtonProps>, never>> & string & Omit<typeof import("@nolwenture/component-library").Button, keyof import("react").Component<any, {}, any>>;
188
+ FileUploadText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, never>> & string;
189
+ FileItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
190
+ UploadedFileItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
191
+ UploadedFileInfoContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
192
+ UploadedFileWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
193
+ FileTypeIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
194
+ UploadingFileName: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
195
+ UploadedFileName: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
196
+ FileSize: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
197
+ RemoveButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
198
+ RemoveButtonIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react-icons").IconBaseProps, never>> & string & Omit<import("react-icons").IconType, keyof import("react").Component<any, {}, any>>;
199
+ ProgressBarContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
200
+ ProgressBar: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
201
+ $progress: number;
202
+ }>> & string;
203
+ DragOverlay: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
178
204
  FileUploadFieldInput: ({ name, uploadedFile, handleFileUpload, value, setFieldValue, className, uploadProgress, handleRemoveFile, removeButton, uploadButtonText, infoText, hideRemoveButton, }: import("../fields/FileUploadField").FileUploadFieldInputProps) => import("react/jsx-runtime").JSX.Element;
179
205
  FileUploadFieldFileUploadButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
180
206
  FileUploadFieldHiddenFileInput: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
@@ -186,7 +212,6 @@ export declare const components: {
186
212
  FileUploadFieldFileItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
187
213
  FileUploadFieldRemoveButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
188
214
  FileUploadFieldFileInfoText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
189
- FileUploadFieldContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
190
215
  BooleanFieldWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>, "ref"> & {
191
216
  ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
192
217
  }, never>> & string;
@@ -0,0 +1,2 @@
1
+ import type { Field } from "../../../common/types";
2
+ export declare const FilesUploadField: Field;
@@ -0,0 +1,37 @@
1
+ import React from "react";
2
+ import { FormikErrors } from "formik";
3
+ type UploadedFile = {
4
+ name: string;
5
+ id: string;
6
+ mimeType: string;
7
+ size: number;
8
+ };
9
+ export type FilesUploadFieldInputProps = {
10
+ name: string;
11
+ uploadedFiles: Array<UploadedFile>;
12
+ handleFileUpload: (files: FileList, setFieldValue: (field: string, value: any, shouldValidate?: boolean) => Promise<void | FormikErrors<any>>) => Promise<void>;
13
+ handleRemoveFile: (file: UploadedFile, setFieldValue: any) => void;
14
+ value: any;
15
+ setFieldValue: (field: string, value: any, shouldValidate?: boolean) => Promise<void | FormikErrors<any>>;
16
+ uploadProgress: Record<string, number>;
17
+ removeButton?: {
18
+ content: React.ReactNode;
19
+ props: {
20
+ style?: React.CSSProperties;
21
+ [key: string]: any;
22
+ };
23
+ };
24
+ renderFile?: (file: UploadedFile, progress: number, onDelete: () => void) => JSX.Element;
25
+ orText?: string;
26
+ uploadButtonText?: string;
27
+ infoText?: string;
28
+ fileInfoText?: string;
29
+ deleteFileAriaLabel?: string;
30
+ hideRemoveButton: boolean;
31
+ hideUploadIcon: boolean;
32
+ className?: string;
33
+ hideFileTypeIcon: boolean;
34
+ hideFileSize: boolean;
35
+ };
36
+ export declare const FilesUploadFieldInput: ({ className, deleteFileAriaLabel, fileInfoText, handleFileUpload, handleRemoveFile, hideFileTypeIcon, hideFileSize, hideRemoveButton, hideUploadIcon, infoText, name, orText, removeButton, renderFile, setFieldValue, uploadButtonText, uploadedFiles, uploadProgress, value, }: FilesUploadFieldInputProps) => import("react/jsx-runtime").JSX.Element;
37
+ export {};
@@ -0,0 +1,31 @@
1
+ export * as fields from "./FilesUploadField";
2
+ declare const components: {
3
+ FilesUploadFieldInput: ({ className, deleteFileAriaLabel, fileInfoText, handleFileUpload, handleRemoveFile, hideFileTypeIcon, hideFileSize, hideRemoveButton, hideUploadIcon, infoText, name, orText, removeButton, renderFile, setFieldValue, uploadButtonText, uploadedFiles, uploadProgress, value, }: import("./FilesUploadFieldInput").FilesUploadFieldInputProps) => import("react/jsx-runtime").JSX.Element;
4
+ FileUploadFieldContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
5
+ HiddenFileInput: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
6
+ UploadIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react-icons").IconBaseProps, never>> & string & Omit<import("react-icons").IconType, keyof import("react").Component<any, {}, any>>;
7
+ InfoText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
8
+ Divider: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
9
+ DividerText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
10
+ FileInfoText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
11
+ FileInfoTextMinimized: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
12
+ FileUploadButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Readonly<import("@nolwenture/component-library").ButtonProps>, never>> & string & Omit<typeof import("@nolwenture/component-library").Button, keyof import("react").Component<any, {}, any>>;
13
+ FileUploadText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, never>> & string;
14
+ FileItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
15
+ UploadedFileItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
16
+ UploadedFileInfoContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
17
+ UploadedFileWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
18
+ FileTypeIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
19
+ UploadingFileName: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
20
+ UploadedFileName: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
21
+ FileSize: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
22
+ RemoveButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
23
+ RemoveButtonIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react-icons").IconBaseProps, never>> & string & Omit<import("react-icons").IconType, keyof import("react").Component<any, {}, any>>;
24
+ ProgressBarContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
25
+ ProgressBar: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
26
+ $progress: number;
27
+ }>> & string;
28
+ DragOverlay: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
29
+ };
30
+ export { components };
31
+ export type * from "./FilesUploadFieldInput";
@@ -0,0 +1,26 @@
1
+ import { Button } from "@nolwenture/component-library";
2
+ export declare const FileUploadFieldContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
3
+ export declare const HiddenFileInput: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
4
+ export declare const UploadIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react-icons").IconBaseProps, never>> & string & Omit<import("react-icons").IconType, keyof import("react").Component<any, {}, any>>;
5
+ export declare const InfoText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
6
+ export declare const Divider: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
7
+ export declare const DividerText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
8
+ export declare const FileInfoText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
9
+ export declare const FileInfoTextMinimized: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
10
+ export declare const FileUploadButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Readonly<import("@nolwenture/component-library").ButtonProps>, never>> & string & Omit<typeof Button, keyof import("react").Component<any, {}, any>>;
11
+ export declare const FileUploadText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, never>> & string;
12
+ export declare const FileItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
13
+ export declare const UploadedFileItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
14
+ export declare const UploadedFileInfoContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
15
+ export declare const UploadedFileWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
16
+ export declare const FileTypeIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
17
+ export declare const UploadingFileName: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
18
+ export declare const UploadedFileName: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
19
+ export declare const FileSize: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
20
+ export declare const RemoveButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
21
+ export declare const RemoveButtonIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react-icons").IconBaseProps, never>> & string & Omit<import("react-icons").IconType, keyof import("react").Component<any, {}, any>>;
22
+ export declare const ProgressBarContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
23
+ export declare const ProgressBar: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
24
+ $progress: number;
25
+ }>> & string;
26
+ export declare const DragOverlay: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
@@ -1,5 +1,6 @@
1
1
  import { Field } from "../../common/types";
2
2
  import * as FileUploadField from "./FileUploadField";
3
+ import * as FilesUploadField from "./FilesUploadField";
3
4
  import * as MultipleChoiceField from "./MultipleChoiceField";
4
5
  import * as ObjectField from "./ObjectField";
5
6
  import * as RadioField from "./RadioField";
@@ -104,6 +105,32 @@ export declare const fieldComponents: {
104
105
  MultipleChoiceFieldLabel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>, "ref"> & {
105
106
  ref?: ((instance: HTMLSpanElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLSpanElement> | null | undefined;
106
107
  }, never>> & string;
108
+ FilesUploadFieldInput: ({ className, deleteFileAriaLabel, fileInfoText, handleFileUpload, handleRemoveFile, hideFileTypeIcon, hideFileSize, hideRemoveButton, hideUploadIcon, infoText, name, orText, removeButton, renderFile, setFieldValue, uploadButtonText, uploadedFiles, uploadProgress, value, }: FilesUploadField.FilesUploadFieldInputProps) => import("react/jsx-runtime").JSX.Element;
109
+ FileUploadFieldContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
110
+ HiddenFileInput: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
111
+ UploadIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react-icons").IconBaseProps, never>> & string & Omit<import("react-icons").IconType, keyof import("react").Component<any, {}, any>>;
112
+ InfoText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
113
+ Divider: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
114
+ DividerText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
115
+ FileInfoText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
116
+ FileInfoTextMinimized: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
117
+ FileUploadButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Readonly<import("@nolwenture/component-library").ButtonProps>, never>> & string & Omit<typeof import("@nolwenture/component-library").Button, keyof import("react").Component<any, {}, any>>;
118
+ FileUploadText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, never>> & string;
119
+ FileItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
120
+ UploadedFileItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
121
+ UploadedFileInfoContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
122
+ UploadedFileWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
123
+ FileTypeIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
124
+ UploadingFileName: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
125
+ UploadedFileName: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
126
+ FileSize: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
127
+ RemoveButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
128
+ RemoveButtonIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react-icons").IconBaseProps, never>> & string & Omit<import("react-icons").IconType, keyof import("react").Component<any, {}, any>>;
129
+ ProgressBarContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
130
+ ProgressBar: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
131
+ $progress: number;
132
+ }>> & string;
133
+ DragOverlay: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
107
134
  FileUploadFieldInput: ({ name, uploadedFile, handleFileUpload, value, setFieldValue, className, uploadProgress, handleRemoveFile, removeButton, uploadButtonText, infoText, hideRemoveButton, }: FileUploadField.FileUploadFieldInputProps) => import("react/jsx-runtime").JSX.Element;
108
135
  FileUploadFieldFileUploadButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
109
136
  FileUploadFieldHiddenFileInput: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
@@ -115,7 +142,6 @@ export declare const fieldComponents: {
115
142
  FileUploadFieldFileItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
116
143
  FileUploadFieldRemoveButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
117
144
  FileUploadFieldFileInfoText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
118
- FileUploadFieldContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
119
145
  BooleanFieldWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>, "ref"> & {
120
146
  ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
121
147
  }, never>> & string;
@@ -143,6 +169,7 @@ export declare const fields: {
143
169
  NumberField: Field;
144
170
  NullField: Field;
145
171
  MultipleChoiceField: Field;
172
+ FilesUploadField: Field;
146
173
  FileUploadField: Field;
147
174
  DateField: Field;
148
175
  BooleanField: Field;
@@ -0,0 +1,2 @@
1
+ import type { Field } from "../../common/types";
2
+ export declare const FilesUploadField: Field;
@@ -0,0 +1,12 @@
1
+ import { AxiosProgressEvent } from "axios";
2
+ export type FilesUploadContextType<T> = {
3
+ uploadFiles: (x: {
4
+ data: FormData;
5
+ onUploadProgress?: (progressEvent: AxiosProgressEvent, id: string) => void;
6
+ }) => Promise<T[]>;
7
+ removeFile: (file: T) => Promise<{
8
+ success: boolean;
9
+ message?: string;
10
+ }>;
11
+ };
12
+ export declare const FilesUploadContext: import("react").Context<FilesUploadContextType<any>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nolwenture/formik-jsonschema-form",
3
- "version": "1.0.0-beta.50",
3
+ "version": "1.0.0-beta.52",
4
4
  "description": "Formik form generation from json schema",
5
5
  "author": "anttivikman <antti.vikman@nolwenture.com>",
6
6
  "contributors": [