Skip to content

Commit

Permalink
a solution with width
Browse files Browse the repository at this point in the history
  • Loading branch information
hannojg committed Mar 6, 2023
1 parent 37a4d7d commit 73ad460
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
42 changes: 40 additions & 2 deletions src/components/Tooltip/TooltipRenderedOnPageBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
}

/**
Expand Down Expand Up @@ -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,
);
Expand All @@ -125,7 +152,18 @@ class TooltipRenderedOnPageBody extends React.PureComponent {
onLayout={this.measureTooltip}
style={[tooltipWrapperStyle, animationStyle]}
>
{content}
<View
ref={(ref) => {
if (this.contentWrapperRef) {
return;
}

this.contentWrapperRef = ref;
this.updateTooltipContentWidth();
}}
>
{content}
</View>
<View style={pointerWrapperStyle}>
<View style={pointerStyle} />
</View>
Expand Down
8 changes: 8 additions & 0 deletions src/styles/getTooltipStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -80,6 +81,7 @@ export default function getTooltipStyles(
maxWidth,
tooltipWidth,
tooltipHeight,
tooltipContentWidth,
manualShiftHorizontal = 0,
manualShiftVertical = 0,
) {
Expand All @@ -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;

Expand All @@ -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
Expand Down

0 comments on commit 73ad460

Please sign in to comment.