@onehat/ui 0.3.237 → 0.3.240
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/Form/Field/CKEditor/CKEditor.js +3 -4
- package/src/Components/Form/Field/Input.js +1 -4
- package/src/Components/Form/Field/Number.js +2 -4
- package/src/Components/Form/Field/TextArea.js +42 -5
- package/src/Components/Form/Form.js +41 -27
- package/src/Components/Hoc/withInlineEditor.js +30 -34
- package/src/UiGlobals.js +3 -0
- package/src/Constants/Input.js +0 -1
package/package.json
CHANGED
|
@@ -2,9 +2,7 @@ import React, { useState, useEffect, useRef, } from 'react';
|
|
|
2
2
|
import {
|
|
3
3
|
Row,
|
|
4
4
|
} from 'native-base';
|
|
5
|
-
import
|
|
6
|
-
AUTO_SUBMIT_DELAY,
|
|
7
|
-
} from '../../../../Constants/Input.js';
|
|
5
|
+
import UiGlobals from '../../../../UiGlobals.js';
|
|
8
6
|
import { CKEditor } from '@ckeditor/ckeditor5-react'; // https://ckeditor.com/docs/ckeditor5/latest/installation/frameworks/react.html
|
|
9
7
|
import './ckeditor.css';
|
|
10
8
|
import Editor from '../../../../../ckeditor5/build/ckeditor.js'; // built using https://ckeditor.com/ckeditor-5/online-builder/
|
|
@@ -19,6 +17,7 @@ const
|
|
|
19
17
|
const {
|
|
20
18
|
value,
|
|
21
19
|
setValue,
|
|
20
|
+
autoSubmitDelay = UiGlobals.autoSubmitDelay,
|
|
22
21
|
h = 150,
|
|
23
22
|
} = props,
|
|
24
23
|
debouncedSetValueRef = useRef(),
|
|
@@ -30,7 +29,7 @@ const
|
|
|
30
29
|
useEffect(() => {
|
|
31
30
|
// Set up debounce fn
|
|
32
31
|
// Have to do this because otherwise, lodash tries to create a debounced version of the fn from only this render
|
|
33
|
-
debouncedSetValueRef.current = _.debounce(setValue,
|
|
32
|
+
debouncedSetValueRef.current = _.debounce(setValue, autoSubmitDelay);
|
|
34
33
|
}, [setValue]);
|
|
35
34
|
|
|
36
35
|
return <Row h={h} flex={1} ref={props.outerRef} {...props}>
|
|
@@ -3,9 +3,6 @@ import {
|
|
|
3
3
|
Input,
|
|
4
4
|
Tooltip,
|
|
5
5
|
} from 'native-base';
|
|
6
|
-
import {
|
|
7
|
-
AUTO_SUBMIT_DELAY,
|
|
8
|
-
} from '../../../Constants/Input.js';
|
|
9
6
|
import UiGlobals from '../../../UiGlobals.js';
|
|
10
7
|
import withComponent from '../../Hoc/withComponent.js';
|
|
11
8
|
import withValue from '../../Hoc/withValue.js';
|
|
@@ -16,7 +13,7 @@ function InputElement(props) {
|
|
|
16
13
|
value,
|
|
17
14
|
setValue,
|
|
18
15
|
autoSubmit = true, // automatically setValue after user stops typing for autoSubmitDelay
|
|
19
|
-
autoSubmitDelay =
|
|
16
|
+
autoSubmitDelay = UiGlobals.autoSubmitDelay,
|
|
20
17
|
autoCapitalize = 'none',
|
|
21
18
|
maxLength,
|
|
22
19
|
onKeyPress,
|
|
@@ -5,9 +5,6 @@ import {
|
|
|
5
5
|
Input,
|
|
6
6
|
Row,
|
|
7
7
|
} from 'native-base';
|
|
8
|
-
import {
|
|
9
|
-
AUTO_SUBMIT_DELAY,
|
|
10
|
-
} from '../../../Constants/Input.js';
|
|
11
8
|
import UiGlobals from '../../../UiGlobals.js';
|
|
12
9
|
import IconButton from '../../Buttons/IconButton.js';
|
|
13
10
|
import withComponent from '../../Hoc/withComponent.js';
|
|
@@ -25,6 +22,7 @@ function NumberElement(props) {
|
|
|
25
22
|
setValue,
|
|
26
23
|
minValue,
|
|
27
24
|
maxValue,
|
|
25
|
+
autoSubmitDelay = UiGlobals.autoSubmitDelay,
|
|
28
26
|
tooltip = null,
|
|
29
27
|
isDisabled = false,
|
|
30
28
|
} = props,
|
|
@@ -94,7 +92,7 @@ function NumberElement(props) {
|
|
|
94
92
|
useEffect(() => {
|
|
95
93
|
// Set up debounce fn
|
|
96
94
|
// Have to do this because otherwise, lodash tries to create a debounced version of the fn from only this render
|
|
97
|
-
debouncedSetValueRef.current = _.debounce(setValue,
|
|
95
|
+
debouncedSetValueRef.current = _.debounce(setValue, autoSubmitDelay);
|
|
98
96
|
}, [setValue]);
|
|
99
97
|
|
|
100
98
|
useEffect(() => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState, useEffect, useRef, } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
TextArea,
|
|
4
4
|
} from 'native-base';
|
|
@@ -10,12 +10,49 @@ import _ from 'lodash';
|
|
|
10
10
|
|
|
11
11
|
const
|
|
12
12
|
TextAreaElement = (props) => {
|
|
13
|
-
|
|
13
|
+
let { // so localValue can be changed, if needed
|
|
14
|
+
setValue,
|
|
15
|
+
autoSubmit = true, // automatically setValue after user stops typing for autoSubmitDelay
|
|
16
|
+
autoSubmitDelay = UiGlobals.autoSubmitDelay,
|
|
17
|
+
onChangeText,
|
|
18
|
+
} = props,
|
|
19
|
+
value = _.isNil(props.value) ? '' : props.value, // null value may not actually reset this TextArea, so set it explicitly to empty string
|
|
14
20
|
styles = UiGlobals.styles,
|
|
15
|
-
|
|
21
|
+
debouncedSetValueRef = useRef(),
|
|
22
|
+
[localValue, setLocalValue] = useState(value),
|
|
23
|
+
onChangeTextLocal = (value) => {
|
|
24
|
+
if (value === '') {
|
|
25
|
+
value = null; // empty string makes value null
|
|
26
|
+
}
|
|
27
|
+
setLocalValue(value);
|
|
28
|
+
if (autoSubmit) {
|
|
29
|
+
debouncedSetValueRef.current(value);
|
|
30
|
+
}
|
|
31
|
+
if (onChangeText) {
|
|
32
|
+
onChangeText(value);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
// Set up debounce fn
|
|
38
|
+
// Have to do this because otherwise, lodash tries to create a debounced version of the fn from only this render
|
|
39
|
+
debouncedSetValueRef.current = _.debounce(setValue, autoSubmitDelay);
|
|
40
|
+
}, [setValue]);
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
|
|
44
|
+
// Make local value conform to externally changed value
|
|
45
|
+
setLocalValue(value);
|
|
46
|
+
|
|
47
|
+
}, [value]);
|
|
48
|
+
|
|
49
|
+
if (localValue === null || typeof localValue === 'undefined') {
|
|
50
|
+
localValue = ''; // If the value is null or undefined, don't let this be an uncontrolled input
|
|
51
|
+
}
|
|
52
|
+
|
|
16
53
|
return <TextArea
|
|
17
54
|
ref={props.outerRef}
|
|
18
|
-
onChangeText={
|
|
55
|
+
onChangeText={onChangeTextLocal}
|
|
19
56
|
flex={1}
|
|
20
57
|
bg={styles.FORM_TEXTAREA_BG}
|
|
21
58
|
_focus={{
|
|
@@ -24,7 +61,7 @@ const
|
|
|
24
61
|
fontSize={styles.FORM_TEXTAREA_FONTSIZE}
|
|
25
62
|
h={styles.FORM_TEXTAREA_HEIGHT}
|
|
26
63
|
{...props}
|
|
27
|
-
value={
|
|
64
|
+
value={localValue}
|
|
28
65
|
/>;
|
|
29
66
|
},
|
|
30
67
|
TextAreaField = withComponent(withValue(TextAreaElement));
|
|
@@ -237,7 +237,7 @@ function Form(props) {
|
|
|
237
237
|
let editorProps = {};
|
|
238
238
|
if (!editor) {
|
|
239
239
|
const propertyDef = fieldName && Repository?.getSchema().getPropertyDefinition(fieldName);
|
|
240
|
-
editor = propertyDef
|
|
240
|
+
editor = propertyDef?.editorType;
|
|
241
241
|
if (_.isPlainObject(editor)) {
|
|
242
242
|
const {
|
|
243
243
|
type,
|
|
@@ -248,6 +248,13 @@ function Form(props) {
|
|
|
248
248
|
editor = type;
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
|
+
if (!editor) {
|
|
252
|
+
editor = 'Text';
|
|
253
|
+
}
|
|
254
|
+
if (!editor.match(/Toggle/)) {
|
|
255
|
+
editorProps.h = '40px'; // Toggle height gets applied incorrectly; just skip it
|
|
256
|
+
}
|
|
257
|
+
|
|
251
258
|
const Element = getComponentFromType(editor);
|
|
252
259
|
|
|
253
260
|
if (useSelectorId) {
|
|
@@ -258,19 +265,20 @@ function Form(props) {
|
|
|
258
265
|
let element = <Element
|
|
259
266
|
name={name}
|
|
260
267
|
value={value}
|
|
261
|
-
|
|
268
|
+
onChangeValue={(newValue) => {
|
|
269
|
+
if (newValue === undefined) {
|
|
270
|
+
newValue = null; // React Hook Form doesn't respond well when setting value to undefined
|
|
271
|
+
}
|
|
262
272
|
onChange(newValue);
|
|
263
|
-
if (onEditorChange) {
|
|
273
|
+
if (typeof onEditorChange !== 'undefined' && onEditorChange) {
|
|
264
274
|
onEditorChange(newValue, formSetValue, formGetValues, formState);
|
|
265
275
|
}
|
|
266
276
|
}}
|
|
267
277
|
onBlur={onBlur}
|
|
268
278
|
flex={1}
|
|
269
|
-
{...editorProps}
|
|
270
279
|
parent={self}
|
|
271
280
|
reference={fieldName}
|
|
272
|
-
|
|
273
|
-
// {...propsToPass}
|
|
281
|
+
{...editorProps}
|
|
274
282
|
/>;
|
|
275
283
|
|
|
276
284
|
// element = <Tooltip key={ix} label={header} placement="bottom">
|
|
@@ -516,22 +524,20 @@ function Form(props) {
|
|
|
516
524
|
{...editorTypeProps}
|
|
517
525
|
{...dynamicProps}
|
|
518
526
|
/>;
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
message = message.replace(error.ref.name, label);
|
|
525
|
-
}
|
|
527
|
+
let message = null;
|
|
528
|
+
if (error) {
|
|
529
|
+
message = error.message;
|
|
530
|
+
if (label && error.ref?.name) {
|
|
531
|
+
message = message.replace(error.ref.name, label);
|
|
526
532
|
}
|
|
527
|
-
if (message) {
|
|
528
|
-
message = <Text color="#f00">{message}</Text>;
|
|
529
|
-
}
|
|
530
|
-
element = <Column pt={1} flex={1}>
|
|
531
|
-
{element}
|
|
532
|
-
{message}
|
|
533
|
-
</Column>;
|
|
534
533
|
}
|
|
534
|
+
if (message) {
|
|
535
|
+
message = <Text color="#f00">{message}</Text>;
|
|
536
|
+
}
|
|
537
|
+
element = <Column pt={1} flex={1}>
|
|
538
|
+
{element}
|
|
539
|
+
{message}
|
|
540
|
+
</Column>;
|
|
535
541
|
|
|
536
542
|
if (item.additionalEditButtons) {
|
|
537
543
|
const buttons = buildAdditionalButtons(item.additionalEditButtons, self, { fieldState, formSetValue, formGetValues, formState });
|
|
@@ -830,9 +836,17 @@ function Form(props) {
|
|
|
830
836
|
}
|
|
831
837
|
|
|
832
838
|
if (editorType === EDITOR_TYPE__INLINE) {
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
footerProps.
|
|
839
|
+
footerProps.position = 'sticky';
|
|
840
|
+
footerProps.alignSelf = 'flex-start';
|
|
841
|
+
footerProps.justifyContent = 'center';
|
|
842
|
+
footerProps.top = '100px';
|
|
843
|
+
footerProps.left = '20px';
|
|
844
|
+
footerProps.width = '200px';
|
|
845
|
+
footerProps.bg = 'primary.100';
|
|
846
|
+
footerProps.p = 0;
|
|
847
|
+
footerProps.px = 4;
|
|
848
|
+
footerProps.py = 2;
|
|
849
|
+
footerProps.borderBottomRadius = 5;
|
|
836
850
|
}
|
|
837
851
|
|
|
838
852
|
if (onDelete && editorMode === EDITOR_MODE__EDIT && isSingle) {
|
|
@@ -868,11 +882,11 @@ function Form(props) {
|
|
|
868
882
|
}
|
|
869
883
|
}
|
|
870
884
|
|
|
871
|
-
return <Column {...sizeProps} onLayout={onLayoutDecorated} ref={formRef}>
|
|
885
|
+
return <Column {...sizeProps} onLayout={onLayoutDecorated} ref={formRef} testID="form">
|
|
872
886
|
{!!containerWidth && <>
|
|
873
887
|
{editorType === EDITOR_TYPE__INLINE &&
|
|
874
|
-
<
|
|
875
|
-
|
|
888
|
+
<Row
|
|
889
|
+
display="inline-block"
|
|
876
890
|
flex={1}
|
|
877
891
|
bg="#fff"
|
|
878
892
|
py={1}
|
|
@@ -880,7 +894,7 @@ function Form(props) {
|
|
|
880
894
|
borderBottomWidth={5}
|
|
881
895
|
borderTopColor="primary.100"
|
|
882
896
|
borderBottomColor="primary.100"
|
|
883
|
-
>{editor}</
|
|
897
|
+
>{editor}</Row>}
|
|
884
898
|
{editorType !== EDITOR_TYPE__INLINE &&
|
|
885
899
|
<ScrollView _web={{ minHeight, }} width="100%" pb={1}>
|
|
886
900
|
{formButtons}
|
|
@@ -82,7 +82,7 @@ export default function withInlineEditor(WrappedComponent) {
|
|
|
82
82
|
editorBounds = editor.parentElement.getBoundingClientRect(), // reference parentElement, because this doesn't change based on last moveEditor call
|
|
83
83
|
delta = editorBounds.top - rowBounds.top;
|
|
84
84
|
|
|
85
|
-
editorStyle.top = (-1 * delta)
|
|
85
|
+
editorStyle.top = (-1 * delta) + 'px';
|
|
86
86
|
};
|
|
87
87
|
|
|
88
88
|
if (isEditorShown && selection.length < 1) {
|
|
@@ -100,13 +100,14 @@ export default function withInlineEditor(WrappedComponent) {
|
|
|
100
100
|
inlineEditor = <>
|
|
101
101
|
{isEditorShown && <Box
|
|
102
102
|
ref={maskRef}
|
|
103
|
+
testID="mask"
|
|
103
104
|
position="fixed"
|
|
104
105
|
w="100vw"
|
|
105
106
|
h="100vh"
|
|
106
107
|
top="0"
|
|
107
108
|
left="0"
|
|
108
109
|
bg="#000"
|
|
109
|
-
opacity={0.
|
|
110
|
+
opacity={0.3}
|
|
110
111
|
zIndex={0}
|
|
111
112
|
onClick={(e) => {
|
|
112
113
|
e.preventDefault();
|
|
@@ -118,39 +119,34 @@ export default function withInlineEditor(WrappedComponent) {
|
|
|
118
119
|
ref={inlineEditorRef}
|
|
119
120
|
position="absolute"
|
|
120
121
|
zIndex={10}
|
|
122
|
+
testID="inline-editor"
|
|
123
|
+
h={isEditorShown ? '100px' : 0}
|
|
124
|
+
minWidth="100%"
|
|
125
|
+
display="inline-block"
|
|
126
|
+
whiteSpace="nowrap"
|
|
121
127
|
>
|
|
122
|
-
{isEditorShown &&
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
py: 2,
|
|
145
|
-
}}
|
|
146
|
-
bg="#fff"
|
|
147
|
-
borderTopWidth={4}
|
|
148
|
-
borderTopColor={styles.GRID_INLINE_EDITOR_BORDER_COLOR}
|
|
149
|
-
borderBottomWidth={4}
|
|
150
|
-
borderBottomColor={styles.GRID_INLINE_EDITOR_BORDER_COLOR}
|
|
151
|
-
py={1}
|
|
152
|
-
px={0}
|
|
153
|
-
/>}
|
|
128
|
+
{isEditorShown &&
|
|
129
|
+
<Form
|
|
130
|
+
parent={self}
|
|
131
|
+
reference="form"
|
|
132
|
+
editorType={EDITOR_TYPE__INLINE}
|
|
133
|
+
editorStateRef={editorStateRef}
|
|
134
|
+
record={selection[0]}
|
|
135
|
+
Repository={Repository}
|
|
136
|
+
isMultiple={selection.length > 1}
|
|
137
|
+
isEditorViewOnly={isEditorViewOnly}
|
|
138
|
+
columnsConfig={localColumnsConfig}
|
|
139
|
+
onCancel={onEditorCancel}
|
|
140
|
+
onSave={onEditorSave}
|
|
141
|
+
onClose={onEditorClose}
|
|
142
|
+
bg="#fff"
|
|
143
|
+
borderTopWidth={4}
|
|
144
|
+
borderTopColor={styles.GRID_INLINE_EDITOR_BORDER_COLOR}
|
|
145
|
+
borderBottomWidth={4}
|
|
146
|
+
borderBottomColor={styles.GRID_INLINE_EDITOR_BORDER_COLOR}
|
|
147
|
+
py={1}
|
|
148
|
+
px={0}
|
|
149
|
+
/>}
|
|
154
150
|
</Column>
|
|
155
151
|
</>;
|
|
156
152
|
}
|
package/src/UiGlobals.js
CHANGED
|
@@ -9,6 +9,9 @@ const Globals = {
|
|
|
9
9
|
// global defaults
|
|
10
10
|
paginationIsShowMoreOnly: false,
|
|
11
11
|
autoAdjustPageSizeToHeight: true,
|
|
12
|
+
doubleClickingGridRowOpensEditorInViewMode: false,
|
|
13
|
+
disableSavedColumnsConfig: false,
|
|
14
|
+
autoSubmitDelay: 500,
|
|
12
15
|
};
|
|
13
16
|
|
|
14
17
|
export default Globals;
|
package/src/Constants/Input.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const AUTO_SUBMIT_DELAY = 500;
|