Skip to content

Commit 4863812

Browse files
authored
refactor: replace MUI Tooltip component with Tooltip (simple usage) (#20849)
for #19974 Redo of #20027, this time splitting it into multiple PRs + using our existing `Tooltip` component instead of creating a new component (see below). This PR covers the most basic usage of the MUI Tooltip, i.e., the tooltip content is a string literal. ~~Adds a global `TooltipProvider` to `AppProviders` and our Storybook decorators, so that we don't have to render a `TooltipProvider` for every tooltip instance. Removing redundant `TooltipProvider`s will be another separate PR~~ <- this was done by #20869
1 parent e340560 commit 4863812

File tree

29 files changed

+563
-331
lines changed

29 files changed

+563
-331
lines changed

site/src/components/Badges/Badges.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import type { Interpolation, Theme } from "@emotion/react";
2-
import Tooltip from "@mui/material/Tooltip";
32
import { Stack } from "components/Stack/Stack";
3+
import {
4+
Tooltip,
5+
TooltipContent,
6+
TooltipTrigger,
7+
} from "components/Tooltip/Tooltip";
48
import {
59
type FC,
610
forwardRef,
@@ -69,16 +73,26 @@ export const NotHealthyBadge: FC = () => {
6973

7074
export const NotRegisteredBadge: FC = () => {
7175
return (
72-
<Tooltip title="Workspace Proxy has never come online and needs to be started.">
73-
<span css={[styles.badge, styles.warnBadge]}>Never seen</span>
76+
<Tooltip>
77+
<TooltipTrigger asChild>
78+
<span css={[styles.badge, styles.warnBadge]}>Never seen</span>
79+
</TooltipTrigger>
80+
<TooltipContent side="bottom" className="max-w-xs">
81+
Workspace Proxy has never come online and needs to be started.
82+
</TooltipContent>
7483
</Tooltip>
7584
);
7685
};
7786

7887
export const NotReachableBadge: FC = () => {
7988
return (
80-
<Tooltip title="Workspace Proxy not responding to http(s) requests.">
81-
<span css={[styles.badge, styles.warnBadge]}>Not reachable</span>
89+
<Tooltip>
90+
<TooltipTrigger asChild>
91+
<span css={[styles.badge, styles.warnBadge]}>Not reachable</span>
92+
</TooltipTrigger>
93+
<TooltipContent side="bottom" className="max-w-xs">
94+
Workspace Proxy not responding to http(s) requests.
95+
</TooltipContent>
8296
</Tooltip>
8397
);
8498
};

site/src/components/Latency/Latency.tsx

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { useTheme } from "@emotion/react";
22
import CircularProgress from "@mui/material/CircularProgress";
3-
import Tooltip from "@mui/material/Tooltip";
43
import { Abbr } from "components/Abbr/Abbr";
4+
import {
5+
Tooltip,
6+
TooltipContent,
7+
TooltipTrigger,
8+
} from "components/Tooltip/Tooltip";
59
import { CircleHelpIcon } from "lucide-react";
610
import type { FC } from "react";
711
import { cn } from "utils/cn";
@@ -11,37 +15,50 @@ interface LatencyProps {
1115
latency?: number;
1216
isLoading?: boolean;
1317
className?: string;
14-
iconClassName?: string;
1518
}
1619

1720
export const Latency: FC<LatencyProps> = ({
1821
latency,
1922
isLoading,
2023
className,
21-
iconClassName,
2224
}) => {
2325
const theme = useTheme();
2426
// Always use the no latency color for loading.
2527
const color = getLatencyColor(theme, isLoading ? undefined : latency);
2628

2729
if (isLoading) {
2830
return (
29-
<Tooltip title="Loading latency..." className={className}>
30-
<CircularProgress
31-
className={cn("!size-icon-xs", iconClassName)}
32-
style={{ color }}
33-
/>
31+
<Tooltip>
32+
<TooltipTrigger asChild>
33+
{/**
34+
* Spinning progress icon must be placed inside a fixed-size container,
35+
* to ensure tooltip remains stationary when opened
36+
*/}
37+
<div
38+
className={cn(
39+
"size-4 flex flex-wrap place-content-center",
40+
className,
41+
)}
42+
>
43+
<CircularProgress className="!size-icon-xs" style={{ color }} />
44+
</div>
45+
</TooltipTrigger>
46+
<TooltipContent side="bottom">Loading latency...</TooltipContent>
3447
</Tooltip>
3548
);
3649
}
3750

3851
if (!latency) {
3952
return (
40-
<Tooltip title="Latency not available" className={className}>
41-
<CircleHelpIcon
42-
className={cn("!size-icon-sm", iconClassName)}
43-
style={{ color }}
44-
/>
53+
<Tooltip>
54+
<TooltipTrigger asChild>
55+
<CircleHelpIcon
56+
aria-label="Latency not available"
57+
className={cn("!size-icon-sm", className)}
58+
style={{ color }}
59+
/>
60+
</TooltipTrigger>
61+
<TooltipContent side="bottom">Latency not available</TooltipContent>
4562
</Tooltip>
4663
);
4764
}

site/src/components/SearchField/SearchField.tsx

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import IconButton from "@mui/material/IconButton";
22
import InputAdornment from "@mui/material/InputAdornment";
33
import TextField, { type TextFieldProps } from "@mui/material/TextField";
4-
import Tooltip from "@mui/material/Tooltip";
4+
import {
5+
Tooltip,
6+
TooltipContent,
7+
TooltipTrigger,
8+
} from "components/Tooltip/Tooltip";
59
import { useEffectEvent } from "hooks/hookPolyfills";
610
import { SearchIcon, XIcon } from "lucide-react";
711
import { type FC, useLayoutEffect, useRef } from "react";
12+
813
export type SearchFieldProps = Omit<TextFieldProps, "onChange"> & {
914
onChange: (query: string) => void;
1015
autoFocus?: boolean;
@@ -47,16 +52,19 @@ export const SearchField: FC<SearchFieldProps> = ({
4752
),
4853
endAdornment: value !== "" && (
4954
<InputAdornment position="end">
50-
<Tooltip title="Clear search">
51-
<IconButton
52-
size="small"
53-
onClick={() => {
54-
onChange("");
55-
}}
56-
>
57-
<XIcon className="size-icon-xs" />
58-
<span className="sr-only">Clear search</span>
59-
</IconButton>
55+
<Tooltip>
56+
<TooltipTrigger asChild>
57+
<IconButton
58+
size="small"
59+
onClick={() => {
60+
onChange("");
61+
}}
62+
>
63+
<XIcon className="size-icon-xs" />
64+
<span className="sr-only">Clear search</span>
65+
</IconButton>
66+
</TooltipTrigger>
67+
<TooltipContent side="bottom">Clear search</TooltipContent>
6068
</Tooltip>
6169
</InputAdornment>
6270
),

site/src/components/Tooltip/Tooltip.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ export const Tooltip = TooltipPrimitive.Root;
1414

1515
export const TooltipTrigger = TooltipPrimitive.Trigger;
1616

17+
export const TooltipArrow = TooltipPrimitive.Arrow;
18+
1719
export type TooltipContentProps = React.ComponentPropsWithoutRef<
1820
typeof TooltipPrimitive.Content
1921
> & {

site/src/modules/dashboard/Navbar/ProxyMenu.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export const ProxyMenu: FC<ProxyMenuProps> = ({ proxyContextValue }) => {
112112
// to turn this off because otherwise, screen readers will skip over all
113113
// the descriptive text and will only have access to the latency options
114114
autoFocus={false}
115+
className="z-0"
115116
>
116117
{proxyContextValue.proxies &&
117118
proxyContextValue.proxies.length > 1 && [

site/src/modules/dashboard/Navbar/UserDropdown/UserDropdownContent.tsx

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ import {
66
} from "@emotion/react";
77
import Divider from "@mui/material/Divider";
88
import MenuItem from "@mui/material/MenuItem";
9-
import Tooltip from "@mui/material/Tooltip";
109
import { PopoverClose } from "@radix-ui/react-popover";
1110
import type * as TypesGen from "api/typesGenerated";
1211
import { CopyButton } from "components/CopyButton/CopyButton";
1312
import { Stack } from "components/Stack/Stack";
13+
import {
14+
Tooltip,
15+
TooltipContent,
16+
TooltipTrigger,
17+
} from "components/Tooltip/Tooltip";
1418
import {
1519
CircleUserIcon,
1620
LogOutIcon,
@@ -102,23 +106,31 @@ export const UserDropdownContent: FC<UserDropdownContentProps> = ({
102106
<Divider css={{ marginBottom: "0 !important" }} />
103107

104108
<Stack css={styles.info} spacing={0}>
105-
<Tooltip title="Browse the source code">
106-
<a
107-
css={[styles.footerText, styles.buildInfo]}
108-
href={buildInfo?.external_url}
109-
target="_blank"
110-
rel="noreferrer"
111-
>
112-
{buildInfo?.version} <SquareArrowOutUpRightIcon />
113-
</a>
109+
<Tooltip>
110+
<TooltipTrigger asChild>
111+
<a
112+
css={[styles.footerText, styles.buildInfo]}
113+
href={buildInfo?.external_url}
114+
target="_blank"
115+
rel="noreferrer"
116+
>
117+
{buildInfo?.version} <SquareArrowOutUpRightIcon />
118+
</a>
119+
</TooltipTrigger>
120+
<TooltipContent side="bottom">Browse the source code</TooltipContent>
114121
</Tooltip>
115122

116123
{buildInfo?.deployment_id && (
117124
<div className="flex items-center text-xs">
118-
<Tooltip title="Deployment Identifier">
119-
<span className="whitespace-nowrap overflow-hidden text-ellipsis">
120-
{buildInfo.deployment_id}
121-
</span>
125+
<Tooltip>
126+
<TooltipTrigger asChild>
127+
<span className="whitespace-nowrap overflow-hidden text-ellipsis">
128+
{buildInfo.deployment_id}
129+
</span>
130+
</TooltipTrigger>
131+
<TooltipContent side="bottom">
132+
Deployment Identifier
133+
</TooltipContent>
122134
</Tooltip>
123135
<CopyButton
124136
text={buildInfo.deployment_id}

site/src/modules/provisioners/Provisioner.tsx

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { useTheme } from "@emotion/react";
2-
import Tooltip from "@mui/material/Tooltip";
32
import type { HealthMessage, ProvisionerDaemon } from "api/typesGenerated";
43
import { Pill } from "components/Pill/Pill";
4+
import {
5+
Tooltip,
6+
TooltipContent,
7+
TooltipTrigger,
8+
} from "components/Tooltip/Tooltip";
59
import { Building2Icon, UserIcon } from "lucide-react";
610
import type { FC } from "react";
711
import { createDayString } from "utils/createDayString";
@@ -74,16 +78,19 @@ export const Provisioner: FC<ProvisionerProps> = ({
7478
justifyContent: "right",
7579
}}
7680
>
77-
<Tooltip title="Scope">
78-
<Pill size="lg" icon={iconScope}>
79-
<span
80-
css={{
81-
":first-letter": { textTransform: "uppercase" },
82-
}}
83-
>
84-
{daemonScope}
85-
</span>
86-
</Pill>
81+
<Tooltip>
82+
<TooltipTrigger asChild>
83+
<Pill size="lg" icon={iconScope}>
84+
<span
85+
css={{
86+
":first-letter": { textTransform: "uppercase" },
87+
}}
88+
>
89+
{daemonScope}
90+
</span>
91+
</Pill>
92+
</TooltipTrigger>
93+
<TooltipContent side="bottom">Scope</TooltipContent>
8794
</Tooltip>
8895
{extraTags.map(([key, value]) => (
8996
<ProvisionerTag key={key} tagName={key} tagValue={value} />

site/src/modules/resources/AgentMetadata.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import Skeleton from "@mui/material/Skeleton";
2-
import Tooltip from "@mui/material/Tooltip";
32
import { watchAgentMetadata } from "api/api";
43
import type {
54
ServerSentEvent,
@@ -8,6 +7,11 @@ import type {
87
} from "api/typesGenerated";
98
import { displayError } from "components/GlobalSnackbar/utils";
109
import { Stack } from "components/Stack/Stack";
10+
import {
11+
Tooltip,
12+
TooltipContent,
13+
TooltipTrigger,
14+
} from "components/Tooltip/Tooltip";
1115
import dayjs from "dayjs";
1216
import {
1317
type FC,
@@ -183,10 +187,15 @@ const MetadataItem: FC<MetadataItemProps> = ({ item }) => {
183187
status === "loading" ? (
184188
<Skeleton width={65} height={12} variant="text" className="mt-[6px]" />
185189
) : status === "stale" ? (
186-
<Tooltip title="This data is stale and no longer up to date">
187-
<StaticWidth className="text-ellipsis overflow-hidden whitespace-nowrap max-w-64 text-sm text-content-disabled cursor-pointer">
188-
{item.result.value}
189-
</StaticWidth>
190+
<Tooltip>
191+
<TooltipTrigger asChild>
192+
<StaticWidth className="text-ellipsis overflow-hidden whitespace-nowrap max-w-64 text-sm text-content-disabled cursor-pointer">
193+
{item.result.value}
194+
</StaticWidth>
195+
</TooltipTrigger>
196+
<TooltipContent side="bottom">
197+
This data is stale and no longer up to date
198+
</TooltipContent>
190199
</Tooltip>
191200
) : (
192201
<StaticWidth

site/src/modules/resources/AgentRow.stories.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,13 @@ export const BunchOfApps: Story = {
141141
},
142142
};
143143

144+
export const Disconnected: Story = {
145+
args: {
146+
agent: M.MockWorkspaceAgentDisconnected,
147+
initialMetadata: [],
148+
},
149+
};
150+
144151
export const Connecting: Story = {
145152
args: {
146153
agent: M.MockWorkspaceAgentConnecting,

0 commit comments

Comments
 (0)