import React from 'react'; import PropTypes from 'prop-types'; import Base from './Base'; import style from './style'; const namespaceProps = { 'xmlns': 'http://www.w3.org/2000/svg', 'xmlns:cc': 'http://creativecommons.org/ns#', 'xmlns:rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' }; const metadata = ` `; /** @extends React.PureComponent */ class Image extends Base { static defaultProps = { padding: 10 } publishedMarkup = '' state = { width: 0, height: 0 } componentDidMount() { this.doReflow().then(() => this.publishMarkup()); } componentDidUpdate() { this.doReflow().then(() => this.publishMarkup()); } publishMarkup() { const { onRender } = this.props; const markup = this.svg.outerHTML; if (onRender && this.publishedMarkup !== markup) { this.publishedMarkup = markup; onRender(this.svg.outerHTML); } } preReflow() { return this.contained; } reflow() { return new Promise(resolve => { const { padding } = this.props; const box = this.contained.getBBox(); this.setState({ width: Math.round(box.width + 2 * padding), height: Math.round(box.height + 2 * padding) }, resolve); }); } containedRef = contained => this.contained = contained svgRef = svg => this.svg = svg render() { const { width, height } = this.state; const { padding, children } = this.props; const svgProps = { width, height, viewBox: [0, 0, width, height].join(' '), style: style.image, ref: this.svgRef, ...namespaceProps }; return { React.cloneElement(React.Children.only(children), { ref: this.containedRef }) } ; } } Image.propTypes = { onRender: PropTypes.func, padding: PropTypes.number, children: PropTypes.node }; export default Image;