@onehat/ui 0.3.29 → 0.3.31
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 +1 -1
- package/src/Components/Buttons/SquareButton.js +58 -0
- package/src/Components/Form/FieldSet.js +79 -10
- package/src/Components/Form/Form.js +22 -4
- package/src/Components/Hoc/withPdfButton.js +48 -19
- package/src/Components/Hoc/withPresetButtons.js +12 -0
- package/src/Components/Hoc/withValue.js +45 -8
- package/src/Components/Viewer/Viewer.js +1 -0
- package/src/Components/index.js +2 -0
- package/src/Contexts/FieldSetContext.js +4 -0
package/package.json
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Icon,
|
|
4
|
+
Pressable,
|
|
5
|
+
Text,
|
|
6
|
+
} from 'native-base';
|
|
7
|
+
import UiGlobals from '../../UiGlobals.js';
|
|
8
|
+
|
|
9
|
+
export default function SquareButton(props) {
|
|
10
|
+
const {
|
|
11
|
+
text,
|
|
12
|
+
isActive = false,
|
|
13
|
+
disableInteractions = false,
|
|
14
|
+
...propsToPass
|
|
15
|
+
} = props,
|
|
16
|
+
styles = UiGlobals.styles,
|
|
17
|
+
color = isActive ? '#fff' : '#000';
|
|
18
|
+
const propsIcon = props._icon || {};
|
|
19
|
+
let icon = props.icon;
|
|
20
|
+
if (!icon) {
|
|
21
|
+
throw Error('icon missing');
|
|
22
|
+
}
|
|
23
|
+
if (!text) {
|
|
24
|
+
throw Error('text missing');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (React.isValidElement(icon)) {
|
|
28
|
+
if (!_.isEmpty(propsIcon)) {
|
|
29
|
+
icon = React.cloneElement(icon, {...propsIcon});
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
icon = <Icon as={icon} {...propsIcon} />;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const
|
|
36
|
+
hoverProps = {},
|
|
37
|
+
pressedProps = {};
|
|
38
|
+
if (!disableInteractions) {
|
|
39
|
+
hoverProps.bg = styles.ICON_BUTTON_BG_HOVER;
|
|
40
|
+
pressedProps.bg = styles.ICON_BUTTON_BG_PRESSED;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return <Pressable
|
|
44
|
+
borderRadius="md"
|
|
45
|
+
flexDirection="column"
|
|
46
|
+
justifyContent="center"
|
|
47
|
+
alignItems="center"
|
|
48
|
+
p={2}
|
|
49
|
+
{...propsToPass}
|
|
50
|
+
bg={isActive ? '#56a6f8' : '#fff'}
|
|
51
|
+
_hover={hoverProps}
|
|
52
|
+
_pressed={pressedProps}
|
|
53
|
+
>
|
|
54
|
+
<Icon as={icon} color={color} size="xl" />
|
|
55
|
+
<Text fontSize={20} color={color}>{text}</Text>
|
|
56
|
+
</Pressable>;
|
|
57
|
+
}
|
|
58
|
+
|
|
@@ -1,28 +1,79 @@
|
|
|
1
|
-
import { useState, } from 'react';
|
|
1
|
+
import { useState, useRef, } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Box,
|
|
4
4
|
Column,
|
|
5
5
|
Row,
|
|
6
6
|
Text,
|
|
7
7
|
} from 'native-base';
|
|
8
|
+
import FieldSetContext from '../../Contexts/FieldSetContext.js';
|
|
9
|
+
import useForceUpdate from '../../Hooks/useForceUpdate.js';
|
|
8
10
|
import UiGlobals from '../../UiGlobals.js';
|
|
9
11
|
import IconButton from '../Buttons/IconButton.js';
|
|
12
|
+
import CheckboxButton from '../Buttons/CheckboxButton.js';
|
|
10
13
|
import CaretUp from '../Icons/CaretUp.js';
|
|
11
14
|
import CaretDown from '../Icons/CaretDown.js';
|
|
15
|
+
import _ from 'lodash';
|
|
12
16
|
|
|
13
17
|
export default function FieldSet(props) {
|
|
14
18
|
const {
|
|
15
19
|
title,
|
|
16
20
|
helpText,
|
|
17
21
|
children,
|
|
22
|
+
isCollapsible = true,
|
|
18
23
|
isCollapsed,
|
|
19
24
|
hasErrors,
|
|
25
|
+
showToggleAllCheckbox = false,
|
|
20
26
|
...propsToPass
|
|
21
27
|
} = props,
|
|
22
28
|
styles = UiGlobals.styles,
|
|
29
|
+
forceUpdate = useForceUpdate(),
|
|
30
|
+
childRefs = useRef([]),
|
|
31
|
+
isAllCheckedRef = useRef(false),
|
|
23
32
|
[localIsCollapsed, setLocalIsCollapsed] = useState(isCollapsed),
|
|
33
|
+
getIsAllChecked = () => {
|
|
34
|
+
return isAllCheckedRef.current;
|
|
35
|
+
},
|
|
36
|
+
setIsAllChecked = (bool) => {
|
|
37
|
+
isAllCheckedRef.current = bool;
|
|
38
|
+
forceUpdate();
|
|
39
|
+
},
|
|
24
40
|
onToggleCollapse = () => {
|
|
25
41
|
setLocalIsCollapsed(!localIsCollapsed);
|
|
42
|
+
},
|
|
43
|
+
onToggleAllChecked = () => {
|
|
44
|
+
const bool = !getIsAllChecked();
|
|
45
|
+
setIsAllChecked(bool);
|
|
46
|
+
|
|
47
|
+
_.each(childRefs.current, (child) => {
|
|
48
|
+
if (child.value !== bool) {
|
|
49
|
+
child.value = bool;
|
|
50
|
+
child.setValue(bool);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
registerChild = (child) => {
|
|
55
|
+
childRefs.current.push(child);
|
|
56
|
+
checkChildren();
|
|
57
|
+
},
|
|
58
|
+
onChangeValue = (value, childRef) => {
|
|
59
|
+
const child = _.find(childRefs.current, child => child.childRef === childRef);
|
|
60
|
+
if (child.value !== value) {
|
|
61
|
+
child.value = value;
|
|
62
|
+
checkChildren();
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
checkChildren = () => {
|
|
66
|
+
let isAllChecked = true;
|
|
67
|
+
_.each(childRefs.current, (child) => {
|
|
68
|
+
if (!child.value) {
|
|
69
|
+
isAllChecked = false;
|
|
70
|
+
return false; // break
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (isAllChecked !== getIsAllChecked()) {
|
|
75
|
+
setIsAllChecked(isAllChecked);
|
|
76
|
+
}
|
|
26
77
|
};
|
|
27
78
|
|
|
28
79
|
return <Box
|
|
@@ -50,16 +101,34 @@ export default function FieldSet(props) {
|
|
|
50
101
|
numberOfLines={1}
|
|
51
102
|
ellipsizeMode="head"
|
|
52
103
|
>{title}</Text>
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
104
|
+
{showToggleAllCheckbox && <Row alignSelf="right">
|
|
105
|
+
<Text
|
|
106
|
+
fontSize={styles.FORM_FIELDSET_FONTSIZE}
|
|
107
|
+
py={1}
|
|
108
|
+
px={3}
|
|
109
|
+
flex={1}
|
|
110
|
+
numberOfLines={1}
|
|
111
|
+
>Toggle All?</Text>
|
|
112
|
+
<CheckboxButton
|
|
113
|
+
isChecked={getIsAllChecked()}
|
|
114
|
+
onPress={onToggleAllChecked}
|
|
115
|
+
_icon={{
|
|
116
|
+
size: 'lg',
|
|
117
|
+
}}
|
|
118
|
+
/>
|
|
119
|
+
</Row>}
|
|
120
|
+
{isCollapsible && <IconButton
|
|
121
|
+
_icon={{
|
|
122
|
+
as: localIsCollapsed ? <CaretDown /> : <CaretUp />,
|
|
123
|
+
size: 'sm',
|
|
124
|
+
color: 'trueGray.300',
|
|
125
|
+
}}
|
|
126
|
+
onPress={onToggleCollapse}
|
|
127
|
+
/>}
|
|
61
128
|
</Row>}
|
|
62
129
|
{helpText && <Text>{helpText}</Text>}
|
|
63
|
-
{!localIsCollapsed &&
|
|
130
|
+
{!localIsCollapsed && <FieldSetContext.Provider value={{ registerChild, onChangeValue, }}>
|
|
131
|
+
{children}
|
|
132
|
+
</FieldSetContext.Provider>}
|
|
64
133
|
</Box>;
|
|
65
134
|
}
|
|
@@ -65,10 +65,12 @@ function Form(props) {
|
|
|
65
65
|
validator, // custom validator, mainly for EDITOR_TYPE__PLAIN
|
|
66
66
|
footerProps = {},
|
|
67
67
|
buttonGroupProps = {}, // buttons in footer
|
|
68
|
+
checkIsEditingDisabled = true,
|
|
68
69
|
onBack,
|
|
69
70
|
onReset,
|
|
70
71
|
onViewMode,
|
|
71
|
-
|
|
72
|
+
submitBtnLabel,
|
|
73
|
+
onSubmit,
|
|
72
74
|
additionalEditButtons = [],
|
|
73
75
|
|
|
74
76
|
// sizing of outer container
|
|
@@ -274,7 +276,7 @@ function Form(props) {
|
|
|
274
276
|
editorTypeProps = {};
|
|
275
277
|
|
|
276
278
|
const propertyDef = name && Repository?.getSchema().getPropertyDefinition(name);
|
|
277
|
-
if (propertyDef?.isEditingDisabled) {
|
|
279
|
+
if (propertyDef?.isEditingDisabled && checkIsEditingDisabled) {
|
|
278
280
|
isEditable = false;
|
|
279
281
|
}
|
|
280
282
|
if (!type) {
|
|
@@ -479,6 +481,13 @@ function Form(props) {
|
|
|
479
481
|
const values = record.submitValues;
|
|
480
482
|
reset(values);
|
|
481
483
|
}
|
|
484
|
+
},
|
|
485
|
+
onSubmitDecorated = async (data, e) => {
|
|
486
|
+
const result = await onSubmit(data, e);
|
|
487
|
+
if (result) {
|
|
488
|
+
const values = record.submitValues;
|
|
489
|
+
reset(values);
|
|
490
|
+
}
|
|
482
491
|
};
|
|
483
492
|
|
|
484
493
|
useEffect(() => {
|
|
@@ -579,9 +588,11 @@ function Form(props) {
|
|
|
579
588
|
break;
|
|
580
589
|
}
|
|
581
590
|
|
|
582
|
-
let isSaveDisabled = false
|
|
591
|
+
let isSaveDisabled = false,
|
|
592
|
+
isSubmitDisabled = false;
|
|
583
593
|
if (!_.isEmpty(formState.errors)) {
|
|
584
594
|
isSaveDisabled = true;
|
|
595
|
+
isSubmitDisabled = true;
|
|
585
596
|
}
|
|
586
597
|
if (_.isEmpty(formState.dirtyFields) && !record?.isRemotePhantom) {
|
|
587
598
|
isSaveDisabled = true;
|
|
@@ -655,7 +666,14 @@ function Form(props) {
|
|
|
655
666
|
onPress={(e) => handleSubmit(onSaveDecorated, onSubmitError)(e)}
|
|
656
667
|
isDisabled={isSaveDisabled}
|
|
657
668
|
color="#fff"
|
|
658
|
-
>{
|
|
669
|
+
>{editorMode === EDITOR_MODE__ADD ? 'Add' : 'Save'}</Button>}
|
|
670
|
+
{onSubmit && <Button
|
|
671
|
+
key="submitBtn"
|
|
672
|
+
onPress={(e) => handleSubmit(onSubmitDecorated, onSubmitError)(e)}
|
|
673
|
+
isDisabled={isSubmitDisabled}
|
|
674
|
+
color="#fff"
|
|
675
|
+
>{submitBtnLabel || 'Submit'}</Button>}
|
|
676
|
+
|
|
659
677
|
{isEditorViewOnly && onClose && editorType !== EDITOR_TYPE__SIDE && <Button
|
|
660
678
|
key="closeBtn"
|
|
661
679
|
onPress={onClose}
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
Column,
|
|
4
4
|
Button,
|
|
5
5
|
Modal,
|
|
6
|
-
Row,
|
|
7
6
|
} from 'native-base';
|
|
7
|
+
import * as yup from 'yup'; // https://github.com/jquense/yup#string
|
|
8
8
|
import Inflector from 'inflector-js';
|
|
9
9
|
import qs from 'qs';
|
|
10
10
|
import FormPanel from '../Panel/FormPanel.js';
|
|
@@ -35,6 +35,10 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
35
35
|
// withData
|
|
36
36
|
Repository,
|
|
37
37
|
model,
|
|
38
|
+
|
|
39
|
+
// withSelection
|
|
40
|
+
selection,
|
|
41
|
+
|
|
38
42
|
} = props,
|
|
39
43
|
[isModalShown, setIsModalShown] = useState(false),
|
|
40
44
|
[width, height] = useAdjustedWindowSize(500, 800);
|
|
@@ -42,27 +46,36 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
42
46
|
const modalItems = _.map(_.cloneDeep(items), (item, ix) => buildNextLayer(item, ix, columnDefaults)); // clone, as we don't want to alter the item by reference
|
|
43
47
|
|
|
44
48
|
if (!_.isEmpty(ancillaryItems)) {
|
|
49
|
+
const
|
|
50
|
+
ancillaryItemsClone = _.cloneDeep(ancillaryItems),
|
|
51
|
+
items = [];
|
|
52
|
+
_.each(ancillaryItemsClone, (ancillaryItem) => { // clone, as we don't want to alter the item by reference
|
|
53
|
+
let name;
|
|
54
|
+
if (ancillaryItem.model) {
|
|
55
|
+
name = Inflector.underscore(ancillaryItem.model);
|
|
56
|
+
} else {
|
|
57
|
+
name = ancillaryItem.title;
|
|
58
|
+
}
|
|
59
|
+
if (!inArray(name, ['Photos', 'Videos', 'Files'])) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
name = 'ancillary___' + name;
|
|
63
|
+
items.push({
|
|
64
|
+
title: ancillaryItem.title,
|
|
65
|
+
label: ancillaryItem.title,
|
|
66
|
+
name,
|
|
67
|
+
type: 'Checkbox',
|
|
68
|
+
});
|
|
69
|
+
});
|
|
45
70
|
modalItems.push({
|
|
46
71
|
type: 'FieldSet',
|
|
47
72
|
title: 'Ancillary Items',
|
|
48
73
|
defaults: {
|
|
49
74
|
labelWidth: '90%',
|
|
50
75
|
},
|
|
51
|
-
items
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
name = Inflector.underscore(ancillaryItem.model);
|
|
55
|
-
} else {
|
|
56
|
-
name = ancillaryItem.title;
|
|
57
|
-
}
|
|
58
|
-
name = 'ancillary___' + name;
|
|
59
|
-
return {
|
|
60
|
-
title: ancillaryItem.title,
|
|
61
|
-
label: ancillaryItem.title,
|
|
62
|
-
name,
|
|
63
|
-
type: 'Checkbox',
|
|
64
|
-
};
|
|
65
|
-
}),
|
|
76
|
+
items,
|
|
77
|
+
showToggleAllCheckbox: true,
|
|
78
|
+
isCollapsible: false,
|
|
66
79
|
});
|
|
67
80
|
}
|
|
68
81
|
|
|
@@ -78,6 +91,10 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
78
91
|
if (!item.defaults) {
|
|
79
92
|
item.defaults = {};
|
|
80
93
|
}
|
|
94
|
+
if (type === 'FieldSet') {
|
|
95
|
+
item.showToggleAllCheckbox = true;
|
|
96
|
+
item.isCollapsible = false;
|
|
97
|
+
}
|
|
81
98
|
item.defaults.labelWidth = '90%';
|
|
82
99
|
if (!_.isEmpty(items)) {
|
|
83
100
|
const defaults = item.defaults;
|
|
@@ -97,6 +114,12 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
97
114
|
item.type = 'Checkbox';
|
|
98
115
|
return item;
|
|
99
116
|
},
|
|
117
|
+
buildValidator = (modalItems) => {
|
|
118
|
+
|
|
119
|
+
// TODO: Build a real validator that checks all modalItems as booleans
|
|
120
|
+
|
|
121
|
+
return yup.object();
|
|
122
|
+
},
|
|
100
123
|
getStartingValues = (modalItems) => {
|
|
101
124
|
const startingValues = {};
|
|
102
125
|
function walkTree(item) {
|
|
@@ -117,9 +140,12 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
117
140
|
return startingValues;
|
|
118
141
|
},
|
|
119
142
|
getPdf = (data) => {
|
|
143
|
+
data.id = selection[0].id;
|
|
144
|
+
|
|
120
145
|
const
|
|
121
146
|
url = UiGlobals.baseURL + model + '/viewPdf?',
|
|
122
147
|
queryString = qs.stringify(data);
|
|
148
|
+
|
|
123
149
|
window.open(url + queryString, '_blank');
|
|
124
150
|
};
|
|
125
151
|
|
|
@@ -142,7 +168,8 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
142
168
|
if (isModalShown) {
|
|
143
169
|
const
|
|
144
170
|
modalItems = buildModalItems(),
|
|
145
|
-
startingValues = getStartingValues(modalItems)
|
|
171
|
+
startingValues = getStartingValues(modalItems),
|
|
172
|
+
validator = buildValidator(modalItems);
|
|
146
173
|
modal = <Modal
|
|
147
174
|
isOpen={true}
|
|
148
175
|
onClose={() => setIsModalShown(false)}
|
|
@@ -156,14 +183,16 @@ export default function withPdfButton(WrappedComponent) {
|
|
|
156
183
|
Repository={Repository}
|
|
157
184
|
items={modalItems}
|
|
158
185
|
startingValues={startingValues}
|
|
186
|
+
validator={validator}
|
|
187
|
+
checkIsEditingDisabled={false}
|
|
159
188
|
onCancel={(e) => {
|
|
160
189
|
setIsModalShown(false);
|
|
161
190
|
}}
|
|
162
|
-
|
|
191
|
+
onSubmit={(data, e) => {
|
|
163
192
|
getPdf(data);
|
|
164
193
|
setIsModalShown(false);
|
|
165
194
|
}}
|
|
166
|
-
|
|
195
|
+
submitBtnLabel="View PDF"
|
|
167
196
|
/>
|
|
168
197
|
</Column>
|
|
169
198
|
</Modal>;
|
|
@@ -35,6 +35,9 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
35
35
|
contextMenuItems,
|
|
36
36
|
additionalToolbarButtons,
|
|
37
37
|
onChangeColumnsConfig,
|
|
38
|
+
verifyCanEdit,
|
|
39
|
+
verifyCanDelete,
|
|
40
|
+
verifyCanDuplicate,
|
|
38
41
|
...propsToPass
|
|
39
42
|
} = props,
|
|
40
43
|
{
|
|
@@ -146,6 +149,9 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
146
149
|
if (_.isEmpty(selection) || (_.isArray(selection) && selection.length > 1)) {
|
|
147
150
|
isDisabled = true;
|
|
148
151
|
}
|
|
152
|
+
if (verifyCanEdit && !verifyCanEdit(selection)) {
|
|
153
|
+
isDisabled = true;
|
|
154
|
+
}
|
|
149
155
|
break;
|
|
150
156
|
case 'delete':
|
|
151
157
|
text = 'Delete';
|
|
@@ -157,6 +163,9 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
157
163
|
if (_.isEmpty(selection) || (_.isArray(selection) && selection.length > 1)) {
|
|
158
164
|
isDisabled = true;
|
|
159
165
|
}
|
|
166
|
+
if (verifyCanDelete && !verifyCanDelete(selection)) {
|
|
167
|
+
isDisabled = true;
|
|
168
|
+
}
|
|
160
169
|
break;
|
|
161
170
|
case 'view':
|
|
162
171
|
text = 'View';
|
|
@@ -193,6 +202,9 @@ export default function withPresetButtons(WrappedComponent, isGrid = false) {
|
|
|
193
202
|
if (_.isEmpty(selection) || selection.length > 1) {
|
|
194
203
|
isDisabled = true;
|
|
195
204
|
}
|
|
205
|
+
if (verifyCanDuplicate && !verifyCanDuplicate(selection)) {
|
|
206
|
+
isDisabled = true;
|
|
207
|
+
}
|
|
196
208
|
break;
|
|
197
209
|
// case 'print':
|
|
198
210
|
// text = 'Print';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { useState, useEffect, } from 'react';
|
|
1
|
+
import { useState, useEffect, useRef, useContext, useCallback, } from 'react';
|
|
2
2
|
import natsort from 'natsort';
|
|
3
|
+
import useForceUpdate from '../../Hooks/useForceUpdate.js';
|
|
4
|
+
import FieldSetContext from '../../Contexts/FieldSetContext.js';
|
|
3
5
|
import _ from 'lodash';
|
|
4
6
|
|
|
5
7
|
// This HOC gives the component value props, primarily for a Form Field.
|
|
@@ -27,8 +29,23 @@ export default function withValue(WrappedComponent) {
|
|
|
27
29
|
Repository,
|
|
28
30
|
idIx,
|
|
29
31
|
} = props,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
forceUpdate = useForceUpdate(),
|
|
33
|
+
childRef = useRef({}),
|
|
34
|
+
onChangeValueRef = useRef(),
|
|
35
|
+
localValueRef = useRef(startingValue || value),
|
|
36
|
+
fieldSetOnChangeValueRef = useRef(),
|
|
37
|
+
fieldSetContext = useContext(FieldSetContext),
|
|
38
|
+
fieldSetRegisterChild = fieldSetContext?.registerChild,
|
|
39
|
+
fieldSetOnChangeValue = fieldSetContext?.onChangeValue,
|
|
40
|
+
getLocalValue = () => {
|
|
41
|
+
return localValueRef.current;
|
|
42
|
+
},
|
|
43
|
+
setLocalValue = (value) => {
|
|
44
|
+
localValueRef.current = value;
|
|
45
|
+
forceUpdate();
|
|
46
|
+
},
|
|
47
|
+
setValueRef = useRef((newValue) => {
|
|
48
|
+
// NOTE: We useRef so that this function stays current after renders
|
|
32
49
|
if (valueIsAlwaysArray && !_.isArray(newValue)) {
|
|
33
50
|
newValue = _.isNil(newValue) ? [] : [newValue];
|
|
34
51
|
}
|
|
@@ -62,15 +79,21 @@ export default function withValue(WrappedComponent) {
|
|
|
62
79
|
newValue = JSON.stringify(newValue);
|
|
63
80
|
}
|
|
64
81
|
|
|
65
|
-
if (newValue ===
|
|
82
|
+
if (newValue === getLocalValue()) {
|
|
66
83
|
return;
|
|
67
84
|
}
|
|
68
85
|
|
|
69
86
|
setLocalValue(newValue);
|
|
70
87
|
|
|
71
|
-
if (
|
|
72
|
-
|
|
88
|
+
if (onChangeValueRef.current) {
|
|
89
|
+
onChangeValueRef.current(newValue, childRef.current);
|
|
73
90
|
}
|
|
91
|
+
if (fieldSetOnChangeValueRef.current) {
|
|
92
|
+
fieldSetOnChangeValueRef.current(newValue, childRef.current);
|
|
93
|
+
}
|
|
94
|
+
}),
|
|
95
|
+
setValue = (args) => {
|
|
96
|
+
setValueRef.current(args);
|
|
74
97
|
},
|
|
75
98
|
onChangeSelection = (selection) => {
|
|
76
99
|
let value = null,
|
|
@@ -96,15 +119,29 @@ export default function withValue(WrappedComponent) {
|
|
|
96
119
|
setValue(value);
|
|
97
120
|
};
|
|
98
121
|
|
|
122
|
+
// Ensure these passed functions stay current after render
|
|
123
|
+
onChangeValueRef.current = onChangeValue;
|
|
124
|
+
fieldSetOnChangeValueRef.current = fieldSetOnChangeValue;
|
|
125
|
+
|
|
99
126
|
useEffect(() => {
|
|
100
|
-
if (!_.isEqual(value,
|
|
127
|
+
if (!_.isEqual(value, getLocalValue())) {
|
|
101
128
|
setLocalValue(value);
|
|
102
129
|
}
|
|
103
130
|
}, [value]);
|
|
104
131
|
|
|
132
|
+
if (fieldSetRegisterChild) {
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
fieldSetRegisterChild({
|
|
135
|
+
childRef: childRef.current,
|
|
136
|
+
value,
|
|
137
|
+
setValue: setValueRef.current,
|
|
138
|
+
});
|
|
139
|
+
}, []);
|
|
140
|
+
}
|
|
141
|
+
|
|
105
142
|
|
|
106
143
|
// Convert localValue to normal JS primitives for field components
|
|
107
|
-
let convertedValue =
|
|
144
|
+
let convertedValue = getLocalValue();
|
|
108
145
|
if (_.isString(convertedValue) && valueAsStringifiedJson && !_.isNil(convertedValue)) {
|
|
109
146
|
convertedValue = JSON.parse(convertedValue);
|
|
110
147
|
}
|
package/src/Components/index.js
CHANGED
|
@@ -37,6 +37,7 @@ import Panel from './Panel/Panel.js';
|
|
|
37
37
|
// import Picker from '../Components/Panel/Picker.js';
|
|
38
38
|
import PlusMinusButton from './Buttons/PlusMinusButton.js';
|
|
39
39
|
import RadioGroup from './Form/Field/RadioGroup/RadioGroup.js';
|
|
40
|
+
import SquareButton from './Buttons/SquareButton.js';
|
|
40
41
|
import TabPanel from './Panel/TabPanel.js';
|
|
41
42
|
import Tag from './Form/Field/Combo/Tag.js';
|
|
42
43
|
import TagViewer from './Viewer/TagViewer.js';
|
|
@@ -88,6 +89,7 @@ const components = {
|
|
|
88
89
|
// Picker,
|
|
89
90
|
PlusMinusButton,
|
|
90
91
|
RadioGroup,
|
|
92
|
+
SquareButton,
|
|
91
93
|
TabPanel,
|
|
92
94
|
Tag,
|
|
93
95
|
TagViewer,
|