@nolwenture/formik-jsonschema-form 1.0.0-beta.54 → 1.0.0-beta.56

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.
@@ -17,27 +17,45 @@ const FilesUploadField = (props) => {
17
17
  const value = (0, formik_1.getIn)(values, name);
18
18
  const { uploadFiles, removeFile } = (0, react_1.useContext)(FilesUploadContext_1.FilesUploadContext);
19
19
  const [uploadedFiles, setUploadedFiles] = (0, react_1.useState)([]);
20
- (0, react_1.useEffect)(() => {
21
- (async () => setUploadedFiles(value))();
22
- }, [value]);
23
20
  const [uploadProgress, setUploadProgress] = (0, react_1.useState)({});
21
+ (0, react_1.useEffect)(() => {
22
+ setUploadedFiles(value.map(f => ({
23
+ name: f.name,
24
+ id: f.id,
25
+ progressId: f.id,
26
+ mimeType: f.mimeType,
27
+ size: f.size
28
+ })));
29
+ value.forEach(f => setUploadProgress((prev) => ({ ...prev, [f.id]: 100 })));
30
+ }, []);
24
31
  const handleFileUpload = async (files, setFieldValue) => {
25
- const formData = new FormData();
32
+ const filesWithIds = [];
33
+ const newFiles = [];
26
34
  for (const file of files) {
27
- formData.append("files", file);
35
+ const progressId = file.name + file.size + file.lastModified + Math.random();
36
+ filesWithIds.push({ data: file, progressId });
37
+ newFiles.push({ name: file.name, size: file.size, progressId, mimeType: file.type, id: null });
28
38
  }
39
+ setUploadedFiles((f) => f.concat(newFiles));
29
40
  try {
30
41
  const result = await uploadFiles({
31
- data: formData,
32
- onUploadProgress: (progressEvent, id) => {
42
+ files: filesWithIds,
43
+ onUploadProgress: (progressEvent, progressId) => {
33
44
  const totalLength = progressEvent.total;
34
45
  if (totalLength !== null && totalLength !== undefined) {
35
46
  const progress = Math.round((progressEvent.loaded * 100) / totalLength);
36
- setUploadProgress((prev) => ({ ...prev, [id]: progress }));
47
+ setUploadProgress((prev) => ({ ...prev, [progressId]: progress }));
37
48
  }
38
49
  },
39
50
  });
40
- const newValue = (Array.isArray(value) ? value : []).concat(result);
51
+ // remove progressId values for adding to form data
52
+ const newFormValues = result.map(({ progressId, ...rest }) => rest);
53
+ // update ids for uploaded files
54
+ setUploadedFiles(prev => prev.map(item => {
55
+ const match = result.find(f => f.progressId === item.progressId);
56
+ return match ? { ...item, id: match.id } : item;
57
+ }));
58
+ const newValue = (Array.isArray(value) ? value : []).concat(newFormValues);
41
59
  setFieldValue(name, newValue);
42
60
  }
43
61
  catch (error) {
@@ -48,15 +66,16 @@ const FilesUploadField = (props) => {
48
66
  if (file.id) {
49
67
  await removeFile(file);
50
68
  setUploadProgress((prev) => {
51
- const { [file.id]: _, ...rest } = prev;
69
+ const { [file.progressId]: _, ...rest } = prev;
52
70
  return rest;
53
71
  });
54
- setFieldValue(name, (currentValue) => (currentValue || []).filter((f) => f.id !== file.id));
72
+ setUploadedFiles((prev) => prev.filter(f => f.id !== file.id));
73
+ setFieldValue(name, (prev) => (prev || []).filter((f) => f.id !== file.id));
55
74
  }
56
75
  };
57
76
  const SelectedFieldTemplate = (props.uiSchema?.["ui:template"] &&
58
77
  templates[props.uiSchema?.["ui:template"]]) ??
59
78
  templates.FieldTemplate;
60
- 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 }) }));
79
+ return ((0, jsx_runtime_1.jsx)(SelectedFieldTemplate, { ...props, "data-fjsf-object": name, children: (0, jsx_runtime_1.jsx)(FilesUploadFieldInput, { ...inputProps, acceptedFiletypes: uiSchema["ui:acceptedFiletypes"], 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 }) }));
61
80
  };
62
81
  exports.FilesUploadField = FilesUploadField;
@@ -29,7 +29,7 @@ const getFileIcon = (mimeType) => {
29
29
  }
30
30
  return (0, jsx_runtime_1.jsx)(fa_1.FaFile, {});
31
31
  };
32
- const FilesUploadFieldInput = ({ className, deleteFileAriaLabel, fileInfoText, handleFileUpload, handleRemoveFile, hideFileTypeIcon, hideFileSize, hideRemoveButton, hideUploadIcon, infoText, name, orText, removeButton, renderFile, setFieldValue, uploadButtonText, uploadedFiles, uploadProgress, value, }) => {
32
+ const FilesUploadFieldInput = ({ acceptedFiletypes, className, deleteFileAriaLabel, fileInfoText, handleFileUpload, handleRemoveFile, hideFileTypeIcon, hideFileSize, hideRemoveButton, hideUploadIcon, infoText, name, orText, removeButton, renderFile, setFieldValue, uploadButtonText, uploadedFiles, uploadProgress, value, }) => {
33
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
34
  const [isDragging, setIsDragging] = (0, react_1.useState)(false);
35
35
  const dragCounter = (0, react_1.useRef)(0);
@@ -63,9 +63,10 @@ const FilesUploadFieldInput = ({ className, deleteFileAriaLabel, fileInfoText, h
63
63
  e.dataTransfer.clearData();
64
64
  }
65
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 }) })] })) }));
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 ? (file.size / (1024 * 1024)).toFixed(3) : "?"} MB` }))] })] }), !hideRemoveButton && file.id && ((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
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) => {
68
+ const fileTypes = acceptedFiletypes ? { accept: acceptedFiletypes } : {};
69
+ 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.progressId], () => handleRemoveFile(file, setFieldValue)) }, file.progressId))), !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, ...fileTypes, id: name, name: name, type: "file", onChange: (event) => {
69
70
  const files = event.target.files;
70
71
  if (files) {
71
72
  handleFileUpload(files, setFieldValue);
@@ -14,27 +14,45 @@ export const FilesUploadField = (props) => {
14
14
  const value = getIn(values, name);
15
15
  const { uploadFiles, removeFile } = useContext(FilesUploadContext);
16
16
  const [uploadedFiles, setUploadedFiles] = useState([]);
17
- useEffect(() => {
18
- (async () => setUploadedFiles(value))();
19
- }, [value]);
20
17
  const [uploadProgress, setUploadProgress] = useState({});
18
+ useEffect(() => {
19
+ setUploadedFiles(value.map(f => ({
20
+ name: f.name,
21
+ id: f.id,
22
+ progressId: f.id,
23
+ mimeType: f.mimeType,
24
+ size: f.size
25
+ })));
26
+ value.forEach(f => setUploadProgress((prev) => ({ ...prev, [f.id]: 100 })));
27
+ }, []);
21
28
  const handleFileUpload = async (files, setFieldValue) => {
22
- const formData = new FormData();
29
+ const filesWithIds = [];
30
+ const newFiles = [];
23
31
  for (const file of files) {
24
- formData.append("files", file);
32
+ const progressId = file.name + file.size + file.lastModified + Math.random();
33
+ filesWithIds.push({ data: file, progressId });
34
+ newFiles.push({ name: file.name, size: file.size, progressId, mimeType: file.type, id: null });
25
35
  }
36
+ setUploadedFiles((f) => f.concat(newFiles));
26
37
  try {
27
38
  const result = await uploadFiles({
28
- data: formData,
29
- onUploadProgress: (progressEvent, id) => {
39
+ files: filesWithIds,
40
+ onUploadProgress: (progressEvent, progressId) => {
30
41
  const totalLength = progressEvent.total;
31
42
  if (totalLength !== null && totalLength !== undefined) {
32
43
  const progress = Math.round((progressEvent.loaded * 100) / totalLength);
33
- setUploadProgress((prev) => ({ ...prev, [id]: progress }));
44
+ setUploadProgress((prev) => ({ ...prev, [progressId]: progress }));
34
45
  }
35
46
  },
36
47
  });
37
- const newValue = (Array.isArray(value) ? value : []).concat(result);
48
+ // remove progressId values for adding to form data
49
+ const newFormValues = result.map(({ progressId, ...rest }) => rest);
50
+ // update ids for uploaded files
51
+ setUploadedFiles(prev => prev.map(item => {
52
+ const match = result.find(f => f.progressId === item.progressId);
53
+ return match ? { ...item, id: match.id } : item;
54
+ }));
55
+ const newValue = (Array.isArray(value) ? value : []).concat(newFormValues);
38
56
  setFieldValue(name, newValue);
39
57
  }
40
58
  catch (error) {
@@ -45,14 +63,15 @@ export const FilesUploadField = (props) => {
45
63
  if (file.id) {
46
64
  await removeFile(file);
47
65
  setUploadProgress((prev) => {
48
- const { [file.id]: _, ...rest } = prev;
66
+ const { [file.progressId]: _, ...rest } = prev;
49
67
  return rest;
50
68
  });
51
- setFieldValue(name, (currentValue) => (currentValue || []).filter((f) => f.id !== file.id));
69
+ setUploadedFiles((prev) => prev.filter(f => f.id !== file.id));
70
+ setFieldValue(name, (prev) => (prev || []).filter((f) => f.id !== file.id));
52
71
  }
53
72
  };
54
73
  const SelectedFieldTemplate = (props.uiSchema?.["ui:template"] &&
55
74
  templates[props.uiSchema?.["ui:template"]]) ??
56
75
  templates.FieldTemplate;
57
- 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 }) }));
76
+ return (_jsx(SelectedFieldTemplate, { ...props, "data-fjsf-object": name, children: _jsx(FilesUploadFieldInput, { ...inputProps, acceptedFiletypes: uiSchema["ui:acceptedFiletypes"], 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 }) }));
58
77
  };
@@ -26,7 +26,7 @@ const getFileIcon = (mimeType) => {
26
26
  }
27
27
  return _jsx(FaFile, {});
28
28
  };
29
- export const FilesUploadFieldInput = ({ className, deleteFileAriaLabel, fileInfoText, handleFileUpload, handleRemoveFile, hideFileTypeIcon, hideFileSize, hideRemoveButton, hideUploadIcon, infoText, name, orText, removeButton, renderFile, setFieldValue, uploadButtonText, uploadedFiles, uploadProgress, value, }) => {
29
+ export const FilesUploadFieldInput = ({ acceptedFiletypes, className, deleteFileAriaLabel, fileInfoText, handleFileUpload, handleRemoveFile, hideFileTypeIcon, hideFileSize, hideRemoveButton, hideUploadIcon, infoText, name, orText, removeButton, renderFile, setFieldValue, uploadButtonText, uploadedFiles, uploadProgress, value, }) => {
30
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
31
  const [isDragging, setIsDragging] = useState(false);
32
32
  const dragCounter = useRef(0);
@@ -60,9 +60,10 @@ export const FilesUploadFieldInput = ({ className, deleteFileAriaLabel, fileInfo
60
60
  e.dataTransfer.clearData();
61
61
  }
62
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 }) })] })) }));
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 ? (file.size / (1024 * 1024)).toFixed(3) : "?"} MB` }))] })] }), !hideRemoveButton && file.id && (_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
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) => {
65
+ const fileTypes = acceptedFiletypes ? { accept: acceptedFiletypes } : {};
66
+ 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.progressId], () => handleRemoveFile(file, setFieldValue)) }, file.progressId))), !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, ...fileTypes, id: name, name: name, type: "file", onChange: (event) => {
66
67
  const files = event.target.files;
67
68
  if (files) {
68
69
  handleFileUpload(files, setFieldValue);
@@ -175,7 +175,7 @@ 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;
178
+ FilesUploadFieldInput: ({ acceptedFiletypes, 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
179
  FileUploadFieldContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
180
180
  HiddenFileInput: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
181
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>>;
@@ -2,13 +2,14 @@ import React from "react";
2
2
  import { FormikErrors } from "formik";
3
3
  type UploadedFile = {
4
4
  name: string;
5
- id: string;
6
- mimeType: string;
7
- size: number;
5
+ id: null | string;
6
+ progressId: string;
7
+ mimeType?: string;
8
+ size?: number;
8
9
  };
9
10
  export type FilesUploadFieldInputProps = {
10
11
  name: string;
11
- uploadedFiles: Array<UploadedFile>;
12
+ uploadedFiles: UploadedFile[];
12
13
  handleFileUpload: (files: FileList, setFieldValue: (field: string, value: any, shouldValidate?: boolean) => Promise<void | FormikErrors<any>>) => Promise<void>;
13
14
  handleRemoveFile: (file: UploadedFile, setFieldValue: any) => void;
14
15
  value: any;
@@ -32,6 +33,7 @@ export type FilesUploadFieldInputProps = {
32
33
  className?: string;
33
34
  hideFileTypeIcon: boolean;
34
35
  hideFileSize: boolean;
36
+ acceptedFiletypes?: string;
35
37
  };
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;
38
+ export declare const FilesUploadFieldInput: ({ acceptedFiletypes, 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
39
  export {};
@@ -1,6 +1,6 @@
1
1
  export * as fields from "./FilesUploadField";
2
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;
3
+ FilesUploadFieldInput: ({ acceptedFiletypes, 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
4
  FileUploadFieldContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
5
5
  HiddenFileInput: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
6
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>>;
@@ -105,7 +105,7 @@ export declare const fieldComponents: {
105
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"> & {
106
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;
107
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;
108
+ FilesUploadFieldInput: ({ acceptedFiletypes, 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
109
  FileUploadFieldContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
110
110
  HiddenFileInput: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
111
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>>;
@@ -1,9 +1,14 @@
1
1
  import { AxiosProgressEvent } from "axios";
2
2
  export type FilesUploadContextType<T> = {
3
3
  uploadFiles: (x: {
4
- data: FormData;
5
- onUploadProgress?: (progressEvent: AxiosProgressEvent, id: string) => void;
6
- }) => Promise<T[]>;
4
+ files: {
5
+ data: File;
6
+ progressId: string;
7
+ }[];
8
+ onUploadProgress?: (progressEvent: AxiosProgressEvent, progressId: string) => void;
9
+ }) => Promise<T & {
10
+ progressId: string;
11
+ }[]>;
7
12
  removeFile: (file: T) => Promise<{
8
13
  success: boolean;
9
14
  message?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nolwenture/formik-jsonschema-form",
3
- "version": "1.0.0-beta.54",
3
+ "version": "1.0.0-beta.56",
4
4
  "description": "Formik form generation from json schema",
5
5
  "author": "anttivikman <antti.vikman@nolwenture.com>",
6
6
  "contributors": [