如何让Material UI数字TextField的微调按钮显示深色?能否通过主题配置?
问题:Material UI数字TextField微调按钮未应用自定义主题颜色
我在使用Material UI创建数字类型的TextField时,发现微调按钮的颜色并未应用我的自定义主题。
官方示例代码
<TextField id="outlined-number" label="Number" type="number" InputLabelProps={{ shrink: true, }} />

我的项目效果截图

可复现代码
App.js
import React from 'react'; import darkTheme, {lightTheme, ThemeContext} from "./ThemeUtil"; import {Box, CssBaseline, TextField, ThemeProvider} from "@mui/material"; function App() { const initialTheme = localStorage.getItem('theme') === 'light' ? lightTheme : darkTheme; const [theme, setTheme] = React.useState(initialTheme); const toggleTheme = () => { setTheme(prevTheme => { const newTheme = prevTheme === darkTheme ? lightTheme : darkTheme localStorage.setItem('theme', newTheme === darkTheme ? 'dark' : 'light'); return newTheme; }); } return ( <ThemeContext.Provider value={{theme, toggleTheme}}> <ThemeProvider theme={theme}> <CssBaseline/> <Box className={"TestAppContainer"} sx={{display: "flex", justifyContent: "center", alignItems: "center", width: "100vw", height: "100vh"}}> <TextField label="Number" type="number" InputLabelProps={{ shrink: true, }} /> </Box> </ThemeProvider> </ThemeContext.Provider> ); } export default App;
ThemeUtil.js
import React from "react"; import {createTheme} from '@mui/material/styles'; const darkTheme = createTheme({ palette: { mode: "dark", }, typography: { fontSize: 16, }, }); const lightTheme = createTheme({ palette: { mode: "light", }, typography: { fontSize: 16, }, }); const ThemeContext = React.createContext({ theme: darkTheme, toggleTheme: () => { } }); export default darkTheme; export {lightTheme, ThemeContext};
请问如何让微调按钮显示深色(与Material UI官网示例一致)?能否通过修改主题来指定该颜色?
解决方案
数字输入框的微调按钮属于原生input元素的样式,Material UI默认不会完全覆盖原生样式,你可以通过以下几种方式修改:
方法一:通过自定义主题全局修改
可以在主题配置中统一设置所有数字输入框的微调按钮样式,适配明暗主题:
修改ThemeUtil.js中的主题配置,添加components字段:
const darkTheme = createTheme({ palette: { mode: "dark", }, typography: { fontSize: 16, }, components: { MuiInput: { styleOverrides: { input: { // 适配WebKit内核浏览器(Chrome、Edge等) '&::-webkit-inner-spin-button, &::-webkit-outer-spin-button': { color: '#fff', // 深色主题下使用白色,也可替换为theme.palette.text.primary }, // 隐藏Firefox默认微调按钮(可选,如需自定义Firefox样式需额外处理) '&[type=number]': { MozAppearance: 'textfield', } } } } } }); const lightTheme = createTheme({ palette: { mode: "light", }, typography: { fontSize: 16, }, components: { MuiInput: { styleOverrides: { input: { '&::-webkit-inner-spin-button, &::-webkit-outer-spin-button': { color: '#000', // 浅色主题下使用黑色 }, '&[type=number]': { MozAppearance: 'textfield', } } } } } });
方法二:针对单个TextField自定义样式
如果只需要修改某个特定TextField的微调按钮,直接通过sx属性添加样式即可,还能自动适配当前主题:
<TextField label="Number" type="number" InputLabelProps={{ shrink: true, }} sx={{ '& input::-webkit-inner-spin-button, & input::-webkit-outer-spin-button': { color: theme => theme.palette.text.primary, // 直接引用主题文本主色,自动适配明暗模式 }, '& input[type=number]': { MozAppearance: 'textfield', } }} />
方法三:隐藏原生按钮,自定义样式(进阶)
如果对原生按钮样式不满意,也可以隐藏原生按钮后,用Material UI的IconButton等组件自定义微调按钮:
import {TextField, InputAdornment, IconButton} from '@mui/material'; import AddIcon from '@mui/icons-material/Add'; import RemoveIcon from '@mui/icons-material/Remove'; // 在组件中使用 const [value, setValue] = React.useState(''); <TextField label="Number" value={value} onChange={(e) => setValue(e.target.value)} InputProps={{ type: 'text', // 改为text类型隐藏原生按钮 endAdornment: ( <InputAdornment position="end"> <IconButton size="small" onClick={() => setValue(prev => (Number(prev) + 1).toString())}> <AddIcon /> </IconButton> <IconButton size="small" onClick={() => setValue(prev => (Number(prev) - 1).toString())}> <RemoveIcon /> </IconButton> </InputAdornment> ) }} InputLabelProps={{ shrink: true, }} />
内容的提问来源于stack exchange,提问作者MoreFoam
相关产品推荐
相关产品推荐

