Skip to content

Instantly share code, notes, and snippets.

@iammerrick
Created May 25, 2016 17:06
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save iammerrick/1b6c8b78a6581abfed9940daab20b75a to your computer and use it in GitHub Desktop.
Save iammerrick/1b6c8b78a6581abfed9940daab20b75a 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.
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>
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