我正在尝试在我的应用程序中引入主题切换器。我有很多非材料用户界面元素,我需要主题来反映它们的变化。
下面的代码显示我有一个称为darkState
的状态,该状态设置为true
。我的应用程序中的主要ui组件反映了这些更改,但是例如下面的div
并未获得深色主题的深色。我在这里做错什么了?
import React, { useState } from "react";
import Header from "./components/Header.js";
import TopBar from "./components/TopBar.js";
import Sequence from "./components/Sequence.js";
import SecondaryWindow from "./components/SecondaryWindow.js";
import { MuiThemeProvider, createMuiTheme, makeStyles } from "@material-ui/core/styles";
import "./App.css";
import { MainContextProvider } from "./contexts/mainContext.js";
function App() {
const [darkState, setDarkState] = useState(true);
const palletType = darkState ? "dark" : "light";
const theme = createMuiTheme({
palette: {
secondary: {
main: "#0069ff",
},
type: palletType,
},
});
const useStyles = makeStyles((theme) => ({
root: {
paddingLeft: 80,
height: "100%",
backgroundColor: theme.palette.background.default,
},
}));
const classes = useStyles();
return (
<MuiThemeProvider theme={theme}>
<MainContextProvider>
<div className={classes.root}>
<Header />
<TopBar />
<Sequence />
<SecondaryWindow />
</div>
</MainContextProvider>
</MuiThemeProvider>
);
}
export default App;
答案 0 :(得分:1)
这是因为仅更改@material组件而不更改CSS,要更改CSS主题,您需要为Dark Theme的CSS变量。
在:root
上声明所有浅色主题颜色,在div.darkmode
上声明所有暗色模式:
:root {
--color-bg: #fff;
--color-text: #000;
}
.div.darkmode {
--color-bg: #363636;
--color-text: #d1d1d1;
}
/** Usage */
.div {
color: var(--color-text);
background: var(--color-bg)
}
并在黑暗主题为真时在div
上创建条件,就像您在上面编写的那样,将添加一个新的类名darkmode
进行潜水
<div className={`${classes.root} ${darkState && `darkmode`}`}>
<Header />
<TopBar />
<Sequence />
<SecondaryWindow />
</div>
我创建了an example for you here。 让我们知道是否有任何问题!
如果您没有按CSS
文件进行任何客户样式设置,则可以使用
import React from 'react';
import CssBaseline from '@material-ui/core/CssBaseline';
export default function MyApp() {
return (
<MuiThemeProvider theme={theme}>
<CssBaseline />
{/* The rest of your application */}
</MuiThemeProvider>
);
}
答案 1 :(得分:1)
现在我知道了答案,在我的示例中,类root
无法从theme
提供的自定义创建的MuiThemeProvider
中受益。而是使用Mui随附的原始theme
。为了解决这个问题,我将div
分成了一个组件。这样,theme
可以访问div
上下文(来自MuiThemeProvider的自定义主题)。这样,当我切换DarkState
时,颜色会基于自定义主题调色板在Mui组件和HTML元素上更新。
import React, { useContext, useState } from "react";
import Header from "./components/Header.js";
import TopBar from "./components/TopBar.js";
import Sequence from "./components/Sequence.js";
import SecondaryWindow from "./components/SecondaryWindow.js";
import { MuiThemeProvider, createMuiTheme, makeStyles } from "@material-ui/core/styles";
import "./App.css";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import { MainContextProvider } from "./contexts/mainContext.js";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
function AppContent() {
const useStyles = makeStyles((theme) => ({
root: {
paddingLeft: 80,
height: "100%",
backgroundColor: theme.palette.background.default,
},
}));
const classes = useStyles();
return (
<div className={classes.root}>
<Header />
<TopBar />
<Sequence />
<SecondaryWindow />
</div>
);
}
function App() {
const [darkState, setDarkState] = useState(true);
const palletType = darkState ? "dark" : "light";
const theme = createMuiTheme({
palette: {
secondary: {
main: "#0069ff",
},
type: palletType,
},
});
return (
<MuiThemeProvider theme={theme}>
<MainContextProvider>
<AppContent />
</MainContextProvider>
</MuiThemeProvider>
);
}
export default App;
答案 2 :(得分:0)
我将主题的两个变体都声明为安装或渲染之上的常量。这样,您每次交换主题时就不会真正创建新主题。我会有一个状态,保持对MUI-Theme常量的引用。
答案 3 :(得分:0)
您可以操纵data-theme
属性来切换暗/亮主题。在 StackBlitz 上尝试。
使用data-theme
属性设置所选主题。
/* default theme (light) */
:root {
--primary-color: #302ae6;
--secondary-color: #536390;
--font-color: #424242;
--bg-color: #fff;
}
/* dark theme */
[data-theme='dark'] {
--primary-color: #9a97f3;
--secondary-color: #818cab;
--font-color: #e1e1ff;
--bg-color: #161625;
}
// App.js
const [theme, setTheme] = useState({
light: true,
});
const handleChangeTheme = (event) => {
setTheme({ ...theme, [event.target.name]: event.target.checked });
};
相应地设置我们的data-theme
属性
const currentTheme = theme.light === true ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', currentTheme);