UNPKG

@platform/react

Version:

React refs and helpers.

90 lines (89 loc) 2.66 kB
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); };