1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-04-24 01:18:01 +02:00

Feat/dark mode exp (#1137)

* feat: add dark mode theme

* fix: feature metrics

* fix: add color

* styling

* fix: add switch

* fix: form sidebar

* fix: remove console log

* fix: add properties

* fix: strategy container

* feat: feature flag

* fix: tests

* fix: build

* fix: logo

* fix: icon

* fix: update snapshots

* fix: CES operator

* fix: typography

* fix: input styling

* fix: remove initial load

* fix: change flag name

* fix: refactor to custom hook

* fix: remove unused import

* fix: dialog headers

* fix: use uiConfig flags instead of flags
This commit is contained in:
Fredrik Strand Oseberg 2022-08-23 14:20:02 +02:00 committed by GitHub
parent e6b72ff4a0
commit 6818a82cd1
60 changed files with 860 additions and 115 deletions

View File

@ -39,6 +39,7 @@
"isready": "yarn lint && yarn fmt && yarn prepare"
},
"devDependencies": {
"@codemirror/lang-json": "6.0.0",
"@emotion/react": "11.9.3",
"@emotion/styled": "11.9.3",
"@mui/icons-material": "5.8.4",
@ -62,6 +63,7 @@
"@types/react-test-renderer": "17.0.2",
"@types/react-timeago": "4.1.3",
"@types/semver": "7.3.12",
"@uiw/react-codemirror": "4.11.4",
"@vitejs/plugin-react": "1.3.2",
"chart.js": "3.9.1",
"chartjs-adapter-date-fns": "2.0.0",
@ -102,8 +104,7 @@
"vite-tsconfig-paths": "3.5.0",
"vitest": "0.22.1",
"whatwg-fetch": "3.6.2",
"@codemirror/lang-json": "6.0.0",
"@uiw/react-codemirror": "4.11.4"
"@uiw/codemirror-theme-duotone": "^4.11.5"
},
"jest": {
"moduleNameMapper": {

View File

@ -0,0 +1 @@
<svg id="bg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 653.4 251.24"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#1a4049;}.cls-3{fill:#817afe;}</style></defs><circle class="cls-1" cx="125.62" cy="125.62" r="80"/><polygon class="cls-1" points="137.05 91.33 137.05 114.19 137.05 137.05 159.9 137.05 159.9 114.19 159.9 91.33 137.05 91.33"/><polygon class="cls-1" points="114.19 114.19 114.19 91.33 91.33 91.33 91.33 114.19 91.33 137.05 91.33 159.9 114.19 159.9 137.05 159.9 137.05 137.05 114.19 137.05 114.19 114.19"/><polygon class="cls-2" points="137.05 91.33 137.05 114.19 137.05 137.05 159.9 137.05 159.9 114.19 159.9 91.33 137.05 91.33"/><polygon class="cls-2" points="114.19 114.19 114.19 91.33 91.33 91.33 91.33 114.19 91.33 137.05 91.33 159.9 114.19 159.9 137.05 159.9 137.05 137.05 114.19 137.05 114.19 114.19"/><rect class="cls-3" x="137.05" y="137.05" width="22.86" height="22.86"/><path class="cls-1" d="M251.58,139.13V112.77h11.93v25.06c0,7.36,3.91,12.2,11.27,12.2s11.27-4.84,11.27-12.2V112.77h12v26.36c0,12.67-8.48,21.8-23.1,21.8C260.06,160.93,251.58,151.8,251.58,139.13Z"/><path class="cls-1" d="M321.91,159.9H310.08V112.77h11.83v7.92a17.93,17.93,0,0,1,15.65-9c11.83,0,19.66,8.67,19.66,20.68V159.9h-12V134.75c0-7.45-4.38-12.39-11.46-12.39s-11.83,5-11.83,12.39Z"/><path class="cls-1" d="M369.42,91.34h11.92V159.9H369.42Z"/><path class="cls-1" d="M441.24,137v1.3H403.79c.47,7.36,5.87,13,13.69,13,7.55,0,10.62-3.82,11.46-5.12h11.74c-.75,4.84-7.17,15-23.2,15-15.27,0-25.61-10.61-25.61-24.77,0-14.63,10.24-24.78,24.68-24.78S441.24,121.62,441.24,137Zm-37.08-6.9h24.6c-1.77-6-6.15-9.31-12.21-9.31C410.12,120.78,405.65,124.23,404.16,130.09Z"/><path class="cls-1" d="M467.78,130.37h15.47c0-5.68-4.29-9.31-11.27-9.31-6.62,0-9,3.54-9.78,4.75h-12c1-4.94,6.89-14.25,21.8-14.25,14.62,0,22.73,7.64,22.73,18.81V146.3c0,2.89,1,4,3.72,4.29v9.59h-3.72c-6.06-.09-9.69-2.33-11-6.52-2.23,3.45-7.26,7.27-15.27,7.27-11.09,0-19.47-6.24-19.47-15.93S456.14,130.37,467.78,130.37Zm15.47,12.11v-4H469.74c-5.59,0-9,2-9,6.33,0,4.57,4.29,7.27,10.25,7.27C477.66,152.08,483.25,148.82,483.25,142.48Z"/><path class="cls-1" d="M523.12,140.62c-10.34-.74-17.33-5.59-17.33-14.72,0-8.85,8.1-14.44,20.77-14.44,17,0,21.8,8.76,23.1,13.32H537.09c-.84-1-3.54-4.28-10.62-4.28-5.68,0-8.66,1.86-8.66,4.75,0,2.61,2,4.29,6.7,4.94l8,.84c12.77,1.11,18,6,18,15.27,0,8.85-7.36,14.91-21.8,14.91-17.51,0-23.19-10.16-24.12-14.53h12.76c.47,1.11,3.35,5.31,11.36,5.31,6.62,0,9.69-2.24,9.69-5.22s-1.67-4.66-7-5.31C528.05,141.18,526.38,141,523.12,140.62Z"/><path class="cls-1" d="M571.55,159.9H559.72V91.34h11.83v29.35a17.93,17.93,0,0,1,15.65-9c11.83,0,19.66,8.67,19.66,20.68V159.9h-12V134.75c0-7.45-4.38-12.39-11.46-12.39s-11.83,5-11.83,12.39Z"/></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -17,7 +17,7 @@ export const useStyles = makeStyles()(theme => ({
margin: '0 auto',
flex: 1,
width: '100%',
backgroundColor: theme.palette.grey[300],
backgroundColor: theme.palette.contentWrapper,
},
content: {
width: '1250px',

View File

@ -10,7 +10,7 @@ export const useStyles = makeStyles()(theme => ({
},
},
icon: {
background: theme.palette.primary.main,
background: theme.palette.featureSegmentSearchBackground,
height: 48,
width: 48,
display: 'flex',

View File

@ -2,7 +2,7 @@ import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
badge: {
backgroundColor: theme.palette.primary.main,
backgroundColor: theme.palette.checkmarkBadge,
width: '75px',
height: '75px',
borderRadius: '50px',

View File

@ -2,7 +2,7 @@ import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
container: {
backgroundColor: theme.palette.sidebarContainer,
backgroundColor: theme.palette.codebox,
padding: '1rem',
borderRadius: theme.shape.borderRadiusMedium,
position: 'relative',
@ -13,7 +13,7 @@ export const useStyles = makeStyles()(theme => ({
margin: 0,
wordBreak: 'break-all',
whiteSpace: 'pre-wrap',
color: '#fff',
color: theme.palette.formSidebarTextColor,
fontSize: 14,
},
icon: {

View File

@ -1,10 +1,25 @@
import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
constraintIconContainer: {
backgroundColor: theme.palette.background.paper,
borderRadius: '50%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginRight: theme.spacing(1),
[theme.breakpoints.down(650)]: {
marginBottom: '1rem',
marginRight: 0,
},
},
constraintIcon: {
fill: '#fff',
},
accordion: {
border: `1px solid ${theme.palette.dividerAlternative}`,
borderRadius: theme.shape.borderRadiusMedium,
backgroundColor: '#fff',
backgroundColor: theme.palette.constraintAccordion.background,
boxShadow: 'none',
margin: 0,
},
@ -14,7 +29,7 @@ export const useStyles = makeStyles()(theme => ({
},
},
accordionEdit: {
backgroundColor: '#F6F6FA',
backgroundColor: theme.palette.constraintAccordion.editBackground,
},
headerMetaInfo: {
display: 'flex',

View File

@ -1,4 +1,4 @@
import { Box, Tooltip } from '@mui/material';
import { Box, Tooltip, useTheme } from '@mui/material';
import { ReactComponent as NegatedIcon } from 'assets/icons/24_Negator.svg';
import { ReactComponent as NegatedIconOff } from 'assets/icons/24_Negator off.svg';
import { IConstraint } from 'interfaces/strategy';
@ -7,6 +7,7 @@ import {
StyledToggleButtonOn,
} from '../StyledToggleButton';
import { ConditionallyRender } from '../../../../ConditionallyRender/ConditionallyRender';
import { ThemeMode } from 'component/common/ThemeMode/ThemeMode';
interface InvertedOperatorButtonProps {
localConstraint: IConstraint;
@ -16,7 +17,10 @@ interface InvertedOperatorButtonProps {
export const InvertedOperatorButton = ({
localConstraint,
setInvertedOperator,
}: InvertedOperatorButtonProps) => (
}: InvertedOperatorButtonProps) => {
const theme = useTheme();
return (
<Tooltip
title={
Boolean(localConstraint.inverted)
@ -33,7 +37,17 @@ export const InvertedOperatorButton = ({
onClick={setInvertedOperator}
disableRipple
>
<NegatedIcon />
<ThemeMode
darkmode={
<NegatedIcon
style={{
fill: theme.palette.background
.paper,
}}
/>
}
lightmode={<NegatedIcon />}
/>
</StyledToggleButtonOn>
}
elseShow={
@ -41,10 +55,21 @@ export const InvertedOperatorButton = ({
onClick={setInvertedOperator}
disableRipple
>
<NegatedIconOff />
<ThemeMode
darkmode={
<NegatedIconOff
style={{
fill: theme.palette.background
.paper,
}}
/>
}
lightmode={<NegatedIconOff />}
/>
</StyledToggleButtonOff>
}
/>
</Box>
</Tooltip>
);
};

View File

@ -14,6 +14,7 @@ export const ConstraintIcon: VFC<IConstraintIconProps> = ({ compact }) => (
borderRadius: '50%',
width: compact ? '18px' : '24px',
height: compact ? '18px' : '24px',
marginRight: '13px',
}}
>
<TrackChanges

View File

@ -4,7 +4,7 @@ export const useStyles = makeStyles()(theme => ({
container: {
padding: theme.spacing(0.5, 1.5),
borderRadius: theme.shape.borderRadius,
backgroundColor: theme.palette.grey[200],
backgroundColor: theme.palette.constraintAccordion.operatorBackground,
lineHeight: 1.25,
},
name: {

View File

@ -2,8 +2,8 @@ import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
dialogTitle: {
backgroundColor: theme.palette.primary.main,
color: '#fff',
backgroundColor: theme.palette.dialogHeaderBackground,
color: theme.palette.dialogHeaderText,
height: '150px',
padding: '2rem 3rem',
clipPath: ' ellipse(130% 115px at 120% 20%)',

View File

@ -20,7 +20,7 @@ export const useStyles = makeStyles()(theme => ({
borderRadius: 0,
},
sidebar: {
backgroundColor: theme.palette.primary.main,
backgroundColor: theme.palette.formSidebar,
padding: '2rem',
flexGrow: 0,
flexShrink: 0,
@ -42,7 +42,7 @@ export const useStyles = makeStyles()(theme => ({
fontWeight: 'normal',
},
subtitle: {
color: '#fff',
color: theme.palette.formSidebarTextColor,
marginBottom: '1rem',
display: 'flex',
justifyContent: 'space-between',
@ -51,7 +51,7 @@ export const useStyles = makeStyles()(theme => ({
fontSize: theme.fontSizes.bodySize,
},
description: {
color: '#fff',
color: theme.palette.formSidebarTextColor,
zIndex: 1,
position: 'relative',
},
@ -72,7 +72,7 @@ export const useStyles = makeStyles()(theme => ({
},
},
formContent: {
backgroundColor: '#fff',
backgroundColor: theme.palette.formBackground,
display: 'flex',
flexDirection: 'column',
padding: '3rem',

View File

@ -3,7 +3,7 @@ import React, { FC, VFC, useEffect, useState, useContext } from 'react';
import { InstanceStatusBar } from 'component/common/InstanceStatus/InstanceStatusBar';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { Dialogue } from 'component/common/Dialogue/Dialogue';
import { Typography } from '@mui/material';
import { Typography, useTheme } from '@mui/material';
import { useNavigate } from 'react-router-dom';
import { IInstanceStatus } from 'interfaces/instance';
import { ADMIN } from 'component/providers/AccessProvider/permissions';
@ -91,6 +91,7 @@ export const InstanceStatus: FC = ({ children }) => {
useInstanceStatus();
const { extendTrial } = useInstanceStatusApi();
const { setToastApiError } = useToast();
const theme = useTheme();
const onExtendTrial = async () => {
try {
@ -102,7 +103,12 @@ export const InstanceStatus: FC = ({ children }) => {
};
return (
<div style={{ height: '100%' }}>
<div
style={{
height: '100%',
backgroundColor: theme.palette.background.paper,
}}
>
<ConditionallyRender
condition={isBilling && Boolean(instanceStatus)}
show={() => (

View File

@ -6,6 +6,7 @@ export const useStyles = makeStyles()(theme => ({
justifyContent: 'center',
alignItems: 'center',
height: '100%',
backgroundColor: theme.palette.background.paper,
},
img: {
width: '100px',

View File

@ -6,6 +6,7 @@ export const useStyles = makeStyles()(theme => ({
flexGrow: 1,
alignItems: 'center',
position: 'relative',
backgroundColor: theme.palette.background.paper,
maxWidth: '400px',
[theme.breakpoints.down('md')]: {
marginTop: theme.spacing(1),

View File

@ -7,7 +7,7 @@ export const useStyles = makeStyles()(theme => ({
'& + &': {
marginTop: theme.spacing(2),
},
background: theme.palette.background.default,
background: theme.palette.background.paper,
},
header: {
padding: theme.spacing(0.5, 2),

View File

@ -5,7 +5,8 @@ export const useStyles = makeStyles()(theme => ({
'& > th': {
height: theme.shape.tableRowHeightCompact,
border: 0,
backgroundColor: theme.palette.tableHeaderBackground,
color: theme.palette.tableHeaderColor,
'&:first-of-type': {
borderTopLeftRadius: theme.shape.borderRadiusMedium,
borderBottomLeftRadius: theme.shape.borderRadiusMedium,

View File

@ -0,0 +1,20 @@
import UIContext from 'contexts/UIContext';
import { useContext } from 'react';
import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender';
interface IThemeModeProps {
darkmode: JSX.Element;
lightmode: JSX.Element;
}
export const ThemeMode = ({ darkmode, lightmode }: IThemeModeProps) => {
const { themeMode } = useContext(UIContext);
return (
<ConditionallyRender
condition={themeMode === 'dark'}
show={darkmode}
elseShow={lightmode}
/>
);
};

View File

@ -3,7 +3,7 @@ import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
container: {
maxWidth: '450px',
background: '#fff',
background: theme.palette.background.paper,
boxShadow: '2px 2px 4px rgba(0,0,0,0.4)',
zIndex: 500,
margin: '0 0.8rem',

View File

@ -10,7 +10,7 @@ export const useStyles = makeStyles()(theme => ({
paddingBlockStart: 4,
paddingBlockEnd: 4,
borderRadius: '100rem',
background: theme.palette.primary.main,
background: theme.palette.featureStrategySegmentChipBackground,
color: 'white',
},
link: {

View File

@ -3,7 +3,7 @@ import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
container: {
borderRadius: '12.5px',
backgroundColor: '#fff',
backgroundColor: theme.palette.background.paper,
padding: '2rem',
},
}));

View File

@ -3,7 +3,7 @@ import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
item: {
padding: theme.spacing(2),
background: theme.palette.secondaryContainer,
background: theme.palette.featureMetricsBackground,
borderRadius: theme.spacing(2),
textAlign: 'center',
[theme.breakpoints.up('md')]: {

View File

@ -9,7 +9,7 @@ import { styled } from '@mui/material';
const StyledContainer = styled('div')(({ theme }) => ({
borderRadius: theme.shape.borderRadiusLarge,
backgroundColor: '#fff',
backgroundColor: theme.palette.background.paper,
display: 'flex',
flexDirection: 'column',
padding: '1.5rem',

View File

@ -4,7 +4,8 @@ export const useStyles = makeStyles()(theme => ({
featureOverviewEnvironment: {
borderRadius: theme.shape.borderRadiusLarge,
marginBottom: theme.spacing(2),
background: theme.palette.background.default,
padding: '0.2rem',
backgroundColor: theme.palette.background.paper,
},
accordion: {
boxShadow: 'none',

View File

@ -53,7 +53,7 @@ const FeatureOverviewEnvironment = ({
style={{
background: !env.enabled
? theme.palette.neutral.light
: theme.palette.background.default,
: theme.palette.background.paper,
}}
>
<Accordion

View File

@ -4,7 +4,7 @@ export const useStyles = makeStyles()(theme => ({
container: {
borderRadius: theme.shape.borderRadiusLarge,
color: '#fff',
backgroundColor: theme.palette.primary.main,
backgroundColor: theme.palette.featureMetaData,
display: 'flex',
flexDirection: 'column',
maxWidth: '350px',

View File

@ -7,7 +7,7 @@ export const useStyles = makeStyles()(theme => ({
display: 'flex',
},
header: {
backgroundColor: '#fff',
backgroundColor: theme.palette.background.paper,
borderRadius: theme.shape.borderRadiusLarge,
marginBottom: '1rem',
},

View File

@ -15,7 +15,7 @@ export const useStyles = makeStyles()(theme => ({
pointerEvents: 'auto',
position: 'relative',
padding: '4rem',
background: 'white',
background: theme.palette.background.paper,
boxShadow: '0 0 1rem rgba(0, 0, 0, 0.25)',
borderRadius: '1rem',
[theme.breakpoints.down('md')]: {

View File

@ -131,18 +131,18 @@ exports[`FeedbackCESForm 1`] = `
class="MuiFormControl-root MuiFormControl-fullWidth MuiTextField-root mui-wb57ya-MuiFormControl-root-MuiTextField-root"
>
<div
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-multiline mui-181wpo2-MuiInputBase-root-MuiOutlinedInput-root"
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-multiline mui-1qvtpcv-MuiInputBase-root-MuiOutlinedInput-root"
>
<textarea
aria-invalid="false"
class="MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputMultiline mui-1632cvv-MuiInputBase-input-MuiOutlinedInput-input"
class="MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputMultiline mui-1wvz5kg-MuiInputBase-input-MuiOutlinedInput-input"
id="mui-1"
rows="3"
style="height: 0px; overflow: hidden;"
/>
<textarea
aria-hidden="true"
class="MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputMultiline mui-1632cvv-MuiInputBase-input-MuiOutlinedInput-input"
class="MuiInputBase-input MuiOutlinedInput-input MuiInputBase-inputMultiline mui-1wvz5kg-MuiInputBase-input-MuiOutlinedInput-input"
readonly=""
style="visibility: hidden; position: absolute; overflow: hidden; height: 0px; top: 0px; left: 0px; transform: translateZ(0); padding: 0px; width: 100%;"
tabindex="-1"

View File

@ -3,7 +3,7 @@ import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
feedback: {
borderRadius: '12.5px',
backgroundColor: '#fff',
backgroundColor: theme.palette.background.paper,
zIndex: 9999,
boxShadow: '2px 2px 4px 4px rgba(143,143,143, 0.25)',
padding: '1.5rem',
@ -21,7 +21,7 @@ export const useStyles = makeStyles()(theme => ({
position: 'absolute',
right: '-38px',
top: '-47px',
backgroundColor: '#fff',
backgroundColor: theme.palette.background.paper,
boxShadow: '2px 2px 4px 4px rgba(143,143,143, 0.25)',
['&:hover']: {
backgroundColor: '#fff',

View File

@ -6,6 +6,7 @@ export const useStyles = makeStyles()(theme => ({
width: '100%',
flexGrow: 1,
zIndex: 100,
backgroundColor: theme.palette.footerBackground,
},
list: {
padding: 0,

View File

@ -3,7 +3,7 @@
exports[`should render DrawerMenu 1`] = `
[
<footer
className="tss-wd65c0-footer"
className="tss-16d7ppb-footer"
>
<div
className="MuiGrid-root MuiGrid-container MuiGrid-spacing-xs-10 mui-16chest-MuiGrid-root"
@ -448,7 +448,7 @@ exports[`should render DrawerMenu 1`] = `
exports[`should render DrawerMenu with "features" selected 1`] = `
[
<footer
className="tss-wd65c0-footer"
className="tss-16d7ppb-footer"
>
<div
className="MuiGrid-root MuiGrid-container MuiGrid-spacing-xs-10 mui-16chest-MuiGrid-root"

View File

@ -2,8 +2,7 @@ import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
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],

View File

@ -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,10 +122,20 @@ const Header: VFC = () => {
)}
aria-label="Home"
>
<ThemeMode
darkmode={
<UnleashLogoWhite
className={styles.logo}
aria-label="Unleash logo"
/>
}
lightmode={
<UnleashLogo
className={styles.logo}
aria-label="Unleash logo"
/>
}
/>
</Link>
<nav className={styles.nav}>
<div className={styles.links}>
@ -148,6 +169,22 @@ const Header: VFC = () => {
/>
</div>
<div className={styles.userContainer}>
<ConditionallyRender
condition={Boolean(
uiConfig.flags.ENABLE_DARK_MODE_SUPPORT
)}
show={
<FormControlLabel
control={
<Switch
onChange={onSetThemeMode}
checked={themeMode === 'dark'}
/>
}
label="darkmode"
/>
}
/>
<Tooltip title="Documentation" arrow>
<IconButton
href="https://docs.getunleash.io/"

View File

@ -20,7 +20,7 @@ export const useStyles = makeStyles()(theme => ({
textDecoration: 'none',
alignItems: 'center',
display: 'flex',
color: '#000',
color: 'inherit',
height: '100%',
width: '100%',
'&&': {

View File

@ -159,7 +159,7 @@ export const Playground: VFC<{}> = () => {
>
<Box
sx={{
background: theme.palette.grey[200],
background: theme.palette.playgroundBackground,
borderBottomLeftRadius: theme.shape.borderRadiusMedium,
}}
>
@ -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,

View File

@ -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<IPlaygroundEditorProps> = ({
setContext,
error,
}) => {
const { themeMode } = useContext(UIContext);
const theme = useTheme();
const onCodeFieldChange = useCallback(
context => {
@ -109,6 +113,7 @@ export const PlaygroundEditor: VFC<IPlaygroundEditorProps> = ({
<CodeMirror
value={context}
height="200px"
theme={themeMode === 'dark' ? duotoneDark : duotoneLight}
extensions={[json()]}
onChange={onCodeFieldChange}
style={{

View File

@ -13,7 +13,7 @@ export const useStyles = makeStyles()(theme => ({
minWidth: 0,
},
header: {
backgroundColor: '#fff',
backgroundColor: theme.palette.background.paper,
borderRadius: theme.shape.borderRadiusLarge,
marginBottom: '1rem',
},

View File

@ -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',

View File

@ -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: {

View File

@ -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<IUiProviderProps> = ({
children,
darkmode = false,
}) => {
const [toastData, setToast] = useState<IToast>(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 <UIContext.Provider value={context}>{children}</UIContext.Provider>;

View File

@ -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 (
<UIProvider darkmode={uiConfig.flags.ENABLE_DARK_MODE_SUPPORT || false}>
{children}
</UIProvider>
);
};

View File

@ -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',

View File

@ -13,7 +13,7 @@ test('renders an empty list correctly', () => {
<MemoryRouter>
<ThemeProvider>
<AnnouncerProvider>
<UIProvider>
<UIProvider darkmode={false}>
<AccessProviderMock
permissions={[{ permission: ADMIN }]}
>

View File

@ -7,7 +7,7 @@ exports[`renders an empty list correctly 1`] = `
aria-live="polite"
>
<div
className="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 tss-15wj2kz-container mui-177gdp-MuiPaper-root"
className="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 tss-15wj2kz-container mui-lorrhs-MuiPaper-root"
>
<div
className="header tss-1ywhhai-headerContainer"
@ -32,7 +32,7 @@ exports[`renders an empty list correctly 1`] = `
className="tss-u5t8ea-headerActions"
>
<div
className="tss-119iiqp-container"
className="tss-1oozr04-container"
>
<div
className="tss-1xjrf9m-search search-container"
@ -49,12 +49,12 @@ exports[`renders an empty list correctly 1`] = `
/>
</svg>
<div
className="MuiInputBase-root tss-11gf6cf-inputRoot input-container MuiInputBase-colorPrimary mui-1v3pvzz-MuiInputBase-root"
className="MuiInputBase-root tss-11gf6cf-inputRoot input-container MuiInputBase-colorPrimary mui-qtv7d9-MuiInputBase-root"
onClick={[Function]}
>
<input
aria-label="Search (Ctrl+K)"
className="MuiInputBase-input mui-j79lc6-MuiInputBase-input"
className="MuiInputBase-input mui-mfsqjb-MuiInputBase-input"
onAnimationStart={[Function]}
onBlur={[Function]}
onChange={[Function]}
@ -120,7 +120,7 @@ exports[`renders an empty list correctly 1`] = `
role={null}
>
<tr
className="MuiTableRow-root MuiTableRow-head tss-1sk7xq7-tableHeader mui-cn4v9y-MuiTableRow-root"
className="MuiTableRow-root MuiTableRow-head tss-1u2w2tj-tableHeader mui-cn4v9y-MuiTableRow-root"
role="row"
>
<th

View File

@ -17,8 +17,8 @@ const StandaloneBanner: FC<IStandaloneBannerProps> = ({ title, children }) => {
return (
<Gradient
from={theme.palette.primary.main}
to="#173341"
from={theme.palette.standaloneBannerGradient.from}
to={theme.palette.standaloneBannerGradient.to}
className={styles.gradient}
>
<div className={styles.container}>

View File

@ -75,6 +75,7 @@ const UserProfile = ({
disableRipple
>
<Avatar
style={{ backgroundColor: '#fff', padding: '0.15rem' }}
alt="Your Gravatar"
src={imageUrl}
data-testid={HEADER_USER_AVATAR}

View File

@ -20,6 +20,7 @@ import { basePath } from 'utils/formatPath';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { IUser } from 'interfaces/user';
import { ILocationSettings } from 'hooks/useLocationSettings';
import { useTheme } from '@mui/material/styles';
interface IUserProfileContentProps {
id: string;
@ -45,6 +46,8 @@ const UserProfileContent = ({
setLocationSettings,
}: IUserProfileContentProps) => {
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 = ({
>
<InputLabel
htmlFor="locale-select"
style={{ backgroundColor: '#fff' }}
style={{
backgroundColor:
theme.palette
.inputLabelBackground,
}}
>
Date/Time formatting
</InputLabel>

View File

@ -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',

View File

@ -6,8 +6,12 @@ interface IUIContext {
setToast: React.Dispatch<React.SetStateAction<IToast>>;
showFeedback: boolean;
setShowFeedback: React.Dispatch<React.SetStateAction<boolean>>;
setThemeMode: React.Dispatch<React.SetStateAction<themeMode>>;
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<IUIContext>({
toastData: createEmptyToast(),
setToast: setToastPlaceholder,
showFeedback: false,
setShowFeedback: setShowFeedbackPlaceholder,
themeMode: 'light',
setThemeMode: setThemeModePlaceholder,
});
export default UIContext;

View File

@ -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 };
};

View File

@ -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(
<UIProvider>
<UIProviderContainer>
<AccessProvider>
<BrowserRouter basename={basePath}>
<ThemeProvider>
@ -30,6 +30,6 @@ ReactDOM.render(
</ThemeProvider>
</BrowserRouter>
</AccessProvider>
</UIProvider>,
</UIProviderContainer>,
document.getElementById('app')
);

View File

@ -39,6 +39,7 @@ export interface IFlags {
T?: boolean;
UNLEASH_CLOUD?: boolean;
UG?: boolean;
ENABLE_DARK_MODE_SUPPORT?: boolean;
}
export interface IVersionInfo {

View File

@ -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 }) => (
export const ThemeProvider: FC = ({ children }) => {
const { resolveTheme } = useThemeMode();
return (
<CacheProvider value={muiCache}>
<MuiThemeProvider theme={mainTheme}>
<MuiThemeProvider theme={resolveTheme()}>
<CssBaseline />
{children}
</MuiThemeProvider>
</CacheProvider>
);
};

View File

@ -17,10 +17,6 @@ button {
font-family: 'Sen', sans-serif;
}
.MuiInputBase-root {
background-color: #fff;
}
.MuiAccordion-root.Mui-expanded {
margin: 0;
}

View File

@ -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;

View File

@ -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,
},
},
},
},
});

View File

@ -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,
},
},
},
},
});

View File

@ -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.
*/

View File

@ -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"