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

求助:在MUI X StaticDatePicker中高亮日期并禁用过去日期

解决方案:MUI X StaticDatePicker 高亮指定日期+禁用过去日期

你的代码存在两个核心问题导致renderDay函数不执行、高亮功能失效:

  • 初始value为字符串类型,不符合StaticDatePicker要求的dayjs对象格式,导致组件状态异常,自定义渲染逻辑不触发
  • 缺少禁用过去日期的逻辑实现

关键修改说明:

  1. 修正初始值类型:将useState("")改为useState(dayjs()),确保组件接收合法的日期对象,触发renderDay正常执行
  2. 优化日期高亮:调整renderDay中的日期匹配逻辑,使用Badge实现蓝色圆圈高亮效果,替换原有的"-"为空白内容,更符合视觉需求
  3. 添加禁用过去日期:新增shouldDisableDay属性,通过dayjs的isBefore方法判断并禁用当前日期之前的所有日期

修复后的完整代码:

import { React, useState } from "react";
import dayjs from "dayjs";
import { Box, TextField, Badge } from "@mui/material";
import { Loading } from "../pages/index.mjs";
import { EventCard } from "./index.mjs";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { StaticDatePicker } from "@mui/x-date-pickers/StaticDatePicker";
import { useReadAllEvent } from "../hooks/useEvent.mjs";
import { PickersDay } from "@mui/x-date-pickers";

const SessionBooking = ({ doctor }) => {
  // 修改:初始值改为dayjs对象,而非字符串
  const [value, setValue] = useState(dayjs());

  const [highlightDays, setHighlightDays] = useState([
    "2023-06-01",
    "2023-06-02",
    "2023-06-04",
  ]);

  const { data: eventSet, isLoading } = useReadAllEvent({
    onSuccess: (message) => {},
    onError: (message) => {},
    session: { id: doctor, today: dayjs().format("YYYY-MM-DD") },
  });

  if (isLoading) return <Loading />;

  const events = eventSet.map(
    ({ key, countPatient, start, end, maxPatients }) => (
      <EventCard
        key={key}
        started={start}
        ended={end}
        patients={countPatient}
        max={maxPatients}
      />
    )
  );

  // 新增:判断是否禁用日期的函数
  const shouldDisableDay = (day) => {
    // 禁用当前日期之前的所有日期(仅比较日期,忽略时间)
    return day.isBefore(dayjs().startOf("day"));
  };

  return (
    <Box
      mt={2}
      sx={{
        display: "grid",
        gridTemplateColumns: {
          xs: "repeat(1, 1fr)",
          sm: "repeat(1, 1fr)",
          md: "repeat(2, 1fr)",
        },
        gap: 1,
      }}
    >
      <Box>
        <LocalizationProvider dateAdapter={AdapterDayjs}>
          <StaticDatePicker
            orientation="portrait"
            openTo="day"
            value={value}
            onChange={(newValue) => {
              setValue(newValue);
            }}
            renderInput={(params) => <TextField {...params} />}
            // 新增:禁用过去日期
            shouldDisableDay={shouldDisableDay}
            // 优化:修复renderDay逻辑,确保执行
            renderDay={(day, _value, DayComponentProps) => {
              const formattedDay = day.format("YYYY-MM-DD");
              const isHighlighted = !DayComponentProps.outsideCurrentMonth && highlightDays.includes(formattedDay);

              return (
                <Badge
                  key={formattedDay}
                  overlap="circular"
                  // 空白内容实现蓝色圆圈高亮,若需要圆点可改为"•"
                  badgeContent={isHighlighted ? "" : undefined}
                  color="primary"
                  sx={{
                    // 调整Badge大小,适配日期单元格
                    "& .MuiBadge-badge": {
                      width: 8,
                      height: 8,
                      borderRadius: "50%",
                      top: 1,
                      right: 1,
                    },
                  }}
                >
                  <PickersDay {...DayComponentProps} />
                </Badge>
              );
            }}
          />
        </LocalizationProvider>
      </Box>

      <Box>{events}</Box>
    </Box>
  );
};

export default SessionBooking;

内容的提问来源于stack exchange,提问作者Isuru Akalanka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 10:37:52