From 681af9340e5a3cff76617b27908706dd79378b89 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Fri, 24 Nov 2023 00:10:59 +0100 Subject: [PATCH] Button: always render the `Tooltip` component even when a tooltip should not be shown --- packages/components/src/button/index.tsx | 63 ++++++++++++------------ 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/packages/components/src/button/index.tsx b/packages/components/src/button/index.tsx index f840e259f92e39..ceace45641cf69 100644 --- a/packages/components/src/button/index.tsx +++ b/packages/components/src/button/index.tsx @@ -14,7 +14,7 @@ import type { * WordPress dependencies */ import deprecated from '@wordpress/deprecated'; -import { forwardRef } from '@wordpress/element'; +import { forwardRef, useMemo } from '@wordpress/element'; import { useInstanceId } from '@wordpress/compose'; /** @@ -249,40 +249,39 @@ export function UnforwardedButton( ); - // Convert legacy `position` values to be used with the new `placement` prop - let computedPlacement; - // if `tooltipPosition` is defined, compute value to `placement` - if ( tooltipPosition !== undefined ) { - computedPlacement = positionToPlacement( tooltipPosition ); - } - - if ( ! shouldShowTooltip ) { - return ( - <> - { element } - { describedBy && ( - - { describedBy } - - ) } - - ); - } + // In order to avoid some React reconciliation issues, we are always rendering + // the `Tooltip` component even when `shouldShowTooltip` is `false`. + // In order to make sure that the tooltip doesn't show when it shouldn't, + // we don't pass the props to the `Tooltip` componet. + const tooltipProps = useMemo( + () => + ( shouldShowTooltip + ? { + text: + ( children as string | ReactElement[] )?.length && + describedBy + ? describedBy + : label, + shortcut, + placement: + tooltipPosition && + // Convert legacy `position` values to be used with the new `placement` prop + positionToPlacement( tooltipPosition ), + } + : {} ) as Partial< React.ComponentProps< typeof Tooltip > >, + [ + shouldShowTooltip, + children, + describedBy, + label, + shortcut, + tooltipPosition, + ] + ); return ( <> - - { element } - + { element } { describedBy && ( { describedBy }