I have a react component where it shows a <svg>
. There is a <text>
attribute which will be changed over the time. I want make the <svg>
grow it's width to display the complete text
. How to make following component's size dynamic to the length of the text?
const S = {
Container: styled.div`
background: red;
width: '10px';
height: '10px';
`
};
export class RectNode extends Component<IRectNodeProps> {
render() {
return (
<S.Container>
<svg width="auto" height="auto">
<rect
x="0"
y="0"
width="100%"
height="100%"
stroke="red"
stroke-width="3px"
fill="white"
/>
// more shapes here
<text
x="50%"
y="50%"
dominant-baseline="middle"
text-anchor="middle"
>
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
</text>
</svg>
</S.Container>
);
}
}
JS Fiddle:
<svg width="auto" height="auto">
<rect
x="0"
y="0"
width="100%"
height="100%"
stroke="red"
stroke-width="3px"
fill="white"
/>
// more shapes here
<text
x="50%"
y="50%"
dominant-baseline="middle"
text-anchor="middle"
>
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
</text>
</svg>
Get the text BBox after render and set the SVG width attribute by changing state. The example here.
class SvgComponent extends React.Component {
state = {width: 0};
componentDidMount() {
this.updateTextSize();
}
componentDidUpdate() {
this.updateTextSize();
}
updateTextSize() {
const box = this.text.getBBox();
if(this.state.width !== box.width) {
this.setState({width: box.width});
}
}
render() {
return (
<svg width={this.state.width} height="40">
<text ref={handle => this.text = handle} x="50%" y="25" textAnchor="middle">
{this.props.text}
</text>
</svg>
);
}
}