Skip to content

Commit 8c8103c

Browse files
committed
Create FormLayout component (#44)
1 parent ea1074e commit 8c8103c

33 files changed

+392
-8
lines changed

src/demo/pages/DemoContainer.jsx

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
CTAStart,
2222
CheckboxField,
2323
ForgotPassword,
24+
FormLayout,
2425
LayoutCenter,
2526
List,
2627
ListItem,
@@ -344,6 +345,142 @@ class DemoContainer extends React.Component {
344345
</CTA>
345346
)}
346347
/>
348+
<h3 id="layout-components-form-layout" className="typography-size-4 mb-6">Form Layout</h3>
349+
<p>
350+
Vertical Form Layout works similar to List except that List Items are not needed.
351+
Vertical form field layout is forced.
352+
</p>
353+
<Documentation
354+
name="Vertical Form Layout"
355+
component={(
356+
<FormLayout>
357+
<TextField
358+
id="formLayoutVerticalFirstName"
359+
changeHandler={logger}
360+
label="First Name"
361+
/>
362+
<TextField
363+
id="formLayoutVerticalLastName"
364+
changeHandler={logger}
365+
label="Last Name"
366+
/>
367+
<TextField
368+
id="formLayoutVerticalEmail"
369+
changeHandler={logger}
370+
label="Email address"
371+
type="email"
372+
helperText="Optional"
373+
/>
374+
<TextField
375+
id="formLayoutVerticalAddress1"
376+
changeHandler={logger}
377+
label="Address"
378+
placeholder="Address line 1"
379+
/>
380+
<TextField
381+
id="formLayoutVerticalAddress2"
382+
changeHandler={logger}
383+
isLabelVisible={false}
384+
label="Address 2"
385+
placeholder="Address line 2"
386+
/>
387+
<TextField
388+
id="formLayoutVerticalZip"
389+
changeHandler={logger}
390+
helperText="ZIP should be 5 to 6 digits long code."
391+
label="ZIP"
392+
inputSize={6}
393+
validationState="invalid"
394+
/>
395+
<TextField
396+
id="formLayoutVerticalCountry"
397+
changeHandler={logger}
398+
label="Country"
399+
/>
400+
<SelectField
401+
id="formLayoutVerticalFruit"
402+
changeHandler={logger}
403+
label="Your favourite fruit"
404+
options={this.exampleOptions}
405+
/>
406+
<TextArea
407+
id="formLayoutVerticalMessage"
408+
changeHandler={logger}
409+
fullWidth
410+
label="Message"
411+
rows={3}
412+
/>
413+
</FormLayout>
414+
)}
415+
/>
416+
<p>
417+
Horizontal Form Layout is designed for horizontal form fields.
418+
It is applied starting from <code>md</code> viewport size onwards.
419+
Horizontal form field layout is forced.
420+
</p>
421+
<Documentation
422+
name="Horizontal Form Layout"
423+
component={(
424+
<FormLayout fieldLayout="horizontal">
425+
<TextField
426+
id="formLayoutHorizontalFirstName"
427+
changeHandler={logger}
428+
label="First Name"
429+
/>
430+
<TextField
431+
id="formLayoutHorizontalLastName"
432+
changeHandler={logger}
433+
label="Last Name"
434+
/>
435+
<TextField
436+
id="formLayoutHorizontalEmail"
437+
changeHandler={logger}
438+
label="Email address"
439+
type="email"
440+
helperText="Optional"
441+
/>
442+
<TextField
443+
id="formLayoutHorizontalAddress1"
444+
changeHandler={logger}
445+
label="Address"
446+
placeholder="Address line 1"
447+
/>
448+
<TextField
449+
id="formLayoutHorizontalAddress2"
450+
changeHandler={logger}
451+
isLabelVisible={false}
452+
label="Address 2"
453+
placeholder="Address line 2"
454+
/>
455+
<TextField
456+
id="formLayoutHorizontalZip"
457+
changeHandler={logger}
458+
helperText="ZIP should be 5 to 6 digits long code."
459+
label="ZIP"
460+
inputSize={6}
461+
validationState="invalid"
462+
/>
463+
<TextField
464+
id="formLayoutHorizontalCountry"
465+
changeHandler={logger}
466+
label="Country"
467+
/>
468+
<SelectField
469+
id="formLayoutHorizontalFruit"
470+
changeHandler={logger}
471+
label="Your favourite fruit"
472+
options={this.exampleOptions}
473+
/>
474+
<TextArea
475+
id="formLayoutHorizontalMessage"
476+
changeHandler={logger}
477+
fullWidth
478+
label="Message"
479+
rows={3}
480+
/>
481+
</FormLayout>
482+
)}
483+
/>
347484
<h3 id="layout-components-list" className="typography-size-4 mb-6">List</h3>
348485
<Documentation
349486
name="Default list"

src/demo/pages/navigation.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ export default [
3535
link: '#layout-components-cta',
3636
title: 'CTA',
3737
},
38+
{
39+
link: '#layout-components-form-layout',
40+
title: 'Form Layout',
41+
},
3842
{
3943
link: '#layout-components-list',
4044
title: 'List',

src/lib/components/layout/CardList/CardList.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
@import '../../../styles/settings/layouts';
12
@import '../../../styles/tools/breakpoints';
23
@import '../../../styles/tools/offset';
34
@import './theme';
@@ -8,7 +9,7 @@
89
grid-template-columns: 1fr;
910
grid-template-rows: auto;
1011
grid-gap: $card-list-grid-gap;
11-
margin-bottom: offset(4);
12+
margin-bottom: $layout-common-bottom-offset;
1213

1314
@include breakpoint-up(sm) {
1415
grid-template-columns: repeat(auto-fit, minmax($card-list-card-min-width, $card-list-card-max-width));
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import PropTypes from 'prop-types';
2+
import React from 'react';
3+
import styles from './FormLayout.scss';
4+
5+
const FormLayout = (props) => {
6+
const {
7+
children,
8+
fieldLayout,
9+
id,
10+
} = props;
11+
12+
if (!children) {
13+
return null;
14+
}
15+
16+
const fieldLayoutClass = (layout) => {
17+
if (layout === 'horizontal') {
18+
return styles.rootFieldLayoutHorizontal;
19+
}
20+
21+
return styles.rootFieldLayoutVertical;
22+
};
23+
24+
return (
25+
<div
26+
id={id}
27+
className={[
28+
styles.root,
29+
fieldLayoutClass(fieldLayout),
30+
].join(' ')}
31+
>
32+
{React.Children.map(children, (child) => {
33+
if (!React.isValidElement(child)) {
34+
return null;
35+
}
36+
37+
return React.cloneElement(child, {
38+
inFormLayout: true,
39+
layout: fieldLayout,
40+
});
41+
})}
42+
</div>
43+
);
44+
};
45+
46+
FormLayout.defaultProps = {
47+
children: null,
48+
fieldLayout: 'vertical',
49+
id: undefined,
50+
};
51+
52+
FormLayout.propTypes = {
53+
children: PropTypes.node,
54+
fieldLayout: PropTypes.oneOf(['horizontal', 'vertical']),
55+
id: PropTypes.string,
56+
};
57+
58+
export default FormLayout;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@import '../../../styles/settings/forms';
2+
@import '../../../styles/settings/forms-theme';
3+
@import '../../../styles/settings/layouts';
4+
@import '../../../styles/tools/breakpoints';
5+
@import '../../../styles/tools/offset';
6+
7+
.root {
8+
margin-bottom: $layout-common-bottom-offset;
9+
}
10+
11+
.rootFieldLayoutVertical,
12+
.rootFieldLayoutHorizontal {
13+
display: grid;
14+
grid-template-columns: 1fr;
15+
grid-row-gap: $form-field-vertical-outer-spacing;
16+
}
17+
18+
.rootFieldLayoutHorizontal {
19+
@include breakpoint-up($form-field-horizontal-breakpoint) {
20+
grid-template-columns: $form-layout-horizontal-label-width 1fr;
21+
grid-column-gap: $form-field-horizontal-inner-gap;
22+
}
23+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './FormLayout';

src/lib/components/layout/List/List.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
@import '../../../styles/settings/layouts';
12
@import '../../../styles/tools/offset';
23

34
.root {
4-
margin-bottom: offset(4);
5+
margin-bottom: $layout-common-bottom-offset;
56
}
67

78
.list {

src/lib/components/layout/Media/Media.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
@import '../../../styles/settings/layouts';
12
@import '../../../styles/tools/offset';
23

34
.media {
45
display: flex;
56
align-items: flex-start;
6-
margin-bottom: offset(3);
7+
margin-bottom: $layout-common-bottom-offset;
78
}
89

910
.object {

src/lib/components/layout/Row/Row.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
@import '../../../styles/settings/layouts';
12
@import '../../../styles/tools/offset';
23

34
.row {
45
display: flex;
56
flex-wrap: wrap;
67
align-items: baseline;
7-
margin-bottom: offset(3);
8+
margin-bottom: $layout-common-bottom-offset;
89
}
910

1011
.start,

src/lib/components/screens/Login/__tests__/__snapshots__/ForgotPassword.test.jsx.snap

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ exports[`rendering renders correctly 1`] = `
4848
fullWidth={true}
4949
helperText={null}
5050
id="resetEmailInput"
51+
inFormLayout={false}
5152
inputSize={null}
5253
isLabelVisible={true}
5354
label="E-mail"
@@ -62,6 +63,7 @@ exports[`rendering renders correctly 1`] = `
6263
<label
6364
className="root
6465
isRootFullWidth
66+
6567
rootLayoutVertical
6668
isRootRequired
6769
rootSizeMedium
@@ -198,6 +200,7 @@ exports[`rendering renders correctly 2`] = `
198200
fullWidth={true}
199201
helperText={null}
200202
id="resetEmailInput"
203+
inFormLayout={false}
201204
inputSize={null}
202205
isLabelVisible={true}
203206
label="E-mail"
@@ -212,6 +215,7 @@ exports[`rendering renders correctly 2`] = `
212215
<label
213216
className="root
214217
isRootFullWidth
218+
215219
rootLayoutVertical
216220
isRootRequired
217221
rootSizeMedium
@@ -376,6 +380,7 @@ exports[`rendering renders correctly with all props except translations 1`] = `
376380
fullWidth={true}
377381
helperText={null}
378382
id="custom-id__resetEmailInput"
383+
inFormLayout={false}
379384
inputSize={null}
380385
isLabelVisible={true}
381386
label="E-mail"
@@ -390,6 +395,7 @@ exports[`rendering renders correctly with all props except translations 1`] = `
390395
<label
391396
className="root
392397
isRootFullWidth
398+
393399
rootLayoutVertical
394400
isRootRequired
395401
rootSizeMedium

0 commit comments

Comments
 (0)