got new theme system to work without re-rendering
This commit is contained in:
parent
a452cf9444
commit
3454d16f36
12 changed files with 100 additions and 361 deletions
6
package-lock.json
generated
6
package-lock.json
generated
|
|
@ -14126,9 +14126,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "6.2.5",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz",
|
||||
"integrity": "sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==",
|
||||
"version": "6.2.6",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.6.tgz",
|
||||
"integrity": "sha512-9xpjNl3kR4rVDZgPNdTL0/c6ao4km69a/2ihNQbcANz8RuCOK3hQBmLSJf3bRKVQjVMda+YvizNE8AwvogcPbw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -5,14 +5,13 @@ import HTTPProvider from 'providers/http'
|
|||
import { useState } from 'react'
|
||||
import LoadingScreen from './LoadingScreen'
|
||||
import UserWrapper from './UserWrapper'
|
||||
import { CssBaseline, Theme, ThemeProvider } from '@mui/material'
|
||||
import { CreateTheme } from '../theme/theme'
|
||||
import { getThemeType, setThemeType } from '../theme/themeType'
|
||||
import { CssBaseline } from '@mui/material'
|
||||
import { getWhitelabel } from 'services/whiteLabel'
|
||||
import { AppThemeProvider } from 'theme/AppThemeProvider'
|
||||
|
||||
function App() {
|
||||
const [token, setToken] = useState<string | undefined>(undefined)
|
||||
const [palette, setPalette] = useState<Theme>(CreateTheme(getThemeType()));
|
||||
// const [palette, setPalette] = useState<Theme>(CreateTheme(getThemeType()));
|
||||
|
||||
const whiteLabel = getWhitelabel()
|
||||
const manifestPath = "/" + whiteLabel.name.replace(/\s/g, "") + "/manifest.json"
|
||||
|
|
@ -45,17 +44,8 @@ function App() {
|
|||
|
||||
let client_id = import.meta.env.VITE_AUTH0_DEV_CLIENT_ID;
|
||||
|
||||
const toggleTheme = () => {
|
||||
if (getThemeType() === "light") {
|
||||
setPalette(CreateTheme("dark"));
|
||||
setThemeType("dark");
|
||||
} else {
|
||||
setPalette(CreateTheme("light"));
|
||||
setThemeType("light");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<AppThemeProvider>
|
||||
<Auth0Provider
|
||||
domain={or(url, "")}
|
||||
clientId={or(client_id, "")}
|
||||
|
|
@ -66,12 +56,11 @@ function App() {
|
|||
useRefreshTokens={true}
|
||||
cacheLocation='localstorage'
|
||||
>
|
||||
<ThemeProvider theme={palette}>
|
||||
<CssBaseline />
|
||||
{/* <CssBaseline /> */}
|
||||
<AuthWrapper setToken={setToken}>
|
||||
{ token ?
|
||||
<HTTPProvider token={token}>
|
||||
<UserWrapper toggleTheme={toggleTheme}/>
|
||||
<UserWrapper />
|
||||
</HTTPProvider>
|
||||
:
|
||||
<LoadingScreen
|
||||
|
|
@ -79,8 +68,8 @@ function App() {
|
|||
/>
|
||||
}
|
||||
</AuthWrapper>
|
||||
</ThemeProvider>
|
||||
</Auth0Provider>
|
||||
</AppThemeProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
appBar: {
|
||||
zIndex: theme.zIndex.drawer + 1,
|
||||
backgroundImage: "none", // This prevents de-saturation of header in dark mode
|
||||
// backgroundColor: "#272727"
|
||||
backgroundColor: "#272727"
|
||||
},
|
||||
toolbar: {
|
||||
marginLeft: theme.spacing(0.5),
|
||||
|
|
@ -77,16 +77,8 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
},
|
||||
}));
|
||||
|
||||
interface Props {
|
||||
toggleTheme: () => void;
|
||||
// teams: Team[];
|
||||
// setTeams: React.Dispatch<React.SetStateAction<Team[]>>;
|
||||
}
|
||||
export default function Header() {
|
||||
|
||||
export default function Header(props: Props) {
|
||||
|
||||
// const { sideIsOpen, openSide, toggleTheme } = props;
|
||||
const { toggleTheme } = props;
|
||||
const themeType = useThemeType();
|
||||
const classes = useStyles()
|
||||
const isMobile = useMobile();
|
||||
|
|
@ -125,7 +117,7 @@ export default function Header(props: Props) {
|
|||
)}
|
||||
</Box>
|
||||
<Box className={classes.appBarRight}>
|
||||
<UserMenu toggleTheme={toggleTheme} />
|
||||
<UserMenu />
|
||||
<HeaderButtons hasTeams={hasTeams} team={team} user={user} />
|
||||
</Box>
|
||||
</Toolbar>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ import { GlobalState, GlobalStateAction, StateProvider } from '../providers/Stat
|
|||
import { User } from '../models/user'
|
||||
import { Team } from '../models/team'
|
||||
import { makeStyles } from '@mui/styles'
|
||||
import { Theme } from '@mui/material'
|
||||
import { CssBaseline, Theme } from '@mui/material'
|
||||
import { AppThemeProvider } from 'theme/AppThemeProvider'
|
||||
// import FirmwareLoader from './FirmwareLoader'
|
||||
|
||||
const reducer = (state: GlobalState, action: GlobalStateAction): GlobalState => {
|
||||
|
|
@ -50,12 +51,7 @@ const globalDefault = {
|
|||
firmware: new Map()
|
||||
}
|
||||
|
||||
interface Props {
|
||||
toggleTheme: () => void;
|
||||
}
|
||||
|
||||
export default function UserWrapper(props: Props) {
|
||||
const { toggleTheme } = props;
|
||||
export default function UserWrapper() {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const userAPI = useUserAPI();
|
||||
const classes = useStyles();
|
||||
|
|
@ -99,10 +95,14 @@ export default function UserWrapper(props: Props) {
|
|||
|
||||
return (
|
||||
<StateProvider state={global} reducer={reducer}>
|
||||
{/* <FirmwareLoader> */}
|
||||
<AppThemeProvider >
|
||||
<CssBaseline/>
|
||||
<main className={classes.appContent}>
|
||||
<NavigationContainer toggleTheme={toggleTheme} />
|
||||
<NavigationContainer />
|
||||
</main>
|
||||
</AppThemeProvider>
|
||||
{/* <FirmwareLoader> */}
|
||||
|
||||
{/* </FirmwareLoader> */}
|
||||
</StateProvider>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import {
|
|||
import { usePrevious } from "hooks";
|
||||
import BindaptIcon from "products/Bindapt/BindaptIcon";
|
||||
import BinsIcon from "products/Bindapt/BinsIcon";
|
||||
import VentilationIcon from "products/ventilation/VentilationIcon";
|
||||
import { useGlobalState } from "providers";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useNavigate, useLocation } from "react-router-dom";
|
||||
|
|
|
|||
|
|
@ -1,22 +1,12 @@
|
|||
import React, { PropsWithChildren } from "react";
|
||||
import Router from "./Router";
|
||||
|
||||
interface Props extends PropsWithChildren {
|
||||
toggleTheme: () => void;
|
||||
// teams: Team[];
|
||||
// setTeams: React.Dispatch<React.SetStateAction<Team[]>>;
|
||||
}
|
||||
|
||||
export default function NavigationContainer(props: Props) {
|
||||
// const { toggleTheme, teams, setTeams } = props;
|
||||
const { toggleTheme } = props;
|
||||
export default function NavigationContainer() {
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{/* <NotificationBanner /> */}
|
||||
<Router
|
||||
toggleTheme={toggleTheme}
|
||||
/>
|
||||
<Router />
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,19 +37,13 @@ const BinCableEstimator = lazy(() => import("pages/BinCableEstimator"));
|
|||
const APIDocs = lazy(() => import("pages/APIDocs"));
|
||||
const Fields = lazy(()=> import("pages/Fields"));
|
||||
const Marketplace = lazy(() => import("userFeatures/UserFeatures"))
|
||||
|
||||
interface Props {
|
||||
toggleTheme: () => void;
|
||||
}
|
||||
|
||||
export const appendToUrl = (appendage: number | string) => {
|
||||
const basePath = location.pathname.replace(/\/$/, "");
|
||||
return(`${basePath}/${appendage}`);
|
||||
};
|
||||
|
||||
export default function Router(props: Props) {
|
||||
export default function Router() {
|
||||
|
||||
const { toggleTheme } = props;
|
||||
const { isAuthenticated, loginWithRedirect, isLoading } = useAuth0();
|
||||
const whiteLabel = getWhitelabel();
|
||||
const [{ user }] = useGlobalState();
|
||||
|
|
@ -290,11 +284,7 @@ export default function Router(props: Props) {
|
|||
return (
|
||||
<Suspense fallback={<LoadingScreen />}>
|
||||
<BrowserRouter>
|
||||
<Header
|
||||
toggleTheme={toggleTheme}
|
||||
// teams={teams}
|
||||
// setTeams={setTeams}
|
||||
/>
|
||||
<Header />
|
||||
<Routes>
|
||||
|
||||
{/* Redirects */}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,9 @@ const STAGING_WHITELABEL: WhiteLabel = {
|
|||
const BXT_WHITE_LABEL: WhiteLabel = {
|
||||
name: "Brand X Technologies",
|
||||
primaryColour: "blue",
|
||||
// primaryColour: "#0000FF",
|
||||
secondaryColour: "yellow",
|
||||
// secondaryColour: "#FFFF00",
|
||||
signatureColour: "#272727",
|
||||
// signatureColour: "#005bb0",
|
||||
signatureAccentColour: "#fff",
|
||||
|
|
@ -116,7 +118,9 @@ export function isBXT(): boolean {
|
|||
const ADAPTIVE_AGRICULTURE_WHITE_LABEL: WhiteLabel = {
|
||||
name: "Adaptive Agriculture",
|
||||
primaryColour: "green",
|
||||
// primaryColour: "#008000",
|
||||
secondaryColour: "yellow",
|
||||
// secondaryColour: "#FFFF00",
|
||||
signatureColour: "#272727",
|
||||
signatureAccentColour: "#fff",
|
||||
auth0ClientId: import.meta.env.REACT_APP_AUTH0_ADAPTIVE_AGRICULTURE_CLIENT_ID,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
export * from "./text";
|
||||
export { CreateTheme } from "./theme";
|
||||
// export { CreateTheme } from "./theme";
|
||||
export * from "./themeType";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// src/theme.ts
|
||||
import * as Colours from "@mui/material/colors"
|
||||
import { createTheme, responsiveFontSizes, Theme, ThemeOptions } from '@mui/material/styles';
|
||||
import { createTheme, ThemeOptions } from '@mui/material/styles';
|
||||
import {
|
||||
getPrimaryColour,
|
||||
getSecondaryColour,
|
||||
|
|
@ -7,283 +8,55 @@ import {
|
|||
getSignatureColour
|
||||
} from "../services/whiteLabel";
|
||||
|
||||
export function CreateTheme(themeType: "light" | "dark"): Theme {
|
||||
return responsiveFontSizes(createTheme(options(themeType)));
|
||||
}
|
||||
const baseTheme: ThemeOptions = {
|
||||
palette: {
|
||||
mode: 'light', // default mode; will be overridden by system if needed
|
||||
primary: {
|
||||
main: '#1976d2',
|
||||
},
|
||||
background: {
|
||||
default: '#ffffff',
|
||||
paper: '#f5f5f5',
|
||||
},
|
||||
},
|
||||
// Add other options if needed
|
||||
};
|
||||
|
||||
function generateBackgroundShades(themeType: "light" | "dark") {
|
||||
if(themeType==="light") return ({
|
||||
default: "#e9e9e9",
|
||||
paper: "#fafafa",
|
||||
})
|
||||
function makePaletteColor(name: keyof typeof Colours) {
|
||||
if (name.startsWith("#")) {
|
||||
return { main: name };
|
||||
}
|
||||
const ramp = Colours[name] as Record<number, string>; // e.g., blue[500], blue[300], etc.
|
||||
// if (!ramp) {
|
||||
|
||||
// }
|
||||
return {
|
||||
default: "#303030",
|
||||
paper: "#373737",
|
||||
main: ramp[500],
|
||||
light: ramp[300],
|
||||
dark: ramp[700],
|
||||
};
|
||||
}
|
||||
|
||||
function options(themeType: "light" | "dark"): ThemeOptions {
|
||||
|
||||
const signature = getSignatureColour();
|
||||
const accent = getSignatureAccentColour();
|
||||
const highlight = themeType === "light" ? "black" : "white";
|
||||
const bg = generateBackgroundShades(themeType);
|
||||
return {
|
||||
cssVariables: true,
|
||||
zIndex: {
|
||||
modal: 1300,
|
||||
popover: 1350
|
||||
},
|
||||
export const getTheme = (mode: 'light' | 'dark') =>
|
||||
createTheme({
|
||||
...baseTheme,
|
||||
palette: {
|
||||
primary: Colours[getPrimaryColour() as keyof typeof Colours],
|
||||
secondary: Colours[getSecondaryColour() as keyof typeof Colours],
|
||||
background: bg,
|
||||
mode: themeType,
|
||||
bxt: {
|
||||
primaryBlue: "#005bb0",
|
||||
lightBlue: "#1a86ec",
|
||||
darkBlue: "#081d55",
|
||||
rubberDuckYellow: "#ffd45c"
|
||||
...baseTheme.palette,
|
||||
primary: makePaletteColor(getPrimaryColour()),
|
||||
secondary: makePaletteColor(getSecondaryColour()),
|
||||
mode,
|
||||
...(mode === 'dark'
|
||||
? {
|
||||
background: {
|
||||
default: '#121212',
|
||||
paper: '#1e1e1e',
|
||||
},
|
||||
status: {
|
||||
succes: "#4caf50",
|
||||
unknown: "0288d1",
|
||||
unstable: "rgb(189, 200, 33)",
|
||||
risk: "#ffd642",
|
||||
warning: "#ffb74d",
|
||||
alert: "#f44336"
|
||||
}
|
||||
},
|
||||
typography: {
|
||||
fontFamily: [
|
||||
"Open Sans",
|
||||
"-apple-system",
|
||||
"BlinkMacSystemFont",
|
||||
'"Segoe UI"',
|
||||
'"Helvetica Neue"',
|
||||
"Arial",
|
||||
"sans-serif",
|
||||
'"Apple Color Emoji"',
|
||||
'"Segoe UI Emoji"',
|
||||
'"Segoe UI Symbol"'
|
||||
].join(",")
|
||||
},
|
||||
components: {
|
||||
MuiAppBar: {
|
||||
styleOverrides: {
|
||||
colorPrimary: {
|
||||
backgroundColor: signature,
|
||||
color: accent,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiBottomNavigation: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundColor: signature
|
||||
}
|
||||
: {
|
||||
background: {
|
||||
default: "#e9e9e9",
|
||||
paper: "#fafafa",
|
||||
}
|
||||
}),
|
||||
},
|
||||
MuiBottomNavigationAction: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundColor: signature,
|
||||
color: Colours["grey"][500],
|
||||
"&$selected": {
|
||||
color: accent
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
MuiCard: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderRadius: "5px",
|
||||
"@media (min-width: 600px)": {
|
||||
borderRadius: "7px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiChip: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
"@media (max-width: 600px)": {
|
||||
height: "24px"
|
||||
}
|
||||
},
|
||||
avatar: {
|
||||
"@media (max-width: 600px)": {
|
||||
height: "24px",
|
||||
width: "24px"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
MuiDialog: {
|
||||
styleOverrides: {
|
||||
paperFullScreen: {
|
||||
overflowX: "hidden"
|
||||
},
|
||||
root: {
|
||||
// zIndex: 1500
|
||||
}
|
||||
},
|
||||
},
|
||||
MuiDrawer: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
zIndex: 1300
|
||||
}
|
||||
},
|
||||
},
|
||||
MuiSlider: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
height: 5
|
||||
},
|
||||
thumb: {
|
||||
height: 18,
|
||||
width: 18,
|
||||
marginTop: -6,
|
||||
marginLeft: -9,
|
||||
"&:focus,&:hover,&$active": {
|
||||
boxShadow: "inherit"
|
||||
}
|
||||
},
|
||||
active: {},
|
||||
valueLabel: {
|
||||
left: "calc(-50% + 2px)"
|
||||
},
|
||||
track: {
|
||||
height: 7,
|
||||
borderRadius: 4
|
||||
},
|
||||
rail: {
|
||||
height: 7,
|
||||
borderRadius: 4
|
||||
},
|
||||
vertical: {
|
||||
"& .MuiSlider-thumb": {
|
||||
marginLeft: "-8px !important"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
MuiStepper: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
background: "transparent"
|
||||
}
|
||||
},
|
||||
},
|
||||
MuiSwitch: {
|
||||
styleOverrides: {
|
||||
switchBase: {
|
||||
color: Colours.grey[400],
|
||||
"&$checked": {
|
||||
color: Colours.grey[100]
|
||||
},
|
||||
"&$checked + $track": {
|
||||
color: Colours.grey[100]
|
||||
}
|
||||
},
|
||||
checked: {},
|
||||
track: {}
|
||||
}
|
||||
},
|
||||
MuiButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& .MuiTouchRipple-root': {
|
||||
color: accent, // Customize ripple color here
|
||||
// color: "white"
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: "rgba(125, 125, 125, 0.2)",
|
||||
color: accent,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiListItemButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& .MuiTouchRipple-root': {
|
||||
color: highlight,
|
||||
},
|
||||
'&:hover': {
|
||||
color: highlight
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiCssBaseline: {
|
||||
styleOverrides: {
|
||||
body: {
|
||||
backgroundColor: bg, // Set your desired background color
|
||||
// color: '#333', // Optionally, you can also set the default text color
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiSvgIcon: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
// Set the default icon color for light mode
|
||||
// color: "black", // Dark color for icons in light mode
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiLink: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
color: 'inherit', // Default link color
|
||||
textDecoration: 'none', // Remove underline if desired
|
||||
'&:hover': {
|
||||
// color: 'red !important', // Your hover color
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiToggleButtonGroup: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderRadius: 25
|
||||
},
|
||||
middleButton: {
|
||||
borderRadius: 24,
|
||||
marginRight: 5,
|
||||
marginLeft: 5,
|
||||
},
|
||||
lastButton: {
|
||||
borderRadius: 24,
|
||||
},
|
||||
firstButton: {
|
||||
borderRadius: 24,
|
||||
},
|
||||
grouped: {
|
||||
border: "none",
|
||||
color: "gray"
|
||||
}
|
||||
}
|
||||
},
|
||||
// MuiToggleButton: {
|
||||
// styleOverrides: {
|
||||
// root: {
|
||||
// "&:hover": {
|
||||
// backgroundColor: getPrimaryColour(),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// MuiDataGrid: {
|
||||
// styleOverrides: {
|
||||
// root: {
|
||||
// backgroundColor: "black"
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
}
|
||||
} as unknown as ThemeOptions;
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
export type ThemeType = "light" | "dark";
|
||||
export type ThemeType = "light" | "dark" | "system";
|
||||
|
||||
export function getThemeType(): ThemeType {
|
||||
let theme = localStorage.getItem("theme");
|
||||
|
|
@ -8,3 +8,8 @@ export function getThemeType(): ThemeType {
|
|||
export function setThemeType(theme: ThemeType) {
|
||||
localStorage.setItem("theme", theme);
|
||||
}
|
||||
|
||||
export function getThemeMode(): ThemeType {
|
||||
let theme = localStorage.getItem("theme");
|
||||
return theme === "light" ? "light" : "dark";
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@ import { useNavigate } from "react-router-dom";
|
|||
import TeamDialog from "teams/TeamDialog";
|
||||
import AccessObject from "./AccessObject";
|
||||
import { useSnackbar, useUserAPI } from "hooks";
|
||||
import { useThemeMode } from "theme/AppThemeProvider";
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => ({
|
||||
accessIcon: {
|
||||
|
|
@ -73,13 +74,9 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
},
|
||||
}));
|
||||
|
||||
interface Props {
|
||||
toggleTheme: () => void;
|
||||
}
|
||||
export default function UserMenu() {
|
||||
|
||||
export default function UserMenu(props: Props) {
|
||||
|
||||
const { toggleTheme } = props;
|
||||
const { toggleMode } = useThemeMode()
|
||||
const [{ user, team, as }, dispatch] = useGlobalState();
|
||||
const { loginWithRedirect } = useAuth0();
|
||||
const classes = useStyles();
|
||||
|
|
@ -167,7 +164,7 @@ export default function UserMenu(props: Props) {
|
|||
)}
|
||||
</Button>
|
||||
|
||||
<IconButton onClick={toggleTheme} className={classes.rightIcon} aria-label="Toggle Theme">
|
||||
<IconButton onClick={/*toggleMode*/ () => {}} className={classes.rightIcon} aria-label="Toggle Theme">
|
||||
<ThemeIcon />
|
||||
</IconButton>
|
||||
</>
|
||||
|
|
@ -229,7 +226,7 @@ export default function UserMenu(props: Props) {
|
|||
</ListItemIcon>
|
||||
<ListItemText primary="User Settings" />
|
||||
</MenuItem>
|
||||
<MenuItem onClick={toggleTheme} aria-label="Toggle Theme" dense>
|
||||
<MenuItem onClick={toggleMode} aria-label="Toggle Theme" dense>
|
||||
<ListItemIcon>
|
||||
<ThemeIcon />
|
||||
</ListItemIcon>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue