@bosonprotocol/react-kit 0.32.0-alpha.8 → 0.32.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/contractualAgreement/ContractualAgreement.js +2 -2
- package/dist/cjs/components/contractualAgreement/ContractualAgreement.js.map +1 -1
- package/dist/cjs/components/error/SimpleError.d.ts +7 -5
- package/dist/cjs/components/error/SimpleError.d.ts.map +1 -1
- package/dist/cjs/components/error/SimpleError.js +6 -5
- package/dist/cjs/components/error/SimpleError.js.map +1 -1
- package/dist/cjs/components/form/BaseTextArea.d.ts +5 -0
- package/dist/cjs/components/form/BaseTextArea.d.ts.map +1 -0
- package/dist/cjs/components/form/{Textarea.js → BaseTextArea.js} +6 -5
- package/dist/cjs/components/form/BaseTextArea.js.map +1 -0
- package/dist/cjs/components/form/Field.styles.d.ts +25 -2
- package/dist/cjs/components/form/Field.styles.d.ts.map +1 -1
- package/dist/cjs/components/form/Field.styles.js +35 -60
- package/dist/cjs/components/form/Field.styles.js.map +1 -1
- package/dist/cjs/components/form/FormField.d.ts +1 -1
- package/dist/cjs/components/form/FormField.d.ts.map +1 -1
- package/dist/cjs/components/form/FormField.js +5 -3
- package/dist/cjs/components/form/FormField.js.map +1 -1
- package/dist/cjs/components/form/Upload/ImageEditorModal/ImageEditor.d.ts +9 -0
- package/dist/cjs/components/form/Upload/ImageEditorModal/ImageEditor.d.ts.map +1 -0
- package/dist/cjs/components/form/Upload/ImageEditorModal/ImageEditor.js +65 -0
- package/dist/cjs/components/form/Upload/ImageEditorModal/ImageEditor.js.map +1 -0
- package/dist/cjs/components/form/Upload/ImageEditorModal/ImageEditorModal.d.ts +10 -0
- package/dist/cjs/components/form/Upload/ImageEditorModal/ImageEditorModal.d.ts.map +1 -0
- package/dist/cjs/components/form/Upload/ImageEditorModal/ImageEditorModal.js +100 -0
- package/dist/cjs/components/form/Upload/ImageEditorModal/ImageEditorModal.js.map +1 -0
- package/dist/cjs/components/form/Upload/Upload.d.ts +39 -2
- package/dist/cjs/components/form/Upload/Upload.d.ts.map +1 -1
- package/dist/cjs/components/form/Upload/Upload.js +81 -19
- package/dist/cjs/components/form/Upload/Upload.js.map +1 -1
- package/dist/cjs/components/form/Upload/WithUploadToIpfs.d.ts +1 -1
- package/dist/cjs/components/form/Upload/WithUploadToIpfs.d.ts.map +1 -1
- package/dist/cjs/components/form/Upload/WithUploadToIpfs.js +9 -7
- package/dist/cjs/components/form/Upload/WithUploadToIpfs.js.map +1 -1
- package/dist/cjs/components/form/index.d.ts +2 -2
- package/dist/cjs/components/form/index.d.ts.map +1 -1
- package/dist/cjs/components/form/index.js +3 -4
- package/dist/cjs/components/form/index.js.map +1 -1
- package/dist/cjs/components/form/types.d.ts +21 -5
- package/dist/cjs/components/form/types.d.ts.map +1 -1
- package/dist/cjs/components/license/License.js +2 -2
- package/dist/cjs/components/license/License.js.map +1 -1
- package/dist/cjs/components/modal/ModalComponents.d.ts +2 -0
- package/dist/cjs/components/modal/ModalComponents.d.ts.map +1 -1
- package/dist/cjs/components/modal/ModalComponents.js +3 -1
- package/dist/cjs/components/modal/ModalComponents.js.map +1 -1
- package/dist/cjs/components/modal/ModalContext.d.ts +2 -1
- package/dist/cjs/components/modal/ModalContext.d.ts.map +1 -1
- package/dist/cjs/components/modal/ModalContext.js.map +1 -1
- package/dist/cjs/components/modal/ModalTypes.d.ts +1 -0
- package/dist/cjs/components/modal/ModalTypes.d.ts.map +1 -1
- package/dist/cjs/components/modal/ModalTypes.js +2 -1
- package/dist/cjs/components/modal/ModalTypes.js.map +1 -1
- package/dist/cjs/components/modal/components/Redeem/Confirmation/Confirmation.js +3 -3
- package/dist/cjs/components/modal/components/Redeem/Confirmation/Confirmation.js.map +1 -1
- package/dist/cjs/components/modal/components/Redeem/ExchangeView/cancellation/CancelExchange.js +2 -2
- package/dist/cjs/components/modal/components/Redeem/ExchangeView/cancellation/CancelExchange.js.map +1 -1
- package/dist/cjs/components/modal/components/Redeem/ExchangeView/expireVoucher/ExpireVoucher.js +2 -2
- package/dist/cjs/components/modal/components/Redeem/ExchangeView/expireVoucher/ExpireVoucher.js.map +1 -1
- package/dist/cjs/components/modal/components/common/VariationSelects.js +2 -2
- package/dist/cjs/components/modal/components/common/VariationSelects.js.map +1 -1
- package/dist/cjs/components/modal/useModal.d.ts +3 -2
- package/dist/cjs/components/modal/useModal.d.ts.map +1 -1
- package/dist/cjs/components/step/MultiSteps.d.ts +23 -0
- package/dist/cjs/components/step/MultiSteps.d.ts.map +1 -0
- package/dist/cjs/components/step/MultiSteps.js +121 -0
- package/dist/cjs/components/step/MultiSteps.js.map +1 -0
- package/dist/cjs/components/step/Step.d.ts +28 -0
- package/dist/cjs/components/step/Step.d.ts.map +1 -0
- package/dist/cjs/components/step/Step.js +32 -0
- package/dist/cjs/components/step/Step.js.map +1 -0
- package/dist/cjs/components/step/Step.styles.d.ts +29 -0
- package/dist/cjs/components/step/Step.styles.d.ts.map +1 -0
- package/dist/cjs/components/step/Step.styles.js +196 -0
- package/dist/cjs/components/step/Step.styles.js.map +1 -0
- package/dist/cjs/hooks/images/useFileImage.d.ts +8 -0
- package/dist/cjs/hooks/images/useFileImage.d.ts.map +1 -0
- package/dist/cjs/hooks/images/useFileImage.js +26 -0
- package/dist/cjs/hooks/images/useFileImage.js.map +1 -0
- package/dist/cjs/hooks/images/useIpfsImage.d.ts +13 -0
- package/dist/cjs/hooks/images/useIpfsImage.d.ts.map +1 -0
- package/dist/cjs/hooks/images/useIpfsImage.js +26 -0
- package/dist/cjs/hooks/images/useIpfsImage.js.map +1 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +3 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/base64/base64.d.ts +4 -1
- package/dist/cjs/lib/base64/base64.d.ts.map +1 -1
- package/dist/cjs/lib/base64/base64.js +1 -1
- package/dist/cjs/lib/base64/base64.js.map +1 -1
- package/dist/esm/components/contractualAgreement/ContractualAgreement.js +1 -1
- package/dist/esm/components/contractualAgreement/ContractualAgreement.js.map +1 -1
- package/dist/esm/components/error/SimpleError.d.ts +7 -5
- package/dist/esm/components/error/SimpleError.d.ts.map +1 -1
- package/dist/esm/components/error/SimpleError.js +4 -4
- package/dist/esm/components/error/SimpleError.js.map +1 -1
- package/dist/esm/components/form/BaseTextArea.d.ts +5 -0
- package/dist/esm/components/form/BaseTextArea.d.ts.map +1 -0
- package/dist/esm/components/form/{Textarea.js → BaseTextArea.js} +3 -3
- package/dist/esm/components/form/BaseTextArea.js.map +1 -0
- package/dist/esm/components/form/Field.styles.d.ts +25 -2
- package/dist/esm/components/form/Field.styles.d.ts.map +1 -1
- package/dist/esm/components/form/Field.styles.js +35 -60
- package/dist/esm/components/form/Field.styles.js.map +1 -1
- package/dist/esm/components/form/FormField.d.ts +1 -1
- package/dist/esm/components/form/FormField.d.ts.map +1 -1
- package/dist/esm/components/form/FormField.js +3 -2
- package/dist/esm/components/form/FormField.js.map +1 -1
- package/dist/esm/components/form/Upload/ImageEditorModal/ImageEditor.d.ts +9 -0
- package/dist/esm/components/form/Upload/ImageEditorModal/ImageEditor.d.ts.map +1 -0
- package/dist/esm/components/form/Upload/ImageEditorModal/ImageEditor.js +36 -0
- package/dist/esm/components/form/Upload/ImageEditorModal/ImageEditor.js.map +1 -0
- package/dist/esm/components/form/Upload/ImageEditorModal/ImageEditorModal.d.ts +10 -0
- package/dist/esm/components/form/Upload/ImageEditorModal/ImageEditorModal.d.ts.map +1 -0
- package/dist/esm/components/form/Upload/ImageEditorModal/ImageEditorModal.js +48 -0
- package/dist/esm/components/form/Upload/ImageEditorModal/ImageEditorModal.js.map +1 -0
- package/dist/esm/components/form/Upload/Upload.d.ts +39 -2
- package/dist/esm/components/form/Upload/Upload.d.ts.map +1 -1
- package/dist/esm/components/form/Upload/Upload.js +93 -19
- package/dist/esm/components/form/Upload/Upload.js.map +1 -1
- package/dist/esm/components/form/Upload/WithUploadToIpfs.d.ts +1 -1
- package/dist/esm/components/form/Upload/WithUploadToIpfs.d.ts.map +1 -1
- package/dist/esm/components/form/Upload/WithUploadToIpfs.js +9 -7
- package/dist/esm/components/form/Upload/WithUploadToIpfs.js.map +1 -1
- package/dist/esm/components/form/index.d.ts +2 -2
- package/dist/esm/components/form/index.d.ts.map +1 -1
- package/dist/esm/components/form/index.js +2 -2
- package/dist/esm/components/form/index.js.map +1 -1
- package/dist/esm/components/form/types.d.ts +21 -5
- package/dist/esm/components/form/types.d.ts.map +1 -1
- package/dist/esm/components/license/License.js +1 -1
- package/dist/esm/components/license/License.js.map +1 -1
- package/dist/esm/components/modal/ModalComponents.d.ts +2 -0
- package/dist/esm/components/modal/ModalComponents.d.ts.map +1 -1
- package/dist/esm/components/modal/ModalComponents.js +3 -1
- package/dist/esm/components/modal/ModalComponents.js.map +1 -1
- package/dist/esm/components/modal/ModalContext.d.ts +2 -1
- package/dist/esm/components/modal/ModalContext.d.ts.map +1 -1
- package/dist/esm/components/modal/ModalContext.js.map +1 -1
- package/dist/esm/components/modal/ModalTypes.d.ts +1 -0
- package/dist/esm/components/modal/ModalTypes.d.ts.map +1 -1
- package/dist/esm/components/modal/ModalTypes.js +2 -1
- package/dist/esm/components/modal/ModalTypes.js.map +1 -1
- package/dist/esm/components/modal/components/Redeem/Confirmation/Confirmation.js +1 -1
- package/dist/esm/components/modal/components/Redeem/Confirmation/Confirmation.js.map +1 -1
- package/dist/esm/components/modal/components/Redeem/ExchangeView/cancellation/CancelExchange.js +1 -1
- package/dist/esm/components/modal/components/Redeem/ExchangeView/cancellation/CancelExchange.js.map +1 -1
- package/dist/esm/components/modal/components/Redeem/ExchangeView/expireVoucher/ExpireVoucher.js +1 -1
- package/dist/esm/components/modal/components/Redeem/ExchangeView/expireVoucher/ExpireVoucher.js.map +1 -1
- package/dist/esm/components/modal/components/common/VariationSelects.js +1 -1
- package/dist/esm/components/modal/components/common/VariationSelects.js.map +1 -1
- package/dist/esm/components/modal/useModal.d.ts +3 -2
- package/dist/esm/components/modal/useModal.d.ts.map +1 -1
- package/dist/esm/components/step/MultiSteps.d.ts +23 -0
- package/dist/esm/components/step/MultiSteps.d.ts.map +1 -0
- package/dist/esm/components/step/MultiSteps.js +82 -0
- package/dist/esm/components/step/MultiSteps.js.map +1 -0
- package/dist/esm/components/step/Step.d.ts +28 -0
- package/dist/esm/components/step/Step.d.ts.map +1 -0
- package/dist/esm/components/step/Step.js +13 -0
- package/dist/esm/components/step/Step.js.map +1 -0
- package/dist/esm/components/step/Step.styles.d.ts +29 -0
- package/dist/esm/components/step/Step.styles.d.ts.map +1 -0
- package/dist/esm/components/step/Step.styles.js +170 -0
- package/dist/esm/components/step/Step.styles.js.map +1 -0
- package/dist/esm/hooks/images/useFileImage.d.ts +8 -0
- package/dist/esm/hooks/images/useFileImage.d.ts.map +1 -0
- package/dist/esm/hooks/images/useFileImage.js +13 -0
- package/dist/esm/hooks/images/useFileImage.js.map +1 -0
- package/dist/esm/hooks/images/useIpfsImage.d.ts +13 -0
- package/dist/esm/hooks/images/useIpfsImage.d.ts.map +1 -0
- package/dist/esm/hooks/images/useIpfsImage.js +16 -0
- package/dist/esm/hooks/images/useIpfsImage.js.map +1 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/base64/base64.d.ts +4 -1
- package/dist/esm/lib/base64/base64.d.ts.map +1 -1
- package/dist/esm/lib/base64/base64.js +1 -1
- package/dist/esm/lib/base64/base64.js.map +1 -1
- package/package.json +7 -4
- package/src/components/contractualAgreement/ContractualAgreement.tsx +1 -1
- package/src/components/error/SimpleError.tsx +16 -11
- package/src/components/form/{Textarea.tsx → BaseTextArea.tsx} +8 -3
- package/src/components/form/Field.styles.ts +68 -64
- package/src/components/form/FormField.tsx +6 -4
- package/src/components/form/Upload/ImageEditorModal/ImageEditor.tsx +74 -0
- package/src/components/form/Upload/ImageEditorModal/ImageEditorModal.tsx +77 -0
- package/src/components/form/Upload/Upload.tsx +137 -41
- package/src/components/form/Upload/WithUploadToIpfs.tsx +13 -11
- package/src/components/form/index.ts +2 -2
- package/src/components/form/types.ts +20 -4
- package/src/components/license/License.tsx +1 -1
- package/src/components/modal/ModalComponents.tsx +3 -1
- package/src/components/modal/ModalContext.tsx +4 -3
- package/src/components/modal/ModalTypes.ts +2 -1
- package/src/components/modal/components/Redeem/Confirmation/Confirmation.tsx +1 -1
- package/src/components/modal/components/Redeem/ExchangeView/cancellation/CancelExchange.tsx +1 -1
- package/src/components/modal/components/Redeem/ExchangeView/expireVoucher/ExpireVoucher.tsx +1 -1
- package/src/components/modal/components/common/VariationSelects.tsx +1 -1
- package/src/components/step/MultiSteps.tsx +187 -0
- package/src/components/step/Step.styles.ts +209 -0
- package/src/components/step/Step.tsx +67 -0
- package/src/hooks/images/useFileImage.ts +24 -0
- package/src/hooks/images/useIpfsImage.ts +27 -0
- package/src/index.tsx +3 -0
- package/src/lib/base64/base64.ts +1 -1
- package/src/stories/buttons/Upload.stories.tsx +82 -0
- package/src/stories/form/{Input.stories.tsx → BaseInput.stories.tsx} +1 -1
- package/src/stories/form/BaseTextArea.stories.tsx +59 -0
- package/src/stories/multisteps/MultiSteps.stories.tsx +86 -0
- package/dist/cjs/components/form/Textarea.d.ts +0 -4
- package/dist/cjs/components/form/Textarea.d.ts.map +0 -1
- package/dist/cjs/components/form/Textarea.js.map +0 -1
- package/dist/esm/components/form/Textarea.d.ts +0 -4
- package/dist/esm/components/form/Textarea.d.ts.map +0 -1
- package/dist/esm/components/form/Textarea.js.map +0 -1
- /package/src/stories/buttons/{button.stories.tsx → Button.stories.tsx} +0 -0
|
@@ -4,15 +4,20 @@ import React from "react";
|
|
|
4
4
|
import Error from "./Error";
|
|
5
5
|
import { FieldTextArea } from "./Field.styles";
|
|
6
6
|
import type { TextareaProps } from "./types";
|
|
7
|
-
|
|
8
|
-
export
|
|
7
|
+
export type BaseTextAreaProps = TextareaProps;
|
|
8
|
+
export function BaseTextArea({ name, theme, ...props }: TextareaProps) {
|
|
9
9
|
const [field, meta] = useField(name);
|
|
10
10
|
const errorMessage = meta.error && meta.touched ? meta.error : "";
|
|
11
11
|
const displayError =
|
|
12
12
|
typeof errorMessage === typeof "string" && errorMessage !== "";
|
|
13
13
|
return (
|
|
14
14
|
<>
|
|
15
|
-
<FieldTextArea
|
|
15
|
+
<FieldTextArea
|
|
16
|
+
$error={errorMessage}
|
|
17
|
+
{...field}
|
|
18
|
+
{...props}
|
|
19
|
+
theme={theme}
|
|
20
|
+
/>
|
|
16
21
|
<Error display={displayError} message={errorMessage} />
|
|
17
22
|
</>
|
|
18
23
|
);
|
|
@@ -61,7 +61,6 @@ export const FieldInput = styled.input<{
|
|
|
61
61
|
border: 1px solid ${(props) => props.theme?.borderColor || colors.border};
|
|
62
62
|
border-radius: ${(props) => props.theme?.borderRadius || 0}px;
|
|
63
63
|
outline: none;
|
|
64
|
-
font-family: "Plus Jakarta Sans";
|
|
65
64
|
|
|
66
65
|
${transition}
|
|
67
66
|
|
|
@@ -116,7 +115,7 @@ export const FieldInput = styled.input<{
|
|
|
116
115
|
`};
|
|
117
116
|
`;
|
|
118
117
|
|
|
119
|
-
export const FileUploadWrapper = styled.div<{
|
|
118
|
+
export const FileUploadWrapper = styled.div<{ error: any }>`
|
|
120
119
|
position: relative;
|
|
121
120
|
overflow: hidden;
|
|
122
121
|
display: flex;
|
|
@@ -210,16 +209,38 @@ export const FieldFileUploadWrapper = styled.div<{ $disabled: boolean }>`
|
|
|
210
209
|
background: ${colors.black}80;
|
|
211
210
|
}
|
|
212
211
|
`;
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
export type TextAreaTheme = {
|
|
213
|
+
background: CSSProperties["backgroundColor"];
|
|
214
|
+
borderColor: CSSProperties["borderColor"];
|
|
215
|
+
borderRadius: CSSProperties["borderRadius"];
|
|
216
|
+
focus: {
|
|
217
|
+
caretColor: CSSProperties["caretColor"];
|
|
218
|
+
};
|
|
219
|
+
hover: {
|
|
220
|
+
borderColor: CSSProperties["borderColor"];
|
|
221
|
+
};
|
|
222
|
+
error: {
|
|
223
|
+
borderColor: CSSProperties["borderColor"];
|
|
224
|
+
hover: {
|
|
225
|
+
borderColor: CSSProperties["borderColor"];
|
|
226
|
+
};
|
|
227
|
+
focus: {
|
|
228
|
+
borderColor: CSSProperties["borderColor"];
|
|
229
|
+
caretColor: CSSProperties["caretColor"];
|
|
230
|
+
};
|
|
231
|
+
placeholder: {
|
|
232
|
+
color: CSSProperties["color"];
|
|
233
|
+
};
|
|
234
|
+
};
|
|
235
|
+
};
|
|
236
|
+
export const FieldTextArea = styled.textarea<{ $error: any }>`
|
|
215
237
|
width: 100%;
|
|
216
238
|
padding: 1rem;
|
|
217
239
|
gap: 0.5rem;
|
|
218
|
-
font-family:
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
border:
|
|
222
|
-
border-radius: 0;
|
|
240
|
+
font-family: inherit;
|
|
241
|
+
background: ${(props) => props.theme?.background || "transparent"};
|
|
242
|
+
border: 1px solid ${(props) => props.theme?.borderColor || colors.border};
|
|
243
|
+
border-radius: ${(props) => props.theme?.borderRadius || 0}px;
|
|
223
244
|
outline: none;
|
|
224
245
|
|
|
225
246
|
${transition}
|
|
@@ -227,7 +248,9 @@ export const FieldTextArea = styled.textarea<{ error: any }>`
|
|
|
227
248
|
&:not(:disabled) {
|
|
228
249
|
&:focus,
|
|
229
250
|
&:hover {
|
|
230
|
-
border: 1px solid
|
|
251
|
+
border: 1px solid
|
|
252
|
+
${(props) => props.theme?.hover?.borderColor || colors.lightGrey};
|
|
253
|
+
caret-color: ${(props) => props.theme?.focus?.caretColor || "initial"};
|
|
231
254
|
}
|
|
232
255
|
}
|
|
233
256
|
|
|
@@ -236,39 +259,41 @@ export const FieldTextArea = styled.textarea<{ error: any }>`
|
|
|
236
259
|
opacity: 0.5;
|
|
237
260
|
}
|
|
238
261
|
|
|
239
|
-
${({ error }) =>
|
|
240
|
-
!checkIfValueIsEmpty(error)
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
262
|
+
${({ $error }) =>
|
|
263
|
+
!checkIfValueIsEmpty($error) &&
|
|
264
|
+
css`
|
|
265
|
+
border: 1px solid
|
|
266
|
+
${(props) => props.theme?.error?.borderColor || colors.orange};
|
|
267
|
+
&:not(:disabled) {
|
|
268
|
+
&:hover {
|
|
269
|
+
border: 1px solid
|
|
270
|
+
${(props) =>
|
|
271
|
+
props.theme?.error?.hover?.borderColor || colors.orange};
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
&:not(:disabled) {
|
|
275
|
+
&:focus {
|
|
276
|
+
border: 1px solid
|
|
277
|
+
${(props) =>
|
|
278
|
+
props.theme?.error?.focus?.borderColor || colors.lightGrey};
|
|
279
|
+
caret-color: ${(props) =>
|
|
280
|
+
props.theme?.error?.focus?.caretColor || colors.orange};
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
&::placeholder {
|
|
284
|
+
color: ${(props) =>
|
|
285
|
+
props.theme?.error?.placeholder?.color || colors.orange};
|
|
286
|
+
opacity: 1;
|
|
287
|
+
}
|
|
288
|
+
&:-ms-input-placeholder {
|
|
289
|
+
color: ${(props) =>
|
|
290
|
+
props.theme?.error?.placeholder?.color || colors.orange};
|
|
291
|
+
}
|
|
292
|
+
&::-ms-input-placeholder {
|
|
293
|
+
color: ${(props) =>
|
|
294
|
+
props.theme?.error?.placeholder?.color || colors.orange};
|
|
295
|
+
}
|
|
296
|
+
`}
|
|
272
297
|
`;
|
|
273
298
|
|
|
274
299
|
export const FormFieldWrapper = styled(Grid)`
|
|
@@ -277,31 +302,10 @@ export const FormFieldWrapper = styled(Grid)`
|
|
|
277
302
|
line-height: 150%;
|
|
278
303
|
}
|
|
279
304
|
|
|
280
|
-
// theme white
|
|
281
|
-
margin-bottom: 0.5rem;
|
|
282
|
-
input,
|
|
283
|
-
textarea {
|
|
284
|
-
background: ${colors.white};
|
|
285
|
-
&:disabled {
|
|
286
|
-
opacity: 1;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
input {
|
|
290
|
-
border-width: 0;
|
|
291
|
-
&:hover {
|
|
292
|
-
border-width: 0;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
input + div {
|
|
296
|
-
background: ${colors.white};
|
|
297
|
-
}
|
|
298
|
-
// end theme white
|
|
299
|
-
|
|
300
305
|
[data-header] {
|
|
301
306
|
margin: 0;
|
|
302
307
|
font-weight: 600;
|
|
303
308
|
font-size: 1rem;
|
|
304
|
-
color: ${colors.black};
|
|
305
309
|
+ div button {
|
|
306
310
|
margin-left: 0.5rem;
|
|
307
311
|
padding: 0;
|
|
@@ -13,15 +13,16 @@ import type { FormFieldProps } from "./types";
|
|
|
13
13
|
|
|
14
14
|
const colors = theme.colors.light;
|
|
15
15
|
|
|
16
|
-
export
|
|
16
|
+
export function FormField({
|
|
17
17
|
title,
|
|
18
|
+
titleIcon,
|
|
18
19
|
subTitle = false,
|
|
19
20
|
required = false,
|
|
20
21
|
tooltip,
|
|
21
22
|
children,
|
|
22
23
|
style = {},
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
valueToCopy,
|
|
25
|
+
copyIconColor = colors.secondary
|
|
25
26
|
}: FormFieldProps) {
|
|
26
27
|
return (
|
|
27
28
|
<FormFieldWrapper
|
|
@@ -59,10 +60,11 @@ export default function FormField({
|
|
|
59
60
|
}
|
|
60
61
|
}}
|
|
61
62
|
>
|
|
62
|
-
<Copy size={24} color={
|
|
63
|
+
<Copy size={24} color={copyIconColor} weight="light" />
|
|
63
64
|
</CopyButton>
|
|
64
65
|
)}
|
|
65
66
|
</Typography>
|
|
67
|
+
{titleIcon}
|
|
66
68
|
{tooltip && <Tooltip content={tooltip} size={16} />}
|
|
67
69
|
</Grid>
|
|
68
70
|
{subTitle && (
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React, { ChangeEvent, forwardRef, useState } from "react";
|
|
2
|
+
import AvatarEditor, { AvatarEditorProps } from "react-avatar-editor";
|
|
3
|
+
import Dropzone from "react-dropzone";
|
|
4
|
+
import styled from "styled-components";
|
|
5
|
+
import { Grid } from "../../../ui/Grid";
|
|
6
|
+
import { useIpfsImage } from "../../../../hooks/images/useIpfsImage";
|
|
7
|
+
|
|
8
|
+
const StyledCanvasWrapper = styled.div`
|
|
9
|
+
display: flex;
|
|
10
|
+
justify-content: center;
|
|
11
|
+
> :first-child {
|
|
12
|
+
max-width: 100%;
|
|
13
|
+
object-fit: contain;
|
|
14
|
+
width: auto !important;
|
|
15
|
+
height: auto !important;
|
|
16
|
+
}
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
export type ImageEditorProps = Pick<
|
|
20
|
+
AvatarEditorProps,
|
|
21
|
+
"borderRadius" | "width" | "height"
|
|
22
|
+
> & {
|
|
23
|
+
url?: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const ImageEditor = forwardRef<AvatarEditor, ImageEditorProps>(
|
|
27
|
+
({ url, borderRadius, width, height }, editorRef) => {
|
|
28
|
+
const [scale, setScale] = useState<number>();
|
|
29
|
+
const handleScale = (e: ChangeEvent<HTMLInputElement>) => {
|
|
30
|
+
const scale = parseFloat(e.target.value);
|
|
31
|
+
setScale(scale);
|
|
32
|
+
};
|
|
33
|
+
const { data } = useIpfsImage({ url: url ?? "" }, { enabled: !!url });
|
|
34
|
+
const image = data?.base64;
|
|
35
|
+
const { width: imageWidth, height: imageHeight } = data || {};
|
|
36
|
+
const w = borderRadius ? width : width || imageWidth;
|
|
37
|
+
const h = borderRadius ? height : height || imageHeight;
|
|
38
|
+
return (
|
|
39
|
+
<>
|
|
40
|
+
{image && (
|
|
41
|
+
<div style={{ margin: "2rem 0", maxWidth: "100%" }}>
|
|
42
|
+
<Dropzone noClick noKeyboard>
|
|
43
|
+
{({ getRootProps, getInputProps }) => (
|
|
44
|
+
<StyledCanvasWrapper {...getRootProps()}>
|
|
45
|
+
<AvatarEditor
|
|
46
|
+
image={image}
|
|
47
|
+
ref={editorRef}
|
|
48
|
+
width={w}
|
|
49
|
+
height={h}
|
|
50
|
+
scale={scale}
|
|
51
|
+
borderRadius={borderRadius}
|
|
52
|
+
/>
|
|
53
|
+
<input {...getInputProps()} />
|
|
54
|
+
</StyledCanvasWrapper>
|
|
55
|
+
)}
|
|
56
|
+
</Dropzone>
|
|
57
|
+
<Grid alignItems="center" justifyContent="center">
|
|
58
|
+
Zoom:
|
|
59
|
+
<input
|
|
60
|
+
name="scale"
|
|
61
|
+
type="range"
|
|
62
|
+
onChange={handleScale}
|
|
63
|
+
min={"0.1"}
|
|
64
|
+
max="2"
|
|
65
|
+
step="0.01"
|
|
66
|
+
defaultValue="1"
|
|
67
|
+
/>
|
|
68
|
+
</Grid>
|
|
69
|
+
</div>
|
|
70
|
+
)}
|
|
71
|
+
</>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
);
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as Sentry from "@sentry/browser";
|
|
2
|
+
import React, { useRef, useState } from "react";
|
|
3
|
+
import AvatarEditor from "react-avatar-editor";
|
|
4
|
+
import { dataURItoBlob } from "../../../../lib/base64/base64";
|
|
5
|
+
import Modal from "../../../modal/Modal";
|
|
6
|
+
import { Grid } from "../../../ui/Grid";
|
|
7
|
+
import { Spinner } from "../../../ui/loading/Spinner";
|
|
8
|
+
import { BaseButton, BaseButtonTheme } from "../../../buttons/BaseButton";
|
|
9
|
+
import { ImageEditor, ImageEditorProps } from "./ImageEditor";
|
|
10
|
+
import { useFileImage } from "../../../../hooks/images/useFileImage";
|
|
11
|
+
|
|
12
|
+
export type ImageEditorModalProps = Omit<ImageEditorProps, "url"> & {
|
|
13
|
+
files: File[] | null;
|
|
14
|
+
hideModal: (files?: File[]) => Promise<void>;
|
|
15
|
+
saveButtonTheme: BaseButtonTheme;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const ImageEditorModal: React.FC<ImageEditorModalProps> = ({
|
|
19
|
+
hideModal,
|
|
20
|
+
files,
|
|
21
|
+
saveButtonTheme,
|
|
22
|
+
...rest
|
|
23
|
+
}) => {
|
|
24
|
+
const originalFile = files?.[0];
|
|
25
|
+
const { data: url } = useFileImage(
|
|
26
|
+
{ file: originalFile },
|
|
27
|
+
{ enabled: !!originalFile }
|
|
28
|
+
);
|
|
29
|
+
const editorRef = useRef<AvatarEditor>(null);
|
|
30
|
+
const [isSaving, setSaving] = useState<boolean>(false);
|
|
31
|
+
const onClickSave = async () => {
|
|
32
|
+
setSaving(true);
|
|
33
|
+
try {
|
|
34
|
+
const img = editorRef.current?.getImageScaledToCanvas().toDataURL();
|
|
35
|
+
if (!img) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const blob = dataURItoBlob(img);
|
|
39
|
+
const file = new File([blob], originalFile?.name ?? "edited", {
|
|
40
|
+
type: originalFile?.type,
|
|
41
|
+
lastModified: originalFile?.lastModified
|
|
42
|
+
});
|
|
43
|
+
if (!file) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
await hideModal([file]);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
Sentry.captureException(error);
|
|
49
|
+
} finally {
|
|
50
|
+
setSaving(false);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
return (
|
|
54
|
+
<Modal
|
|
55
|
+
modalType="IMAGE_EDITOR"
|
|
56
|
+
hideModal={() => hideModal()}
|
|
57
|
+
size="auto"
|
|
58
|
+
maxWidths={{
|
|
59
|
+
s: "50rem"
|
|
60
|
+
}}
|
|
61
|
+
theme="light"
|
|
62
|
+
>
|
|
63
|
+
<Grid flexDirection="column">
|
|
64
|
+
<ImageEditor url={url} {...rest} ref={editorRef} />
|
|
65
|
+
<BaseButton
|
|
66
|
+
type="button"
|
|
67
|
+
theme={saveButtonTheme}
|
|
68
|
+
onClick={() => onClickSave()}
|
|
69
|
+
disabled={isSaving}
|
|
70
|
+
>
|
|
71
|
+
{isSaving ? "Saving" : "Save"}
|
|
72
|
+
{isSaving && <Spinner />}
|
|
73
|
+
</BaseButton>
|
|
74
|
+
</Grid>
|
|
75
|
+
</Modal>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as Sentry from "@sentry/browser";
|
|
1
2
|
import { useField } from "formik";
|
|
2
3
|
import { Image, Trash, VideoCamera } from "phosphor-react";
|
|
3
4
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -19,6 +20,8 @@ import {
|
|
|
19
20
|
import type { UploadFileType, UploadProps, FileProps } from "../types";
|
|
20
21
|
import UploadedFiles from "./UploadedFiles";
|
|
21
22
|
import { WithUploadToIpfs, WithUploadToIpfsProps } from "./WithUploadToIpfs";
|
|
23
|
+
import { useModal } from "../../modal/useModal";
|
|
24
|
+
import { ImageEditorModal } from "./ImageEditorModal/ImageEditorModal";
|
|
22
25
|
const colors = theme.colors.light;
|
|
23
26
|
|
|
24
27
|
function Upload({
|
|
@@ -33,11 +36,21 @@ function Upload({
|
|
|
33
36
|
wrapperProps,
|
|
34
37
|
onLoadSinglePreviewImage,
|
|
35
38
|
withUpload,
|
|
39
|
+
withEditor,
|
|
36
40
|
saveToIpfs,
|
|
37
41
|
loadMedia,
|
|
38
42
|
onLoading,
|
|
43
|
+
width,
|
|
44
|
+
height,
|
|
45
|
+
borderRadius,
|
|
46
|
+
imgPreviewStyle,
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
48
|
+
removeFile,
|
|
49
|
+
saveButtonTheme,
|
|
39
50
|
...props
|
|
40
51
|
}: UploadProps & WithUploadToIpfsProps) {
|
|
52
|
+
const { updateProps, store } = useModal();
|
|
53
|
+
const [showEditor, setShowEditor] = useState<boolean>(false);
|
|
41
54
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
42
55
|
const [preview, setPreview] = useState<string | null>();
|
|
43
56
|
const [field, meta, helpers] = useField(name);
|
|
@@ -51,10 +64,10 @@ function Upload({
|
|
|
51
64
|
);
|
|
52
65
|
|
|
53
66
|
const errorMessage = meta.error && meta.touched ? meta.error : "";
|
|
54
|
-
const displayError =
|
|
55
|
-
typeof errorMessage === typeof "string" && errorMessage !== "";
|
|
67
|
+
const displayError = typeof errorMessage === "string" && errorMessage !== "";
|
|
56
68
|
|
|
57
69
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
70
|
+
const [nativeFiles, setNativeFiles] = useState<File[] | null>(null);
|
|
58
71
|
const setFiles = useCallback(
|
|
59
72
|
(value: unknown) => {
|
|
60
73
|
helpers.setValue(value);
|
|
@@ -74,7 +87,7 @@ function Upload({
|
|
|
74
87
|
useEffect(() => {
|
|
75
88
|
onFilesSelect?.(files);
|
|
76
89
|
helpers.setValue(files);
|
|
77
|
-
|
|
90
|
+
console.log("useEffect", { files });
|
|
78
91
|
if (!multiple && files && files?.length !== 0) {
|
|
79
92
|
if (isImageOnly) {
|
|
80
93
|
if (withUpload) {
|
|
@@ -104,10 +117,17 @@ function Upload({
|
|
|
104
117
|
}
|
|
105
118
|
handleLoading(true);
|
|
106
119
|
try {
|
|
107
|
-
const imagePreview
|
|
108
|
-
|
|
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
|
+
}
|
|
109
128
|
} catch (error) {
|
|
110
129
|
console.error(error);
|
|
130
|
+
Sentry.captureException(error);
|
|
111
131
|
} finally {
|
|
112
132
|
handleLoading(false);
|
|
113
133
|
}
|
|
@@ -120,11 +140,18 @@ function Upload({
|
|
|
120
140
|
}
|
|
121
141
|
try {
|
|
122
142
|
handleLoading(true);
|
|
123
|
-
const imagePreview
|
|
124
|
-
|
|
125
|
-
|
|
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
|
+
}
|
|
126
152
|
} catch (error) {
|
|
127
153
|
console.error(error);
|
|
154
|
+
Sentry.captureException(error);
|
|
128
155
|
} finally {
|
|
129
156
|
handleLoading(false);
|
|
130
157
|
}
|
|
@@ -152,41 +179,83 @@ function Upload({
|
|
|
152
179
|
setFiles(newArray);
|
|
153
180
|
};
|
|
154
181
|
|
|
155
|
-
const handleChange = (
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
182
|
+
const handleChange = useCallback(
|
|
183
|
+
async (filesArray: File[] | null) => {
|
|
184
|
+
if (!meta.touched) {
|
|
185
|
+
helpers.setTouched(true);
|
|
186
|
+
}
|
|
159
187
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
console.error(error);
|
|
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
|
+
}
|
|
173
200
|
}
|
|
174
201
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
202
|
+
setFiles(filesArray);
|
|
203
|
+
},
|
|
204
|
+
[helpers, maxSize, meta.touched, setFiles]
|
|
205
|
+
);
|
|
178
206
|
|
|
179
207
|
const handleSave = useCallback(
|
|
180
|
-
async (
|
|
208
|
+
async (efiles: File[] | null) => {
|
|
209
|
+
if (!meta.touched) {
|
|
210
|
+
helpers.setTouched(true);
|
|
211
|
+
}
|
|
181
212
|
handleLoading(true);
|
|
182
|
-
const files
|
|
183
|
-
|
|
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);
|
|
184
223
|
},
|
|
185
|
-
[saveToIpfs,
|
|
224
|
+
[meta.touched, handleLoading, saveToIpfs, helpers, setFiles]
|
|
186
225
|
);
|
|
187
|
-
|
|
226
|
+
const saveFn = withUpload ? handleSave : handleChange;
|
|
227
|
+
const style = {
|
|
228
|
+
borderRadius: borderRadius ? `${borderRadius}%` : "",
|
|
229
|
+
width: width ? `100%` : ""
|
|
230
|
+
};
|
|
188
231
|
return (
|
|
189
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
|
+
)}
|
|
190
259
|
<FieldFileUploadWrapper {...wrapperProps} $disabled={!!disabled}>
|
|
191
260
|
<FieldInput
|
|
192
261
|
{...props}
|
|
@@ -194,7 +263,29 @@ function Upload({
|
|
|
194
263
|
type="file"
|
|
195
264
|
accept={accept}
|
|
196
265
|
multiple={multiple}
|
|
197
|
-
onChange={
|
|
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
|
+
}}
|
|
198
289
|
ref={(ref) => {
|
|
199
290
|
inputRef.current = ref;
|
|
200
291
|
}}
|
|
@@ -206,10 +297,10 @@ function Upload({
|
|
|
206
297
|
</ThemedButton>
|
|
207
298
|
) : (
|
|
208
299
|
<FileUploadWrapper
|
|
209
|
-
choosen={files !== null}
|
|
210
300
|
data-disabled={disabled}
|
|
211
301
|
onClick={handleChooseFile}
|
|
212
302
|
error={errorMessage}
|
|
303
|
+
style={style}
|
|
213
304
|
>
|
|
214
305
|
{isLoading ? (
|
|
215
306
|
<Loading size={2} />
|
|
@@ -220,17 +311,22 @@ function Upload({
|
|
|
220
311
|
{isVideoOnly ? (
|
|
221
312
|
<VideoPreview
|
|
222
313
|
src={
|
|
223
|
-
"
|
|
224
|
-
|
|
225
|
-
"data:
|
|
226
|
-
|
|
314
|
+
preview?.startsWith("http")
|
|
315
|
+
? preview
|
|
316
|
+
: "data:video/mp4;base64," +
|
|
317
|
+
preview?.substring(
|
|
318
|
+
"data:application/octet-stream;base64,".length
|
|
319
|
+
)
|
|
227
320
|
}
|
|
228
321
|
autoPlay
|
|
229
322
|
muted
|
|
230
323
|
loop
|
|
231
324
|
/>
|
|
232
325
|
) : (
|
|
233
|
-
<ImagePreview
|
|
326
|
+
<ImagePreview
|
|
327
|
+
style={{ ...imgPreviewStyle }}
|
|
328
|
+
src={preview}
|
|
329
|
+
/>
|
|
234
330
|
)}
|
|
235
331
|
</>
|
|
236
332
|
) : isVideoOnly ? (
|
|
@@ -248,7 +344,7 @@ function Upload({
|
|
|
248
344
|
</FileUploadWrapper>
|
|
249
345
|
)}
|
|
250
346
|
{!disabled && field.value && field.value?.length !== 0 && preview && (
|
|
251
|
-
<div onClick={handleRemoveAllFiles} data-remove>
|
|
347
|
+
<div onClick={handleRemoveAllFiles} data-remove style={style}>
|
|
252
348
|
<Trash size={24} color={colors.white} />
|
|
253
349
|
</div>
|
|
254
350
|
)}
|