({
header: {
- backgroundColor: '#fff',
- color: '#000',
+ backgroundColor: theme.palette.headerBackground,
padding: '0.5rem',
boxShadow: 'none',
position: 'relative',
@@ -80,7 +79,6 @@ export const useStyles = makeStyles()(theme => ({
textDecoration: 'none',
alignItems: 'center',
display: 'flex',
- color: '#000',
},
icon: {
color: theme.palette.grey[700],
diff --git a/frontend/src/component/menu/Header/Header.tsx b/frontend/src/component/menu/Header/Header.tsx
index dbe8726e91..c12341e408 100644
--- a/frontend/src/component/menu/Header/Header.tsx
+++ b/frontend/src/component/menu/Header/Header.tsx
@@ -2,13 +2,21 @@ import { useEffect, useState, VFC } from 'react';
import useMediaQuery from '@mui/material/useMediaQuery';
import { useTheme } from '@mui/material/styles';
import { Link } from 'react-router-dom';
-import { AppBar, Container, IconButton, Tooltip } from '@mui/material';
+import {
+ AppBar,
+ Container,
+ FormControlLabel,
+ IconButton,
+ Tooltip,
+ Switch,
+} from '@mui/material';
import MenuIcon from '@mui/icons-material/Menu';
import SettingsIcon from '@mui/icons-material/Settings';
import UserProfile from 'component/user/UserProfile';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import MenuBookIcon from '@mui/icons-material/MenuBook';
import { ReactComponent as UnleashLogo } from 'assets/img/logoDarkWithText.svg';
+import { ReactComponent as UnleashLogoWhite } from 'assets/img/logoWithWhiteText.svg';
import { DrawerMenu } from './DrawerMenu/DrawerMenu';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
@@ -24,8 +32,11 @@ import { useStyles } from './Header.styles';
import classNames from 'classnames';
import { useId } from 'hooks/useId';
import { IRoute } from 'interfaces/route';
+import { ThemeMode } from 'component/common/ThemeMode/ThemeMode';
+import { useThemeMode } from 'hooks/useThemeMode';
const Header: VFC = () => {
+ const { onSetThemeMode, themeMode } = useThemeMode();
const theme = useTheme();
const adminId = useId();
const configId = useId();
@@ -111,9 +122,19 @@ const Header: VFC = () => {
)}
aria-label="Home"
>
-
+ }
+ lightmode={
+
+ }
/>
+
+ }
+ label="darkmode"
+ />
+ }
+ />
({
textDecoration: 'none',
alignItems: 'center',
display: 'flex',
- color: '#000',
+ color: 'inherit',
height: '100%',
width: '100%',
'&&': {
diff --git a/frontend/src/component/playground/Playground/Playground.tsx b/frontend/src/component/playground/Playground/Playground.tsx
index 53e1b7e185..9277298596 100644
--- a/frontend/src/component/playground/Playground/Playground.tsx
+++ b/frontend/src/component/playground/Playground/Playground.tsx
@@ -159,7 +159,7 @@ export const Playground: VFC<{}> = () => {
>
@@ -170,7 +170,7 @@ export const Playground: VFC<{}> = () => {
py: 3,
mb: 4,
mt: 2,
- background: theme.palette.grey[200],
+ background: theme.palette.playgroundBackground,
transition: 'width 0.4s ease',
minWidth: matches ? 'auto' : '500px',
width: formWidth,
diff --git a/frontend/src/component/playground/Playground/PlaygroundForm/PlaygroundCodeFieldset/PlaygroundEditor/PlaygroundEditor.tsx b/frontend/src/component/playground/Playground/PlaygroundForm/PlaygroundCodeFieldset/PlaygroundEditor/PlaygroundEditor.tsx
index d57b527dd1..61db181346 100644
--- a/frontend/src/component/playground/Playground/PlaygroundForm/PlaygroundCodeFieldset/PlaygroundEditor/PlaygroundEditor.tsx
+++ b/frontend/src/component/playground/Playground/PlaygroundForm/PlaygroundCodeFieldset/PlaygroundEditor/PlaygroundEditor.tsx
@@ -1,10 +1,13 @@
import CodeMirror from '@uiw/react-codemirror';
+import { useContext } from 'react';
import { json } from '@codemirror/lang-json';
import { Dispatch, SetStateAction, VFC, useCallback } from 'react';
import { styled, useTheme, Box } from '@mui/material';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
+import { duotoneDark, duotoneLight } from '@uiw/codemirror-theme-duotone';
import Check from '@mui/icons-material/Check';
import { Error } from '@mui/icons-material';
+import UIContext from 'contexts/UIContext';
interface IPlaygroundEditorProps {
context: string | undefined;
@@ -78,6 +81,7 @@ export const PlaygroundEditor: VFC = ({
setContext,
error,
}) => {
+ const { themeMode } = useContext(UIContext);
const theme = useTheme();
const onCodeFieldChange = useCallback(
context => {
@@ -109,6 +113,7 @@ export const PlaygroundEditor: VFC = ({
({
minWidth: 0,
},
header: {
- backgroundColor: '#fff',
+ backgroundColor: theme.palette.background.paper,
borderRadius: theme.shape.borderRadiusLarge,
marginBottom: '1rem',
},
diff --git a/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.styles.ts b/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.styles.ts
index d51d8e9a8e..ec3a9b5626 100644
--- a/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.styles.ts
+++ b/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.styles.ts
@@ -55,7 +55,7 @@ export const useStyles = makeStyles()(theme => ({
margin: '0',
textAlign: 'center',
marginBottom: '1rem',
- backgroundColor: '#fff',
+ backgroundColor: theme.palette.background.paper,
borderRadius: theme.shape.borderRadiusLarge,
width: '100%',
padding: '1.5rem 1rem 1.5rem 1rem',
diff --git a/frontend/src/component/project/ProjectCard/ProjectCard.styles.ts b/frontend/src/component/project/ProjectCard/ProjectCard.styles.ts
index 849697ecbe..a4a3f3fafb 100644
--- a/frontend/src/component/project/ProjectCard/ProjectCard.styles.ts
+++ b/frontend/src/component/project/ProjectCard/ProjectCard.styles.ts
@@ -16,7 +16,7 @@ export const useStyles = makeStyles()(theme => ({
},
'&:hover': {
transition: 'background-color 0.2s ease-in-out',
- backgroundColor: theme.palette.neutral.light,
+ backgroundColor: theme.palette.projectCard.hover,
},
},
header: {
@@ -49,7 +49,7 @@ export const useStyles = makeStyles()(theme => ({
textAlign: 'center',
},
infoStats: {
- color: '#4A4599',
+ color: theme.palette.projectCard.textColor,
fontWeight: 'bold',
},
actionsBtn: {
diff --git a/frontend/src/component/providers/UIProvider/UIProvider.tsx b/frontend/src/component/providers/UIProvider/UIProvider.tsx
index 75e53a255a..c13853f878 100644
--- a/frontend/src/component/providers/UIProvider/UIProvider.tsx
+++ b/frontend/src/component/providers/UIProvider/UIProvider.tsx
@@ -1,10 +1,36 @@
import React, { useState } from 'react';
-import UIContext, { createEmptyToast } from 'contexts/UIContext';
+import UIContext, { createEmptyToast, themeMode } from 'contexts/UIContext';
import { IToast } from 'interfaces/toast';
+import { getLocalStorageItem } from 'utils/storage';
-const UIProvider: React.FC = ({ children }) => {
+const resolveMode = (darkmode: boolean): themeMode => {
+ const value = getLocalStorageItem('unleash-theme');
+ if (value) {
+ return value as themeMode;
+ }
+
+ let osDark;
+ if (darkmode) {
+ osDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
+ }
+
+ if (osDark) {
+ return 'dark';
+ }
+ return 'light';
+};
+
+interface IUiProviderProps {
+ darkmode: boolean;
+}
+
+const UIProvider: React.FC = ({
+ children,
+ darkmode = false,
+}) => {
const [toastData, setToast] = useState(createEmptyToast());
const [showFeedback, setShowFeedback] = useState(false);
+ const [themeMode, setThemeMode] = useState(resolveMode(darkmode));
const context = React.useMemo(
() => ({
@@ -12,8 +38,10 @@ const UIProvider: React.FC = ({ children }) => {
toastData,
showFeedback,
setShowFeedback,
+ themeMode,
+ setThemeMode,
}),
- [toastData, showFeedback]
+ [toastData, showFeedback, themeMode]
);
return {children};
diff --git a/frontend/src/component/providers/UIProvider/UIProviderContainer.tsx b/frontend/src/component/providers/UIProvider/UIProviderContainer.tsx
new file mode 100644
index 0000000000..199d9b94fe
--- /dev/null
+++ b/frontend/src/component/providers/UIProvider/UIProviderContainer.tsx
@@ -0,0 +1,16 @@
+import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
+import UIProvider from './UIProvider';
+
+export const UIProviderContainer: React.FC = ({ children }) => {
+ const { uiConfig } = useUiConfig();
+
+ if (!uiConfig.flags) {
+ return null;
+ }
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/frontend/src/component/segments/SegmentFormStepList/SegmentFormStepList.styles.ts b/frontend/src/component/segments/SegmentFormStepList/SegmentFormStepList.styles.ts
index aec450382d..c296846693 100644
--- a/frontend/src/component/segments/SegmentFormStepList/SegmentFormStepList.styles.ts
+++ b/frontend/src/component/segments/SegmentFormStepList/SegmentFormStepList.styles.ts
@@ -17,7 +17,7 @@ export const useStyles = makeStyles()(theme => ({
steps: {
position: 'relative',
borderRadius: 10,
- background: '#fff',
+ background: theme.palette.background.paper,
padding: '0.6rem 1.5rem',
margin: 'auto',
display: 'flex',
diff --git a/frontend/src/component/tags/TagTypeList/__tests__/TagTypeList.test.tsx b/frontend/src/component/tags/TagTypeList/__tests__/TagTypeList.test.tsx
index 77d3329739..04d088a221 100644
--- a/frontend/src/component/tags/TagTypeList/__tests__/TagTypeList.test.tsx
+++ b/frontend/src/component/tags/TagTypeList/__tests__/TagTypeList.test.tsx
@@ -13,7 +13,7 @@ test('renders an empty list correctly', () => {
-
+
diff --git a/frontend/src/component/tags/TagTypeList/__tests__/__snapshots__/TagTypeList.test.tsx.snap b/frontend/src/component/tags/TagTypeList/__tests__/__snapshots__/TagTypeList.test.tsx.snap
index 683d8ef5b2..05551828e1 100644
--- a/frontend/src/component/tags/TagTypeList/__tests__/__snapshots__/TagTypeList.test.tsx.snap
+++ b/frontend/src/component/tags/TagTypeList/__tests__/__snapshots__/TagTypeList.test.tsx.snap
@@ -7,7 +7,7 @@ exports[`renders an empty list correctly 1`] = `
aria-live="polite"
>
= ({ title, children }) => {
return (
diff --git a/frontend/src/component/user/UserProfile/UserProfile.tsx b/frontend/src/component/user/UserProfile/UserProfile.tsx
index 0d2aa0b0ac..be50c9fe05 100644
--- a/frontend/src/component/user/UserProfile/UserProfile.tsx
+++ b/frontend/src/component/user/UserProfile/UserProfile.tsx
@@ -75,6 +75,7 @@ const UserProfile = ({
disableRipple
>
{
const { classes: themeStyles } = useThemeStyles();
+ const theme = useTheme();
+
const { uiConfig } = useUiConfig();
const [updatedPassword, setUpdatedPassword] = useState(false);
const [editingProfile, setEditingProfile] = useState(false);
@@ -121,7 +124,11 @@ const UserProfileContent = ({
>
Date/Time formatting
diff --git a/frontend/src/component/user/common/StandaloneLayout/StandaloneLayout.styles.ts b/frontend/src/component/user/common/StandaloneLayout/StandaloneLayout.styles.ts
index 2e10dbde9c..c535ddf662 100644
--- a/frontend/src/component/user/common/StandaloneLayout/StandaloneLayout.styles.ts
+++ b/frontend/src/component/user/common/StandaloneLayout/StandaloneLayout.styles.ts
@@ -3,7 +3,7 @@ import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
container: {
padding: '5.5rem',
- background: '#EFF2F2',
+ background: theme.palette.standaloneBackground,
display: 'flex',
[theme.breakpoints.down('md')]: {
flexDirection: 'column',
@@ -27,7 +27,7 @@ export const useStyles = makeStyles()(theme => ({
flex: '1',
borderTopRightRadius: '3px',
borderBottomRightRadius: '3px',
- backgroundColor: '#fff',
+ backgroundColor: theme.palette.background.paper,
position: 'relative',
[theme.breakpoints.down('md')]: {
borderRadius: '0',
diff --git a/frontend/src/contexts/UIContext.ts b/frontend/src/contexts/UIContext.ts
index 7102fb8643..0237330d67 100644
--- a/frontend/src/contexts/UIContext.ts
+++ b/frontend/src/contexts/UIContext.ts
@@ -6,8 +6,12 @@ interface IUIContext {
setToast: React.Dispatch>;
showFeedback: boolean;
setShowFeedback: React.Dispatch>;
+ setThemeMode: React.Dispatch>;
+ themeMode: themeMode;
}
+export type themeMode = 'light' | 'dark';
+
export const createEmptyToast = (): IToast => {
return {
type: 'success',
@@ -27,11 +31,17 @@ const setShowFeedbackPlaceholder = () => {
throw new Error('setShowFeedback called outside UIContext');
};
+const setThemeModePlaceholder = () => {
+ throw new Error('setMode called outside UIContext');
+};
+
const UIContext = React.createContext({
toastData: createEmptyToast(),
setToast: setToastPlaceholder,
showFeedback: false,
setShowFeedback: setShowFeedbackPlaceholder,
+ themeMode: 'light',
+ setThemeMode: setThemeModePlaceholder,
});
export default UIContext;
diff --git a/frontend/src/hooks/useThemeMode.ts b/frontend/src/hooks/useThemeMode.ts
new file mode 100644
index 0000000000..750a0daa33
--- /dev/null
+++ b/frontend/src/hooks/useThemeMode.ts
@@ -0,0 +1,37 @@
+import UIContext, { themeMode } from 'contexts/UIContext';
+import { useContext } from 'react';
+import { setLocalStorageItem } from 'utils/storage';
+import mainTheme from 'themes/theme';
+import darkTheme from 'themes/dark-theme';
+import { Theme } from '@emotion/react';
+
+interface IUseThemeModeOutput {
+ resolveTheme: () => Theme;
+ onSetThemeMode: () => void;
+ themeMode: themeMode;
+}
+
+export const useThemeMode = (): IUseThemeModeOutput => {
+ const { themeMode, setThemeMode } = useContext(UIContext);
+
+ const resolveTheme = () => {
+ if (themeMode === 'light') {
+ return mainTheme;
+ }
+
+ return darkTheme;
+ };
+
+ const onSetThemeMode = () => {
+ setThemeMode((prev: themeMode) => {
+ if (prev === 'light') {
+ setLocalStorageItem('unleash-theme', 'dark');
+ return 'dark';
+ }
+ setLocalStorageItem('unleash-theme', 'light');
+ return 'light';
+ });
+ };
+
+ return { resolveTheme, onSetThemeMode, themeMode };
+};
diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx
index 8340227e40..5e28bea193 100644
--- a/frontend/src/index.tsx
+++ b/frontend/src/index.tsx
@@ -10,12 +10,12 @@ import { ScrollTop } from 'component/common/ScrollTop/ScrollTop';
import { AccessProvider } from 'component/providers/AccessProvider/AccessProvider';
import { basePath } from 'utils/formatPath';
import { FeedbackCESProvider } from 'component/feedback/FeedbackCESContext/FeedbackCESProvider';
-import UIProvider from 'component/providers/UIProvider/UIProvider';
import { AnnouncerProvider } from 'component/common/Announcer/AnnouncerProvider/AnnouncerProvider';
import { InstanceStatus } from 'component/common/InstanceStatus/InstanceStatus';
+import { UIProviderContainer } from 'component/providers/UIProvider/UIProviderContainer';
ReactDOM.render(
-
+
@@ -30,6 +30,6 @@ ReactDOM.render(
- ,
+ ,
document.getElementById('app')
);
diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts
index 0383ac9674..cc70e5f795 100644
--- a/frontend/src/interfaces/uiConfig.ts
+++ b/frontend/src/interfaces/uiConfig.ts
@@ -39,6 +39,7 @@ export interface IFlags {
T?: boolean;
UNLEASH_CLOUD?: boolean;
UG?: boolean;
+ ENABLE_DARK_MODE_SUPPORT?: boolean;
}
export interface IVersionInfo {
diff --git a/frontend/src/themes/ThemeProvider.tsx b/frontend/src/themes/ThemeProvider.tsx
index 3a44706ba3..ed50d60300 100644
--- a/frontend/src/themes/ThemeProvider.tsx
+++ b/frontend/src/themes/ThemeProvider.tsx
@@ -1,19 +1,24 @@
import React, { FC } from 'react';
import { CssBaseline, ThemeProvider as MuiThemeProvider } from '@mui/material';
-import mainTheme from 'themes/theme';
+
import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
+import { useThemeMode } from 'hooks/useThemeMode';
export const muiCache = createCache({
key: 'mui',
prepend: true,
});
-export const ThemeProvider: FC = ({ children }) => (
-
-
-
- {children}
-
-
-);
+export const ThemeProvider: FC = ({ children }) => {
+ const { resolveTheme } = useThemeMode();
+
+ return (
+
+
+
+ {children}
+
+
+ );
+};
diff --git a/frontend/src/themes/app.css b/frontend/src/themes/app.css
index 9867297ea3..d5d420d53a 100644
--- a/frontend/src/themes/app.css
+++ b/frontend/src/themes/app.css
@@ -17,10 +17,6 @@ button {
font-family: 'Sen', sans-serif;
}
-.MuiInputBase-root {
- background-color: #fff;
-}
-
.MuiAccordion-root.Mui-expanded {
margin: 0;
}
diff --git a/frontend/src/themes/colors.ts b/frontend/src/themes/colors.ts
index 4a3c143706..3c115fd241 100644
--- a/frontend/src/themes/colors.ts
+++ b/frontend/src/themes/colors.ts
@@ -78,4 +78,12 @@ export const colors = {
100: '#DCEEFA',
50: '#EBF7FF',
},
+ darkblue: {
+ 1000: '#091826',
+ 900: '#041c32',
+ 800: '#1d3247',
+ 700: '#28415c',
+ 600: '#1f3751',
+ 500: '#0e2840',
+ },
} as const;
diff --git a/frontend/src/themes/dark-theme.ts b/frontend/src/themes/dark-theme.ts
new file mode 100644
index 0000000000..035dd2651d
--- /dev/null
+++ b/frontend/src/themes/dark-theme.ts
@@ -0,0 +1,418 @@
+import { createTheme } from '@mui/material/styles';
+import { colors } from './colors';
+
+const themeColors = {
+ main: colors.darkblue[900],
+ secondary: colors.darkblue[800],
+ textColor: '#ffffffe6',
+ hover: 'rgb(255, 255, 255, 0.7)',
+};
+
+export default createTheme({
+ breakpoints: {
+ values: {
+ xs: 0,
+ sm: 600,
+ md: 960,
+ lg: 1260,
+ xl: 1536,
+ },
+ },
+ boxShadows: {
+ main: '0px 2px 4px rgba(129, 122, 254, 0.2)',
+ card: '0px 2px 10px rgba(28, 25, 78, 0.12)',
+ elevated: '0px 1px 20px rgba(45, 42, 89, 0.1)',
+ },
+ typography: {
+ fontFamily: 'Sen, Roboto, sans-serif',
+ fontWeightBold: '700',
+ fontWeightMedium: '700',
+ allVariants: { lineHeight: 1.4 },
+ button: { lineHeight: 1.75 },
+ h1: {
+ fontSize: '1.5rem',
+ lineHeight: 1.875,
+ },
+ h3: {
+ fontSize: '1rem',
+ fontWeight: '700',
+ },
+ caption: {
+ fontSize: `${12 / 16}rem`,
+ },
+ },
+ fontSizes: {
+ mainHeader: '1.25rem',
+ bodySize: '1rem',
+ smallBody: `${14 / 16}rem`,
+ smallerBody: `${12 / 16}rem`,
+ },
+ fontWeight: {
+ thin: 300,
+ medium: 400,
+ semi: 700,
+ bold: 700,
+ },
+ shape: {
+ borderRadius: 4,
+ borderRadiusMedium: 8,
+ borderRadiusLarge: 12,
+ borderRadiusExtraLarge: 20,
+ tableRowHeight: 64,
+ tableRowHeightCompact: 56,
+ tableRowHeightDense: 48,
+ },
+ palette: {
+ primary: {
+ main: themeColors.textColor,
+ light: colors.purple[700],
+ dark: colors.purple[900],
+ },
+ secondary: {
+ main: colors.purple[800],
+ light: colors.purple[700],
+ dark: colors.purple[900],
+ },
+ info: {
+ light: colors.blue[50],
+ main: colors.blue[500],
+ dark: colors.blue[700],
+ border: colors.blue[200],
+ },
+ success: {
+ light: colors.green[50],
+ main: colors.green[600],
+ dark: themeColors.main,
+ border: colors.green[300],
+ },
+ warning: {
+ light: colors.orange[100],
+ main: colors.orange[800],
+ dark: colors.orange[900],
+ border: colors.orange[500],
+ },
+ error: {
+ light: colors.red[50],
+ main: colors.red[700],
+ dark: colors.red[800],
+ border: colors.red[300],
+ },
+ background: {
+ paper: themeColors.main,
+ },
+ divider: themeColors.secondary,
+ dividerAlternative: colors.grey[400],
+ tableHeaderHover: colors.darkblue[700],
+ tableHeaderBackground: themeColors.secondary,
+ tableHeaderColor: themeColors.textColor,
+ highlight: '#FFEACC',
+ secondaryContainer: themeColors.secondary,
+ contentWrapper: colors.darkblue[800],
+ formBackground: themeColors.main,
+ formSidebar: colors.darkblue[1000],
+ headerBackground: themeColors.main,
+ footerBackground: themeColors.main,
+ sidebarContainer: 'rgba(32,32,33, 0.2)',
+ codebox: colors.darkblue[600],
+ featureMetaData: colors.darkblue[1000],
+ playgroundBackground: colors.darkblue[600],
+ playgroundFormBackground: themeColors.secondary,
+ standaloneBackground: colors.black,
+ featureStrategySegmentChipBackground: themeColors.secondary,
+ featureSegmentSearchBackground: themeColors.secondary,
+ dialogHeaderBackground: themeColors.secondary,
+ dialogHeaderText: themeColors.textColor,
+ lightBorder: colors.darkblue[500],
+ constraintAccordion: {
+ editBackground: colors.darkblue[600],
+ background: themeColors.secondary,
+ operatorBackground: themeColors.main,
+ },
+ standaloneBannerGradient: {
+ from: colors.darkblue[1000],
+ to: colors.black,
+ },
+ projectCard: {
+ hover: themeColors.secondary,
+ textColor: themeColors.textColor,
+ },
+ formSidebarTextColor: themeColors.textColor,
+ checkmarkBadge: themeColors.secondary,
+ inputLabelBackground: 'transparent',
+ featureMetricsBackground: themeColors.secondary,
+ grey: colors.grey,
+ text: {
+ primary: themeColors.textColor,
+ secondary: colors.grey[800],
+ disabled: colors.grey[600],
+ },
+ code: {
+ main: '#0b8c8f',
+ diffAdd: 'green',
+ diffSub: 'red',
+ diffNeutral: 'black',
+ edited: 'blue',
+ },
+ neutral: {
+ light: colors.darkblue[500],
+ main: colors.grey[700],
+ dark: colors.grey[800],
+ border: colors.grey[500],
+ },
+ activityIndicators: {
+ primary: themeColors.secondary,
+ unknown: themeColors.secondary,
+ recent: themeColors.secondary,
+ inactive: themeColors.secondary,
+ abandoned: themeColors.secondary,
+ },
+ tertiary: {
+ light: themeColors.secondary,
+ main: colors.grey[400],
+ dark: colors.grey[600],
+ background: 'white',
+ contrast: colors.grey[300],
+ },
+ inactiveIcon: colors.grey[600],
+ },
+ components: {
+ MuiAppBar: {
+ styleOverrides: {
+ root: {
+ color: themeColors.textColor,
+ },
+ },
+ },
+ MuiInputLabel: {
+ styleOverrides: {
+ root: {
+ color: themeColors.textColor,
+ },
+ },
+ },
+ MuiIconButton: {
+ styleOverrides: {
+ root: {
+ color: colors.white,
+ '&:hover': {
+ backgroundColor: themeColors.hover,
+ },
+ '&.Mui-disabled': {
+ '& .MuiSvgIcon-root': {
+ color: colors.grey[700],
+ },
+ },
+ },
+ },
+ },
+ MuiLink: {
+ styleOverrides: {
+ root: {
+ color: colors.white,
+ '&:hover': {
+ textDecoration: 'none',
+ },
+ },
+ },
+ },
+ MuiBreadcrumbs: {
+ styleOverrides: {
+ root: {
+ color: themeColors.textColor,
+ fontSize: '0.875rem',
+ '& a': {
+ color: themeColors.textColor,
+ textDecoration: 'underline',
+ '&:hover': {
+ textDecoration: 'none',
+ },
+ },
+ },
+ },
+ },
+ MuiTableHead: {
+ styleOverrides: {
+ root: {
+ background: 'transparent',
+ '& th': {
+ background: colors.grey[200],
+ },
+ },
+ },
+ },
+ MuiTableRow: {
+ styleOverrides: {
+ root: {
+ '&.MuiTableRow-hover:hover': {
+ background: themeColors.secondary,
+ },
+ },
+ },
+ },
+ MuiTableCell: {
+ styleOverrides: {
+ root: {
+ borderBottomColor: themeColors.main,
+ },
+ },
+ },
+ MuiAlert: {
+ styleOverrides: {
+ root: {
+ borderRadius: '8px',
+ a: {
+ color: 'inherit',
+ },
+ '&.MuiAlert-standardInfo': {
+ backgroundColor: colors.blue[50],
+ color: colors.blue[700],
+ border: `1px solid ${colors.blue[200]}`,
+ '& .MuiAlert-icon .MuiSvgIcon-root': {
+ color: colors.blue[500],
+ },
+ },
+ '&.MuiAlert-standardSuccess': {
+ backgroundColor: colors.green[50],
+ color: colors.green[800],
+ border: `1px solid ${colors.green[300]}`,
+ '& .MuiAlert-icon .MuiSvgIcon-root': {
+ color: colors.green[500],
+ },
+ },
+ '&.MuiAlert-standardWarning': {
+ backgroundColor: colors.orange[100],
+ color: colors.orange[900],
+ border: `1px solid ${colors.orange[500]}`,
+ '& .MuiAlert-icon .MuiSvgIcon-root': {
+ color: colors.orange[800],
+ },
+ },
+ '&.MuiAlert-standardError': {
+ backgroundColor: colors.red[50],
+ color: colors.red[800],
+ border: `1px solid ${colors.red[300]}`,
+ '& .MuiAlert-icon .MuiSvgIcon-root': {
+ color: colors.red[700],
+ },
+ },
+ },
+ },
+ },
+ MuiButton: {
+ styleOverrides: {
+ root: {
+ '&.Mui-disabled': {
+ backgroundColor: colors.grey[400],
+ },
+ },
+ },
+ },
+ MuiSvgIcon: {
+ styleOverrides: {
+ root: {
+ color: themeColors.textColor,
+ },
+ },
+ },
+ MuiTabs: {
+ styleOverrides: {
+ root: {
+ backgroundColor: themeColors.main,
+ color: themeColors.textColor,
+ '& .MuiTabs-indicator': {
+ height: '4px',
+ },
+ },
+ },
+ },
+ MuiTab: {
+ styleOverrides: {
+ root: {
+ color: themeColors.textColor,
+ fontSize: '1rem',
+ textTransform: 'none',
+ fontWeight: 400,
+ minHeight: '62px',
+ '&:hover': {
+ backgroundColor: themeColors.secondary,
+ },
+ '&.Mui-selected': {
+ color: themeColors.textColor,
+ fontWeight: 700,
+ },
+ '& > span': {
+ color: colors.purple[900],
+ },
+ },
+ },
+ },
+ MuiAccordionSummary: {
+ styleOverrides: {
+ root: {
+ '& > .MuiAccordionSummary-content.Mui-expanded': {
+ margin: '12px 0',
+ },
+ },
+ },
+ },
+ MuiSwitch: {
+ styleOverrides: {
+ switchBase: {
+ zIndex: 1,
+ '&:not(.Mui-checked) .MuiTouchRipple-child': {
+ color: colors.grey['500'],
+ },
+ },
+ },
+ },
+ MuiIcon: {
+ styleOverrides: {
+ root: {
+ color: colors.white,
+ },
+ colorDisabled: {
+ color: colors.white[600],
+ },
+ },
+ },
+ MuiMenu: {
+ styleOverrides: {
+ root: {
+ '.MuiMenu-list': {
+ backgroundColor: colors.darkblue[600],
+ },
+ },
+ },
+ },
+ MuiMenuItem: {
+ styleOverrides: {
+ root: {
+ '&.Mui-disabled': {
+ opacity: 0.66,
+ },
+ '&:hover': {
+ backgroundColor: themeColors.secondary,
+ },
+ },
+ },
+ },
+ MuiInputBase: {
+ styleOverrides: {
+ root: {
+ backgroundColor: colors.darkblue[1000],
+ '.MuiSvgIcon-root': {
+ color: '#fff',
+ },
+ },
+ },
+ },
+ MuiPaper: {
+ styleOverrides: {
+ root: {
+ backgroundColor: themeColors.main,
+ color: themeColors.textColor,
+ },
+ },
+ },
+ },
+});
diff --git a/frontend/src/themes/theme.ts b/frontend/src/themes/theme.ts
index 7acd21d876..bfbd7804c9 100644
--- a/frontend/src/themes/theme.ts
+++ b/frontend/src/themes/theme.ts
@@ -107,9 +107,42 @@ export default createTheme({
divider: colors.grey[300],
dividerAlternative: colors.grey[400],
tableHeaderHover: colors.grey[400],
+ tableHeaderBackground: colors.grey[200],
+ tableHeaderColor: colors.grey[900],
+ formSidebarTextColor: colors.white,
highlight: '#FFEACC',
secondaryContainer: colors.grey[200],
+ contentWrapper: colors.grey[300],
+ headerBackground: colors.white,
+ footerBackground: colors.white,
+ formBackground: colors.white,
+ formSidebar: colors.purple[800],
+ featureMetaData: colors.purple[800],
+ codebox: 'rgba(32,32,33, 0.2)',
sidebarContainer: 'rgba(32,32,33, 0.2)',
+ playgroundBackground: colors.grey[200],
+ playgroundFormBackground: colors.grey[200],
+ standaloneBackground: colors.grey[300],
+ constraintAccordion: {
+ editBackground: '#F6F6FA',
+ background: colors.white,
+ operatorBackground: colors.grey[200],
+ },
+ projectCard: {
+ hover: colors.grey[100],
+ textColor: '#4A4599',
+ },
+ standaloneBannerGradient: {
+ from: colors.purple[900],
+ to: '#173341',
+ },
+ checkmarkBadge: colors.purple[800],
+ inputLabelBackground: colors.white,
+ featureMetricsBackground: colors.grey[100],
+ featureStrategySegmentChipBackground: colors.purple[800],
+ featureSegmentSearchBackground: colors.purple[800],
+ dialogHeaderBackground: colors.purple[800],
+ dialogHeaderText: '#ffffffe6',
grey: colors.grey,
lightBorder: colors.grey[400],
text: {
@@ -333,5 +366,26 @@ export default createTheme({
}),
},
},
+ MuiInputBase: {
+ styleOverrides: {
+ root: {
+ backgroundColor: '#fff',
+ },
+ },
+ },
+ MuiPaper: {
+ styleOverrides: {
+ root: {
+ backgroundColor: '#fff',
+ },
+ },
+ },
+ MuiAppBar: {
+ styleOverrides: {
+ root: {
+ color: colors.black,
+ },
+ },
+ },
},
});
diff --git a/frontend/src/themes/themeTypes.ts b/frontend/src/themes/themeTypes.ts
index c90527cf54..87c29ac3a7 100644
--- a/frontend/src/themes/themeTypes.ts
+++ b/frontend/src/themes/themeTypes.ts
@@ -54,10 +54,44 @@ declare module '@mui/material/styles' {
primary: string;
};
dividerAlternative: string;
+ contentWrapper: string;
+ headerBackground: string;
+ footerBackground: string;
+ codebox: string;
+ featureMetaData: string;
+ playgroundBackground: string;
+ playgroundFormBackground: string;
+ standaloneBackground: string;
+ standaloneBannerGradient: {
+ from: string;
+ to: string;
+ };
+ featureMetricsBackground: string;
+ constraintAccordion: {
+ editBackground: string;
+ background: string;
+ operatorBackground: string;
+ };
+ projectCard: {
+ hover: string;
+ textColor: string;
+ };
+ checkmarkBadge: string;
+ inputLabelBackground: string;
+ featureStrategySegmentChipBackground: string;
+ featureSegmentSearchBackground: string;
+ dialogHeaderBackground: string;
+ dialogHeaderText: string;
+ formSidebarTextColor: string;
/**
* For table header hover effect.
*/
+ tableHeaderBackground: string;
tableHeaderHover: string;
+ tableHeaderColor: string;
+
+ formBackground: string;
+ formSidebar: string;
/**
* Text highlight effect color. Used when filtering/searching over content.
*/
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 98d0507568..fd756e1d7c 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -2447,6 +2447,22 @@
"@codemirror/state" "^6.0.0"
"@codemirror/view" "^6.0.0"
+"@uiw/codemirror-theme-duotone@^4.11.5":
+ version "4.11.5"
+ resolved "https://registry.yarnpkg.com/@uiw/codemirror-theme-duotone/-/codemirror-theme-duotone-4.11.5.tgz#12df3666337f757253f810fc4e61c8bc887e40c6"
+ integrity sha512-5Ea9naIp/KM6jZjog7tChdOjEPQgeKwSDuCh+TY1lQyt5YJS5P3eZSZq68KNZlwuBHj2c53h069brMnhguTFag==
+ dependencies:
+ "@uiw/codemirror-themes" "4.11.5"
+
+"@uiw/codemirror-themes@4.11.5":
+ version "4.11.5"
+ resolved "https://registry.yarnpkg.com/@uiw/codemirror-themes/-/codemirror-themes-4.11.5.tgz#15926e65129b41c9ec607065416fc829970e122a"
+ integrity sha512-f2i3yGPzxmCsvx4t6HHykcEhAxbI4GDAMzdFtQfFYMuu1F5sQP43JQvBC8ESflYk05QmE9rCWWZZpvOathLzVw==
+ dependencies:
+ "@codemirror/language" "^6.0.0"
+ "@codemirror/state" "^6.0.0"
+ "@codemirror/view" "^6.0.0"
+
"@uiw/react-codemirror@4.11.4":
version "4.11.4"
resolved "https://registry.yarnpkg.com/@uiw/react-codemirror/-/react-codemirror-4.11.4.tgz#76adc757baa0b8b1a9bd30d7081f5622b896d607"
|