Calendar日历

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

何时使用

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

代码演示

Calendar日历 - 图1

基本

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

  1. import { Calendar } from 'antd';
  2. function onPanelChange(value, mode) {
  3. console.log(value.format('YYYY-MM-DD'), mode);
  4. }
  5. ReactDOM.render(<Calendar onPanelChange={onPanelChange} />, mountNode);

Calendar日历 - 图2

通知事项日历

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

  1. import { Calendar, Badge } from 'antd';
  2. function getListData(value) {
  3. let listData;
  4. switch (value.date()) {
  5. case 8:
  6. listData = [
  7. { type: 'warning', content: 'This is warning event.' },
  8. { type: 'success', content: 'This is usual event.' },
  9. ];
  10. break;
  11. case 10:
  12. listData = [
  13. { type: 'warning', content: 'This is warning event.' },
  14. { type: 'success', content: 'This is usual event.' },
  15. { type: 'error', content: 'This is error event.' },
  16. ];
  17. break;
  18. case 15:
  19. listData = [
  20. { type: 'warning', content: 'This is warning event' },
  21. { type: 'success', content: 'This is very long usual event。。....' },
  22. { type: 'error', content: 'This is error event 1.' },
  23. { type: 'error', content: 'This is error event 2.' },
  24. { type: 'error', content: 'This is error event 3.' },
  25. { type: 'error', content: 'This is error event 4.' },
  26. ];
  27. break;
  28. default:
  29. }
  30. return listData || [];
  31. }
  32. function dateCellRender(value) {
  33. const listData = getListData(value);
  34. return (
  35. <ul className="events">
  36. {listData.map(item => (
  37. <li key={item.content}>
  38. <Badge status={item.type} text={item.content} />
  39. </li>
  40. ))}
  41. </ul>
  42. );
  43. }
  44. function getMonthData(value) {
  45. if (value.month() === 8) {
  46. return 1394;
  47. }
  48. }
  49. function monthCellRender(value) {
  50. const num = getMonthData(value);
  51. return num ? (
  52. <div className="notes-month">
  53. <section>{num}</section>
  54. <span>Backlog number</span>
  55. </div>
  56. ) : null;
  57. }
  58. ReactDOM.render(
  59. <Calendar dateCellRender={dateCellRender} monthCellRender={monthCellRender} />,
  60. mountNode,
  61. );
  1. .events {
  2. list-style: none;
  3. margin: 0;
  4. padding: 0;
  5. }
  6. .events .ant-badge-status {
  7. overflow: hidden;
  8. white-space: nowrap;
  9. width: 100%;
  10. text-overflow: ellipsis;
  11. font-size: 12px;
  12. }
  13. .notes-month {
  14. text-align: center;
  15. font-size: 28px;
  16. }
  17. .notes-month section {
  18. font-size: 28px;
  19. }

Calendar日历 - 图3

卡片模式

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

  1. import { Calendar } from 'antd';
  2. function onPanelChange(value, mode) {
  3. console.log(value, mode);
  4. }
  5. ReactDOM.render(
  6. <div className="site-calendar-demo-card">
  7. <Calendar fullscreen={false} onPanelChange={onPanelChange} />
  8. </div>,
  9. mountNode,
  10. );
  1. .site-calendar-demo-card {
  2. width: 300px;
  3. border: 1px solid #f0f0f0;
  4. border-radius: 2px;
  5. }

Calendar日历 - 图4

选择功能

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

  1. import { Calendar, Alert } from 'antd';
  2. import moment from 'moment';
  3. class App extends React.Component {
  4. state = {
  5. value: moment('2017-01-25'),
  6. selectedValue: moment('2017-01-25'),
  7. };
  8. onSelect = value => {
  9. this.setState({
  10. value,
  11. selectedValue: value,
  12. });
  13. };
  14. onPanelChange = value => {
  15. this.setState({ value });
  16. };
  17. render() {
  18. const { value, selectedValue } = this.state;
  19. return (
  20. <>
  21. <Alert
  22. message={`You selected date: ${selectedValue && selectedValue.format('YYYY-MM-DD')}`}
  23. />
  24. <Calendar value={value} onSelect={this.onSelect} onPanelChange={this.onPanelChange} />
  25. </>
  26. );
  27. }
  28. }
  29. ReactDOM.render(<App />, mountNode);

Calendar日历 - 图5

自定义头部

自定义日历头部内容。

  1. import { Calendar, Select, Radio, Col, Row, Typography } from 'antd';
  2. function onPanelChange(value, mode) {
  3. console.log(value, mode);
  4. }
  5. ReactDOM.render(
  6. <div className="site-calendar-customize-header-wrapper">
  7. <Calendar
  8. fullscreen={false}
  9. headerRender={({ value, type, onChange, onTypeChange }) => {
  10. const start = 0;
  11. const end = 12;
  12. const monthOptions = [];
  13. const current = value.clone();
  14. const localeData = value.localeData();
  15. const months = [];
  16. for (let i = 0; i < 12; i++) {
  17. current.month(i);
  18. months.push(localeData.monthsShort(current));
  19. }
  20. for (let index = start; index < end; index++) {
  21. monthOptions.push(
  22. <Select.Option className="month-item" key={`${index}`}>
  23. {months[index]}
  24. </Select.Option>,
  25. );
  26. }
  27. const month = value.month();
  28. const year = value.year();
  29. const options = [];
  30. for (let i = year - 10; i < year + 10; i += 1) {
  31. options.push(
  32. <Select.Option key={i} value={i} className="year-item">
  33. {i}
  34. </Select.Option>,
  35. );
  36. }
  37. return (
  38. <div style={{ padding: 8 }}>
  39. <Typography.Title level={4}>Custom header</Typography.Title>
  40. <Row gutter={8}>
  41. <Col>
  42. <Radio.Group size="small" onChange={e => onTypeChange(e.target.value)} value={type}>
  43. <Radio.Button value="month">Month</Radio.Button>
  44. <Radio.Button value="year">Year</Radio.Button>
  45. </Radio.Group>
  46. </Col>
  47. <Col>
  48. <Select
  49. size="small"
  50. dropdownMatchSelectWidth={false}
  51. className="my-year-select"
  52. onChange={newYear => {
  53. const now = value.clone().year(newYear);
  54. onChange(now);
  55. }}
  56. value={String(year)}
  57. >
  58. {options}
  59. </Select>
  60. </Col>
  61. <Col>
  62. <Select
  63. size="small"
  64. dropdownMatchSelectWidth={false}
  65. value={String(month)}
  66. onChange={selectedMonth => {
  67. const newValue = value.clone();
  68. newValue.month(parseInt(selectedMonth, 10));
  69. onChange(newValue);
  70. }}
  71. >
  72. {monthOptions}
  73. </Select>
  74. </Col>
  75. </Row>
  76. </div>
  77. );
  78. }}
  79. onPanelChange={onPanelChange}
  80. />
  81. </div>,
  82. mountNode,
  83. );
  1. .site-calendar-customize-header-wrapper {
  2. width: 300px;
  3. border: 1px solid #f0f0f0;
  4. border-radius: 2px;
  5. }

API

注意:Calendar 部分 locale 是从 value 中读取,所以请先正确设置 moment 的 locale。

  1. // 默认语言为 en-US,所以如果需要使用其他语言,推荐在入口文件全局设置 locale
  2. // import moment from 'moment';
  3. // import 'moment/locale/zh-cn';
  4. // moment.locale('zh-cn');
  5. <Calendar
  6. dateCellRender={dateCellRender}
  7. monthCellRender={monthCellRender}
  8. onPanelChange={onPanelChange}
  9. onSelect={onSelect}
  10. />
参数说明类型默认值版本
dateCellRender自定义渲染日期单元格,返回内容会被追加到单元格function(date: moment): ReactNode-
dateFullCellRender自定义渲染日期单元格,返回内容覆盖单元格function(date: moment): ReactNode-
defaultValue默认展示的日期moment-
disabledDate不可选择的日期(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