You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为MUI DateCalendar设置间隔日期的样式?

为MUI DateCalendar设置间隔日期样式

要实现间隔日期(选中起始和结束日期之间的所有日期)的样式定制,你需要调整状态管理逻辑,并通过slotProps.day的回调判断日期是否处于目标区间,进而应用自定义样式。以下是具体实现步骤:

1. 调整状态与选择逻辑

将单一选中日期的状态改为起始日期和结束日期,同时修改点击事件处理区间选择逻辑:

import { useState } from 'react';
import dayjs from 'dayjs';
import { Box, LocalizationProvider } from '@mui/material';
import { DateCalendar } from '@mui/x-date-pickers/DateCalendar';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';

export default function CalendarComp() {
  // 维护起始和结束日期状态
  const [selectedRange, setSelectedRange] = useState({
    start: null,
    end: null,
  });

  function handleDateClick(date) {
    const { start, end } = selectedRange;
    // 区间选择逻辑:未选起始则设为起始;已选起始且点击日期在起始之后则设为结束;否则重置起始
    if (!start) {
      setSelectedRange({ start: date, end: null });
    } else if (!end && date.isAfter(start)) {
      setSelectedRange({ start, end: date });
    } else {
      setSelectedRange({ start: date, end: null });
    }
  }

  return (
    <Box
      sx={{
        height: 340,
        width: 340,
        backgroundColor: "secondary.main",
      }}
    >
      <LocalizationProvider dateAdapter={AdapterDayjs}>
        <DateCalendar
          value={selectedRange.start || dayjs()}
          onChange={handleDateClick}
          disableHighlightToday={true}
          slotProps={{
            day: ({ date }) => {
              const { start, end } = selectedRange;
              // 判断当前日期是否处于选中区间内
              const isInRange = start && end && date.isAfter(start) && date.isBefore(end);
              // 判断是否是起始/结束日期
              const isStart = start && date.isSame(start, 'day');
              const isEnd = end && date.isSame(end, 'day');

              return {
                sx: {
                  // 区间内日期的背景样式
                  ...(isInRange && {
                    backgroundColor: 'rgba(25, 118, 210, 0.2)',
                    borderRadius: 0,
                  }),
                  // 起始日期的左侧圆角样式
                  ...(isStart && {
                    backgroundColor: '#1976d2',
                    color: 'white',
                    borderTopLeftRadius: '50%',
                    borderBottomLeftRadius: '50%',
                  }),
                  // 结束日期的右侧圆角样式
                  ...(isEnd && {
                    backgroundColor: '#1976d2',
                    color: 'white',
                    borderTopRightRadius: '50%',
                    borderBottomRightRadius: '50%',
                  }),
                  // 鼠标悬停样式
                  '&:hover': {
                    backgroundColor: isInRange ? 'rgba(25, 118, 210, 0.3)' : 'rgba(0, 0, 0, 0.04)',
                  },
                },
              };
            },
          }}
        />
      </LocalizationProvider>
    </Box>
  );
}

2. 关键逻辑说明

  • 状态管理:用selectedRange对象维护起始和结束日期,支撑区间选择的基础逻辑。
  • 日期判断:借助dayjs的isAfter、isBefore、isSame方法,识别当前渲染日期的状态(区间内、起始、结束)。
  • 样式定制:在slotProps.day的回调中,根据日期状态分别设置背景色、圆角等样式,实现区间选择的视觉效果。

3. 扩展说明

如果需要支持点击取消选中、跨月份区间样式等复杂逻辑,可以在handleDateClick中补充对应判断;样式部分也可根据需求调整颜色、透明度,或使用MUI主题变量(如theme.palette.primary.main)保持风格统一。

内容的提问来源于stack exchange,提问作者Brenden Baio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 20:50:10