diff --git a/components/calendar/Constants.js b/components/calendar/Constants.js index dfa98bd3fe..0476376b93 100644 --- a/components/calendar/Constants.js +++ b/components/calendar/Constants.js @@ -1,3 +1,3 @@ export default { - PREFIX_CLS: 'ant-calendar', + PREFIX_CLS: 'ant-notice-calendar', }; diff --git a/components/calendar/Header.jsx b/components/calendar/Header.jsx new file mode 100644 index 0000000000..0136890ac6 --- /dev/null +++ b/components/calendar/Header.jsx @@ -0,0 +1,107 @@ +import React, {PropTypes, Component} from 'react'; +import {PREFIX_CLS} from './Constants'; +import Select from '../select'; +import {Group, Button} from '../radio'; + +function noop() {} + +class Header extends Component { + getYearSelectElement(year) { + const {yearSelectOffset, yearSelectTotal, locale, prefixCls, fullscreen} = this.props; + const start = year - yearSelectOffset; + const end = start + yearSelectTotal; + const suffix = locale.year === '年' ? '年' : ''; + + const options = []; + for (let index = start; index < end; index++) { + options.push( ); + } + return ( + + ); + } + getMonthSelectElement(month) { + const props = this.props; + const months = props.locale.format.months; + const {prefixCls, fullscreen} = props; + const options = []; + + for (let index = 0; index < 12; index++) { + options.push(); + } + + return ( + + ); + } + onYearChange(year) { + const newValue = this.props.value.clone(); + newValue.setYear(parseInt(year, 10)); + this.props.onValueChange(newValue); + } + + onMonthChange(month) { + const newValue = this.props.value.clone(); + newValue.setMonth(parseInt(month, 10)); + this.props.onValueChange(newValue); + } + onTypeChange(e) { + this.props.onTypeChange(e.target.value); + } + render() { + const {type, value, prefixCls, locale} = this.props; + + const yearSelect = this.getYearSelectElement(value.getYear()); + + const monthSelect = type === 'date' ? this.getMonthSelectElement(value.getMonth()) : null; + + const typeSwitch = ( + + + + + ); + + return ( +
+ { yearSelect } + { monthSelect } + { typeSwitch } +
+ ); + } +} +Header.propTypes = { + value: PropTypes.object, + locale: PropTypes.object, + yearSelectOffset: PropTypes.number, + yearSelectTotal: PropTypes.number, + onValueChange: PropTypes.func, + onTypeChange: PropTypes.func, + prefixCls: PropTypes.string, + selectPrefixCls: PropTypes.string, + type: PropTypes.string, +}; +Header.defaultProps = { + prefixCls: `${PREFIX_CLS}-header`, + yearSelectOffset: 10, + yearSelectTotal: 20, + onValueChange: noop, + onTypeChange: noop, +}; + +export default Header; diff --git a/components/calendar/NoteList.jsx b/components/calendar/NoteList.jsx index 547278ad6c..51b38e4121 100644 --- a/components/calendar/NoteList.jsx +++ b/components/calendar/NoteList.jsx @@ -21,7 +21,7 @@ NoteList.propTypes = { prefixCls: PropTypes.string, }; NoteList.defaultProps = { - prefixCls: `${PREFIX_CLS}-notes-list`, + prefixCls: `${PREFIX_CLS}-note-list`, }; export default NoteList; diff --git a/components/calendar/Notes.jsx b/components/calendar/Notes.jsx index 477217d9e2..b67f149e73 100644 --- a/components/calendar/Notes.jsx +++ b/components/calendar/Notes.jsx @@ -1,6 +1,6 @@ import React, {PropTypes, Component} from 'react'; import NoteList from './NoteList'; -import Tooltip from '../tooltip'; +import Popover from '../popover'; import {PREFIX_CLS} from './Constants'; class Notes extends Component { @@ -26,7 +26,7 @@ class Notes extends Component { ); return ( - }>{el} + }>{el} ); } } diff --git a/components/calendar/demo/basic.md b/components/calendar/demo/basic.md index 1d3f783e50..69584961c3 100644 --- a/components/calendar/demo/basic.md +++ b/components/calendar/demo/basic.md @@ -36,9 +36,14 @@ function getDateData(value) { return listData; } - +function onChange(value) { + console.log('change'); +} +function onTypeChange(type) { + console.log('Type change: %s.', type); +} ReactDOM.render( - +
, document.getElementById('components-calendar-demo-basic')); ```` diff --git a/components/calendar/demo/fullscreen.md b/components/calendar/demo/fullscreen.md index 8b0535034c..12fe12de46 100644 --- a/components/calendar/demo/fullscreen.md +++ b/components/calendar/demo/fullscreen.md @@ -26,7 +26,9 @@ function getDateData(value) { case 15: listData = [ { type: 'warn', content: '这里是警告事项.' }, - { type: 'normal', content: '这里是普通事项好长啊。。.' }, + { type: 'normal', content: '这里是普通事项好长啊。。....' }, + { type: 'error', content: '这里是错误事项.' }, + { type: 'error', content: '这里是错误事项.' }, { type: 'error', content: '这里是错误事项.' }, { type: 'error', content: '这里是错误事项.' } ]; break; @@ -40,7 +42,7 @@ function getMonthData(value) { return 0; } ReactDOM.render( - + , document.getElementById('components-calendar-demo-fullscreen')); ```` diff --git a/components/calendar/index.jsx b/components/calendar/index.jsx index 3e36fee07f..c4662fd85b 100644 --- a/components/calendar/index.jsx +++ b/components/calendar/index.jsx @@ -1,9 +1,11 @@ import React, {PropTypes, Component} from 'react'; +import GregorianCalendar from 'gregorian-calendar'; import CalendarLocale from 'rc-calendar/lib/locale/zh_CN'; import FullCalendar from 'rc-calendar/lib/FullCalendar'; import Notes from './Notes'; import NoteList from './NoteList'; import {PREFIX_CLS} from './Constants'; +import Header from './Header'; function noop () { return null; } @@ -11,10 +13,15 @@ function zerofixed (v) { if (v < 10) return '0' + v; return v + ''; } +function getNow() { + const value = new GregorianCalendar(); + value.setTime(Date.now()); + return value; +} const MonthCellNoteNum = ({num, prefixCls}) => { return ( -
+
{num}
待办事项数
@@ -22,29 +29,36 @@ const MonthCellNoteNum = ({num, prefixCls}) => { }; class NoticeCalendar extends Component { + constructor(props) { + super(); + this.state = { + value: props.value || getNow(), + type: props.type, + }; + } monthCellRender(value, locale) { const prefixCls = this.props.prefixCls; const month = value.getMonth(); const noteNum = this.props.getMonthData(value); if (noteNum > 0) { return ( - + {locale.format.shortMonths[month]} ); } return ( - {locale.format.shortMonths[month]} + {locale.format.shortMonths[month]} ); } fullscreenDateCellRender(value) { const prefixCls = this.props.prefixCls; let listData = this.props.getDateData(value); return ( - + { zerofixed(value.getDayOfMonth()) } - +
); } @@ -53,24 +67,58 @@ class NoticeCalendar extends Component { const el = ({ zerofixed(value.getDayOfMonth()) }); const listData = this.props.getDateData(value); return ( -
+
{ el } - { (listData && listData.length > 0) ? : null } + { (listData && listData.length > 0) ?
: null }
); } + setValue(value) { + if (this.state.value !== value) { + this.setState({ value }); + this.props.onChange(value); + } + } + setType(type) { + const oldType = this.state.type; + this.setState({ type }); + this.props.onTypeChange(type, oldType); + } + onPanelChange(value) { + if (this.state.type === 'month') { + this.setType('date'); + } + this.setValue(value); + } render() { const props = this.props; - const {fullscreen, monthCellRender, dateCellRender, fullscreenDateCellRender} = props; + const {value, type} = this.state; + const {locale, prefixCls, style, className, fullscreen, monthCellRender, dateCellRender, fullscreenDateCellRender} = props; const _monthCellRender = monthCellRender ? monthCellRender : this.monthCellRender; const _dateCellRender = dateCellRender ? dateCellRender : this.dateCellRender; const _fullscreenDateCellRender = fullscreenDateCellRender ? fullscreenDateCellRender : this.fullscreenDateCellRender; - - return (); + return ( +
+
+ +
+ ); } } NoticeCalendar.propTypes = { @@ -82,6 +130,10 @@ NoticeCalendar.propTypes = { fullscreen: PropTypes.bool, locale: PropTypes.object, prefixCls: PropTypes.string, + className: PropTypes.string, + style: PropTypes.object, + onChange: PropTypes.func, + onTypeChange: PropTypes.func, }; NoticeCalendar.defaultProps = { locale: CalendarLocale, @@ -89,6 +141,9 @@ NoticeCalendar.defaultProps = { getDateData: noop, fullscreen: false, prefixCls: PREFIX_CLS, + onChange: noop, + onTypeChange: noop, + type: 'date', }; export default NoticeCalendar; diff --git a/components/calendar/index.md b/components/calendar/index.md index 9b2ceca6b4..baece6c5ba 100644 --- a/components/calendar/index.md +++ b/components/calendar/index.md @@ -28,3 +28,5 @@ | fullscreenDateCellRendar | 自定义渲染日期单元格(全屏) | function | 无 | | monthCellRendar | 自定义渲染月单元格 | function | 无 | | locale | 国际化配置 | object | [默认配置](https://github.com/ant-design/ant-design/issues/424) | +| onChange | 日期改变 | bool | 无 | +| onTypeChange | 年月切换 | function | 无 | diff --git a/package.json b/package.json index 50800d001a..514b44f0b6 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "gregorian-calendar-format": "~4.0.4", "object-assign": "~4.0.1", "rc-animate": "~2.0.0", - "rc-calendar": "4.0.0-alpha15", + "rc-calendar": "4.0.0-alpha18", "rc-checkbox": "~1.1.1", "rc-collapse": "~1.4.0", "rc-dialog": "~5.2.0", diff --git a/style/components/calendar/NoteList.less b/style/components/calendar/NoteList.less index a1858dea29..2b72438633 100644 --- a/style/components/calendar/NoteList.less +++ b/style/components/calendar/NoteList.less @@ -1,5 +1,6 @@ -.@{calendar-prefix-cls}-notes { +.@{notice-calendar-prefix-cls}-note { &-list { + line-height: 24px; list-style: none; text-align: left; margin: 0; diff --git a/style/components/calendar/Notes.less b/style/components/calendar/Notes.less index 6373fcd064..10ef08247c 100644 --- a/style/components/calendar/Notes.less +++ b/style/components/calendar/Notes.less @@ -1,4 +1,4 @@ -.@{calendar-prefix-cls}-notes { +.@{notice-calendar-prefix-cls}-notes { height: 9px; line-height: 8px; text-align: center; diff --git a/style/components/calendar/index.less b/style/components/calendar/index.less index 76569cb657..d04ed92d53 100644 --- a/style/components/calendar/index.less +++ b/style/components/calendar/index.less @@ -1,95 +1,251 @@ -.@{calendar-prefix-cls}-header{ - &-switcher { - margin-top: 4px; - margin-right: 8px; - float: right; - display: inline-block; - > span { - float: left; - height: 24px; - line-height: 24px; - border: 1px solid @btn-default-border; - padding: 0 10px; +@notice-calendar-prefix-cls: ant-notice-calendar; + +.@{notice-calendar-prefix-cls}-wrapper { + + position: relative; + list-style: none; + font-size: 12px; + text-align: left; + line-height: 1.5; + + .@{notice-calendar-prefix-cls} { + &-month-select { + margin-left: 5px; + } + + &-header { + padding: 11px 16px 11px 0; + text-align: right; + + .ant-radio-group { + margin-left: 10px; + } + + label.ant-radio-button { + height: 22px; + line-height: 22px; + padding: 0 10px; + } + } + + outline: none; + border-top: 1px solid @legend-border-color; + &-date-panel { + position: relative; + outline: none; + } + + &-calendar-body { + padding: 8px 8px 14px; + } + + table { + border-collapse: collapse; + max-width: 100%; + background-color: transparent; + width: 100%; + height: 235px; + } + + table, td, th, td { + border: none; + } + + &-calendar-table { + border-spacing: 0; + margin-bottom: 0; + } + + &-column-header { + line-height: 18px; + padding: 0; + width: 33px; + text-align: center; + .@{notice-calendar-prefix-cls}-column-header-inner { + display: block; + font-weight: normal; + } + } + + &-week-number-header { + .@{notice-calendar-prefix-cls}-column-header-inner { + display: none; + } + } + + &-cell { + padding: 8px 0; + } + + &-date { + display: block; + margin: 0 auto; color: @text-color; - &:first-child { - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - border-right: none; - } - &:last-child { - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - border-left: none; - } - &.normal:hover { - border-color: @primary-color; - box-shadow: 0 0 2px rgba(45, 183, 245, 0.8); + border-radius: 4px; + width: 22px; + height: 22px; + padding: 0; + background: transparent; + line-height: 22px; + text-align: center; + + &:hover { + background: tint(@primary-color, 90%); cursor: pointer; } - &.focus { - border-color: @primary-color; - background-color: @link-hover-color; + } + &-today .@{notice-calendar-prefix-cls}-date { + background: @primary-color; + color: #fff; + } + &-disabled-cell &-date { + cursor: not-allowed; + color: #bcbcbc; + background: #f3f3f3; + border-radius: 0; + width: auto; + + &:hover { + background: #f3f3f3; + } + } + + &-disabled-cell-first-of-row &-date { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + } + + &-disabled-cell-last-of-row &-date { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + } + + &-last-month-cell .@{notice-calendar-prefix-cls}-date, + &-next-month-btn-day .@{notice-calendar-prefix-cls}-date { + color: #ccc; + } + + &-month-panel-table { + table-layout: fixed; + width: 100%; + border-collapse: separate; + } + + &-month-panel-cell { + text-align: center; + + .@{notice-calendar-prefix-cls}-month-panel-month { + display: block; + width: 46px; + margin: 0 auto; + color: @text-color; + border-radius: 4px 4px; + height: 36px; + padding: 0; + background: transparent; + line-height: 36px; + text-align: center; + + &:hover { + background: tint(@primary-color, 90%); + cursor: pointer; + } + } + + &-disabled { + .@{notice-calendar-prefix-cls}-month-panel-month { + color: #bfbfbf; + + &:hover { + background: white; + cursor: not-allowed; + } + } + } + } + + &-month-panel-selected-cell .@{notice-calendar-prefix-cls}-month-panel-month { + background: @primary-color; + color: #fff; + + &:hover { + background: @primary-color; color: #fff; } } - } - .rc-select-selection--single { - height: 24px; - .rc-select-selection__rendered { - line-height: 24px; + &-notes-wrapper { + position: absolute; + width: 100%; + left:0; + bottom: -9px; } } -} + + -.@{calendar-prefix-cls}-fullscreen { - width: 100%; + &-fullscreen { + .@{notice-calendar-prefix-cls} { + border-top: none; + &-table { + table-layout: fixed; + } + &-header { + label.ant-radio-button { + height: 28px; + line-height: 28px; + } + } - .@{calendar-prefix-cls} { - &-table { - table-layout: fixed; - } - &-header { - border-bottom: none; - } - &-column-header { - text-align: right; padding-right: 12px; - } - &-cell { padding:0; } - &-date, - &-month-panel-month { - display: block; - height: 116px; - width: auto; - border-radius: 0; - margin: 0 4px; - border: none; - border-top: 2px solid #eee; - text-align: right; - padding-right: 8px; - color: @text-color; - } - &-today .@{calendar-prefix-cls}-date, - &-month-panel-selected-cell .@{calendar-prefix-cls}-month-panel-month { - border-top-color: @primary-color; - color: @primary-color; - background: none; - } - &-selected-day .@{calendar-prefix-cls}-date, - &-month-panel-selected-cell .@{calendar-prefix-cls}-month-panel-month { - background-color: tint(@primary-color, 90%); - } - &-notes-month-cell { - text-align: center!important; - color: @text-color; + &-fullscreen-month, + &-fullscreen-date { + margin: 0 4px; + display: block; + color: @text-color; + height: 116px; + padding:4px 8px; + text-align: right; + border-top: 2px solid #eee; - > section { - font-size: 24px; + &:hover { + background: tint(@primary-color, 90%); + cursor: pointer; + } + } + + &-column-header { + text-align: right; + padding-right: 12px; + } + &-cell { + padding: 0; + } + &-month-panel-selected-cell .@{notice-calendar-prefix-cls}-fullscreen-month { + background-color: tint(@primary-color, 90%); + color: @text-color; + } + &-month-panel-selected-cell .@{notice-calendar-prefix-cls}-fullscreen-month, + &-today .@{notice-calendar-prefix-cls}-fullscreen-date { + border-top-color: @primary-color; + background-color: tint(@primary-color, 90%); + color: @primary-color; + } + + &-last-month-cell .@{notice-calendar-prefix-cls}-fullscreen-date, + &-next-month-btn-day .@{notice-calendar-prefix-cls}-fullscreen-date { + color: #ccc; + } + &-note-list-wrapper { + height: 90px; + overflow-y: auto; + } + &-notes-month { + text-align: center; + > section { + font-size: 28px; + } } } - &-notes-date-full { - overflow: auto; - padding: 0 8px 8px 8px; - } } -} + +} \ No newline at end of file