I have a React component that can render one string or another.
const MyComponent = (props: {
readonly textA: string;
readonly textB: string;
readonly renderB: boolean;
}) => {
return <>{props.renderB ? props.textB : props.textA}</>;
};
The problem is when I use this and I toggle renderB
on and off, the width of the component can change based on which string is rendered. I want the component width to fit the longer of the two strings.
How can I take the max length of textA
and textB
and use that to determine the width of my component?
For example, it could look something like this:
const MyComponent = (props: {
readonly textA: string;
readonly textB: string;
readonly renderB: boolean;
}) => {
const widthA = /* compute the width of props.textA */;
const widthB = /* compute the width of props.textB */;
return (
<div style={{ width: `${Math.max(widthA, widthB)}px` }}>
{props.renderB ? props.textB : props.textA}
</div>
);
};
One solution is to use grid layout, render both child span, and hide the one that shouldn't be rendered (using visibility:hidden
). The advantage is that this can be done pure CSS without needing to calculate the Text size, which is usually pretty troublesome and buggy. But the drawback is of course the user can see the other child in the DOM tree, which might not be ideal depending on your use case.
.wrapper {
display: inline-grid;
border: 1px solid red; /* for showing the size*/
}
.wrapper>span {
grid-column: 1;
grid-row: 1;
text-wrap: nowrap;
}
.wrapper>span:not(.rendered) {
visibility: hidden;
}
<span class="wrapper">
<span>Short Text</span>
<span class="rendered">Example 1. Long text I'm very long</span>
</span>
<span class="wrapper">
<span class="rendered">Example 2. Short Text</span>
<span>Very Long textttttttttttttttttttttttttttttttttttt</span>
</span>
const MyComponent = (props: {
readonly textA: string;
readonly textB: string;
readonly renderB: boolean;
}) => {
return (
<span style={{ display: 'inline-grid' }}>
<span
style={{
gridColumn: 1,
gridRow: 1,
visibility: props.renderB ? 'hidden' : 'visible',
}}
>
{props.textA}
</span>
<span
style={{
gridColumn: 1,
gridRow: 1,
visibility: props.renderB ? 'visible' : 'hidden',
}}
>
{props.textB}
</span>
</span>
);
};