Skip to content

Commit 33761c9

Browse files
authored
refactor: add experimental NewTheme (#10613)
1 parent 652097e commit 33761c9

File tree

13 files changed

+508
-37
lines changed

13 files changed

+508
-37
lines changed

site/.storybook/preview.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
import { ThemeProvider as EmotionThemeProvider } from "@emotion/react";
77
import { withRouter } from "storybook-addon-react-router-v6";
88
import { HelmetProvider } from "react-helmet-async";
9-
import { dark } from "theme";
9+
import { dark } from "theme/mui";
1010
import "theme/globalFonts";
1111
import { QueryClient, QueryClientProvider } from "react-query";
1212

site/src/@types/emotion.d.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import type { DefaultTheme as MuiTheme } from "@mui/system";
2+
import type { NewTheme } from "theme/experimental";
23

34
declare module "@emotion/react" {
4-
interface Theme extends MuiTheme {}
5+
interface Theme extends MuiTheme {
6+
experimental: NewTheme;
7+
}
58
}

site/src/@types/mui.d.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1-
import { PaletteColor, PaletteColorOptions, Theme } from "@mui/material/styles";
1+
import type {
2+
PaletteColor,
3+
PaletteColorOptions,
4+
Theme,
5+
} from "@mui/material/styles";
6+
import type { NewTheme } from "theme/experimental";
27

38
declare module "@mui/styles/defaultTheme" {
49
interface DefaultTheme extends Theme {}
510
}
611

712
declare module "@mui/material/styles" {
13+
interface Theme {
14+
experimental: NewTheme;
15+
}
16+
817
interface TypeBackground {
918
paperLight: string;
1019
}
@@ -23,3 +32,9 @@ declare module "@mui/material/Button" {
2332
neutral: true;
2433
}
2534
}
35+
36+
declare module "@mui/system" {
37+
interface Theme {
38+
experimental: NewTheme;
39+
}
40+
}

site/src/App.tsx

+9-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { HelmetProvider } from "react-helmet-async";
66
import { AppRouter } from "./AppRouter";
77
import { ErrorBoundary } from "./components/ErrorBoundary/ErrorBoundary";
88
import { GlobalSnackbar } from "./components/GlobalSnackbar/GlobalSnackbar";
9-
import { dark } from "./theme";
9+
import { dark } from "./theme/mui";
10+
import { dark as experimental } from "./theme/experimental";
1011
import "./theme/globalFonts";
1112
import {
1213
StyledEngineProvider,
@@ -25,11 +26,16 @@ const defaultQueryClient = new QueryClient({
2526
},
2627
});
2728

29+
const theme = {
30+
...dark,
31+
experimental,
32+
};
33+
2834
export const ThemeProviders: FC<PropsWithChildren> = ({ children }) => {
2935
return (
3036
<StyledEngineProvider injectFirst>
31-
<MuiThemeProvider theme={dark}>
32-
<EmotionThemeProvider theme={dark}>
37+
<MuiThemeProvider theme={theme}>
38+
<EmotionThemeProvider theme={theme}>
3339
<CssBaseline enableColorScheme />
3440
{children}
3541
</EmotionThemeProvider>

site/src/components/BuildAvatar/BuildAvatar.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import Badge from "@mui/material/Badge";
2-
import { useTheme, withStyles } from "@mui/styles";
3-
import { FC } from "react";
2+
import { withStyles } from "@mui/styles";
3+
import { type FC } from "react";
44
import { WorkspaceBuild } from "api/typesGenerated";
55
import { getDisplayWorkspaceBuildStatus } from "utils/workspace";
66
import { Avatar, AvatarProps } from "components/Avatar/Avatar";
7-
import { PaletteIndex } from "theme/theme";
8-
import { Theme } from "@mui/material/styles";
7+
import type { PaletteIndex } from "theme/mui";
8+
import { useTheme } from "@emotion/react";
99
import { BuildIcon } from "components/BuildIcon/BuildIcon";
1010

1111
interface StylesBadgeProps {
@@ -30,7 +30,7 @@ export interface BuildAvatarProps {
3030
}
3131

3232
export const BuildAvatar: FC<BuildAvatarProps> = ({ build, size }) => {
33-
const theme = useTheme<Theme>();
33+
const theme = useTheme();
3434
const displayBuildStatus = getDisplayWorkspaceBuildStatus(theme, build);
3535

3636
return (

site/src/components/Dashboard/Navbar/NavbarView.tsx

+12-13
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
import Drawer from "@mui/material/Drawer";
22
import IconButton from "@mui/material/IconButton";
3-
import MenuIcon from "@mui/icons-material/Menu";
4-
import { CoderIcon } from "components/Icons/CoderIcon";
5-
import { type FC, type ReactNode, useRef, useState } from "react";
6-
import { NavLink, useLocation, useNavigate } from "react-router-dom";
7-
import { colors } from "theme/colors";
8-
import * as TypesGen from "api/typesGenerated";
9-
import { navHeight } from "theme/constants";
10-
import { UserDropdown } from "./UserDropdown/UserDropdown";
3+
import Divider from "@mui/material/Divider";
4+
import Skeleton from "@mui/material/Skeleton";
115
import Box from "@mui/material/Box";
126
import Menu from "@mui/material/Menu";
137
import Button from "@mui/material/Button";
148
import MenuItem from "@mui/material/MenuItem";
159
import KeyboardArrowDownOutlined from "@mui/icons-material/KeyboardArrowDownOutlined";
10+
import MenuIcon from "@mui/icons-material/Menu";
11+
import Typography from "@mui/material/Typography";
12+
import { css, type Interpolation, type Theme, useTheme } from "@emotion/react";
13+
import { type FC, type ReactNode, useRef, useState } from "react";
14+
import { NavLink, useLocation, useNavigate } from "react-router-dom";
15+
import { colors } from "theme/colors";
16+
import type * as TypesGen from "api/typesGenerated";
17+
import { BUTTON_SM_HEIGHT, navHeight } from "theme/constants";
1618
import { ProxyContextValue } from "contexts/ProxyContext";
1719
import { displayError } from "components/GlobalSnackbar/utils";
18-
import Divider from "@mui/material/Divider";
19-
import Skeleton from "@mui/material/Skeleton";
20-
import { BUTTON_SM_HEIGHT } from "theme/theme";
20+
import { CoderIcon } from "components/Icons/CoderIcon";
2121
import { ProxyStatusLatency } from "components/ProxyStatusLatency/ProxyStatusLatency";
2222
import { usePermissions } from "hooks/usePermissions";
23-
import Typography from "@mui/material/Typography";
24-
import { css, type Interpolation, type Theme, useTheme } from "@emotion/react";
23+
import { UserDropdown } from "./UserDropdown/UserDropdown";
2524

2625
export const USERS_LINK = `/users?filter=${encodeURIComponent(
2726
"status:active",

site/src/components/Dashboard/Navbar/UserDropdown/UserDropdown.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ import Badge from "@mui/material/Badge";
22
import { type FC, type PropsWithChildren } from "react";
33
import { colors } from "theme/colors";
44
import type * as TypesGen from "api/typesGenerated";
5-
import { navHeight } from "theme/constants";
5+
import { BUTTON_SM_HEIGHT, navHeight } from "theme/constants";
66
import { DropdownArrow } from "components/DropdownArrow/DropdownArrow";
77
import { UserAvatar } from "components/UserAvatar/UserAvatar";
88
import { UserDropdownContent } from "./UserDropdownContent";
9-
import { BUTTON_SM_HEIGHT } from "theme/theme";
109
import { css } from "@emotion/react";
1110
import {
1211
Popover,

site/src/components/DeploySettingsLayout/Option.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1+
import Box, { type BoxProps } from "@mui/material/Box";
2+
import CheckCircleOutlined from "@mui/icons-material/CheckCircleOutlined";
3+
import { css, useTheme } from "@emotion/react";
14
import type { PropsWithChildren, FC } from "react";
25
import { MONOSPACE_FONT_FAMILY } from "theme/constants";
3-
import Box, { BoxProps } from "@mui/material/Box";
4-
import { useTheme } from "@mui/system";
56
import { DisabledBadge, EnabledBadge } from "./Badges";
6-
import { css } from "@emotion/react";
7-
import CheckCircleOutlined from "@mui/icons-material/CheckCircleOutlined";
87

98
export const OptionName: FC<PropsWithChildren> = (props) => {
109
const { children } = props;

site/src/theme/constants.ts

+5
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,8 @@ export const containerWidth = 1380;
77
export const containerWidthMedium = 1080;
88
export const sidePadding = 24;
99
export const dashboardContentBottomPadding = 8 * 6;
10+
11+
// MUI does not have aligned heights for buttons and inputs so we have to "hack" it a little bit
12+
export const BUTTON_LG_HEIGHT = 40;
13+
export const BUTTON_MD_HEIGHT = 36;
14+
export const BUTTON_SM_HEIGHT = 32;

site/src/theme/experimental.ts

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import colors from "./tailwind";
2+
3+
export interface NewTheme {
4+
l1: Role; // page background, things which sit at the "root level"
5+
l2: InteractiveRole; // sidebars, table headers, navigation
6+
l3: InteractiveRole; // buttons, inputs
7+
modal: Role; // modals/popovers/dropdowns
8+
9+
roles: {
10+
danger: InteractiveRole; // delete, immutable parameters, stuff that sucks to fix
11+
error: Role; // something went wrong
12+
warning: Role; // something is amiss
13+
notice: Role; // like info, but actionable. "this is fine, but you may want to..."
14+
info: Role; // just sharing :)
15+
success: InteractiveRole; // yay!! it's working!!
16+
active: Role; // selected items, focused inputs, in progress
17+
};
18+
}
19+
20+
export interface Role {
21+
background: string;
22+
outline: string;
23+
fill: string;
24+
// contrastOutline?: string;
25+
text: string;
26+
}
27+
28+
export interface InteractiveRole extends Role {
29+
disabled: Role;
30+
hover: Role;
31+
}
32+
33+
export const dark: NewTheme = {
34+
l1: {
35+
background: colors.gray[950],
36+
outline: colors.gray[700],
37+
fill: "#f00",
38+
text: colors.white,
39+
},
40+
41+
l2: {
42+
background: colors.gray[900],
43+
outline: colors.gray[700],
44+
fill: "#f00",
45+
text: colors.white,
46+
disabled: {
47+
background: "#f00",
48+
outline: "#f00",
49+
fill: "#f00",
50+
text: colors.gray[200],
51+
},
52+
hover: {
53+
background: "#f00",
54+
outline: "#f00",
55+
fill: "#f00",
56+
text: colors.white,
57+
},
58+
},
59+
60+
l3: {
61+
background: colors.gray[800],
62+
outline: colors.gray[700],
63+
fill: "#f00",
64+
text: colors.white,
65+
disabled: {
66+
background: "#f00",
67+
outline: "#f00",
68+
fill: "#f00",
69+
text: colors.gray[200],
70+
},
71+
hover: {
72+
background: "#f00",
73+
outline: "#f00",
74+
fill: "#f00",
75+
text: colors.white,
76+
},
77+
},
78+
79+
modal: {
80+
background: "#f00",
81+
outline: "#f00",
82+
fill: "#f00",
83+
text: colors.white,
84+
},
85+
86+
roles: {
87+
danger: {
88+
background: colors.orange[950],
89+
outline: colors.orange[500],
90+
fill: colors.orange[600],
91+
text: colors.orange[50],
92+
disabled: {
93+
background: colors.orange[950],
94+
outline: colors.orange[600],
95+
fill: colors.orange[800],
96+
text: colors.orange[200],
97+
},
98+
hover: {
99+
background: colors.orange[900],
100+
outline: colors.orange[500],
101+
fill: colors.orange[500],
102+
text: colors.orange[50],
103+
},
104+
},
105+
error: {
106+
background: colors.red[950],
107+
outline: colors.red[500],
108+
fill: colors.red[600],
109+
text: colors.red[50],
110+
},
111+
warning: {
112+
background: colors.amber[950],
113+
outline: colors.amber[300],
114+
fill: "#f00",
115+
text: colors.amber[50],
116+
},
117+
notice: {
118+
background: colors.yellow[950],
119+
outline: colors.yellow[200],
120+
fill: "#f00",
121+
text: colors.yellow[50],
122+
},
123+
info: {
124+
background: colors.blue[950],
125+
outline: colors.blue[400],
126+
fill: "#f00",
127+
text: colors.blue[50],
128+
},
129+
success: {
130+
background: colors.green[950],
131+
outline: colors.green[500],
132+
fill: colors.green[600],
133+
text: colors.green[50],
134+
disabled: {
135+
background: colors.green[950],
136+
outline: colors.green[600],
137+
fill: colors.green[800],
138+
text: colors.green[200],
139+
},
140+
hover: {
141+
background: colors.green[900],
142+
outline: colors.green[500],
143+
fill: colors.green[500],
144+
text: colors.green[50],
145+
},
146+
},
147+
active: {
148+
background: colors.sky[950],
149+
outline: colors.sky[500],
150+
fill: "#f00",
151+
text: colors.sky[50],
152+
},
153+
},
154+
};

site/src/theme/index.ts

-1
This file was deleted.

site/src/theme/theme.ts renamed to site/src/theme/mui.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { colors, experimentalTheme } from "./colors";
22
import { createTheme, type ThemeOptions } from "@mui/material/styles";
3-
import { BODY_FONT_FAMILY, borderRadius } from "./constants";
4-
5-
// MUI does not have aligned heights for buttons and inputs so we have to "hack" it a little bit
6-
export const BUTTON_LG_HEIGHT = 40;
7-
export const BUTTON_MD_HEIGHT = 36;
8-
export const BUTTON_SM_HEIGHT = 32;
3+
import {
4+
BODY_FONT_FAMILY,
5+
borderRadius,
6+
BUTTON_LG_HEIGHT,
7+
BUTTON_MD_HEIGHT,
8+
BUTTON_SM_HEIGHT,
9+
} from "./constants";
910

1011
export type PaletteIndex =
1112
| "primary"

0 commit comments

Comments
 (0)