diff --git a/site/src/components/CopyableValue/CopyableValue.tsx b/site/src/components/CopyableValue/CopyableValue.tsx index 92cb6ec3c4e42..89d98e43e0474 100644 --- a/site/src/components/CopyableValue/CopyableValue.tsx +++ b/site/src/components/CopyableValue/CopyableValue.tsx @@ -1,35 +1,91 @@ -import Tooltip, { type TooltipProps } from "@mui/material/Tooltip"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "components/Tooltip/Tooltip"; import { useClickable } from "hooks/useClickable"; import { useClipboard } from "hooks/useClipboard"; -import type { FC, HTMLAttributes } from "react"; +import { type FC, type HTMLAttributes, useState } from "react"; +import { cn } from "utils/cn"; + +type TooltipSide = "top" | "right" | "bottom" | "left"; interface CopyableValueProps extends HTMLAttributes { value: string; - placement?: TooltipProps["placement"]; - PopperProps?: TooltipProps["PopperProps"]; + side?: TooltipSide; } export const CopyableValue: FC = ({ value, - placement = "bottom-start", - PopperProps, + side = "bottom", children, + className, + role, + tabIndex, + onClick, + onKeyDown, + onKeyUp, ...attrs }) => { const { showCopiedSuccess, copyToClipboard } = useClipboard(); + const [tooltipOpen, setTooltipOpen] = useState(false); + const [isFocused, setIsFocused] = useState(false); const clickableProps = useClickable(() => { copyToClipboard(value); + setTooltipOpen(true); }); return ( - - - {children} - - + + { + // Always keep the tooltip open when in focus to handle issues when onOpenChange is unexpectedly false + if (!shouldBeOpen && isFocused) return; + setTooltipOpen(shouldBeOpen); + }} + > + + { + clickableProps.onClick(event); + onClick?.(event); + }} + onKeyDown={(event) => { + clickableProps.onKeyDown(event); + onKeyDown?.(event); + }} + onKeyUp={(event) => { + clickableProps.onKeyUp(event); + onKeyUp?.(event); + }} + onMouseEnter={() => { + setIsFocused(true); + setTooltipOpen(true); + }} + onMouseLeave={() => { + setTooltipOpen(false); + }} + onFocus={() => { + setIsFocused(true); + }} + onBlur={() => { + setTooltipOpen(false); + }} + > + {children} + + + + {showCopiedSuccess ? "Copied!" : "Click to copy"} + + + ); }; diff --git a/site/src/modules/resources/SensitiveValue.tsx b/site/src/modules/resources/SensitiveValue.tsx index b1ec1b4410e3e..3a0cf65bedafe 100644 --- a/site/src/modules/resources/SensitiveValue.tsx +++ b/site/src/modules/resources/SensitiveValue.tsx @@ -32,7 +32,10 @@ export const SensitiveValue: FC = ({ value }) => { gap: 4, }} > - + {displayValue} @@ -52,14 +55,6 @@ export const SensitiveValue: FC = ({ value }) => { }; const styles = { - value: { - // 22px is the button width - width: "calc(100% - 22px)", - overflow: "hidden", - whiteSpace: "nowrap", - textOverflow: "ellipsis", - }, - button: css` color: inherit; `, diff --git a/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/EditOAuth2AppPageView.tsx b/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/EditOAuth2AppPageView.tsx index 73149d2a30645..7e2c4e31bcd06 100644 --- a/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/EditOAuth2AppPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/EditOAuth2AppPageView.tsx @@ -150,20 +150,20 @@ export const EditOAuth2AppPageView: FC = ({
Client ID
- + {app.id}
Authorization URL
- + {app.endpoints.authorization}{" "}
Token URL
- + {app.endpoints.token}
diff --git a/site/src/pages/IconsPage/IconsPage.tsx b/site/src/pages/IconsPage/IconsPage.tsx index a15ee72114dc6..a7574fced567c 100644 --- a/site/src/pages/IconsPage/IconsPage.tsx +++ b/site/src/pages/IconsPage/IconsPage.tsx @@ -12,7 +12,6 @@ import { PageHeaderSubtitle, PageHeaderTitle, } from "components/PageHeader/PageHeader"; -import { Stack } from "components/Stack/Stack"; import { SearchIcon, XIcon } from "lucide-react"; import { type FC, type ReactNode, useMemo, useState } from "react"; import { @@ -79,13 +78,7 @@ const IconsPage: FC = () => { +

You can suggest a new icon by submitting a Pull Request to our public GitHub repository. Just keep in mind that it should be relevant to many Coder users, and redistributable under a @@ -124,12 +117,7 @@ const IconsPage: FC = () => { }, startAdornment: ( - + ), endAdornment: searchInputText && ( @@ -147,19 +135,13 @@ const IconsPage: FC = () => { }} /> - +

{searchedIcons.length === 0 && ( )} {searchedIcons.map((icon) => ( - - + +
{icon.url} { > {icon.description} - +
))} -
+
);