Skip to content

Commit 669599a

Browse files
authored
Merge pull request #131 from brumik/input-addon
Added inputAddon support to PF3 text and textarea input fields
2 parents ed1d7e2 + d6ba34f commit 669599a

File tree

13 files changed

+8047
-292
lines changed

13 files changed

+8047
-292
lines changed

packages/pf3-component-mapper/demo/demo-schemas/sandbox.js

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
/* eslint-disable camelcase */
2-
import { componentTypes as components, validatorTypes as validators } from '@data-driven-forms/react-form-renderer';
2+
import {
3+
componentTypes as components,
4+
validatorTypes as validators,
5+
} from '@data-driven-forms/react-form-renderer';
36

47
const output = {
58
title: 'Testing dialog',
@@ -64,7 +67,6 @@ const output = {
6467
bsSize: 'mn',
6568
onText: 'True',
6669
offText: 'False',
67-
validate: undefined,
6870
},
6971
{
7072
name: 'text_box_111',
@@ -100,6 +102,64 @@ const output = {
100102
helperText: 'Helper text',
101103
component: components.TEXT_FIELD,
102104
},
105+
{
106+
name: 'text_box_21',
107+
label: 'Text Box With Input Addon',
108+
title: 'Text Box With Input Addon',
109+
component: components.TEXT_FIELD,
110+
inputAddon: {
111+
before: {
112+
fields: [
113+
{
114+
component: components.INPUT_ADDON_BUTTON_GROUP,
115+
name: 'i-a-g-2',
116+
fields: [
117+
{
118+
component: components.BUTTON,
119+
label: 'Set 1',
120+
name: 'set1',
121+
onClick: () => console.log('fooo'),
122+
},
123+
{
124+
component: components.BUTTON,
125+
label: 'Set 2',
126+
name: 'set2',
127+
onClick: () => console.log('foo2o'),
128+
},
129+
],
130+
},
131+
],
132+
},
133+
after: {
134+
fields: [
135+
{
136+
component: components.INPUT_ADDON_GROUP,
137+
name: 'i-a-g-2',
138+
fields: [
139+
{
140+
component: components.PLAIN_TEXT,
141+
label: '-',
142+
name: 'name1',
143+
variant: 'span',
144+
},
145+
],
146+
},
147+
{
148+
component: components.INPUT_ADDON_BUTTON_GROUP,
149+
name: 'i-a-g-3',
150+
fields: [
151+
{
152+
component: components.BUTTON,
153+
label: 'Set 3',
154+
name: 'set3',
155+
onClick: () => console.log('foo3o'),
156+
},
157+
],
158+
},
159+
],
160+
},
161+
},
162+
},
103163
{
104164
name: 'text_box_3',
105165
label: 'Text Box required',
Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
import React from 'react';
2-
import { Button } from 'patternfly-react';
2+
import PropTypes from 'prop-types';
3+
import { Button as PFButton } from 'patternfly-react';
34

4-
const ButtonOverride = (props) => <Button style={{ marginLeft: 3 }} { ...props } />;
5+
export const Button = ({ label, variant, className, ...rest }) => {
6+
const { formOptions, FieldProvider, validate, ...props } = { ...rest };
7+
return <PFButton bsStyle={ variant } className={ className } { ...props }>{ label }</PFButton>;
8+
};
59

6-
export default ButtonOverride;
10+
Button.propTypes = {
11+
label: PropTypes.string.isRequired,
12+
variant: PropTypes.string,
13+
className: PropTypes.string,
14+
};
15+
16+
Button.defaultProps = {
17+
className: '',
18+
};
19+
20+
export default Button;

packages/pf3-component-mapper/src/form-fields/component-mapper.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,20 @@ import {
88
Radio,
99
SwitchField,
1010
DatePickerField,
11-
PlainTextField,
1211
} from './form-fields';
1312
import SubForm from './sub-form';
1413
import Tabs from './tabs';
1514
import Wizard from './wizzard/wizzard';
1615
import Select from './select';
16+
import PlainTextField from './plain-text';
17+
import Button from './button';
18+
import {
19+
InputAddonButtonGroup,
20+
InputAddonGroup,
21+
} from './input-group-fields';
1722

1823
const mapper = {
24+
[componentTypes.BUTTON]: Button,
1925
[componentTypes.TEXT_FIELD]: TextField,
2026
[componentTypes.TEXTAREA_FIELD]: TextareaField,
2127
[componentTypes.SELECT_COMPONENT]: SelectField,
@@ -28,6 +34,8 @@ const mapper = {
2834
[componentTypes.SWITCH]: SwitchField,
2935
[componentTypes.WIZARD]: Wizard,
3036
[componentTypes.PLAIN_TEXT]: PlainTextField,
37+
[componentTypes.INPUT_ADDON_BUTTON_GROUP]: InputAddonButtonGroup,
38+
[componentTypes.INPUT_ADDON_GROUP]: InputAddonGroup,
3139
};
3240

3341
export default mapper;

packages/pf3-component-mapper/src/form-fields/form-fields.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3-
import { FormControl, HelpBlock, Checkbox, FormGroup, ControlLabel, FieldLevelHelp } from 'patternfly-react';
3+
import { FormControl, HelpBlock, Checkbox, FormGroup, ControlLabel, InputGroup, FieldLevelHelp } from 'patternfly-react';
44
import { componentTypes } from '@data-driven-forms/react-form-renderer';
55
import { validationError } from './helpers';
66
import MultipleChoiceList from './multiple-choice-list';
@@ -9,7 +9,6 @@ import Switch from './switch-field';
99
import { DateTimePicker } from './date-time-picker/date-time-picker';
1010

1111
import RagioGroup from './radio';
12-
import PlainText from './plain-text';
1312
import Select from './select';
1413

1514
const selectComponent = ({
@@ -81,6 +80,20 @@ export const renderHelperText = (error, description) => (error // eslint-disable
8180
? <HelpBlock>{ error }</HelpBlock>
8281
: description ? <HelpBlock>{ description }</HelpBlock> : null);
8382

83+
const renderInputGroup = (inputAddon, params, formOptions, { ...rest }) => {
84+
if (inputAddon) {
85+
return (
86+
<InputGroup>
87+
{ inputAddon.before && inputAddon.before.fields && formOptions.renderForm(inputAddon.before.fields, rest) }
88+
{ selectComponent({ ...rest, ...params })() }
89+
{ inputAddon.after && inputAddon.after.fields && formOptions.renderForm(inputAddon.after.fields, rest) }
90+
</InputGroup>
91+
);
92+
}
93+
94+
return (selectComponent({ ...rest, ...params })());
95+
};
96+
8497
const FinalFormField = ({
8598
meta,
8699
validateOnMount,
@@ -89,6 +102,7 @@ const FinalFormField = ({
89102
description,
90103
hideLabel,
91104
isVisible,
105+
inputAddon,
92106
noCheckboxLabel,
93107
...rest
94108
}) => {
@@ -100,7 +114,7 @@ const FinalFormField = ({
100114
{ rest.isRequired ? <RequiredLabel label={ label } /> : label }
101115
{ helperText && <FieldLevelHelp content={ helperText } /> }
102116
</ControlLabel> }
103-
{ selectComponent({ ...rest, invalid, label, meta, helperText })() }
117+
{ renderInputGroup(inputAddon, { invalid, label, meta, helperText }, rest.formOptions, rest) }
104118
{ renderHelperText(invalid && meta.error, description) }
105119
</FormGroup>
106120
);
@@ -114,6 +128,7 @@ FinalFormField.propTypes = {
114128
description: PropTypes.string,
115129
hideLabel: PropTypes.bool,
116130
isVisible: PropTypes.bool,
131+
inputAddon: PropTypes.shape({ fields: PropTypes.array }),
117132
noCheckboxLabel: PropTypes.bool,
118133
};
119134

@@ -180,4 +195,3 @@ export const SwitchField = ({ FieldProvider, ...props }) =>
180195
<FieldProvider { ...props } render={ props => <FieldInterface { ...props } name={ props.input.name } componentType={ componentTypes.SWITCH } /> }/>;
181196
export const DatePickerField = props =>
182197
<FieldInterface { ...props } name={ props.input.name } variant={ props.variant } componentType={ componentTypes.DATE_PICKER } />;
183-
export const PlainTextField = ({ input, label }) => <PlainText { ...input } label={ label } />;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { InputGroup } from 'patternfly-react';
4+
5+
export const InputAddonButtonGroup = ({ fields, formOptions }) => (
6+
<InputGroup.Button>
7+
{ formOptions.renderForm(fields, formOptions) }
8+
</InputGroup.Button>
9+
);
10+
11+
InputAddonButtonGroup.propTypes = {
12+
formOptions: PropTypes.object.isRequired,
13+
fields: PropTypes.array.isRequired,
14+
};
15+
16+
export const InputAddonGroup = ({ fields, formOptions }) => (
17+
<InputGroup.Addon>
18+
{ formOptions.renderForm(fields, formOptions) }
19+
</InputGroup.Addon>
20+
);
21+
22+
InputAddonGroup.propTypes = {
23+
formOptions: PropTypes.object.isRequired,
24+
fields: PropTypes.array.isRequired,
25+
};
26+
27+
export default {
28+
InputAddonGroup,
29+
InputAddonButtonGroup,
30+
};

packages/pf3-component-mapper/src/form-fields/plain-text.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33

4-
const PlainText = ({ label, name }) => label.split('\n').map((paragraph, index) => <p key={ `${name}-${index}` }>{ paragraph }</p>);
4+
const validTextFields = [
5+
'p', 'span', 'strong', 'b', 'cite', 'caption', 'code', 'em', 'i',
6+
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h6',
7+
'div', 'label', 'pre', 'q', 'samp', 'small', 'sub', 'sup',
8+
];
9+
10+
const PlainText = ({ variant, label, name }) => label.split('\n').map((paragraph, index) =>
11+
React.createElement(`${variant}`, { key: `${name}-${index}` }, paragraph));
512

613
PlainText.propTypes = {
14+
variant: PropTypes.oneOf(validTextFields),
715
label: PropTypes.string.isRequired,
816
name: PropTypes.string.isRequired,
917
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.margin-left-3 {
2+
margin-left: 3px;
3+
}

packages/pf3-component-mapper/src/form-fields/wizzard/step-buttons.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33
import Button from '../button';
4+
import './button.scss';
45
import { Icon, Wizard } from 'patternfly-react';
56

67
const SimpleNext = ({
@@ -13,6 +14,7 @@ const SimpleNext = ({
1314
<Button
1415
bsStyle="primary"
1516
type="button"
17+
className="margin-left-3"
1618
onClick={ () => valid ? handleNext(next) : submit() }
1719
>
1820
{ buttonLabels.next }<Icon type="fa" name="angle-right" />
@@ -48,7 +50,11 @@ ConditionalNext.propTypes = {
4850
FieldProvider: PropTypes.func.isRequired,
4951
};
5052

51-
const submitButton = (handleSubmit, submitText) => <Button type="button" bsStyle="primary" onClick={ handleSubmit }>
53+
const submitButton = (handleSubmit, submitText) => <Button
54+
className="margin-left-3"
55+
type="button"
56+
bsStyle="primary"
57+
onClick={ handleSubmit }>
5258
{ submitText }
5359
</Button>;
5460

@@ -64,6 +70,7 @@ const WizardStepButtons = ({ formOptions, disableBack, handlePrev, nextStep, Fie
6470
{ formOptions.onCancel && (
6571
<Button
6672
style={{ marginRight: 20 }}
73+
className="margin-left-3"
6774
type="button" variant="contained"
6875
color="secondary" onClick={ formOptions.onCancel }>
6976
{ buttonLabels.cancel }
@@ -73,6 +80,7 @@ const WizardStepButtons = ({ formOptions, disableBack, handlePrev, nextStep, Fie
7380
<Button
7481
type="button"
7582
variant="contained"
83+
className="margin-left-3"
7684
disabled={ disableBack }
7785
onClick={ handlePrev }>
7886
<Icon type="fa" name="angle-left" />{ buttonLabels.back }

0 commit comments

Comments
 (0)