diff --git a/components/calendar/demo/basic.md b/components/calendar/demo/basic.md
new file mode 100644
index 0000000000..3c2918998b
--- /dev/null
+++ b/components/calendar/demo/basic.md
@@ -0,0 +1,44 @@
+# 基本
+
+- order: 0
+
+最简单的用法。
+
+---
+
+````jsx
+import { Calendar } from 'antd';
+
+function getDateData(value) {
+
+ let listdata;
+ switch (value.getDayOfMonth()) {
+ case 8:
+ listdata = [
+ { type: 'warn', content: '这里是警告事项.' },
+ { type: 'normal', content: '这里是普通事项.' }
+ ]; break;
+ case 10:
+ listdata = [
+ { type: 'warn', content: '这里是警告事项.' },
+ { type: 'normal', content: '这里是普通事项.' },
+ { type: 'error', content: '这里是错误事项.' }
+ ]; break;
+ case 15:
+ listdata = [
+ { type: 'warn', content: '这里是警告事项.' },
+ { type: 'normal', content: '这里是普通事项.' },
+ { type: 'error', content: '这里是错误事项.' },
+ { type: 'error', content: '这里是错误事项.' }
+ ]; break;
+ }
+
+ return listdata;
+
+}
+
+
+ReactDOM.render(
+
+, document.getElementById('components-calendar-demo-basic'));
+````
diff --git a/components/calendar/demo/fullscreen.md b/components/calendar/demo/fullscreen.md
new file mode 100644
index 0000000000..d34999729f
--- /dev/null
+++ b/components/calendar/demo/fullscreen.md
@@ -0,0 +1,52 @@
+# 全屏
+
+- order: 3
+
+变大
+
+---
+
+````jsx
+import { Calendar } from 'antd';
+
+function getDateData(value) {
+
+ let listdata;
+ switch (value.getDayOfMonth()) {
+ case 8:
+ listdata = [
+ { type: 'warn', content: '这里是警告事项.' },
+ { type: 'normal', content: '这里是普通事项.' }
+ ]; break;
+ case 10:
+ listdata = [
+ { type: 'warn', content: '这里是警告事项.' },
+ { type: 'normal', content: '这里是普通事项.' },
+ { type: 'error', content: '这里是错误事项.' }
+ ]; break;
+ case 15:
+ listdata = [
+ { type: 'warn', content: '这里是警告事项.' },
+ { type: 'normal', content: '这里是普通事项好长啊。。.' },
+ { type: 'error', content: '这里是错误事项.' },
+ { type: 'error', content: '这里是错误事项.' }
+ ]; break;
+ }
+
+ return listdata;
+
+}
+
+function getMonthData(value) {
+ if (value.getMonth() === 8) {
+ return 1394;
+ }
+ return 0;
+}
+
+ReactDOM.render(
+
+, document.getElementById('components-calendar-demo-fullscreen'));
+````
+
+
diff --git a/components/calendar/index.jsx b/components/calendar/index.jsx
new file mode 100644
index 0000000000..88a9c566d4
--- /dev/null
+++ b/components/calendar/index.jsx
@@ -0,0 +1,168 @@
+import React, {PropTypes, Component} from 'react';
+import CalendarLocale from 'rc-calendar/lib/locale/zh_CN';
+import FullCalendar from 'rc-calendar/lib/FullCalendar';
+import Tooltip from 'rc-tooltip';
+import 'rc-tooltip/assets/bootstrap.css';
+import 'rc-calendar/assets/index.css';
+
+function noop () { return null; }
+
+class NoteList extends Component {
+ render() {
+ const {listdata, prefixCls} = this.props;
+
+ if (!listdata || listdata === 0) return null;
+
+ return (
+
+ { listdata.map(function (item, index) {
+ return - ●{ item.content }
;
+ }) }
+
+ );
+ }
+}
+NoteList.propTypes = {
+ listdata: PropTypes.array,
+ prefixCls: PropTypes.string,
+};
+NoteList.defaultProps = {
+ prefixCls: 'calendar-notes-list'
+};
+
+class Notes extends Component {
+ constructor(props) {
+ super();
+ }
+ type2class(type) {
+ return type;
+ }
+ render() {
+ const {listdata, threshold, prefixCls} = this.props;
+
+ if (!listdata || listdata.length === 0) return null;
+
+ const classNames = [prefixCls];
+ let items;
+ if (listdata.length > threshold) {
+ items = new Array(threshold).fill('gray');
+ classNames.push(`${prefixCls}-overflow`);
+ } else {
+ items = listdata.map(item => item.type);
+ }
+ const el = (
+ { items.map(function (type, i) {
+ return (●);
+ }.bind(this)) }
+
);
+
+ return (
+ }>{el}
+ );
+ }
+}
+Notes.propTypes = {
+ listdata: PropTypes.array,
+ threshold: PropTypes.number,
+ prefixCls: PropTypes.string,
+};
+Notes.defaultProps = {
+ listdata: null,
+ threshold: 3,
+ prefixCls: 'calendar-notes',
+};
+
+class MonthCellNoteNum extends Component {
+ render() {
+ const {num} = this.props;
+ return (
+
+
+ 待办事项数
+
+ );
+ }
+}
+MonthCellNoteNum.propTypes = {
+ num: PropTypes.number,
+ prefixCls: PropTypes.string,
+};
+MonthCellNoteNum.defaultProps = {
+ num: 0,
+ prefixCls: 'calendar-notes',
+};
+
+function zerofixed (v) {
+ if (v < 10) return '0' + v;
+ return v + '';
+}
+
+class NoticeCalendar extends Component {
+ monthCellRender(value, locale) {
+ const month = value.getMonth();
+ const noteNum = this.props.getMonthData(value);
+ if (noteNum > 0) {
+ return (
+
+ {locale.format.shortMonths[month]}
+
+
+ );
+ }
+
+ return (
+ {locale.format.shortMonths[month]}
+ );
+ }
+ fullscreenDateCellRender(value) {
+ let listdata = this.props.getDateData(value);
+
+ return (
+
+ { zerofixed(value.getDayOfMonth()) }
+
+
+ );
+ }
+ dateCellRender(value) {
+ const el = ({ zerofixed(value.getDayOfMonth()) });
+ const listdata = this.props.getDateData(value);
+ return (
+
+ { el }
+ { }
+
+ );
+ }
+ render() {
+ const props = this.props;
+ const {fullscreen, monthCellRender, dateCellRender, fullscreenDateCellRender} = props;
+
+ const _monthCellRender = monthCellRender ? monthCellRender : this.monthCellRender;
+ const _dateCellRender = dateCellRender ? dateCellRender : this.dateCellRender;
+ const _fullscreenDateCellRender = fullscreenDateCellRender ? fullscreenDateCellRender : this.fullscreenDateCellRender;
+
+ return ();
+ }
+}
+NoticeCalendar.propTypes = {
+ monthCellRender: PropTypes.func,
+ dateCellRender: PropTypes.func,
+ fullDateCellRender: PropTypes.func,
+ getMonthData: PropTypes.func,
+ getDateData: PropTypes.func,
+ fullscreen: PropTypes.bool,
+ locale: PropTypes.object,
+};
+NoticeCalendar.defaultProps = {
+ locale: CalendarLocale,
+ getMonthData: noop,
+ getDateData: noop,
+ fullscreen: false,
+};
+
+
+export default NoticeCalendar;
diff --git a/components/calendar/index.md b/components/calendar/index.md
new file mode 100644
index 0000000000..2588595a97
--- /dev/null
+++ b/components/calendar/index.md
@@ -0,0 +1,33 @@
+# Calendar
+
+- category: Components
+- chinese: 日历
+
+---
+
+可以显示代办事项的日历。
+
+## 何时使用
+
+可以显示内容的日历。
+
+## API
+
+```html
+
+```
+
+| 参数 | 说明 | 类型 | 默认值 |
+|--------------|----------------|----------|--------------|
+| value | 展示日期 | gregorian-calendar object | 当前日期 |
+| fullscrenn | 是否全屏显示 | bool | false |
+| getDateData | 获取日的显示数据 | function | 无 |
+| getMonthData | 获取月的显示数据 | function | 无 |
+| dateCellRendar | 自定义渲染日期单元格 | function | 无 |
+| fullscreenDateCellRendar | 自定义渲染日期单元格(全屏) | function | 无 |
+| monthCellRendar | 自定义渲染月单元格 | function | 无 |
+| locale | 国际化配置 | object | [默认配置](https://github.com/ant-design/ant-design/issues/424) |
+
+
\ No newline at end of file
diff --git a/index.js b/index.js
index cbecea6832..710600f886 100644
--- a/index.js
+++ b/index.js
@@ -58,6 +58,7 @@ const antd = {
Spin: require('./components/spin'),
Form: require('./components/form').Form,
Input: require('./components/form').Input,
+ Calendar: require('./components/calendar'),
};
antd.version = require('./package.json').version;
diff --git a/style/components/calendar.less b/style/components/calendar.less
new file mode 100644
index 0000000000..5de9d907f2
--- /dev/null
+++ b/style/components/calendar.less
@@ -0,0 +1,105 @@
+div.rc-calendar-full { width: 280px; }
+div.rc-calendar-fullscreen { width: 100%; }
+
+.rc-calendar-fullscreen {
+ .rc-calendar-table {
+ table-layout: fixed;
+ }
+
+ .rc-calendar-month-cell-notes {
+ text-align: center;
+ color: #666;
+
+ > section {
+ font-size: 24px;
+ }
+ }
+
+}
+
+.calendar-notes {
+ height: 9px;
+ line-height: 8px;
+ text-align: center;
+ overflow: hidden;
+ border-radius: 4px;
+ bottom: -5px;
+ left: 4px;
+ font-size: 8px;
+ margin: auto;
+ width: 19px;
+ cursor: pointer;
+
+ &-overflow {
+ border: 1px solid #d9d9d9;
+ }
+
+ span&-node-gray {
+ color: #ccc;
+ }
+ span&-node-warn {
+ color: #fac450;
+ }
+ span&-node-normal {
+ color: #2db7f5;
+ }
+ span&-node-error {
+ color: #f60;
+ }
+
+ &-date {
+ width: 20px;
+ height: 20px;
+ line-height: 20px;
+ }
+}
+
+span.calendar-notes-date-full {
+ overflow: auto;
+ padding: 0 8px 8px 8px;
+}
+
+.calendar-notes-list {
+ list-style: none;
+ text-align: left;
+ margin: 0;
+ padding: 0;
+
+
+ & * { vertical-align: middle; }
+
+ > li {
+ color: #999;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+
+ > span:first-child {
+ font-size: 9px;
+ margin-right: 4px;
+ }
+ }
+
+ &-node-gray {
+ color: #ccc;
+ }
+ &-node-warn {
+ color: #fac450;
+ }
+ &-node-normal {
+ color: #2db7f5;
+ }
+ &-node-error {
+ color: #f60;
+ }
+}
+
+.rc-tooltip {
+ .rc-tooltip-inner {
+ padding: 8px 12px;
+ }
+
+}
+
+
+
diff --git a/style/components/index.less b/style/components/index.less
index 318fc647b2..c2a292d9ac 100644
--- a/style/components/index.less
+++ b/style/components/index.less
@@ -35,3 +35,4 @@
@import "badge";
@import "timeline";
@import "spin";
+@import "calendar";