Calendar 日历

如果项目中使用的是 0.x 版本的基础组件(@icedesign/base, @ali/ice, @alife/next),请在左侧导航顶部切换组件版本。

安装方法

  1. 在命令行中执行以下命令npm install @alifd/next@latest -S

Guide

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

何时使用

日历组件是一个偏向于展示与受控的基础组件,可用于日程、课表、价格日历、农历展示等。

日期值的多语言

由于 Calendar 组件内部使用 moment 对象来设置日期(请使用最新版 moment),部分 Locale 读取自 moment,因此用户需要在外部使用时正确的设置 moment 的 locale

  1. import moment from 'moment';
  2. moment.locale('zh-cn');

API

Calendar

参数说明类型默认值
defaultValue默认选中的日期(moment 对象)custom-
shape展现形态可选值:'card', 'fullscreen', 'panel'Enum'fullscreen'
value选中的日期值 (moment 对象)custom-
mode面板模式可选值:'date', 'month', 'year'Enum-
showOtherMonth是否展示非本月的日期Booleantrue
defaultVisibleMonth默认展示的月份签名:Function() => voidFunction-
onSelect选择日期单元格时的回调签名:Function(value: Object) => void参数:value: {Object} 对应的日期值 (moment 对象)Functionfunc.noop
onModeChange面板模式变化时的回调签名:Function(mode: String) => void参数:mode: {String} 对应面板模式 date month yearFunctionfunc.noop
onVisibleMonthChange展现的月份变化时的回调签名:Function(value: Object, reason: String) => void参数:value: {Object} 显示的月份 (moment 对象)reason: {String} 触发月份改变原因Functionfunc.noop
dateCellRender自定义日期渲染函数签名:Function(value: Object) => ReactNode参数:value: {Object} 日期值(moment对象)返回值:{ReactNode} nullFunctionvalue => value.date()
monthCellRender自定义月份渲染函数签名:Function(calendarDate: Object) => ReactNode参数:calendarDate: {Object} 对应 Calendar 返回的自定义日期对象返回值:{ReactNode} nullFunction-
yearRange年份范围,START_YEAR, END_YEAR (只在shape 为 ‘card’, 'fullscreen' 下生效)Array<Number>-
disabledDate不可选择的日期签名:Function(calendarDate: Object, view: String) => Boolean参数:calendarDate: {Object} 对应 Calendar 返回的自定义日期对象view: {String} 当前视图类型,year: 年, month: 月, date: 日返回值:{Boolean} nullFunction-

代码示例

全屏日历

最简单的日历用法,用户可以切换年/月。

Calendar 日历 - 图1

查看源码在线预览

  1. import { Calendar } from '@alifd/next';
  2. import moment from 'moment';
  3. function onDateChange(value) {
  4. console.log(value.format('L'));
  5. }
  6. ReactDOM.render(<div>
  7. <Calendar onSelect={onDateChange} defaultValue={moment().add(1, 'days')} /></div>, mountNode);

农历

农历

Calendar 日历 - 图2

查看源码在线预览

  1. import { Calendar } from '@alifd/next';
  2. import moment from 'moment';
  3. import solarLunar from 'solarlunar';
  4. function onDateChange(value) {
  5. console.log(value.format('L'));
  6. }
  7. function dateCellRender(value) {
  8. const solar2lunarData = solarLunar.solar2lunar(value.year(), value.month(), value.date());
  9. return (<div className="custom-cell">
  10. {value.date()}
  11. <span>{solar2lunarData.lDay === 1 ? solar2lunarData.monthCn: solar2lunarData.dayCn}</span>
  12. </div>);
  13. }
  14. ReactDOM.render(<div>
  15. <Calendar onSelect={onDateChange} dateCellRender={dateCellRender} defaultValue={moment().add(1, 'days')} /></div>, mountNode);
  1. .custom-cell {
  2. width: 100%;
  3. height: 70px;
  4. display: flex;
  5. flex-direction: column;
  6. justify-content: space-between;
  7. align-items: flex-end;
  8. }

日历卡片

可以将 card 形态的日历组件嵌套在宽高受限的容器中。

Calendar 日历 - 图3

查看源码在线预览

  1. import { Calendar } from '@alifd/next';
  2. function onDateChange(value) {
  3. console.log(value);
  4. }
  5. ReactDOM.render(<div className="wrapped-calendar">
  6. <Calendar onSelect={onDateChange} shape="card" />
  7. </div>, mountNode);
  1. .wrapped-calendar {
  2. width: 300px;
  3. border: 1px solid #C4C6CF;
  4. border-radius: 3px;
  5. padding: 8px;
  6. }

禁用日期

可以通过 disabledDate 属性禁止用户选择某些日期。

Calendar 日历 - 图4

查看源码在线预览

  1. import { Calendar } from '@alifd/next';
  2. import moment from 'moment';
  3. const currentDate = moment();
  4. const disabledDate = function (date) {
  5. return date.valueOf() > currentDate.valueOf();
  6. };
  7. ReactDOM.render(<div className="wrapped-calendar">
  8. <Calendar disabledDate={disabledDate} shape="card" />
  9. </div>, mountNode);
  1. .wrapped-calendar {
  2. width: 300px;
  3. border: 1px solid #C4C6CF;
  4. border-radius: 3px;
  5. padding: 8px;
  6. }

定制日历内容

通过 dateCellRendermonthCellRender 用户可以在日历中添加自定义内容。

Calendar 日历 - 图5

查看源码在线预览

  1. import { Calendar } from '@alifd/next';
  2. import moment from 'moment';
  3. const currentDate = moment();
  4. const localeData = currentDate.clone().localeData();
  5. const monthLocale = localeData.monthsShort();
  6. function dateCellRender(date) {
  7. const dateNum = date.date();
  8. if (currentDate.month() !== date.month()) {
  9. return dateNum;
  10. }
  11. let eventList;
  12. switch (dateNum) {
  13. case 1:
  14. eventList = [
  15. { type: 'primary', content: 'Event 1' },
  16. { type: 'normal', content: 'Event 2' }
  17. ];
  18. break;
  19. case 10:
  20. eventList = [
  21. { type: 'normal', content: 'Event 3' },
  22. { type: 'normal', content: 'Event 4' }
  23. ];
  24. break;
  25. case 11:
  26. eventList = [
  27. { type: 'primary', content: 'Event 5' },
  28. { type: 'primary', content: 'Event 6' }
  29. ];
  30. break;
  31. default:
  32. eventList = [];
  33. }
  34. return (<div className="custom-calendar-cell">
  35. <div className="custom-calendar-cell-value">{dateNum}</div>
  36. <div className="custom-calendar-cell-content">
  37. <ul className="event-list">
  38. {eventList.map((item, key) => <li className={`${item.type}-event`} key={key}>{item.content}</li>)}
  39. </ul>
  40. </div>
  41. </div>);
  42. }
  43. function monthCellRender(date) {
  44. if (currentDate.month() === date.month()) {
  45. return (<div>
  46. <div>{monthLocale[date.month()]}</div>
  47. <div>Events</div>
  48. </div>);
  49. }
  50. return monthLocale[date.month()];
  51. }
  52. ReactDOM.render(<Calendar dateCellRender={dateCellRender} monthCellRender={monthCellRender} />, mountNode);
  1. .custom-calendar-guide {
  2. width: 270px;
  3. border: 1px solid #C4C6CF;
  4. border-radius: 3px;
  5. overflow: hidden;
  6. margin-top: 20px;
  7. }
  8. .custom-calendar-cell-content {
  9. height: 50px;
  10. text-align: left;
  11. }
  12. .event-list {
  13. margin: 0;
  14. padding: 0;
  15. list-style: none;
  16. }
  17. .primary-event {
  18. color: white;
  19. background: red;
  20. border-radius: 3px;
  21. padding-left: 10px;
  22. margin-bottom: 3px;
  23. }
  24. .normal-event {
  25. color: white;
  26. background: blue;
  27. border-radius: 3px;
  28. padding-left: 10px;
  29. margin-bottom: 3px;
  30. }

日历默认展示月份

日历组件默认使用当前月作为展示的月份,用户可以可以通过 defaultVisibleMonth 属性进行定制。并可以通过 onVisibleMonthChange 属性监听面板可视月份的变化。

Calendar 日历 - 图6

查看源码在线预览

  1. import { Calendar } from '@alifd/next';
  2. import moment from 'moment';
  3. function onSelect(value) {
  4. console.log(value.format('L'));
  5. }
  6. function onVisibleMonthChange(value, reason) {
  7. console.log('Visible month changed to %s from <%s>', value.format('YYYY-MM'), reason);
  8. }
  9. ReactDOM.render(<Calendar onSelect={onSelect} defaultVisibleMonth={() => moment('2018-01', 'YYYY-MM', true)} onVisibleMonthChange={onVisibleMonthChange} />, mountNode);

日历面板

日历面板通用用于嵌套在弹层容器中。

Calendar 日历 - 图7

查看源码在线预览

  1. import { Calendar } from '@alifd/next';
  2. import moment from 'moment';
  3. ReactDOM.render(<div>
  4. <Calendar shape="panel" value={moment().add(1, 'days')} />
  5. </div>, mountNode);

多语言

日期时间的多语言来源于 moment ,可以通过 moment.locale('zh-cn') 来设置显示中文。

Calendar 日历 - 图8

查看源码在线预览

  1. import { Calendar } from '@alifd/next';
  2. import moment from 'moment';
  3. // Setting moment locale to Chinese
  4. moment.locale('zh-cn');
  5. ReactDOM.render(<Calendar />, mountNode);

相关区块

Calendar 日历 - 图9

暂无相关区块