Calendar日历

按照日历形式展示数据的容器。

何时使用#

当数据是日期或按照日期划分时,例如日程、课表、价格日历等,农历等。目前支持年/月切换。

代码演示

2022年
7月
27
28
29
30
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
01
02
03
04
05
06
07

一个通用的日历面板,支持年/月切换。

expand codeexpand code
import { Calendar } from 'infrad';
import type { CalendarMode } from 'infrad/lib/calendar/generateCalendar';
import type { Moment } from 'moment';
import React from 'react';

const App: React.FC = () => {
  const onPanelChange = (value: Moment, mode: CalendarMode) => {
    console.log(value.format('YYYY-MM-DD'), mode);
  };

  return <Calendar onPanelChange={onPanelChange} />;
};

export default App;
2022年
7月
27
    28
      29
        30
          01
            02
              03
                04
                  05
                    06
                      07
                        08
                        • This is warning event.
                        • This is usual event.
                        09
                          10
                          • This is warning event.
                          • This is usual event.
                          • This is error event.
                          11
                            12
                              13
                                14
                                  15
                                  • This is warning event
                                  • This is very long usual event。。....
                                  • This is error event 1.
                                  • This is error event 2.
                                  • This is error event 3.
                                  • This is error event 4.
                                  16
                                    17
                                      18
                                        19
                                          20
                                            21
                                              22
                                                23
                                                  24
                                                    25
                                                      26
                                                        27
                                                          28
                                                            29
                                                              30
                                                                31
                                                                  01
                                                                    02
                                                                      03
                                                                        04
                                                                          05
                                                                            06
                                                                              07

                                                                                一个复杂的应用示例,用 dateCellRendermonthCellRender 函数来自定义需要渲染的数据。

                                                                                expand codeexpand code
                                                                                import type { BadgeProps } from 'infrad';
                                                                                import { Badge, Calendar } from 'infrad';
                                                                                import type { Moment } from 'moment';
                                                                                import React from 'react';
                                                                                
                                                                                const getListData = (value: Moment) => {
                                                                                  let listData;
                                                                                  switch (value.date()) {
                                                                                    case 8:
                                                                                      listData = [
                                                                                        { type: 'warning', content: 'This is warning event.' },
                                                                                        { type: 'success', content: 'This is usual event.' },
                                                                                      ];
                                                                                      break;
                                                                                    case 10:
                                                                                      listData = [
                                                                                        { type: 'warning', content: 'This is warning event.' },
                                                                                        { type: 'success', content: 'This is usual event.' },
                                                                                        { type: 'error', content: 'This is error event.' },
                                                                                      ];
                                                                                      break;
                                                                                    case 15:
                                                                                      listData = [
                                                                                        { type: 'warning', content: 'This is warning event' },
                                                                                        { type: 'success', content: 'This is very long usual event。。....' },
                                                                                        { type: 'error', content: 'This is error event 1.' },
                                                                                        { type: 'error', content: 'This is error event 2.' },
                                                                                        { type: 'error', content: 'This is error event 3.' },
                                                                                        { type: 'error', content: 'This is error event 4.' },
                                                                                      ];
                                                                                      break;
                                                                                    default:
                                                                                  }
                                                                                  return listData || [];
                                                                                };
                                                                                
                                                                                const getMonthData = (value: Moment) => {
                                                                                  if (value.month() === 8) {
                                                                                    return 1394;
                                                                                  }
                                                                                };
                                                                                
                                                                                const App: React.FC = () => {
                                                                                  const monthCellRender = (value: Moment) => {
                                                                                    const num = getMonthData(value);
                                                                                    return num ? (
                                                                                      <div className="notes-month">
                                                                                        <section>{num}</section>
                                                                                        <span>Backlog number</span>
                                                                                      </div>
                                                                                    ) : null;
                                                                                  };
                                                                                
                                                                                  const dateCellRender = (value: Moment) => {
                                                                                    const listData = getListData(value);
                                                                                    return (
                                                                                      <ul className="events">
                                                                                        {listData.map(item => (
                                                                                          <li key={item.content}>
                                                                                            <Badge status={item.type as BadgeProps['status']} text={item.content} />
                                                                                          </li>
                                                                                        ))}
                                                                                      </ul>
                                                                                    );
                                                                                  };
                                                                                
                                                                                  return <Calendar dateCellRender={dateCellRender} monthCellRender={monthCellRender} />;
                                                                                };
                                                                                
                                                                                export default App;
                                                                                .events {
                                                                                  margin: 0;
                                                                                  padding: 0;
                                                                                  list-style: none;
                                                                                }
                                                                                .events .ant-badge-status {
                                                                                  width: 100%;
                                                                                  overflow: hidden;
                                                                                  font-size: 12px;
                                                                                  white-space: nowrap;
                                                                                  text-overflow: ellipsis;
                                                                                }
                                                                                .notes-month {
                                                                                  font-size: 28px;
                                                                                  text-align: center;
                                                                                }
                                                                                .notes-month section {
                                                                                  font-size: 28px;
                                                                                }
                                                                                2022年
                                                                                7月
                                                                                27
                                                                                28
                                                                                29
                                                                                30
                                                                                01
                                                                                02
                                                                                03
                                                                                04
                                                                                05
                                                                                06
                                                                                07
                                                                                08
                                                                                09
                                                                                10
                                                                                11
                                                                                12
                                                                                13
                                                                                14
                                                                                15
                                                                                16
                                                                                17
                                                                                18
                                                                                19
                                                                                20
                                                                                21
                                                                                22
                                                                                23
                                                                                24
                                                                                25
                                                                                26
                                                                                27
                                                                                28
                                                                                29
                                                                                30
                                                                                31
                                                                                01
                                                                                02
                                                                                03
                                                                                04
                                                                                05
                                                                                06
                                                                                07

                                                                                用于嵌套在空间有限的容器中。

                                                                                expand codeexpand code
                                                                                import { Calendar } from 'infrad';
                                                                                import type { CalendarMode } from 'infrad/lib/calendar/generateCalendar';
                                                                                import type { Moment } from 'moment';
                                                                                import React from 'react';
                                                                                
                                                                                const App: React.FC = () => {
                                                                                  const onPanelChange = (value: Moment, mode: CalendarMode) => {
                                                                                    console.log(value.format('YYYY-MM-DD'), mode);
                                                                                  };
                                                                                
                                                                                  return (
                                                                                    <div className="site-calendar-demo-card">
                                                                                      <Calendar fullscreen={false} onPanelChange={onPanelChange} />
                                                                                    </div>
                                                                                  );
                                                                                };
                                                                                
                                                                                export default App;
                                                                                .site-calendar-demo-card {
                                                                                  width: 300px;
                                                                                  border: 1px solid #f0f0f0;
                                                                                  border-radius: 2px;
                                                                                }
                                                                                2017年
                                                                                1月
                                                                                26
                                                                                27
                                                                                28
                                                                                29
                                                                                30
                                                                                31
                                                                                01
                                                                                02
                                                                                03
                                                                                04
                                                                                05
                                                                                06
                                                                                07
                                                                                08
                                                                                09
                                                                                10
                                                                                11
                                                                                12
                                                                                13
                                                                                14
                                                                                15
                                                                                16
                                                                                17
                                                                                18
                                                                                19
                                                                                20
                                                                                21
                                                                                22
                                                                                23
                                                                                24
                                                                                25
                                                                                26
                                                                                27
                                                                                28
                                                                                29
                                                                                30
                                                                                31
                                                                                01
                                                                                02
                                                                                03
                                                                                04
                                                                                05

                                                                                一个通用的日历面板,支持年/月切换。

                                                                                expand codeexpand code
                                                                                import { Alert, Calendar } from 'infrad';
                                                                                import type { Moment } from 'moment';
                                                                                import moment from 'moment';
                                                                                import React, { useState } from 'react';
                                                                                
                                                                                const App: React.FC = () => {
                                                                                  const [value, setValue] = useState(moment('2017-01-25'));
                                                                                  const [selectedValue, setSelectedValue] = useState(moment('2017-01-25'));
                                                                                
                                                                                  const onSelect = (newValue: Moment) => {
                                                                                    setValue(newValue);
                                                                                    setSelectedValue(newValue);
                                                                                  };
                                                                                
                                                                                  const onPanelChange = (newValue: Moment) => {
                                                                                    setValue(newValue);
                                                                                  };
                                                                                
                                                                                  return (
                                                                                    <>
                                                                                      <Alert message={`You selected date: ${selectedValue?.format('YYYY-MM-DD')}`} />
                                                                                      <Calendar value={value} onSelect={onSelect} onPanelChange={onPanelChange} />
                                                                                    </>
                                                                                  );
                                                                                };
                                                                                
                                                                                export default App;

                                                                                Custom header

                                                                                2022
                                                                                7月
                                                                                27
                                                                                28
                                                                                29
                                                                                30
                                                                                01
                                                                                02
                                                                                03
                                                                                04
                                                                                05
                                                                                06
                                                                                07
                                                                                08
                                                                                09
                                                                                10
                                                                                11
                                                                                12
                                                                                13
                                                                                14
                                                                                15
                                                                                16
                                                                                17
                                                                                18
                                                                                19
                                                                                20
                                                                                21
                                                                                22
                                                                                23
                                                                                24
                                                                                25
                                                                                26
                                                                                27
                                                                                28
                                                                                29
                                                                                30
                                                                                31
                                                                                01
                                                                                02
                                                                                03
                                                                                04
                                                                                05
                                                                                06
                                                                                07

                                                                                自定义日历头部内容。

                                                                                expand codeexpand code
                                                                                import { Calendar, Col, Radio, Row, Select, Typography } from 'infrad';
                                                                                import type { CalendarMode } from 'infrad/lib/calendar/generateCalendar';
                                                                                import type { Moment } from 'moment';
                                                                                import React from 'react';
                                                                                
                                                                                const App: React.FC = () => {
                                                                                  const onPanelChange = (value: Moment, mode: CalendarMode) => {
                                                                                    console.log(value.format('YYYY-MM-DD'), mode);
                                                                                  };
                                                                                
                                                                                  return (
                                                                                    <div className="site-calendar-customize-header-wrapper">
                                                                                      <Calendar
                                                                                        fullscreen={false}
                                                                                        headerRender={({ value, type, onChange, onTypeChange }) => {
                                                                                          const start = 0;
                                                                                          const end = 12;
                                                                                          const monthOptions = [];
                                                                                
                                                                                          const current = value.clone();
                                                                                          const localeData = value.localeData();
                                                                                          const months = [];
                                                                                          for (let i = 0; i < 12; i++) {
                                                                                            current.month(i);
                                                                                            months.push(localeData.monthsShort(current));
                                                                                          }
                                                                                
                                                                                          for (let i = start; i < end; i++) {
                                                                                            monthOptions.push(
                                                                                              <Select.Option key={i} value={i} className="month-item">
                                                                                                {months[i]}
                                                                                              </Select.Option>,
                                                                                            );
                                                                                          }
                                                                                
                                                                                          const year = value.year();
                                                                                          const month = value.month();
                                                                                          const options = [];
                                                                                          for (let i = year - 10; i < year + 10; i += 1) {
                                                                                            options.push(
                                                                                              <Select.Option key={i} value={i} className="year-item">
                                                                                                {i}
                                                                                              </Select.Option>,
                                                                                            );
                                                                                          }
                                                                                          return (
                                                                                            <div style={{ padding: 8 }}>
                                                                                              <Typography.Title level={4}>Custom header</Typography.Title>
                                                                                              <Row gutter={8}>
                                                                                                <Col>
                                                                                                  <Radio.Group
                                                                                                    size="small"
                                                                                                    onChange={e => onTypeChange(e.target.value)}
                                                                                                    value={type}
                                                                                                  >
                                                                                                    <Radio.Button value="month">Month</Radio.Button>
                                                                                                    <Radio.Button value="year">Year</Radio.Button>
                                                                                                  </Radio.Group>
                                                                                                </Col>
                                                                                                <Col>
                                                                                                  <Select
                                                                                                    size="small"
                                                                                                    dropdownMatchSelectWidth={false}
                                                                                                    className="my-year-select"
                                                                                                    value={year}
                                                                                                    onChange={newYear => {
                                                                                                      const now = value.clone().year(newYear);
                                                                                                      onChange(now);
                                                                                                    }}
                                                                                                  >
                                                                                                    {options}
                                                                                                  </Select>
                                                                                                </Col>
                                                                                                <Col>
                                                                                                  <Select
                                                                                                    size="small"
                                                                                                    dropdownMatchSelectWidth={false}
                                                                                                    value={month}
                                                                                                    onChange={newMonth => {
                                                                                                      const now = value.clone().month(newMonth);
                                                                                                      onChange(now);
                                                                                                    }}
                                                                                                  >
                                                                                                    {monthOptions}
                                                                                                  </Select>
                                                                                                </Col>
                                                                                              </Row>
                                                                                            </div>
                                                                                          );
                                                                                        }}
                                                                                        onPanelChange={onPanelChange}
                                                                                      />
                                                                                    </div>
                                                                                  );
                                                                                };
                                                                                
                                                                                export default App;
                                                                                .site-calendar-customize-header-wrapper {
                                                                                  width: 300px;
                                                                                  border: 1px solid #f0f0f0;
                                                                                  border-radius: 2px;
                                                                                }

                                                                                API#

                                                                                <Calendar
                                                                                  dateCellRender={dateCellRender}
                                                                                  monthCellRender={monthCellRender}
                                                                                  onPanelChange={onPanelChange}
                                                                                  onSelect={onSelect}
                                                                                />
                                                                                参数说明类型默认值版本
                                                                                dateCellRender自定义渲染日期单元格,返回内容会被追加到单元格function(date: Moment): ReactNode-
                                                                                dateFullCellRender自定义渲染日期单元格,返回内容覆盖单元格function(date: Moment): ReactNode-
                                                                                defaultValue默认展示的日期moment-
                                                                                disabledDate不可选择的日期,参数为当前 value,注意使用时不要直接修改(currentDate: Moment) => boolean-
                                                                                fullscreen是否全屏显示booleantrue
                                                                                headerRender自定义头部内容function(object:{value: Moment, type: string, onChange: f(), onTypeChange: f()})-
                                                                                locale国际化配置object(默认配置)
                                                                                mode初始模式month | yearmonth
                                                                                monthCellRender自定义渲染月单元格,返回内容会被追加到单元格function(date: Moment): ReactNode-
                                                                                monthFullCellRender自定义渲染月单元格,返回内容覆盖单元格function(date: Moment): ReactNode-
                                                                                validRange设置可以显示的日期[moment, moment]-
                                                                                value展示日期moment-
                                                                                onChange日期变化回调function(date: Moment)-
                                                                                onPanelChange日期面板变化回调function(date: Moment, mode: string)-
                                                                                onSelect点击选择日期回调function(date: Moment)-

                                                                                FAQ#

                                                                                如何在 Calendar 中使用自定义日期库(如 dayjs )#

                                                                                参考 如何在 Calendar 中使用自定义日期库(如 dayjs )

                                                                                如何给日期类组件配置国际化?#

                                                                                参考 如何给日期类组件配置国际化

                                                                                为什么时间类组件的国际化 locale 设置不生效?#

                                                                                参考 FAQ 为什么时间类组件的国际化 locale 设置不生效?