diff --git a/biome.jsonc b/biome.jsonc index daa99a8b90ce4..d1258a77d65ae 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -51,6 +51,7 @@ "@mui/material/Popover": "Use components/Popover/Popover instead.", "@mui/material/Typography": "Use native HTML elements instead. Eg: ,

,

, etc.", "@mui/material/Box": "Use a
instead.", + "@mui/material/Button": "Use a components/Button/Button instead.", "@mui/material/styles": "Import from @emotion/react instead.", "lodash": "Use lodash/ instead." } diff --git a/site/src/@types/mui.d.ts b/site/src/@types/mui.d.ts index 49804d33f8971..daad165f7d335 100644 --- a/site/src/@types/mui.d.ts +++ b/site/src/@types/mui.d.ts @@ -13,16 +13,6 @@ declare module "@mui/material/styles" { } } -declare module "@mui/material/Button" { - interface ButtonPropsColorOverrides { - neutral: true; - } - - interface ButtonPropsSizeOverrides { - xlarge: true; - } -} - declare module "@mui/material/Checkbox" { interface CheckboxPropsSizeOverrides { xsmall: true; diff --git a/site/src/components/InputGroup/InputGroup.stories.tsx b/site/src/components/InputGroup/InputGroup.stories.tsx index 77c86e52344ae..728970af93c49 100644 --- a/site/src/components/InputGroup/InputGroup.stories.tsx +++ b/site/src/components/InputGroup/InputGroup.stories.tsx @@ -1,6 +1,6 @@ -import Button from "@mui/material/Button"; import TextField from "@mui/material/TextField"; import type { Meta, StoryObj } from "@storybook/react-vite"; +import { Button } from "components/Button/Button"; import { InputGroup } from "./InputGroup"; const meta: Meta = { @@ -15,7 +15,9 @@ export const Default: Story = { args: { children: ( <> - + ), diff --git a/site/src/modules/dashboard/DeploymentBanner/DeploymentBannerView.tsx b/site/src/modules/dashboard/DeploymentBanner/DeploymentBannerView.tsx index 4f9838e0255da..eccd9ad6b62bb 100644 --- a/site/src/modules/dashboard/DeploymentBanner/DeploymentBannerView.tsx +++ b/site/src/modules/dashboard/DeploymentBanner/DeploymentBannerView.tsx @@ -1,5 +1,4 @@ import { css, type Interpolation, type Theme, useTheme } from "@emotion/react"; -import Button from "@mui/material/Button"; import Link from "@mui/material/Link"; import Tooltip from "@mui/material/Tooltip"; import type { @@ -7,6 +6,7 @@ import type { HealthcheckReport, WorkspaceStatus, } from "api/typesGenerated"; +import { Button } from "components/Button/Button"; import { HelpTooltipTitle } from "components/HelpTooltip/HelpTooltip"; import { JetBrainsIcon } from "components/Icons/JetBrainsIcon"; import { RocketIcon } from "components/Icons/RocketIcon"; @@ -323,9 +323,9 @@ export const DeploymentBannerView: FC = ({ fetchStats(); } }} - variant="text" + variant="subtle" > - + {timeUntilRefresh}s diff --git a/site/src/modules/resources/Resources.tsx b/site/src/modules/resources/Resources.tsx index 094092619347b..13e1bbf835252 100644 --- a/site/src/modules/resources/Resources.tsx +++ b/site/src/modules/resources/Resources.tsx @@ -1,5 +1,5 @@ -import Button from "@mui/material/Button"; import type { WorkspaceAgent, WorkspaceResource } from "api/typesGenerated"; +import { Button } from "components/Button/Button"; import { DropdownArrow } from "components/DropdownArrow/DropdownArrow"; import { Stack } from "components/Stack/Stack"; import { type FC, type JSX, useState } from "react"; @@ -37,8 +37,9 @@ export const Resources: FC = ({ resources, agentRow }) => { {hasHideResources && (
- diff --git a/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.tsx b/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.tsx index 847b531949c00..7614013c9bfbf 100644 --- a/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.tsx +++ b/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.tsx @@ -1,5 +1,4 @@ import type { Interpolation, Theme } from "@emotion/react"; -import Button from "@mui/material/Button"; import Collapse from "@mui/material/Collapse"; import Skeleton from "@mui/material/Skeleton"; import type { @@ -7,6 +6,7 @@ import type { AgentScriptTiming, ProvisionerTiming, } from "api/typesGenerated"; +import { Button } from "components/Button/Button"; import sortBy from "lodash/sortBy"; import uniqBy from "lodash/uniqBy"; import { ChevronDownIcon, ChevronUpIcon } from "lucide-react"; @@ -96,7 +96,7 @@ export const WorkspaceTimings: FC = ({
} > @@ -86,15 +85,14 @@ export const NotificationEvents: FC = ({ - Read the docs + } > diff --git a/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.tsx b/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.tsx index 55ee649353158..4b42f946758b8 100644 --- a/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.tsx @@ -1,5 +1,4 @@ import { useTheme } from "@emotion/react"; -import Button from "@mui/material/Button"; import Table from "@mui/material/Table"; import TableBody from "@mui/material/TableBody"; import TableCell from "@mui/material/TableCell"; @@ -9,6 +8,7 @@ import TableRow from "@mui/material/TableRow"; import type * as TypesGen from "api/typesGenerated"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { Avatar } from "components/Avatar/Avatar"; +import { Button } from "components/Button/Button"; import { SettingsHeader, SettingsHeaderDescription, @@ -48,12 +48,11 @@ const OAuth2AppsSettingsPageView: FC = ({
- diff --git a/site/src/pages/ExternalAuthPage/ExternalAuthPage.tsx b/site/src/pages/ExternalAuthPage/ExternalAuthPage.tsx index 105e7ee501b38..c4ae645d015c2 100644 --- a/site/src/pages/ExternalAuthPage/ExternalAuthPage.tsx +++ b/site/src/pages/ExternalAuthPage/ExternalAuthPage.tsx @@ -1,4 +1,3 @@ -import Button from "@mui/material/Button"; import type { ApiErrorResponse } from "api/errors"; import { exchangeExternalAuthDevice, @@ -6,6 +5,7 @@ import { externalAuthProvider, } from "api/queries/externalAuth"; import { isAxiosError } from "axios"; +import { Button } from "components/Button/Button"; import { isExchangeErrorRetryable, newRetryDelay, @@ -91,6 +91,7 @@ const ExternalAuthPage: FC = () => {


+ )} @@ -353,12 +351,6 @@ const styles = { autoComplete: { width: 300, }, - removeButton: (theme) => ({ - color: theme.palette.error.main, - "&:hover": { - backgroundColor: "transparent", - }, - }), status: { textTransform: "capitalize", }, diff --git a/site/src/pages/HealthPage/DERPPage.tsx b/site/src/pages/HealthPage/DERPPage.tsx index 8b4b85bd37551..3a913f23e05d5 100644 --- a/site/src/pages/HealthPage/DERPPage.tsx +++ b/site/src/pages/HealthPage/DERPPage.tsx @@ -1,11 +1,11 @@ import { useTheme } from "@emotion/react"; -import Button from "@mui/material/Button"; import type { HealthcheckReport, HealthSeverity, NetcheckReport, } from "api/typesGenerated"; import { Alert } from "components/Alert/Alert"; +import { Button } from "components/Button/Button"; import { MapPinIcon } from "lucide-react"; import type { FC } from "react"; import { Link, useOutletContext } from "react-router"; @@ -100,10 +100,9 @@ const DERPPage: FC = () => { }) .map(({ severity, region }) => { return ( - ); })} diff --git a/site/src/pages/LoginPage/OAuthSignInForm.tsx b/site/src/pages/LoginPage/OAuthSignInForm.tsx index e4872d6600389..343353d18dfca 100644 --- a/site/src/pages/LoginPage/OAuthSignInForm.tsx +++ b/site/src/pages/LoginPage/OAuthSignInForm.tsx @@ -1,16 +1,11 @@ import GitHubIcon from "@mui/icons-material/GitHub"; import KeyIcon from "@mui/icons-material/VpnKey"; -import Button from "@mui/material/Button"; import { visuallyHidden } from "@mui/utils"; import type { AuthMethods } from "api/typesGenerated"; +import { Button } from "components/Button/Button"; import { type FC, useId } from "react"; import { Language } from "./Language"; -const iconStyles = { - width: 16, - height: 16, -}; - type OAuthSignInFormProps = { isSigningIn: boolean; redirectTo: string; @@ -26,41 +21,45 @@ export const OAuthSignInForm: FC = ({
{authMethods?.github.enabled && ( )} {authMethods?.oidc.enabled && ( )}
@@ -80,7 +79,7 @@ const OidcIcon: FC = ({ iconUrl }) => { // if that happens, but also still need a way to inject accessible text return ( <> - +
Open ID Connect
diff --git a/site/src/pages/OrganizationSettingsPage/CustomRolesPage/CustomRolesPageView.tsx b/site/src/pages/OrganizationSettingsPage/CustomRolesPage/CustomRolesPageView.tsx index cd94b6a18e669..e3074f3ada94e 100644 --- a/site/src/pages/OrganizationSettingsPage/CustomRolesPage/CustomRolesPageView.tsx +++ b/site/src/pages/OrganizationSettingsPage/CustomRolesPage/CustomRolesPageView.tsx @@ -1,8 +1,7 @@ import type { Interpolation, Theme } from "@emotion/react"; -import Button from "@mui/material/Button"; import Skeleton from "@mui/material/Skeleton"; import type { AssignableRoles, Role } from "api/typesGenerated"; -import { Button as ShadcnButton } from "components/Button/Button"; +import { Button, Button as ShadcnButton } from "components/Button/Button"; import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; import { DropdownMenu, @@ -72,12 +71,11 @@ export const CustomRolesPageView: FC = ({ {canCreateOrgRole && isCustomRolesEnabled && ( - )} @@ -157,13 +155,11 @@ const RoleTable: FC = ({ cta={ canCreateOrgRole && isCustomRolesEnabled && ( - ) } diff --git a/site/src/pages/ResetPasswordPage/ChangePasswordPage.tsx b/site/src/pages/ResetPasswordPage/ChangePasswordPage.tsx index c7ae619950b43..9ec361a39932c 100644 --- a/site/src/pages/ResetPasswordPage/ChangePasswordPage.tsx +++ b/site/src/pages/ResetPasswordPage/ChangePasswordPage.tsx @@ -1,5 +1,4 @@ import type { Interpolation, Theme } from "@emotion/react"; -import MUIButton from "@mui/material/Button"; import TextField from "@mui/material/TextField"; import { isApiValidationError } from "api/errors"; import { changePasswordWithOTP } from "api/queries/users"; @@ -119,15 +118,9 @@ const ChangePasswordPage: FC = ({ redirect }) => { Reset password - - Back to login - + diff --git a/site/src/pages/SetupPage/SetupPageView.tsx b/site/src/pages/SetupPage/SetupPageView.tsx index 96654bdda8514..57534ddbe74cd 100644 --- a/site/src/pages/SetupPage/SetupPageView.tsx +++ b/site/src/pages/SetupPage/SetupPageView.tsx @@ -1,7 +1,6 @@ import GitHubIcon from "@mui/icons-material/GitHub"; import AlertTitle from "@mui/material/AlertTitle"; import Autocomplete from "@mui/material/Autocomplete"; -import MuiButton from "@mui/material/Button"; import Checkbox from "@mui/material/Checkbox"; import Link from "@mui/material/Link"; import MenuItem from "@mui/material/MenuItem"; @@ -173,17 +172,12 @@ export const SetupPageView: FC = ({ {authMethods?.github.enabled && ( <> - } - type="submit" - size="xlarge" - > - {Language.githubCreate} - +
diff --git a/site/src/pages/TemplatePage/TemplatePageHeader.tsx b/site/src/pages/TemplatePage/TemplatePageHeader.tsx index dd93054f64d9e..8db6afcd07292 100644 --- a/site/src/pages/TemplatePage/TemplatePageHeader.tsx +++ b/site/src/pages/TemplatePage/TemplatePageHeader.tsx @@ -1,4 +1,3 @@ -import Button from "@mui/material/Button"; import { API } from "api/api"; import { workspaces } from "api/queries/workspaces"; import type { @@ -7,7 +6,7 @@ import type { TemplateVersion, } from "api/typesGenerated"; import { Avatar } from "components/Avatar/Avatar"; -import { Button as ShadcnButton } from "components/Button/Button"; +import { Button, Button as ShadcnButton } from "components/Button/Button"; import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog"; import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog"; import { @@ -222,13 +221,11 @@ export const TemplatePageHeader: FC = ({ <> {!template.deprecated && workspacePermissions.createWorkspaceForUserID && ( - )} diff --git a/site/src/theme/constants.ts b/site/src/theme/constants.ts index f74611cefd324..28b5234d8f138 100644 --- a/site/src/theme/constants.ts +++ b/site/src/theme/constants.ts @@ -34,7 +34,5 @@ export const containerWidthMedium = 1080; export const sidePadding = 24; // MUI does not have aligned heights for buttons and inputs so we have to "hack" it a little bit -export const BUTTON_XL_HEIGHT = 44; export const BUTTON_LG_HEIGHT = 40; export const BUTTON_MD_HEIGHT = 36; -export const BUTTON_SM_HEIGHT = 32; diff --git a/site/src/theme/light/mui.ts b/site/src/theme/light/mui.ts index 8092b5f8cbe80..8fe2e25b6ca0d 100644 --- a/site/src/theme/light/mui.ts +++ b/site/src/theme/light/mui.ts @@ -108,67 +108,6 @@ const muiTheme = createTheme({ }, }, }, - MuiButton: { - ...components.MuiButton, - styleOverrides: { - ...components.MuiButton.styleOverrides, - outlined: ({ theme }) => ({ - boxShadow: "0 1px 4px #0001", - ":hover": { - boxShadow: "0 1px 4px #0001", - border: `1px solid ${theme.palette.secondary.main}`, - }, - "&.Mui-disabled": { - boxShadow: "none !important", - }, - }), - ["outlinedNeutral" as MuiStyle]: { - borderColor: tw.zinc[300], - - "&.Mui-disabled": { - borderColor: tw.zinc[200], - color: tw.zinc[500], - - "& > .MuiLoadingButton-loadingIndicator": { - color: tw.zinc[500], - }, - }, - }, - contained: { - boxShadow: "0 1px 4px #0001", - "&.Mui-disabled": { - boxShadow: "none !important", - }, - ":hover": { - boxShadow: "0 1px 4px #0001", - }, - }, - ["containedNeutral" as MuiStyle]: { - backgroundColor: tw.zinc[100], - border: `1px solid ${tw.zinc[200]}`, - - "&.Mui-disabled": { - backgroundColor: tw.zinc[50], - border: `1px solid ${tw.zinc[100]}`, - }, - - "&:hover": { - backgroundColor: tw.zinc[200], - border: `1px solid ${tw.zinc[300]}`, - }, - }, - }, - }, - MuiButtonGroup: { - styleOverrides: { - root: { - ">button:hover+button": { - // The !important is unfortunate, but necessary for the border. - borderLeftColor: `${tw.zinc[300]} !important`, - }, - }, - }, - }, MuiChip: { styleOverrides: { root: { diff --git a/site/src/theme/mui.ts b/site/src/theme/mui.ts index fc20b0a9f9be1..4435579a33153 100644 --- a/site/src/theme/mui.ts +++ b/site/src/theme/mui.ts @@ -6,8 +6,6 @@ import { BODY_FONT_FAMILY, BUTTON_LG_HEIGHT, BUTTON_MD_HEIGHT, - BUTTON_SM_HEIGHT, - BUTTON_XL_HEIGHT, borderRadius, } from "./constants"; import tw from "./tailwindColors"; @@ -61,112 +59,6 @@ export const components = { }), }, }, - // Button styles are based on - // https://tailwindui.com/components/application-ui/elements/buttons - MuiButtonBase: { - defaultProps: { - disableRipple: true, - }, - }, - MuiButton: { - defaultProps: { - variant: "outlined", - color: "neutral", - }, - styleOverrides: { - root: ({ theme }) => ({ - textTransform: "none", - letterSpacing: "normal", - fontWeight: 500, - height: BUTTON_MD_HEIGHT, - padding: "8px 16px", - borderRadius: "6px", - fontSize: 14, - - whiteSpace: "nowrap", - ":focus-visible": { - outline: `2px solid ${theme.palette.primary.main}`, - }, - - "& .MuiLoadingButton-loadingIndicator": { - width: 14, - height: 14, - }, - - "& .MuiLoadingButton-loadingIndicator .MuiCircularProgress-root": { - width: "inherit !important", - height: "inherit !important", - }, - }), - sizeSmall: { - height: BUTTON_SM_HEIGHT, - }, - sizeLarge: { - height: BUTTON_LG_HEIGHT, - }, - ["sizeXlarge" as MuiStyle]: { - height: BUTTON_XL_HEIGHT, - - // With higher size we need to increase icon spacing. - "& .MuiButton-startIcon": { - marginRight: 12, - }, - "& .MuiButton-endIcon": { - marginLeft: 12, - }, - }, - outlined: ({ theme }) => ({ - ":hover": { - border: `1px solid ${theme.palette.secondary.main}`, - }, - }), - ["outlinedNeutral" as MuiStyle]: { - borderColor: tw.zinc[600], - - "&.Mui-disabled": { - borderColor: tw.zinc[700], - color: tw.zinc[500], - - "& > .MuiLoadingButton-loadingIndicator": { - color: tw.zinc[500], - }, - }, - }, - ["containedNeutral" as MuiStyle]: { - backgroundColor: tw.zinc[800], - - "&:hover": { - backgroundColor: tw.zinc[700], - }, - }, - iconSizeMedium: { - "& > .MuiSvgIcon-root": { - fontSize: 14, - }, - }, - iconSizeSmall: { - "& > .MuiSvgIcon-root": { - fontSize: 13, - }, - }, - }, - }, - MuiButtonGroup: { - styleOverrides: { - root: ({ theme }) => ({ - ">button:hover+button": { - // The !important is unfortunate, but necessary for the border. - borderLeftColor: `${theme.palette.secondary.main} !important`, - }, - }), - }, - }, - ["MuiLoadingButton" as MuiStyle]: { - defaultProps: { - variant: "outlined", - color: "neutral", - }, - }, MuiTableContainer: { styleOverrides: { root: ({ theme }) => ({