发布于 2026-01-06 1 阅读
0

带有自定义样式的 ReactCalendar

带有自定义样式的 ReactCalendar

我一直在寻找一款可以在 React 项目中使用的日历组件,然后找到了React-Calendar组件。它具备我需要的所有功能,而且省去了我自己开发的时间。它可以通过状态进行控制,因此选定的日期可以影响应用程序中的显示内容。我想自定义它的样式以适应我的项目,所以就有了现在的成果!

这里的示例基于以下组件:

  • react(版本 17.0.2)
  • react-calendar(版本 3.5.0)
  • styled-components(版本 5.3.3)

初始样式

我将使用styled-components包为我的项目添加样式,但如果您更喜欢这种方式,也可以在 CSS 文件中完成所有操作。以下是我的初始代码:



import Calendar from 'react-calendar';
import styled from 'styled-components';

function App() {
  return (
    <CalendarContainer>
      <Calendar calendarType='US' />
    </CalendarContainer>
  );
}

export default App;

const CalendarContainer = styled.div`
  /* ~~~ container styles ~~~ */
  max-width: 600px;
  margin: auto;
  margin-top: 20px;
  background-color: #d4f7d4;
  padding: 10px;
  border-radius: 3px;
`;


Enter fullscreen mode Exit fullscreen mode

我已经开始设计一些用于<div>放置日历的样式,这样日历就不会显得空荡荡的了。

注:我还给calendarType日历应用了将一周的第一天设置为星期日的属性。这是我习惯看到的日历格式,但如果禁用此属性,一周应该从星期一开始。

这是组件在应用任何样式之前的样子<Calendar />

没有样式的 React-Calendar

你可以看到这个组件是由很多按钮组件构成的。在应用我们自己的样式之前,让我们先看一下组件自带的样式表。

默认样式表

react-calendar 组件可以选择导入默认样式表。您可以通过在文件顶部添加以下代码行来导入它:



import 'react-calendar/dist/Calendar.css';


Enter fullscreen mode Exit fullscreen mode

以下是应用这些样式后的日历样式:

React-Calendar 默认样式

看起来好多了!不过,我希望它能完全按照我的想法来设计,完全掌控它的外观。这样我才能确保它的外观与我的应用程序其他部分保持一致。幸运的是,我们可以添加自定义样式!

定制造型

由于 styled-components 可以像 SCSS 一样嵌套选择器,我们可以将所有自定义样式添加到CalendarContainerstyled-components 中。React-Calendar 创建的元素已经应用了某些特定的类,因此我们可以使用这些类作为选择器。

导航

我们先来更新导航。我想做的是:

  • 让导航栏占据日历的整个宽度。
  • 将中间按钮中的文字加粗。
  • 把箭头按钮放大

以下是具体做法:



const CalendarContainer = styled.div`
  /* ~~~ container styles ~~~ */
  /* ... */

  /* ~~~ navigation styles ~~~ */
  .react-calendar__navigation {
    display: flex;

    .react-calendar__navigation__label {
      font-weight: bold;
    }

    .react-calendar__navigation__arrow {
      flex-grow: 0.333;
    }
  }
`;


Enter fullscreen mode Exit fullscreen mode

React-Calendar 导航样式

标签

接下来,我想把星期几的标签居中显示:



const CalendarContainer = styled.div`
  /* ~~~ container styles ~~~ */
  /* ~~~ navigation styles ~~~ */
  /* ... */

  /* ~~~ label styles ~~~ */
  .react-calendar__month-view__weekdays {
    text-align: center;
  }
`;


Enter fullscreen mode Exit fullscreen mode

React-Calendar 带标签样式

按钮

布局看起来不错,但我们还需要给按钮添加一些样式:



const CalendarContainer = styled.div`
  /* ~~~ container styles ~~~ */
  /* ~~~ navigation styles ~~~ */
  /* ~~~ label styles ~~~ */
  /* ... */

  /* ~~~ button styles ~~~ */
  button {
    margin: 3px;
    background-color: #6f876f;
    border: 0;
    border-radius: 3px;
    color: white;
    padding: 5px 0;

    &:hover {
      background-color: #556b55;
    }

    &:active {
      background-color: #a5c1a5;
    }
  }
`;


Enter fullscreen mode Exit fullscreen mode

React-Calendar 带按钮样式

按钮看起来好多了,但是布局完全乱了!现在才连续六天,我们得赶紧解决这个问题!

网格

因此,默认情况下视图会display: flex;应用样式,但这会导致项目溢出到其他行,而不是确保一周始终有 7 天。幸运的是,我们可以使用以下方法覆盖此行为grid



const CalendarContainer = styled.div`
  /* ~~~ container styles ~~~ */
  /* ~~~ navigation styles ~~~ */
  /* ~~~ label styles ~~~ */
  /* ~~~ button styles ~~~ */
  /* ... */

  /* ~~~ day grid styles ~~~ */
  .react-calendar__month-view__days {
    display: grid !important;
    grid-template-columns: 14.2% 14.2% 14.2% 14.2% 14.2% 14.2% 14.2%; 

    .react-calendar__tile {
      max-width: initial !important;
    }
  }
`;


Enter fullscreen mode Exit fullscreen mode

React-Calendar 网格显示

太棒了,通过创建一个包含七列(每列占 14.2%)的网格,我们又回到了每周七天!

请注意,react-calendar 创建的某些元素会直接应用样式。要覆盖这些样式,我们需要添加规则,!important以便我们的类选择器能够优先生效。

相邻的月份和周末

目前相邻月份的日期看起来与当前月份的日期完全相同,但我们可以更改这一点。我们还可以更改周末的日期样式。



const CalendarContainer = styled.div`
  /* ~~~ container styles ~~~ */
  /* ~~~ navigation styles ~~~ */
  /* ~~~ label styles ~~~ */
  /* ~~~ button styles ~~~ */
  /* ~~~ day grid styles ~~~ */
  /* ... */

  /* ~~~ neighboring month & weekend styles ~~~ */
  .react-calendar__month-view__days__day--neighboringMonth {
    opacity: 0.7;
  }
  .react-calendar__month-view__days__day--weekend {
    color: #dfdfdf;
  }
`;


Enter fullscreen mode Exit fullscreen mode

React-Calendar,带有相邻月份和周末日期的样式

活力日

使用 React-Calendar 时,当用户点击某一天时,该日期会被设置为当前活动日期。然而,用户目前还无法得知当前选中的是哪一天,所以我们现在就来解决这个问题:



const CalendarContainer = styled.div`
  /* ~~~ container styles ~~~ */
  /* ~~~ navigation styles ~~~ */
  /* ~~~ label styles ~~~ */
  /* ~~~ button styles ~~~ */
  /* ~~~ day grid styles ~~~ */
  /* ~~~ neighboring month & weekend styles ~~~ */
  /* ... */

  /* ~~~ active day styles ~~~ */
  .react-calendar__tile--range {
      box-shadow: 0 0 6px 2px black;
  }
`;


Enter fullscreen mode Exit fullscreen mode

React-Calendar 带有活动日样式

其他观点

月度视图看起来不错,但其他视图呢?让我们来看看年视图:

React-Calendar 年视图样式化之前

因此,年份视图需要改进。由于我们为按钮添加了自定义样式,一些按钮被推到了下一行。十年视图和世纪视图也存在类似的问题。幸运的是,我们可以像之前一样使用网格布局来解决这个问题grid。我们将以 3 列 4 行的网格布局显示月份列表。十年视图和世纪视图中的 10 个按钮将以 5 列 2 行的网格布局显示。



const CalendarContainer = styled.div`
  /* ~~~ container styles ~~~ */
  /* ~~~ navigation styles ~~~ */
  /* ~~~ label styles ~~~ */
  /* ~~~ button styles ~~~ */
  /* ~~~ day grid styles ~~~ */
  /* ~~~ neighboring month & weekend styles ~~~ */
  /* ~~~ active day styles ~~~ */
  /* ... */

  /* ~~~ other view styles ~~~ */
  .react-calendar__year-view__months, 
  .react-calendar__decade-view__years, 
  .react-calendar__century-view__decades {
    display: grid !important;
    grid-template-columns: 20% 20% 20% 20% 20%;

    &.react-calendar__year-view__months {
      grid-template-columns: 33.3% 33.3% 33.3%;
    }

    .react-calendar__tile {
      max-width: initial !important;
    }
  }
`;


Enter fullscreen mode Exit fullscreen mode

React-Calendar 年视图样式化后

好了!一个借助 styled-components 进行样式设计的 React-Calendar 组件就完成了。

结论

修改 React-Calendar 组件的样式非常简单,你只需要知道该使用哪些类选择器。我在这里提供的样式只是其中一种方法。一旦所有选择器和样式都设置好,你就可以更轻松地进行尝试,并确定哪种样式最适合你的项目。

如果您想与本文所用的应用程序进行交互,该应用程序已在GitHub上发布。所有样式应用所在的文件可以在这里找到。

我在目前正在开发的一个应用中也对这个组件应用了非常类似的样式,如果您感兴趣,也可以在这里查看。该应用仍在开发中,您需要注册才能查看日历,以下是它目前的屏幕截图:

AppliTracker 日历演示

感谢阅读!

文章来源:https://dev.to/fitzgeraldkd/react-calendar-with-custom-styles-30c9