955 lines
25 KiB
JavaScript
955 lines
25 KiB
JavaScript
/////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin 4 - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2013 - 2025, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
/* The complete styling file for Material-UI components used
|
|
* This will become the main theme file for pgAdmin. All the
|
|
* custom themes info will come here.
|
|
*/
|
|
|
|
import React, { useEffect, useMemo, useState } from 'react';
|
|
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
|
import { LocalizationProvider } from '@mui/x-date-pickers';
|
|
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
|
import CustomPropTypes from '../custom_prop_types';
|
|
import getLightTheme from './light';
|
|
import getDarkTheme from './dark';
|
|
import getHightContrastTheme from './high_contrast';
|
|
import { CssBaseline } from '@mui/material';
|
|
import pickrOverride from './overrides/pickr.override';
|
|
import uplotOverride from './overrides/uplot.override';
|
|
import rcdockOverride from './overrides/rcdock.override';
|
|
import cmOverride from './overrides/codemirror.override';
|
|
import jsonEditorOverride from './overrides/jsoneditor.override';
|
|
import pgadminOverride from './overrides/pgadmin.classes.override';
|
|
import reactAspenOverride from './overrides/reactaspen.override';
|
|
import usePreferences from '../../../preferences/static/js/store';
|
|
import szhMenuOverride from './overrides/szhmenu.override';
|
|
|
|
/* Common settings across all themes */
|
|
let basicSettings = createTheme();
|
|
basicSettings = createTheme(basicSettings, {
|
|
typography: {
|
|
fontSize: 14,
|
|
htmlFontSize: 14,
|
|
fontFamilyIcon: '"Font Awesome 5 Free"',
|
|
fontFamilySourceCode: '"Source Code Pro", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
|
fontFamily: [
|
|
'Roboto',
|
|
'"Helvetica Neue"',
|
|
'-apple-system',
|
|
'BlinkMacSystemFont',
|
|
'"Segoe UI"',
|
|
'Arial',
|
|
'sans-serif',
|
|
'"Apple Color Emoji"',
|
|
'"Segoe UI Emoji"',
|
|
'"Segoe UI Symbol"',
|
|
].join(','),
|
|
},
|
|
shape: {
|
|
borderRadius: 4,
|
|
},
|
|
palette: {
|
|
action: {
|
|
disabledOpacity: 0.32,
|
|
}
|
|
},
|
|
transitions: {
|
|
create: () => 'none',
|
|
},
|
|
zIndex: {
|
|
modal: 3001,
|
|
},
|
|
components: {
|
|
MuiTextField: {
|
|
defaultProps: {
|
|
variant: 'outlined',
|
|
}
|
|
},
|
|
MuiButton: {
|
|
defaultProps: {
|
|
disableTouchRipple: true,
|
|
variant: 'outlined',
|
|
},
|
|
styleOverrides: {
|
|
root: {
|
|
textTransform: 'none',
|
|
padding: '2px 10px',
|
|
fontSize: 'inherit',
|
|
'&.Mui-disabled': {
|
|
opacity: 0.60,
|
|
},
|
|
'&.MuiButton-sizeSmall, &.MuiButton-outlined.MuiButton-sizeSmall, &.MuiButton-contained.MuiButton-sizeSmall': {
|
|
height: '28px',
|
|
fontSize: '0.875rem',
|
|
'& .MuiSvgIcon-root': {
|
|
height: '1.2rem',
|
|
},
|
|
},
|
|
},
|
|
contained: {
|
|
boxShadow: 'none',
|
|
'&:hover': {
|
|
boxShadow: 'none',
|
|
}
|
|
},
|
|
outlined: {
|
|
padding: '3px 9px',
|
|
},
|
|
startIcon: {
|
|
marginRight: basicSettings.spacing(0.5),
|
|
},
|
|
}
|
|
},
|
|
MuiIconButton: {
|
|
defaultProps: {
|
|
size: 'small',
|
|
disableTouchRipple: true,
|
|
}
|
|
},
|
|
MuiAccordion: {
|
|
defaultProps: {
|
|
defaultExpanded: true,
|
|
},
|
|
styleOverrides: {
|
|
root: {
|
|
boxShadow: 'none',
|
|
}
|
|
}
|
|
},
|
|
MuiTab: {
|
|
defaultProps: {
|
|
textColor: 'inherit',
|
|
},
|
|
styleOverrides: {
|
|
root: {
|
|
lineHeight: '1.75',
|
|
textTransform: 'none',
|
|
minHeight: 0,
|
|
padding: '3px 10px',
|
|
[basicSettings.breakpoints.up('xs')]: {
|
|
minWidth: 0,
|
|
},
|
|
[basicSettings.breakpoints.up('sm')]: {
|
|
minWidth: 0,
|
|
},
|
|
[basicSettings.breakpoints.up('md')]: {
|
|
minWidth: 0,
|
|
},
|
|
[basicSettings.breakpoints.up('lg')]: {
|
|
minWidth: 0,
|
|
},
|
|
},
|
|
textColorInherit: {
|
|
textTransform: 'none',
|
|
opacity: 1,
|
|
}
|
|
}
|
|
},
|
|
MuiCheckbox: {
|
|
defaultProps: {
|
|
disableTouchRipple: true,
|
|
}
|
|
},
|
|
MuiDialogTitle: {
|
|
defaultProps: {
|
|
}
|
|
},
|
|
MuiCardHeader: {
|
|
defaultProps: {
|
|
disableTypography: true,
|
|
}
|
|
},
|
|
MuiListItem: {
|
|
defaultProps: {
|
|
disableGutters: true,
|
|
}
|
|
},
|
|
MuiListItemButton: {
|
|
defaultProps: {
|
|
disableGutters: true,
|
|
disableTouchRipple: true,
|
|
}
|
|
},
|
|
MuiTabs: {
|
|
styleOverrides: {
|
|
root: {
|
|
minHeight: '30px',
|
|
}
|
|
}
|
|
},
|
|
PrivateTabIndicator: {
|
|
styleOverrides: {
|
|
root: {
|
|
height: '2px',
|
|
transition: basicSettings.transitions.create(['all'], {duration: '150ms'}),
|
|
}
|
|
}
|
|
},
|
|
MuiOutlinedInput: {
|
|
styleOverrides: {
|
|
multiline: {
|
|
padding: '0px',
|
|
},
|
|
input: {
|
|
padding: basicSettings.spacing(0.75, 1.5),
|
|
borderRadius: 'inherit',
|
|
},
|
|
inputMultiline: {
|
|
padding: basicSettings.spacing(0.75, 1.5),
|
|
resize: 'vertical',
|
|
height: '100%',
|
|
boxSizing: 'border-box',
|
|
},
|
|
adornedStart: {
|
|
paddingLeft: basicSettings.spacing(0.75),
|
|
},
|
|
inputAdornedStart: {
|
|
paddingLeft: '2px',
|
|
},
|
|
adornedEnd: {
|
|
paddingRight: basicSettings.spacing(0.75),
|
|
},
|
|
marginDense: {
|
|
height: '28px',
|
|
}
|
|
}
|
|
},
|
|
MuiPickersOutlinedInput: {
|
|
styleOverrides: {
|
|
multiline: {
|
|
padding: '0px',
|
|
},
|
|
input: {
|
|
padding: basicSettings.spacing(0.75, 1.5),
|
|
borderRadius: 'inherit',
|
|
},
|
|
inputMultiline: {
|
|
padding: basicSettings.spacing(0.75, 1.5),
|
|
resize: 'vertical',
|
|
height: '100%',
|
|
boxSizing: 'border-box',
|
|
},
|
|
adornedStart: {
|
|
paddingLeft: basicSettings.spacing(0.75),
|
|
},
|
|
inputAdornedStart: {
|
|
paddingLeft: '2px',
|
|
},
|
|
adornedEnd: {
|
|
paddingRight: basicSettings.spacing(0.75),
|
|
},
|
|
marginDense: {
|
|
height: '28px',
|
|
},
|
|
sectionsContainer: {
|
|
padding: '0px',
|
|
}
|
|
}
|
|
},
|
|
MuiAccordionSummary: {
|
|
styleOverrides: {
|
|
root: {
|
|
minHeight: 0,
|
|
'&.Mui-expanded': {
|
|
minHeight: 0,
|
|
},
|
|
padding: basicSettings.spacing(0, 1),
|
|
fontWeight: basicSettings.typography.fontWeightBold
|
|
},
|
|
content: {
|
|
margin: basicSettings.spacing(0.5),
|
|
'&.Mui-expanded': {
|
|
margin: basicSettings.spacing(0.5),
|
|
}
|
|
},
|
|
expandIconWrapper: {
|
|
order: -1,
|
|
}
|
|
}
|
|
},
|
|
MuiAccordionDetails: {
|
|
styleOverrides: {
|
|
root: {
|
|
padding: basicSettings.spacing(1),
|
|
}
|
|
}
|
|
},
|
|
MuiFormControlLabel: {
|
|
styleOverrides: {
|
|
root: {
|
|
marginBottom: 0,
|
|
marginLeft: 0,
|
|
marginRight: 0,
|
|
gap: '4px'
|
|
}
|
|
}
|
|
},
|
|
MuiFormHelperText: {
|
|
styleOverrides: {
|
|
root: {
|
|
fontSize: '1em',
|
|
},
|
|
contained: {
|
|
marginLeft: 0,
|
|
marginRight: 0,
|
|
}
|
|
}
|
|
},
|
|
MuiTypography: {
|
|
styleOverrides: {
|
|
root: {
|
|
fontSize: '0.875rem',
|
|
lineHeight: '1.43em',
|
|
letterSpacing: '0.01071em',
|
|
},
|
|
body1: {
|
|
fontSize: '1em',
|
|
}
|
|
}
|
|
},
|
|
MuiDialog: {
|
|
styleOverrides: {
|
|
paper: {
|
|
margin: 0,
|
|
},
|
|
scrollPaper: {
|
|
alignItems: 'flex-start',
|
|
margin: '5% auto',
|
|
}
|
|
}
|
|
},
|
|
MuiTooltip: {
|
|
defaultProps: {
|
|
arrow: true,
|
|
disableInteractive: true
|
|
},
|
|
styleOverrides: {
|
|
popper: {
|
|
top: 0,
|
|
zIndex: 9999,
|
|
},
|
|
}
|
|
},
|
|
MuiMenu: {
|
|
styleOverrides: {
|
|
list: {
|
|
padding: '0',
|
|
}
|
|
}
|
|
},
|
|
MuiMenuItem: {
|
|
styleOverrides: {
|
|
root: {
|
|
fontSize: 14,
|
|
}
|
|
}
|
|
},
|
|
MuiSelect: {
|
|
styleOverrides: {
|
|
selectMenu: {
|
|
minHeight: 'unset',
|
|
},
|
|
select:{
|
|
'&:focus':{
|
|
backgroundColor: 'unset',
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
});
|
|
|
|
/* Get the final theme after merging base theme with selected theme */
|
|
function getFinalTheme(baseTheme) {
|
|
let mixins = {
|
|
panelBorder: {
|
|
border: '1px solid '+baseTheme.otherVars.borderColor,
|
|
all: {
|
|
border: '1px solid '+baseTheme.otherVars.borderColor,
|
|
},
|
|
top: {
|
|
borderTop: '1px solid '+baseTheme.otherVars.borderColor,
|
|
},
|
|
bottom: {
|
|
borderBottom: '1px solid '+baseTheme.otherVars.borderColor,
|
|
},
|
|
right: {
|
|
borderRight: '1px solid '+baseTheme.otherVars.borderColor,
|
|
},
|
|
left: {
|
|
borderLeft: '1px solid '+baseTheme.otherVars.borderColor,
|
|
}
|
|
},
|
|
nodeIcon: {
|
|
backgroundPosition: 'center',
|
|
padding: baseTheme.spacing(0, 1.5),
|
|
},
|
|
tabPanel: {
|
|
height: '100%',
|
|
padding: baseTheme.spacing(1),
|
|
overflow: 'auto',
|
|
backgroundColor: baseTheme.palette.grey[400],
|
|
position: 'relative',
|
|
flexGrow: 1,
|
|
},
|
|
fontSourceCode: {
|
|
fontFamily: basicSettings.typography.fontFamilySourceCode,
|
|
}
|
|
};
|
|
|
|
baseTheme = createTheme({
|
|
mixins: mixins,
|
|
}, baseTheme);
|
|
|
|
return createTheme({
|
|
components: {
|
|
MuiCssBaseline: {
|
|
styleOverrides: {
|
|
body: {
|
|
fontFamily: baseTheme.typography.fontFamily,
|
|
fontSize: '0.875rem',
|
|
lineHeight: '1.43em',
|
|
letterSpacing: '0.01071em',
|
|
height: '100vh',
|
|
},
|
|
'::-webkit-scrollbar,::-webkit-scrollbar-corner': {
|
|
width: '1rem !important',
|
|
height: '1rem !important',
|
|
background: baseTheme.otherVars.scroll.barBackgroundColor
|
|
},
|
|
'::-webkit-scrollbar-thumb': {
|
|
border: '0.25rem solid transparent',
|
|
borderRadius: '0.5rem',
|
|
background: baseTheme.otherVars.scroll.thumbBackground + ' !important',
|
|
backgroundClip: 'content-box !important',
|
|
},
|
|
'::-webkit-scrollbar-thumb:hover': {
|
|
border: '0.25rem solid transparent',
|
|
background: baseTheme.otherVars.scroll.baseColor + ' !important',
|
|
backgroundClip: 'content-box !important'
|
|
},
|
|
'input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus,textarea:-webkit-autofill,textarea:-webkit-autofill:hover,textarea:-webkit-autofill:focus,select:-webkit-autofill,select:-webkit-autofill:hover,select:-webkit-autofill:focus': {
|
|
webkitTextFillColor : baseTheme.palette.text.primary,
|
|
webkitBoxShadow: '0 0 0px 1000px '+ baseTheme.palette.primary.light +' inset',
|
|
transition: 'backgroundColor 5000s ease-in-out 0s',
|
|
},
|
|
ul: {
|
|
margin: 0,
|
|
padding: 0,
|
|
},
|
|
li: {
|
|
listStyle: 'none',
|
|
margin: 0,
|
|
padding: 0,
|
|
},
|
|
textarea: {
|
|
fontFamily: 'inherit',
|
|
color: baseTheme.palette.text.primary,
|
|
backgroundColor: baseTheme.palette.background.default
|
|
},
|
|
iframe: {
|
|
margin: 0,
|
|
padding: 0,
|
|
},
|
|
svg: {
|
|
verticalAlign: 'middle',
|
|
},
|
|
img: {
|
|
verticalAlign: 'middle',
|
|
},
|
|
...pickrOverride(baseTheme),
|
|
...uplotOverride(baseTheme),
|
|
...rcdockOverride(baseTheme),
|
|
...cmOverride(baseTheme),
|
|
...jsonEditorOverride(baseTheme),
|
|
...pgadminOverride(baseTheme),
|
|
...reactAspenOverride(baseTheme),
|
|
...szhMenuOverride(baseTheme)
|
|
},
|
|
},
|
|
MuiOutlinedInput: {
|
|
styleOverrides: {
|
|
root: {
|
|
lineHeight: '1.1876em',
|
|
'&.Mui-disabled .MuiOutlinedInput-notchedOutline': {
|
|
borderColor: baseTheme.otherVars.inputBorderColor,
|
|
},
|
|
'.MuiButtonGroup-root &': {
|
|
borderRadius: 0,
|
|
|
|
'& .MuiOutlinedInput-notchedOutline': {
|
|
borderRadius: 0,
|
|
}
|
|
},
|
|
},
|
|
notchedOutline: {
|
|
borderColor: baseTheme.otherVars.inputBorderColor,
|
|
}
|
|
}
|
|
},
|
|
MuiPickersTextField: {
|
|
styleOverrides: {
|
|
root: {
|
|
width: '100%',
|
|
}
|
|
}
|
|
},
|
|
MuiPickersOutlinedInput: {
|
|
styleOverrides: {
|
|
root: {
|
|
lineHeight: '1.1876em',
|
|
fontSize: 'inherit',
|
|
backgroundColor: baseTheme.palette.background.default,
|
|
textOverflow: 'ellipsis',
|
|
'&.Mui-disabled': {
|
|
backgroundColor: baseTheme.otherVars.inputDisabledBg,
|
|
},
|
|
padding: '2px 12px',
|
|
},
|
|
notchedOutline: {
|
|
borderColor: baseTheme.otherVars.inputBorderColor,
|
|
},
|
|
}
|
|
},
|
|
MuiPickersSectionList: {
|
|
styleOverrides: {
|
|
root: {
|
|
padding: '0px',
|
|
}
|
|
}
|
|
},
|
|
MuiFormControlLabel: {
|
|
styleOverrides: {
|
|
label: {
|
|
'&.Mui-disabled': {
|
|
color: baseTheme.palette.text.muted
|
|
}
|
|
}
|
|
}
|
|
},
|
|
MuiTabs: {
|
|
styleOverrides: {
|
|
root: {
|
|
backgroundColor: baseTheme.otherVars.headerBg,
|
|
...mixins.panelBorder.bottom
|
|
},
|
|
indicator: {
|
|
backgroundColor: baseTheme.otherVars.activeColor,
|
|
}
|
|
}
|
|
},
|
|
MuiFormLabel: {
|
|
styleOverrides: {
|
|
root: {
|
|
color: baseTheme.palette.text.primary,
|
|
fontSize: baseTheme.typography.fontSize,
|
|
whiteSpace: 'normal !important'
|
|
},
|
|
asterisk: {
|
|
color: baseTheme.palette.error.main,
|
|
}
|
|
}
|
|
},
|
|
MuiInputBase: {
|
|
styleOverrides: {
|
|
root: {
|
|
backgroundColor: baseTheme.palette.background.default,
|
|
textOverflow: 'ellipsis',
|
|
'&.Mui-disabled': {
|
|
backgroundColor: baseTheme.otherVars.inputDisabledBg,
|
|
},
|
|
},
|
|
inputMultiline: {
|
|
fontSize: baseTheme.typography.fontSize,
|
|
height: 'unset',
|
|
backgroundColor: baseTheme.palette.background.default,
|
|
'&[readonly], &.Mui-disabled': {
|
|
color: baseTheme.palette.text.muted,
|
|
backgroundColor: baseTheme.otherVars.inputDisabledBg,
|
|
},
|
|
},
|
|
input: {
|
|
fontSize: baseTheme.typography.fontSize,
|
|
height: 'unset',
|
|
backgroundColor: baseTheme.palette.background.default,
|
|
'&[readonly], &.Mui-disabled': {
|
|
color: baseTheme.palette.text.muted,
|
|
backgroundColor: baseTheme.otherVars.inputDisabledBg,
|
|
WebkitTextFillColor: baseTheme.palette.text.muted
|
|
},
|
|
'&:focus': {
|
|
outline: '0 !important',
|
|
}
|
|
},
|
|
sizeSmall: {
|
|
height: '28px',
|
|
},
|
|
inputSizeSmall: {
|
|
height: '16px', // + 12px of padding = 28px;
|
|
},
|
|
}
|
|
},
|
|
MuiSelect: {
|
|
styleOverrides: {
|
|
icon: {
|
|
color: baseTheme.palette.text.primary,
|
|
'&.Mui-disabled': {
|
|
color: baseTheme.palette.text.muted,
|
|
}
|
|
},
|
|
}
|
|
},
|
|
MuiNativeSelect:{
|
|
styleOverrides: {
|
|
icon: {
|
|
color: baseTheme.palette.text.primary,
|
|
'&.Mui-disabled': {
|
|
color: baseTheme.palette.text.muted,
|
|
}
|
|
}
|
|
}
|
|
},
|
|
MuiIconButton: {
|
|
styleOverrides: {
|
|
root: {
|
|
color: baseTheme.palette.text.primary,
|
|
'&.Mui-disabled': {
|
|
color: 'abc',
|
|
}
|
|
}
|
|
}
|
|
},
|
|
MuiAccordion: {
|
|
styleOverrides: {
|
|
root: {
|
|
...mixins.panelBorder,
|
|
'&.Mui-expanded': {
|
|
margin: '8px 0px',
|
|
},
|
|
}
|
|
}
|
|
},
|
|
MuiAccordionSummary: {
|
|
styleOverrides: {
|
|
root: {
|
|
...mixins.panelBorder.bottom,
|
|
backgroundColor: baseTheme.otherVars.headerBg,
|
|
},
|
|
content: {
|
|
margin: '4px',
|
|
},
|
|
expandIconWrapper: {
|
|
color: baseTheme.palette.text.primary,
|
|
}
|
|
}
|
|
},
|
|
MuiToggleButtonGroup: {
|
|
styleOverrides: {
|
|
groupedHorizontal : {
|
|
'&:not(:first-of-type)': {
|
|
borderLeft: 'abc'
|
|
}
|
|
},
|
|
middleButton: {
|
|
borderLeftColor: baseTheme.otherVars.borderColor,
|
|
},
|
|
lastButton: {
|
|
borderLeftColor: baseTheme.otherVars.borderColor,
|
|
}
|
|
}
|
|
},
|
|
MuiSwitch: {
|
|
styleOverrides: {
|
|
root: {
|
|
width: 54,
|
|
height: 28,
|
|
padding: '7px 12px',
|
|
},
|
|
colorPrimary: {
|
|
'&.Mui-disabled': {
|
|
color: 'abc',
|
|
'& + .MuiSwitch-track': {
|
|
backgroundColor: 'abc',
|
|
}
|
|
}
|
|
},
|
|
switchBase: {
|
|
padding: baseTheme.spacing(0.5),
|
|
'&.Mui-disabled': {
|
|
color: 'abc',
|
|
'& + .MuiSwitch-track': {
|
|
opacity: baseTheme.palette.action.disabledOpacity,
|
|
}
|
|
},
|
|
'&.Mui-checked': {
|
|
transform: 'translateX(24px)',
|
|
'& .MuiSwitch-thumb': {
|
|
border: 0
|
|
}
|
|
}
|
|
},
|
|
thumb: {
|
|
border: '1px solid ' + baseTheme.otherVars.inputBorderColor
|
|
},
|
|
track: {
|
|
backgroundColor: baseTheme.otherVars.toggleBtnBg
|
|
}
|
|
}
|
|
},
|
|
MuiCheckbox: {
|
|
styleOverrides: {
|
|
root: {
|
|
padding: '0px',
|
|
color: baseTheme.custom.checkbox.borderColor,
|
|
},
|
|
|
|
colorPrimary: {
|
|
'&.Mui-disabled': {
|
|
color: baseTheme.custom.checkbox.disabled
|
|
}
|
|
}
|
|
}
|
|
},
|
|
MuiRadio: {
|
|
styleOverrides: {
|
|
root: {
|
|
padding: '0px',
|
|
color: baseTheme.custom.checkbox.borderColor,
|
|
},
|
|
|
|
colorPrimary: {
|
|
'&.Mui-disabled': {
|
|
color: baseTheme.custom.checkbox.disabled
|
|
}
|
|
}
|
|
}
|
|
},
|
|
MuiToggleButton: {
|
|
styleOverrides: {
|
|
root: {
|
|
padding: '3px 16px 3px 4px',
|
|
color: 'abc',
|
|
textTransform: 'initial',
|
|
'&:hover':{
|
|
backgroundColor: 'abc',
|
|
},
|
|
'&.Mui-selected': {
|
|
color: baseTheme.palette.primary.contrastTextLight ?? baseTheme.palette.primary.main,
|
|
backgroundColor: baseTheme.palette.primary.light,
|
|
borderColor: baseTheme.palette.primary.main,
|
|
zIndex: 1,
|
|
'&:hover':{
|
|
backgroundColor: baseTheme.palette.primary.hoverLight,
|
|
}
|
|
},
|
|
backgroundClip: 'padding-box',
|
|
},
|
|
}
|
|
},
|
|
MuiFormHelperText: {
|
|
styleOverrides: {
|
|
root: {
|
|
color: baseTheme.palette.text.muted,
|
|
},
|
|
}
|
|
},
|
|
MuiDialogContent: {
|
|
styleOverrides: {
|
|
root: {
|
|
padding: 0,
|
|
userSelect: 'text',
|
|
}
|
|
}
|
|
},
|
|
MuiDialogTitle: {
|
|
styleOverrides: {
|
|
root: {
|
|
fontSize: '0.875rem',
|
|
fontWeight: 'bold',
|
|
padding: '5px 10px',
|
|
cursor: 'move',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
...mixins.panelBorder.bottom,
|
|
}
|
|
}
|
|
},
|
|
MuiCardHeader: {
|
|
styleOverrides: {
|
|
root: {
|
|
padding: '4px 8px',
|
|
backgroundColor: baseTheme.otherVars.cardHeaderBg,
|
|
fontWeight: 'bold',
|
|
...mixins.panelBorder.bottom,
|
|
}
|
|
}
|
|
},
|
|
MuiCardContent: {
|
|
styleOverrides: {
|
|
root: {
|
|
padding: 0,
|
|
'&:last-child': {
|
|
paddingBottom: 0,
|
|
}
|
|
}
|
|
}
|
|
},
|
|
MuiListItemButton: {
|
|
styleOverrides: {
|
|
root: {
|
|
color: baseTheme.palette.text.primary,
|
|
backgroundColor: baseTheme.palette.background.default,
|
|
flexDirection: 'column',
|
|
alignItems: 'initial',
|
|
padding: '0px 4px',
|
|
paddingTop: '0px',
|
|
paddingBottom: '0px',
|
|
...mixins.panelBorder.top,
|
|
...mixins.panelBorder.bottom,
|
|
borderTopColor: 'transparent',
|
|
cursor: 'pointer',
|
|
'&.Mui-selected': {
|
|
backgroundColor: baseTheme.palette.primary.light,
|
|
borderColor: baseTheme.palette.primary.main,
|
|
color: basicSettings.palette.getContrastText(baseTheme.palette.primary.light),
|
|
'&:hover': {
|
|
backgroundColor: baseTheme.palette.primary.light,
|
|
}
|
|
},
|
|
}
|
|
}
|
|
},
|
|
MuiListItem: {
|
|
styleOverrides: {
|
|
root: {
|
|
color: baseTheme.palette.text.primary,
|
|
backgroundColor: baseTheme.palette.background.default,
|
|
flexDirection: 'column',
|
|
alignItems: 'initial',
|
|
padding: '0px 4px',
|
|
paddingTop: '0px',
|
|
paddingBottom: '0px',
|
|
...mixins.panelBorder.top,
|
|
...mixins.panelBorder.bottom,
|
|
borderTopColor: 'transparent',
|
|
cursor: 'pointer',
|
|
}
|
|
}
|
|
},
|
|
MuiTooltip: {
|
|
styleOverrides: {
|
|
tooltip: {
|
|
fontSize: '0.7rem',
|
|
color: baseTheme.palette.background.default,
|
|
backgroundColor: baseTheme.palette.text.primary,
|
|
},
|
|
arrow: {
|
|
color: baseTheme.palette.text.primary,
|
|
}
|
|
}
|
|
},
|
|
MuiTab: {
|
|
styleOverrides: {
|
|
root: {
|
|
'&:not(.Mui-disabled).MuiTab-textColorPrimary':{
|
|
color: baseTheme.palette.text.primary,
|
|
},
|
|
'&.Mui-selected': {
|
|
color: baseTheme.otherVars.activeColor,
|
|
},
|
|
},
|
|
icon: {
|
|
fontSize: '1rem',
|
|
marginRight: '2px',
|
|
},
|
|
}
|
|
},
|
|
MuiBackdrop: {
|
|
styleOverrides: {
|
|
root: {
|
|
backgroundColor: baseTheme.otherVars.loader.backgroundColor,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}, baseTheme);
|
|
}
|
|
|
|
/* Get the actual system theme is user selected system theme in preferences */
|
|
function parseSystemTheme(selectedTheme) {
|
|
if (selectedTheme === 'system') {
|
|
const systemMatchMedia = matchMedia('(prefers-color-scheme: dark)');
|
|
return {
|
|
'theme': systemMatchMedia.matches ? 'dark' : 'light',
|
|
'systemMatchMedia': systemMatchMedia,
|
|
};
|
|
}
|
|
return {
|
|
'theme': selectedTheme,
|
|
'systemMatchMedia': null,
|
|
};
|
|
}
|
|
|
|
/* Theme wrapper used by DOM containers to apply theme */
|
|
/* In future, this will be moved to App container */
|
|
export default function Theme({children}) {
|
|
const prefStore = usePreferences();
|
|
const selectedTheme =
|
|
prefStore?.getPreferencesForModule('misc')?.theme ||
|
|
window.theme ||
|
|
'light';
|
|
|
|
// Initialize theme state
|
|
const [theme, setTheme] = useState(parseSystemTheme(selectedTheme).theme);
|
|
|
|
// Memoize the theme object
|
|
const themeObj = useMemo(()=>{
|
|
let baseTheme = getLightTheme(basicSettings);
|
|
switch(theme) {
|
|
case 'dark':
|
|
baseTheme = getDarkTheme(baseTheme);
|
|
break;
|
|
case 'high_contrast':
|
|
baseTheme = getHightContrastTheme(baseTheme);
|
|
break;
|
|
}
|
|
return getFinalTheme(baseTheme);
|
|
}, [theme]);
|
|
|
|
// Handle theme updates
|
|
useEffect(() => {
|
|
let {theme, systemMatchMedia} = parseSystemTheme(selectedTheme);
|
|
setTheme(theme);
|
|
|
|
const updateTheme = (event) => {
|
|
const newTheme = event.matches ? 'dark' : 'light';
|
|
setTheme(newTheme);
|
|
};
|
|
systemMatchMedia?.addEventListener('change', updateTheme);
|
|
|
|
return () => {
|
|
systemMatchMedia?.removeEventListener('change', updateTheme);
|
|
};
|
|
},[selectedTheme]);
|
|
|
|
return (
|
|
<ThemeProvider theme={themeObj}>
|
|
<CssBaseline />
|
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
|
{children}
|
|
</LocalizationProvider>
|
|
</ThemeProvider>
|
|
);
|
|
}
|
|
|
|
Theme.propTypes = {
|
|
children: CustomPropTypes.children,
|
|
};
|