Skip to content

Commit 4d2af9c

Browse files
nathanstittsilvenon
authored andcommitted
Export row/column prop builder functions (#95)
* Export row/column prop builder functions Previously the get<Row/Column>Class methods exported an array of classNames, which wasn't really suitable for passing directly onto a className prop. Plus it didn't clean the props so the caller would know which were intended for them and which were sizing props This changes the exports to return an object with a `className` property and the rest of the props, so you can do something like: `{className, ...otherProps} = getColumnProps(this.props)` * Update composition example to show use with a third-party component * Change component name, improve explanation * Demonstrate re-use of existing propType validations
1 parent 8cc6553 commit 4d2af9c

File tree

7 files changed

+47
-23
lines changed

7 files changed

+47
-23
lines changed

README.md

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,36 @@ Looking for example to use `react-flexbox-grid`? Head over to [react-flexbox-gri
5959

6060
Advanced composition
6161
-------
62-
Functions for generating Row and Column classNames are exported for use in other components. For example, suppose you have a `MyFormInput` component that should also act as both a `Row` and a `Col`.
62+
Functions for generating Row and Column classNames are exported for use in other components.
63+
64+
For example, suppose you're using a third party component that accepts a className and you would like it to be rendered as Column. You could do so by extracting the column sizing props that `MyComponent` uses and then pass the generated className on to `SomeComponent`
65+
6366

6467
```js
65-
import {getRowClassNames, getColClassNames} from 'react-flexbox-grid'
68+
import React from 'react';
69+
import { Row, Col, getRowProps, getColumnProps } from 'react-flexbox-grid';
70+
// a component that accepts a className
71+
import SomeComponent from 'some-package';
72+
73+
export default function MyComponent(props) {
74+
const colProps = getColumnProps(props);
75+
const rowProps = getRowProps(props);
6676

67-
export default function MyFormInput(props) {
6877
return (
69-
<form className={getRowClassNames(props)}>
70-
<input className={getColClassNames(props)} />
78+
<form className={rowProps.className}>
79+
<SomeComponent classname={colProps.className} />
80+
<input value={props.value} onChange={props.onChange} />
7181
</form>
7282
);
7383
}
7484

75-
// Can now be rendered as: <MyFormInput end="sm" sm={8} />
76-
```
77-
85+
MyComponent.propTypes = Object.assign({
86+
onChange: React.PropTypes.func.isRequired,
87+
value: React.PropTypes.string.isRequired,
88+
}, Col.propTypes, Row.propTypes); // Re-use existing Row and Col propType validations
7889

90+
// Can now be rendered as: <MyComponent end="sm" sm={8} value="my input value" onChange={...} />
91+
```
7992

8093
Installation
8194
------------

src/components/Col.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ function isInteger(value) {
3535
return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
3636
}
3737

38-
export function getColClassNames(props) {
38+
function getColClassNames(props) {
3939
const extraClasses = [];
4040

4141
if (props.className) {
@@ -60,10 +60,13 @@ export function getColClassNames(props) {
6060
.concat(extraClasses);
6161
}
6262

63-
export default function Col(props) {
64-
const classNames = getColClassNames(props);
63+
export function getColumnProps(props) {
64+
return createProps(propTypes, props, getColClassNames(props));
65+
}
6566

66-
return React.createElement(props.tagName || 'div', createProps(propTypes, props, classNames));
67+
export default function Col(props) {
68+
const { tagName, ...columnProps } = props;
69+
return React.createElement(tagName || 'div', getColumnProps(columnProps));
6770
}
6871

6972
Col.propTypes = propTypes;

src/components/Row.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const propTypes = {
2020
children: PropTypes.node
2121
};
2222

23-
export function getRowClassNames(props) {
23+
function getRowClassNames(props) {
2424
const modificators = [props.className, getClass('row')];
2525

2626
for (let i = 0; i < rowKeys.length; ++i) {
@@ -38,8 +38,12 @@ export function getRowClassNames(props) {
3838
return modificators;
3939
}
4040

41+
export function getRowProps(props) {
42+
return createProps(propTypes, props, getRowClassNames(props));
43+
}
44+
4145
export default function Row(props) {
42-
return React.createElement(props.tagName || 'div', createProps(propTypes, props, getRowClassNames(props)));
46+
return React.createElement(props.tagName || 'div', getRowProps(props));
4347
}
4448

4549
Row.propTypes = propTypes;

src/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export Grid from './components/Grid';
2-
export Row, { getRowClassNames } from './components/Row';
3-
export Col, { getColClassNames } from './components/Col';
2+
export Row, { getRowProps } from './components/Row';
3+
export Col, { getColumnProps } from './components/Col';

test/components/Col.spec.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import expect from 'expect';
22
import React from 'react';
33
import TestUtils from 'react-addons-test-utils';
4-
import Col, { getColClassNames } from '../../src/components/Col';
4+
import Col, { getColumnProps } from '../../src/components/Col';
55
import style from 'flexboxgrid';
66

77
const renderer = TestUtils.createRenderer();
@@ -17,8 +17,10 @@ describe('Col', () => {
1717
expect(className).toContain(style['col-lg-4']);
1818
});
1919

20-
it('Computes the classNames', () => {
21-
expect(getColClassNames({ className: 'test', xs: 12 })).toEqual([style['col-xs-12'], 'test']);
20+
it('Computes the column properties', () => {
21+
expect(getColumnProps({ className: 'test', xs: 12, unknown: 'foo' })).toEqual({
22+
unknown: 'foo', className: `${style['col-xs-12']} test`
23+
});
2224
});
2325

2426
it('Should add "first-*" class if "first" property is set', () => {

test/components/Row.spec.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import expect from 'expect';
22
import React from 'react';
33
import TestUtils from 'react-addons-test-utils';
4-
import Row, { getRowClassNames } from '../../src/components/Row';
4+
import Row, { getRowProps } from '../../src/components/Row';
55
import style from 'flexboxgrid';
66

77
const renderer = TestUtils.createRenderer();
@@ -12,8 +12,10 @@ describe('Row', () => {
1212
expect(renderer.getRenderOutput().props.className).toEqual(style.row);
1313
});
1414

15-
it('Computes the classNames', () => {
16-
expect(getRowClassNames({ className: 'test', reverse: true })).toEqual(['test', style.row, style.reverse]);
15+
it('Computes the row properties', () => {
16+
expect(getRowProps({ className: 'test', reverse: true, unknown: 'bar' })).toEqual({
17+
unknown: 'bar', className: `test ${style.row} ${style.reverse}`
18+
});
1719
});
1820

1921
it('Should add "reverse" class if "reverse" property is true', () => {

test/index.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as Exports from '../src/index';
33

44
describe('react-flexbox-grid exports', () => {
55
it('exports all the symbols it should', () => {
6-
['Grid', 'Row', 'Col', 'getColClassNames', 'getRowClassNames'].forEach((prop) => {
6+
['Grid', 'Row', 'Col', 'getColumnProps', 'getRowProps'].forEach((prop) => {
77
expect(Exports.hasOwnProperty(prop)).toBe(true);
88
});
99
});

0 commit comments

Comments
 (0)