From 73ad460cbbe1c52006cc3d095e60fa43f2ae17bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 6 Mar 2023 16:19:51 +0100 Subject: [PATCH] a solution with width --- .../Tooltip/TooltipRenderedOnPageBody.js | 42 ++++++++++++++++++- src/styles/getTooltipStyles.js | 8 ++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index a3c8adda3376..0f86ff70438c 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -62,16 +62,42 @@ class TooltipRenderedOnPageBody extends React.PureComponent { constructor(props) { super(props); this.state = { + // The width of tooltip's inner content + tooltipContentWidth: undefined, + // The width and height of the tooltip itself tooltipWidth: 0, tooltipHeight: 0, }; this.measureTooltip = this.measureTooltip.bind(this); + this.updateTooltipContentWidth = this.updateTooltipContentWidth.bind(this); } componentDidMount() { - // this.updateTooltipContentWidth(); + this.updateTooltipContentWidth(); + } + + componentDidUpdate(prevProps) { + if (prevProps.text === this.props.text && prevProps.renderTooltipContent === this.props.renderTooltipContent) { + return; + } + + // Reset the tooltip content width to undefined so that we can measure it again. + // eslint-disable-next-line react/no-did-update-set-state + this.setState({tooltipContentWidth: undefined}, this.updateTooltipContentWidth); + } + + updateTooltipContentWidth() { + if (!this.contentWrapperRef) { + return; + } + + const contentWidth = this.contentWrapperRef.offsetWidth; + + this.setState({ + tooltipContentWidth: contentWidth, + }); } /** @@ -103,6 +129,7 @@ class TooltipRenderedOnPageBody extends React.PureComponent { this.props.maxWidth, this.state.tooltipWidth, this.state.tooltipHeight, + this.state.tooltipContentWidth, this.props.shiftHorizontal, this.props.shiftVertical, ); @@ -125,7 +152,18 @@ class TooltipRenderedOnPageBody extends React.PureComponent { onLayout={this.measureTooltip} style={[tooltipWrapperStyle, animationStyle]} > - {content} + { + if (this.contentWrapperRef) { + return; + } + + this.contentWrapperRef = ref; + this.updateTooltipContentWidth(); + }} + > + {content} + diff --git a/src/styles/getTooltipStyles.js b/src/styles/getTooltipStyles.js index f2d2267ec4af..4b262fa87d7b 100644 --- a/src/styles/getTooltipStyles.js +++ b/src/styles/getTooltipStyles.js @@ -63,6 +63,7 @@ function computeHorizontalShift(windowWidth, xOffset, componentWidth, tooltipWid * @param {Number} maxWidth - The tooltip's max width. * @param {Number} tooltipWidth - The width of the tooltip itself. * @param {Number} tooltipHeight - The height of the tooltip itself. + * @param {Number} tooltipContentWidth - The tooltip's inner content width. * @param {Number} [manualShiftHorizontal] - Any additional amount to manually shift the tooltip to the left or right. * A positive value shifts it to the right, * and a negative value shifts it to the left. @@ -80,6 +81,7 @@ export default function getTooltipStyles( maxWidth, tooltipWidth, tooltipHeight, + tooltipContentWidth, manualShiftHorizontal = 0, manualShiftVertical = 0, ) { @@ -95,6 +97,11 @@ export default function getTooltipStyles( const tooltipVerticalPadding = spacing.pv1; const tooltipFontSize = variables.fontSizeSmall; + // We get wrapper width based on the tooltip's inner text width so the wrapper is just big enough to fit text and prevent white space. + // If the text width is less than the maximum available width, add horizontal padding. + // Note: tooltipContentWidth ignores the fractions (OffsetWidth) so add 1px to fit the text properly. + const wrapperWidth = tooltipContentWidth && tooltipContentWidth + (spacing.ph2.paddingHorizontal * 2) + 1; + // Hide the tooltip entirely if it's position hasn't finished measuring yet. This prevents UI jank where the tooltip flashes in the top left corner of the screen. const opacity = (xOffset === 0 && yOffset === 0) ? 0 : 1; @@ -114,6 +121,7 @@ export default function getTooltipStyles( ...tooltipVerticalPadding, ...spacing.ph2, zIndex: variables.tooltipzIndex, + width: wrapperWidth, maxWidth, // Because it uses fixed positioning, the top-left corner of the tooltip is aligned