@nolwenture/formik-jsonschema-form 0.21.3 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/FileUploadContext.d.ts +19 -0
- package/dist/FileUploadContext.js +12 -0
- package/dist/Form.stories.d.ts +1 -0
- package/dist/Form.stories.js +21 -5
- package/dist/fields/FileUploadField.d.ts +3 -0
- package/dist/fields/FileUploadField.js +70 -0
- package/dist/fields/index.d.ts +1 -0
- package/dist/fields/index.js +1 -0
- package/dist/fields/stories/FileUploadField.stories.d.ts +15 -0
- package/dist/fields/stories/FileUploadField.stories.js +66 -0
- package/dist/sampleData/fileUpload.d.ts +7 -0
- package/dist/sampleData/fileUpload.js +39 -0
- package/dist/styledComponents.d.ts +28 -1
- package/dist/styledComponents.js +75 -1
- package/dist/types.d.ts +23 -0
- package/package.json +1 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { AxiosProgressEvent } from "axios";
|
|
3
|
+
export type FileUploadContext<T> = {
|
|
4
|
+
uploadFile: (x: {
|
|
5
|
+
data: FormData;
|
|
6
|
+
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
|
|
7
|
+
}) => Promise<T>;
|
|
8
|
+
fetchFile: (value: T) => Promise<{
|
|
9
|
+
name: string;
|
|
10
|
+
}>;
|
|
11
|
+
removeFile: (fileName: string) => Promise<{
|
|
12
|
+
success: boolean;
|
|
13
|
+
message?: undefined;
|
|
14
|
+
} | {
|
|
15
|
+
success: boolean;
|
|
16
|
+
message: string;
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
export declare const FileUploadContext: import("react").Context<FileUploadContext<any>>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
export const FileUploadContext = createContext({
|
|
3
|
+
uploadFile: () => {
|
|
4
|
+
console.error("Lacking upload from FileUploadContext");
|
|
5
|
+
return Promise.reject();
|
|
6
|
+
},
|
|
7
|
+
fetchFile: (value) => Promise.resolve(value),
|
|
8
|
+
removeFile: () => {
|
|
9
|
+
console.error("Lacking remove from FileUploadContext");
|
|
10
|
+
return Promise.reject();
|
|
11
|
+
},
|
|
12
|
+
});
|
package/dist/Form.stories.d.ts
CHANGED
package/dist/Form.stories.js
CHANGED
|
@@ -25,6 +25,16 @@ import { Formik, useFormikContext } from "formik";
|
|
|
25
25
|
import { InfoFieldButton, SearchableMultiTagSelectField, } from "./styledComponents";
|
|
26
26
|
import { completeSchema, completeUiSchema, simpleSchema, simpleUiSchema, generatedSchema, requiredInputSchema, requiredInputUiSchema, conditionsSchema, conditionsUiSchema, refDefSchema, refDefUiSchema, multipleChoiceSchema, multipleChoiceUiSchema, collapsibleSchema, collapsibleUiSchema, } from "./sampleData";
|
|
27
27
|
import { Form, styledComponents } from "./";
|
|
28
|
+
import { fileUploadSchema, fileUploadUiSchema } from "./sampleData/fileUpload";
|
|
29
|
+
import { FileUploadContext } from "./FileUploadContext";
|
|
30
|
+
import { mockFetchFile, mockRemoveFile, mockUploadFile, } from "./fields/stories/FileUploadField.stories";
|
|
31
|
+
const MockFileUploadProvider = ({ children, }) => {
|
|
32
|
+
return (_jsx(FileUploadContext.Provider, { value: {
|
|
33
|
+
uploadFile: mockUploadFile,
|
|
34
|
+
fetchFile: mockFetchFile,
|
|
35
|
+
removeFile: mockRemoveFile,
|
|
36
|
+
}, children: children }));
|
|
37
|
+
};
|
|
28
38
|
const meta = {
|
|
29
39
|
title: "Form",
|
|
30
40
|
component: Form,
|
|
@@ -35,11 +45,11 @@ const meta = {
|
|
|
35
45
|
},
|
|
36
46
|
render: (_a) => {
|
|
37
47
|
var args = __rest(_a, []);
|
|
38
|
-
return (_jsx(Formik, { initialValues: {}, onSubmit: (values, formikHelpers) => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
48
|
+
return (_jsx(MockFileUploadProvider, { children: _jsx(Formik, { initialValues: {}, onSubmit: (values, formikHelpers) => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
+
action("onSubmit(_, formHelper)")(formikHelpers);
|
|
50
|
+
action("onSubmit(values)")(values);
|
|
51
|
+
formikHelpers.setSubmitting(false);
|
|
52
|
+
}), children: _jsx(Form, Object.assign({}, args)) }) }));
|
|
43
53
|
},
|
|
44
54
|
};
|
|
45
55
|
export default meta;
|
|
@@ -202,3 +212,9 @@ export const Collapsible = {
|
|
|
202
212
|
uiSchema: collapsibleUiSchema,
|
|
203
213
|
},
|
|
204
214
|
};
|
|
215
|
+
export const FileUploadForm = {
|
|
216
|
+
args: {
|
|
217
|
+
schema: fileUploadSchema,
|
|
218
|
+
uiSchema: fileUploadUiSchema,
|
|
219
|
+
},
|
|
220
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
import { useContext, useEffect, useState } from "react";
|
|
12
|
+
import { FormRegistry } from "../Form";
|
|
13
|
+
import { useExtractUiSchema, useSetDefault } from "../hooks";
|
|
14
|
+
import { getIn, useFormikContext } from "formik";
|
|
15
|
+
import { FileUploadContext } from "../FileUploadContext";
|
|
16
|
+
export const FileUploadField = (props) => {
|
|
17
|
+
const { templates: { FieldTemplate }, components: { FileUploadField }, } = useContext(FormRegistry);
|
|
18
|
+
useSetDefault(props);
|
|
19
|
+
const { name, uiSchema } = props;
|
|
20
|
+
const { props: inputProps } = useExtractUiSchema(uiSchema);
|
|
21
|
+
const { setFieldValue, values } = useFormikContext();
|
|
22
|
+
const value = getIn(values, name);
|
|
23
|
+
const { uploadFile, fetchFile, removeFile } = useContext(FileUploadContext);
|
|
24
|
+
const [uploadedFile, setUploadedFile] = useState(null);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
(() => __awaiter(void 0, void 0, void 0, function* () { return setUploadedFile(yield fetchFile(value)); }))();
|
|
27
|
+
}, [value]);
|
|
28
|
+
const [uploadProgress, setUploadProgress] = useState(0);
|
|
29
|
+
const handleFileUpload = (file, setFieldValue) => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
|
+
const formData = new FormData();
|
|
31
|
+
formData.append("file", file);
|
|
32
|
+
try {
|
|
33
|
+
// Simulate slower upload progress with manual updates in order to show bar at all for fast uploads
|
|
34
|
+
let fakeProgress = 0;
|
|
35
|
+
const interval = setInterval(() => {
|
|
36
|
+
fakeProgress += 10;
|
|
37
|
+
if (fakeProgress <= 100) {
|
|
38
|
+
setUploadProgress(fakeProgress);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
clearInterval(interval);
|
|
42
|
+
}
|
|
43
|
+
}, 100);
|
|
44
|
+
const result = yield uploadFile({
|
|
45
|
+
data: formData,
|
|
46
|
+
onUploadProgress: (progressEvent) => {
|
|
47
|
+
const totalLength = progressEvent.total;
|
|
48
|
+
if (totalLength !== null && totalLength !== undefined) {
|
|
49
|
+
const progress = Math.round((progressEvent.loaded * 100) / totalLength);
|
|
50
|
+
if (progress === 100) {
|
|
51
|
+
setUploadProgress(progress);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
setFieldValue(name, result);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error("File upload failed", error);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
const handleRemoveFile = (setFieldValue) => __awaiter(void 0, void 0, void 0, function* () {
|
|
63
|
+
if (uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.name) {
|
|
64
|
+
yield removeFile(uploadedFile.name);
|
|
65
|
+
setUploadProgress(0);
|
|
66
|
+
setFieldValue(name, null);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
return (_jsx(FieldTemplate, Object.assign({}, props, { children: _jsx(FileUploadField, Object.assign({}, inputProps, { name: name, value: value, handleRemoveFile: handleRemoveFile, uploadedFile: uploadedFile, setFieldValue: setFieldValue, handleFileUpload: handleFileUpload, uploadProgress: uploadProgress, removeButton: uiSchema["ui:removeButton"], uploadButtonText: uiSchema["ui:uploadButtonText"], infoText: uiSchema["ui:infoText"] })) })));
|
|
70
|
+
};
|
package/dist/fields/index.d.ts
CHANGED
package/dist/fields/index.js
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { StoryObj } from "@storybook/react";
|
|
2
|
+
import { FileUploadField } from "../FileUploadField";
|
|
3
|
+
export declare const mockUploadFile: ({ data, onUploadProgress, }: {
|
|
4
|
+
data: FormData;
|
|
5
|
+
onUploadProgress?: ((progressEvent: any) => void) | undefined;
|
|
6
|
+
}) => Promise<string>;
|
|
7
|
+
export declare const mockFetchFile: (fileId: string) => Promise<{
|
|
8
|
+
name: string;
|
|
9
|
+
}>;
|
|
10
|
+
export declare const mockRemoveFile: (fileName: string) => Promise<{
|
|
11
|
+
success: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
declare const _default: import("@storybook/types").ComponentAnnotations<import("@storybook/react").ReactRenderer, import("../../types").FieldProps>;
|
|
14
|
+
export default _default;
|
|
15
|
+
export declare const Default: StoryObj<typeof FileUploadField>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
import { Formik, Form } from "formik";
|
|
12
|
+
import { FileUploadField } from "../FileUploadField";
|
|
13
|
+
import { FileUploadContext } from "../../FileUploadContext";
|
|
14
|
+
let isFileUploaded = false;
|
|
15
|
+
let mockFileName = "";
|
|
16
|
+
export const mockUploadFile = (_a) => __awaiter(void 0, [_a], void 0, function* ({ data, onUploadProgress, }) {
|
|
17
|
+
const file = data.get("file");
|
|
18
|
+
mockFileName = (file === null || file === void 0 ? void 0 : file.name) || "unknown";
|
|
19
|
+
console.log("Mock uploadFile called with FormData:", data);
|
|
20
|
+
const mockFileId = (file === null || file === void 0 ? void 0 : file.name) || "mockFileId";
|
|
21
|
+
setTimeout(() => {
|
|
22
|
+
isFileUploaded = true;
|
|
23
|
+
}, 1000);
|
|
24
|
+
let progress = 0;
|
|
25
|
+
const interval = setInterval(() => {
|
|
26
|
+
progress += 10;
|
|
27
|
+
if (onUploadProgress) {
|
|
28
|
+
onUploadProgress({ loaded: progress, total: 100 });
|
|
29
|
+
}
|
|
30
|
+
if (progress >= 100)
|
|
31
|
+
clearInterval(interval);
|
|
32
|
+
}, 100);
|
|
33
|
+
return mockFileId;
|
|
34
|
+
});
|
|
35
|
+
export const mockFetchFile = (fileId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
+
console.log("Mock fetchFile called with fileId:", fileId);
|
|
37
|
+
if (!isFileUploaded) {
|
|
38
|
+
return new Promise((resolve) => setTimeout(() => resolve({ name: mockFileName }), 0));
|
|
39
|
+
}
|
|
40
|
+
return new Promise((resolve) => setTimeout(() => resolve({ name: mockFileName }), 500));
|
|
41
|
+
});
|
|
42
|
+
export const mockRemoveFile = (fileName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
console.log("Mock removeFile called with fileName:", fileName);
|
|
44
|
+
isFileUploaded = false;
|
|
45
|
+
mockFileName = "";
|
|
46
|
+
return { success: true };
|
|
47
|
+
});
|
|
48
|
+
export default {
|
|
49
|
+
title: "Fields/FileUploadField",
|
|
50
|
+
component: FileUploadField,
|
|
51
|
+
decorators: [
|
|
52
|
+
(Story) => (_jsx(FileUploadContext.Provider, { value: {
|
|
53
|
+
uploadFile: mockUploadFile,
|
|
54
|
+
fetchFile: mockFetchFile,
|
|
55
|
+
removeFile: mockRemoveFile,
|
|
56
|
+
}, children: _jsx(Formik, { initialValues: {}, onSubmit: () => { }, children: _jsx(Form, { children: Story() }) }) })),
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
export const Default = {
|
|
60
|
+
args: {
|
|
61
|
+
name: "file",
|
|
62
|
+
schema: { type: "object" },
|
|
63
|
+
uiSchema: {},
|
|
64
|
+
},
|
|
65
|
+
play: (_b) => __awaiter(void 0, [_b], void 0, function* ({ canvasElement }) { }),
|
|
66
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export const fileUploadSchema = {
|
|
3
|
+
title: "File Upload Form",
|
|
4
|
+
properties: {
|
|
5
|
+
file: { type: "object", title: "Single upload field" },
|
|
6
|
+
fileArray: { type: "array", additionalItems: { type: "object" } },
|
|
7
|
+
},
|
|
8
|
+
};
|
|
9
|
+
export const fileUploadUiSchema = {
|
|
10
|
+
"ui:description": "File upload form with on single field and one array field for uploads",
|
|
11
|
+
file: {
|
|
12
|
+
"ui:field": "FileUploadField",
|
|
13
|
+
"ui:removeButton": {
|
|
14
|
+
content: _jsx("span", { children: "-" }),
|
|
15
|
+
props: {
|
|
16
|
+
style: {
|
|
17
|
+
height: "25px",
|
|
18
|
+
width: "25px",
|
|
19
|
+
background: "red",
|
|
20
|
+
borderRadius: "50%",
|
|
21
|
+
display: "inline-block",
|
|
22
|
+
border: "unset",
|
|
23
|
+
padding: "unset",
|
|
24
|
+
color: "white",
|
|
25
|
+
fontWeight: "bolder",
|
|
26
|
+
textAlign: "center",
|
|
27
|
+
lineHeight: "1.4em",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
fileArray: {
|
|
33
|
+
items: {
|
|
34
|
+
"ui:field": "FileUploadField",
|
|
35
|
+
"ui:uploadButtonText": "Add?",
|
|
36
|
+
"ui:infoText": "There's nothing here",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="hoist-non-react-statics" />
|
|
2
|
-
import type { ClickableProps, InfoFieldButtonProps, MultipleChoiceFieldProps, ObjectFieldButtonProps, RadioButtonFieldProps, SelectFieldProps, TextAreaInputFieldProps, ToggleSwitchFieldProps } from "./types";
|
|
2
|
+
import type { ClickableProps, InfoFieldButtonProps, MultipleChoiceFieldProps, ObjectFieldButtonProps, RadioButtonFieldProps, SelectFieldProps, TextAreaInputFieldProps, ToggleSwitchFieldProps, FileUploadFieldProps } from "./types";
|
|
3
3
|
import * as formik from "formik";
|
|
4
4
|
import React from "react";
|
|
5
5
|
export declare const Form: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<Omit<Omit<React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, "ref"> & React.RefAttributes<HTMLFormElement>, "ref"> & {
|
|
@@ -240,4 +240,31 @@ export declare const SearchInput: import("styled-components").IStyledComponent<"
|
|
|
240
240
|
}, never>> & Omit<({ formikAs, ...props }: Omit<formik.FieldAttributes<any>, "as">) => import("react/jsx-runtime").JSX.Element, keyof React.Component<any, {}, any>>, keyof React.Component<any, {}, any>>;
|
|
241
241
|
export declare const SearchClearButton: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>>;
|
|
242
242
|
export declare const SearchInputContainer: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
|
|
243
|
+
export declare const FileUploadButton: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>>;
|
|
244
|
+
export declare const HiddenFileInput: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>>;
|
|
245
|
+
export declare const ProgressBarContainer: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
|
|
246
|
+
export declare const ProgressBar: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
247
|
+
$progress: number;
|
|
248
|
+
}>>;
|
|
249
|
+
export declare const ProgressText: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>>;
|
|
250
|
+
export declare const FileItemContainer: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
|
|
251
|
+
export declare const RemoveButton: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>>;
|
|
252
|
+
export declare const FileInfoText: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>>;
|
|
253
|
+
export declare const FileUploadFieldContainer: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
|
|
254
|
+
export declare const FileUploadField: {
|
|
255
|
+
({ name, uploadedFile, handleFileUpload, value, setFieldValue, className, uploadProgress, handleRemoveFile, removeButton, uploadButtonText, infoText, }: FileUploadFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
256
|
+
styles: {
|
|
257
|
+
FileUploadFieldFileUploadFieldContainerStyle: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
|
|
258
|
+
FileUploadFieldFileUploadButtonStyle: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>>;
|
|
259
|
+
FileUploadFieldHiddenFileInputStyle: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>>;
|
|
260
|
+
FileUploadFieldFileInfoTextStyle: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>>;
|
|
261
|
+
FileUploadFieldFileItemContainerStyle: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
|
|
262
|
+
FileUploadFieldRemoveButtonStyle: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>>;
|
|
263
|
+
FileUploadFieldProgressBarContainerStyle: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
|
|
264
|
+
FileUploadFieldProgressBarStyle: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
265
|
+
$progress: number;
|
|
266
|
+
}>>;
|
|
267
|
+
FileUploadFieldProgressTextStyle: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>>;
|
|
268
|
+
};
|
|
269
|
+
};
|
|
243
270
|
export {};
|
package/dist/styledComponents.js
CHANGED
|
@@ -9,7 +9,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
13
13
|
import * as formik from "formik";
|
|
14
14
|
import { useState } from "react";
|
|
15
15
|
import styled from "styled-components";
|
|
@@ -456,3 +456,77 @@ export const SearchClearButton = styled.span `
|
|
|
456
456
|
export const SearchInputContainer = styled.div `
|
|
457
457
|
display: flex;
|
|
458
458
|
`;
|
|
459
|
+
// --> FileUploadField
|
|
460
|
+
export const FileUploadButton = styled.button `
|
|
461
|
+
background-color: #ccc;
|
|
462
|
+
color: black;
|
|
463
|
+
padding: 10px 20px;
|
|
464
|
+
border: none;
|
|
465
|
+
border-radius: 5px;
|
|
466
|
+
cursor: pointer;
|
|
467
|
+
font-size: 14px;
|
|
468
|
+
`;
|
|
469
|
+
export const HiddenFileInput = styled.input `
|
|
470
|
+
display: none;
|
|
471
|
+
`;
|
|
472
|
+
export const ProgressBarContainer = styled.div `
|
|
473
|
+
width: 120px;
|
|
474
|
+
height: 20px;
|
|
475
|
+
border-radius: 2px;
|
|
476
|
+
background-color: #b1b2b5;
|
|
477
|
+
position: relative;
|
|
478
|
+
margin-left: 10px;
|
|
479
|
+
`;
|
|
480
|
+
export const ProgressBar = styled.div `
|
|
481
|
+
width: ${(props) => props.$progress}%;
|
|
482
|
+
height: 100%;
|
|
483
|
+
background-color: #548088;
|
|
484
|
+
border-radius: 2px;
|
|
485
|
+
transition: width 0.2s ease;
|
|
486
|
+
`;
|
|
487
|
+
export const ProgressText = styled.span `
|
|
488
|
+
position: absolute;
|
|
489
|
+
top: 50%;
|
|
490
|
+
left: 50%;
|
|
491
|
+
transform: translate(-50%, -50%);
|
|
492
|
+
color: white;
|
|
493
|
+
font-weight: bold;
|
|
494
|
+
`;
|
|
495
|
+
export const FileItemContainer = styled.div `
|
|
496
|
+
margin-bottom: 10px;
|
|
497
|
+
display: flex;
|
|
498
|
+
align-items: center;
|
|
499
|
+
`;
|
|
500
|
+
export const RemoveButton = styled.button `
|
|
501
|
+
margin-left: 10px;
|
|
502
|
+
background-color: transparent;
|
|
503
|
+
border: none;
|
|
504
|
+
cursor: pointer;
|
|
505
|
+
`;
|
|
506
|
+
export const FileInfoText = styled.span `
|
|
507
|
+
margin-left: 10px;
|
|
508
|
+
font-size: 14px;
|
|
509
|
+
color: #555;
|
|
510
|
+
`;
|
|
511
|
+
export const FileUploadFieldContainer = styled.div ``;
|
|
512
|
+
export const FileUploadField = ({ name, uploadedFile, handleFileUpload, value, setFieldValue, className, uploadProgress, handleRemoveFile, removeButton, uploadButtonText, infoText, }) => {
|
|
513
|
+
var _a, _b;
|
|
514
|
+
const uiSchema = {};
|
|
515
|
+
return (_jsxs(FileUploadFieldContainer, { className: className, children: [_jsxs("div", { children: [_jsx(FileUploadButton, { type: "button", onClick: () => { var _a; return (_a = document.getElementById(name)) === null || _a === void 0 ? void 0 : _a.click(); }, children: uploadButtonText !== null && uploadButtonText !== void 0 ? uploadButtonText : "Choose File" }), _jsx(HiddenFileInput, { id: name, name: name, type: "file", onChange: (event) => {
|
|
516
|
+
const file = event.currentTarget.files[0];
|
|
517
|
+
if (file) {
|
|
518
|
+
handleFileUpload(file, setFieldValue);
|
|
519
|
+
}
|
|
520
|
+
} }), !value ? (_jsx(FileInfoText, { children: infoText !== null && infoText !== void 0 ? infoText : "No file chosen" })) : null] }), uploadedFile && value && (_jsx(FileItemContainer, { children: uploadProgress === 100 ? (_jsxs(_Fragment, { children: [_jsx("span", { children: uploadedFile.name }), _jsx(RemoveButton, Object.assign({ type: "button", onClick: () => handleRemoveFile(setFieldValue) }, ((_a = removeButton === null || removeButton === void 0 ? void 0 : removeButton.props) !== null && _a !== void 0 ? _a : {}), { children: (_b = removeButton === null || removeButton === void 0 ? void 0 : removeButton.content) !== null && _b !== void 0 ? _b : "X" }))] })) : (_jsxs(_Fragment, { children: [_jsx("span", { children: uploadedFile.name }), _jsxs(ProgressBarContainer, { children: [_jsx(ProgressBar, { "$progress": uploadProgress }), _jsxs(ProgressText, { children: [uploadProgress, "%"] })] })] })) }))] }));
|
|
521
|
+
};
|
|
522
|
+
FileUploadField.styles = {
|
|
523
|
+
FileUploadFieldFileUploadFieldContainerStyle: FileUploadFieldContainer,
|
|
524
|
+
FileUploadFieldFileUploadButtonStyle: FileUploadButton,
|
|
525
|
+
FileUploadFieldHiddenFileInputStyle: HiddenFileInput,
|
|
526
|
+
FileUploadFieldFileInfoTextStyle: FileInfoText,
|
|
527
|
+
FileUploadFieldFileItemContainerStyle: FileItemContainer,
|
|
528
|
+
FileUploadFieldRemoveButtonStyle: RemoveButton,
|
|
529
|
+
FileUploadFieldProgressBarContainerStyle: ProgressBarContainer,
|
|
530
|
+
FileUploadFieldProgressBarStyle: ProgressBar,
|
|
531
|
+
FileUploadFieldProgressTextStyle: ProgressText,
|
|
532
|
+
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FormikErrors } from "formik";
|
|
1
2
|
import type { JSONSchema7, JSONSchema7Definition } from "json-schema";
|
|
2
3
|
import React, { MouseEventHandler } from "react";
|
|
3
4
|
export type FormProps<T> = React.PropsWithChildren<{
|
|
@@ -155,6 +156,7 @@ export type ComponentsType = {
|
|
|
155
156
|
SearchInput: React.FunctionComponent<any>;
|
|
156
157
|
SearchClearButton: React.FunctionComponent<any>;
|
|
157
158
|
SearchInputContainer: React.FunctionComponent<any>;
|
|
159
|
+
FileUploadField: React.FunctionComponent<any>;
|
|
158
160
|
};
|
|
159
161
|
export declare enum ObjectFieldButtonPurpose {
|
|
160
162
|
ADD = 0,
|
|
@@ -265,4 +267,25 @@ export type AddButtonProps = {
|
|
|
265
267
|
onClick: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
|
266
268
|
disabled: boolean;
|
|
267
269
|
};
|
|
270
|
+
export type FileUploadFieldProps = {
|
|
271
|
+
className: string;
|
|
272
|
+
name: string;
|
|
273
|
+
uploadedFile: {
|
|
274
|
+
name: string;
|
|
275
|
+
} | null;
|
|
276
|
+
handleFileUpload: (file: File, setFieldValue: (field: string, value: any, shouldValidate?: boolean) => Promise<void | FormikErrors<any>>) => Promise<void>;
|
|
277
|
+
value: any;
|
|
278
|
+
setFieldValue: (field: string, value: any, shouldValidate?: boolean) => Promise<void | FormikErrors<any>>;
|
|
279
|
+
uploadProgress: number;
|
|
280
|
+
handleRemoveFile: (setFieldValue: any) => void;
|
|
281
|
+
removeButton?: {
|
|
282
|
+
content: React.ReactNode;
|
|
283
|
+
props: {
|
|
284
|
+
style?: React.CSSProperties;
|
|
285
|
+
[key: string]: any;
|
|
286
|
+
};
|
|
287
|
+
};
|
|
288
|
+
uploadButtonText?: string;
|
|
289
|
+
infoText?: string;
|
|
290
|
+
};
|
|
268
291
|
export {};
|