Last active
August 29, 2015 14:19
-
-
Save dlmanning/262c8df1c8e70e980d04 to your computer and use it in GitHub Desktop.
react-svg-flexbox
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
import React from 'react'; | |
import { FlexContext, FlexBox } from 'flex'; | |
const { Component } = React; | |
class Container extends Component { | |
render () { | |
console.log('Rendering Container'); | |
return ( | |
<g> | |
<rect fill={this.props.color} | |
x="0" | |
y="0" | |
width={this.props.layout.width} | |
height={this.props.layout.height} /> | |
{this.props.children} | |
</g> | |
); | |
} | |
} | |
const Backdrop = FlexBox(Container, { | |
flexDirection: 'row', | |
flex: 1, | |
padding: 40, | |
justifyContent: 'flex-start' | |
}); | |
const Square = FlexBox(Container, { | |
height: 40, | |
width: 40 | |
}); | |
const containerStyle = { | |
width: 400, | |
height: 400 | |
} | |
export default class App extends Component { | |
render () { | |
return ( | |
<svg height="600" width="600"> | |
<FlexContext layout={containerStyle}> | |
<Backdrop color="#CE6E09"> | |
<Square color="#470300" /> | |
<Square color="#F6B968" /> | |
<Square color="#470300" /> | |
</Backdrop> | |
</FlexContext> | |
</svg> | |
) | |
} | |
} |
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
import React from 'react'; | |
import { FlexContext, FlexBox } from 'flex'; | |
const { Component } = React; | |
class Container extends Component { | |
render () { | |
console.log('Rendering Container'); | |
return ( | |
<g> | |
<rect fill={this.props.color} | |
x="0" | |
y="0" | |
width={this.props.layout.width} | |
height={this.props.layout.height} /> | |
{this.props.children} | |
</g> | |
); | |
} | |
} | |
const Backdrop = FlexBox(Container, { | |
flexDirection: 'row', | |
flex: 1, | |
padding: 40, | |
justifyContent: 'flex-start' | |
}); | |
const Square = FlexBox(Container, { | |
height: 40, | |
width: 40 | |
}); | |
const containerStyle = { | |
width: 400, | |
height: 400 | |
} | |
export default class App extends Component { | |
render () { | |
const board = []; | |
for (let i = 0; i < 64; i++) { | |
board[i] = i; | |
} | |
return ( | |
<svg height="600" width="600"> | |
<FlexContext layout={containerStyle}> | |
<Backdrop color="#CE6E09"> | |
{board.map(id => <Square key={id} color={id % 2 ? '#470300' : '#F6B968'} />)} | |
</Backdrop> | |
</FlexContext> | |
</svg> | |
) | |
} | |
} |
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
import React from 'react'; | |
import computeLayout from 'css-layout'; | |
const { Component } = React; | |
const styles = { children: [] }; | |
function setLayout (style, layout = styles, path = []) { | |
if (layout.style === undefined) { | |
layout.style = style; | |
} else { | |
let childLayout = { style: style, children: [] }; | |
layout.children.push(childLayout); | |
path.push(layout.children.length - 1); | |
layout = childLayout; | |
} | |
return { | |
path: path.slice(), | |
setLayout : function (style) { | |
return setLayout(style, layout, path.slice()); | |
} | |
} | |
} | |
export class FlexContext extends Component { | |
static childContextTypes = { | |
setLayout: React.PropTypes.func.isRequired, | |
getLayout: React.PropTypes.func.isRequired | |
} | |
constructor (props, context) { | |
super(); | |
this.state = {}; | |
const layout = props.layout || {} | |
const { setLayout: layoutFunc } = setLayout(layout); | |
this.setLayout = layoutFunc; | |
} | |
getLayout = (path = []) => { | |
if (this.state.flexStyles !== undefined && path.length > 0) { | |
let layout = this.state.flexStyles; | |
path.forEach(childIndex => { | |
layout = layout.children[childIndex] | |
}); | |
return layout; | |
} else { | |
return { | |
top: 0, | |
left: 0, | |
width: 0, | |
height: 0 | |
}; | |
} | |
} | |
getChildContext () { | |
return { | |
setLayout: this.setLayout, | |
getLayout: this.getLayout | |
} | |
} | |
render () { | |
console.log('Rendering FlexContainer'); | |
return <g>{this.props.children}</g>; | |
} | |
componentDidMount () { | |
console.log('FlexContainer did mount'); | |
const flexStyles = computeLayout(styles); | |
this.setState({ flexStyles: flexStyles }); | |
} | |
} | |
export const FlexBox = (Composed, style = {}) => class extends Component { | |
static displayName = 'FlexBox'; | |
static contextTypes = { | |
setLayout: React.PropTypes.func.isRequired, | |
getLayout: React.PropTypes.func.isRequired | |
} | |
static childContextTypes = { | |
setLayout: React.PropTypes.func.isRequired | |
} | |
constructor (props, context) { | |
super(); | |
const { setLayout: layoutFunc, path} = context.setLayout(style); | |
this.setLayout = layoutFunc; | |
this.pathToNode = path; | |
} | |
getChildContext () { | |
return { | |
setLayout: this.setLayout | |
} | |
} | |
render () { | |
const layout = this.context.getLayout(this.pathToNode); | |
const transformation = `translate(${layout.left},${layout.top})` | |
return <g transform={transformation}><Composed {...this.props} layout={layout}/></g>; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment