From 61a269f6473e38f3efb51caf9f71a67935a3c759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Tue, 21 Feb 2023 20:00:17 +0100 Subject: [PATCH 01/15] wip: story for tooltip + render content --- .../Tooltip/TooltipRenderedOnPageBody.js | 29 ++++++++--- src/components/Tooltip/index.js | 27 +++++++++- src/components/Tooltip/tooltipPropTypes.js | 7 ++- src/stories/Tooltip.stories.js | 52 +++++++++++++++++++ 4 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 src/stories/Tooltip.stories.js diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index 54095286313c..e124169bfe9f 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -36,16 +36,21 @@ const propTypes = { /** Text to be shown in the tooltip */ text: PropTypes.string.isRequired, + /** Maximum number of lines to show in tooltip */ + numberOfLines: PropTypes.number.isRequired, + /** Number of pixels to set max-width on tooltip */ maxWidth: PropTypes.number.isRequired, - /** Maximum number of lines to show in tooltip */ - numberOfLines: PropTypes.number.isRequired, + /** Render custom content inside the tooltip. Note: This cannot be used together with the text props. */ + renderTooltipContent: PropTypes.func, + }; const defaultProps = { shiftHorizontal: 0, shiftVertical: 0, + renderTooltipContent: undefined, }; // Props will change frequently. @@ -122,11 +127,12 @@ class TooltipRenderedOnPageBody extends React.PureComponent { this.props.shiftHorizontal, this.props.shiftVertical, ); - return ReactDOM.createPortal( - + + let content; + if (this.props.renderTooltipContent) { + content = this.props.renderTooltipContent(); + } else { + content = ( + ); + } + + return ReactDOM.createPortal( + + {content} diff --git a/src/components/Tooltip/index.js b/src/components/Tooltip/index.js index 88c8d7401430..236bfdbb99a3 100644 --- a/src/components/Tooltip/index.js +++ b/src/components/Tooltip/index.js @@ -8,6 +8,7 @@ import {propTypes, defaultProps} from './tooltipPropTypes'; import TooltipSense from './TooltipSense'; import makeCancellablePromise from '../../libs/MakeCancellablePromise'; import * as DeviceCapabilities from '../../libs/DeviceCapabilities'; +import styles from '../../styles/styles'; class Tooltip extends PureComponent { constructor(props) { @@ -26,6 +27,9 @@ class Tooltip extends PureComponent { // The width and height of the wrapper view wrapperWidth: 0, wrapperHeight: 0, + + contentWidth: 0, + contentHeight: 0, }; // Whether the tooltip is first tooltip to activate the TooltipSense @@ -37,6 +41,7 @@ class Tooltip extends PureComponent { this.getWrapperPosition = this.getWrapperPosition.bind(this); this.showTooltip = this.showTooltip.bind(this); this.hideTooltip = this.hideTooltip.bind(this); + this.measureContent = this.measureContent.bind(this); } componentDidUpdate(prevProps) { @@ -141,9 +146,16 @@ class Tooltip extends PureComponent { TooltipSense.deactivate(); } + measureContent({nativeEvent}) { + this.setState({ + contentWidth: nativeEvent.layout.width, + contentHeight: nativeEvent.layout.height, + }); + } + render() { // Skip the tooltip and return the children if the text is empty or the device does not support hovering - if (_.isEmpty(this.props.text) || !this.hasHoverSupport) { + if ((_.isEmpty(this.props.text) && this.props.renderTooltipContent == null) || !this.hasHoverSupport) { return this.props.children; } let child = ( @@ -180,8 +192,21 @@ class Tooltip extends PureComponent { focusable: true, }); } + + const isCustomContent = _.isFunction(this.props.renderTooltipContent); + + // New state is introduced for the content dimensions + const isContentMeasured = this.state.contentWidth > 0 && this.state.contentHeight > 0; return ( <> + {isCustomContent && !isContentMeasured && ( + + {this.props.renderTooltipContent()} + + )} {this.state.isRendered && ( ( +
+ {/* eslint-disable-next-line react/jsx-props-no-spreading */} + +
+); + +const Children = ( +
+ Hover me +
+); + +// Arguments can be passed to the component by binding +// See: https://storybook.js.org/docs/react/writing-stories/introduction#using-args +const Default = Template.bind({}); +Default.args = { + text: 'Tooltip', + numberOfLines: 1, + maxWidth: 0, + absolute: false, + children: Children, +}; + +export default story; +export { + Default, +}; From 2ce661c840a12a8c76f4cc0c35e499f0ad6621ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Tue, 21 Feb 2023 20:27:25 +0100 Subject: [PATCH 02/15] fix render tooltip size correctly --- .../Tooltip/TooltipRenderedOnPageBody.js | 17 +++++--- src/components/Tooltip/index.js | 4 ++ src/stories/Tooltip.stories.js | 41 ++++++++++++------- src/styles/getTooltipStyles.js | 10 ++--- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index e124169bfe9f..5686d6fea44c 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -45,11 +45,14 @@ const propTypes = { /** Render custom content inside the tooltip. Note: This cannot be used together with the text props. */ renderTooltipContent: PropTypes.func, + /** When rendering arbitrarily content using renderTooltipContent you should specify the width of the content */ + contentWidth: PropTypes.number, }; const defaultProps = { shiftHorizontal: 0, shiftVertical: 0, + contentWidth: 0, renderTooltipContent: undefined, }; @@ -62,8 +65,8 @@ class TooltipRenderedOnPageBody extends React.PureComponent { constructor(props) { super(props); this.state = { - // The width of tooltip's inner text - tooltipTextWidth: 0, + // The width of tooltip's inner content + tooltipContentWidth: props.contentWidth, // The width and height of the tooltip itself tooltipWidth: 0, @@ -85,12 +88,16 @@ class TooltipRenderedOnPageBody extends React.PureComponent { // Reset the tooltip text width to 0 so that we can measure it again. // eslint-disable-next-line react/no-did-update-set-state - this.setState({tooltipTextWidth: 0}, this.updateTooltipTextWidth); + this.setState({tooltipContentWidth: 0}, this.updateTooltipTextWidth); } updateTooltipTextWidth() { + if (!this.textRef) { + return; + } + this.setState({ - tooltipTextWidth: this.textRef.offsetWidth, + tooltipContentWidth: this.textRef.offsetWidth, }); } @@ -123,7 +130,7 @@ class TooltipRenderedOnPageBody extends React.PureComponent { this.props.maxWidth, this.state.tooltipWidth, this.state.tooltipHeight, - this.state.tooltipTextWidth, + this.state.tooltipContentWidth, this.props.shiftHorizontal, this.props.shiftVertical, ); diff --git a/src/components/Tooltip/index.js b/src/components/Tooltip/index.js index 236bfdbb99a3..f75bff78e67b 100644 --- a/src/components/Tooltip/index.js +++ b/src/components/Tooltip/index.js @@ -197,6 +197,7 @@ class Tooltip extends PureComponent { // New state is introduced for the content dimensions const isContentMeasured = this.state.contentWidth > 0 && this.state.contentHeight > 0; + return ( <> {isCustomContent && !isContentMeasured && ( @@ -220,6 +221,9 @@ class Tooltip extends PureComponent { text={this.props.text} maxWidth={this.props.maxWidth} numberOfLines={this.props.numberOfLines} + contentWidth={this.state.contentWidth} + contentHeight={this.state.contentHeight} + renderTooltipContent={this.props.renderTooltipContent} /> )} ( }} > {/* eslint-disable-next-line react/jsx-props-no-spreading */} - - -); - -const Children = ( -
- Hover me + +
+ Hover me +
+
); @@ -43,10 +42,22 @@ Default.args = { numberOfLines: 1, maxWidth: 0, absolute: false, - children: Children, +}; + +const RenderContent = Template.bind({}); +RenderContent.args = { + renderTooltipContent: () => ( +
+ ), }; export default story; export { Default, + RenderContent, }; diff --git a/src/styles/getTooltipStyles.js b/src/styles/getTooltipStyles.js index c2816665a45b..00eb9c230964 100644 --- a/src/styles/getTooltipStyles.js +++ b/src/styles/getTooltipStyles.js @@ -63,7 +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} tooltipTextWidth - The tooltip's inner text width. + * @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. @@ -81,7 +81,7 @@ export default function getTooltipStyles( maxWidth, tooltipWidth, tooltipHeight, - tooltipTextWidth, + tooltipContentWidth, manualShiftHorizontal = 0, manualShiftVertical = 0, ) { @@ -99,9 +99,9 @@ export default function getTooltipStyles( // 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: tooltipTextWidth ignores the fractions (OffsetWidth) so add 1px to fit the text properly. - const wrapperWidth = tooltipTextWidth && tooltipTextWidth < maxWidth - ? tooltipTextWidth + (spacing.ph2.paddingHorizontal * 2) + 1 + // Note: tooltipContentWidth ignores the fractions (OffsetWidth) so add 1px to fit the text properly. + const wrapperWidth = tooltipContentWidth && tooltipContentWidth < maxWidth + ? tooltipContentWidth + (spacing.ph2.paddingHorizontal * 2) + 1 : maxWidth; // 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. From be3970cc00354675ccdd147f3145e3a5e36ee6ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Tue, 21 Feb 2023 20:28:36 +0100 Subject: [PATCH 03/15] formatting --- src/components/Tooltip/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/Tooltip/index.js b/src/components/Tooltip/index.js index f75bff78e67b..121378ead8a4 100644 --- a/src/components/Tooltip/index.js +++ b/src/components/Tooltip/index.js @@ -154,7 +154,8 @@ class Tooltip extends PureComponent { } render() { - // Skip the tooltip and return the children if the text is empty or the device does not support hovering + // Skip the tooltip and return the children if the text is empty, + // we don't have a render function or the device does not support hovering if ((_.isEmpty(this.props.text) && this.props.renderTooltipContent == null) || !this.hasHoverSupport) { return this.props.children; } @@ -194,8 +195,6 @@ class Tooltip extends PureComponent { } const isCustomContent = _.isFunction(this.props.renderTooltipContent); - - // New state is introduced for the content dimensions const isContentMeasured = this.state.contentWidth > 0 && this.state.contentHeight > 0; return ( From 80a0babf645917c4f9d3f10772839fc32ceb0863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Sun, 5 Mar 2023 18:36:19 +0100 Subject: [PATCH 04/15] move logic for measuring tooltip content size to TooltipRendererdOnpageBody --- .../Tooltip/TooltipRenderedOnPageBody.js | 50 +++++++++++++------ src/components/Tooltip/index.js | 25 ---------- src/stories/Tooltip.stories.js | 44 +++++++++++++--- 3 files changed, 73 insertions(+), 46 deletions(-) diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index 5686d6fea44c..bcbea4673272 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -2,8 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import {Animated, View} from 'react-native'; import ReactDOM from 'react-dom'; +import _ from 'underscore'; import getTooltipStyles from '../../styles/getTooltipStyles'; import Text from '../Text'; +import styles from '../../styles/styles'; const propTypes = { /** Window width */ @@ -40,20 +42,17 @@ const propTypes = { numberOfLines: PropTypes.number.isRequired, /** Number of pixels to set max-width on tooltip */ - maxWidth: PropTypes.number.isRequired, + maxWidth: PropTypes.number, /** Render custom content inside the tooltip. Note: This cannot be used together with the text props. */ renderTooltipContent: PropTypes.func, - - /** When rendering arbitrarily content using renderTooltipContent you should specify the width of the content */ - contentWidth: PropTypes.number, }; const defaultProps = { shiftHorizontal: 0, shiftVertical: 0, - contentWidth: 0, renderTooltipContent: undefined, + maxWidth: 0, }; // Props will change frequently. @@ -66,7 +65,7 @@ class TooltipRenderedOnPageBody extends React.PureComponent { super(props); this.state = { // The width of tooltip's inner content - tooltipContentWidth: props.contentWidth, + tooltipContentWidth: 0, // The width and height of the tooltip itself tooltipWidth: 0, @@ -74,6 +73,7 @@ class TooltipRenderedOnPageBody extends React.PureComponent { }; this.measureTooltip = this.measureTooltip.bind(this); + this.measureContent = this.measureContent.bind(this); this.updateTooltipTextWidth = this.updateTooltipTextWidth.bind(this); } @@ -113,6 +113,12 @@ class TooltipRenderedOnPageBody extends React.PureComponent { }); } + measureContent({nativeEvent}) { + this.setState({ + tooltipContentWidth: nativeEvent.layout.width, + }); + } + render() { const { animationStyle, @@ -160,16 +166,30 @@ class TooltipRenderedOnPageBody extends React.PureComponent { ); } + const isCustomContent = _.isFunction(this.props.renderTooltipContent); + return ReactDOM.createPortal( - - {content} - - - - , + <> + {/* If rendering custom content always render an invisible version of + it to detect layout size changes, if the content updates. */} + {isCustomContent && ( + + {this.props.renderTooltipContent()} + + )} + + {content} + + + + + , document.querySelector('body'), ); } diff --git a/src/components/Tooltip/index.js b/src/components/Tooltip/index.js index 121378ead8a4..68dcd2e1cce9 100644 --- a/src/components/Tooltip/index.js +++ b/src/components/Tooltip/index.js @@ -8,7 +8,6 @@ import {propTypes, defaultProps} from './tooltipPropTypes'; import TooltipSense from './TooltipSense'; import makeCancellablePromise from '../../libs/MakeCancellablePromise'; import * as DeviceCapabilities from '../../libs/DeviceCapabilities'; -import styles from '../../styles/styles'; class Tooltip extends PureComponent { constructor(props) { @@ -27,9 +26,6 @@ class Tooltip extends PureComponent { // The width and height of the wrapper view wrapperWidth: 0, wrapperHeight: 0, - - contentWidth: 0, - contentHeight: 0, }; // Whether the tooltip is first tooltip to activate the TooltipSense @@ -41,7 +37,6 @@ class Tooltip extends PureComponent { this.getWrapperPosition = this.getWrapperPosition.bind(this); this.showTooltip = this.showTooltip.bind(this); this.hideTooltip = this.hideTooltip.bind(this); - this.measureContent = this.measureContent.bind(this); } componentDidUpdate(prevProps) { @@ -146,13 +141,6 @@ class Tooltip extends PureComponent { TooltipSense.deactivate(); } - measureContent({nativeEvent}) { - this.setState({ - contentWidth: nativeEvent.layout.width, - contentHeight: nativeEvent.layout.height, - }); - } - render() { // Skip the tooltip and return the children if the text is empty, // we don't have a render function or the device does not support hovering @@ -194,19 +182,8 @@ class Tooltip extends PureComponent { }); } - const isCustomContent = _.isFunction(this.props.renderTooltipContent); - const isContentMeasured = this.state.contentWidth > 0 && this.state.contentHeight > 0; - return ( <> - {isCustomContent && !isContentMeasured && ( - - {this.props.renderTooltipContent()} - - )} {this.state.isRendered && ( )} diff --git a/src/stories/Tooltip.stories.js b/src/stories/Tooltip.stories.js index 87029028a29d..1642a4676ab4 100644 --- a/src/stories/Tooltip.stories.js +++ b/src/stories/Tooltip.stories.js @@ -44,16 +44,48 @@ Default.args = { absolute: false, }; -const RenderContent = Template.bind({}); -RenderContent.args = { - renderTooltipContent: () => ( +const RenderContent = () => { + const [size, setSize] = React.useState(40); + + const renderTooltipContent = () => (
- ), + ); + + return ( +
+ {/* eslint-disable-next-line react/jsx-props-no-spreading */} + + {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */} +
setSize(size + 25)} + style={{ + width: 100, + height: 60, + display: 'flex', + backgroundColor: 'red', + justifyContent: 'center', + alignItems: 'center', + }} + > + Hover me + {' '} + {'\n'} + Press me change content +
+
+
+ ); +}; +RenderContent.args = { + }; export default story; From 0d6fd7af11ddd9baaf7a97fc0abccc6f4a85d479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Sun, 5 Mar 2023 18:36:50 +0100 Subject: [PATCH 05/15] add default value --- src/components/Tooltip/tooltipPropTypes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Tooltip/tooltipPropTypes.js b/src/components/Tooltip/tooltipPropTypes.js index 6cb2aee9c0e3..3a8746b41dc0 100644 --- a/src/components/Tooltip/tooltipPropTypes.js +++ b/src/components/Tooltip/tooltipPropTypes.js @@ -45,6 +45,7 @@ const defaultProps = { text: '', maxWidth: variables.sideBarWidth, numberOfLines: CONST.TOOLTIP_MAX_LINES, + renderTooltipContent: undefined, }; export { From aef0e9783814392c7be8f80faa31229fb6123c32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 6 Mar 2023 13:04:07 +0100 Subject: [PATCH 06/15] unify to updateTooltipContentWidth --- .../Tooltip/TooltipRenderedOnPageBody.js | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index bcbea4673272..46b37bc3b956 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -73,12 +73,11 @@ class TooltipRenderedOnPageBody extends React.PureComponent { }; this.measureTooltip = this.measureTooltip.bind(this); - this.measureContent = this.measureContent.bind(this); - this.updateTooltipTextWidth = this.updateTooltipTextWidth.bind(this); + this.updateTooltipContentWidth = this.updateTooltipContentWidth.bind(this); } componentDidMount() { - this.updateTooltipTextWidth(); + this.updateTooltipContentWidth(); } componentDidUpdate(prevProps) { @@ -88,16 +87,24 @@ class TooltipRenderedOnPageBody extends React.PureComponent { // Reset the tooltip text width to 0 so that we can measure it again. // eslint-disable-next-line react/no-did-update-set-state - this.setState({tooltipContentWidth: 0}, this.updateTooltipTextWidth); + this.setState({tooltipContentWidth: 0}, this.updateTooltipContentWidth); } - updateTooltipTextWidth() { - if (!this.textRef) { + /** + * Updates the tooltipContentWidth state with the width of the tooltip's inner content. + * Can be called in onLayout, or if you are using text just call it after the first render + * to get the text's width. + * + * @param {Object} [event] + */ + updateTooltipContentWidth(event) { + if (!this.textRef && !event) { return; } + const widthFromEvent = _.get(event, ['nativeEvent', 'layout', 'width']); this.setState({ - tooltipContentWidth: this.textRef.offsetWidth, + tooltipContentWidth: widthFromEvent || this.textRef.offsetWidth, }); } @@ -113,12 +120,6 @@ class TooltipRenderedOnPageBody extends React.PureComponent { }); } - measureContent({nativeEvent}) { - this.setState({ - tooltipContentWidth: nativeEvent.layout.width, - }); - } - render() { const { animationStyle, @@ -157,7 +158,7 @@ class TooltipRenderedOnPageBody extends React.PureComponent { } this.textRef = ref; - this.updateTooltipTextWidth(); + this.updateTooltipContentWidth(); }} > {this.props.text} @@ -175,7 +176,7 @@ class TooltipRenderedOnPageBody extends React.PureComponent { {isCustomContent && ( {this.props.renderTooltipContent()} From c00581762ad913c258d44bd43940620d4ee2801f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 6 Mar 2023 13:04:35 +0100 Subject: [PATCH 07/15] clean: remove empty args --- src/stories/Tooltip.stories.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/stories/Tooltip.stories.js b/src/stories/Tooltip.stories.js index 1642a4676ab4..bb865bf242c7 100644 --- a/src/stories/Tooltip.stories.js +++ b/src/stories/Tooltip.stories.js @@ -84,9 +84,6 @@ const RenderContent = () => {
); }; -RenderContent.args = { - -}; export default story; export { From 37a4d7d5a1ea08eec7c2dbc146e9ae5aab08fa08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 6 Mar 2023 16:14:58 +0100 Subject: [PATCH 08/15] a solution without width --- .../Tooltip/TooltipRenderedOnPageBody.js | 83 +++---------------- src/styles/getTooltipStyles.js | 15 +--- 2 files changed, 14 insertions(+), 84 deletions(-) diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index 46b37bc3b956..a3c8adda3376 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -2,10 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import {Animated, View} from 'react-native'; import ReactDOM from 'react-dom'; -import _ from 'underscore'; import getTooltipStyles from '../../styles/getTooltipStyles'; import Text from '../Text'; -import styles from '../../styles/styles'; const propTypes = { /** Window width */ @@ -64,48 +62,16 @@ class TooltipRenderedOnPageBody extends React.PureComponent { constructor(props) { super(props); this.state = { - // The width of tooltip's inner content - tooltipContentWidth: 0, - // 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(); - } - - componentDidUpdate(prevProps) { - if (prevProps.text === this.props.text) { - return; - } - - // Reset the tooltip text width to 0 so that we can measure it again. - // eslint-disable-next-line react/no-did-update-set-state - this.setState({tooltipContentWidth: 0}, this.updateTooltipContentWidth); - } - - /** - * Updates the tooltipContentWidth state with the width of the tooltip's inner content. - * Can be called in onLayout, or if you are using text just call it after the first render - * to get the text's width. - * - * @param {Object} [event] - */ - updateTooltipContentWidth(event) { - if (!this.textRef && !event) { - return; - } - - const widthFromEvent = _.get(event, ['nativeEvent', 'layout', 'width']); - this.setState({ - tooltipContentWidth: widthFromEvent || this.textRef.offsetWidth, - }); + // this.updateTooltipContentWidth(); } /** @@ -137,7 +103,6 @@ class TooltipRenderedOnPageBody extends React.PureComponent { this.props.maxWidth, this.state.tooltipWidth, this.state.tooltipHeight, - this.state.tooltipContentWidth, this.props.shiftHorizontal, this.props.shiftVertical, ); @@ -148,49 +113,23 @@ class TooltipRenderedOnPageBody extends React.PureComponent { } else { content = ( - { - // Once the text for the tooltip first renders, update the width of the tooltip dynamically to fit the width of the text. - // Note that we can't have this code in componentDidMount because the ref for the text won't be set until after the first render - if (this.textRef) { - return; - } - - this.textRef = ref; - this.updateTooltipContentWidth(); - }} - > + {this.props.text} ); } - const isCustomContent = _.isFunction(this.props.renderTooltipContent); - return ReactDOM.createPortal( - <> - {/* If rendering custom content always render an invisible version of - it to detect layout size changes, if the content updates. */} - {isCustomContent && ( - - {this.props.renderTooltipContent()} - - )} - - {content} - - - - - , + + {content} + + + + , document.querySelector('body'), ); } diff --git a/src/styles/getTooltipStyles.js b/src/styles/getTooltipStyles.js index 00eb9c230964..f2d2267ec4af 100644 --- a/src/styles/getTooltipStyles.js +++ b/src/styles/getTooltipStyles.js @@ -63,7 +63,6 @@ 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. @@ -81,7 +80,6 @@ export default function getTooltipStyles( maxWidth, tooltipWidth, tooltipHeight, - tooltipContentWidth, manualShiftHorizontal = 0, manualShiftVertical = 0, ) { @@ -97,21 +95,14 @@ 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 < maxWidth - ? tooltipContentWidth + (spacing.ph2.paddingHorizontal * 2) + 1 - : maxWidth; - // 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; return { animationStyle: { - // remember Transform causes a new Local cordinate system + // remember Transform causes a new Local coordinate system // https://drafts.csswg.org/css-transforms-1/#transform-rendering - // so Position fixed children will be relative to this new Local cordinate system + // so Position fixed children will be relative to this new Local coordinate system transform: [{ scale: currentSize, }], @@ -123,7 +114,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 // with the top-left corner of the window by default. 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 09/15] 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 From 43a90cee9a6e44c7efe3adb0fde68339386677e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 6 Mar 2023 17:51:17 +0100 Subject: [PATCH 10/15] Revert "a solution with width" This reverts commit 73ad460cbbe1c52006cc3d095e60fa43f2ae17bb. --- .../Tooltip/TooltipRenderedOnPageBody.js | 42 +------------------ src/styles/getTooltipStyles.js | 8 ---- 2 files changed, 2 insertions(+), 48 deletions(-) diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index 0f86ff70438c..a3c8adda3376 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -62,42 +62,16 @@ 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(); - } - - 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, - }); + // this.updateTooltipContentWidth(); } /** @@ -129,7 +103,6 @@ class TooltipRenderedOnPageBody extends React.PureComponent { this.props.maxWidth, this.state.tooltipWidth, this.state.tooltipHeight, - this.state.tooltipContentWidth, this.props.shiftHorizontal, this.props.shiftVertical, ); @@ -152,18 +125,7 @@ class TooltipRenderedOnPageBody extends React.PureComponent { onLayout={this.measureTooltip} style={[tooltipWrapperStyle, animationStyle]} > - { - if (this.contentWrapperRef) { - return; - } - - this.contentWrapperRef = ref; - this.updateTooltipContentWidth(); - }} - > - {content} - + {content} diff --git a/src/styles/getTooltipStyles.js b/src/styles/getTooltipStyles.js index 4b262fa87d7b..f2d2267ec4af 100644 --- a/src/styles/getTooltipStyles.js +++ b/src/styles/getTooltipStyles.js @@ -63,7 +63,6 @@ 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. @@ -81,7 +80,6 @@ export default function getTooltipStyles( maxWidth, tooltipWidth, tooltipHeight, - tooltipContentWidth, manualShiftHorizontal = 0, manualShiftVertical = 0, ) { @@ -97,11 +95,6 @@ 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; @@ -121,7 +114,6 @@ 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 From fa31c0f6d7546c9f3e920ae251ab07a67b088215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 6 Mar 2023 17:51:27 +0100 Subject: [PATCH 11/15] Revert "a solution without width" This reverts commit 37a4d7d5a1ea08eec7c2dbc146e9ae5aab08fa08. --- .../Tooltip/TooltipRenderedOnPageBody.js | 83 ++++++++++++++++--- src/styles/getTooltipStyles.js | 15 +++- 2 files changed, 84 insertions(+), 14 deletions(-) diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index a3c8adda3376..46b37bc3b956 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -2,8 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import {Animated, View} from 'react-native'; import ReactDOM from 'react-dom'; +import _ from 'underscore'; import getTooltipStyles from '../../styles/getTooltipStyles'; import Text from '../Text'; +import styles from '../../styles/styles'; const propTypes = { /** Window width */ @@ -62,16 +64,48 @@ class TooltipRenderedOnPageBody extends React.PureComponent { constructor(props) { super(props); this.state = { + // The width of tooltip's inner content + tooltipContentWidth: 0, + // 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) { + return; + } + + // Reset the tooltip text width to 0 so that we can measure it again. + // eslint-disable-next-line react/no-did-update-set-state + this.setState({tooltipContentWidth: 0}, this.updateTooltipContentWidth); + } + + /** + * Updates the tooltipContentWidth state with the width of the tooltip's inner content. + * Can be called in onLayout, or if you are using text just call it after the first render + * to get the text's width. + * + * @param {Object} [event] + */ + updateTooltipContentWidth(event) { + if (!this.textRef && !event) { + return; + } + + const widthFromEvent = _.get(event, ['nativeEvent', 'layout', 'width']); + this.setState({ + tooltipContentWidth: widthFromEvent || this.textRef.offsetWidth, + }); } /** @@ -103,6 +137,7 @@ class TooltipRenderedOnPageBody extends React.PureComponent { this.props.maxWidth, this.state.tooltipWidth, this.state.tooltipHeight, + this.state.tooltipContentWidth, this.props.shiftHorizontal, this.props.shiftVertical, ); @@ -113,23 +148,49 @@ class TooltipRenderedOnPageBody extends React.PureComponent { } else { content = ( - + { + // Once the text for the tooltip first renders, update the width of the tooltip dynamically to fit the width of the text. + // Note that we can't have this code in componentDidMount because the ref for the text won't be set until after the first render + if (this.textRef) { + return; + } + + this.textRef = ref; + this.updateTooltipContentWidth(); + }} + > {this.props.text} ); } + const isCustomContent = _.isFunction(this.props.renderTooltipContent); + return ReactDOM.createPortal( - - {content} - - - - , + <> + {/* If rendering custom content always render an invisible version of + it to detect layout size changes, if the content updates. */} + {isCustomContent && ( + + {this.props.renderTooltipContent()} + + )} + + {content} + + + + + , document.querySelector('body'), ); } diff --git a/src/styles/getTooltipStyles.js b/src/styles/getTooltipStyles.js index f2d2267ec4af..00eb9c230964 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,14 +97,21 @@ 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 < maxWidth + ? tooltipContentWidth + (spacing.ph2.paddingHorizontal * 2) + 1 + : maxWidth; + // 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; return { animationStyle: { - // remember Transform causes a new Local coordinate system + // remember Transform causes a new Local cordinate system // https://drafts.csswg.org/css-transforms-1/#transform-rendering - // so Position fixed children will be relative to this new Local coordinate system + // so Position fixed children will be relative to this new Local cordinate system transform: [{ scale: currentSize, }], @@ -114,7 +123,7 @@ export default function getTooltipStyles( ...tooltipVerticalPadding, ...spacing.ph2, zIndex: variables.tooltipzIndex, - maxWidth, + width: wrapperWidth, // Because it uses fixed positioning, the top-left corner of the tooltip is aligned // with the top-left corner of the window by default. From e57fd78dbe90b55361e999e259c2c937bbd2bfac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 6 Mar 2023 18:09:24 +0100 Subject: [PATCH 12/15] changed to a simpler solution --- .../Tooltip/TooltipRenderedOnPageBody.js | 69 +++++++------------ src/styles/getTooltipStyles.js | 4 +- 2 files changed, 28 insertions(+), 45 deletions(-) diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index 46b37bc3b956..59b13d467cf6 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -2,10 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import {Animated, View} from 'react-native'; import ReactDOM from 'react-dom'; -import _ from 'underscore'; import getTooltipStyles from '../../styles/getTooltipStyles'; import Text from '../Text'; -import styles from '../../styles/styles'; const propTypes = { /** Window width */ @@ -64,8 +62,10 @@ class TooltipRenderedOnPageBody extends React.PureComponent { constructor(props) { super(props); this.state = { - // The width of tooltip's inner content - tooltipContentWidth: 0, + // The width of tooltip's inner content. Has to be undefined in the beginning + // as a width of 0 will cause the content to be rendered of a width of 0, + // which prevents us from measuring it correctly. + tooltipContentWidth: undefined, // The width and height of the tooltip itself tooltipWidth: 0, @@ -81,30 +81,22 @@ class TooltipRenderedOnPageBody extends React.PureComponent { } componentDidUpdate(prevProps) { - if (prevProps.text === this.props.text) { + if (prevProps.text === this.props.text && prevProps.renderTooltipContent === this.props.renderTooltipContent) { return; } // Reset the tooltip text width to 0 so that we can measure it again. // eslint-disable-next-line react/no-did-update-set-state - this.setState({tooltipContentWidth: 0}, this.updateTooltipContentWidth); + this.setState({tooltipContentWidth: undefined}, this.updateTooltipContentWidth); } - /** - * Updates the tooltipContentWidth state with the width of the tooltip's inner content. - * Can be called in onLayout, or if you are using text just call it after the first render - * to get the text's width. - * - * @param {Object} [event] - */ - updateTooltipContentWidth(event) { - if (!this.textRef && !event) { + updateTooltipContentWidth() { + if (!this.contentRef) { return; } - const widthFromEvent = _.get(event, ['nativeEvent', 'layout', 'width']); this.setState({ - tooltipContentWidth: widthFromEvent || this.textRef.offsetWidth, + tooltipContentWidth: this.contentRef.offsetWidth, }); } @@ -143,44 +135,35 @@ class TooltipRenderedOnPageBody extends React.PureComponent { ); let content; + const contentRef = (ref) => { + // Once the content for the tooltip first renders, update the width of the tooltip dynamically to fit the width of the content. + // Note that we can't have this code in componentDidMount because the ref for the content won't be set until after the first render + if (this.contentRef) { + return; + } + + this.contentRef = ref; + this.updateTooltipContentWidth(); + }; + if (this.props.renderTooltipContent) { - content = this.props.renderTooltipContent(); + content = ( + + {this.props.renderTooltipContent()} + + ); } else { content = ( - { - // Once the text for the tooltip first renders, update the width of the tooltip dynamically to fit the width of the text. - // Note that we can't have this code in componentDidMount because the ref for the text won't be set until after the first render - if (this.textRef) { - return; - } - - this.textRef = ref; - this.updateTooltipContentWidth(); - }} - > + {this.props.text} ); } - const isCustomContent = _.isFunction(this.props.renderTooltipContent); - return ReactDOM.createPortal( <> - {/* If rendering custom content always render an invisible version of - it to detect layout size changes, if the content updates. */} - {isCustomContent && ( - - {this.props.renderTooltipContent()} - - )} Date: Mon, 6 Mar 2023 19:12:02 +0100 Subject: [PATCH 13/15] remove unnecessary fragment --- .../Tooltip/TooltipRenderedOnPageBody.js | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index 59b13d467cf6..6f429a2a162d 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -163,17 +163,15 @@ class TooltipRenderedOnPageBody extends React.PureComponent { } return ReactDOM.createPortal( - <> - - {content} - - - - - , + + {content} + + + + , document.querySelector('body'), ); } From b2940699a36a98879aa16bf11907335354a4a4c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Mon, 6 Mar 2023 19:12:53 +0100 Subject: [PATCH 14/15] clean --- src/components/Tooltip/TooltipRenderedOnPageBody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index 6f429a2a162d..68de0226b128 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -134,7 +134,6 @@ class TooltipRenderedOnPageBody extends React.PureComponent { this.props.shiftVertical, ); - let content; const contentRef = (ref) => { // Once the content for the tooltip first renders, update the width of the tooltip dynamically to fit the width of the content. // Note that we can't have this code in componentDidMount because the ref for the content won't be set until after the first render @@ -146,6 +145,7 @@ class TooltipRenderedOnPageBody extends React.PureComponent { this.updateTooltipContentWidth(); }; + let content; if (this.props.renderTooltipContent) { content = ( From 98632042e9e3d1e5636dc4a3e69f5f46cdfeb0d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Tue, 7 Mar 2023 14:44:02 +0100 Subject: [PATCH 15/15] log warning when trying to use both props --- src/components/Tooltip/TooltipRenderedOnPageBody.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/Tooltip/TooltipRenderedOnPageBody.js b/src/components/Tooltip/TooltipRenderedOnPageBody.js index 68de0226b128..40dabf1b7651 100644 --- a/src/components/Tooltip/TooltipRenderedOnPageBody.js +++ b/src/components/Tooltip/TooltipRenderedOnPageBody.js @@ -4,6 +4,7 @@ import {Animated, View} from 'react-native'; import ReactDOM from 'react-dom'; import getTooltipStyles from '../../styles/getTooltipStyles'; import Text from '../Text'; +import Log from '../../libs/Log'; const propTypes = { /** Window width */ @@ -72,6 +73,10 @@ class TooltipRenderedOnPageBody extends React.PureComponent { tooltipHeight: 0, }; + if (props.renderTooltipContent && props.text) { + Log.warn('Developer error: Cannot use both text and renderTooltipContent props at the same time in !'); + } + this.measureTooltip = this.measureTooltip.bind(this); this.updateTooltipContentWidth = this.updateTooltipContentWidth.bind(this); }