diff --git a/site/src/components/Alert/Alert.tsx b/site/src/components/Alert/Alert.tsx index 2673cd9bc4f8a..befe6c0d2780e 100644 --- a/site/src/components/Alert/Alert.tsx +++ b/site/src/components/Alert/Alert.tsx @@ -10,6 +10,7 @@ import { type ReactNode, useState, } from "react"; +import { cn } from "utils/cn"; export type AlertColor = MuiAlertColor; export type AlertProps = MuiAlertProps & { @@ -39,7 +40,7 @@ export const Alert: FC = ({ @@ -72,7 +73,7 @@ export const Alert: FC = ({ export const AlertDetail: FC = ({ children }) => { return ( ({ color: theme.palette.text.secondary, fontSize: 13 })} + className={"text-[13px] text-content-secondary"} data-chromatic="ignore" > {children} diff --git a/site/src/components/Avatar/AvatarCard.tsx b/site/src/components/Avatar/AvatarCard.tsx index 97df5c6ee765c..c7f29a66ad616 100644 --- a/site/src/components/Avatar/AvatarCard.tsx +++ b/site/src/components/Avatar/AvatarCard.tsx @@ -1,6 +1,6 @@ -import { type CSSObject, useTheme } from "@emotion/react"; import { Avatar } from "components/Avatar/Avatar"; import type { FC, ReactNode } from "react"; +import { cn } from "utils/cn"; type AvatarCardProps = { header: string; @@ -15,20 +15,16 @@ export const AvatarCard: FC = ({ subtitle, maxWidth = "none", }) => { - const theme = useTheme(); - return (
{/** @@ -37,31 +33,17 @@ export const AvatarCard: FC = ({ * * @see {@link https://css-tricks.com/flexbox-truncated-text/} */} -
+

{header}

{subtitle && ( -
+
{subtitle}
)} diff --git a/site/src/components/Badges/Badges.stories.tsx b/site/src/components/Badges/Badges.stories.tsx index 36c8fddb37ea9..2deca004660a1 100644 --- a/site/src/components/Badges/Badges.stories.tsx +++ b/site/src/components/Badges/Badges.stories.tsx @@ -2,8 +2,10 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import { AlphaBadge, Badges, + DeprecatedBadge, DisabledBadge, EnabledBadge, + EnterpriseBadge, EntitledBadge, HealthyBadge, NotHealthyBadge, @@ -50,6 +52,11 @@ export const Disabled: Story = { children: , }, }; +export const Enterprise: Story = { + args: { + children: , + }, +}; export const Premium: Story = { args: { children: , @@ -65,3 +72,8 @@ export const Alpha: Story = { children: , }, }; +export const Deprecated: Story = { + args: { + children: , + }, +}; diff --git a/site/src/components/Badges/Badges.tsx b/site/src/components/Badges/Badges.tsx index cef5288091373..fe0a45db2dad1 100644 --- a/site/src/components/Badges/Badges.tsx +++ b/site/src/components/Badges/Badges.tsx @@ -1,5 +1,3 @@ -import type { Interpolation, Theme } from "@emotion/react"; -import { Stack } from "components/Stack/Stack"; import { Tooltip, TooltipContent, @@ -11,49 +9,44 @@ import { type HTMLAttributes, type PropsWithChildren, } from "react"; +import { cn } from "utils/cn"; -const styles = { - badge: { - fontSize: 10, - height: 24, - fontWeight: 600, - textTransform: "uppercase", - letterSpacing: "0.085em", - padding: "0 12px", - borderRadius: 9999, - display: "flex", - alignItems: "center", - width: "fit-content", - whiteSpace: "nowrap", - }, - - enabledBadge: (theme) => ({ - border: `1px solid ${theme.roles.success.outline}`, - backgroundColor: theme.roles.success.background, - color: theme.roles.success.text, - }), - errorBadge: (theme) => ({ - border: `1px solid ${theme.roles.error.outline}`, - backgroundColor: theme.roles.error.background, - color: theme.roles.error.text, - }), - warnBadge: (theme) => ({ - border: `1px solid ${theme.roles.warning.outline}`, - backgroundColor: theme.roles.warning.background, - color: theme.roles.warning.text, - }), -} satisfies Record>; +const badgeClasses = { + root: [ + "text-[10px] h-6 font-semibold uppercase tracking-[0.085em]", + "px-3 rounded-full flex items-center w-fit whitespace-nowrap", + "border border-solid leading-none", + ], + enabled: ["border-green-500 bg-green-950 text-green-50"], + error: ["border-red-600 bg-red-950 text-red-50"], + warn: ["border-amber-300 bg-amber-950 text-amber-50"], + enterprise: ["border-blue-400 bg-blue-950 text-blue-50"], + disabled: ["border-zinc-700 bg-zinc-900 text-white"], + premium: ["border-violet-400 bg-violet-950 text-violet-50"], + preview: ["border-violet-500 bg-violet-950 text-violet-50"], + deprecated: ["border-orange-500 bg-orange-950 text-orange-50"], +} as const; export const EnabledBadge: FC = () => { return ( - + Enabled ); }; export const EntitledBadge: FC = () => { - return Entitled; + return ( + + Entitled + + ); }; interface HealthyBadge { @@ -61,21 +54,25 @@ interface HealthyBadge { } export const HealthyBadge: FC = ({ derpOnly }) => { return ( - + {derpOnly ? "Healthy (DERP only)" : "Healthy"} ); }; export const NotHealthyBadge: FC = () => { - return Unhealthy; + return ( + Unhealthy + ); }; export const NotRegisteredBadge: FC = () => { return ( - Never seen + + Never seen + Workspace Proxy has never come online and needs to be started. @@ -88,7 +85,9 @@ export const NotReachableBadge: FC = () => { return ( - Not reachable + + Not reachable + Workspace Proxy not responding to http(s) requests. @@ -105,15 +104,11 @@ export const DisabledBadge: FC = forwardRef< ({ - border: `1px solid ${theme.experimental.l1.outline}`, - backgroundColor: theme.experimental.l1.background, - color: theme.experimental.l1.text, - }), - ]} - className="option-disabled" + className={cn([ + "option-disabled", + badgeClasses.root, + badgeClasses.disabled, + ])} > Disabled @@ -122,16 +117,7 @@ export const DisabledBadge: FC = forwardRef< export const EnterpriseBadge: FC = () => { return ( - ({ - backgroundColor: theme.branding.enterprise.background, - border: `1px solid ${theme.branding.enterprise.border}`, - color: theme.branding.enterprise.text, - }), - ]} - > + Enterprise ); @@ -139,67 +125,25 @@ export const EnterpriseBadge: FC = () => { export const PremiumBadge: FC = () => { return ( - ({ - backgroundColor: theme.branding.premium.background, - border: `1px solid ${theme.branding.premium.border}`, - color: theme.branding.premium.text, - }), - ]} - > - Premium - + Premium ); }; export const PreviewBadge: FC = () => { return ( - ({ - border: `1px solid ${theme.roles.preview.outline}`, - backgroundColor: theme.roles.preview.background, - color: theme.roles.preview.text, - }), - ]} - > - Preview - + Preview ); }; export const AlphaBadge: FC = () => { return ( - ({ - border: `1px solid ${theme.roles.preview.outline}`, - backgroundColor: theme.roles.preview.background, - color: theme.roles.preview.text, - }), - ]} - > - Alpha - + Alpha ); }; export const DeprecatedBadge: FC = () => { return ( - ({ - border: `1px solid ${theme.roles.danger.outline}`, - backgroundColor: theme.roles.danger.background, - color: theme.roles.danger.text, - }), - ]} - > + Deprecated ); @@ -207,13 +151,6 @@ export const DeprecatedBadge: FC = () => { export const Badges: FC = ({ children }) => { return ( - - {children} - +
{children}
); }; diff --git a/site/src/components/CodeExample/CodeExample.tsx b/site/src/components/CodeExample/CodeExample.tsx index 42759889fd1eb..58f4411b836da 100644 --- a/site/src/components/CodeExample/CodeExample.tsx +++ b/site/src/components/CodeExample/CodeExample.tsx @@ -1,4 +1,3 @@ -import type { Interpolation, Theme } from "@emotion/react"; import { Button } from "components/Button/Button"; import { Tooltip, @@ -7,7 +6,7 @@ import { } from "components/Tooltip/Tooltip"; import { EyeIcon, EyeOffIcon } from "lucide-react"; import { type FC, useState } from "react"; -import { MONOSPACE_FONT_FAMILY } from "theme/constants"; +import { cn } from "utils/cn"; import { CopyButton } from "../CopyButton/CopyButton"; interface CodeExampleProps { @@ -52,8 +51,21 @@ export const CodeExample: FC = ({ ); return ( -
- +
+ {secret ? ( <> {/* @@ -99,33 +111,3 @@ export const CodeExample: FC = ({ function obfuscateText(text: string): string { return new Array(text.length).fill("*").join(""); } - -const styles = { - container: (theme) => ({ - cursor: "pointer", - display: "flex", - flexDirection: "row", - alignItems: "center", - color: theme.experimental.l1.text, - fontFamily: MONOSPACE_FONT_FAMILY, - fontSize: 14, - borderRadius: 8, - padding: 8, - lineHeight: "150%", - border: `1px solid ${theme.experimental.l1.outline}`, - - "&:hover": { - backgroundColor: theme.experimental.l2.hover.background, - }, - }), - - code: { - padding: "0 8px", - flexGrow: 1, - wordBreak: "break-all", - }, - - secret: { - "-webkit-text-security": "disc", // also supported by firefox - }, -} satisfies Record>; diff --git a/site/src/components/CustomLogo/CustomLogo.tsx b/site/src/components/CustomLogo/CustomLogo.tsx index 0e8c080d4375c..ca6a7da781d06 100644 --- a/site/src/components/CustomLogo/CustomLogo.tsx +++ b/site/src/components/CustomLogo/CustomLogo.tsx @@ -24,8 +24,7 @@ export const CustomLogo: FC<{ css?: Interpolation }> = (props) => { onLoad={(e) => { e.currentTarget.style.display = "inline"; }} - css={{ maxWidth: 200 }} - className="application-logo" + className="application-logo max-w-50" /> ) : ( diff --git a/site/src/components/Dialogs/ConfirmDialog/ConfirmDialog.tsx b/site/src/components/Dialogs/ConfirmDialog/ConfirmDialog.tsx index 1b253ad848c77..6ffd7075a3d10 100644 --- a/site/src/components/Dialogs/ConfirmDialog/ConfirmDialog.tsx +++ b/site/src/components/Dialogs/ConfirmDialog/ConfirmDialog.tsx @@ -1,6 +1,6 @@ -import type { Interpolation, Theme } from "@emotion/react"; import DialogActions from "@mui/material/DialogActions"; import type { FC, ReactNode } from "react"; +import { cn } from "utils/cn"; import { Dialog, DialogActionButtons, @@ -52,48 +52,6 @@ export interface ConfirmDialogProps readonly title: string; } -const styles = { - dialogWrapper: (theme) => ({ - "& .MuiPaper-root": { - background: theme.palette.background.paper, - border: `1px solid ${theme.palette.divider}`, - width: "100%", - maxWidth: 440, - }, - "& .MuiDialogActions-spacing": { - padding: "0 40px 40px", - }, - }), - dialogContent: (theme) => ({ - color: theme.palette.text.secondary, - padding: "40px 40px 20px", - }), - dialogTitle: (theme) => ({ - margin: 0, - marginBottom: 16, - color: theme.palette.text.primary, - fontWeight: 400, - fontSize: 20, - }), - dialogDescription: (theme) => ({ - color: theme.palette.text.secondary, - lineHeight: "160%", - fontSize: 16, - - "& strong": { - color: theme.palette.text.primary, - }, - - "& p:not(.MuiFormHelperText-root)": { - margin: 0, - }, - - "& > p": { - margin: "8px 0", - }, - }), -} satisfies Record>; - /** * Quick-use version of the Dialog component with slightly alternative styles, * great to use for dialogs that don't have any interaction beyond yes / no. @@ -119,14 +77,24 @@ export const ConfirmDialog: FC = ({ return ( -
-

{title}

- {description &&
{description}
} +
+

+ {title} +

+ {description && ( +
+ {description} +
+ )}
diff --git a/site/src/components/Dialogs/DeleteDialog/DeleteDialog.tsx b/site/src/components/Dialogs/DeleteDialog/DeleteDialog.tsx index 9bee94fe24714..cdc4b63949e63 100644 --- a/site/src/components/Dialogs/DeleteDialog/DeleteDialog.tsx +++ b/site/src/components/Dialogs/DeleteDialog/DeleteDialog.tsx @@ -1,4 +1,3 @@ -import type { Interpolation, Theme } from "@emotion/react"; import TextField from "@mui/material/TextField"; import { type FC, type FormEvent, useId, useState } from "react"; import { Stack } from "../../Stack/Stack"; @@ -67,7 +66,11 @@ export const DeleteDialog: FC = ({ {verb ?? "Deleting"} this {entity} is irreversible!

- {Boolean(info) &&
{info}
} + {Boolean(info) && ( +
+ {info} +
+ )}

Type {name} below to confirm. @@ -78,7 +81,7 @@ export const DeleteDialog: FC = ({ = ({ /> ); }; - -const styles = { - callout: (theme) => ({ - backgroundColor: theme.roles.danger.background, - border: `1px solid ${theme.roles.danger.outline}`, - borderRadius: theme.shape.borderRadius, - color: theme.roles.danger.text, - padding: "8px 16px", - }), -} satisfies Record>; diff --git a/site/src/components/DropdownArrow/DropdownArrow.tsx b/site/src/components/DropdownArrow/DropdownArrow.tsx index a791f2e26e1cc..abf230b5f8a90 100644 --- a/site/src/components/DropdownArrow/DropdownArrow.tsx +++ b/site/src/components/DropdownArrow/DropdownArrow.tsx @@ -1,6 +1,6 @@ -import type { Interpolation, Theme } from "@emotion/react"; import { ChevronDownIcon, ChevronUpIcon } from "lucide-react"; import type { FC } from "react"; +import { cn } from "utils/cn"; interface ArrowProps { margin?: boolean; @@ -18,20 +18,8 @@ export const DropdownArrow: FC = ({ return ( ); }; - -const styles = { - base: { - color: "currentcolor", - width: 16, - height: 16, - }, - - withMargin: { - marginLeft: 8, - }, -} satisfies Record>; diff --git a/site/src/components/DurationField/DurationField.tsx b/site/src/components/DurationField/DurationField.tsx index 9a2cb602fb469..8d94ae6f87037 100644 --- a/site/src/components/DurationField/DurationField.tsx +++ b/site/src/components/DurationField/DurationField.tsx @@ -77,12 +77,7 @@ export const DurationField: FC = (props) => { return (

-
+
= (props) => { /> = ({
Shared Ports @@ -536,10 +520,9 @@ export const PortForwardPopoverView: FC = ({ > diff --git a/site/src/modules/resources/PortForwardPopoverView.stories.tsx b/site/src/modules/resources/PortForwardPopoverView.stories.tsx index e1663f1db4590..c116d1403e416 100644 --- a/site/src/modules/resources/PortForwardPopoverView.stories.tsx +++ b/site/src/modules/resources/PortForwardPopoverView.stories.tsx @@ -16,11 +16,10 @@ const meta: Meta = { (Story) => (
({ - width: 404, border: `1px solid ${theme.palette.divider}`, - borderRadius: 8, backgroundColor: theme.palette.background.paper, })} + className="w-[404px] rounded-lg" >
diff --git a/site/src/modules/resources/VSCodeDesktopButton/VSCodeDesktopButton.tsx b/site/src/modules/resources/VSCodeDesktopButton/VSCodeDesktopButton.tsx index 56f3b5d07027c..5ff59698ba423 100644 --- a/site/src/modules/resources/VSCodeDesktopButton/VSCodeDesktopButton.tsx +++ b/site/src/modules/resources/VSCodeDesktopButton/VSCodeDesktopButton.tsx @@ -78,21 +78,21 @@ export const VSCodeDesktopButton: FC = (props) => { }} > { selectVariant("vscode"); }} > - + {DisplayAppNameMap.vscode} { selectVariant("vscode-insiders"); }} > - + {DisplayAppNameMap.vscode_insiders} diff --git a/site/src/modules/resources/VSCodeDevContainerButton/VSCodeDevContainerButton.tsx b/site/src/modules/resources/VSCodeDevContainerButton/VSCodeDevContainerButton.tsx index efd6ecc9bc00c..4016fc2b754d7 100644 --- a/site/src/modules/resources/VSCodeDevContainerButton/VSCodeDevContainerButton.tsx +++ b/site/src/modules/resources/VSCodeDevContainerButton/VSCodeDevContainerButton.tsx @@ -75,28 +75,27 @@ export const VSCodeDevContainerButton: FC = ( open={isVariantMenuOpen} anchorEl={menuAnchorRef.current} onClose={() => setIsVariantMenuOpen(false)} - css={{ - "& .MuiMenu-paper": { - width: menuAnchorRef.current?.clientWidth, - }, + style={{ + "--anchor-width": menuAnchorRef.current?.clientWidth, }} + className="[&_.MuiMenu-paper]:w-[var(--anchor-width)]" > { selectVariant("vscode"); }} > - + {DisplayAppNameMap.vscode} { selectVariant("vscode-insiders"); }} > - + {DisplayAppNameMap.vscode_insiders} diff --git a/site/src/modules/templates/TemplateExampleCard/TemplateExampleCard.tsx b/site/src/modules/templates/TemplateExampleCard/TemplateExampleCard.tsx index 6ecdc11ed84d9..7c4c2f2154801 100644 --- a/site/src/modules/templates/TemplateExampleCard/TemplateExampleCard.tsx +++ b/site/src/modules/templates/TemplateExampleCard/TemplateExampleCard.tsx @@ -1,4 +1,3 @@ -import type { Interpolation, Theme } from "@emotion/react"; import Link from "@mui/material/Link"; import type { TemplateExample } from "api/typesGenerated"; import { Button } from "components/Button/Button"; @@ -6,6 +5,7 @@ import { ExternalImage } from "components/ExternalImage/ExternalImage"; import { Pill } from "components/Pill/Pill"; import type { FC, HTMLAttributes } from "react"; import { Link as RouterLink } from "react-router"; +import { cn } from "utils/cn"; type TemplateExampleCardProps = HTMLAttributes & { example: TemplateExample; @@ -18,19 +18,24 @@ export const TemplateExampleCard: FC = ({ ...divProps }) => { return ( -
-
-
+
+
+
-
+
{example.tags.map((tag) => ( - + {tag} @@ -39,22 +44,20 @@ export const TemplateExampleCard: FC = ({
-

- {example.name} -

- +

{example.name}

+ {example.description}{" "} Read more
-
+
diff --git a/site/src/pages/CreateTokenPage/CreateTokenPage.tsx b/site/src/pages/CreateTokenPage/CreateTokenPage.tsx index 5184efb908d1d..813a81be1cdd1 100644 --- a/site/src/pages/CreateTokenPage/CreateTokenPage.tsx +++ b/site/src/pages/CreateTokenPage/CreateTokenPage.tsx @@ -72,12 +72,7 @@ const CreateTokenPage: FC = () => { ); diff --git a/site/src/pages/CreateUserPage/CreateUserForm.tsx b/site/src/pages/CreateUserPage/CreateUserForm.tsx index 3cad2f2a718cb..bca8e47fd043e 100644 --- a/site/src/pages/CreateUserPage/CreateUserForm.tsx +++ b/site/src/pages/CreateUserPage/CreateUserForm.tsx @@ -124,7 +124,7 @@ export const CreateUserForm: FC< return ( {isApiError(error) && !hasApiFieldErrors(error) && ( - + )}
@@ -188,21 +188,9 @@ export const CreateUserForm: FC< const language = authMethodLanguage[value]; return ( - + {language.displayName} - ({ - fontSize: 14, - color: theme.palette.text.secondary, - wordWrap: "normal", - whiteSpace: "break-spaces", - })} - > + {language.description} diff --git a/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AnnouncementBannerDialog.tsx b/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AnnouncementBannerDialog.tsx index 510a369c85807..432127fcfee0b 100644 --- a/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AnnouncementBannerDialog.tsx +++ b/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AnnouncementBannerDialog.tsx @@ -41,7 +41,7 @@ export const AnnouncementBannerDialog: FC = ({ return ( {/* Banner preview */} -
+
-

- Announcement Banners -

+

Announcement Banners