如何使用MUI DateCalendar组件实现多日期视觉高亮?
解决MUI DateCalendar多日期高亮问题
你之前用:nth-of-type(1)的方式无法实现目标,因为这个选择器是按DOM节点的位置匹配元素,会把每一行的第一个日期都统一应用样式,不是基于具体日期的高亮。要实现指定多个日期高亮,得通过判断日期本身来设置样式,下面是两种可行方案:
方案1:通过day插槽的自定义渲染函数
先定义要高亮的日期数组,然后在slotProps.day.render里判断当前日期是否在高亮数组中,自定义单元格样式:
import { DateCalendar, LocalizationProvider, Day } from '@mui/x-date-pickers'; import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; import ptBR from 'date-fns/locale/pt-BR'; // 定义需要高亮的日期(注意月份是0基,比如5月对应4) const highlightedDates = [ new Date(2024, 4, 5), new Date(2024, 4, 10), new Date(2024, 4, 15) ]; // 日期比较工具函数,判断两个日期是否为同一天 const isSameDay = (dateA, dateB) => { return dateA.getDate() === dateB.getDate() && dateA.getMonth() === dateB.getMonth() && dateA.getFullYear() === dateB.getFullYear(); }; // 组件代码 <LocalizationProvider dateFormats={{ monthAndYear: "MMMMMMMMM" }} dateAdapter={AdapterDateFns} adapterLocale={ptBR} > <DateCalendar dayOfWeekFormatter={dayOfWeekFormatter} disableHighlightToday views={['day']} className={styles.teste} showDaysOutsideCurrentMonth={false} value={new Date()} fixedWeekNumber={0} referenceDate={new Date(currentDate.getFullYear(), 1, 1)} slotProps={{ day: ({ day, selected, disabled, ...other }) => { const shouldHighlight = highlightedDates.some(date => isSameDay(date, day)); return ( <Day {...other} selected={selected || shouldHighlight} disabled={disabled} sx={{ ...(shouldHighlight && { backgroundColor: '#1976d2', color: '#fff', fontWeight: 500 }) }} /> ); } }} /> </LocalizationProvider>
方案2:通过sx的回调函数动态设置样式
如果不想自定义单元格渲染,也可以直接在slotProps.day.sx里用回调函数,接收当前日期作为参数,动态判断是否应用高亮样式:
import { DateCalendar, LocalizationProvider } from '@mui/x-date-pickers'; import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; import ptBR from 'date-fns/locale/pt-BR'; const highlightedDates = [ new Date(2024, 4, 5), new Date(2024, 4, 10), new Date(2024, 4, 15) ]; const isSameDay = (dateA, dateB) => { return dateA.getDate() === dateB.getDate() && dateA.getMonth() === dateB.getMonth() && dateA.getFullYear() === dateB.getFullYear(); }; <LocalizationProvider dateFormats={{ monthAndYear: "MMMMMMMMM" }} dateAdapter={AdapterDateFns} adapterLocale={ptBR} > <DateCalendar dayOfWeekFormatter={dayOfWeekFormatter} disableHighlightToday views={['day']} className={styles.teste} showDaysOutsideCurrentMonth={false} value={new Date()} fixedWeekNumber={0} referenceDate={new Date(currentDate.getFullYear(), 1, 1)} slotProps={{ day: { sx: ({ day }) => { const shouldHighlight = highlightedDates.some(date => isSameDay(date, day)); return { ...(shouldHighlight && { color: '#fff', backgroundColor: '#1976d2', fontWeight: 500 }) }; } } }} /> </LocalizationProvider>
这两种方案都是基于日期本身做判断,只会给你指定的日期应用高亮样式,不会出现全局统一样式的问题。
内容的提问来源于stack exchange,提问作者Marcos Oliveira
相关产品推荐
相关产品推荐

