@bosonprotocol/react-kit 0.33.0-alpha.8 → 0.33.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/cjs/components/buttons/BaseButton.d.ts +1 -0
- package/dist/cjs/components/buttons/BaseButton.d.ts.map +1 -1
- package/dist/cjs/components/buttons/BaseButton.js +1 -0
- package/dist/cjs/components/buttons/BaseButton.js.map +1 -1
- package/dist/cjs/components/buttons/CommitButtonView.d.ts.map +1 -1
- package/dist/cjs/components/buttons/CommitButtonView.js +4 -0
- package/dist/cjs/components/buttons/CommitButtonView.js.map +1 -1
- package/dist/cjs/components/error/SimpleError.d.ts +2 -2
- package/dist/cjs/components/error/SimpleError.d.ts.map +1 -1
- package/dist/cjs/components/error/SimpleError.js.map +1 -1
- package/dist/cjs/components/form/BaseCheckbox.d.ts +5 -0
- package/dist/cjs/components/form/BaseCheckbox.d.ts.map +1 -0
- package/dist/cjs/components/form/BaseCheckbox.js +69 -0
- package/dist/cjs/components/form/BaseCheckbox.js.map +1 -0
- package/dist/cjs/components/form/Checkbox.d.ts +13 -2
- package/dist/cjs/components/form/Checkbox.d.ts.map +1 -1
- package/dist/cjs/components/form/Checkbox.js +18 -61
- package/dist/cjs/components/form/Checkbox.js.map +1 -1
- package/dist/cjs/components/form/CountrySelect.d.ts +26 -11
- package/dist/cjs/components/form/CountrySelect.d.ts.map +1 -1
- package/dist/cjs/components/form/CountrySelect.js +64 -31
- package/dist/cjs/components/form/CountrySelect.js.map +1 -1
- package/dist/cjs/components/form/Field.styles.d.ts +36 -2
- package/dist/cjs/components/form/Field.styles.d.ts.map +1 -1
- package/dist/cjs/components/form/Field.styles.js +83 -24
- package/dist/cjs/components/form/Field.styles.js.map +1 -1
- package/dist/cjs/components/form/FormField.d.ts +2 -1
- package/dist/cjs/components/form/FormField.d.ts.map +1 -1
- package/dist/cjs/components/form/FormField.js +14 -2
- package/dist/cjs/components/form/FormField.js.map +1 -1
- package/dist/cjs/components/form/Select.d.ts +2 -1
- package/dist/cjs/components/form/Select.d.ts.map +1 -1
- package/dist/cjs/components/form/Select.js +32 -20
- package/dist/cjs/components/form/Select.js.map +1 -1
- package/dist/cjs/components/form/Upload/BaseUpload.d.ts +71 -0
- package/dist/cjs/components/form/Upload/BaseUpload.d.ts.map +1 -0
- package/dist/cjs/components/form/Upload/BaseUpload.js +264 -0
- package/dist/cjs/components/form/Upload/BaseUpload.js.map +1 -0
- package/dist/cjs/components/form/Upload/Upload.d.ts +3 -41
- package/dist/cjs/components/form/Upload/Upload.d.ts.map +1 -1
- package/dist/cjs/components/form/Upload/Upload.js +7 -258
- package/dist/cjs/components/form/Upload/Upload.js.map +1 -1
- package/dist/cjs/components/form/Upload/UploadedFile.js +2 -2
- package/dist/cjs/components/form/Upload/UploadedFile.js.map +1 -1
- package/dist/cjs/components/form/Upload/WithUploadToIpfs.d.ts.map +1 -1
- package/dist/cjs/components/form/Upload/WithUploadToIpfs.js +9 -12
- package/dist/cjs/components/form/Upload/WithUploadToIpfs.js.map +1 -1
- package/dist/cjs/components/form/index.d.ts +6 -4
- package/dist/cjs/components/form/index.d.ts.map +1 -1
- package/dist/cjs/components/form/index.js +7 -3
- package/dist/cjs/components/form/index.js.map +1 -1
- package/dist/cjs/components/form/types.d.ts +31 -3
- package/dist/cjs/components/form/types.d.ts.map +1 -1
- package/dist/cjs/components/ui/IpfsImage.d.ts +4 -3
- package/dist/cjs/components/ui/IpfsImage.d.ts.map +1 -1
- package/dist/cjs/components/ui/IpfsImage.js +2 -2
- package/dist/cjs/components/ui/IpfsImage.js.map +1 -1
- package/dist/cjs/components/ui/Video.d.ts +3 -3
- package/dist/cjs/components/ui/Video.d.ts.map +1 -1
- package/dist/cjs/components/ui/Video.js +8 -9
- package/dist/cjs/components/ui/Video.js.map +1 -1
- package/dist/cjs/hooks/ipfs/useIpfsStorage.d.ts.map +1 -1
- package/dist/cjs/hooks/ipfs/useIpfsStorage.js +2 -1
- package/dist/cjs/hooks/ipfs/useIpfsStorage.js.map +1 -1
- package/dist/cjs/hooks/useIpfsMetadataStorage.d.ts +2 -2
- package/dist/cjs/hooks/useIpfsMetadataStorage.d.ts.map +1 -1
- package/dist/cjs/hooks/useIpfsMetadataStorage.js +6 -6
- package/dist/cjs/hooks/useIpfsMetadataStorage.js.map +1 -1
- package/dist/cjs/hooks/useIpfsStorage.d.ts.map +1 -1
- package/dist/cjs/hooks/useIpfsStorage.js +2 -1
- package/dist/cjs/hooks/useIpfsStorage.js.map +1 -1
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/bytes/bytesToSize.d.ts +1 -1
- package/dist/cjs/lib/bytes/bytesToSize.d.ts.map +1 -1
- package/dist/cjs/lib/bytes/bytesToSize.js +2 -1
- package/dist/cjs/lib/bytes/bytesToSize.js.map +1 -1
- package/dist/cjs/lib/const/chainInfo.d.ts.map +1 -1
- package/dist/cjs/lib/const/chainInfo.js +10 -0
- package/dist/cjs/lib/const/chainInfo.js.map +1 -1
- package/dist/esm/components/buttons/BaseButton.d.ts +1 -0
- package/dist/esm/components/buttons/BaseButton.d.ts.map +1 -1
- package/dist/esm/components/buttons/BaseButton.js +1 -0
- package/dist/esm/components/buttons/BaseButton.js.map +1 -1
- package/dist/esm/components/buttons/CommitButtonView.d.ts.map +1 -1
- package/dist/esm/components/buttons/CommitButtonView.js +4 -0
- package/dist/esm/components/buttons/CommitButtonView.js.map +1 -1
- package/dist/esm/components/error/SimpleError.d.ts +2 -2
- package/dist/esm/components/error/SimpleError.d.ts.map +1 -1
- package/dist/esm/components/error/SimpleError.js.map +1 -1
- package/dist/esm/components/form/BaseCheckbox.d.ts +5 -0
- package/dist/esm/components/form/BaseCheckbox.d.ts.map +1 -0
- package/dist/esm/components/form/BaseCheckbox.js +27 -0
- package/dist/esm/components/form/BaseCheckbox.js.map +1 -0
- package/dist/esm/components/form/Checkbox.d.ts +13 -2
- package/dist/esm/components/form/Checkbox.d.ts.map +1 -1
- package/dist/esm/components/form/Checkbox.js +16 -25
- package/dist/esm/components/form/Checkbox.js.map +1 -1
- package/dist/esm/components/form/CountrySelect.d.ts +26 -11
- package/dist/esm/components/form/CountrySelect.d.ts.map +1 -1
- package/dist/esm/components/form/CountrySelect.js +97 -67
- package/dist/esm/components/form/CountrySelect.js.map +1 -1
- package/dist/esm/components/form/Field.styles.d.ts +36 -2
- package/dist/esm/components/form/Field.styles.d.ts.map +1 -1
- package/dist/esm/components/form/Field.styles.js +58 -20
- package/dist/esm/components/form/Field.styles.js.map +1 -1
- package/dist/esm/components/form/FormField.d.ts +2 -1
- package/dist/esm/components/form/FormField.d.ts.map +1 -1
- package/dist/esm/components/form/FormField.js +2 -2
- package/dist/esm/components/form/FormField.js.map +1 -1
- package/dist/esm/components/form/Select.d.ts +2 -1
- package/dist/esm/components/form/Select.d.ts.map +1 -1
- package/dist/esm/components/form/Select.js +52 -30
- package/dist/esm/components/form/Select.js.map +1 -1
- package/dist/esm/components/form/Upload/BaseUpload.d.ts +71 -0
- package/dist/esm/components/form/Upload/BaseUpload.d.ts.map +1 -0
- package/dist/esm/components/form/Upload/BaseUpload.js +226 -0
- package/dist/esm/components/form/Upload/BaseUpload.js.map +1 -0
- package/dist/esm/components/form/Upload/Upload.d.ts +3 -41
- package/dist/esm/components/form/Upload/Upload.d.ts.map +1 -1
- package/dist/esm/components/form/Upload/Upload.js +5 -225
- package/dist/esm/components/form/Upload/Upload.js.map +1 -1
- package/dist/esm/components/form/Upload/UploadedFile.js +1 -1
- package/dist/esm/components/form/Upload/UploadedFile.js.map +1 -1
- package/dist/esm/components/form/Upload/WithUploadToIpfs.d.ts.map +1 -1
- package/dist/esm/components/form/Upload/WithUploadToIpfs.js +8 -11
- package/dist/esm/components/form/Upload/WithUploadToIpfs.js.map +1 -1
- package/dist/esm/components/form/index.d.ts +6 -4
- package/dist/esm/components/form/index.d.ts.map +1 -1
- package/dist/esm/components/form/index.js +4 -2
- package/dist/esm/components/form/index.js.map +1 -1
- package/dist/esm/components/form/types.d.ts +31 -3
- package/dist/esm/components/form/types.d.ts.map +1 -1
- package/dist/esm/components/ui/IpfsImage.d.ts +4 -3
- package/dist/esm/components/ui/IpfsImage.d.ts.map +1 -1
- package/dist/esm/components/ui/IpfsImage.js +2 -2
- package/dist/esm/components/ui/IpfsImage.js.map +1 -1
- package/dist/esm/components/ui/Video.d.ts +3 -3
- package/dist/esm/components/ui/Video.d.ts.map +1 -1
- package/dist/esm/components/ui/Video.js +6 -9
- package/dist/esm/components/ui/Video.js.map +1 -1
- package/dist/esm/hooks/ipfs/useIpfsStorage.d.ts.map +1 -1
- package/dist/esm/hooks/ipfs/useIpfsStorage.js +2 -1
- package/dist/esm/hooks/ipfs/useIpfsStorage.js.map +1 -1
- package/dist/esm/hooks/useIpfsMetadataStorage.d.ts +2 -2
- package/dist/esm/hooks/useIpfsMetadataStorage.d.ts.map +1 -1
- package/dist/esm/hooks/useIpfsMetadataStorage.js +6 -6
- package/dist/esm/hooks/useIpfsMetadataStorage.js.map +1 -1
- package/dist/esm/hooks/useIpfsStorage.d.ts.map +1 -1
- package/dist/esm/hooks/useIpfsStorage.js +2 -1
- package/dist/esm/hooks/useIpfsStorage.js.map +1 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/bytes/bytesToSize.d.ts +1 -1
- package/dist/esm/lib/bytes/bytesToSize.d.ts.map +1 -1
- package/dist/esm/lib/bytes/bytesToSize.js +1 -1
- package/dist/esm/lib/bytes/bytesToSize.js.map +1 -1
- package/dist/esm/lib/const/chainInfo.d.ts.map +1 -1
- package/dist/esm/lib/const/chainInfo.js +10 -0
- package/dist/esm/lib/const/chainInfo.js.map +1 -1
- package/package.json +5 -5
- package/src/components/buttons/BaseButton.tsx +4 -0
- package/src/components/buttons/CommitButtonView.tsx +4 -0
- package/src/components/error/SimpleError.tsx +2 -2
- package/src/components/form/BaseCheckbox.tsx +50 -0
- package/src/components/form/Checkbox.tsx +17 -40
- package/src/components/form/CountrySelect.tsx +178 -130
- package/src/components/form/Field.styles.ts +113 -24
- package/src/components/form/FormField.tsx +4 -1
- package/src/components/form/Select.tsx +65 -34
- package/src/components/form/Upload/BaseUpload.tsx +367 -0
- package/src/components/form/Upload/Upload.tsx +8 -360
- package/src/components/form/Upload/UploadedFile.tsx +1 -1
- package/src/components/form/Upload/WithUploadToIpfs.tsx +8 -11
- package/src/components/form/index.ts +6 -4
- package/src/components/form/types.ts +31 -3
- package/src/components/ui/IpfsImage.tsx +14 -7
- package/src/components/ui/Video.tsx +8 -12
- package/src/hooks/ipfs/useIpfsStorage.ts +2 -0
- package/src/hooks/useIpfsMetadataStorage.tsx +6 -4
- package/src/hooks/useIpfsStorage.ts +2 -0
- package/src/index.tsx +2 -0
- package/src/lib/bytes/bytesToSize.ts +1 -1
- package/src/lib/const/chainInfo.ts +10 -1
- package/src/stories/buttons/Upload.stories.tsx +8 -0
- package/src/stories/form/BaseCheckbox.stories.tsx +113 -0
- package/src/stories/selects/CountrySelect.stories.tsx +49 -11
- package/src/stories/selects/Select.stories.tsx +117 -0
|
@@ -1,360 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import Loading from "../../ui/loading/LoadingWrapper";
|
|
10
|
-
import ThemedButton from "../../ui/ThemedButton";
|
|
11
|
-
import { Typography } from "../../ui/Typography";
|
|
12
|
-
import Error from "../Error";
|
|
13
|
-
import {
|
|
14
|
-
FieldFileUploadWrapper,
|
|
15
|
-
FieldInput,
|
|
16
|
-
FileUploadWrapper,
|
|
17
|
-
ImagePreview,
|
|
18
|
-
VideoPreview
|
|
19
|
-
} from "../Field.styles";
|
|
20
|
-
import type { UploadFileType, UploadProps, FileProps } from "../types";
|
|
21
|
-
import UploadedFiles from "./UploadedFiles";
|
|
22
|
-
import { WithUploadToIpfs, WithUploadToIpfsProps } from "./WithUploadToIpfs";
|
|
23
|
-
import { useModal } from "../../modal/useModal";
|
|
24
|
-
import { ImageEditorModal } from "./ImageEditorModal/ImageEditorModal";
|
|
25
|
-
const colors = theme.colors.light;
|
|
26
|
-
|
|
27
|
-
function Upload({
|
|
28
|
-
name,
|
|
29
|
-
accept = "image/*",
|
|
30
|
-
disabled,
|
|
31
|
-
maxSize,
|
|
32
|
-
multiple = false,
|
|
33
|
-
trigger,
|
|
34
|
-
onFilesSelect,
|
|
35
|
-
placeholder,
|
|
36
|
-
wrapperProps,
|
|
37
|
-
onLoadSinglePreviewImage,
|
|
38
|
-
withUpload,
|
|
39
|
-
withEditor,
|
|
40
|
-
saveToIpfs,
|
|
41
|
-
loadMedia,
|
|
42
|
-
onLoading,
|
|
43
|
-
width,
|
|
44
|
-
height,
|
|
45
|
-
borderRadius,
|
|
46
|
-
imgPreviewStyle,
|
|
47
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
48
|
-
removeFile,
|
|
49
|
-
saveButtonTheme,
|
|
50
|
-
...props
|
|
51
|
-
}: UploadProps & WithUploadToIpfsProps) {
|
|
52
|
-
const { updateProps, store } = useModal();
|
|
53
|
-
const [showEditor, setShowEditor] = useState<boolean>(false);
|
|
54
|
-
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
55
|
-
const [preview, setPreview] = useState<string | null>();
|
|
56
|
-
const [field, meta, helpers] = useField(name);
|
|
57
|
-
|
|
58
|
-
const handleLoading = useCallback(
|
|
59
|
-
(loadingValue: boolean) => {
|
|
60
|
-
onLoading?.(loadingValue);
|
|
61
|
-
setIsLoading(loadingValue);
|
|
62
|
-
},
|
|
63
|
-
[onLoading]
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
const errorMessage = meta.error && meta.touched ? meta.error : "";
|
|
67
|
-
const displayError = typeof errorMessage === "string" && errorMessage !== "";
|
|
68
|
-
|
|
69
|
-
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
70
|
-
const [nativeFiles, setNativeFiles] = useState<File[] | null>(null);
|
|
71
|
-
const setFiles = useCallback(
|
|
72
|
-
(value: unknown) => {
|
|
73
|
-
helpers.setValue(value);
|
|
74
|
-
},
|
|
75
|
-
[helpers]
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
const files = field.value as UploadFileType[];
|
|
79
|
-
const mimetypes = accept.split(",").map((acc) => acc.trim());
|
|
80
|
-
const isImageOnly = mimetypes.every((mimetype) =>
|
|
81
|
-
mimetype.startsWith("image/")
|
|
82
|
-
);
|
|
83
|
-
const isVideoOnly = mimetypes.every((mimetype) =>
|
|
84
|
-
mimetype.startsWith("video/")
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
useEffect(() => {
|
|
88
|
-
onFilesSelect?.(files);
|
|
89
|
-
helpers.setValue(files);
|
|
90
|
-
|
|
91
|
-
if (!multiple && files && files?.length !== 0) {
|
|
92
|
-
if (isImageOnly) {
|
|
93
|
-
if (withUpload) {
|
|
94
|
-
loadIpfsImagePreview(files[0] as FileProps);
|
|
95
|
-
} else {
|
|
96
|
-
loadAndSetMedia(files[0] as File, (base64Uri) => {
|
|
97
|
-
setPreview(base64Uri);
|
|
98
|
-
onLoadSinglePreviewImage?.(base64Uri);
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
} else if (isVideoOnly) {
|
|
102
|
-
if (withUpload) {
|
|
103
|
-
loadIpfsVideo(files[0] as FileProps);
|
|
104
|
-
} else {
|
|
105
|
-
loadAndSetMedia(files[0] as File, (base64Uri) => {
|
|
106
|
-
setPreview(base64Uri);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}, [files]); // eslint-disable-line
|
|
112
|
-
|
|
113
|
-
const loadIpfsVideo = async (file: FileProps) => {
|
|
114
|
-
const fileSrc = file && file?.src ? file?.src : false;
|
|
115
|
-
if (!fileSrc) {
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
handleLoading(true);
|
|
119
|
-
try {
|
|
120
|
-
const imagePreview = await loadMedia(fileSrc || "");
|
|
121
|
-
if (imagePreview) {
|
|
122
|
-
setPreview(imagePreview);
|
|
123
|
-
} else {
|
|
124
|
-
console.warn(
|
|
125
|
-
`imagePreview ${imagePreview} is falsy in loadIpfsImagePreview`
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
} catch (error) {
|
|
129
|
-
console.error(error);
|
|
130
|
-
Sentry.captureException(error);
|
|
131
|
-
} finally {
|
|
132
|
-
handleLoading(false);
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const loadIpfsImagePreview = async (file: FileProps) => {
|
|
137
|
-
const fileSrc = file && file?.src ? file?.src : false;
|
|
138
|
-
if (!fileSrc) {
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
141
|
-
try {
|
|
142
|
-
handleLoading(true);
|
|
143
|
-
const imagePreview = await loadMedia(fileSrc || "");
|
|
144
|
-
if (imagePreview) {
|
|
145
|
-
setPreview(imagePreview);
|
|
146
|
-
onLoadSinglePreviewImage?.(imagePreview);
|
|
147
|
-
} else {
|
|
148
|
-
console.warn(
|
|
149
|
-
`imagePreview ${imagePreview} is falsy in loadIpfsImagePreview`
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
} catch (error) {
|
|
153
|
-
console.error(error);
|
|
154
|
-
Sentry.captureException(error);
|
|
155
|
-
} finally {
|
|
156
|
-
handleLoading(false);
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const handleChooseFile = () => {
|
|
161
|
-
const input = inputRef.current;
|
|
162
|
-
if (input) {
|
|
163
|
-
input.click();
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
const handleRemoveAllFiles = () => {
|
|
168
|
-
if (disabled) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
setFiles([]);
|
|
172
|
-
setPreview(null);
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
const handleRemoveFile = (index: number) => {
|
|
176
|
-
const newArray = files.filter(
|
|
177
|
-
(i: File | FileProps, k: number) => k !== index
|
|
178
|
-
);
|
|
179
|
-
setFiles(newArray);
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
const handleChange = useCallback(
|
|
183
|
-
async (filesArray: File[] | null) => {
|
|
184
|
-
if (!meta.touched) {
|
|
185
|
-
helpers.setTouched(true);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (!filesArray) {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
for (const file of filesArray) {
|
|
192
|
-
if (maxSize) {
|
|
193
|
-
if (file.size > maxSize) {
|
|
194
|
-
const error = `File size cannot exceed more than ${bytesToSize(
|
|
195
|
-
maxSize
|
|
196
|
-
)}`;
|
|
197
|
-
// TODO: change to notification
|
|
198
|
-
console.error(error);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
setFiles(filesArray);
|
|
203
|
-
},
|
|
204
|
-
[helpers, maxSize, meta.touched, setFiles]
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
const handleSave = useCallback(
|
|
208
|
-
async (efiles: File[] | null) => {
|
|
209
|
-
if (!meta.touched) {
|
|
210
|
-
helpers.setTouched(true);
|
|
211
|
-
}
|
|
212
|
-
handleLoading(true);
|
|
213
|
-
const files = await saveToIpfs(efiles);
|
|
214
|
-
if (files) {
|
|
215
|
-
setFiles(files);
|
|
216
|
-
} else {
|
|
217
|
-
setFiles([]);
|
|
218
|
-
console.warn(
|
|
219
|
-
`There has been an error because 'files' ${files} is falsy in handleSave`
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
handleLoading(false);
|
|
223
|
-
},
|
|
224
|
-
[meta.touched, handleLoading, saveToIpfs, helpers, setFiles]
|
|
225
|
-
);
|
|
226
|
-
const saveFn = withUpload ? handleSave : handleChange;
|
|
227
|
-
const style = {
|
|
228
|
-
borderRadius: borderRadius ? `${borderRadius}%` : "",
|
|
229
|
-
width: width ? `100%` : ""
|
|
230
|
-
};
|
|
231
|
-
return (
|
|
232
|
-
<>
|
|
233
|
-
{withEditor && showEditor && (
|
|
234
|
-
<ImageEditorModal
|
|
235
|
-
saveButtonTheme={saveButtonTheme}
|
|
236
|
-
files={nativeFiles}
|
|
237
|
-
borderRadius={borderRadius}
|
|
238
|
-
width={width}
|
|
239
|
-
height={height}
|
|
240
|
-
hideModal={async (fileList) => {
|
|
241
|
-
if (fileList) {
|
|
242
|
-
await saveFn(fileList);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
setShowEditor(false);
|
|
246
|
-
updateProps({
|
|
247
|
-
...store,
|
|
248
|
-
modalType: store.modalType,
|
|
249
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
250
|
-
// @ts-ignore
|
|
251
|
-
modalProps: {
|
|
252
|
-
...store.modalProps,
|
|
253
|
-
hidden: false
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
}}
|
|
257
|
-
/>
|
|
258
|
-
)}
|
|
259
|
-
<FieldFileUploadWrapper {...wrapperProps} $disabled={!!disabled}>
|
|
260
|
-
<FieldInput
|
|
261
|
-
{...props}
|
|
262
|
-
hidden
|
|
263
|
-
type="file"
|
|
264
|
-
accept={accept}
|
|
265
|
-
multiple={multiple}
|
|
266
|
-
onChange={async (e) => {
|
|
267
|
-
const files = e.target.files
|
|
268
|
-
? Object.values(e.target.files)
|
|
269
|
-
: e.target.files;
|
|
270
|
-
|
|
271
|
-
if (files && withEditor) {
|
|
272
|
-
setNativeFiles(files);
|
|
273
|
-
setShowEditor(true);
|
|
274
|
-
updateProps({
|
|
275
|
-
...store,
|
|
276
|
-
modalType: store.modalType,
|
|
277
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
278
|
-
// @ts-ignore
|
|
279
|
-
modalProps: {
|
|
280
|
-
...store.modalProps,
|
|
281
|
-
hidden: true
|
|
282
|
-
}
|
|
283
|
-
});
|
|
284
|
-
} else {
|
|
285
|
-
await saveFn(files);
|
|
286
|
-
}
|
|
287
|
-
e.target.value = ""; // allow user to select the same file again
|
|
288
|
-
}}
|
|
289
|
-
ref={(ref) => {
|
|
290
|
-
inputRef.current = ref;
|
|
291
|
-
}}
|
|
292
|
-
disabled={disabled}
|
|
293
|
-
/>
|
|
294
|
-
{trigger ? (
|
|
295
|
-
<ThemedButton onClick={handleChooseFile} type="button">
|
|
296
|
-
<>{trigger}</>
|
|
297
|
-
</ThemedButton>
|
|
298
|
-
) : (
|
|
299
|
-
<FileUploadWrapper
|
|
300
|
-
data-disabled={disabled}
|
|
301
|
-
onClick={handleChooseFile}
|
|
302
|
-
error={errorMessage}
|
|
303
|
-
style={style}
|
|
304
|
-
>
|
|
305
|
-
{isLoading ? (
|
|
306
|
-
<Loading size={2} />
|
|
307
|
-
) : (
|
|
308
|
-
<>
|
|
309
|
-
{field.value && field.value?.length !== 0 && preview ? (
|
|
310
|
-
<>
|
|
311
|
-
{isVideoOnly ? (
|
|
312
|
-
<VideoPreview
|
|
313
|
-
src={
|
|
314
|
-
preview?.startsWith("http")
|
|
315
|
-
? preview
|
|
316
|
-
: "data:video/mp4;base64," +
|
|
317
|
-
preview?.substring(
|
|
318
|
-
"data:application/octet-stream;base64,".length
|
|
319
|
-
)
|
|
320
|
-
}
|
|
321
|
-
autoPlay
|
|
322
|
-
muted
|
|
323
|
-
loop
|
|
324
|
-
/>
|
|
325
|
-
) : (
|
|
326
|
-
<ImagePreview
|
|
327
|
-
style={{ ...imgPreviewStyle }}
|
|
328
|
-
src={preview}
|
|
329
|
-
/>
|
|
330
|
-
)}
|
|
331
|
-
</>
|
|
332
|
-
) : isVideoOnly ? (
|
|
333
|
-
<VideoCamera size={24} />
|
|
334
|
-
) : (
|
|
335
|
-
<Image size={24} />
|
|
336
|
-
)}
|
|
337
|
-
{placeholder && (
|
|
338
|
-
<Typography tag="p" style={{ marginBottom: "0" }}>
|
|
339
|
-
{placeholder}
|
|
340
|
-
</Typography>
|
|
341
|
-
)}
|
|
342
|
-
</>
|
|
343
|
-
)}
|
|
344
|
-
</FileUploadWrapper>
|
|
345
|
-
)}
|
|
346
|
-
{!disabled && field.value && field.value?.length !== 0 && preview && (
|
|
347
|
-
<div onClick={handleRemoveAllFiles} data-remove style={style}>
|
|
348
|
-
<Trash size={24} color={colors.white} />
|
|
349
|
-
</div>
|
|
350
|
-
)}
|
|
351
|
-
{multiple && (
|
|
352
|
-
<UploadedFiles files={files} handleRemoveFile={handleRemoveFile} />
|
|
353
|
-
)}
|
|
354
|
-
</FieldFileUploadWrapper>
|
|
355
|
-
<Error display={displayError} message={errorMessage} />
|
|
356
|
-
</>
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
export default WithUploadToIpfs(Upload);
|
|
1
|
+
import { UploadProps } from "../types";
|
|
2
|
+
import BaseUpload from "./BaseUpload";
|
|
3
|
+
import React from "react";
|
|
4
|
+
export type { UploadProps } from "../types";
|
|
5
|
+
|
|
6
|
+
export const Upload = (props: UploadProps) => {
|
|
7
|
+
return <BaseUpload {...props} />;
|
|
8
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ImageSquare, X } from "phosphor-react";
|
|
2
2
|
import React, { useCallback } from "react";
|
|
3
3
|
import styled from "styled-components";
|
|
4
|
-
import bytesToSize from "../../../lib/bytes/bytesToSize";
|
|
4
|
+
import { bytesToSize } from "../../../lib/bytes/bytesToSize";
|
|
5
5
|
import { theme } from "../../../theme";
|
|
6
6
|
|
|
7
7
|
import { Grid } from "../../ui/Grid";
|
|
@@ -8,7 +8,7 @@ import ErrorToast from "../../toasts/common/ErrorToast";
|
|
|
8
8
|
import { Typography } from "../../ui/Typography";
|
|
9
9
|
import { FileProps, UploadProps } from "../types";
|
|
10
10
|
import { useSaveImageToIpfs } from "../../../hooks/ipfs/useSaveImageToIpfs";
|
|
11
|
-
import bytesToSize from "../../../lib/bytes/bytesToSize";
|
|
11
|
+
import { bytesToSize } from "../../../lib/bytes/bytesToSize";
|
|
12
12
|
|
|
13
13
|
const colors = theme.colors.light;
|
|
14
14
|
|
|
@@ -34,9 +34,8 @@ export function WithUploadToIpfs<P extends WithUploadToIpfsProps>(
|
|
|
34
34
|
props: Omit<P & UploadProps, keyof WithUploadToIpfsProps>
|
|
35
35
|
) => {
|
|
36
36
|
const withUpload = props?.withUpload || false;
|
|
37
|
-
const accept: string = props.accept
|
|
38
|
-
|
|
39
|
-
: SUPPORTED_FORMATS.join(",");
|
|
37
|
+
const accept: string = props.accept || SUPPORTED_FORMATS.join(",");
|
|
38
|
+
const maxSize = Number(props.maxSize) || MAX_FILE_SIZE;
|
|
40
39
|
const { saveFile, loadMedia, removeFile } = useSaveImageToIpfs();
|
|
41
40
|
|
|
42
41
|
const saveToIpfs: WithUploadToIpfsProps["saveToIpfs"] = useCallback(
|
|
@@ -47,10 +46,8 @@ export function WithUploadToIpfs<P extends WithUploadToIpfsProps>(
|
|
|
47
46
|
const filesErrors: string[] = [];
|
|
48
47
|
|
|
49
48
|
for (const file of filesArray) {
|
|
50
|
-
const sizeValidation =
|
|
51
|
-
const formatValidation =
|
|
52
|
-
? props.accept.split(",").map((acc) => acc.trim())
|
|
53
|
-
: SUPPORTED_FORMATS;
|
|
49
|
+
const sizeValidation = maxSize;
|
|
50
|
+
const formatValidation = accept.split(",").map((acc) => acc.trim());
|
|
54
51
|
|
|
55
52
|
if (file?.size > sizeValidation) {
|
|
56
53
|
const err = `File ${
|
|
@@ -101,18 +98,18 @@ export function WithUploadToIpfs<P extends WithUploadToIpfsProps>(
|
|
|
101
98
|
|
|
102
99
|
return ipfsArray as FileProps[];
|
|
103
100
|
},
|
|
104
|
-
[
|
|
101
|
+
[accept, maxSize, saveFile]
|
|
105
102
|
);
|
|
106
103
|
|
|
107
104
|
const newProps = useMemo(
|
|
108
105
|
() => ({
|
|
109
|
-
maxSize
|
|
106
|
+
maxSize,
|
|
110
107
|
accept,
|
|
111
108
|
saveToIpfs,
|
|
112
109
|
loadMedia,
|
|
113
110
|
removeFile
|
|
114
111
|
}),
|
|
115
|
-
[saveToIpfs, loadMedia, removeFile, accept]
|
|
112
|
+
[saveToIpfs, loadMedia, removeFile, accept, maxSize]
|
|
116
113
|
);
|
|
117
114
|
|
|
118
115
|
if (withUpload) {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { Checkbox, CheckboxProps } from "./Checkbox";
|
|
2
|
+
export { BaseCheckbox, BaseCheckboxProps } from "./BaseCheckbox";
|
|
2
3
|
export { default as Datepicker } from "./Datepicker";
|
|
3
4
|
export { default as Error } from "./Error";
|
|
4
|
-
export { FormField } from "./FormField";
|
|
5
|
+
export { FormField, FormFieldProps } from "./FormField";
|
|
5
6
|
export * from "./BaseInput";
|
|
6
7
|
export { default as Input, InputProps } from "./Input";
|
|
7
8
|
export { default as Phone } from "./Phone";
|
|
8
|
-
export { default as Select } from "./Select";
|
|
9
|
+
export { default as Select, SelectProps } from "./Select";
|
|
9
10
|
export * from "./CountrySelect";
|
|
10
11
|
export * from "./BaseTagsInput";
|
|
11
12
|
export * from "./BaseTextArea";
|
|
12
|
-
export { default as
|
|
13
|
+
export { default as BaseUpload, BaseUploadProps } from "./Upload/BaseUpload";
|
|
14
|
+
export { Upload, UploadProps } from "./Upload/Upload";
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
-
import { SingleValue } from "react-select";
|
|
2
|
+
import { CSSObjectWithLabel, SingleValue } from "react-select";
|
|
3
3
|
import { CSSProperties } from "styled-components";
|
|
4
4
|
import { ImageEditorModalProps } from "./Upload/ImageEditorModal/ImageEditorModal";
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
CheckboxTheme,
|
|
7
|
+
FileUploadWrapperTheme,
|
|
8
|
+
TextAreaTheme
|
|
9
|
+
} from "./Field.styles";
|
|
10
|
+
import type { GridProps } from "../ui/Grid";
|
|
6
11
|
|
|
7
12
|
export interface BaseProps {
|
|
8
13
|
name: string;
|
|
@@ -20,6 +25,7 @@ export interface DatepickerProps extends BaseProps {
|
|
|
20
25
|
|
|
21
26
|
export interface CheckboxProps extends BaseProps {
|
|
22
27
|
text?: string;
|
|
28
|
+
theme?: CheckboxTheme;
|
|
23
29
|
}
|
|
24
30
|
|
|
25
31
|
export type TextareaProps = BaseProps &
|
|
@@ -30,7 +36,7 @@ export interface ErrorProps {
|
|
|
30
36
|
message?: string;
|
|
31
37
|
}
|
|
32
38
|
|
|
33
|
-
export interface FormFieldProps {
|
|
39
|
+
export interface FormFieldProps extends GridProps {
|
|
34
40
|
title: string;
|
|
35
41
|
titleIcon?: ReactNode;
|
|
36
42
|
subTitle?: string | false;
|
|
@@ -89,6 +95,26 @@ export interface SelectProps extends BaseProps {
|
|
|
89
95
|
errorMessage?: string;
|
|
90
96
|
onChange?: (option: SelectDataProps<string>) => void;
|
|
91
97
|
label?: string;
|
|
98
|
+
theme?: Partial<{
|
|
99
|
+
control: Partial<CSSProperties> &
|
|
100
|
+
Partial<{
|
|
101
|
+
hover: Partial<CSSProperties>;
|
|
102
|
+
focus: Partial<CSSProperties>;
|
|
103
|
+
error: Partial<CSSProperties>;
|
|
104
|
+
}>;
|
|
105
|
+
option: Partial<CSSProperties> &
|
|
106
|
+
Partial<{
|
|
107
|
+
selected: Partial<CSSProperties>;
|
|
108
|
+
disabled: Partial<CSSProperties>;
|
|
109
|
+
focus: Partial<CSSProperties>;
|
|
110
|
+
error: Partial<CSSObjectWithLabel>;
|
|
111
|
+
}>;
|
|
112
|
+
placeholder: Partial<CSSProperties> &
|
|
113
|
+
Partial<{ error: CSSObjectWithLabel }>;
|
|
114
|
+
input: Partial<CSSProperties> & Partial<{ error: CSSObjectWithLabel }>;
|
|
115
|
+
singleValue: Partial<CSSProperties> &
|
|
116
|
+
Partial<{ error: CSSObjectWithLabel }>;
|
|
117
|
+
}>;
|
|
92
118
|
}
|
|
93
119
|
|
|
94
120
|
export type UploadProps = BaseProps & {
|
|
@@ -103,9 +129,11 @@ export type UploadProps = BaseProps & {
|
|
|
103
129
|
withUpload?: boolean;
|
|
104
130
|
onLoading?: (loading: boolean) => void;
|
|
105
131
|
borderRadius?: number;
|
|
132
|
+
borderRadiusUnit?: "px" | "%";
|
|
106
133
|
width?: number;
|
|
107
134
|
height?: number;
|
|
108
135
|
imgPreviewStyle?: Pick<CSSProperties, "objectFit">;
|
|
136
|
+
theme?: Partial<{ triggerTheme: FileUploadWrapperTheme }>;
|
|
109
137
|
} & (
|
|
110
138
|
| {
|
|
111
139
|
withEditor: true;
|
|
@@ -73,7 +73,7 @@ const ImagePlaceholder = styled.div`
|
|
|
73
73
|
}
|
|
74
74
|
`;
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
export type IpfsImageProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
77
77
|
src: string;
|
|
78
78
|
children?: React.ReactNode;
|
|
79
79
|
dataTestId?: string;
|
|
@@ -85,10 +85,9 @@ interface IImage {
|
|
|
85
85
|
overrides?: {
|
|
86
86
|
ipfsGateway?: string;
|
|
87
87
|
};
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
> = ({
|
|
88
|
+
className?: string;
|
|
89
|
+
};
|
|
90
|
+
export const IpfsImage: React.FC<IpfsImageProps> = ({
|
|
92
91
|
src,
|
|
93
92
|
children,
|
|
94
93
|
dataTestId = "image",
|
|
@@ -130,7 +129,11 @@ export const IpfsImage: React.FC<
|
|
|
130
129
|
|
|
131
130
|
return (
|
|
132
131
|
<>
|
|
133
|
-
<ImageWrapper
|
|
132
|
+
<ImageWrapper
|
|
133
|
+
{...rest}
|
|
134
|
+
$hide={!isLoading}
|
|
135
|
+
className={"loading-container " + rest.className}
|
|
136
|
+
>
|
|
134
137
|
<ImagePlaceholder>
|
|
135
138
|
<Typography tag="div">
|
|
136
139
|
<Loading />
|
|
@@ -149,7 +152,11 @@ export const IpfsImage: React.FC<
|
|
|
149
152
|
)}
|
|
150
153
|
</ImagePlaceholder>
|
|
151
154
|
</ImageWrapper>
|
|
152
|
-
<ImageWrapper
|
|
155
|
+
<ImageWrapper
|
|
156
|
+
{...rest}
|
|
157
|
+
$hide={!isSuccess}
|
|
158
|
+
className={"image-container " + rest.className}
|
|
159
|
+
>
|
|
153
160
|
{children || ""}
|
|
154
161
|
<ImageContainer
|
|
155
162
|
data-testid={dataTestId}
|
|
@@ -97,7 +97,7 @@ const VideoPlaceholder = styled.div<{ $position?: CSSProperties["position"] }>`
|
|
|
97
97
|
}
|
|
98
98
|
`;
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
export type VideoProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
101
101
|
src: string;
|
|
102
102
|
children?: ReactNode;
|
|
103
103
|
dataTestId?: string;
|
|
@@ -106,8 +106,8 @@ interface IVideo {
|
|
|
106
106
|
videoProps?: VideoHTMLAttributes<HTMLElement>;
|
|
107
107
|
withMuteButton?: boolean;
|
|
108
108
|
componentWhileLoading?: () => ReactElement;
|
|
109
|
-
}
|
|
110
|
-
const Video: React.FC<
|
|
109
|
+
};
|
|
110
|
+
export const Video: React.FC<VideoProps> = ({
|
|
111
111
|
src,
|
|
112
112
|
children,
|
|
113
113
|
dataTestId = "video",
|
|
@@ -133,6 +133,8 @@ const Video: React.FC<IVideo & React.HTMLAttributes<HTMLDivElement>> = ({
|
|
|
133
133
|
ipfsMetadataStorage
|
|
134
134
|
);
|
|
135
135
|
setVideoSrc(base64str as string);
|
|
136
|
+
setIsLoaded(true);
|
|
137
|
+
setIsError(false);
|
|
136
138
|
} catch (error) {
|
|
137
139
|
console.error("error in Video", error);
|
|
138
140
|
setIsLoaded(true);
|
|
@@ -146,12 +148,12 @@ const Video: React.FC<IVideo & React.HTMLAttributes<HTMLDivElement>> = ({
|
|
|
146
148
|
if (!isLoaded && videoSrc === null) {
|
|
147
149
|
if (
|
|
148
150
|
src?.startsWith("ipfs://") ||
|
|
149
|
-
src
|
|
151
|
+
src?.startsWith("https://bosonprotocol.infura-ipfs.io/ipfs/")
|
|
150
152
|
) {
|
|
151
|
-
const
|
|
153
|
+
const split = src?.startsWith("ipfs://")
|
|
152
154
|
? src.split("//")
|
|
153
155
|
: src.split("https://bosonprotocol.infura-ipfs.io/ipfs/");
|
|
154
|
-
const CID =
|
|
156
|
+
const CID = split[split.length - 1];
|
|
155
157
|
fetchData(`ipfs://${CID}`);
|
|
156
158
|
} else if (src?.startsWith("undefined") && src?.length > 9) {
|
|
157
159
|
const CID = src.replace("undefined", "");
|
|
@@ -162,12 +164,6 @@ const Video: React.FC<IVideo & React.HTMLAttributes<HTMLDivElement>> = ({
|
|
|
162
164
|
}
|
|
163
165
|
}, []); // eslint-disable-line
|
|
164
166
|
|
|
165
|
-
useEffect(() => {
|
|
166
|
-
if (videoSrc !== null) {
|
|
167
|
-
setTimeout(() => setIsLoaded(true), 100);
|
|
168
|
-
}
|
|
169
|
-
}, [videoSrc]);
|
|
170
|
-
|
|
171
167
|
const mp4Src = useMemo(() => {
|
|
172
168
|
const octetSrc =
|
|
173
169
|
videoSrc?.startsWith("data:application/octet-stream;base64,") || false;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { validateMetadata } from "@bosonprotocol/core-sdk";
|
|
1
2
|
import { useConfigContext } from "../../components/config/ConfigContext";
|
|
2
3
|
import { useIpfsContext } from "../../components/ipfs/IpfsContext";
|
|
3
4
|
import { useIpfsMetadataStorage } from "../useIpfsMetadataStorage";
|
|
@@ -9,6 +10,7 @@ export function useIpfsStorage() {
|
|
|
9
10
|
const storage = useIpfsMetadataStorage(
|
|
10
11
|
config.envName,
|
|
11
12
|
config.configId,
|
|
13
|
+
validateMetadata,
|
|
12
14
|
ipfsMetadataStorageUrl,
|
|
13
15
|
ipfsMetadataStorageHeaders
|
|
14
16
|
);
|
|
@@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
|
|
|
2
2
|
import {
|
|
3
3
|
getEnvConfigById,
|
|
4
4
|
ConfigId,
|
|
5
|
-
|
|
5
|
+
AnyMetadata
|
|
6
6
|
} from "@bosonprotocol/core-sdk";
|
|
7
7
|
import { IpfsMetadataStorage } from "@bosonprotocol/ipfs-storage";
|
|
8
8
|
import { EnvironmentType } from "@bosonprotocol/common/src/types";
|
|
@@ -18,19 +18,20 @@ import { EnvironmentType } from "@bosonprotocol/common/src/types";
|
|
|
18
18
|
export function useIpfsMetadataStorage(
|
|
19
19
|
envName: EnvironmentType,
|
|
20
20
|
configId: ConfigId,
|
|
21
|
+
validateMetadata: (metadata: AnyMetadata) => void,
|
|
21
22
|
url?: string,
|
|
22
23
|
headers?: Headers | Record<string, string>
|
|
23
24
|
) {
|
|
24
25
|
const [ipfsMetadataStorage, setIpfsMetadataStorage] =
|
|
25
26
|
useState<IpfsMetadataStorage>(
|
|
26
|
-
initIpfsMetadataStorage(envName, configId, url, headers)
|
|
27
|
+
initIpfsMetadataStorage(envName, configId, validateMetadata, url, headers)
|
|
27
28
|
);
|
|
28
29
|
|
|
29
30
|
useEffect(() => {
|
|
30
31
|
setIpfsMetadataStorage(
|
|
31
|
-
initIpfsMetadataStorage(envName, configId, url, headers)
|
|
32
|
+
initIpfsMetadataStorage(envName, configId, validateMetadata, url, headers)
|
|
32
33
|
);
|
|
33
|
-
}, [envName, configId, url, headers]);
|
|
34
|
+
}, [envName, configId, validateMetadata, url, headers]);
|
|
34
35
|
|
|
35
36
|
return ipfsMetadataStorage;
|
|
36
37
|
}
|
|
@@ -38,6 +39,7 @@ export function useIpfsMetadataStorage(
|
|
|
38
39
|
function initIpfsMetadataStorage(
|
|
39
40
|
envName: EnvironmentType,
|
|
40
41
|
configId: ConfigId,
|
|
42
|
+
validateMetadata: (metadata: AnyMetadata) => void,
|
|
41
43
|
url?: string,
|
|
42
44
|
headers?: Headers | Record<string, string>
|
|
43
45
|
) {
|