@onehat/ui 0.3.320 → 0.3.322
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/package.json
CHANGED
|
@@ -82,6 +82,8 @@ function Form(props) {
|
|
|
82
82
|
onReset,
|
|
83
83
|
onInit,
|
|
84
84
|
onViewMode,
|
|
85
|
+
onValidityChange,
|
|
86
|
+
onDirtyChange,
|
|
85
87
|
submitBtnLabel,
|
|
86
88
|
onSubmit,
|
|
87
89
|
formSetup, // this fn will be executed after the form setup is complete
|
|
@@ -807,6 +809,18 @@ function Form(props) {
|
|
|
807
809
|
};
|
|
808
810
|
}, [Repository]);
|
|
809
811
|
|
|
812
|
+
if (onValidityChange) {
|
|
813
|
+
useEffect(() => {
|
|
814
|
+
onValidityChange(formState.isValid);
|
|
815
|
+
}, [formState.isValid]);
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
if (onDirtyChange) {
|
|
819
|
+
useEffect(() => {
|
|
820
|
+
onDirtyChange(formState.isDirty);
|
|
821
|
+
}, [formState.isDirty]);
|
|
822
|
+
}
|
|
823
|
+
|
|
810
824
|
if (skipAll) {
|
|
811
825
|
return null;
|
|
812
826
|
}
|
|
@@ -821,6 +835,8 @@ function Form(props) {
|
|
|
821
835
|
|
|
822
836
|
if (self) {
|
|
823
837
|
self.ref = formRef;
|
|
838
|
+
self.reset = doReset;
|
|
839
|
+
self.submit = handleSubmit;
|
|
824
840
|
self.formState = formState;
|
|
825
841
|
self.formSetValue = formSetValue;
|
|
826
842
|
self.formGetValues = formGetValues;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useRef
|
|
1
|
+
import React, { useState, useRef } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Box,
|
|
4
4
|
Button,
|
|
@@ -8,7 +8,10 @@ import {
|
|
|
8
8
|
Row,
|
|
9
9
|
Text,
|
|
10
10
|
} from 'native-base';
|
|
11
|
+
import Form from '../Form/Form.js';
|
|
11
12
|
import Panel from '../Panel/Panel.js';
|
|
13
|
+
import IconButton from '../Buttons/IconButton.js';
|
|
14
|
+
import Rotate from '../Icons/Rotate.js';
|
|
12
15
|
import TriangleExclamation from '../Icons/TriangleExclamation.js';
|
|
13
16
|
import useAdjustedWindowSize from '../../Hooks/useAdjustedWindowSize.js';
|
|
14
17
|
import testProps from '../../Functions/testProps.js';
|
|
@@ -31,19 +34,36 @@ export default function withModal(WrappedComponent) {
|
|
|
31
34
|
[message, setMessage] = useState(''),
|
|
32
35
|
[canClose, setCanClose] = useState(true),
|
|
33
36
|
[includeCancel, setIncludeCancel] = useState(false),
|
|
37
|
+
[includeReset, setIncludeReset] = useState(false),
|
|
34
38
|
[isModalShown, setIsModalShown] = useState(false),
|
|
39
|
+
[isValid, setIsValid] = useState(false),
|
|
40
|
+
[isDirty, setIsDirty] = useState(false),
|
|
35
41
|
[h, setHeight] = useState(250),
|
|
36
42
|
[w, setWidth] = useState(400),
|
|
37
43
|
[onOk, setOnOk] = useState(),
|
|
38
44
|
[okBtnLabel, setOkBtnLabel] = useState('OK'),
|
|
39
45
|
[onYes, setOnYes] = useState(),
|
|
40
46
|
[onNo, setOnNo] = useState(),
|
|
47
|
+
[onSubmit, setOnSubmit] = useState(),
|
|
48
|
+
[submitBtnLabel, setSubmitBtnLabel] = useState(),
|
|
41
49
|
[customButtons, setCustomButtons] = useState(),
|
|
50
|
+
[formProps, setFormProps] = useState(),
|
|
51
|
+
[self, setSelf] = useState(),
|
|
42
52
|
[color, setColor] = useState('#000'),
|
|
43
53
|
[body, setBody] = useState(),
|
|
54
|
+
useForm = !!formProps, // convenience flag
|
|
44
55
|
autoFocusRef = useRef(null),
|
|
45
56
|
cancelRef = useRef(null),
|
|
46
57
|
[width, height] = useAdjustedWindowSize(w, h),
|
|
58
|
+
onValidityChange = (isValid) => {
|
|
59
|
+
setIsValid(isValid);
|
|
60
|
+
},
|
|
61
|
+
onDirtyChange = (isDirty) => {
|
|
62
|
+
setIsDirty(isDirty);
|
|
63
|
+
},
|
|
64
|
+
onReset = () => {
|
|
65
|
+
self?.children?.ModalForm?.reset();
|
|
66
|
+
},
|
|
47
67
|
onCancel = () => {
|
|
48
68
|
setIsModalShown(false);
|
|
49
69
|
},
|
|
@@ -51,35 +71,41 @@ export default function withModal(WrappedComponent) {
|
|
|
51
71
|
const {
|
|
52
72
|
title = '',
|
|
53
73
|
message = '',
|
|
74
|
+
body,
|
|
54
75
|
canClose = true,
|
|
55
76
|
includeCancel = false,
|
|
56
77
|
onOk,
|
|
57
78
|
okBtnLabel,
|
|
58
79
|
onYes,
|
|
59
80
|
onNo,
|
|
81
|
+
onSubmit,
|
|
82
|
+
submitBtnLabel,
|
|
60
83
|
customButtons,
|
|
84
|
+
includeReset = false,
|
|
85
|
+
formProps,
|
|
86
|
+
self,
|
|
61
87
|
color,
|
|
62
|
-
// formItems = {},
|
|
63
|
-
body,
|
|
64
88
|
h,
|
|
65
89
|
w,
|
|
66
90
|
} = args;
|
|
67
91
|
|
|
68
|
-
if (!message && !body) {
|
|
69
|
-
throw new Error('Either message or
|
|
92
|
+
if (!message && !body && !formProps) {
|
|
93
|
+
throw new Error('Either message, body, or formProps is required for showModal');
|
|
94
|
+
}
|
|
95
|
+
if (includeReset && !self) {
|
|
96
|
+
throw new Error('self is required when using includeReset');
|
|
70
97
|
}
|
|
71
|
-
|
|
72
98
|
if (title) {
|
|
73
99
|
setTitle(title);
|
|
74
100
|
}
|
|
75
101
|
if (message) {
|
|
76
102
|
setMessage(message);
|
|
77
103
|
}
|
|
104
|
+
if (body) {
|
|
105
|
+
setBody(body);
|
|
106
|
+
}
|
|
78
107
|
setCanClose(canClose);
|
|
79
108
|
setIncludeCancel(includeCancel);
|
|
80
|
-
if (onNo) {
|
|
81
|
-
setOnNo(() => onNo);
|
|
82
|
-
}
|
|
83
109
|
if (onOk) {
|
|
84
110
|
setOnOk(() => onOk);
|
|
85
111
|
}
|
|
@@ -89,15 +115,28 @@ export default function withModal(WrappedComponent) {
|
|
|
89
115
|
if (onYes) {
|
|
90
116
|
setOnYes(() => onYes);
|
|
91
117
|
}
|
|
118
|
+
if (onNo) {
|
|
119
|
+
setOnNo(() => onNo);
|
|
120
|
+
}
|
|
121
|
+
if (onSubmit) {
|
|
122
|
+
setOnSubmit(() => onSubmit);
|
|
123
|
+
}
|
|
124
|
+
if (submitBtnLabel) {
|
|
125
|
+
setSubmitBtnLabel(submitBtnLabel);
|
|
126
|
+
}
|
|
92
127
|
if (customButtons) {
|
|
93
128
|
setCustomButtons(customButtons);
|
|
94
129
|
}
|
|
130
|
+
setIncludeReset(includeReset);
|
|
131
|
+
if (formProps) {
|
|
132
|
+
setFormProps(formProps);
|
|
133
|
+
}
|
|
134
|
+
if (self) {
|
|
135
|
+
setSelf(self);
|
|
136
|
+
}
|
|
95
137
|
if (color) {
|
|
96
138
|
setColor(color);
|
|
97
139
|
}
|
|
98
|
-
if (body) {
|
|
99
|
-
setBody(body);
|
|
100
|
-
}
|
|
101
140
|
if (h) {
|
|
102
141
|
setHeight(h);
|
|
103
142
|
}
|
|
@@ -111,6 +150,19 @@ export default function withModal(WrappedComponent) {
|
|
|
111
150
|
let buttons = [];
|
|
112
151
|
if (isModalShown) {
|
|
113
152
|
// assemble buttons
|
|
153
|
+
if (includeReset) {
|
|
154
|
+
buttons.push(<IconButton
|
|
155
|
+
{...testProps('resetBtn')}
|
|
156
|
+
key="resetBtn"
|
|
157
|
+
onPress={onReset}
|
|
158
|
+
icon={Rotate}
|
|
159
|
+
_icon={{
|
|
160
|
+
color: !isDirty ? 'trueGray.400' : '#000',
|
|
161
|
+
}}
|
|
162
|
+
isDisabled={!isDirty}
|
|
163
|
+
mr={2}
|
|
164
|
+
/>);
|
|
165
|
+
}
|
|
114
166
|
if (includeCancel) {
|
|
115
167
|
buttons.push(<Button
|
|
116
168
|
{...testProps('cancelBtn')}
|
|
@@ -147,6 +199,15 @@ export default function withModal(WrappedComponent) {
|
|
|
147
199
|
onPress={onYes}
|
|
148
200
|
>Yes</Button>);
|
|
149
201
|
}
|
|
202
|
+
if (useForm && onSubmit) {
|
|
203
|
+
buttons.push(<Button
|
|
204
|
+
{...testProps('submitBtn')}
|
|
205
|
+
key="submitBtn"
|
|
206
|
+
onPress={onSubmit}
|
|
207
|
+
isDisabled={!isValid}
|
|
208
|
+
color="#fff"
|
|
209
|
+
>{submitBtnLabel || 'Submit'}</Button>);
|
|
210
|
+
}
|
|
150
211
|
if (customButtons) {
|
|
151
212
|
_.each(customButtons, (button) => {
|
|
152
213
|
buttons.push(button);
|
|
@@ -154,6 +215,25 @@ export default function withModal(WrappedComponent) {
|
|
|
154
215
|
}
|
|
155
216
|
}
|
|
156
217
|
|
|
218
|
+
let modalBody = null;
|
|
219
|
+
if (useForm) {
|
|
220
|
+
modalBody = <Form
|
|
221
|
+
{...formProps}
|
|
222
|
+
reference="ModalForm"
|
|
223
|
+
onValidityChange={onValidityChange}
|
|
224
|
+
onDirtyChange={onDirtyChange}
|
|
225
|
+
/>;
|
|
226
|
+
} else if (body) {
|
|
227
|
+
modalBody = body;
|
|
228
|
+
} else {
|
|
229
|
+
modalBody = <>
|
|
230
|
+
<Box w="50px" mx={2}>
|
|
231
|
+
<Icon as={TriangleExclamation} color={color} size="10" />
|
|
232
|
+
</Box>
|
|
233
|
+
<Text flex={1} color={color} fontSize="18px">{message}</Text>
|
|
234
|
+
</>;
|
|
235
|
+
}
|
|
236
|
+
|
|
157
237
|
return <>
|
|
158
238
|
<WrappedComponent
|
|
159
239
|
{...props}
|
|
@@ -185,13 +265,7 @@ export default function withModal(WrappedComponent) {
|
|
|
185
265
|
borderRadius={5}
|
|
186
266
|
flexDirection="row"
|
|
187
267
|
>
|
|
188
|
-
{
|
|
189
|
-
<>
|
|
190
|
-
<Box w="50px" mx={2}>
|
|
191
|
-
<Icon as={TriangleExclamation} color={color} size="10" />
|
|
192
|
-
</Box>
|
|
193
|
-
<Text flex={1} color={color} fontSize="18px">{message}</Text>
|
|
194
|
-
</>}
|
|
268
|
+
{modalBody}
|
|
195
269
|
</Modal.Body>
|
|
196
270
|
<Modal.Footer py={2} pr={4} justifyContent="flex-end">
|
|
197
271
|
{buttons}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import * as yup from 'yup';
|
|
2
|
+
import _ from 'lodash';
|
|
2
3
|
|
|
3
|
-
export default function json() {
|
|
4
|
+
export default function json(isRequired = false) {
|
|
4
5
|
return yup.mixed().test(
|
|
5
6
|
'is-json',
|
|
6
7
|
'${path} is not valid JSON',
|
|
7
8
|
value => {
|
|
8
9
|
try {
|
|
9
|
-
JSON.parse(value);
|
|
10
|
-
|
|
10
|
+
const json = JSON.parse(value);
|
|
11
|
+
// Valid JSON
|
|
12
|
+
if (isRequired && _.isEmpty(json)) {
|
|
13
|
+
return false; // Empty JSON
|
|
14
|
+
}
|
|
15
|
+
return true;
|
|
11
16
|
} catch (error) {
|
|
12
17
|
return false; // Invalid JSON
|
|
13
18
|
}
|