From 4fa9d30bf4b70f73264b81ad6acd773d3eb00166 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Tue, 6 May 2025 13:26:37 -0300 Subject: [PATCH] refactor: update app buttons to use the new button component (#17684) Related to https://github.com/coder/coder/issues/17311 - Replaces the MUI Buttons by the new shadcn/ui buttons. This change allows the reuse of app links, and terminal buttons using the `asChild` capability from the Radix components - Uses the new [proposed design](https://www.figma.com/design/OR75XeUI0Z3ksqt1mHsNQw/Workspace-views?node-id=1014-8242&t=wtUXJRN1SfyZiFKn-0) - Updates the button styles to support image tags as icons - Uses the new Tooltip component for the app buttons **Before:** Screenshot 2025-05-05 at 17 55 49 **After:** Screenshot 2025-05-05 at 18 05 38 --- site/e2e/helpers.ts | 4 +- site/src/components/Button/Button.tsx | 12 ++-- .../ExternalImage/ExternalImage.tsx | 8 +-- .../modules/dashboard/Navbar/ProxyMenu.tsx | 25 +++---- .../management/OrganizationSidebarView.tsx | 34 +++++----- site/src/modules/resources/AgentButton.tsx | 27 +------- .../resources/AgentDevcontainerCard.tsx | 38 ++++++----- .../src/modules/resources/AppLink/AppLink.tsx | 68 +++++++++---------- .../resources/TerminalLink/TerminalLink.tsx | 35 +++++----- .../VSCodeDesktopButton.tsx | 20 +++--- .../VSCodeDevContainerButton.tsx | 20 +++--- site/src/theme/externalImages.ts | 2 - 12 files changed, 127 insertions(+), 166 deletions(-) diff --git a/site/e2e/helpers.ts b/site/e2e/helpers.ts index 71b1c039c5..85a9283aba 100644 --- a/site/e2e/helpers.ts +++ b/site/e2e/helpers.ts @@ -1042,7 +1042,9 @@ export async function openTerminalWindow( ): Promise { // Wait for the web terminal to open in a new tab const pagePromise = context.waitForEvent("page"); - await page.getByTestId("terminal").click({ timeout: 60_000 }); + await page + .getByRole("link", { name: /terminal/i }) + .click({ timeout: 60_000 }); const terminal = await pagePromise; await terminal.waitForLoadState("domcontentloaded"); diff --git a/site/src/components/Button/Button.tsx b/site/src/components/Button/Button.tsx index f3940fe45c..908dacb8c5 100644 --- a/site/src/components/Button/Button.tsx +++ b/site/src/components/Button/Button.tsx @@ -13,7 +13,9 @@ const buttonVariants = cva( text-sm font-semibold font-medium cursor-pointer no-underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-content-link disabled:pointer-events-none disabled:text-content-disabled - [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:p-0.5`, + [&:is(a):not([href])]:pointer-events-none [&:is(a):not([href])]:text-content-disabled + [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:p-0.5 + [&>img]:pointer-events-none [&>img]:shrink-0 [&>img]:p-0.5`, { variants: { variant: { @@ -28,11 +30,11 @@ const buttonVariants = cva( }, size: { - lg: "min-w-20 h-10 px-3 py-2 [&_svg]:size-icon-lg", - sm: "min-w-20 h-8 px-2 py-1.5 text-xs [&_svg]:size-icon-sm", + lg: "min-w-20 h-10 px-3 py-2 [&_svg]:size-icon-lg [&>img]:size-icon-lg", + sm: "min-w-20 h-8 px-2 py-1.5 text-xs [&_svg]:size-icon-sm [&>img]:size-icon-sm", xs: "min-w-8 py-1 px-2 text-2xs rounded-md", - icon: "size-8 px-1.5 [&_svg]:size-icon-sm", - "icon-lg": "size-10 px-2 [&_svg]:size-icon-lg", + icon: "size-8 px-1.5 [&_svg]:size-icon-sm [&>img]:size-icon-sm", + "icon-lg": "size-10 px-2 [&_svg]:size-icon-lg [&>img]:size-icon-lg", }, }, defaultVariants: { diff --git a/site/src/components/ExternalImage/ExternalImage.tsx b/site/src/components/ExternalImage/ExternalImage.tsx index b15af07944..d85b227b99 100644 --- a/site/src/components/ExternalImage/ExternalImage.tsx +++ b/site/src/components/ExternalImage/ExternalImage.tsx @@ -5,15 +5,15 @@ import { getExternalImageStylesFromUrl } from "theme/externalImages"; export const ExternalImage = forwardRef< HTMLImageElement, ImgHTMLAttributes ->((attrs, ref) => { +>((props, ref) => { const theme = useTheme(); return ( - // biome-ignore lint/a11y/useAltText: no reasonable alt to provide + // biome-ignore lint/a11y/useAltText: alt should be passed in as a prop ); }); diff --git a/site/src/modules/dashboard/Navbar/ProxyMenu.tsx b/site/src/modules/dashboard/Navbar/ProxyMenu.tsx index 86d9b9b53e..97e3609843 100644 --- a/site/src/modules/dashboard/Navbar/ProxyMenu.tsx +++ b/site/src/modules/dashboard/Navbar/ProxyMenu.tsx @@ -81,32 +81,25 @@ export const ProxyMenu: FC = ({ proxyContextValue }) => { {selectedProxy ? ( -
-
- -
+ <> + -
+ ) : ( "Select Proxy" )} - + -
- {activeOrganization ? ( - <> - - - {activeOrganization.display_name || activeOrganization.name} - - - ) : ( - No organization selected - )} -
- + {activeOrganization ? ( + <> + + + {activeOrganization.display_name || activeOrganization.name} + + + ) : ( + No organization selected + )} + diff --git a/site/src/modules/resources/AgentButton.tsx b/site/src/modules/resources/AgentButton.tsx index 2f772e4f8e..e5b4a54834 100644 --- a/site/src/modules/resources/AgentButton.tsx +++ b/site/src/modules/resources/AgentButton.tsx @@ -1,31 +1,8 @@ -import Button, { type ButtonProps } from "@mui/material/Button"; +import { Button, type ButtonProps } from "components/Button/Button"; import { forwardRef } from "react"; export const AgentButton = forwardRef( (props, ref) => { - const { children, ...buttonProps } = props; - - return ( - - ); + return