-
-
Save insin/5113176bc6074249a7954f67756d9db9 to your computer and use it in GitHub Desktop.
A React component that computes the ratio based on the width or height of a given container.
This file contains hidden or 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 { FluidRatio } from './FluidRatio'; | |
<FluidRatio> | |
{(width, height) => ( | |
<div style={{ width, height }}>This will be a ratio of 3/4 with a width of whatever container it is rendered into.</div> | |
)} | |
</FluidRatio> |
This file contains hidden or 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'; | |
const AXIS = { | |
X: 'X', | |
Y: 'Y' | |
}; | |
export class FluidRatio extends React.Component { | |
constructor() { | |
super(...arguments); | |
this.state = { | |
hasComputed: false, | |
width: 0, | |
height: 0 | |
}; | |
} | |
getComputedDimensions({axis, x, y}) { | |
if (axis === AXIS.X) { | |
const {width} = this.refs.container.getBoundingClientRect(); | |
return { | |
width, | |
height: width * (y / x) | |
}; | |
} | |
const {height} = this.refs.container.getBoundingClientRect(); | |
return { | |
height, | |
width: height * (x / y) | |
}; | |
} | |
componentWillReceiveProps(next) { | |
this.setState(this.getComputedDimensions(next)); | |
} | |
componentDidMount() { | |
this.setState({ | |
...this.getComputedDimensions(this.props), | |
hasComputed: true | |
}); | |
} | |
shouldComponentUpdate(props, state) { | |
return state.width !== this.state.width || state.height !== this.state.height; | |
} | |
render() { | |
const renderedChildren = (this.state.hasComputed) | |
? this.props.children(this.state.width, this.state.height) | |
: null; | |
return ( | |
<div ref='container'> | |
{renderedChildren} | |
</div> | |
); | |
} | |
} | |
FluidRatio.AXIS = AXIS; | |
FluidRatio.propTypes = { | |
x: React.PropTypes.number.isRequired, | |
y: React.PropTypes.number.isRequired, | |
axis: React.PropTypes.oneOf(Object.keys(AXIS)), | |
children: React.PropTypes.func.isRequired | |
}; | |
FluidRatio.defaultProps = { | |
x: 3, | |
y: 4, | |
axis: AXIS.X | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment