Skip to content

Commit dd34874

Browse files
committed
overridable: Add support for all custom field widgets
* Implemented the standardised props and dynamic-ID overridable wrapper for all the UI widgets available for use in custom widgets.
1 parent da9b8ba commit dd34874

File tree

9 files changed

+189
-75
lines changed

9 files changed

+189
-75
lines changed

src/lib/forms/RichInputField.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import { Form } from "semantic-ui-react";
1515

1616
export class RichInputField extends Component {
1717
renderFormField = (formikBag) => {
18-
const { fieldPath, label, required, className, editor, editorConfig } = this.props;
18+
const { fieldPath, label, required, className, editor, editorConfig, disabled } =
19+
this.props;
1920
const value = getIn(formikBag.form.values, fieldPath, "");
2021
const initialValue = getIn(formikBag.form.initialValues, fieldPath, "");
2122
const error =
@@ -28,6 +29,7 @@ export class RichInputField extends Component {
2829
<Form.Field
2930
id={fieldPath}
3031
required={required}
32+
disabled={disabled}
3133
error={error}
3234
className={className}
3335
>
@@ -74,6 +76,7 @@ RichInputField.propTypes = {
7476
label: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
7577
required: PropTypes.bool,
7678
editorConfig: PropTypes.object,
79+
disabled: PropTypes.bool,
7780
};
7881

7982
RichInputField.defaultProps = {
@@ -83,4 +86,5 @@ RichInputField.defaultProps = {
8386
label: "",
8487
editor: undefined,
8588
editorConfig: undefined,
89+
disabled: false,
8690
};

src/lib/forms/widgets/array/Array.js

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import PropTypes from "prop-types";
33

44
import { FieldLabel } from "../../FieldLabel";
55
import { ArrayField } from "../../ArrayField";
6+
import { fieldCommonProps } from "src/lib/utils";
67

78
export default class Array extends Component {
89
render() {
@@ -17,16 +18,21 @@ export default class Array extends Component {
1718
addButtonLabel,
1819
defaultNewValue,
1920
className,
21+
helpText: helpTextProp,
22+
labelIcon: labelIconProp,
2023
} = this.props;
2124

25+
const helpText = helpTextProp ?? description;
26+
const labelIcon = labelIconProp ?? icon;
27+
2228
return (
2329
<ArrayField
2430
key={fieldPath}
2531
fieldPath={fieldPath}
2632
required={required}
27-
helpText={description}
33+
helpText={helpText}
2834
disabled={disabled}
29-
label={<FieldLabel htmlFor={fieldPath} icon={icon} label={label} />}
35+
label={<FieldLabel htmlFor={fieldPath} icon={labelIcon} label={label} />}
3036
addButtonLabel={addButtonLabel}
3137
defaultNewValue={defaultNewValue}
3238
className={className}
@@ -38,21 +44,22 @@ export default class Array extends Component {
3844
}
3945

4046
Array.propTypes = {
41-
fieldPath: PropTypes.string.isRequired,
42-
label: PropTypes.string.isRequired,
43-
description: PropTypes.string.isRequired,
44-
icon: PropTypes.string,
45-
required: PropTypes.bool,
46-
disabled: PropTypes.bool,
4747
children: PropTypes.func.isRequired,
4848
addButtonLabel: PropTypes.string.isRequired,
4949
defaultNewValue: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
5050
className: PropTypes.string,
51+
/**
52+
* @deprecated Use `labelIcon` instead
53+
*/
54+
icon: PropTypes.string,
55+
/**
56+
* @deprecated Use `helpText` instead
57+
*/
58+
description: PropTypes.string.isRequired,
59+
...fieldCommonProps,
5160
};
5261

5362
Array.defaultProps = {
54-
icon: undefined,
55-
required: false,
56-
disabled: false,
5763
className: "",
64+
icon: undefined,
5865
};

src/lib/forms/widgets/text/BooleanCheckbox.js

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,33 @@ import { FieldLabel } from "../../FieldLabel";
1212
import { RadioField } from "../../RadioField";
1313

1414
import { useField } from "formik";
15+
import {
16+
createDynamicOverridableComponent,
17+
createShowHideComponent,
18+
fieldCommonProps,
19+
} from "../../../utils";
1520

16-
export default function BooleanCheckbox({
21+
function _BooleanCheckboxComponent({
1722
description,
1823
icon,
1924
falseLabel,
2025
fieldPath,
2126
label,
2227
trueLabel,
2328
required,
29+
helpText: helpTextProp,
30+
labelIcon: labelIconProp,
2431
}) {
32+
const helpText = helpTextProp ?? description;
33+
const labelIcon = labelIconProp ?? icon;
34+
2535
// eslint-disable-next-line no-unused-vars
2636
const [_, meta] = useField(fieldPath);
2737
return (
2838
<>
2939
<Form.Group inline className="mb-0">
3040
<Form.Field required={required}>
31-
<FieldLabel htmlFor={fieldPath} icon={icon} label={label} />
41+
<FieldLabel htmlFor={fieldPath} icon={labelIcon} label={label} />
3242
</Form.Field>
3343
<RadioField
3444
fieldPath={fieldPath}
@@ -52,22 +62,33 @@ export default function BooleanCheckbox({
5262
</Form.Field>
5363
)}
5464
</Form.Group>
55-
{description && <label className="helptext">{description}</label>}
65+
{helpText && <label className="helptext">{helpText}</label>}
5666
</>
5767
);
5868
}
5969

60-
BooleanCheckbox.propTypes = {
61-
fieldPath: PropTypes.string.isRequired,
62-
label: PropTypes.string.isRequired,
70+
_BooleanCheckboxComponent.propTypes = {
6371
trueLabel: PropTypes.string.isRequired,
6472
falseLabel: PropTypes.string.isRequired,
73+
/**
74+
* @deprecated Use `helpText` instead
75+
*/
6576
description: PropTypes.string.isRequired,
77+
/**
78+
* @deprecated Use `labelIcon` instead
79+
*/
6680
icon: PropTypes.string,
67-
required: PropTypes.bool,
81+
...fieldCommonProps,
6882
};
6983

70-
BooleanCheckbox.defaultProps = {
84+
_BooleanCheckboxComponent.defaultProps = {
7185
icon: undefined,
7286
required: false,
7387
};
88+
89+
export const BooleanCheckboxComponent = createShowHideComponent(
90+
_BooleanCheckboxComponent
91+
);
92+
export const BooleanCheckbox = createDynamicOverridableComponent(
93+
BooleanCheckboxComponent
94+
);

src/lib/forms/widgets/text/Input.js

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import React, { Component } from "react";
22
import PropTypes from "prop-types";
3-
43
import { FieldLabel } from "../../FieldLabel";
54
import { TextField } from "../../TextField";
5+
import {
6+
createShowHideComponent,
7+
createDynamicOverridableComponent,
8+
fieldCommonProps,
9+
} from "../../../utils/";
610

7-
export default class Input extends Component {
11+
class _InputComponent extends Component {
812
render() {
913
const {
1014
fieldPath,
@@ -15,37 +19,45 @@ export default class Input extends Component {
1519
description,
1620
disabled,
1721
type,
22+
helpText: helpTextProp,
23+
labelIcon: labelIconProp,
1824
} = this.props;
1925

26+
const helpText = helpTextProp ?? description;
27+
const labelIcon = labelIconProp ?? icon;
28+
2029
return (
2130
<TextField
2231
key={fieldPath}
2332
fieldPath={fieldPath}
2433
required={required}
25-
helpText={description}
34+
helpText={helpText}
2635
disabled={disabled}
27-
label={<FieldLabel htmlFor={fieldPath} icon={icon} label={label} />}
36+
label={<FieldLabel htmlFor={fieldPath} icon={labelIcon} label={label} />}
2837
placeholder={placeholder}
2938
type={type}
3039
/>
3140
);
3241
}
3342
}
3443

35-
Input.propTypes = {
36-
fieldPath: PropTypes.string.isRequired,
37-
label: PropTypes.string.isRequired,
38-
placeholder: PropTypes.string.isRequired,
44+
_InputComponent.propTypes = {
45+
/**
46+
* @deprecated Use `helpText` instead
47+
*/
3948
description: PropTypes.string.isRequired,
49+
/**
50+
* @deprecated Use `labelIcon` instead
51+
*/
4052
icon: PropTypes.string,
41-
required: PropTypes.bool,
42-
disabled: PropTypes.bool,
4353
type: PropTypes.string,
54+
...fieldCommonProps,
4455
};
4556

46-
Input.defaultProps = {
57+
_InputComponent.defaultProps = {
4758
icon: undefined,
48-
required: false,
49-
disabled: false,
5059
type: "input",
5160
};
61+
62+
export const InputComponent = createShowHideComponent(_InputComponent);
63+
export const Input = createDynamicOverridableComponent(InputComponent);

src/lib/forms/widgets/text/MultiInput.js

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
import React, { useState } from "react";
22
import PropTypes from "prop-types";
33
import { useFormikContext, getIn } from "formik";
4-
54
import { FieldLabel } from "../../FieldLabel";
65
import { SelectField } from "../../SelectField";
6+
import {
7+
createDynamicOverridableComponent,
8+
createShowHideComponent,
9+
fieldCommonProps,
10+
} from "../../../utils";
711

8-
export default function MultiInput({
12+
function _MultiInputComponent({
913
additionLabel,
1014
description,
1115
placeholder,
1216
fieldPath,
1317
label,
1418
icon,
1519
required,
20+
disabled,
21+
helpText: helpTextProp,
22+
labelIcon: labelIconProp,
1623
}) {
1724
const [options, setOptions] = useState([]);
1825
const { values } = useFormikContext();
@@ -23,14 +30,18 @@ export default function MultiInput({
2330
value: item,
2431
}));
2532

33+
const helpText = helpTextProp ?? description;
34+
const labelIcon = labelIconProp ?? icon;
35+
2636
return (
2737
<>
2838
<SelectField
2939
fieldPath={fieldPath}
30-
label={<FieldLabel htmlFor={fieldPath} icon={icon} label={label} />}
40+
label={<FieldLabel htmlFor={fieldPath} icon={labelIcon} label={label} />}
3141
options={serializeValues(getIn(values, fieldPath, []))}
3242
placeholder={placeholder}
3343
required={required}
44+
disabled={disabled}
3445
search
3546
multiple
3647
clearable
@@ -47,23 +58,28 @@ export default function MultiInput({
4758
setOptions([{ text: data.value, value: data.value }, ...options]);
4859
}}
4960
/>
50-
{description && <label className="helptext">{description}</label>}
61+
{helpText && <label className="helptext">{helpText}</label>}
5162
</>
5263
);
5364
}
5465

55-
MultiInput.propTypes = {
56-
fieldPath: PropTypes.string.isRequired,
57-
label: PropTypes.string.isRequired,
58-
placeholder: PropTypes.string.isRequired,
66+
_MultiInputComponent.propTypes = {
67+
/**
68+
* @deprecated Use `helpText` instead
69+
*/
5970
description: PropTypes.string.isRequired,
6071
additionLabel: PropTypes.string,
72+
/**
73+
* @deprecated Use `labelIcon` instead
74+
*/
6175
icon: PropTypes.string,
62-
required: PropTypes.bool,
76+
...fieldCommonProps,
6377
};
6478

65-
MultiInput.defaultProps = {
79+
_MultiInputComponent.defaultProps = {
6680
additionLabel: undefined,
6781
icon: undefined,
68-
required: false,
6982
};
83+
84+
export const MultiInputComponent = createShowHideComponent(_MultiInputComponent);
85+
export const MultiInput = createDynamicOverridableComponent(MultiInputComponent);
Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import React from "react";
2-
import Input from "./Input";
2+
import {
3+
createDynamicOverridableComponent,
4+
createShowHideComponent,
5+
} from "../../../utils";
6+
import InputComponent from "./Input";
37

4-
const NumberInput = (props) => <Input {...props} type="number" />;
5-
export default NumberInput;
8+
const _NumberInputComponent = (props) => <InputComponent {...props} type="number" />;
9+
export const NumberInputComponent = createShowHideComponent(_NumberInputComponent);
10+
export const NumberInput = createDynamicOverridableComponent(NumberInputComponent);

0 commit comments

Comments
 (0)