Skip to content

Instantly share code, notes, and snippets.

@trotzig
Last active March 31, 2017 20:53
Show Gist options
  • Save trotzig/56d1232ff48c14514371934d72fd59dd to your computer and use it in GitHub Desktop.
Save trotzig/56d1232ff48c14514371934d72fd59dd to your computer and use it in GitHub Desktop.
import { addEventListener, removeEventListener } from 'consolidated-events';
import React, { PureComponent } from 'react';
/**
* HoC that injects a `contextWidth` prop to the component, equal to the
* available width in the current context
*
* @param {Object} Component
* @return {Object} a wrapped Component
*/
export default function withContextWidth(Component) {
return class extends PureComponent {
constructor() {
super();
const initialState = {
contextWidth: undefined,
};
this.state = initialState;
this._handleDivRef = this._handleDivRef.bind(this);
this._resizeHandle = addEventListener(
window,
'resize',
() => this.setState(initialState),
{ passive: true },
);
}
componentWillUnmount() {
removeEventListener(this._resizeHandle);
}
_handleDivRef(domElement) {
if (!domElement) {
return;
}
this.setState({
contextWidth: domElement.offsetWidth,
});
}
render() {
if (typeof this.state.contextWidth === 'undefined') {
// This div will live in the document for a brief moment, just long
// enough for it to mount. We then use it to calculate its width, and
// replace it immediately with the underlying component.
return (
<div
style={{ flexGrow: '1' }}
ref={this._handleDivRef}
/>
);
}
return (
<Component
contextWidth={this.state.contextWidth}
{...this.props}
/>
);
}
};
}
@trotzig
Copy link
Author

trotzig commented Mar 31, 2017

@lencioni just pointed me at http://elementqueries.com/, which is basically what I'm trying to do here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment