Calendar 日历
如果项目中使用的是 0.x 版本的基础组件(@icedesign/base, @ali/ice, @alife/next),请在左侧导航顶部切换组件版本。
安装方法
- 在命令行中执行以下命令
npm install @alifd/next@latest -S
Guide
按照日历形式展示数据的容器。
何时使用
日历组件是一个偏向于展示与受控的基础组件,可用于日程、课表、价格日历、农历展示等。
日期值的多语言
由于 Calendar 组件内部使用 moment 对象来设置日期(请使用最新版 moment),部分 Locale 读取自 moment,因此用户需要在外部使用时正确的设置 moment 的 locale 。
import moment from 'moment';
moment.locale('zh-cn');
API
Calendar
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
defaultValue | 默认选中的日期(moment 对象) | custom | - |
shape | 展现形态可选值:'card', 'fullscreen', 'panel' | Enum | 'fullscreen' |
value | 选中的日期值 (moment 对象) | custom | - |
mode | 面板模式可选值:'date', 'month', 'year' | Enum | - |
showOtherMonth | 是否展示非本月的日期 | Boolean | true |
defaultVisibleMonth | 默认展示的月份签名:Function() => void | Function | - |
onSelect | 选择日期单元格时的回调签名:Function(value: Object) => void参数:value: {Object} 对应的日期值 (moment 对象) | Function | func.noop |
onModeChange | 面板模式变化时的回调签名:Function(mode: String) => void参数:mode: {String} 对应面板模式 date month year | Function | func.noop |
onVisibleMonthChange | 展现的月份变化时的回调签名:Function(value: Object, reason: String) => void参数:value: {Object} 显示的月份 (moment 对象)reason: {String} 触发月份改变原因 | Function | func.noop |
dateCellRender | 自定义日期渲染函数签名:Function(value: Object) => ReactNode参数:value: {Object} 日期值(moment对象)返回值:{ReactNode} null | Function | value => value.date() |
monthCellRender | 自定义月份渲染函数签名:Function(calendarDate: Object) => ReactNode参数:calendarDate: {Object} 对应 Calendar 返回的自定义日期对象返回值:{ReactNode} null | Function | - |
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} null | Function | - |
代码示例
最简单的日历用法,用户可以切换年/月。
查看源码在线预览
import { Calendar } from '@alifd/next';
import moment from 'moment';
function onDateChange(value) {
console.log(value.format('L'));
}
ReactDOM.render(<div>
<Calendar onSelect={onDateChange} defaultValue={moment().add(1, 'days')} /></div>, mountNode);
农历
查看源码在线预览
import { Calendar } from '@alifd/next';
import moment from 'moment';
import solarLunar from 'solarlunar';
function onDateChange(value) {
console.log(value.format('L'));
}
function dateCellRender(value) {
const solar2lunarData = solarLunar.solar2lunar(value.year(), value.month(), value.date());
return (<div className="custom-cell">
{value.date()}
<span>{solar2lunarData.lDay === 1 ? solar2lunarData.monthCn: solar2lunarData.dayCn}</span>
</div>);
}
ReactDOM.render(<div>
<Calendar onSelect={onDateChange} dateCellRender={dateCellRender} defaultValue={moment().add(1, 'days')} /></div>, mountNode);
.custom-cell {
width: 100%;
height: 70px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-end;
}
可以将 card
形态的日历组件嵌套在宽高受限的容器中。
查看源码在线预览
import { Calendar } from '@alifd/next';
function onDateChange(value) {
console.log(value);
}
ReactDOM.render(<div className="wrapped-calendar">
<Calendar onSelect={onDateChange} shape="card" />
</div>, mountNode);
.wrapped-calendar {
width: 300px;
border: 1px solid #C4C6CF;
border-radius: 3px;
padding: 8px;
}
可以通过 disabledDate
属性禁止用户选择某些日期。
查看源码在线预览
import { Calendar } from '@alifd/next';
import moment from 'moment';
const currentDate = moment();
const disabledDate = function (date) {
return date.valueOf() > currentDate.valueOf();
};
ReactDOM.render(<div className="wrapped-calendar">
<Calendar disabledDate={disabledDate} shape="card" />
</div>, mountNode);
.wrapped-calendar {
width: 300px;
border: 1px solid #C4C6CF;
border-radius: 3px;
padding: 8px;
}
通过 dateCellRender
和 monthCellRender
用户可以在日历中添加自定义内容。
查看源码在线预览
import { Calendar } from '@alifd/next';
import moment from 'moment';
const currentDate = moment();
const localeData = currentDate.clone().localeData();
const monthLocale = localeData.monthsShort();
function dateCellRender(date) {
const dateNum = date.date();
if (currentDate.month() !== date.month()) {
return dateNum;
}
let eventList;
switch (dateNum) {
case 1:
eventList = [
{ type: 'primary', content: 'Event 1' },
{ type: 'normal', content: 'Event 2' }
];
break;
case 10:
eventList = [
{ type: 'normal', content: 'Event 3' },
{ type: 'normal', content: 'Event 4' }
];
break;
case 11:
eventList = [
{ type: 'primary', content: 'Event 5' },
{ type: 'primary', content: 'Event 6' }
];
break;
default:
eventList = [];
}
return (<div className="custom-calendar-cell">
<div className="custom-calendar-cell-value">{dateNum}</div>
<div className="custom-calendar-cell-content">
<ul className="event-list">
{eventList.map((item, key) => <li className={`${item.type}-event`} key={key}>{item.content}</li>)}
</ul>
</div>
</div>);
}
function monthCellRender(date) {
if (currentDate.month() === date.month()) {
return (<div>
<div>{monthLocale[date.month()]}</div>
<div>Events</div>
</div>);
}
return monthLocale[date.month()];
}
ReactDOM.render(<Calendar dateCellRender={dateCellRender} monthCellRender={monthCellRender} />, mountNode);
.custom-calendar-guide {
width: 270px;
border: 1px solid #C4C6CF;
border-radius: 3px;
overflow: hidden;
margin-top: 20px;
}
.custom-calendar-cell-content {
height: 50px;
text-align: left;
}
.event-list {
margin: 0;
padding: 0;
list-style: none;
}
.primary-event {
color: white;
background: red;
border-radius: 3px;
padding-left: 10px;
margin-bottom: 3px;
}
.normal-event {
color: white;
background: blue;
border-radius: 3px;
padding-left: 10px;
margin-bottom: 3px;
}
日历组件默认使用当前月作为展示的月份,用户可以可以通过 defaultVisibleMonth
属性进行定制。并可以通过 onVisibleMonthChange
属性监听面板可视月份的变化。
查看源码在线预览
import { Calendar } from '@alifd/next';
import moment from 'moment';
function onSelect(value) {
console.log(value.format('L'));
}
function onVisibleMonthChange(value, reason) {
console.log('Visible month changed to %s from <%s>', value.format('YYYY-MM'), reason);
}
ReactDOM.render(<Calendar onSelect={onSelect} defaultVisibleMonth={() => moment('2018-01', 'YYYY-MM', true)} onVisibleMonthChange={onVisibleMonthChange} />, mountNode);
日历面板通用用于嵌套在弹层容器中。
查看源码在线预览
import { Calendar } from '@alifd/next';
import moment from 'moment';
ReactDOM.render(<div>
<Calendar shape="panel" value={moment().add(1, 'days')} />
</div>, mountNode);
日期时间的多语言来源于 moment ,可以通过 moment.locale('zh-cn')
来设置显示中文。
查看源码在线预览
import { Calendar } from '@alifd/next';
import moment from 'moment';
// Setting moment locale to Chinese
moment.locale('zh-cn');
ReactDOM.render(<Calendar />, mountNode);