Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor: create a global tooltip provider with a consistent delay du…
…ration
  • Loading branch information
jaaydenh committed Nov 21, 2025
commit 06cd20617a6e90efa3f155a27239354753e57cf8
7 changes: 5 additions & 2 deletions site/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import isChromatic from "chromatic/isChromatic";
import { StrictMode } from "react";
import { QueryClient, QueryClientProvider } from "react-query";
import { withRouter } from "storybook-addon-remix-react-router";
import { TooltipProvider } from "../src/components/Tooltip/Tooltip";
import "theme/globalFonts";
import type { Decorator, Loader, Parameters } from "@storybook/react-vite";
import themes from "../src/theme";
Expand Down Expand Up @@ -100,8 +101,10 @@ const withTheme: Decorator = (Story, context) => {
<StyledEngineProvider injectFirst>
<MuiThemeProvider theme={themes[selected]}>
<EmotionThemeProvider theme={themes[selected]}>
<CssBaseline />
<Story />
<TooltipProvider delayDuration={100}>
<CssBaseline />
<Story />
</TooltipProvider>
</EmotionThemeProvider>
</MuiThemeProvider>
</StyledEngineProvider>
Expand Down
7 changes: 5 additions & 2 deletions site/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import "./theme/globalFonts";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { TooltipProvider } from "components/Tooltip/Tooltip";
import {
type FC,
type ReactNode,
Expand Down Expand Up @@ -53,8 +54,10 @@ export const AppProviders: FC<AppProvidersProps> = ({
<QueryClientProvider client={queryClient}>
<AuthProvider>
<ThemeProvider>
{children}
<GlobalSnackbar />
<TooltipProvider delayDuration={100}>
{children}
<GlobalSnackbar />
</TooltipProvider>
</ThemeProvider>
</AuthProvider>
{showDevtools && <ReactQueryDevtools initialIsOpen={showDevtools} />}
Expand Down
29 changes: 13 additions & 16 deletions site/src/components/CodeExample/CodeExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Button } from "components/Button/Button";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import { EyeIcon, EyeOffIcon } from "lucide-react";
Expand Down Expand Up @@ -77,21 +76,19 @@ export const CodeExample: FC<CodeExampleProps> = ({

<div className="flex items-center gap-1">
{showRevealButton && redactPattern && !secret && (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
size="icon"
variant="subtle"
onClick={() => setShowFullValue(!showFullValue)}
>
{icon}
<span className="sr-only">{showButtonLabel}</span>
</Button>
</TooltipTrigger>
<TooltipContent>{showButtonLabel}</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
size="icon"
variant="subtle"
onClick={() => setShowFullValue(!showFullValue)}
>
{icon}
<span className="sr-only">{showButtonLabel}</span>
</Button>
</TooltipTrigger>
<TooltipContent>{showButtonLabel}</TooltipContent>
</Tooltip>
)}
<CopyButton text={code} label="Copy code" />
</div>
Expand Down
29 changes: 13 additions & 16 deletions site/src/components/Combobox/Combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import { Check, ChevronDown, CornerDownLeft, Info } from "lucide-react";
Expand Down Expand Up @@ -138,21 +137,19 @@ export const Combobox: FC<ComboboxProps> = ({
<Check className="size-icon-sm" />
)}
{option.description && (
<TooltipProvider delayDuration={100}>
<Tooltip>
<TooltipTrigger asChild>
<span
className="flex"
onMouseEnter={(e) => e.stopPropagation()}
>
<Info className="w-3.5 h-3.5 text-content-secondary" />
</span>
</TooltipTrigger>
<TooltipContent side="right" sideOffset={10}>
{option.description}
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span
className="flex"
onMouseEnter={(e) => e.stopPropagation()}
>
<Info className="w-3.5 h-3.5 text-content-secondary" />
</span>
</TooltipTrigger>
<TooltipContent side="right" sideOffset={10}>
{option.description}
</TooltipContent>
</Tooltip>
)}
</div>
</CommandItem>
Expand Down
31 changes: 14 additions & 17 deletions site/src/components/CopyButton/CopyButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Button, type ButtonProps } from "components/Button/Button";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import { useClipboard } from "hooks/useClipboard";
Expand All @@ -22,21 +21,19 @@ export const CopyButton: FC<CopyButtonProps> = ({
const { showCopiedSuccess, copyToClipboard } = useClipboard();

return (
<TooltipProvider delayDuration={100}>
<Tooltip>
<TooltipTrigger asChild>
<Button
size="icon"
variant="subtle"
onClick={() => copyToClipboard(text)}
{...buttonProps}
>
{showCopiedSuccess ? <CheckIcon /> : <CopyIcon />}
<span className="sr-only">{label}</span>
</Button>
</TooltipTrigger>
<TooltipContent>{label}</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
size="icon"
variant="subtle"
onClick={() => copyToClipboard(text)}
{...buttonProps}
>
{showCopiedSuccess ? <CheckIcon /> : <CopyIcon />}
<span className="sr-only">{label}</span>
</Button>
</TooltipTrigger>
<TooltipContent>{label}</TooltipContent>
</Tooltip>
);
};
1 change: 0 additions & 1 deletion site/src/components/CopyableValue/CopyableValue.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import { useClickable } from "hooks/useClickable";
Expand Down Expand Up @@ -37,7 +36,7 @@
});

return (
<TooltipProvider>

Check failure on line 39 in site/src/components/CopyableValue/CopyableValue.tsx

View workflow job for this annotation

GitHub Actions / test-js

src/modules/resources/ResourceCard.test.tsx > Resource Card > renders 4 metadata tiles if no daily cost

ReferenceError: TooltipProvider is not defined ❯ CopyableValue src/components/CopyableValue/CopyableValue.tsx:39:4 ❯ Object.react_stack_bottom_frame node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:25904:20 ❯ renderWithHooks node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:7662:22 ❯ updateFunctionComponent node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:10166:19 ❯ beginWork node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:11778:18 ❯ runWithFiberInDEV node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:874:13 ❯ performUnitOfWork node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:17641:22 ❯ workLoopSync node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:17469:41 ❯ renderRootSync node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:17450:11 ❯ performWorkOnRoot node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:16583:35

Check failure on line 39 in site/src/components/CopyableValue/CopyableValue.tsx

View workflow job for this annotation

GitHub Actions / test-js

src/modules/resources/ResourceCard.test.tsx > Resource Card > renders daily cost and 3 metadata tiles

ReferenceError: TooltipProvider is not defined ❯ CopyableValue src/components/CopyableValue/CopyableValue.tsx:39:4 ❯ Object.react_stack_bottom_frame node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:25904:20 ❯ renderWithHooks node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:7662:22 ❯ updateFunctionComponent node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:10166:19 ❯ beginWork node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:11778:18 ❯ runWithFiberInDEV node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:874:13 ❯ performUnitOfWork node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:17641:22 ❯ workLoopSync node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:17469:41 ❯ renderRootSync node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:17450:11 ❯ performWorkOnRoot node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:16583:35

Check failure on line 39 in site/src/components/CopyableValue/CopyableValue.tsx

View workflow job for this annotation

GitHub Actions / test-js

src/modules/resources/ResourceCard.test.tsx > Resource Card > renders daily cost and metadata tiles

ReferenceError: TooltipProvider is not defined ❯ CopyableValue src/components/CopyableValue/CopyableValue.tsx:39:4 ❯ Object.react_stack_bottom_frame node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:25904:20 ❯ renderWithHooks node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:7662:22 ❯ updateFunctionComponent node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:10166:19 ❯ beginWork node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:11778:18 ❯ runWithFiberInDEV node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:874:13 ❯ performUnitOfWork node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:17641:22 ❯ workLoopSync node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:17469:41 ❯ renderRootSync node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:17450:11 ❯ performWorkOnRoot node_modules/.pnpm/react-dom@19.2.0_react@19.2.0/node_modules/react-dom/cjs/react-dom-client.development.js:16583:35
<Tooltip
open={tooltipOpen}
onOpenChange={(shouldBeOpen) => {
Expand Down
65 changes: 31 additions & 34 deletions site/src/components/FeatureStageBadge/FeatureStageBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Link } from "components/Link/Link";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import type { FC, HTMLAttributes, ReactNode } from "react";
Expand Down Expand Up @@ -47,40 +46,38 @@ export const FeatureStageBadge: FC<FeatureStageBadgeProps> = ({
const sizeClasses = badgeSizeClasses[size];

return (
<TooltipProvider delayDuration={100}>
<Tooltip>
<TooltipTrigger asChild>
<span
className={cn(
"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",
sizeClasses,
colorClasses,
className,
)}
{...delegatedProps}
>
<span className="sr-only"> (This is a</span>
<span className="first-letter:uppercase">
{labelText && `${labelText} `}
{featureStageBadgeTypes[contentType]}
</span>
<span className="sr-only"> feature)</span>
<Tooltip>
<TooltipTrigger asChild>
<span
className={cn(
"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",
sizeClasses,
colorClasses,
className,
)}
{...delegatedProps}
>
<span className="sr-only"> (This is a</span>
<span className="first-letter:uppercase">
{labelText && `${labelText} `}
{featureStageBadgeTypes[contentType]}
</span>
</TooltipTrigger>
<TooltipContent align="start" className="max-w-xs text-sm">
<p className="m-0">
This feature has not yet reached general availability (GA).
</p>
<span className="sr-only"> feature)</span>
</span>
</TooltipTrigger>
<TooltipContent align="start" className="max-w-xs text-sm">
<p className="m-0">
This feature has not yet reached general availability (GA).
</p>

<Link
href={docs("/install/releases/feature-stages")}
className="font-semibold"
>
Learn about feature stages
<span className="sr-only"> (link opens in new tab)</span>
</Link>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Link
href={docs("/install/releases/feature-stages")}
className="font-semibold"
>
Learn about feature stages
<span className="sr-only"> (link opens in new tab)</span>
</Link>
</TooltipContent>
</Tooltip>
);
};
7 changes: 1 addition & 6 deletions site/src/components/HelpTooltip/HelpTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
TooltipContent,
type TooltipContentProps,
type TooltipProps,
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import { CircleHelpIcon, ExternalLinkIcon } from "lucide-react";
Expand All @@ -33,11 +32,7 @@ export const HelpTooltipTrigger = TooltipTrigger;
export const HelpTooltipIcon = CircleHelpIcon;

export const HelpTooltip: FC<TooltipProps> = (props) => {
return (
<TooltipProvider>
<Tooltip delayDuration={0} {...props} />
</TooltipProvider>
);
return <Tooltip {...props} />;
};

export const HelpTooltipContent: FC<TooltipContentProps> = ({
Expand Down
29 changes: 13 additions & 16 deletions site/src/components/MultiSelectCombobox/MultiSelectCombobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import { useDebouncedValue } from "hooks/debounce";
Expand Down Expand Up @@ -684,21 +683,19 @@ export const MultiSelectCombobox = forwardRef<
)}
{option.label}
{option.description && (
<TooltipProvider delayDuration={100}>
<Tooltip>
<TooltipTrigger asChild>
<span className="flex items-center pointer-events-auto">
<Info className="!w-3.5 !h-3.5 text-content-secondary" />
</span>
</TooltipTrigger>
<TooltipContent
side="right"
sideOffset={10}
>
{option.description}
</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span className="flex items-center pointer-events-auto">
<Info className="!w-3.5 !h-3.5 text-content-secondary" />
</span>
</TooltipTrigger>
<TooltipContent
side="right"
sideOffset={10}
>
{option.description}
</TooltipContent>
</Tooltip>
)}
</div>
</CommandItem>
Expand Down
11 changes: 4 additions & 7 deletions site/src/components/StatusPill/StatusPill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Pill } from "components/Pill/Pill";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import type { FC } from "react";
Expand Down Expand Up @@ -33,11 +32,9 @@ export const StatusPill: FC<StatusPillProps> = ({
return pill;
}
return (
<TooltipProvider>
<Tooltip delayDuration={150}>
<TooltipTrigger asChild>{pill}</TooltipTrigger>
<TooltipContent>{label}</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>{pill}</TooltipTrigger>
<TooltipContent>{label}</TooltipContent>
</Tooltip>
);
};
29 changes: 13 additions & 16 deletions site/src/modules/dashboard/Navbar/NavbarView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { CoderIcon } from "components/Icons/CoderIcon";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import type { ProxyContextValue } from "contexts/ProxyContext";
Expand Down Expand Up @@ -230,21 +229,19 @@ const TasksNavItem: FC<TasksNavItemProps> = ({ user }) => {
>
Tasks
{idleCount > 0 && (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Badge
variant="info"
size="xs"
className="ml-2"
aria-label={idleTasksLabel(idleCount)}
>
{idleCount}
</Badge>
</TooltipTrigger>
<TooltipContent>{idleTasksLabel(idleCount)}</TooltipContent>
</Tooltip>
</TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Badge
variant="info"
size="xs"
className="ml-2"
aria-label={idleTasksLabel(idleCount)}
>
{idleCount}
</Badge>
</TooltipTrigger>
<TooltipContent>{idleTasksLabel(idleCount)}</TooltipContent>
</Tooltip>
)}
</NavLink>
);
Expand Down
Loading
Loading