如何为MUI DatePicker组件添加悬停及弹窗状态下的自定义样式
自定义MUI DatePicker悬停与弹窗打开时的样式需求
需求说明
- 悬停DatePicker组件时,将边框、标签文字、下拉图标的默认样式改为蓝色
- 日历弹窗打开时,将边框、标签、下拉图标颜色改为蓝色(当前为黑色)
状态截图
悬停状态

未悬停状态

日历弹窗打开状态

当前代码示例
import * as React from "react"; import dayjs from "dayjs"; import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; import { DesktopDatePicker } from "@mui/x-date-pickers/DesktopDatePicker"; import TextField from "@mui/material/TextField"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; export default function DatePickerValue() { const [value, setValue] = React.useState(null); const openCalendar = () => { console.log("hello"); }; return ( <LocalizationProvider dateAdapter={AdapterDayjs}> <DesktopDatePicker label="Date" value={value} onChange={(newValue) => { console.log("newValue", newValue); setValue(newValue); }} renderInput={(params) => ( <TextField {...params} onClick={openCalendar} /> )} InputProps={{ endAdornment: ( <div> <ExpandMoreIcon /> </div> ) }} components={{ OpenPickerIcon: ExpandMoreIcon }} componentsProps={{ actionBar: { actions: ["clear"], style: { justifyContent: "flex-start" } } }} /> </LocalizationProvider> ); }
解决方案
DatePicker的输入区域基于MUI的TextField组件实现,我们可以通过覆盖TextField的悬停和聚焦(弹窗打开时的状态)样式来实现需求,以下是两种实现方式:
方式一:直接使用sx属性修改样式
在renderInput的TextField中添加sx属性,针对悬停和聚焦状态分别设置样式:
renderInput={(params) => ( <TextField {...params} onClick={openCalendar} sx={{ // 悬停状态样式 '&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'blue', }, '&:hover .MuiInputLabel-root': { color: 'blue', }, '&:hover .MuiSvgIcon-root': { color: 'blue', }, // 弹窗打开(聚焦)状态样式 '&.Mui-focused .MuiOutlinedInput-notchedOutline': { borderColor: 'blue', }, '&.Mui-focused .MuiInputLabel-root': { color: 'blue', }, '&.Mui-focused .MuiSvgIcon-root': { color: 'blue', }, }} /> )}
方式二:创建自定义TextField组件复用样式
如果需要在多个地方复用该样式,可以使用styled组件创建自定义TextField:
import { styled } from '@mui/material/styles'; const StyledTextField = styled(TextField)(({ theme }) => ({ '&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'blue', }, '&:hover .MuiInputLabel-root': { color: 'blue', }, '&:hover .MuiSvgIcon-root': { color: 'blue', }, '&.Mui-focused .MuiOutlinedInput-notchedOutline': { borderColor: 'blue', }, '&.Mui-focused .MuiInputLabel-root': { color: 'blue', }, '&.Mui-focused .MuiSvgIcon-root': { color: 'blue', }, })); // 调用时替换原TextField renderInput={(params) => ( <StyledTextField {...params} onClick={openCalendar} /> )}
完整修改后的代码
import * as React from "react"; import dayjs from "dayjs"; import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; import { DesktopDatePicker } from "@mui/x-date-pickers/DesktopDatePicker"; import TextField from "@mui/material/TextField"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; export default function DatePickerValue() { const [value, setValue] = React.useState(null); const openCalendar = () => { console.log("hello"); }; return ( <LocalizationProvider dateAdapter={AdapterDayjs}> <DesktopDatePicker label="Date" value={value} onChange={(newValue) => { console.log("newValue", newValue); setValue(newValue); }} renderInput={(params) => ( <TextField {...params} onClick={openCalendar} sx={{ '&:hover .MuiOutlinedInput-notchedOutline': { borderColor: 'blue', }, '&:hover .MuiInputLabel-root': { color: 'blue', }, '&:hover .MuiSvgIcon-root': { color: 'blue', }, '&.Mui-focused .MuiOutlinedInput-notchedOutline': { borderColor: 'blue', }, '&.Mui-focused .MuiInputLabel-root': { color: 'blue', }, '&.Mui-focused .MuiSvgIcon-root': { color: 'blue', }, }} /> )} components={{ OpenPickerIcon: ExpandMoreIcon }} componentsProps={{ actionBar: { actions: ["clear"], style: { justifyContent: "flex-start" } } }} /> </LocalizationProvider> ); }
内容的提问来源于stack exchange,提问作者Happy1234
相关产品推荐
相关产品推荐

