diff --git a/apps/builder/app/builder/features/style-panel/property-label.tsx b/apps/builder/app/builder/features/style-panel/property-label.tsx index 2a7fdfe74d20..ebe4f40892cb 100644 --- a/apps/builder/app/builder/features/style-panel/property-label.tsx +++ b/apps/builder/app/builder/features/style-panel/property-label.tsx @@ -257,8 +257,6 @@ export const PropertyLabel = ({ event.preventDefault()} triggerProps={{ onClick: (event) => { if (event.altKey) { diff --git a/packages/design-system/src/components/tooltip.tsx b/packages/design-system/src/components/tooltip.tsx index 9d8dce4b17e6..11632596eee9 100644 --- a/packages/design-system/src/components/tooltip.tsx +++ b/packages/design-system/src/components/tooltip.tsx @@ -1,4 +1,4 @@ -import type { Ref, ComponentProps, ReactNode } from "react"; +import type { Ref, ComponentProps, ReactNode, MouseEventHandler } from "react"; import { forwardRef, useEffect, useRef, useState } from "react"; import { autoUpdate, @@ -75,6 +75,7 @@ export const Tooltip = forwardRef( onOpenChange?.(open); }, }); + const preventCloseRef = useRef(false); /** * When the mouse leaves Tooltip.Content and hovers over an iframe, the Radix Tooltip stays open. @@ -89,13 +90,19 @@ export const Tooltip = forwardRef( * * The simpler solution with fewer side effects is to close the tooltip on mouse leave. */ - const handleMouseEnterComposed: React.MouseEventHandler = ( - event - ) => { + const handleMouseLeave: MouseEventHandler = (event) => { setOpen(false); props.onMouseLeave?.(event); }; + const handleOpenChange = (open: boolean) => { + if (open === false && preventCloseRef.current) { + return; + } + + setOpen(open); + }; + // There's no way to prevent a rendered trigger from opening. // This causes delay issues when an invisible tooltip forces other tooltips to show immediately. return content == null ? ( @@ -104,7 +111,7 @@ export const Tooltip = forwardRef( @@ -149,7 +156,16 @@ export const Tooltip = forwardRef( collisionPadding={8} arrowPadding={8} {...props} - onMouseLeave={handleMouseEnterComposed} + onMouseLeave={handleMouseLeave} + onPointerDown={() => { + // Allows clicking on links or selecting text inside the tooltip. + // Prevent closing tooltip on content click. + // Can't use preventDefault() because it will prevent selecting code for copy/paste. + preventCloseRef.current = true; + requestAnimationFrame(() => { + preventCloseRef.current = false; + }); + }} > {typeof content === "string" ? {content} : content}