Skip to content

Commit

Permalink
Add dark mode theme to the UI (weaveworks#3677)
Browse files Browse the repository at this point in the history
* theme edits and styles-provider component

* add toggleDarkMode

* localStorage

* brackets on children prop and one color prop fix

* fix places where theme was inline or imported, use mode variable

* add mode to test-utils

* reverse some colors in dark mode, footer adjustments, nav icon button color inherit

* add initial switch plus greyToPrimary color

* defaultChecked for dark mode switch

* backgrounds, sign in, graph, nav text, switch icons, detail modal. Still a little polishing left to do

* new yaml colorization, sync dropdown, alerts in dark mode plus failed toastify, signin eye icon

* adds window mock to test-utils, plus various fixes to yaml header, filter dialog button, and detail modal background

* alert type error, update toastify for theme access

* get new app detail styling in dark mode, style switch for dark mode, overrides for disabled checkbox and input

* lint

* unify spelling of "gray" and remove all uses of backGray to try and streamline colors a bit

* add theme enum, option to override in yaml view

* useInDarkMode hook, add mode field to theme

* snaps

* chip group tests
  • Loading branch information
joshri authored May 15, 2023
1 parent 3c9e653 commit f69ed59
Show file tree
Hide file tree
Showing 48 changed files with 630 additions and 445 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"react-query": "^3.34.7",
"react-router-dom": "^5.2.0",
"react-syntax-highlighter": "^15.5.0",
"react-toastify": "^7.0.4",
"react-toastify": "^9.1.2",
"styled-components": "^5.3.0",
"yaml": "^2.2.2"
},
Expand Down
224 changes: 122 additions & 102 deletions ui/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import qs from "query-string";
import * as React from "react";
import { QueryClient, QueryClientProvider } from "react-query";
import {
BrowserRouter as Router,
Redirect,
Route,
BrowserRouter as Router,
Switch,
} from "react-router-dom";
import { ToastContainer } from "react-toastify";
Expand All @@ -17,9 +17,13 @@ import ImageAutomationRepoDetails from "./components/ImageAutomation/repositorie
import ImageAutomationUpdatesDetails from "./components/ImageAutomation/updates/ImageAutomationUpdatesDetails";
import Layout from "./components/Layout";
import PendoContainer from "./components/PendoContainer";
import AppContextProvider from "./contexts/AppContext";
import AppContextProvider, {
AppContext,
ThemeTypes,
} from "./contexts/AppContext";
import AuthContextProvider, { AuthCheck } from "./contexts/AuthContext";
import CoreClientContextProvider from "./contexts/CoreClientContext";
import { useInDarkMode } from "./hooks/theme";
import { Core } from "./lib/api/core/core.pb";
import Fonts from "./lib/fonts";
import theme, { GlobalStyle, muiTheme } from "./lib/theme";
Expand Down Expand Up @@ -50,110 +54,126 @@ function withSearchParams(Cmp) {
return <Cmp {...rest} {...params} />;
};
}
const App = () => (
<Layout>
<PendoContainer />
<ErrorBoundary>
<Switch>
<Route exact path={V2Routes.Automations} component={Automations} />
<Route
path={V2Routes.Kustomization}
component={withSearchParams(KustomizationPage)}
/>
<Route path={V2Routes.Sources} component={Sources} />
<Route
path={V2Routes.ImageAutomation}
component={ImageAutomationPage}
/>
<Route
path={V2Routes.ImageAutomationUpdatesDetails}
component={withSearchParams(ImageAutomationUpdatesDetails)}
/>
<Route
path={V2Routes.ImageAutomationRepositoryDetails}
component={withSearchParams(ImageAutomationRepoDetails)}
/>
<Route
path={V2Routes.ImagePolicyDetails}
component={withSearchParams(ImagePolicyDetails)}
/>
<Route path={V2Routes.FluxRuntime} component={FluxRuntime} />
<Route
path={V2Routes.GitRepo}
component={withSearchParams(GitRepositoryDetail)}
/>
<Route
path={V2Routes.HelmRepo}
component={withSearchParams(HelmRepositoryDetail)}
/>
<Route
path={V2Routes.Bucket}
component={withSearchParams(BucketDetail)}
/>
<Route
path={V2Routes.HelmRelease}
component={withSearchParams(HelmReleasePage)}
/>
<Route
path={V2Routes.HelmChart}
component={withSearchParams(HelmChartDetail)}
/>
<Route
path={V2Routes.OCIRepository}
component={withSearchParams(OCIRepositoryPage)}
/>
<Route
path={V2Routes.Notifications}
component={withSearchParams(Notifications)}
/>
<Route
path={V2Routes.Provider}
component={withSearchParams(ProviderPage)}
/>
<Route path={V2Routes.UserInfo} component={UserInfo} />

<Redirect exact from="/" to={V2Routes.Automations} />
const App = () => {
const dark = useInDarkMode();
return (
<Layout>
<PendoContainer />
<ErrorBoundary>
<Switch>
<Route exact path={V2Routes.Automations} component={Automations} />
<Route
path={V2Routes.Kustomization}
component={withSearchParams(KustomizationPage)}
/>
<Route path={V2Routes.Sources} component={Sources} />
<Route
path={V2Routes.ImageAutomation}
component={ImageAutomationPage}
/>
<Route
path={V2Routes.ImageAutomationUpdatesDetails}
component={withSearchParams(ImageAutomationUpdatesDetails)}
/>
<Route
path={V2Routes.ImageAutomationRepositoryDetails}
component={withSearchParams(ImageAutomationRepoDetails)}
/>
<Route
path={V2Routes.ImagePolicyDetails}
component={withSearchParams(ImagePolicyDetails)}
/>
<Route path={V2Routes.FluxRuntime} component={FluxRuntime} />
<Route
path={V2Routes.GitRepo}
component={withSearchParams(GitRepositoryDetail)}
/>
<Route
path={V2Routes.HelmRepo}
component={withSearchParams(HelmRepositoryDetail)}
/>
<Route
path={V2Routes.Bucket}
component={withSearchParams(BucketDetail)}
/>
<Route
path={V2Routes.HelmRelease}
component={withSearchParams(HelmReleasePage)}
/>
<Route
path={V2Routes.HelmChart}
component={withSearchParams(HelmChartDetail)}
/>
<Route
path={V2Routes.OCIRepository}
component={withSearchParams(OCIRepositoryPage)}
/>
<Route
path={V2Routes.Notifications}
component={withSearchParams(Notifications)}
/>
<Route
path={V2Routes.Provider}
component={withSearchParams(ProviderPage)}
/>
<Route path={V2Routes.UserInfo} component={UserInfo} />

<Redirect exact from="/" to={V2Routes.Automations} />

<Route exact path="*" component={Error} />
</Switch>
</ErrorBoundary>
<ToastContainer
position="top-center"
autoClose={5000}
newestOnTop={false}
/>
</Layout>
);
<Route exact path="*" component={Error} />
</Switch>
</ErrorBoundary>
<ToastContainer
position="top-center"
autoClose={5000}
newestOnTop={false}
theme={dark ? ThemeTypes.Dark : ThemeTypes.Light}
/>
</Layout>
);
};

const StylesProvider = ({ children }) => {
const { settings } = React.useContext(AppContext);
const mode = settings.theme;
const appliedTheme = theme(mode);
return (
<ThemeProvider theme={appliedTheme}>
<MuiThemeProvider theme={muiTheme(appliedTheme.colors, mode)}>
<Fonts />
<GlobalStyle />
{children}
</MuiThemeProvider>
</ThemeProvider>
);
};

export default function AppContainer() {
return (
<MuiThemeProvider theme={muiTheme}>
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={theme}>
<Fonts />
<GlobalStyle />
<Router>
<AppContextProvider renderFooter>
<AuthContextProvider>
<CoreClientContextProvider api={Core}>
<Switch>
{/* <Signin> does not use the base page <Layout> so pull it up here */}
<Route exact path="/sign_in">
<SignIn />
</Route>
<Route path="*">
{/* Check we've got a logged in user otherwise redirect back to signin */}
<AuthCheck>
<App />
</AuthCheck>
</Route>
</Switch>
</CoreClientContextProvider>
</AuthContextProvider>
</AppContextProvider>
</Router>
</ThemeProvider>
</QueryClientProvider>
</MuiThemeProvider>
<QueryClientProvider client={queryClient}>
<Router>
<AppContextProvider renderFooter>
<StylesProvider>
<AuthContextProvider>
<CoreClientContextProvider api={Core}>
<Switch>
{/* <Signin> does not use the base page <Layout> so pull it up here */}
<Route exact path="/sign_in">
<SignIn />
</Route>
<Route path="*">
{/* Check we've got a logged in user otherwise redirect back to signin */}
<AuthCheck>
<App />
</AuthCheck>
</Route>
</Switch>
</CoreClientContextProvider>
</AuthContextProvider>
</StylesProvider>
</AppContextProvider>
</Router>
</QueryClientProvider>
);
}
22 changes: 12 additions & 10 deletions ui/components/Alert.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import {
Alert as MaterialAlert,
// eslint-disable-next-line
AlertProps,
AlertTitle,
} from "@material-ui/lab";
import { AlertTitle, Alert as MaterialAlert } from "@material-ui/lab";
import * as React from "react";
import styled from "styled-components";
import Flex from "./Flex";
import Text from "./Text";

/** Alert Properties */
export interface Props {
/** string of one of the colors from our `MuiTheme` - also sets the corresponding material icon - see /ui/lib/theme.ts and https://mui.com/customization/theming/ */
severity?: AlertProps["severity"];
severity?: "error" | "info" | "success" | "warning";
/** Overrides `justify-content: flex-start` (left) to render the Alert in the center of it's 100% width `<Flex />` component */
center?: boolean;
/** text for Mui's `<AlertTitle />` component */
Expand All @@ -21,19 +17,25 @@ export interface Props {
/** CSS MUI Overrides or other styling */
className?: string;
}

/** Form Alert */
function UnstyledAlert({ center, title, message, severity, className }: Props) {
return (
<Flex wide start={!center} className={className}>
<MaterialAlert severity={severity}>
<AlertTitle>{title}</AlertTitle>
{message}
<Text color="black">{message}</Text>
</MaterialAlert>
</Flex>
);
}

const Alert = styled(UnstyledAlert)``;
const Alert = styled(UnstyledAlert)`
.MuiAlert-standardError {
background-color: ${(props) => props.theme.colors.alertLight};
}
.MuiAlertTitle-root {
color: ${(props) => props.theme.colors.black};
}
`;

export default Alert;
28 changes: 0 additions & 28 deletions ui/components/Animations/SignInBackground.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion ui/components/AutomationDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ function AutomationDetail({
<div className="grid grid-items">
{info.map(([k, v]) => {
return (
<Flex id={k} gap="8">
<Flex id={k} gap="8" key={k}>
<Text capitalize semiBold color="neutral30">
{k}:
</Text>
Expand Down
1 change: 0 additions & 1 deletion ui/components/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export const Breadcrumbs = () => {
const parentValue = getParentNavValue(currentPage) as V2Routes;
const label = getPageLabel(parentValue);
const parsed = qs.parse(search);

return (
<Flex align>
<Link
Expand Down
Loading

0 comments on commit f69ed59

Please sign in to comment.