@platform/react
Version:
React refs and helpers.
90 lines (89 loc) • 2.66 kB
JavaScript
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { css } from '@platform/css';
const HIDDEN = {
position: 'absolute',
left: -999999,
top: -999999,
};
class Measurer {
constructor(props) {
this.props = props;
this.div = document.createElement('DIV');
document.body.appendChild(this.div);
const ref = (el) => (this.component = el);
ReactDOM.render(React.createElement(MeasureSize, Object.assign({ ref: ref }, props, { style: HIDDEN })), this.div);
}
static measure(props) {
const instance = new Measurer(props);
const size = instance.size;
instance.dispose();
return size;
}
dispose() {
if (!this.isDisposed) {
ReactDOM.unmountComponentAtNode(this.div);
document.body.removeChild(this.div);
}
}
get isDisposed() {
return !Boolean(this.component);
}
get width() {
return this.component ? this.component.width : -1;
}
get height() {
return this.component ? this.component.height : -1;
}
get size() {
const width = this.width;
const height = this.height;
return { width, height };
}
}
Measurer.create = (props) => {
return {
props,
size: (content) => Measurer.measure(Object.assign(Object.assign({}, props), { content })),
};
};
export class MeasureSize extends React.PureComponent {
static measure(props) {
return Measurer.measure(props);
}
componentDidMount() {
const el = ReactDOM.findDOMNode(this);
this.el = el.firstChild;
}
get width() {
return this.el ? this.el.offsetWidth : -1;
}
get height() {
return this.el ? this.el.offsetHeight : -1;
}
get size() {
const width = this.width;
const height = this.height;
return { width, height };
}
render() {
const { content, fontFamily, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, width, } = this.props;
const styles = {
text: css({
display: 'inline-block',
fontFamily,
fontSize,
fontWeight: fontWeight,
fontStyle,
lineHeight,
letterSpacing,
width,
}),
};
return (React.createElement("div", Object.assign({ className: 'platform.MeasureText' }, css(this.props.style)),
React.createElement("div", Object.assign({}, styles.text), content)));
}
}
MeasureSize.create = (props) => {
return Measurer.create(props);
};