Skip to content

Commit

Permalink
feat(flex-grid): Document the props. Refactor the gutterless prop to …
Browse files Browse the repository at this point in the history
…be in the positive.

Switching to gutter instead of gutterless is cognitively easier to reason about as it is written in
the positive tense.
  • Loading branch information
ryanoglesby08 committed Dec 13, 2017
1 parent 35e4fb0 commit 937682c
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 72 deletions.
34 changes: 21 additions & 13 deletions src/components/FlexGrid/Col.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,33 @@ const removeProps = ({
}) => safeRest(rest)

const Col = ({ span, offset, children, ...rest }) => (
<Subscriber channel="gutterless">
{gutterless => {
return (
<ReactFlexboxGridCol
{...removeProps(rest)}
xs={span || true}
xsOffset={offset}
style={gutterless}
>
{children}
</ReactFlexboxGridCol>
)
}}
<Subscriber channel="flex-grid">
{gutterStyle => (
<ReactFlexboxGridCol
{...removeProps(rest)}
xs={span || true}
xsOffset={offset}
style={gutterStyle}
>
{children}
</ReactFlexboxGridCol>
)}
</Subscriber>
)

Col.propTypes = {
/**
* Span the specified number of columns.
*/
span: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),
/**
* Offset the specified number of columns.
*/
offset: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]),
/**
* The columns of the Grid. Will typically be `FlexGrid.Col` components, but could be other components such as a
* `Responsive` wrapper.
*/
children: PropTypes.node.isRequired,
}

Expand Down
19 changes: 13 additions & 6 deletions src/components/FlexGrid/FlexGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,32 @@ import safeRest from '../../utils/safeRest'
import Col from './Col'
import Row from './Row'

const FlexGrid = ({ gutterless, children, ...rest }) => {
const css = gutterless ? { padding: 0, margin: 0 } : undefined
const FlexGrid = ({ gutter, children, ...rest }) => {
const gutterStyle = gutter ? undefined : { padding: 0, margin: 0 }

return (
<Broadcast channel="gutterless" value={css}>
<Grid {...safeRest(rest)} fluid style={css}>
<Broadcast channel="flex-grid" value={gutterStyle}>
<Grid {...safeRest(rest)} fluid style={gutterStyle}>
{children}
</Grid>
</Broadcast>
)
}

FlexGrid.propTypes = {
gutterless: PropTypes.bool,
/**
* Whether or not to include gutters in between columns.
*/
gutter: PropTypes.bool,
/**
* The rows of the Grid. Will typically be `FlexGrid.Row` components, but could be other components such as a
* `Responsive` wrapper.
*/
children: PropTypes.node.isRequired,
}

FlexGrid.defaultProps = {
gutterless: false,
gutter: true,
}

FlexGrid.Row = Row
Expand Down
14 changes: 6 additions & 8 deletions src/components/FlexGrid/Row.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ import { Row as ReactFlexboxGridRow } from 'react-flexbox-grid'
import safeRest from '../../utils/safeRest'

const Row = ({ children, ...rest }) => (
<Subscriber channel="gutterless">
{gutterless => {
return (
<ReactFlexboxGridRow {...safeRest(rest)} style={gutterless}>
{children}
</ReactFlexboxGridRow>
)
}}
<Subscriber channel="flex-grid">
{gutterStyle => (
<ReactFlexboxGridRow {...safeRest(rest)} style={gutterStyle}>
{children}
</ReactFlexboxGridRow>
)}
</Subscriber>
)

Expand Down
72 changes: 32 additions & 40 deletions src/components/FlexGrid/__tests__/FlexGrid.spec.jsx
Original file line number Diff line number Diff line change
@@ -1,87 +1,79 @@
import React from 'react'
import { mount } from 'enzyme'
import { mount, render } from 'enzyme'

import { Grid } from 'react-flexbox-grid'

import Responsive from '../../Responsive/Responsive'
import FlexGrid from '../FlexGrid'

describe('FlexGrid', () => {
const doMount = (props = {}) => {
const wrapper = mount(<FlexGrid {...props}>Some grid stuff</FlexGrid>)
return wrapper.find('Grid')
}

const doMountWithChildren = (props = {}) => {
const flexGrid = mount(
<FlexGrid {...props}>
<Responsive id="responsive" minWidth="md">
{match => {
return (
<FlexGrid.Col>
<div>HALF: {match}</div>
</FlexGrid.Col>
)
}}
</Responsive>
<FlexGrid.Row>
<FlexGrid.Col>HALF</FlexGrid.Col>
<FlexGrid.Col>HALF</FlexGrid.Col>
<FlexGrid.Row id="row-1">
<FlexGrid.Col id="col-1">1st column content</FlexGrid.Col>
<FlexGrid.Col id="col-2">2nd column content</FlexGrid.Col>
</FlexGrid.Row>
</FlexGrid>
)

return {
findColum: index => flexGrid.find('Col').at(index),
findRow: index => flexGrid.find('Row').at(index),
findNowRelated: el => flexGrid.find(el),
gutterless: { padding: 0, margin: 0 },
flexGrid: flexGrid.find(Grid),
findColumn: index => flexGrid.find(`div#col-${index}`),
findRow: index => flexGrid.find(`div#row-${index}`),
}
}

const expectToHaveNoGutter = element => {
expect(element).toHaveStyle('padding', 0)
expect(element).toHaveStyle('margin', 0)
}

it('renders', () => {
const flexGrid = doMount()
const flexGrid = render(
<FlexGrid>
<FlexGrid.Row>
<FlexGrid.Col>1st column content</FlexGrid.Col>
<FlexGrid.Col>2nd column content</FlexGrid.Col>
</FlexGrid.Row>
</FlexGrid>
)

expect(flexGrid).toMatchSnapshot()
})

it('renders a react-flexbox-grid Grid component', () => {
const flexGrid = doMount()
const { flexGrid } = doMount()

expect(flexGrid).toMatchSelector(Grid)
})

it('is fluid by default', () => {
const flexGrid = doMount()
const { flexGrid } = doMount()

expect(flexGrid).toHaveProp('fluid', true)
})

it('should render all children related to Grid with no gutter', () => {
const { findColum, findRow, findNowRelated, gutterless } = doMountWithChildren({
gutterless: true,
})
const { findColumn, findRow } = doMount({ gutter: false })

const col1 = findColum(1)
const col2 = findColum(3)
const col3 = findColum(5)
const col1 = findColumn(1)
const col2 = findColumn(2)
const row = findRow(1)
const NonRelatedElement = findNowRelated('Responsive')

expect(col1).toHaveProp('style', gutterless)
expect(col2).toHaveProp('style', gutterless)
expect(col3).toHaveProp('style', gutterless)
expect(row).toHaveProp('style', gutterless)
expect(NonRelatedElement).not.toHaveProp('style', gutterless)
expectToHaveNoGutter(col1)
expectToHaveNoGutter(col2)
expectToHaveNoGutter(row)
})

it('passes additional attributes to the element', () => {
const flexGrid = doMount({ id: 'the-id', 'data-some-attr': 'some value' })
const { flexGrid } = doMount({ id: 'the-id', 'data-some-attr': 'some value' })

expect(flexGrid).toHaveProp('id', 'the-id')
expect(flexGrid).toHaveProp('data-some-attr', 'some value')
})

it('does not allow custom CSS', () => {
const flexGrid = doMount({
const { flexGrid } = doMount({
className: 'my-custom-class',
style: { color: 'hotpink' },
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`FlexGrid renders 1`] = `
<Grid
fluid={true}
<div
class="container-fluid"
>
<div
className="container-fluid"
class="row"
>
Some grid stuff
<div
class="col-xs col-xs-offset"
>
1st column content
</div>
<div
class="col-xs col-xs-offset"
>
2nd column content
</div>
</div>
</Grid>
</div>
`;

0 comments on commit 937682c

Please sign in to comment.