-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Layout]: Add new Layout
components
#5267
Closed
Closed
Changes from all commits
Commits
Show all changes
70 commits
Select commit
Hold shift + click to select a range
48700a8
[style]: Add `priority` and `isMatch`
65c9775
[Layout]: Add a new `Layout` components
460df18
[mocha]: jsdom stub `window.matchMedia` function
b4309bf
[Layout]: fix some of the `flex` issues
2f451e3
[babel] Fix plugin format
oliviertassinari 9f72b65
[test] Improve the solution
oliviertassinari 73e232c
[docs] Import the Related projects section from master
oliviertassinari 93ed119
[docs] Migrate required-knowledge section from master
oliviertassinari 8d85105
Add card component basics
nathanmarks a5cf000
Rebase and update docs
nathanmarks 377755b
Fix lint error
nathanmarks 1dc8259
Fix flow errors
nathanmarks 4696d17
[eslint] Go deeper in the folder strucutre
oliviertassinari 97a262b
[test] Fix the regression test suite on travis
oliviertassinari 1b2aa01
[test] Fix the regression test suite
oliviertassinari d590328
[TextField] Add required prop
leMaik 657760d
[TextField] Add a visual regression test
oliviertassinari 2339048
[test] Run eslint on more files
oliviertassinari c845258
[TextField] Follow the spec more closely
oliviertassinari fc8d5ac
[test] Run eslint on more files
oliviertassinari a131435
Update jss-theme-reactor and refactor sheet ordering configuration
nathanmarks e954567
Quick fix for ordering bug
nathanmarks b34363c
[npm] Upgrade the dependencies on the next
oliviertassinari bb94260
[react] Remove the static keyword from getChildContext methods
oliviertassinari 2c420b2
Use circleCI for next branch (#5366)
nathanmarks 1799ef2
Remove unused cache folder from circle config
nathanmarks c1f2f21
[ListItemText] Unwrap text from object
31c063a
[ListItemText] Add some test for the primary and secondary fix
oliviertassinari 6c5afff
[npm] Upgrade the dependencies
oliviertassinari 85806b2
[npm] Upgrade the dev dependencies
oliviertassinari c6703ad
[docs] Add a note regarding other properties
oliviertassinari fac0c82
[Subheader] Migration of subheader component
pradel 3a48889
[theme] Add ListSubheader to the list
oliviertassinari 19d5525
[Dialog] Fix an issue with the SSR
oliviertassinari ec09543
Hotfix a few instances of missing rule refs
nathanmarks 21b04a2
Remove component variable file (#5519)
nathanmarks bd52c19
[LinearProgress] Migration of linear-progress component (#5463)
pradel 85722fc
[LinearProgress] Add visual regression test
oliviertassinari 6d9894e
[npm] Upgrade the dependencies (#5530)
oliviertassinari 16757a9
[eslint] Lint more files
oliviertassinari d049564
[style] Add a withStyles HoC (#5542)
oliviertassinari 0ab76cf
[Dialog] add a paperClassName property
oliviertassinari 5a3599d
[style] use fontWeightRegular instead of fontWeightNormal as in the spec
oliviertassinari 0955977
[style] Iteration on the typography
oliviertassinari ba908ba
[npm] Upgrade the dependencies (#5598)
oliviertassinari 4574110
[Radio] label (outer element) should be customizable via labelClassNa…
rosskevin 5f64549
[TextField] Improve the required feature (#5599)
oliviertassinari 4db81d9
[BottomNavigation] Migration of bottom-navigation component (#5600)
oliviertassinari 1d38b3b
[TextField] Fix an issue on IE11
oliviertassinari 7aa3db6
[docs] Makes it run locally on windows box (#5602)
oliviertassinari 076a241
[docs] Improve the readability
oliviertassinari 975671a
[TextField] Use palette.text.primary for the input color
oliviertassinari b2ab6b6
[Dialog] Add a DialogContentText component (#5605)
oliviertassinari 6e23d39
[Divider] Add inset prop (#5617)
pradel d9f56c1
[Divider] Add visual regressions tests
pradel 455f739
[Checkbox] Add visual regressions tests
pradel f77698e
[IconButton] Add visual regressions tests
pradel 701bca9
Fix function name
pradel 32dd850
[Docs] Add more examples to list (#5616)
pradel acc52de
[Tabs] Initial migration of component
newoga a1f0bd1
[mocha]: jsdom stub `window.matchMedia` function
bb414cf
[test] Run eslint on more files
oliviertassinari 658e001
[git]: fix merge conflict
12c906c
[layout]: better nesting using `jss-nested`
fe2eb6c
[layout]: `flexNone` should be `0 0 auto`
7fd0af1
[Layout]: interactive demo
157cec5
Merge remote-tracking branch 'refs/remotes/upstream/next'
8c3e8c5
[Layout]: renaming to `LayoutInteractive`
238b670
[Layout]: fix typo
dbe2e25
[layout]: fix `offset` referencing `order` prop.
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// @flow weak | ||
|
||
import React, { PropTypes } from 'react'; | ||
import { createStyleSheet } from 'jss-theme-reactor'; | ||
import Block from 'material-ui/Layout'; | ||
import { darkWhite, teal, deepPurple } from 'material-ui/styles/colors'; | ||
|
||
const styleSheet = createStyleSheet('LayoutColumn', () => ({ | ||
root: { height: 150, width: '50%', backgroundColor: darkWhite }, | ||
cell1: { backgroundColor: teal[300] }, | ||
cell2: { backgroundColor: deepPurple[300] }, | ||
})); | ||
|
||
export default function LayoutColumn(props, context) { | ||
const { root, cell1, cell2 } = context.styleManager.render(styleSheet); | ||
return ( | ||
<Block className={root} layout="column"> | ||
<Block flex className={cell1}>First item</Block> | ||
<Block flex="20" className={cell2}>Second item</Block> | ||
</Block> | ||
); | ||
} | ||
|
||
LayoutColumn.contextTypes = { | ||
styleManager: PropTypes.object.isRequired, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
// @flow weak | ||
|
||
import React, { Component, PropTypes } from 'react'; | ||
import { createStyleSheet } from 'jss-theme-reactor'; | ||
import Block from 'material-ui/Layout'; | ||
import { Radio, RadioGroup } from 'material-ui/Radio'; | ||
import Switch from 'material-ui/Switch'; | ||
import Text from 'material-ui/Text'; | ||
import Button from 'material-ui/Button'; | ||
import IconButton from 'material-ui/IconButton'; | ||
import { teal, deepPurple } from 'material-ui/styles/colors'; | ||
|
||
const styleSheet = createStyleSheet('LayoutInteractive', ({ shadows, palette }) => ({ | ||
root: { width: 750, backgroundColor: palette.background.paper, position: 'relative' }, | ||
add: { position: 'absolute', top: '42%', right: 0 }, | ||
demo: { | ||
height: 300, | ||
boxShadow: shadows[1], | ||
}, | ||
zone: { | ||
'& > div': { | ||
'&:nth-child(even)': { backgroundColor: teal[300] }, | ||
'&:nth-child(odd)': { backgroundColor: deepPurple[300] }, | ||
}, | ||
}, | ||
})); | ||
|
||
export default class Interactive extends Component { | ||
static contextTypes = { | ||
styleManager: PropTypes.object.isRequired, | ||
} | ||
state = { | ||
block: { | ||
direction: 'row', | ||
justification: 'center', | ||
alignment: 'center', | ||
padding: false, | ||
margin: false, | ||
fill: false, | ||
wrap: false, | ||
}, | ||
cells: [{ flex: false }, { flex: false }, { flex: false }], | ||
} | ||
handleChange = (key) => (e, val) => { | ||
const { block } = this.state; | ||
this.setState({ block: { ...block, [key]: val } }); | ||
} | ||
setCell = (idx) => () => { | ||
const { cells } = this.state; | ||
if (idx === undefined && cells.length < 30) { | ||
this.setState({ cells: [...cells, { flex: false }] }); | ||
return; | ||
} | ||
if (cells.length > 1) { | ||
const cellSlice = cells.slice(); | ||
cellSlice.splice(idx, 1); | ||
this.setState({ cells: cellSlice }); | ||
} | ||
} | ||
render() { | ||
const { root, add, demo, zone } = this.context.styleManager.render(styleSheet); | ||
const { | ||
block: { direction, justification, alignment, padding, margin, fill, wrap }, | ||
cells, | ||
} = this.state; | ||
|
||
return ( | ||
<Block className={root} layout="column" margin> | ||
<Block flex="none" layout="row"> | ||
<Block flex layout="column"> | ||
<Text type="title">Direction</Text> | ||
<RadioGroup | ||
aria-label="Direction" | ||
selectedValue={direction} | ||
onChange={this.handleChange('direction')} | ||
> | ||
<Radio label="Row" value="row" /> | ||
<Radio label="Column" value="column" /> | ||
</RadioGroup> | ||
</Block> | ||
<Block flex> | ||
<Block layout="row" align="center"> | ||
<Text type="subheading">Padding</Text> | ||
<Switch | ||
checked={padding} | ||
onChange={this.handleChange('padding')} | ||
aria-label="padding" | ||
/> | ||
</Block> | ||
<Block layout="row" align="center"> | ||
<Text type="subheading">Margin</Text> | ||
<Switch | ||
checked={margin} | ||
onChange={this.handleChange('margin')} | ||
aria-label="margin" | ||
/> | ||
</Block> | ||
<Block layout="row" align="center"> | ||
<Text type="subheading">Fill</Text> | ||
<Switch | ||
checked={fill} | ||
onChange={this.handleChange('fill')} | ||
aria-label="fill" | ||
/> | ||
</Block> | ||
<Block layout="row" align="center"> | ||
<Text type="subheading">Wrap</Text> | ||
<Switch | ||
checked={wrap} | ||
onChange={this.handleChange('wrap')} | ||
aria-label="wrap" | ||
/> | ||
</Block> | ||
</Block> | ||
<Block flex> | ||
<Text type="title">Justification</Text> | ||
<RadioGroup | ||
aria-label="Justification" | ||
selectedValue={justification} | ||
onChange={this.handleChange('justification')} | ||
> | ||
<Radio label="Start" value="start" /> | ||
<Radio label="Center" value="center" /> | ||
<Radio label="End" value="end" /> | ||
<Radio label="Space Between" value="space-between" /> | ||
<Radio label="Space Around" value="space-around" /> | ||
</RadioGroup> | ||
</Block> | ||
<Block flex> | ||
<Text type="title">Alignment</Text> | ||
<RadioGroup | ||
aria-label="Alignment" | ||
selectedValue={alignment} | ||
onChange={this.handleChange('alignment')} | ||
> | ||
<Radio label="Start" value="start" /> | ||
<Radio label="Center" value="center" /> | ||
<Radio label="End" value="end" /> | ||
<Radio label="Stretch" value="stretch" /> | ||
</RadioGroup> | ||
</Block> | ||
</Block> | ||
<Button | ||
fab | ||
accent | ||
disabled={cells.length >= 30} | ||
onClick={this.setCell()} | ||
className={add} | ||
> | ||
<span className="material-icons">add</span> | ||
</Button> | ||
<Block flex className={demo} layout="row"> | ||
<Block | ||
scroll | ||
className={zone} | ||
flex | ||
layout={direction} | ||
justify={justification} | ||
align={alignment} | ||
padding={padding} | ||
margin={margin} | ||
fill={fill} | ||
wrap={wrap} | ||
> | ||
{ | ||
cells.map((cell, i) => ( | ||
<Block {...cell} layout="row" align="center"> | ||
<IconButton accent onClick={this.setCell(i)}>delete</IconButton> | ||
<Button>{`Cell ${i + 1}`}</Button> | ||
</Block> | ||
)) | ||
} | ||
</Block> | ||
</Block> | ||
</Block> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// @flow weak | ||
|
||
import React, { PropTypes } from 'react'; | ||
import { createStyleSheet } from 'jss-theme-reactor'; | ||
import Block from 'material-ui/Layout'; | ||
import { darkWhite, teal, deepPurple } from 'material-ui/styles/colors'; | ||
|
||
const styleSheet = createStyleSheet('LayoutRow', () => ({ | ||
root: { height: 150, width: '50%', backgroundColor: darkWhite }, | ||
cell1: { backgroundColor: teal[300] }, | ||
cell2: { backgroundColor: deepPurple[300] }, | ||
})); | ||
|
||
export default function LayoutRow(props, context) { | ||
const { root, cell1, cell2 } = context.styleManager.render(styleSheet); | ||
return ( | ||
<Block className={root} layout="row"> | ||
<Block className={cell1} flex>First item</Block> | ||
<Block className={cell2} flex="20">Second item</Block> | ||
</Block> | ||
); | ||
} | ||
|
||
LayoutRow.contextTypes = { | ||
styleManager: PropTypes.object.isRequired, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Layout | ||
|
||
Layout is based on [flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes) and inspired by [angular material](https://material.angularjs.org/latest/layout/introduction) | ||
|
||
|
||
## Row layout | ||
|
||
{{demo='demos/layout/LayoutRow.js'}} | ||
|
||
## Column layout | ||
|
||
{{demo='demos/layout/LayoutColumn.js'}} | ||
|
||
|
||
## Play | ||
|
||
{{demo='demos/layout/LayoutInteractive.js'}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// @flow weak | ||
import withLayout from './with-layout'; | ||
|
||
/* | ||
* This is the Base <Block /> Element | ||
*/ | ||
export default withLayout('div'); | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
// @flow weak | ||
/* eslint-env mocha */ | ||
/* eslint react/prop-types: off */ | ||
import React from 'react'; | ||
import { assert } from 'chai'; | ||
import { createShallowWithContext, createMountWithContext } from 'test/utils'; | ||
import Block from './Block'; | ||
import { styleSheet } from './with-layout'; | ||
|
||
describe('<Block /> component', () => { | ||
let shallow; | ||
let mount; | ||
let classes; | ||
before(() => { | ||
shallow = createShallowWithContext(); | ||
mount = createMountWithContext(); | ||
classes = shallow.context.styleManager.render(styleSheet); | ||
}); | ||
it('Renders a div', () => { | ||
const wrapper = shallow(<Block />); | ||
assert.isTrue(wrapper.is('div'), 'should be a div'); | ||
}); | ||
|
||
it('should render with layout classes', () => { | ||
const wrapper = shallow(<Block layout="row" />); | ||
const className = wrapper.prop('className'); | ||
assert.isOk(className, 'should have className prop'); | ||
const classNames = className.split(' '); | ||
const expected = [ | ||
classes.layoutRow, | ||
classes.alignStretch, | ||
classes.justifyStart, | ||
]; | ||
assert.sameMembers(classNames, expected, `should have className prop be ${expected.join(' ')}`); | ||
}); | ||
it('should create layout algin and justify property', () => { | ||
const wrapper = shallow( | ||
<Block | ||
layout="row" | ||
fill | ||
align="start" | ||
justify="start" | ||
/>, | ||
); | ||
const className = wrapper.prop('className'); | ||
assert.isOk(className, 'should have className prop'); | ||
const classNames = className.split(' '); | ||
const expected = [ | ||
classes.layoutRow, | ||
classes.layoutFill, | ||
classes.justifyStart, | ||
classes.alignStart, | ||
]; | ||
assert.sameMembers(classNames, expected, `should have className prop be ${expected.join(' ')}`); | ||
}); | ||
|
||
it('should render child component.', () => { | ||
const wrapper = shallow(<Block layout="row"><span>Hello</span></Block>); | ||
assert.isTrue(wrapper.childAt(0).is('span'), 'should be a `span`'); | ||
}); | ||
|
||
it('should include the existing className', () => { | ||
const wrapper = shallow(<Block className="someClass" layout="row"><span>Hello</span></Block>); | ||
const className = wrapper.prop('className'); | ||
assert.isOk(className, 'should have className prop'); | ||
assert.include(className, 'someClass', '`someClass` class name be part of `className` prop'); | ||
}); | ||
|
||
describe('flex props', () => { | ||
let wrapper; | ||
before(() => { | ||
wrapper = mount( | ||
<Block layout="row"> | ||
<Block flex>just flex</Block> | ||
<Block flex={33}>flex 33%</Block> | ||
<Block flex={50}>flex 50%</Block> | ||
<Block flex="none">flex none</Block> | ||
<Block flex="grow">flex none</Block> | ||
<Block flex order={3}>flex none</Block> | ||
<Block flex order={-10}>flex none</Block> | ||
<Block flex offset={2}>flex none</Block> | ||
</Block>, | ||
); | ||
}); | ||
it('should have .flex class', () => { | ||
const actual = wrapper.childAt(0).find('div').prop('className'); | ||
const expected = classes.flex; | ||
assert.strictEqual(actual, expected); | ||
}); | ||
it('should have .flex33 class', () => { | ||
const actual = wrapper.childAt(1).find('div').prop('className'); | ||
const expected = classes.flex33; | ||
assert.strictEqual(actual, expected); | ||
}); | ||
it('should have .flex50 class', () => { | ||
const actual = wrapper.childAt(2).find('div').prop('className'); | ||
const expected = classes.flex50; | ||
assert.strictEqual(actual, expected); | ||
}); | ||
it('should have .flexNone class', () => { | ||
const actual = wrapper.childAt(3).find('div').prop('className'); | ||
const expected = classes.flexNone; | ||
assert.strictEqual(actual, expected); | ||
}); | ||
it('should have .flexGrow class', () => { | ||
const actual = wrapper.childAt(4).find('div').prop('className'); | ||
const expected = classes.flexGrow; | ||
assert.strictEqual(actual, expected); | ||
}); | ||
it('should have .flexOrder3 class', () => { | ||
const actual = wrapper.childAt(5).find('div').prop('className'); | ||
const expected = classes.flexOrder3; | ||
assert.include(actual, expected); | ||
}); | ||
it('should have .flexOrder-10 class', () => { | ||
const actual = wrapper.childAt(6).find('div').prop('className'); | ||
const expected = classes['flexOrder-10']; | ||
assert.include(actual, expected); | ||
}); | ||
it('should have .flexOffset2 class', () => { | ||
const actual = wrapper.childAt(7).find('div').prop('className'); | ||
const expected = classes.flexOffset2; | ||
assert.include(actual, expected); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/* eslint-disable flowtype/require-valid-file-annotation */ | ||
|
||
export default from './Block'; | ||
export Block from './Block'; | ||
export withLayout from './with-layout'; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious about this API decision. What's the benefit of having a Higer order Component over a component that accepts a
component
property?