Skip to content

Commit 6c2900f

Browse files
jaaydenhclaude
andauthored
refactor: use a global tooltip provider with a consistent 100 millisecond delay duration (#20869)
Part 1 of 2 - this sets up the TooltipProvider for Storybook in preview.tsx and for the app in App.tsx along with removing TooltipProvider in some of the usages of Tooltip - I tested existing components that haven't had the TooltipProvider removed and they still function correctly. So should be fine until the 2nd PR to complete the migration. --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent f08cb2f commit 6c2900f

File tree

37 files changed

+636
-744
lines changed

37 files changed

+636
-744
lines changed

site/.storybook/preview.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import isChromatic from "chromatic/isChromatic";
1111
import { StrictMode } from "react";
1212
import { QueryClient, QueryClientProvider } from "react-query";
1313
import { withRouter } from "storybook-addon-remix-react-router";
14+
import { TooltipProvider } from "../src/components/Tooltip/Tooltip";
1415
import "theme/globalFonts";
1516
import type { Decorator, Loader, Parameters } from "@storybook/react-vite";
1617
import themes from "../src/theme";
@@ -100,8 +101,10 @@ const withTheme: Decorator = (Story, context) => {
100101
<StyledEngineProvider injectFirst>
101102
<MuiThemeProvider theme={themes[selected]}>
102103
<EmotionThemeProvider theme={themes[selected]}>
103-
<CssBaseline />
104-
<Story />
104+
<TooltipProvider delayDuration={100}>
105+
<CssBaseline />
106+
<Story />
107+
</TooltipProvider>
105108
</EmotionThemeProvider>
106109
</MuiThemeProvider>
107110
</StyledEngineProvider>

site/src/App.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import "./theme/globalFonts";
22
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
3+
import { TooltipProvider } from "components/Tooltip/Tooltip";
34
import {
45
type FC,
56
type ReactNode,
@@ -53,8 +54,10 @@ export const AppProviders: FC<AppProvidersProps> = ({
5354
<QueryClientProvider client={queryClient}>
5455
<AuthProvider>
5556
<ThemeProvider>
56-
{children}
57-
<GlobalSnackbar />
57+
<TooltipProvider delayDuration={100}>
58+
{children}
59+
<GlobalSnackbar />
60+
</TooltipProvider>
5861
</ThemeProvider>
5962
</AuthProvider>
6063
{showDevtools && <ReactQueryDevtools initialIsOpen={showDevtools} />}

site/src/components/CodeExample/CodeExample.tsx

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { Button } from "components/Button/Button";
33
import {
44
Tooltip,
55
TooltipContent,
6-
TooltipProvider,
76
TooltipTrigger,
87
} from "components/Tooltip/Tooltip";
98
import { EyeIcon, EyeOffIcon } from "lucide-react";
@@ -77,21 +76,19 @@ export const CodeExample: FC<CodeExampleProps> = ({
7776

7877
<div className="flex items-center gap-1">
7978
{showRevealButton && redactPattern && !secret && (
80-
<TooltipProvider>
81-
<Tooltip>
82-
<TooltipTrigger asChild>
83-
<Button
84-
size="icon"
85-
variant="subtle"
86-
onClick={() => setShowFullValue(!showFullValue)}
87-
>
88-
{icon}
89-
<span className="sr-only">{showButtonLabel}</span>
90-
</Button>
91-
</TooltipTrigger>
92-
<TooltipContent>{showButtonLabel}</TooltipContent>
93-
</Tooltip>
94-
</TooltipProvider>
79+
<Tooltip>
80+
<TooltipTrigger asChild>
81+
<Button
82+
size="icon"
83+
variant="subtle"
84+
onClick={() => setShowFullValue(!showFullValue)}
85+
>
86+
{icon}
87+
<span className="sr-only">{showButtonLabel}</span>
88+
</Button>
89+
</TooltipTrigger>
90+
<TooltipContent>{showButtonLabel}</TooltipContent>
91+
</Tooltip>
9592
)}
9693
<CopyButton text={code} label="Copy code" />
9794
</div>

site/src/components/Combobox/Combobox.tsx

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
import {
1616
Tooltip,
1717
TooltipContent,
18-
TooltipProvider,
1918
TooltipTrigger,
2019
} from "components/Tooltip/Tooltip";
2120
import { Check, ChevronDown, CornerDownLeft, Info } from "lucide-react";
@@ -138,21 +137,19 @@ export const Combobox: FC<ComboboxProps> = ({
138137
<Check className="size-icon-sm" />
139138
)}
140139
{option.description && (
141-
<TooltipProvider delayDuration={100}>
142-
<Tooltip>
143-
<TooltipTrigger asChild>
144-
<span
145-
className="flex"
146-
onMouseEnter={(e) => e.stopPropagation()}
147-
>
148-
<Info className="w-3.5 h-3.5 text-content-secondary" />
149-
</span>
150-
</TooltipTrigger>
151-
<TooltipContent side="right" sideOffset={10}>
152-
{option.description}
153-
</TooltipContent>
154-
</Tooltip>
155-
</TooltipProvider>
140+
<Tooltip>
141+
<TooltipTrigger asChild>
142+
<span
143+
className="flex"
144+
onMouseEnter={(e) => e.stopPropagation()}
145+
>
146+
<Info className="w-3.5 h-3.5 text-content-secondary" />
147+
</span>
148+
</TooltipTrigger>
149+
<TooltipContent side="right" sideOffset={10}>
150+
{option.description}
151+
</TooltipContent>
152+
</Tooltip>
156153
)}
157154
</div>
158155
</CommandItem>

site/src/components/CopyButton/CopyButton.tsx

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { Button, type ButtonProps } from "components/Button/Button";
22
import {
33
Tooltip,
44
TooltipContent,
5-
TooltipProvider,
65
TooltipTrigger,
76
} from "components/Tooltip/Tooltip";
87
import { useClipboard } from "hooks/useClipboard";
@@ -22,21 +21,19 @@ export const CopyButton: FC<CopyButtonProps> = ({
2221
const { showCopiedSuccess, copyToClipboard } = useClipboard();
2322

2423
return (
25-
<TooltipProvider delayDuration={100}>
26-
<Tooltip>
27-
<TooltipTrigger asChild>
28-
<Button
29-
size="icon"
30-
variant="subtle"
31-
onClick={() => copyToClipboard(text)}
32-
{...buttonProps}
33-
>
34-
{showCopiedSuccess ? <CheckIcon /> : <CopyIcon />}
35-
<span className="sr-only">{label}</span>
36-
</Button>
37-
</TooltipTrigger>
38-
<TooltipContent>{label}</TooltipContent>
39-
</Tooltip>
40-
</TooltipProvider>
24+
<Tooltip>
25+
<TooltipTrigger asChild>
26+
<Button
27+
size="icon"
28+
variant="subtle"
29+
onClick={() => copyToClipboard(text)}
30+
{...buttonProps}
31+
>
32+
{showCopiedSuccess ? <CheckIcon /> : <CopyIcon />}
33+
<span className="sr-only">{label}</span>
34+
</Button>
35+
</TooltipTrigger>
36+
<TooltipContent>{label}</TooltipContent>
37+
</Tooltip>
4138
);
4239
};
Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
Tooltip,
33
TooltipContent,
4-
TooltipProvider,
54
TooltipTrigger,
65
} from "components/Tooltip/Tooltip";
76
import { useClickable } from "hooks/useClickable";
@@ -37,55 +36,53 @@ export const CopyableValue: FC<CopyableValueProps> = ({
3736
});
3837

3938
return (
40-
<TooltipProvider delayDuration={100}>
41-
<Tooltip
42-
open={tooltipOpen}
43-
onOpenChange={(shouldBeOpen) => {
44-
// Always keep the tooltip open when in focus to handle issues when onOpenChange is unexpectedly false
45-
if (!shouldBeOpen && isFocused) return;
46-
setTooltipOpen(shouldBeOpen);
47-
}}
48-
>
49-
<TooltipTrigger asChild>
50-
<span
51-
ref={clickableProps.ref}
52-
{...attrs}
53-
className={cn("cursor-pointer", className)}
54-
role={role ?? clickableProps.role}
55-
tabIndex={tabIndex ?? clickableProps.tabIndex}
56-
onClick={(event) => {
57-
clickableProps.onClick(event);
58-
onClick?.(event);
59-
}}
60-
onKeyDown={(event) => {
61-
clickableProps.onKeyDown(event);
62-
onKeyDown?.(event);
63-
}}
64-
onKeyUp={(event) => {
65-
clickableProps.onKeyUp(event);
66-
onKeyUp?.(event);
67-
}}
68-
onMouseEnter={() => {
69-
setIsFocused(true);
70-
setTooltipOpen(true);
71-
}}
72-
onMouseLeave={() => {
73-
setTooltipOpen(false);
74-
}}
75-
onFocus={() => {
76-
setIsFocused(true);
77-
}}
78-
onBlur={() => {
79-
setTooltipOpen(false);
80-
}}
81-
>
82-
{children}
83-
</span>
84-
</TooltipTrigger>
85-
<TooltipContent side={side}>
86-
{showCopiedSuccess ? "Copied!" : "Click to copy"}
87-
</TooltipContent>
88-
</Tooltip>
89-
</TooltipProvider>
39+
<Tooltip
40+
open={tooltipOpen}
41+
onOpenChange={(shouldBeOpen) => {
42+
// Always keep the tooltip open when in focus to handle issues when onOpenChange is unexpectedly false
43+
if (!shouldBeOpen && isFocused) return;
44+
setTooltipOpen(shouldBeOpen);
45+
}}
46+
>
47+
<TooltipTrigger asChild>
48+
<span
49+
ref={clickableProps.ref}
50+
{...attrs}
51+
className={cn("cursor-pointer", className)}
52+
role={role ?? clickableProps.role}
53+
tabIndex={tabIndex ?? clickableProps.tabIndex}
54+
onClick={(event) => {
55+
clickableProps.onClick(event);
56+
onClick?.(event);
57+
}}
58+
onKeyDown={(event) => {
59+
clickableProps.onKeyDown(event);
60+
onKeyDown?.(event);
61+
}}
62+
onKeyUp={(event) => {
63+
clickableProps.onKeyUp(event);
64+
onKeyUp?.(event);
65+
}}
66+
onMouseEnter={() => {
67+
setIsFocused(true);
68+
setTooltipOpen(true);
69+
}}
70+
onMouseLeave={() => {
71+
setTooltipOpen(false);
72+
}}
73+
onFocus={() => {
74+
setIsFocused(true);
75+
}}
76+
onBlur={() => {
77+
setTooltipOpen(false);
78+
}}
79+
>
80+
{children}
81+
</span>
82+
</TooltipTrigger>
83+
<TooltipContent side={side}>
84+
{showCopiedSuccess ? "Copied!" : "Click to copy"}
85+
</TooltipContent>
86+
</Tooltip>
9087
);
9188
};

site/src/components/FeatureStageBadge/FeatureStageBadge.tsx

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { Link } from "components/Link/Link";
22
import {
33
Tooltip,
44
TooltipContent,
5-
TooltipProvider,
65
TooltipTrigger,
76
} from "components/Tooltip/Tooltip";
87
import type { FC, HTMLAttributes, ReactNode } from "react";
@@ -47,40 +46,38 @@ export const FeatureStageBadge: FC<FeatureStageBadgeProps> = ({
4746
const sizeClasses = badgeSizeClasses[size];
4847

4948
return (
50-
<TooltipProvider delayDuration={100}>
51-
<Tooltip>
52-
<TooltipTrigger asChild>
53-
<span
54-
className={cn(
55-
"block max-w-fit cursor-default flex-shrink-0 leading-none whitespace-nowrap border rounded-md transition-colors duration-200 ease-in-out bg-transparent border-solid border-transparent",
56-
sizeClasses,
57-
colorClasses,
58-
className,
59-
)}
60-
{...delegatedProps}
61-
>
62-
<span className="sr-only"> (This is a</span>
63-
<span className="first-letter:uppercase">
64-
{labelText && `${labelText} `}
65-
{featureStageBadgeTypes[contentType]}
66-
</span>
67-
<span className="sr-only"> feature)</span>
49+
<Tooltip>
50+
<TooltipTrigger asChild>
51+
<span
52+
className={cn(
53+
"block max-w-fit cursor-default flex-shrink-0 leading-none whitespace-nowrap border rounded-md transition-colors duration-200 ease-in-out bg-transparent border-solid border-transparent",
54+
sizeClasses,
55+
colorClasses,
56+
className,
57+
)}
58+
{...delegatedProps}
59+
>
60+
<span className="sr-only"> (This is a</span>
61+
<span className="first-letter:uppercase">
62+
{labelText && `${labelText} `}
63+
{featureStageBadgeTypes[contentType]}
6864
</span>
69-
</TooltipTrigger>
70-
<TooltipContent align="start" className="max-w-xs text-sm">
71-
<p className="m-0">
72-
This feature has not yet reached general availability (GA).
73-
</p>
65+
<span className="sr-only"> feature)</span>
66+
</span>
67+
</TooltipTrigger>
68+
<TooltipContent align="start" className="max-w-xs text-sm">
69+
<p className="m-0">
70+
This feature has not yet reached general availability (GA).
71+
</p>
7472

75-
<Link
76-
href={docs("/install/releases/feature-stages")}
77-
className="font-semibold"
78-
>
79-
Learn about feature stages
80-
<span className="sr-only"> (link opens in new tab)</span>
81-
</Link>
82-
</TooltipContent>
83-
</Tooltip>
84-
</TooltipProvider>
73+
<Link
74+
href={docs("/install/releases/feature-stages")}
75+
className="font-semibold"
76+
>
77+
Learn about feature stages
78+
<span className="sr-only"> (link opens in new tab)</span>
79+
</Link>
80+
</TooltipContent>
81+
</Tooltip>
8582
);
8683
};

site/src/components/HelpTooltip/HelpTooltip.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
TooltipContent,
1212
type TooltipContentProps,
1313
type TooltipProps,
14-
TooltipProvider,
1514
TooltipTrigger,
1615
} from "components/Tooltip/Tooltip";
1716
import { CircleHelpIcon, ExternalLinkIcon } from "lucide-react";
@@ -33,11 +32,7 @@ export const HelpTooltipTrigger = TooltipTrigger;
3332
export const HelpTooltipIcon = CircleHelpIcon;
3433

3534
export const HelpTooltip: FC<TooltipProps> = (props) => {
36-
return (
37-
<TooltipProvider>
38-
<Tooltip delayDuration={0} {...props} />
39-
</TooltipProvider>
40-
);
35+
return <Tooltip {...props} />;
4136
};
4237

4338
export const HelpTooltipContent: FC<TooltipContentProps> = ({

0 commit comments

Comments
 (0)