Skip to content

Commit 08fa5ca

Browse files
Avi Sharvitsharvit
authored andcommitted
feat(Form): Add form related components
re #118 #117 #116
1 parent 26311e3 commit 08fa5ca

18 files changed

+755
-0
lines changed

src/components/Form/Checkbox.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Checkbox as default } from 'react-bootstrap';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { ControlLabel as default } from 'react-bootstrap';

src/components/Form/Form.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Form as default } from 'react-bootstrap';
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
/* eslint react/prop-types: 0 */
2+
3+
import React from 'react';
4+
import { storiesOf } from '@storybook/react';
5+
import { action } from '@storybook/addon-actions';
6+
import { withKnobs, boolean } from '@storybook/addon-knobs';
7+
import { defaultTemplate } from '../../../storybook/decorators/storyTemplates';
8+
import { Icon } from '../Icon';
9+
import { Col, Row, Grid } from '../Grid';
10+
import { Button } from '../Button';
11+
import { Modal } from '../Modal';
12+
import { Form } from './index';
13+
14+
import {
15+
InlineFormFields,
16+
InlineFormButtons,
17+
getInlineFormKnobs
18+
} from './Stories/InlineForm';
19+
import {
20+
BasicFormFields,
21+
BasicFormButtons,
22+
BasicFormSpinner,
23+
getBasicFormKnobs
24+
} from './Stories/BasicForm';
25+
import {
26+
SupportedControlsFormFields,
27+
getSupportedControlsFormKnobs
28+
} from './Stories/SupportedControlsForm';
29+
import {
30+
InputGroupsFormFields,
31+
getInputGroupsFormKnobs
32+
} from './Stories/InputGroupsForm';
33+
import { InlineFormField } from './Stories/InlineFormField';
34+
import { HorizontalFormField } from './Stories/HorizontalFormField';
35+
import { VerticalFormField } from './Stories/VerticalFormField';
36+
37+
const stories = storiesOf('Forms', module);
38+
39+
stories.addDecorator(withKnobs);
40+
41+
const description = (
42+
<p>
43+
Those components are based on React Bootstrap Form components. See{' '}
44+
<a href="https://react-bootstrap.github.io/components/forms/">
45+
React Bootstrap Docs
46+
</a>{' '}
47+
for complete Form components documentation.
48+
</p>
49+
);
50+
51+
stories.addDecorator(
52+
defaultTemplate({
53+
title: 'Forms',
54+
documentationLink:
55+
'http://www.patternfly.org/pattern-library/widgets/#forms',
56+
description: description
57+
})
58+
);
59+
60+
stories.addWithInfo('Inline Form', '', () => {
61+
const formFieldsKnobs = getInlineFormKnobs();
62+
const { bsSize, disabled } = formFieldsKnobs;
63+
const buttonsProps = {};
64+
65+
if (bsSize) buttonsProps.bsSize = bsSize;
66+
if (disabled) buttonsProps.disabled = disabled;
67+
68+
const formFields = InlineFormFields.map(formField =>
69+
InlineFormField({ ...formField, ...formFieldsKnobs })
70+
).reduce((result = [], element) => {
71+
return [...result, element, ' ']; // create spacing betwwen elements
72+
}, []);
73+
74+
const formButtons = InlineFormButtons.map(({ text, ...props }) => (
75+
<Button key={text} {...props} {...buttonsProps}>
76+
{text}
77+
</Button>
78+
));
79+
80+
return (
81+
<Grid>
82+
<Form inline>
83+
{formFields} {formButtons}
84+
</Form>
85+
</Grid>
86+
);
87+
});
88+
89+
stories.addWithInfo('Horizontal Form', '', () => {
90+
const formFieldsKnobs = getBasicFormKnobs();
91+
const { bsSize, disabled } = formFieldsKnobs;
92+
const buttonsProps = {};
93+
94+
if (bsSize) buttonsProps.bsSize = bsSize;
95+
if (disabled) buttonsProps.disabled = disabled;
96+
97+
const showLoading = boolean('Show Loading', false);
98+
99+
const formFields = BasicFormFields.map(formField =>
100+
HorizontalFormField({ ...formField, ...formFieldsKnobs })
101+
);
102+
103+
const formButtons = BasicFormButtons.map(({ text, ...props }) => (
104+
<span key={text}>
105+
<Button {...props} {...buttonsProps}>
106+
{text}
107+
</Button>{' '}
108+
</span>
109+
));
110+
111+
return (
112+
<Grid>
113+
<Form horizontal>
114+
{formFields}
115+
<Row style={{ paddingTop: '10px', paddingBottom: '10px' }}>
116+
<Col smOffset={3} sm={9}>
117+
{formButtons}
118+
</Col>
119+
</Row>
120+
{showLoading && (
121+
<Row style={{ paddingTop: '10px', paddingBottom: '10px' }}>
122+
<Col smOffset={3} sm={9}>
123+
{[...BasicFormSpinner]}
124+
</Col>
125+
</Row>
126+
)}
127+
</Form>
128+
</Grid>
129+
);
130+
});
131+
132+
stories.addWithInfo('Vertical Form', '', () => {
133+
const formFieldsKnobs = getBasicFormKnobs();
134+
const { bsSize, disabled } = formFieldsKnobs;
135+
const buttonsProps = {};
136+
137+
if (bsSize) buttonsProps.bsSize = bsSize;
138+
if (disabled) buttonsProps.disabled = disabled;
139+
140+
const showLoading = boolean('Show Loading', false);
141+
142+
const formFields = BasicFormFields.map(formField =>
143+
VerticalFormField({ ...formField, ...formFieldsKnobs })
144+
);
145+
146+
const formButtons = BasicFormButtons.map(({ text, ...props }) => (
147+
<span key={text}>
148+
<Button {...props} {...buttonsProps}>
149+
{text}
150+
</Button>{' '}
151+
</span>
152+
));
153+
154+
return (
155+
<Grid>
156+
<Form>
157+
<Row>
158+
<Col>{formFields}</Col>
159+
</Row>
160+
<Row style={{ paddingTop: '10px', paddingBottom: '10px' }}>
161+
<Col>{formButtons}</Col>
162+
</Row>
163+
{showLoading && (
164+
<Row style={{ paddingTop: '10px', paddingBottom: '10px' }}>
165+
<Col>{BasicFormSpinner}</Col>
166+
</Row>
167+
)}
168+
</Form>
169+
</Grid>
170+
);
171+
});
172+
173+
stories.addWithInfo('Modal Form', '', () => {
174+
const formFieldsKnobs = getBasicFormKnobs();
175+
const { bsSize, disabled } = formFieldsKnobs;
176+
const buttonsProps = {};
177+
178+
if (bsSize) buttonsProps.bsSize = bsSize;
179+
if (disabled) buttonsProps.disabled = disabled;
180+
181+
const showModal = boolean('Show Modal', true);
182+
const showLoading = boolean('Show Loading', false);
183+
184+
const formFields = BasicFormFields.map(formField =>
185+
HorizontalFormField({ ...formField, ...formFieldsKnobs })
186+
);
187+
188+
const formButtons = BasicFormButtons.map(({ text, ...props }) => (
189+
<Button key={text} {...props} {...buttonsProps}>
190+
{text}
191+
</Button>
192+
)).reverse();
193+
194+
const formSpinner = (
195+
<div style={{ paddingTop: '20px', paddingBottom: '10px' }}>
196+
{[...BasicFormSpinner].reverse()}
197+
</div>
198+
);
199+
200+
return (
201+
<Modal show={showModal}>
202+
<Modal.Header>
203+
<button
204+
className="close"
205+
onClick={action('Close')}
206+
aria-hidden="true"
207+
aria-label="Close"
208+
>
209+
<Icon type="pf" name="close" />
210+
</button>
211+
<Modal.Title>Basic Settings</Modal.Title>
212+
</Modal.Header>
213+
<Modal.Body>
214+
<Form horizontal>{formFields}</Form>
215+
</Modal.Body>
216+
<Modal.Footer>
217+
{formButtons}
218+
{showLoading && formSpinner}
219+
</Modal.Footer>
220+
</Modal>
221+
);
222+
});
223+
224+
stories.addWithInfo('Supported Controls', '', () => {
225+
const formFieldsKnobs = getSupportedControlsFormKnobs();
226+
227+
const formFields = SupportedControlsFormFields.map(formField =>
228+
VerticalFormField({ ...formField, ...formFieldsKnobs })
229+
);
230+
231+
return (
232+
<Grid>
233+
<Form>{formFields}</Form>
234+
</Grid>
235+
);
236+
});
237+
238+
stories.addWithInfo('Input Groups', '', () => {
239+
const formFieldsKnobs = getInputGroupsFormKnobs();
240+
241+
const formFields = InputGroupsFormFields.map(formField =>
242+
VerticalFormField({ ...formField, ...formFieldsKnobs })
243+
);
244+
245+
return (
246+
<Grid>
247+
<Form>
248+
<Row>
249+
<Col>{formFields}</Col>
250+
</Row>
251+
</Form>
252+
</Grid>
253+
);
254+
});

src/components/Form/FormControl.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { FormControl as default } from 'react-bootstrap';

src/components/Form/FormGroup.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { FormGroup as default } from 'react-bootstrap';

src/components/Form/HelpBlock.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { HelpBlock as default } from 'react-bootstrap';

src/components/Form/InputGroup.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { InputGroup as default } from 'react-bootstrap';

src/components/Form/Radio.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Radio as default } from 'react-bootstrap';
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/* eslint react/prop-types: 0 */
2+
3+
import React from 'react';
4+
import { action } from '@storybook/addon-actions';
5+
import { select, boolean } from '@storybook/addon-knobs';
6+
import { Spinner } from '../../Spinner';
7+
import { Button } from '../../Button';
8+
import { FormControl, InputGroup } from '../index';
9+
10+
export const BasicFormFields = [
11+
{
12+
controlId: 'name',
13+
label: 'Name',
14+
help: 'Enter your name',
15+
formControl: ({ validationState, ...props }) => (
16+
<FormControl type="text" {...props} />
17+
)
18+
},
19+
{
20+
controlId: 'address',
21+
label: 'Address',
22+
help: 'Enter your address',
23+
formControl: ({ validationState, ...props }) => (
24+
<FormControl type="address" {...props} />
25+
)
26+
},
27+
{
28+
controlId: 'city',
29+
label: 'City',
30+
help: 'Enter your city',
31+
formControl: ({ validationState, ...props }) => (
32+
<FormControl type="text" {...props} />
33+
)
34+
},
35+
{
36+
controlId: 'email',
37+
label: 'Email',
38+
help: 'Enter a valid email address',
39+
formControl: ({ validationState, ...props }) => (
40+
<FormControl type="email" {...props} />
41+
)
42+
},
43+
{
44+
controlId: 'url',
45+
label: 'My meeting URL',
46+
help: 'Enter a valid URL',
47+
formControl: ({ validationState, disabled, ...props }) => {
48+
const controlProps = { disabled };
49+
return (
50+
<InputGroup {...props}>
51+
<FormControl type="url" {...controlProps} />
52+
<InputGroup.Button>
53+
<Button onClick={action('CopyUrl')} {...controlProps}>
54+
Copy URL
55+
</Button>
56+
</InputGroup.Button>
57+
</InputGroup>
58+
);
59+
}
60+
}
61+
];
62+
63+
export const BasicFormButtons = [
64+
{
65+
text: 'Save',
66+
bsStyle: 'primary',
67+
onClick: action('Save')
68+
},
69+
{
70+
text: 'Cancel',
71+
bsStyle: 'default',
72+
onClick: action('Cancel')
73+
}
74+
];
75+
76+
export const BasicFormSpinner = [
77+
<Spinner key="spinner" size="xs" loading inline />,
78+
' ',
79+
<span key="text">
80+
Do not refresh this page. This request may take a minute...
81+
</span>
82+
];
83+
84+
export const getBasicFormKnobs = () => ({
85+
validationState: select('Validation State', [
86+
null,
87+
'success',
88+
'warning',
89+
'error'
90+
]),
91+
bsSize: select('Size', [null, 'small', 'large']),
92+
showHelp: boolean('Show Help', true),
93+
disabled: boolean('Disabled', false)
94+
});

0 commit comments

Comments
 (0)