rc-calendar
Advanced tools
+596
| 'use strict'; | ||
| var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
| var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | ||
| function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
| function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; } | ||
| var React = require('react'); | ||
| var DATE_ROW_COUNT = 6; | ||
| var DATE_COL_COUNT = 7; | ||
| var DateTimeFormat = require('gregorian-calendar-format'); | ||
| var GregorianCalendar = require('gregorian-calendar'); | ||
| var rcUtil = require('rc-util'); | ||
| var KeyCode = rcUtil.KeyCode; | ||
| var MonthPanel = require('./MonthPanel'); | ||
| var Time = require('./Time'); | ||
| function noop() {} | ||
| function getIdFromDate(d) { | ||
| return 'rc-calendar-' + d.getYear() + '-' + d.getMonth() + '-' + d.getDayOfMonth(); | ||
| } | ||
| function goStartMonth() { | ||
| var next = this.state.value.clone(); | ||
| next.setDayOfMonth(1); | ||
| this.setState({ value: next }); | ||
| } | ||
| function goEndMonth() { | ||
| var next = this.state.value.clone(); | ||
| next.setDayOfMonth(next.getActualMaximum(GregorianCalendar.MONTH)); | ||
| this.setState({ value: next }); | ||
| } | ||
| function goMonth(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addMonth(direction); | ||
| this.setState({ value: next }); | ||
| } | ||
| function goYear(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addYear(direction); | ||
| this.setState({ value: next }); | ||
| } | ||
| function goWeek(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addWeekOfYear(direction); | ||
| this.setState({ value: next }); | ||
| } | ||
| function goDay(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addDayOfMonth(direction); | ||
| this.setState({ value: next }); | ||
| } | ||
| function isSameDay(one, two) { | ||
| return one.getYear() === two.getYear() && one.getMonth() === two.getMonth() && one.getDayOfMonth() === two.getDayOfMonth(); | ||
| } | ||
| function beforeCurrentMonthYear(current, today) { | ||
| if (current.getYear() < today.getYear()) { | ||
| return 1; | ||
| } | ||
| return current.getYear() === today.getYear() && current.getMonth() < today.getMonth(); | ||
| } | ||
| function afterCurrentMonthYear(current, today) { | ||
| if (current.getYear() > today.getYear()) { | ||
| return 1; | ||
| } | ||
| return current.getYear() === today.getYear() && current.getMonth() > today.getMonth(); | ||
| } | ||
| function onFocus() { | ||
| if (this._blurTimer) { | ||
| clearTimeout(this._blurTimer); | ||
| this._blurTimer = null; | ||
| } else { | ||
| this.props.onFocus(); | ||
| } | ||
| } | ||
| function onBlur() { | ||
| var _this = this; | ||
| if (this._blurTimer) { | ||
| clearTimeout(this._blurTimer); | ||
| } | ||
| this._blurTimer = setTimeout(function () { | ||
| _this.props.onBlur(); | ||
| }, 100); | ||
| } | ||
| function chooseToday() { | ||
| var today = this.state.value.clone(); | ||
| today.setTime(Date.now()); | ||
| this.handleSelect(today); | ||
| } | ||
| function handleDayClick(current) { | ||
| this.handleSelect(current); | ||
| } | ||
| function handleSelect(current, keyDownEvent) { | ||
| var props = this.props; | ||
| this.setState({ | ||
| value: current | ||
| }); | ||
| if (!keyDownEvent) { | ||
| props.onSelect(current); | ||
| } | ||
| } | ||
| function clear() { | ||
| this.props.onClear(); | ||
| } | ||
| function onMonthPanelSelect(current) { | ||
| this.setState({ | ||
| value: current, | ||
| showMonthPanel: 0 | ||
| }); | ||
| } | ||
| function handleKeyDown(e) { | ||
| var keyCode = e.keyCode; | ||
| // mac | ||
| var ctrlKey = e.ctrlKey || e.metaKey; | ||
| switch (keyCode) { | ||
| case KeyCode.DOWN: | ||
| goWeek.call(this, 1); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.UP: | ||
| goWeek.call(this, -1); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.LEFT: | ||
| if (ctrlKey) { | ||
| this.previousYear(); | ||
| } else { | ||
| goDay.call(this, -1); | ||
| } | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.RIGHT: | ||
| if (ctrlKey) { | ||
| this.nextYear(); | ||
| } else { | ||
| goDay.call(this, 1); | ||
| } | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.HOME: | ||
| goStartMonth.call(this); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.END: | ||
| goEndMonth.call(this); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.PAGE_DOWN: | ||
| this.nextMonth(); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.PAGE_UP: | ||
| this.previousMonth(); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.ENTER: | ||
| this.props.onSelect(this.state.value); | ||
| e.preventDefault(); | ||
| return true; | ||
| default: | ||
| this.props.onKeyDown(e); | ||
| return true; | ||
| } | ||
| } | ||
| function showMonthPanel() { | ||
| this.setState({ | ||
| showMonthPanel: 1 | ||
| }); | ||
| } | ||
| var Calendar = (function (_React$Component) { | ||
| function Calendar(props) { | ||
| _classCallCheck(this, Calendar); | ||
| _get(Object.getPrototypeOf(Calendar.prototype), 'constructor', this).call(this, props); | ||
| var value = props.value || props.defaultValue; | ||
| if (!value) { | ||
| value = new GregorianCalendar(); | ||
| value.setTime(Date.now()); | ||
| } | ||
| this.dateFormatter = new DateTimeFormat(props.locale.dateFormat); | ||
| this.state = { | ||
| orient: props.orient, | ||
| prefixCls: props.prefixCls || 'rc-calendar', | ||
| value: value | ||
| }; | ||
| // bind methods | ||
| this.onBlur = onBlur.bind(this); | ||
| this.onFocus = onFocus.bind(this); | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| this.nextMonth = goMonth.bind(this, 1); | ||
| this.previousMonth = goMonth.bind(this, -1); | ||
| this.nextYear = goYear.bind(this, 1); | ||
| this.previousYear = goYear.bind(this, -1); | ||
| this.chooseToday = chooseToday.bind(this); | ||
| this.clear = clear.bind(this); | ||
| this.handleSelect = handleSelect.bind(this); | ||
| this.onMonthPanelSelect = onMonthPanelSelect.bind(this); | ||
| this.handleKeyDown = handleKeyDown.bind(this); | ||
| this.showMonthPanel = showMonthPanel.bind(this); | ||
| } | ||
| _inherits(Calendar, _React$Component); | ||
| _createClass(Calendar, [{ | ||
| key: 'shouldComponentUpdate', | ||
| value: function shouldComponentUpdate() { | ||
| return rcUtil.PureRenderMixin.shouldComponentUpdate.apply(this, arguments); | ||
| } | ||
| }, { | ||
| key: 'componentWillReceiveProps', | ||
| value: function componentWillReceiveProps(nextProps) { | ||
| var value = nextProps.value; | ||
| if (value !== undefined) { | ||
| if (!value) { | ||
| value = this.state.value.clone(); | ||
| value.setTime(Date.now()); | ||
| } | ||
| this.setState({ | ||
| value: value | ||
| }); | ||
| } | ||
| if (nextProps.orient) { | ||
| this.setState({ | ||
| orient: nextProps.orient | ||
| }); | ||
| } | ||
| if (nextProps.locale !== this.props.locale) { | ||
| this.dateFormatter = new DateTimeFormat(nextProps.locale.dateFormat); | ||
| } | ||
| } | ||
| }, { | ||
| key: 'renderDates', | ||
| value: function renderDates() { | ||
| var props = this.props; | ||
| var i, j, current; | ||
| var dateTable = []; | ||
| var showWeekNumber = props.showWeekNumber; | ||
| var value = this.state.value; | ||
| var today = value.clone(); | ||
| var prefixClsFn = this.prefixClsFn; | ||
| var cellClass = prefixClsFn('cell'); | ||
| var weekNumberCellClass = prefixClsFn('week-number-cell'); | ||
| var dateClass = prefixClsFn('date'); | ||
| var dateRender = props.dateRender; | ||
| var disabledDate = props.disabledDate; | ||
| var dateFormatter = this.dateFormatter; | ||
| var todayClass = prefixClsFn('today'); | ||
| var selectedClass = prefixClsFn('selected-day'); | ||
| var lastMonthDayClass = prefixClsFn('last-month-cell'); | ||
| var nextMonthDayClass = prefixClsFn('next-month-btn-day'); | ||
| var disabledClass = prefixClsFn('disabled-cell'); | ||
| today.setTime(Date.now()); | ||
| var month1 = value.clone(); | ||
| month1.set(value.getYear(), value.getMonth(), 1); | ||
| var day = month1.getDayOfWeek(); | ||
| var lastMonthDiffDay = (day + 7 - value.getFirstDayOfWeek()) % 7; | ||
| // calculate last month | ||
| var lastMonth1 = month1.clone(); | ||
| lastMonth1.addDayOfMonth(0 - lastMonthDiffDay); | ||
| var passed = 0; | ||
| for (i = 0; i < DATE_ROW_COUNT; i++) { | ||
| for (j = 0; j < DATE_COL_COUNT; j++) { | ||
| current = lastMonth1; | ||
| if (passed) { | ||
| current = current.clone(); | ||
| current.addDayOfMonth(passed); | ||
| } | ||
| dateTable.push(current); | ||
| passed++; | ||
| } | ||
| } | ||
| var tableHtml = []; | ||
| passed = 0; | ||
| for (i = 0; i < DATE_ROW_COUNT; i++) { | ||
| var weekNumberCell; | ||
| var dateCells = []; | ||
| if (showWeekNumber) { | ||
| weekNumberCell = React.createElement( | ||
| 'td', | ||
| { key: dateTable[passed].getWeekOfYear(), role: 'gridcell', className: weekNumberCellClass }, | ||
| dateTable[passed].getWeekOfYear() | ||
| ); | ||
| } | ||
| for (j = 0; j < DATE_COL_COUNT; j++) { | ||
| current = dateTable[passed]; | ||
| var cls = cellClass; | ||
| var disabled = false; | ||
| var selected = false; | ||
| if (isSameDay(current, today)) { | ||
| cls += ' ' + todayClass; | ||
| } | ||
| if (isSameDay(current, value)) { | ||
| cls += ' ' + selectedClass; | ||
| selected = true; | ||
| } | ||
| if (beforeCurrentMonthYear(current, value)) { | ||
| cls += ' ' + lastMonthDayClass; | ||
| } | ||
| if (afterCurrentMonthYear(current, value)) { | ||
| cls += ' ' + nextMonthDayClass; | ||
| } | ||
| if (disabledDate && disabledDate(current, value)) { | ||
| cls += ' ' + disabledClass; | ||
| disabled = true; | ||
| } | ||
| var dateHtml; | ||
| if (!(dateRender && (dateHtml = dateRender(current, value)))) { | ||
| dateHtml = React.createElement( | ||
| 'span', | ||
| { | ||
| key: getIdFromDate(current), | ||
| className: dateClass, | ||
| 'aria-selected': selected, | ||
| 'aria-disabled': disabled }, | ||
| current.getDayOfMonth() | ||
| ); | ||
| } | ||
| dateCells.push(React.createElement( | ||
| 'td', | ||
| { key: passed, onClick: disabled ? noop : handleDayClick.bind(this, current), role: 'gridcell', title: dateFormatter.format(current), className: cls }, | ||
| dateHtml | ||
| )); | ||
| passed++; | ||
| } | ||
| tableHtml.push(React.createElement( | ||
| 'tr', | ||
| { | ||
| key: i, | ||
| role: 'row' }, | ||
| weekNumberCell, | ||
| dateCells | ||
| )); | ||
| } | ||
| this.dateTable = dateTable; | ||
| return tableHtml; | ||
| } | ||
| }, { | ||
| key: 'getTodayTime', | ||
| value: function getTodayTime() { | ||
| var value = this.state.value; | ||
| var today = value.clone(); | ||
| today.setTime(Date.now()); | ||
| return this.dateFormatter.format(today); | ||
| } | ||
| }, { | ||
| key: 'getMonthYear', | ||
| value: function getMonthYear() { | ||
| var locale = this.props.locale; | ||
| var value = this.state.value; | ||
| return new DateTimeFormat(locale.monthYearFormat).format(value); | ||
| } | ||
| }, { | ||
| key: 'render', | ||
| value: function render() { | ||
| // console.log('re render'); | ||
| var showWeekNumberEl; | ||
| var props = this.props; | ||
| var locale = props.locale; | ||
| var state = this.state; | ||
| var value = state.value; | ||
| var veryShortWeekdays = []; | ||
| var weekDays = []; | ||
| var firstDayOfWeek = value.getFirstDayOfWeek(); | ||
| var prefixCls = state.prefixCls; | ||
| var prefixClsFn = this.prefixClsFn; | ||
| for (var i = 0; i < DATE_COL_COUNT; i++) { | ||
| var index = (firstDayOfWeek + i) % DATE_COL_COUNT; | ||
| veryShortWeekdays[i] = locale.format.veryShortWeekdays[index]; | ||
| weekDays[i] = locale.format.weekdays[index]; | ||
| } | ||
| if (props.showWeekNumber) { | ||
| showWeekNumberEl = React.createElement( | ||
| 'th', | ||
| { role: 'columnheader', className: prefixClsFn('column-header', 'week-number-header') }, | ||
| React.createElement( | ||
| 'span', | ||
| { className: prefixClsFn('column-header-inner') }, | ||
| 'x' | ||
| ) | ||
| ); | ||
| } | ||
| var weekDaysEls = weekDays.map(function (day, xindex) { | ||
| return React.createElement( | ||
| 'th', | ||
| { key: xindex, role: 'columnheader', title: day, className: prefixClsFn('column-header') }, | ||
| React.createElement( | ||
| 'span', | ||
| { className: prefixClsFn('column-header-inner') }, | ||
| veryShortWeekdays[xindex] | ||
| ) | ||
| ); | ||
| }); | ||
| var footerEl; | ||
| if (props.showToday || props.showTime) { | ||
| var todayEl; | ||
| if (props.showToday) { | ||
| todayEl = React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('today-btn'), | ||
| role: 'button', | ||
| onClick: this.chooseToday, | ||
| title: this.getTodayTime() }, | ||
| locale.today | ||
| ); | ||
| } | ||
| var clearEl; | ||
| if (props.showClear) { | ||
| clearEl = React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('clear-btn'), | ||
| role: 'button', | ||
| onClick: this.clear }, | ||
| locale.clear | ||
| ); | ||
| } | ||
| var footerBtn; | ||
| if (todayEl || clearEl) { | ||
| footerBtn = React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('footer-btn') }, | ||
| todayEl, | ||
| ' ', | ||
| clearEl | ||
| ); | ||
| } | ||
| var timeEl; | ||
| if (props.showTime) { | ||
| timeEl = React.createElement(Time, { value: value, rootPrefixCls: prefixCls, prefixClsFn: prefixClsFn, locale: locale, onChange: this.handleSelect }); | ||
| } | ||
| footerEl = React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('footer') }, | ||
| timeEl, | ||
| footerBtn | ||
| ); | ||
| } | ||
| var monthPanel; | ||
| if (state.showMonthPanel) { | ||
| monthPanel = React.createElement(MonthPanel, { locale: locale, value: value, rootPrefixCls: state.prefixCls, onSelect: this.onMonthPanelSelect }); | ||
| } | ||
| var className = prefixCls; | ||
| if (props.className) { | ||
| className += ' ' + props.className; | ||
| } | ||
| var orient = state.orient; | ||
| if (orient) { | ||
| orient.forEach(function (o) { | ||
| className += ' ' + prefixClsFn('orient-' + o); | ||
| }); | ||
| } | ||
| return React.createElement( | ||
| 'div', | ||
| { className: className, tabIndex: '0', onFocus: this.onFocus, onBlur: this.onBlur, onKeyDown: this.handleKeyDown }, | ||
| React.createElement( | ||
| 'div', | ||
| { style: { outline: 'none' } }, | ||
| React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('header') }, | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('prev-year-btn'), | ||
| role: 'button', | ||
| onClick: this.previousYear, | ||
| title: locale.previousYear }, | ||
| '«' | ||
| ), | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('prev-month-btn'), | ||
| role: 'button', | ||
| onClick: this.previousMonth, | ||
| title: locale.previousMonth }, | ||
| '‹' | ||
| ), | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('month-select'), | ||
| role: 'button', | ||
| onClick: this.showMonthPanel, | ||
| title: locale.monthSelect }, | ||
| React.createElement( | ||
| 'span', | ||
| { className: prefixClsFn('month-select-content') }, | ||
| this.getMonthYear() | ||
| ), | ||
| React.createElement( | ||
| 'span', | ||
| { className: prefixClsFn('month-select-arrow') }, | ||
| 'x' | ||
| ) | ||
| ), | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('next-month-btn'), | ||
| onClick: this.nextMonth, | ||
| title: locale.nextMonth }, | ||
| '›' | ||
| ), | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('next-year-btn'), | ||
| onClick: this.nextYear, | ||
| title: locale.nextYear }, | ||
| '»' | ||
| ) | ||
| ), | ||
| React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('calendar-body') }, | ||
| React.createElement( | ||
| 'table', | ||
| { className: prefixClsFn('table'), cellSpacing: '0', role: 'grid' }, | ||
| React.createElement( | ||
| 'thead', | ||
| null, | ||
| React.createElement( | ||
| 'tr', | ||
| { role: 'row' }, | ||
| showWeekNumberEl, | ||
| weekDaysEls | ||
| ) | ||
| ), | ||
| React.createElement( | ||
| 'tbody', | ||
| { className: prefixClsFn('tbody') }, | ||
| this.renderDates() | ||
| ) | ||
| ) | ||
| ), | ||
| footerEl | ||
| ), | ||
| monthPanel | ||
| ); | ||
| } | ||
| }]); | ||
| return Calendar; | ||
| })(React.Component); | ||
| Calendar.propTypes = { | ||
| value: React.PropTypes.object, | ||
| defaultValue: React.PropTypes.object, | ||
| className: React.PropTypes.string, | ||
| orient: React.PropTypes.arrayOf(React.PropTypes.oneOf(['left', 'top', 'right', 'bottom'])), | ||
| locale: React.PropTypes.object, | ||
| showWeekNumber: React.PropTypes.bool, | ||
| showToday: React.PropTypes.bool, | ||
| showTime: React.PropTypes.bool, | ||
| onSelect: React.PropTypes.func, | ||
| onBlur: React.PropTypes.func | ||
| }; | ||
| Calendar.defaultProps = { | ||
| locale: require('./locale/en-us'), | ||
| onKeyDown: noop, | ||
| className: '', | ||
| showToday: true, | ||
| onSelect: noop, | ||
| onFocus: noop, | ||
| onBlur: noop, | ||
| onClear: noop | ||
| }; | ||
| module.exports = Calendar; |
| 'use strict'; | ||
| var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
| var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | ||
| function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
| function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; } | ||
| var React = require('react'); | ||
| var ROW = 4; | ||
| var COL = 3; | ||
| var cx = require('rc-util').classSet; | ||
| function goYear(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addYear(direction); | ||
| this.setState({ | ||
| value: next | ||
| }); | ||
| } | ||
| function chooseDecade(year, e) { | ||
| var next = this.state.value.clone(); | ||
| next.setYear(year); | ||
| this.props.onSelect(next); | ||
| e.preventDefault(); | ||
| } | ||
| var DecadePanel = (function (_React$Component) { | ||
| function DecadePanel(props) { | ||
| _classCallCheck(this, DecadePanel); | ||
| _get(Object.getPrototypeOf(DecadePanel.prototype), 'constructor', this).call(this, props); | ||
| this.state = { | ||
| value: props.value, | ||
| prefixCls: props.rootPrefixCls + '-decade-panel' | ||
| }; | ||
| // bind methods | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| this.nextCentury = goYear.bind(this, 100); | ||
| this.previousCentury = goYear.bind(this, -100); | ||
| } | ||
| _inherits(DecadePanel, _React$Component); | ||
| _createClass(DecadePanel, [{ | ||
| key: 'render', | ||
| value: function render() { | ||
| var _this = this; | ||
| var value = this.state.value; | ||
| var locale = this.props.locale; | ||
| var currentYear = value.getYear(); | ||
| var startYear = parseInt(currentYear / 100, 10) * 100; | ||
| var preYear = startYear - 10; | ||
| var endYear = startYear + 99; | ||
| var decades = []; | ||
| var index = 0; | ||
| var prefixClsFn = this.prefixClsFn; | ||
| for (var i = 0; i < ROW; i++) { | ||
| decades[i] = []; | ||
| for (var j = 0; j < COL; j++) { | ||
| decades[i][j] = { | ||
| startDecade: preYear + index * 10, | ||
| endDecade: preYear + index * 10 + 9 | ||
| }; | ||
| index++; | ||
| } | ||
| } | ||
| var decadesEls = decades.map(function (row, decadeIndex) { | ||
| var tds = row.map(function (d) { | ||
| var startDecade = d.startDecade; | ||
| var endDecade = d.endDecade; | ||
| var classNameMap = {}; | ||
| classNameMap[prefixClsFn('cell')] = 1; | ||
| classNameMap[prefixClsFn('selected-cell')] = startDecade <= currentYear && currentYear <= endDecade; | ||
| classNameMap[prefixClsFn('last-century-cell')] = startDecade < startYear; | ||
| classNameMap[prefixClsFn('next-century-cell')] = endDecade > endYear; | ||
| return React.createElement( | ||
| 'td', | ||
| { | ||
| key: startDecade, | ||
| onClick: chooseDecade.bind(_this, startDecade), | ||
| role: 'gridcell', | ||
| className: cx(classNameMap) | ||
| }, | ||
| React.createElement( | ||
| 'a', | ||
| { | ||
| className: prefixClsFn('decade') }, | ||
| startDecade, | ||
| ' - ', | ||
| endDecade | ||
| ) | ||
| ); | ||
| }); | ||
| return React.createElement( | ||
| 'tr', | ||
| { key: decadeIndex, role: 'row' }, | ||
| tds | ||
| ); | ||
| }); | ||
| return React.createElement( | ||
| 'div', | ||
| { className: this.state.prefixCls }, | ||
| React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('header') }, | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('prev-century-btn'), | ||
| role: 'button', | ||
| onClick: this.previousCentury, | ||
| title: locale.previousCentury }, | ||
| '«' | ||
| ), | ||
| React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('century') }, | ||
| startYear, | ||
| '-', | ||
| endYear | ||
| ), | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('next-century-btn'), | ||
| role: 'button', | ||
| onClick: this.nextCentury, | ||
| title: locale.nextCentury }, | ||
| '»' | ||
| ) | ||
| ), | ||
| React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('body') }, | ||
| React.createElement( | ||
| 'table', | ||
| { className: prefixClsFn('table'), cellSpacing: '0', role: 'grid' }, | ||
| React.createElement( | ||
| 'tbody', | ||
| { className: prefixClsFn('tbody') }, | ||
| decadesEls | ||
| ) | ||
| ) | ||
| ) | ||
| ); | ||
| } | ||
| }]); | ||
| return DecadePanel; | ||
| })(React.Component); | ||
| DecadePanel.defaultProps = { | ||
| onSelect: function onSelect() {} | ||
| }; | ||
| module.exports = DecadePanel; |
| 'use strict'; | ||
| module.exports = require('./Calendar'); | ||
| module.exports.Picker = require('./Picker'); |
| 'use strict'; | ||
| var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
| var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | ||
| function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
| function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; } | ||
| var React = require('react'); | ||
| var DateTimeFormat = require('gregorian-calendar-format'); | ||
| var ROW = 3; | ||
| var COL = 4; | ||
| var cx = require('rc-util').classSet; | ||
| var YearPanel = require('./YearPanel'); | ||
| function goYear(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addYear(direction); | ||
| this.setState({ | ||
| value: next | ||
| }); | ||
| } | ||
| function showYearPanel() { | ||
| this.setState({ | ||
| showYearPanel: 1 | ||
| }); | ||
| } | ||
| function chooseMonth(month) { | ||
| var next = this.state.value.clone(); | ||
| next.setMonth(month); | ||
| this.props.onSelect(next); | ||
| } | ||
| function onYearPanelSelect(current) { | ||
| this.setState({ | ||
| value: current, | ||
| showYearPanel: 0 | ||
| }); | ||
| } | ||
| var MonthPanel = (function (_React$Component) { | ||
| function MonthPanel(props) { | ||
| _classCallCheck(this, MonthPanel); | ||
| _get(Object.getPrototypeOf(MonthPanel.prototype), 'constructor', this).call(this, props); | ||
| this.state = { | ||
| value: this.props.value, | ||
| prefixCls: this.props.rootPrefixCls + '-month-panel' | ||
| }; | ||
| // bind methods | ||
| this.nextYear = goYear.bind(this, 1); | ||
| this.previousYear = goYear.bind(this, -1); | ||
| this.showYearPanel = showYearPanel.bind(this); | ||
| this.onYearPanelSelect = onYearPanelSelect.bind(this); | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| } | ||
| _inherits(MonthPanel, _React$Component); | ||
| _createClass(MonthPanel, [{ | ||
| key: 'getMonths', | ||
| value: function getMonths() { | ||
| var props = this.props; | ||
| var value = this.state.value; | ||
| var current = value.clone(); | ||
| var locale = props.locale; | ||
| var monthYearFormat = locale.monthYearFormat; | ||
| var dateFormatter = new DateTimeFormat(monthYearFormat); | ||
| var months = []; | ||
| var shortMonths = locale.format.shortMonths; | ||
| var index = 0; | ||
| for (var i = 0; i < ROW; i++) { | ||
| months[i] = []; | ||
| for (var j = 0; j < COL; j++) { | ||
| current.setMonth(index); | ||
| months[i][j] = { | ||
| value: index, | ||
| content: shortMonths[index], | ||
| title: dateFormatter.format(current) | ||
| }; | ||
| index++; | ||
| } | ||
| } | ||
| return months; | ||
| } | ||
| }, { | ||
| key: 'render', | ||
| value: function render() { | ||
| var _this = this; | ||
| var props = this.props; | ||
| var value = this.state.value; | ||
| var locale = props.locale; | ||
| var months = this.getMonths(); | ||
| var year = value.getYear(); | ||
| var currentMonth = value.getMonth(); | ||
| var prefixClsFn = this.prefixClsFn; | ||
| var monthsEls = months.map(function (month, index) { | ||
| var tds = month.map(function (m) { | ||
| var classNameMap = {}; | ||
| classNameMap[prefixClsFn('cell')] = 1; | ||
| classNameMap[prefixClsFn('selected-cell')] = m.value === currentMonth; | ||
| return React.createElement( | ||
| 'td', | ||
| { role: 'gridcell', | ||
| key: m.value, | ||
| onClick: chooseMonth.bind(_this, m.value), | ||
| title: m.title, | ||
| className: cx(classNameMap) }, | ||
| React.createElement( | ||
| 'a', | ||
| { | ||
| className: prefixClsFn('month') }, | ||
| m.content | ||
| ) | ||
| ); | ||
| }); | ||
| return React.createElement( | ||
| 'tr', | ||
| { key: index, role: 'row' }, | ||
| tds | ||
| ); | ||
| }); | ||
| var yearPanel; | ||
| if (this.state.showYearPanel) { | ||
| yearPanel = React.createElement(YearPanel, { locale: locale, value: value, rootPrefixCls: props.rootPrefixCls, onSelect: this.onYearPanelSelect }); | ||
| } | ||
| return React.createElement( | ||
| 'div', | ||
| { className: this.state.prefixCls }, | ||
| React.createElement( | ||
| 'div', | ||
| null, | ||
| React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('header') }, | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('prev-year-btn'), | ||
| role: 'button', | ||
| onClick: this.previousYear, | ||
| title: locale.previousYear }, | ||
| '«' | ||
| ), | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('year-select'), | ||
| role: 'button', | ||
| onClick: this.showYearPanel, | ||
| title: locale.yearSelect }, | ||
| React.createElement( | ||
| 'span', | ||
| { className: prefixClsFn('year-select-content') }, | ||
| year | ||
| ), | ||
| React.createElement( | ||
| 'span', | ||
| { className: prefixClsFn('year-select-arrow') }, | ||
| 'x' | ||
| ) | ||
| ), | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('next-year-btn'), | ||
| role: 'button', | ||
| onClick: this.nextYear, | ||
| title: locale.nextYear }, | ||
| '»' | ||
| ) | ||
| ), | ||
| React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('body') }, | ||
| React.createElement( | ||
| 'table', | ||
| { className: prefixClsFn('table'), cellSpacing: '0', role: 'grid' }, | ||
| React.createElement( | ||
| 'tbody', | ||
| { className: prefixClsFn('tbody') }, | ||
| monthsEls | ||
| ) | ||
| ) | ||
| ) | ||
| ), | ||
| yearPanel | ||
| ); | ||
| } | ||
| }]); | ||
| return MonthPanel; | ||
| })(React.Component); | ||
| MonthPanel.defaultProps = { | ||
| onSelect: function onSelect() {} | ||
| }; | ||
| module.exports = MonthPanel; |
+299
| 'use strict'; | ||
| var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
| var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | ||
| function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
| function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; } | ||
| var React = require('react'); | ||
| var DateTimeFormat = require('gregorian-calendar-format'); | ||
| var rcUtil = require('rc-util'); | ||
| var KeyCode = require('rc-util').KeyCode; | ||
| var domAlign = require('dom-align'); | ||
| var orientMap = { | ||
| tl: ['top', 'left'], | ||
| tr: ['top', 'right'], | ||
| bl: ['bottom', 'left'], | ||
| br: ['bottom', 'right'] | ||
| }; | ||
| function getImmutableOrient(orient) { | ||
| if (orient) { | ||
| for (var i in orientMap) { | ||
| var original = orientMap[i]; | ||
| if (original[0] === orient[0] && original[1] === orient[1]) { | ||
| return original; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| function refFn(field, component) { | ||
| this[field] = component; | ||
| } | ||
| /** | ||
| * DatePicker = wrap input using Calendar | ||
| */ | ||
| var Picker = (function (_React$Component) { | ||
| function Picker(props) { | ||
| var _this = this; | ||
| _classCallCheck(this, Picker); | ||
| _get(Object.getPrototypeOf(Picker.prototype), 'constructor', this).call(this, props); | ||
| this.state = { | ||
| open: props.open, | ||
| value: props.value || props.defaultValue | ||
| }; | ||
| var events = ['handleInputClick', 'handleCalendarBlur', 'handleTriggerClick', 'handleCalendarClear', 'handleCalendarKeyDown', 'handleKeyDown', 'handleCalendarSelect']; | ||
| // bind methods | ||
| events.forEach(function (m) { | ||
| _this[m] = _this[m].bind(_this); | ||
| }); | ||
| this.saveCalendarRef = refFn.bind(this, 'calendarInstance'); | ||
| this.saveInputRef = refFn.bind(this, 'inputInstance'); | ||
| } | ||
| _inherits(Picker, _React$Component); | ||
| _createClass(Picker, [{ | ||
| key: 'componentWillReceiveProps', | ||
| value: function componentWillReceiveProps(nextProps) { | ||
| if (nextProps.value) { | ||
| this.setState({ | ||
| value: nextProps.value | ||
| }); | ||
| } | ||
| } | ||
| }, { | ||
| key: 'open', | ||
| value: function open(callback) { | ||
| this.setState({ | ||
| open: true | ||
| }, callback); | ||
| } | ||
| }, { | ||
| key: 'close', | ||
| value: function close(callback) { | ||
| this.setState({ | ||
| open: false | ||
| }, callback); | ||
| } | ||
| }, { | ||
| key: 'handleInputClick', | ||
| value: function handleInputClick() { | ||
| this.toggle(); | ||
| } | ||
| }, { | ||
| key: 'handleTriggerClick', | ||
| value: function handleTriggerClick() { | ||
| this.toggle(); | ||
| } | ||
| }, { | ||
| key: 'toggle', | ||
| value: function toggle(callback) { | ||
| this.setState({ | ||
| open: !this.state.open | ||
| }, callback); | ||
| } | ||
| }, { | ||
| key: 'handleKeyDown', | ||
| value: function handleKeyDown(e) { | ||
| // down | ||
| if (e.keyCode === KeyCode.DOWN) { | ||
| e.preventDefault(); | ||
| this.open(); | ||
| } | ||
| } | ||
| }, { | ||
| key: 'handleCalendarKeyDown', | ||
| value: function handleCalendarKeyDown(e) { | ||
| var _this2 = this; | ||
| if (e.keyCode === KeyCode.ESC) { | ||
| e.stopPropagation(); | ||
| this.close(function () { | ||
| React.findDOMNode(_this2.inputInstance).focus(); | ||
| }); | ||
| } | ||
| } | ||
| }, { | ||
| key: 'handleCalendarSelect', | ||
| value: function handleCalendarSelect(value) { | ||
| var _this3 = this; | ||
| this.props.calendar.props.onSelect(value); | ||
| var currentValue = this.state.value; | ||
| if (this.props.calendar.props.showTime) { | ||
| this.setState({ | ||
| value: value | ||
| }); | ||
| } else { | ||
| this.setState({ | ||
| value: value, | ||
| open: false | ||
| }, function () { | ||
| React.findDOMNode(_this3.inputInstance).focus(); | ||
| }); | ||
| } | ||
| if (!currentValue || currentValue.getTime() !== value.getTime()) { | ||
| this.props.onChange(value); | ||
| } | ||
| } | ||
| }, { | ||
| key: 'handleCalendarBlur', | ||
| value: function handleCalendarBlur() { | ||
| // if invisible, will not trigger blur | ||
| this.setState({ | ||
| open: false | ||
| }); | ||
| } | ||
| }, { | ||
| key: 'handleCalendarClear', | ||
| value: function handleCalendarClear() { | ||
| var _this4 = this; | ||
| this.props.calendar.props.onClear(); | ||
| this.setState({ | ||
| open: false, | ||
| value: null | ||
| }, function () { | ||
| React.findDOMNode(_this4.inputInstance).focus(); | ||
| }); | ||
| if (this.state.value !== null) { | ||
| this.props.onChange(null); | ||
| } | ||
| } | ||
| }, { | ||
| key: 'componentDidMount', | ||
| value: function componentDidMount() { | ||
| this.componentDidUpdate(); | ||
| } | ||
| }, { | ||
| key: 'componentDidUpdate', | ||
| value: function componentDidUpdate() { | ||
| if (this.state.open && !this._lastOpen) { | ||
| var orient = this._cacheCalendar.props.orient; | ||
| var points = ['tl', 'bl']; | ||
| var offset = [0, 5]; | ||
| if (orient.indexOf('top') !== -1 && orient.indexOf('left') !== -1) { | ||
| points = ['tl', 'bl']; | ||
| } else if (orient.indexOf('top') !== -1 && orient.indexOf('right') !== -1) { | ||
| points = ['tr', 'br']; | ||
| } else if (orient.indexOf('bottom') !== -1 && orient.indexOf('left') !== -1) { | ||
| points = ['bl', 'tl']; | ||
| offset = [0, -5]; | ||
| } else if (orient.indexOf('bottom') !== -1 && orient.indexOf('right') !== -1) { | ||
| points = ['br', 'tr']; | ||
| offset = [0, -5]; | ||
| } | ||
| var align = domAlign(React.findDOMNode(this.calendarInstance), React.findDOMNode(this.inputInstance), { | ||
| points: points, | ||
| offset: offset, | ||
| overflow: { | ||
| adjustX: 1, | ||
| adjustY: 1 | ||
| } | ||
| }); | ||
| points = align.points; | ||
| var newOrient = orientMap[points[0]]; | ||
| this.calendarInstance.setState({ | ||
| orient: newOrient | ||
| }); | ||
| React.findDOMNode(this.calendarInstance).focus(); | ||
| } | ||
| this._lastOpen = this.state.open; | ||
| } | ||
| }, { | ||
| key: 'render', | ||
| value: function render() { | ||
| var props = this.props; | ||
| // var input = React.Children.only(props.children); bug 0.13.0 | ||
| /* | ||
| children: Object | ||
| .0: (...) | ||
| get .0: function () { | ||
| set .0: function (value) { | ||
| _reactDidWarn: false | ||
| _reactFragment: Object | ||
| __proto__: Object | ||
| */ | ||
| var input = props.children; | ||
| if (!React.isValidElement(input)) { | ||
| var children = input; | ||
| React.Children.forEach(children, function (m) { | ||
| input = m; | ||
| }); | ||
| } | ||
| var state = this.state; | ||
| var value = state.value; | ||
| var calendar = this._cacheCalendar; | ||
| if (state.open) { | ||
| var calendarInstance = this.calendarInstance; | ||
| var calendarProp = props.calendar; | ||
| this._cacheCalendar = calendar = React.cloneElement(calendarProp, { | ||
| ref: rcUtil.createChainedFunction(calendarProp.props.ref, this.saveCalendarRef), | ||
| value: value, | ||
| // focused: true, | ||
| orient: calendarInstance && calendarInstance.state.orient || getImmutableOrient(calendarProp.props.orient) || orientMap.tl, | ||
| onBlur: this.handleCalendarBlur, | ||
| onKeyDown: this.handleCalendarKeyDown, | ||
| onSelect: this.handleCalendarSelect, | ||
| onClear: this.handleCalendarClear | ||
| }); | ||
| } | ||
| var inputValue = ''; | ||
| if (value) { | ||
| inputValue = props.formatter.format(value); | ||
| } | ||
| input = React.cloneElement(input, { | ||
| ref: rcUtil.createChainedFunction(input.props.ref, this.saveInputRef), | ||
| readOnly: true, | ||
| onClick: this.handleInputClick, | ||
| value: inputValue, | ||
| onKeyDown: this.handleKeyDown | ||
| }); | ||
| var classes = [props.prefixCls]; | ||
| if (state.open) { | ||
| classes.push(props.prefixCls + '-open'); | ||
| } | ||
| var trigger = props.trigger; | ||
| if (trigger) { | ||
| trigger = React.cloneElement(trigger, { | ||
| onClick: this.handleTriggerClick, | ||
| unselectable: true, | ||
| onMouseDown: prevent | ||
| }); | ||
| } | ||
| return React.createElement( | ||
| 'span', | ||
| { className: classes.join(' ') }, | ||
| [input, calendar, trigger] | ||
| ); | ||
| } | ||
| }]); | ||
| return Picker; | ||
| })(React.Component); | ||
| function prevent(e) { | ||
| e.preventDefault(); | ||
| } | ||
| Picker.propTypes = { | ||
| onChange: React.PropTypes.func | ||
| }; | ||
| Picker.defaultProps = { | ||
| prefixCls: 'rc-calendar-picker', | ||
| onChange: function onChange() {}, | ||
| formatter: new DateTimeFormat('yyyy-MM-dd') | ||
| }; | ||
| module.exports = Picker; |
+200
| 'use strict'; | ||
| var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
| var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
| var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | ||
| function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
| function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; } | ||
| var React = require('react'); | ||
| var rcUtil = require('rc-util'); | ||
| var KeyCode = rcUtil.KeyCode; | ||
| var TimePanel = require('./TimePanel'); | ||
| var setHourOfDay = 'setHourOfDay'; | ||
| var setMinutes = 'setMinutes'; | ||
| var setSeconds = 'setSeconds'; | ||
| function padding(number) { | ||
| if (number < 10) { | ||
| number = '0' + number; | ||
| } | ||
| return number; | ||
| } | ||
| function loop(value, min, max) { | ||
| if (value === min - 1) { | ||
| value = max; | ||
| } else if (value === max + 1) { | ||
| value = min; | ||
| } | ||
| return value; | ||
| } | ||
| function keyDownWrap(method, min, max) { | ||
| return function (e) { | ||
| var value = e.target.value; | ||
| var number = parseInt(value, 10); | ||
| var keyCode = e.keyCode; | ||
| var handled; | ||
| if (keyCode === KeyCode.DOWN) { | ||
| number++; | ||
| e.stopPropagation(); | ||
| e.preventDefault(); | ||
| handled = 1; | ||
| } else if (keyCode === KeyCode.UP) { | ||
| number--; | ||
| e.stopPropagation(); | ||
| e.preventDefault(); | ||
| handled = 1; | ||
| } | ||
| if (handled) { | ||
| number = loop(number, min, max); | ||
| var time = this.props.value.clone(); | ||
| time[method](number); | ||
| this.props.onChange(time, e); | ||
| } | ||
| }; | ||
| } | ||
| var Time = (function (_React$Component) { | ||
| function Time(props) { | ||
| var _this = this; | ||
| _classCallCheck(this, Time); | ||
| _get(Object.getPrototypeOf(Time.prototype), 'constructor', this).call(this, props); | ||
| this.state = { | ||
| showHourPanel: 0, | ||
| showMinutePanel: 0, | ||
| showSecondPanel: 0 | ||
| }; | ||
| var events = ['onHourKeyDown', 'onMinuteKeyDown', 'onSecondKeyDown', 'onHourClick', 'onMinuteClick', 'onSecondClick', 'onSelectPanel']; | ||
| events.forEach(function (m) { | ||
| _this[m] = _this[m].bind(_this); | ||
| }); | ||
| } | ||
| _inherits(Time, _React$Component); | ||
| _createClass(Time, [{ | ||
| key: 'onSelectPanel', | ||
| value: function onSelectPanel(value, setter) { | ||
| var _this2 = this; | ||
| this.setState({ | ||
| showHourPanel: 0, | ||
| showMinutePanel: 0, | ||
| showSecondPanel: 0 | ||
| }, function () { | ||
| // ie9 has broken focus | ||
| React.findDOMNode(_this2.refs[setter]).focus(); | ||
| }); | ||
| this.props.onChange(value); | ||
| } | ||
| }, { | ||
| key: 'onHourClick', | ||
| value: function onHourClick() { | ||
| this.setState({ | ||
| showHourPanel: 1, | ||
| showMinutePanel: 0, | ||
| showSecondPanel: 0 | ||
| }); | ||
| } | ||
| }, { | ||
| key: 'onMinuteClick', | ||
| value: function onMinuteClick() { | ||
| this.setState({ | ||
| showHourPanel: 0, | ||
| showMinutePanel: 1, | ||
| showSecondPanel: 0 | ||
| }); | ||
| } | ||
| }, { | ||
| key: 'onSecondClick', | ||
| value: function onSecondClick() { | ||
| this.setState({ | ||
| showHourPanel: 0, | ||
| showMinutePanel: 0, | ||
| showSecondPanel: 1 | ||
| }); | ||
| } | ||
| }, { | ||
| key: 'shouldComponentUpdate', | ||
| value: function shouldComponentUpdate() { | ||
| return rcUtil.PureRenderMixin.shouldComponentUpdate.apply(this, arguments); | ||
| } | ||
| }, { | ||
| key: 'render', | ||
| value: function render() { | ||
| var state = this.state; | ||
| var props = this.props; | ||
| var prefixClsFn = props.prefixClsFn; | ||
| var value = props.value; | ||
| var locale = props.locale; | ||
| var hour = value.getHourOfDay(); | ||
| var minute = value.getMinutes(); | ||
| var second = value.getSeconds(); | ||
| var panel; | ||
| var commonProps = { | ||
| value: value, | ||
| onSelect: this.onSelectPanel, | ||
| rootPrefixCls: props.rootPrefixCls | ||
| }; | ||
| if (state.showHourPanel) { | ||
| panel = React.createElement(TimePanel, _extends({ rowCount: 6, colCount: 4, getter: 'getHourOfDay', setter: setHourOfDay, | ||
| title: locale.hourPanelTitle | ||
| }, commonProps)); | ||
| } else if (state.showMinutePanel) { | ||
| panel = React.createElement(TimePanel, _extends({ rowCount: 6, colCount: 10, getter: 'getMinutes', setter: setMinutes, | ||
| title: locale.minutePanelTitle | ||
| }, commonProps)); | ||
| } else if (state.showSecondPanel) { | ||
| panel = React.createElement(TimePanel, _extends({ rowCount: 6, colCount: 10, getter: 'getSeconds', setter: setSeconds, | ||
| title: locale.secondPanelTitle | ||
| }, commonProps)); | ||
| } | ||
| return React.createElement( | ||
| 'div', | ||
| null, | ||
| React.createElement('input', { className: prefixClsFn('time-input'), title: locale.hourInput, | ||
| ref: setHourOfDay, | ||
| readOnly: true, value: padding(hour), | ||
| onClick: this.onHourClick, | ||
| onKeyDown: this.onHourKeyDown }), | ||
| React.createElement( | ||
| 'span', | ||
| null, | ||
| ' : ' | ||
| ), | ||
| React.createElement('input', { className: prefixClsFn('time-input'), title: locale.minuteInput, | ||
| ref: setMinutes, | ||
| readOnly: true, value: padding(minute), | ||
| onClick: this.onMinuteClick, | ||
| onKeyDown: this.onMinuteKeyDown }), | ||
| React.createElement( | ||
| 'span', | ||
| null, | ||
| ' : ' | ||
| ), | ||
| React.createElement('input', { className: prefixClsFn('time-input'), title: locale.secondInput, | ||
| ref: setSeconds, | ||
| readOnly: true, value: padding(second), | ||
| onClick: this.onSecondClick, | ||
| onKeyDown: this.onSecondKeyDown }), | ||
| panel | ||
| ); | ||
| } | ||
| }]); | ||
| return Time; | ||
| })(React.Component); | ||
| Time.prototype.onHourKeyDown = keyDownWrap('setHourOfDay', 0, 23); | ||
| Time.prototype.onMinuteKeyDown = keyDownWrap('setMinutes', 0, 59); | ||
| Time.prototype.onSecondKeyDown = keyDownWrap('setSeconds', 0, 59); | ||
| module.exports = Time; |
+120
| 'use strict'; | ||
| var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
| var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | ||
| function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
| function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; } | ||
| var React = require('react'); | ||
| var cx = require('rc-util').classSet; | ||
| function choose(hour, e) { | ||
| var next = this.state.value.clone(); | ||
| var method = this.props.setter; | ||
| next[method](hour); | ||
| this.props.onSelect(next, method); | ||
| e.preventDefault(); | ||
| } | ||
| var TimePanel = (function (_React$Component) { | ||
| function TimePanel(props) { | ||
| _classCallCheck(this, TimePanel); | ||
| _get(Object.getPrototypeOf(TimePanel.prototype), 'constructor', this).call(this, props); | ||
| this.state = { | ||
| value: props.value, | ||
| prefixCls: props.rootPrefixCls + '-time-panel' | ||
| }; | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| } | ||
| _inherits(TimePanel, _React$Component); | ||
| _createClass(TimePanel, [{ | ||
| key: 'render', | ||
| value: function render() { | ||
| var _this = this; | ||
| var value = this.state.value; | ||
| var props = this.props; | ||
| var method = props.getter; | ||
| var currentHour = value[method](); | ||
| var data = []; | ||
| var prefixClsFn = this.prefixClsFn; | ||
| var ROW = props.rowCount; | ||
| var COL = props.colCount; | ||
| for (var i = 0; i < ROW; i++) { | ||
| data[i] = []; | ||
| for (var j = 0; j < COL; j++) { | ||
| data[i][j] = i * COL + j; | ||
| } | ||
| } | ||
| var hoursEls = data.map(function (row, index) { | ||
| var tds = row.map(function (d) { | ||
| var classNameMap = {}; | ||
| classNameMap[prefixClsFn('cell')] = 1; | ||
| classNameMap[prefixClsFn('selected-cell')] = d === currentHour; | ||
| return React.createElement( | ||
| 'td', | ||
| { | ||
| key: d, | ||
| onClick: choose.bind(_this, d), | ||
| role: 'gridcell', | ||
| className: cx(classNameMap) }, | ||
| React.createElement( | ||
| 'a', | ||
| { | ||
| className: prefixClsFn('time') }, | ||
| d | ||
| ) | ||
| ); | ||
| }); | ||
| return React.createElement( | ||
| 'tr', | ||
| { key: index, role: 'row' }, | ||
| tds | ||
| ); | ||
| }); | ||
| return React.createElement( | ||
| 'div', | ||
| { className: this.state.prefixCls }, | ||
| React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('header') }, | ||
| React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('title') }, | ||
| props.title | ||
| ) | ||
| ), | ||
| React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('body') }, | ||
| React.createElement( | ||
| 'table', | ||
| { className: prefixClsFn('table'), cellSpacing: '0', role: 'grid' }, | ||
| React.createElement( | ||
| 'tbody', | ||
| { className: prefixClsFn('tbody') }, | ||
| hoursEls | ||
| ) | ||
| ) | ||
| ) | ||
| ); | ||
| } | ||
| }]); | ||
| return TimePanel; | ||
| })(React.Component); | ||
| TimePanel.defaultProps = { | ||
| onSelect: function onSelect() {} | ||
| }; | ||
| module.exports = TimePanel; |
+212
| 'use strict'; | ||
| var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
| var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | ||
| function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
| function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; } | ||
| var React = require('react'); | ||
| var DateTimeFormat = require('gregorian-calendar-format'); | ||
| var ROW = 3; | ||
| var COL = 4; | ||
| var cx = require('rc-util').classSet; | ||
| var DecadePanel = require('./DecadePanel'); | ||
| function goYear(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addYear(direction); | ||
| this.setState({ value: next }); | ||
| } | ||
| function chooseYear(year) { | ||
| var next = this.state.value.clone(); | ||
| next.setYear(year); | ||
| this.props.onSelect(next); | ||
| } | ||
| var YearPanel = (function (_React$Component) { | ||
| function YearPanel(props) { | ||
| var _this = this; | ||
| _classCallCheck(this, YearPanel); | ||
| _get(Object.getPrototypeOf(YearPanel.prototype), 'constructor', this).call(this, props); | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| this.state = { | ||
| value: props.value, | ||
| prefixCls: props.rootPrefixCls + '-year-panel' | ||
| }; | ||
| this.nextDecade = goYear.bind(this, 10); | ||
| this.previousDecade = goYear.bind(this, -10); | ||
| ['showDecadePanel', 'onDecadePanelSelect'].forEach(function (m) { | ||
| _this[m] = _this[m].bind(_this); | ||
| }); | ||
| } | ||
| _inherits(YearPanel, _React$Component); | ||
| _createClass(YearPanel, [{ | ||
| key: 'showDecadePanel', | ||
| value: function showDecadePanel() { | ||
| this.setState({ | ||
| showDecadePanel: 1 | ||
| }); | ||
| } | ||
| }, { | ||
| key: 'onDecadePanelSelect', | ||
| value: function onDecadePanelSelect(current) { | ||
| this.setState({ | ||
| value: current, | ||
| showDecadePanel: 0 | ||
| }); | ||
| } | ||
| }, { | ||
| key: 'getYears', | ||
| value: function getYears() { | ||
| var value = this.state.value; | ||
| var currentYear = value.getYear(); | ||
| var startYear = parseInt(currentYear / 10, 10) * 10; | ||
| var preYear = startYear - 1; | ||
| var current = value.clone(); | ||
| var locale = this.props.locale; | ||
| var yearFormat = locale.yearFormat; | ||
| var dateFormatter = new DateTimeFormat(yearFormat); | ||
| var years = []; | ||
| var index = 0; | ||
| for (var i = 0; i < ROW; i++) { | ||
| years[i] = []; | ||
| for (var j = 0; j < COL; j++) { | ||
| current.setYear(preYear + index); | ||
| years[i][j] = { | ||
| content: preYear + index, | ||
| title: dateFormatter.format(current) | ||
| }; | ||
| index++; | ||
| } | ||
| } | ||
| return years; | ||
| } | ||
| }, { | ||
| key: 'render', | ||
| value: function render() { | ||
| var _this2 = this; | ||
| var props = this.props; | ||
| var value = this.state.value; | ||
| var locale = props.locale; | ||
| var years = this.getYears(); | ||
| var currentYear = value.getYear(); | ||
| var startYear = parseInt(currentYear / 10, 10) * 10; | ||
| var endYear = startYear + 9; | ||
| var prefixClsFn = this.prefixClsFn; | ||
| var yeasEls = years.map(function (row, index) { | ||
| var tds = row.map(function (y) { | ||
| var classNameMap = {}; | ||
| classNameMap[prefixClsFn('cell')] = 1; | ||
| classNameMap[prefixClsFn('selected-cell')] = y.content === currentYear; | ||
| classNameMap[prefixClsFn('last-decade-cell')] = y.content < startYear; | ||
| classNameMap[prefixClsFn('next-decade-cell')] = y.content > endYear; | ||
| return React.createElement( | ||
| 'td', | ||
| { role: 'gridcell', | ||
| title: y.title, | ||
| key: y.content, | ||
| onClick: chooseYear.bind(_this2, y.content), | ||
| className: cx(classNameMap) | ||
| }, | ||
| React.createElement( | ||
| 'a', | ||
| { | ||
| className: prefixClsFn('year') }, | ||
| y.content | ||
| ) | ||
| ); | ||
| }); | ||
| return React.createElement( | ||
| 'tr', | ||
| { key: index, role: 'row' }, | ||
| tds | ||
| ); | ||
| }); | ||
| var decadePanel; | ||
| if (this.state.showDecadePanel) { | ||
| decadePanel = React.createElement(DecadePanel, { locale: locale, value: value, rootPrefixCls: props.rootPrefixCls, onSelect: this.onDecadePanelSelect }); | ||
| } | ||
| return React.createElement( | ||
| 'div', | ||
| { className: this.state.prefixCls }, | ||
| React.createElement( | ||
| 'div', | ||
| null, | ||
| React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('header') }, | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('prev-decade-btn'), | ||
| role: 'button', | ||
| onClick: this.previousDecade, | ||
| title: locale.previousDecade }, | ||
| '«' | ||
| ), | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('decade-select'), | ||
| role: 'button', | ||
| onClick: this.showDecadePanel, | ||
| title: locale.decadeSelect }, | ||
| React.createElement( | ||
| 'span', | ||
| { className: prefixClsFn('decade-select-content') }, | ||
| startYear, | ||
| '-', | ||
| endYear | ||
| ), | ||
| React.createElement( | ||
| 'span', | ||
| { className: prefixClsFn('decade-select-arrow') }, | ||
| 'x' | ||
| ) | ||
| ), | ||
| React.createElement( | ||
| 'a', | ||
| { className: prefixClsFn('next-decade-btn'), | ||
| role: 'button', | ||
| onClick: this.nextDecade, | ||
| title: locale.nextDecade }, | ||
| '»' | ||
| ) | ||
| ), | ||
| React.createElement( | ||
| 'div', | ||
| { className: prefixClsFn('body') }, | ||
| React.createElement( | ||
| 'table', | ||
| { className: prefixClsFn('table'), cellSpacing: '0', role: 'grid' }, | ||
| React.createElement( | ||
| 'tbody', | ||
| { className: prefixClsFn('tbody') }, | ||
| yeasEls | ||
| ) | ||
| ) | ||
| ) | ||
| ), | ||
| decadePanel | ||
| ); | ||
| } | ||
| }]); | ||
| return YearPanel; | ||
| })(React.Component); | ||
| YearPanel.defaultProps = { | ||
| onSelect: function onSelect() {} | ||
| }; | ||
| module.exports = YearPanel; |
+518
| 'use strict'; | ||
| var React = require('react'); | ||
| var DATE_ROW_COUNT = 6; | ||
| var DATE_COL_COUNT = 7; | ||
| var DateTimeFormat = require('gregorian-calendar-format'); | ||
| var GregorianCalendar = require('gregorian-calendar'); | ||
| var rcUtil = require('rc-util'); | ||
| var KeyCode = rcUtil.KeyCode; | ||
| var MonthPanel = require('./MonthPanel'); | ||
| var Time = require('./Time'); | ||
| function noop() { | ||
| } | ||
| function getIdFromDate(d) { | ||
| return 'rc-calendar-' + d.getYear() + | ||
| '-' + d.getMonth() + '-' + | ||
| d.getDayOfMonth(); | ||
| } | ||
| function goStartMonth() { | ||
| var next = this.state.value.clone(); | ||
| next.setDayOfMonth(1); | ||
| this.setState({value: next}); | ||
| } | ||
| function goEndMonth() { | ||
| var next = this.state.value.clone(); | ||
| next.setDayOfMonth(next.getActualMaximum(GregorianCalendar.MONTH)); | ||
| this.setState({value: next}); | ||
| } | ||
| function goMonth(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addMonth(direction); | ||
| this.setState({value: next}); | ||
| } | ||
| function goYear(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addYear(direction); | ||
| this.setState({value: next}); | ||
| } | ||
| function goWeek(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addWeekOfYear(direction); | ||
| this.setState({value: next}); | ||
| } | ||
| function goDay(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addDayOfMonth(direction); | ||
| this.setState({value: next}); | ||
| } | ||
| function isSameDay(one, two) { | ||
| return one.getYear() === two.getYear() && | ||
| one.getMonth() === two.getMonth() && | ||
| one.getDayOfMonth() === two.getDayOfMonth(); | ||
| } | ||
| function beforeCurrentMonthYear(current, today) { | ||
| if (current.getYear() < today.getYear()) { | ||
| return 1; | ||
| } | ||
| return current.getYear() === today.getYear() && | ||
| current.getMonth() < today.getMonth(); | ||
| } | ||
| function afterCurrentMonthYear(current, today) { | ||
| if (current.getYear() > today.getYear()) { | ||
| return 1; | ||
| } | ||
| return current.getYear() === today.getYear() && | ||
| current.getMonth() > today.getMonth(); | ||
| } | ||
| function onFocus() { | ||
| if (this._blurTimer) { | ||
| clearTimeout(this._blurTimer); | ||
| this._blurTimer = null; | ||
| } else { | ||
| this.props.onFocus(); | ||
| } | ||
| } | ||
| function onBlur() { | ||
| if (this._blurTimer) { | ||
| clearTimeout(this._blurTimer); | ||
| } | ||
| this._blurTimer = setTimeout(()=> { | ||
| this.props.onBlur(); | ||
| }, 100); | ||
| } | ||
| function chooseToday() { | ||
| var today = this.state.value.clone(); | ||
| today.setTime(Date.now()); | ||
| this.handleSelect(today); | ||
| } | ||
| function handleDayClick(current) { | ||
| this.handleSelect(current); | ||
| } | ||
| function handleSelect(current, keyDownEvent) { | ||
| var props = this.props; | ||
| this.setState({ | ||
| value: current | ||
| }); | ||
| if (!keyDownEvent) { | ||
| props.onSelect(current); | ||
| } | ||
| } | ||
| function clear() { | ||
| this.props.onClear(); | ||
| } | ||
| function onMonthPanelSelect(current) { | ||
| this.setState({ | ||
| value: current, | ||
| showMonthPanel: 0 | ||
| }); | ||
| } | ||
| function handleKeyDown(e) { | ||
| var keyCode = e.keyCode; | ||
| // mac | ||
| var ctrlKey = e.ctrlKey || e.metaKey; | ||
| switch (keyCode) { | ||
| case KeyCode.DOWN: | ||
| goWeek.call(this, 1); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.UP: | ||
| goWeek.call(this, -1); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.LEFT: | ||
| if (ctrlKey) { | ||
| this.previousYear(); | ||
| } else { | ||
| goDay.call(this, -1); | ||
| } | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.RIGHT: | ||
| if (ctrlKey) { | ||
| this.nextYear(); | ||
| } else { | ||
| goDay.call(this, 1); | ||
| } | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.HOME: | ||
| goStartMonth.call(this); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.END: | ||
| goEndMonth.call(this); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.PAGE_DOWN: | ||
| this.nextMonth(); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.PAGE_UP: | ||
| this.previousMonth(); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.ENTER: | ||
| this.props.onSelect(this.state.value); | ||
| e.preventDefault(); | ||
| return true; | ||
| default: | ||
| this.props.onKeyDown(e); | ||
| return true; | ||
| } | ||
| } | ||
| function showMonthPanel() { | ||
| this.setState({ | ||
| showMonthPanel: 1 | ||
| }); | ||
| } | ||
| class Calendar extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| var value = props.value || props.defaultValue; | ||
| if (!value) { | ||
| value = new GregorianCalendar(); | ||
| value.setTime(Date.now()); | ||
| } | ||
| this.dateFormatter = new DateTimeFormat(props.locale.dateFormat); | ||
| this.state = { | ||
| orient: props.orient, | ||
| prefixCls: props.prefixCls || 'rc-calendar', | ||
| value: value | ||
| }; | ||
| // bind methods | ||
| this.onBlur = onBlur.bind(this); | ||
| this.onFocus = onFocus.bind(this); | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| this.nextMonth = goMonth.bind(this, 1); | ||
| this.previousMonth = goMonth.bind(this, -1); | ||
| this.nextYear = goYear.bind(this, 1); | ||
| this.previousYear = goYear.bind(this, -1); | ||
| this.chooseToday = chooseToday.bind(this); | ||
| this.clear = clear.bind(this); | ||
| this.handleSelect = handleSelect.bind(this); | ||
| this.onMonthPanelSelect = onMonthPanelSelect.bind(this); | ||
| this.handleKeyDown = handleKeyDown.bind(this); | ||
| this.showMonthPanel = showMonthPanel.bind(this); | ||
| } | ||
| shouldComponentUpdate() { | ||
| return rcUtil.PureRenderMixin.shouldComponentUpdate.apply(this, arguments); | ||
| } | ||
| componentWillReceiveProps(nextProps) { | ||
| var value = nextProps.value; | ||
| if (value !== undefined) { | ||
| if (!value) { | ||
| value = this.state.value.clone(); | ||
| value.setTime(Date.now()); | ||
| } | ||
| this.setState({ | ||
| value: value | ||
| }); | ||
| } | ||
| if (nextProps.orient) { | ||
| this.setState({ | ||
| orient: nextProps.orient | ||
| }); | ||
| } | ||
| if (nextProps.locale !== this.props.locale) { | ||
| this.dateFormatter = new DateTimeFormat(nextProps.locale.dateFormat); | ||
| } | ||
| } | ||
| renderDates() { | ||
| var props = this.props; | ||
| var i, j, current; | ||
| var dateTable = []; | ||
| var showWeekNumber = props.showWeekNumber; | ||
| var value = this.state.value; | ||
| var today = value.clone(); | ||
| var prefixClsFn = this.prefixClsFn; | ||
| var cellClass = prefixClsFn('cell'); | ||
| var weekNumberCellClass = prefixClsFn('week-number-cell'); | ||
| var dateClass = prefixClsFn('date'); | ||
| var dateRender = props.dateRender; | ||
| var disabledDate = props.disabledDate; | ||
| var dateFormatter = this.dateFormatter; | ||
| var todayClass = prefixClsFn('today'); | ||
| var selectedClass = prefixClsFn('selected-day'); | ||
| var lastMonthDayClass = prefixClsFn('last-month-cell'); | ||
| var nextMonthDayClass = prefixClsFn('next-month-btn-day'); | ||
| var disabledClass = prefixClsFn('disabled-cell'); | ||
| today.setTime(Date.now()); | ||
| var month1 = value.clone(); | ||
| month1.set(value.getYear(), value.getMonth(), 1); | ||
| var day = month1.getDayOfWeek(); | ||
| var lastMonthDiffDay = (day + 7 - value.getFirstDayOfWeek()) % 7; | ||
| // calculate last month | ||
| var lastMonth1 = month1.clone(); | ||
| lastMonth1.addDayOfMonth(0 - lastMonthDiffDay); | ||
| var passed = 0; | ||
| for (i = 0; i < DATE_ROW_COUNT; i++) { | ||
| for (j = 0; j < DATE_COL_COUNT; j++) { | ||
| current = lastMonth1; | ||
| if (passed) { | ||
| current = current.clone(); | ||
| current.addDayOfMonth(passed); | ||
| } | ||
| dateTable.push(current); | ||
| passed++; | ||
| } | ||
| } | ||
| var tableHtml = []; | ||
| passed = 0; | ||
| for (i = 0; i < DATE_ROW_COUNT; i++) { | ||
| var weekNumberCell; | ||
| var dateCells = []; | ||
| if (showWeekNumber) { | ||
| weekNumberCell = ( | ||
| <td key={dateTable[passed].getWeekOfYear()} role="gridcell" className = {weekNumberCellClass}>{dateTable[passed].getWeekOfYear()}</td> | ||
| ); | ||
| } | ||
| for (j = 0; j < DATE_COL_COUNT; j++) { | ||
| current = dateTable[passed]; | ||
| var cls = cellClass; | ||
| var disabled = false; | ||
| var selected = false; | ||
| if (isSameDay(current, today)) { | ||
| cls += ' ' + todayClass; | ||
| } | ||
| if (isSameDay(current, value)) { | ||
| cls += ' ' + selectedClass; | ||
| selected = true; | ||
| } | ||
| if (beforeCurrentMonthYear(current, value)) { | ||
| cls += ' ' + lastMonthDayClass; | ||
| } | ||
| if (afterCurrentMonthYear(current, value)) { | ||
| cls += ' ' + nextMonthDayClass; | ||
| } | ||
| if (disabledDate && disabledDate(current, value)) { | ||
| cls += ' ' + disabledClass; | ||
| disabled = true; | ||
| } | ||
| var dateHtml; | ||
| if (!(dateRender && (dateHtml = dateRender(current, value)))) { | ||
| dateHtml = ( | ||
| <span | ||
| key={getIdFromDate(current)} | ||
| className = {dateClass} | ||
| aria-selected={selected} | ||
| aria-disabled={disabled}> | ||
| {current.getDayOfMonth()} | ||
| </span>); | ||
| } | ||
| dateCells.push( | ||
| <td key={passed} onClick={disabled ? noop : handleDayClick.bind(this, current)} role="gridcell" title={dateFormatter.format(current)} className = {cls}> | ||
| {dateHtml} | ||
| </td>); | ||
| passed++; | ||
| } | ||
| tableHtml.push( | ||
| <tr | ||
| key={i} | ||
| role="row"> | ||
| {weekNumberCell} | ||
| {dateCells} | ||
| </tr>); | ||
| } | ||
| this.dateTable = dateTable; | ||
| return tableHtml; | ||
| } | ||
| getTodayTime() { | ||
| var value = this.state.value; | ||
| var today = value.clone(); | ||
| today.setTime(Date.now()); | ||
| return this.dateFormatter.format(today); | ||
| } | ||
| getMonthYear() { | ||
| var locale = this.props.locale; | ||
| var value = this.state.value; | ||
| return new DateTimeFormat(locale.monthYearFormat).format(value); | ||
| } | ||
| render() { | ||
| // console.log('re render'); | ||
| var showWeekNumberEl; | ||
| var props = this.props; | ||
| var locale = props.locale; | ||
| var state = this.state; | ||
| var value = state.value; | ||
| var veryShortWeekdays = []; | ||
| var weekDays = []; | ||
| var firstDayOfWeek = value.getFirstDayOfWeek(); | ||
| var prefixCls = state.prefixCls; | ||
| var prefixClsFn = this.prefixClsFn; | ||
| for (var i = 0; i < DATE_COL_COUNT; i++) { | ||
| var index = (firstDayOfWeek + i) % DATE_COL_COUNT; | ||
| veryShortWeekdays[i] = locale.format.veryShortWeekdays[index]; | ||
| weekDays[i] = locale.format.weekdays[index]; | ||
| } | ||
| if (props.showWeekNumber) { | ||
| showWeekNumberEl = ( | ||
| <th role="columnheader" className = {prefixClsFn('column-header', 'week-number-header')}> | ||
| <span className ={prefixClsFn('column-header-inner')}>x</span> | ||
| </th>); | ||
| } | ||
| var weekDaysEls = weekDays.map((day, xindex)=> { | ||
| return ( | ||
| <th key={xindex} role="columnheader" title={day} className ={prefixClsFn('column-header')}> | ||
| <span className = {prefixClsFn('column-header-inner')}> | ||
| {veryShortWeekdays[xindex]} | ||
| </span> | ||
| </th>); | ||
| }); | ||
| var footerEl; | ||
| if (props.showToday || props.showTime) { | ||
| var todayEl; | ||
| if (props.showToday) { | ||
| todayEl = (<a className = {prefixClsFn('today-btn')} | ||
| role="button" | ||
| onClick={this.chooseToday} | ||
| title={this.getTodayTime()}>{locale.today}</a>); | ||
| } | ||
| var clearEl; | ||
| if (props.showClear) { | ||
| clearEl = (<a className = {prefixClsFn('clear-btn')} | ||
| role="button" | ||
| onClick={this.clear}>{locale.clear}</a>); | ||
| } | ||
| var footerBtn; | ||
| if (todayEl || clearEl) { | ||
| footerBtn = <div className={prefixClsFn('footer-btn')}>{todayEl} {clearEl}</div>; | ||
| } | ||
| var timeEl; | ||
| if (props.showTime) { | ||
| timeEl = (<Time value={value} rootPrefixCls={prefixCls} prefixClsFn={prefixClsFn} locale={locale} onChange={this.handleSelect}/>); | ||
| } | ||
| footerEl = ( | ||
| <div className = {prefixClsFn('footer')}> | ||
| {timeEl} | ||
| {footerBtn} | ||
| </div>); | ||
| } | ||
| var monthPanel; | ||
| if (state.showMonthPanel) { | ||
| monthPanel = <MonthPanel locale={locale} value={value} rootPrefixCls={state.prefixCls} onSelect={this.onMonthPanelSelect}/>; | ||
| } | ||
| var className = prefixCls; | ||
| if (props.className) { | ||
| className += ' ' + props.className; | ||
| } | ||
| var orient = state.orient; | ||
| if (orient) { | ||
| orient.forEach(o => { | ||
| className += ' ' + prefixClsFn('orient-' + o); | ||
| }); | ||
| } | ||
| return ( | ||
| <div className = {className} tabIndex="0" onFocus={this.onFocus} onBlur={this.onBlur} onKeyDown={this.handleKeyDown}> | ||
| <div style={{outline: 'none'}}> | ||
| <div className = {prefixClsFn('header')}> | ||
| <a className ={prefixClsFn('prev-year-btn')} | ||
| role="button" | ||
| onClick={this.previousYear} | ||
| title={locale.previousYear}> | ||
| « | ||
| </a> | ||
| <a className = {prefixClsFn('prev-month-btn')} | ||
| role="button" | ||
| onClick={this.previousMonth} | ||
| title={locale.previousMonth}> | ||
| ‹ | ||
| </a> | ||
| <a className = {prefixClsFn('month-select')} | ||
| role="button" | ||
| onClick={this.showMonthPanel} | ||
| title={locale.monthSelect}> | ||
| <span className = {prefixClsFn('month-select-content')}>{this.getMonthYear()}</span> | ||
| <span className = {prefixClsFn('month-select-arrow')}>x</span> | ||
| </a> | ||
| <a className = {prefixClsFn('next-month-btn')} | ||
| onClick={this.nextMonth} | ||
| title={locale.nextMonth}> | ||
| › | ||
| </a> | ||
| <a className = {prefixClsFn('next-year-btn')} | ||
| onClick={this.nextYear} | ||
| title={locale.nextYear}> | ||
| » | ||
| </a> | ||
| </div> | ||
| <div className = {prefixClsFn('calendar-body')}> | ||
| <table className = {prefixClsFn('table')} cellSpacing="0" role="grid"> | ||
| <thead> | ||
| <tr role="row"> | ||
| {showWeekNumberEl} | ||
| {weekDaysEls} | ||
| </tr> | ||
| </thead> | ||
| <tbody className = {prefixClsFn('tbody')}> | ||
| {this.renderDates()} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| {footerEl} | ||
| </div> | ||
| {monthPanel} | ||
| </div>); | ||
| } | ||
| } | ||
| Calendar.propTypes = { | ||
| value: React.PropTypes.object, | ||
| defaultValue: React.PropTypes.object, | ||
| className: React.PropTypes.string, | ||
| orient: React.PropTypes.arrayOf(React.PropTypes.oneOf(['left', 'top', 'right', 'bottom'])), | ||
| locale: React.PropTypes.object, | ||
| showWeekNumber: React.PropTypes.bool, | ||
| showToday: React.PropTypes.bool, | ||
| showTime: React.PropTypes.bool, | ||
| onSelect: React.PropTypes.func, | ||
| onBlur: React.PropTypes.func | ||
| }; | ||
| Calendar.defaultProps = { | ||
| locale: require('./locale/en-us'), | ||
| onKeyDown: noop, | ||
| className: '', | ||
| showToday: true, | ||
| onSelect: noop, | ||
| onFocus: noop, | ||
| onBlur: noop, | ||
| onClear: noop | ||
| }; | ||
| module.exports = Calendar; |
| 'use strict'; | ||
| var React = require('react'); | ||
| var ROW = 4; | ||
| var COL = 3; | ||
| var cx = require('rc-util').classSet; | ||
| function goYear(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addYear(direction); | ||
| this.setState({ | ||
| value: next | ||
| }); | ||
| } | ||
| function chooseDecade(year, e) { | ||
| var next = this.state.value.clone(); | ||
| next.setYear(year); | ||
| this.props.onSelect(next); | ||
| e.preventDefault(); | ||
| } | ||
| class DecadePanel extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| this.state = { | ||
| value: props.value, | ||
| prefixCls: props.rootPrefixCls + '-decade-panel' | ||
| }; | ||
| // bind methods | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| this.nextCentury = goYear.bind(this, 100); | ||
| this.previousCentury = goYear.bind(this, -100); | ||
| } | ||
| render() { | ||
| var value = this.state.value; | ||
| var locale = this.props.locale; | ||
| var currentYear = value.getYear(); | ||
| var startYear = parseInt(currentYear / 100, 10) * 100; | ||
| var preYear = startYear - 10; | ||
| var endYear = startYear + 99; | ||
| var decades = []; | ||
| var index = 0; | ||
| var prefixClsFn = this.prefixClsFn; | ||
| for (var i = 0; i < ROW; i++) { | ||
| decades[i] = []; | ||
| for (var j = 0; j < COL; j++) { | ||
| decades[i][j] = { | ||
| startDecade: preYear + index * 10, | ||
| endDecade: preYear + index * 10 + 9 | ||
| }; | ||
| index++; | ||
| } | ||
| } | ||
| var decadesEls = decades.map((row, decadeIndex) => { | ||
| var tds = row.map(d => { | ||
| var startDecade = d.startDecade; | ||
| var endDecade = d.endDecade; | ||
| var classNameMap = {}; | ||
| classNameMap[prefixClsFn('cell')] = 1; | ||
| classNameMap[prefixClsFn('selected-cell')] = startDecade <= currentYear && currentYear <= endDecade; | ||
| classNameMap[prefixClsFn('last-century-cell')] = startDecade < startYear; | ||
| classNameMap[prefixClsFn('next-century-cell')] = endDecade > endYear; | ||
| return (<td | ||
| key={startDecade} | ||
| onClick={chooseDecade.bind(this, startDecade)} | ||
| role="gridcell" | ||
| className = {cx(classNameMap)} | ||
| > | ||
| <a | ||
| className={prefixClsFn('decade')}> | ||
| {startDecade} - {endDecade} | ||
| </a> | ||
| </td>); | ||
| }); | ||
| return (<tr key={decadeIndex} role="row">{tds}</tr>); | ||
| }); | ||
| return ( | ||
| <div className={this.state.prefixCls}> | ||
| <div className = {prefixClsFn('header')}> | ||
| <a className = {prefixClsFn('prev-century-btn')} | ||
| role="button" | ||
| onClick={this.previousCentury} | ||
| title={locale.previousCentury}> | ||
| « | ||
| </a> | ||
| <div className = {prefixClsFn('century')}> | ||
| {startYear}-{endYear} | ||
| </div> | ||
| <a className = {prefixClsFn('next-century-btn')} | ||
| role="button" | ||
| onClick={this.nextCentury} | ||
| title={locale.nextCentury}> | ||
| » | ||
| </a> | ||
| </div> | ||
| <div className = {prefixClsFn('body')}> | ||
| <table className = {prefixClsFn('table')} cellSpacing="0" role="grid"> | ||
| <tbody className = {prefixClsFn('tbody')}> | ||
| {decadesEls} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| </div>); | ||
| } | ||
| } | ||
| DecadePanel.defaultProps = { | ||
| onSelect() { | ||
| } | ||
| }; | ||
| module.exports = DecadePanel; |
| module.exports = require('./Calendar'); | ||
| module.exports.Picker = require('./Picker'); |
| 'use strict'; | ||
| module.exports = ({ | ||
| today: 'Today', | ||
| clear: 'Clear', | ||
| hourPanelTitle: 'Select hour', | ||
| minutePanelTitle: 'Select minute', | ||
| secondPanelTitle: 'Select second', | ||
| monthSelect: 'Choose a month', | ||
| yearSelect: 'Choose a year', | ||
| decadeSelect: 'Choose a decade', | ||
| yearFormat: 'yyyy', | ||
| dateFormat: 'M/d/yyyy', | ||
| monthYearFormat: 'MMMM yyyy', | ||
| previousMonth: 'Previous month (PageUp)', | ||
| nextMonth: 'Next month (PageDown)', | ||
| hourInput: 'Last hour(Up), Next hour(Down)', | ||
| minuteInput: 'Last minute(Up), Next minute(Down)', | ||
| secondInput: 'Last second(Up), Next second(Down)', | ||
| previousYear: 'Last year (Control + left)', | ||
| nextYear: 'Next year (Control + right)', | ||
| previousDecade: 'Last decade', | ||
| nextDecade: 'Next decade', | ||
| previousCentury: 'Last century', | ||
| nextCentury: 'Next century', | ||
| format: require('gregorian-calendar-format/lib/locale/en-us') | ||
| }); |
| 'use strict'; | ||
| module.exports = ({ | ||
| today: '今天', | ||
| clear: '清除', | ||
| previousMonth: '上个月 (翻页上键)', | ||
| nextMonth: '下个月 (翻页下键)', | ||
| monthSelect: '选择月份', | ||
| yearSelect: '选择年份', | ||
| decadeSelect: '选择年代', | ||
| hourInput: '上一小时(上方向键), 下一小时(下方向键)', | ||
| minuteInput: '上一分钟(上方向键), 下一分钟(下方向键)', | ||
| secondInput: '上一秒(上方向键), 下一小时(下方向键)', | ||
| hourPanelTitle: '选择小时', | ||
| minutePanelTitle: '选择分钟', | ||
| secondPanelTitle: '选择秒', | ||
| yearFormat: 'yyyy\'年\'', | ||
| monthYearFormat: 'yyyy\'年\'M\'月\'', | ||
| dateFormat: 'yyyy\'年\'M\'月\'d\'日\'', | ||
| previousYear: '上一年 (Control键加左方向键)', | ||
| nextYear: '下一年 (Control键加右方向键)', | ||
| previousDecade: '上一年代', | ||
| nextDecade: '下一年代', | ||
| previousCentury: '上一世纪', | ||
| nextCentury: '下一世纪', | ||
| format: require('gregorian-calendar-format/lib/locale/zh-cn') | ||
| }); |
| 'use strict'; | ||
| var React = require('react'); | ||
| var DateTimeFormat = require('gregorian-calendar-format'); | ||
| var ROW = 3; | ||
| var COL = 4; | ||
| var cx = require('rc-util').classSet; | ||
| var YearPanel = require('./YearPanel'); | ||
| function goYear(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addYear(direction); | ||
| this.setState({ | ||
| value: next | ||
| }); | ||
| } | ||
| function showYearPanel() { | ||
| this.setState({ | ||
| showYearPanel: 1 | ||
| }); | ||
| } | ||
| function chooseMonth(month) { | ||
| var next = this.state.value.clone(); | ||
| next.setMonth(month); | ||
| this.props.onSelect(next); | ||
| } | ||
| function onYearPanelSelect(current) { | ||
| this.setState({ | ||
| value: current, | ||
| showYearPanel: 0 | ||
| }); | ||
| } | ||
| class MonthPanel extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| this.state = { | ||
| value: this.props.value, | ||
| prefixCls: this.props.rootPrefixCls + '-month-panel' | ||
| }; | ||
| // bind methods | ||
| this.nextYear = goYear.bind(this, 1); | ||
| this.previousYear = goYear.bind(this, -1); | ||
| this.showYearPanel = showYearPanel.bind(this); | ||
| this.onYearPanelSelect = onYearPanelSelect.bind(this); | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| } | ||
| getMonths() { | ||
| var props = this.props; | ||
| var value = this.state.value; | ||
| var current = value.clone(); | ||
| var locale = props.locale; | ||
| var monthYearFormat = locale.monthYearFormat; | ||
| var dateFormatter = new DateTimeFormat(monthYearFormat); | ||
| var months = []; | ||
| var shortMonths = locale.format.shortMonths; | ||
| var index = 0; | ||
| for (var i = 0; i < ROW; i++) { | ||
| months[i] = []; | ||
| for (var j = 0; j < COL; j++) { | ||
| current.setMonth(index); | ||
| months[i][j] = { | ||
| value: index, | ||
| content: shortMonths[index], | ||
| title: dateFormatter.format(current) | ||
| }; | ||
| index++; | ||
| } | ||
| } | ||
| return months; | ||
| } | ||
| render() { | ||
| var props = this.props; | ||
| var value = this.state.value; | ||
| var locale = props.locale; | ||
| var months = this.getMonths(); | ||
| var year = value.getYear(); | ||
| var currentMonth = value.getMonth(); | ||
| var prefixClsFn = this.prefixClsFn; | ||
| var monthsEls = months.map((month, index)=> { | ||
| var tds = month.map(m => { | ||
| var classNameMap = {}; | ||
| classNameMap[prefixClsFn('cell')] = 1; | ||
| classNameMap[prefixClsFn('selected-cell')] = m.value === currentMonth; | ||
| return ( | ||
| <td role="gridcell" | ||
| key={m.value} | ||
| onClick={chooseMonth.bind(this, m.value)} | ||
| title={m.title} | ||
| className = {cx(classNameMap)}> | ||
| <a | ||
| className = {prefixClsFn('month')}> | ||
| {m.content} | ||
| </a> | ||
| </td>); | ||
| }); | ||
| return (<tr key={index} role="row">{tds}</tr>); | ||
| }); | ||
| var yearPanel; | ||
| if (this.state.showYearPanel) { | ||
| yearPanel = <YearPanel locale={locale} value={value} rootPrefixCls={props.rootPrefixCls} onSelect={this.onYearPanelSelect}/>; | ||
| } | ||
| return ( | ||
| <div className= {this.state.prefixCls}> | ||
| <div> | ||
| <div className = {prefixClsFn('header')}> | ||
| <a className = {prefixClsFn('prev-year-btn')} | ||
| role="button" | ||
| onClick={this.previousYear} | ||
| title={locale.previousYear}> | ||
| « | ||
| </a> | ||
| <a className = {prefixClsFn('year-select')} | ||
| role="button" | ||
| onClick={this.showYearPanel} | ||
| title={locale.yearSelect}> | ||
| <span className = {prefixClsFn('year-select-content')}>{year}</span> | ||
| <span className = {prefixClsFn('year-select-arrow')}>x</span> | ||
| </a> | ||
| <a className = {prefixClsFn('next-year-btn')} | ||
| role="button" | ||
| onClick={this.nextYear} | ||
| title={locale.nextYear}> | ||
| » | ||
| </a> | ||
| </div> | ||
| <div className = {prefixClsFn('body')}> | ||
| <table className = {prefixClsFn('table')} cellSpacing="0" role="grid"> | ||
| <tbody className = {prefixClsFn('tbody')}> | ||
| {monthsEls} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| </div> | ||
| {yearPanel} | ||
| </div>); | ||
| } | ||
| } | ||
| MonthPanel.defaultProps = { | ||
| onSelect() { | ||
| } | ||
| }; | ||
| module.exports = MonthPanel; |
+261
| 'use strict'; | ||
| var React = require('react'); | ||
| var DateTimeFormat = require('gregorian-calendar-format'); | ||
| var rcUtil = require('rc-util'); | ||
| var KeyCode = require('rc-util').KeyCode; | ||
| var domAlign = require('dom-align'); | ||
| var orientMap = { | ||
| tl: ['top', 'left'], | ||
| tr: ['top', 'right'], | ||
| bl: ['bottom', 'left'], | ||
| br: ['bottom', 'right'] | ||
| }; | ||
| function getImmutableOrient(orient) { | ||
| if (orient) { | ||
| for (var i in orientMap) { | ||
| var original = orientMap[i]; | ||
| if (original[0] === orient[0] && original[1] === orient[1]) { | ||
| return original; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| function refFn(field, component) { | ||
| this[field] = component; | ||
| } | ||
| /** | ||
| * DatePicker = wrap input using Calendar | ||
| */ | ||
| class Picker extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| this.state = { | ||
| open: props.open, | ||
| value: props.value || props.defaultValue | ||
| }; | ||
| var events = [ | ||
| 'handleInputClick', 'handleCalendarBlur', 'handleTriggerClick', | ||
| 'handleCalendarClear', 'handleCalendarKeyDown', | ||
| 'handleKeyDown', 'handleCalendarSelect' | ||
| ]; | ||
| // bind methods | ||
| events.forEach(m => { | ||
| this[m] = this[m].bind(this); | ||
| }); | ||
| this.saveCalendarRef = refFn.bind(this, 'calendarInstance'); | ||
| this.saveInputRef = refFn.bind(this, 'inputInstance'); | ||
| } | ||
| componentWillReceiveProps(nextProps) { | ||
| if (nextProps.value) { | ||
| this.setState({ | ||
| value: nextProps.value | ||
| }); | ||
| } | ||
| } | ||
| open(callback) { | ||
| this.setState({ | ||
| open: true | ||
| }, callback); | ||
| } | ||
| close(callback) { | ||
| this.setState({ | ||
| open: false | ||
| }, callback); | ||
| } | ||
| handleInputClick() { | ||
| this.toggle(); | ||
| } | ||
| handleTriggerClick() { | ||
| this.toggle(); | ||
| } | ||
| toggle(callback) { | ||
| this.setState({ | ||
| open: !this.state.open | ||
| }, callback); | ||
| } | ||
| handleKeyDown(e) { | ||
| // down | ||
| if (e.keyCode === KeyCode.DOWN) { | ||
| e.preventDefault(); | ||
| this.open(); | ||
| } | ||
| } | ||
| handleCalendarKeyDown(e) { | ||
| if (e.keyCode === KeyCode.ESC) { | ||
| e.stopPropagation(); | ||
| this.close(() => { | ||
| React.findDOMNode(this.inputInstance).focus(); | ||
| }); | ||
| } | ||
| } | ||
| handleCalendarSelect(value) { | ||
| this.props.calendar.props.onSelect(value); | ||
| var currentValue = this.state.value; | ||
| if (this.props.calendar.props.showTime) { | ||
| this.setState({ | ||
| value: value | ||
| }); | ||
| } else { | ||
| this.setState({ | ||
| value: value, | ||
| open: false | ||
| }, () => { | ||
| React.findDOMNode(this.inputInstance).focus(); | ||
| }); | ||
| } | ||
| if (!currentValue || currentValue.getTime() !== value.getTime()) { | ||
| this.props.onChange(value); | ||
| } | ||
| } | ||
| handleCalendarBlur() { | ||
| // if invisible, will not trigger blur | ||
| this.setState({ | ||
| open: false | ||
| }); | ||
| } | ||
| handleCalendarClear() { | ||
| this.props.calendar.props.onClear(); | ||
| this.setState({ | ||
| open: false, | ||
| value: null | ||
| }, ()=> { | ||
| React.findDOMNode(this.inputInstance).focus(); | ||
| }); | ||
| if (this.state.value !== null) { | ||
| this.props.onChange(null); | ||
| } | ||
| } | ||
| componentDidMount() { | ||
| this.componentDidUpdate(); | ||
| } | ||
| componentDidUpdate() { | ||
| if (this.state.open && !this._lastOpen) { | ||
| var orient = this._cacheCalendar.props.orient; | ||
| var points = ['tl', 'bl']; | ||
| var offset = [0, 5]; | ||
| if (orient.indexOf('top') !== -1 && orient.indexOf('left') !== -1) { | ||
| points = ['tl', 'bl']; | ||
| } else if (orient.indexOf('top') !== -1 && orient.indexOf('right') !== -1) { | ||
| points = ['tr', 'br']; | ||
| } else if (orient.indexOf('bottom') !== -1 && orient.indexOf('left') !== -1) { | ||
| points = ['bl', 'tl']; | ||
| offset = [0, -5]; | ||
| } else if (orient.indexOf('bottom') !== -1 && orient.indexOf('right') !== -1) { | ||
| points = ['br', 'tr']; | ||
| offset = [0, -5]; | ||
| } | ||
| var align = domAlign(React.findDOMNode(this.calendarInstance), React.findDOMNode(this.inputInstance), { | ||
| points: points, | ||
| offset: offset, | ||
| overflow: { | ||
| adjustX: 1, | ||
| adjustY: 1 | ||
| } | ||
| }); | ||
| points = align.points; | ||
| var newOrient = orientMap[points[0]]; | ||
| this.calendarInstance.setState({ | ||
| orient: newOrient | ||
| }); | ||
| React.findDOMNode(this.calendarInstance).focus(); | ||
| } | ||
| this._lastOpen = this.state.open; | ||
| } | ||
| render() { | ||
| var props = this.props; | ||
| // var input = React.Children.only(props.children); bug 0.13.0 | ||
| /* | ||
| children: Object | ||
| .0: (...) | ||
| get .0: function () { | ||
| set .0: function (value) { | ||
| _reactDidWarn: false | ||
| _reactFragment: Object | ||
| __proto__: Object | ||
| */ | ||
| var input = props.children; | ||
| if (!React.isValidElement(input)) { | ||
| var children = input; | ||
| React.Children.forEach(children, m => { | ||
| input = m; | ||
| }); | ||
| } | ||
| var state = this.state; | ||
| var value = state.value; | ||
| var calendar = this._cacheCalendar; | ||
| if (state.open) { | ||
| var calendarInstance = this.calendarInstance; | ||
| var calendarProp = props.calendar; | ||
| this._cacheCalendar = calendar = React.cloneElement(calendarProp, { | ||
| ref: rcUtil.createChainedFunction(calendarProp.props.ref, this.saveCalendarRef), | ||
| value: value, | ||
| // focused: true, | ||
| orient: calendarInstance && calendarInstance.state.orient || getImmutableOrient(calendarProp.props.orient) || orientMap.tl, | ||
| onBlur: this.handleCalendarBlur, | ||
| onKeyDown: this.handleCalendarKeyDown, | ||
| onSelect: this.handleCalendarSelect, | ||
| onClear: this.handleCalendarClear | ||
| }); | ||
| } | ||
| var inputValue = ''; | ||
| if (value) { | ||
| inputValue = props.formatter.format(value); | ||
| } | ||
| input = React.cloneElement(input, { | ||
| ref: rcUtil.createChainedFunction(input.props.ref, this.saveInputRef), | ||
| readOnly: true, | ||
| onClick: this.handleInputClick, | ||
| value: inputValue, | ||
| onKeyDown: this.handleKeyDown | ||
| }); | ||
| var classes = [props.prefixCls]; | ||
| if (state.open) { | ||
| classes.push(props.prefixCls + '-open'); | ||
| } | ||
| var trigger = props.trigger; | ||
| if (trigger) { | ||
| trigger = React.cloneElement(trigger, { | ||
| onClick: this.handleTriggerClick, | ||
| unselectable: true, | ||
| onMouseDown: prevent | ||
| }); | ||
| } | ||
| return <span className={classes.join(' ')}>{[input, calendar, trigger]}</span>; | ||
| } | ||
| } | ||
| function prevent(e) { | ||
| e.preventDefault(); | ||
| } | ||
| Picker.propTypes = { | ||
| onChange: React.PropTypes.func | ||
| }; | ||
| Picker.defaultProps = { | ||
| prefixCls: 'rc-calendar-picker', | ||
| onChange() { | ||
| }, | ||
| formatter: new DateTimeFormat('yyyy-MM-dd') | ||
| }; | ||
| module.exports = Picker; |
| 'use strict'; | ||
| module.exports = function () { | ||
| var prefixCls = this.state.prefixCls; | ||
| var args = Array.prototype.slice.call(arguments, 0); | ||
| return args.map(s => { | ||
| return prefixCls + '-' + s; | ||
| }).join(' '); | ||
| }; |
+165
| 'use strict'; | ||
| var React = require('react'); | ||
| var rcUtil = require('rc-util'); | ||
| var KeyCode = rcUtil.KeyCode; | ||
| var TimePanel = require('./TimePanel'); | ||
| var setHourOfDay = 'setHourOfDay'; | ||
| var setMinutes = 'setMinutes'; | ||
| var setSeconds = 'setSeconds'; | ||
| function padding(number) { | ||
| if (number < 10) { | ||
| number = '0' + number; | ||
| } | ||
| return number; | ||
| } | ||
| function loop(value, min, max) { | ||
| if (value === min - 1) { | ||
| value = max; | ||
| } else if (value === max + 1) { | ||
| value = min; | ||
| } | ||
| return value; | ||
| } | ||
| function keyDownWrap(method, min, max) { | ||
| return function (e) { | ||
| var value = e.target.value; | ||
| var number = parseInt(value, 10); | ||
| var keyCode = e.keyCode; | ||
| var handled; | ||
| if (keyCode === KeyCode.DOWN) { | ||
| number++; | ||
| e.stopPropagation(); | ||
| e.preventDefault(); | ||
| handled = 1; | ||
| } else if (keyCode === KeyCode.UP) { | ||
| number--; | ||
| e.stopPropagation(); | ||
| e.preventDefault(); | ||
| handled = 1; | ||
| } | ||
| if (handled) { | ||
| number = loop(number, min, max); | ||
| var time = this.props.value.clone(); | ||
| time[method](number); | ||
| this.props.onChange(time, e); | ||
| } | ||
| }; | ||
| } | ||
| class Time extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| this.state = { | ||
| showHourPanel: 0, | ||
| showMinutePanel: 0, | ||
| showSecondPanel: 0 | ||
| }; | ||
| var events = [ | ||
| 'onHourKeyDown', 'onMinuteKeyDown', 'onSecondKeyDown', 'onHourClick', 'onMinuteClick', 'onSecondClick', | ||
| 'onSelectPanel' | ||
| ]; | ||
| events.forEach(m => { | ||
| this[m] = this[m].bind(this); | ||
| }); | ||
| } | ||
| onSelectPanel(value, setter) { | ||
| this.setState({ | ||
| showHourPanel: 0, | ||
| showMinutePanel: 0, | ||
| showSecondPanel: 0 | ||
| }, ()=> { | ||
| // ie9 has broken focus | ||
| React.findDOMNode(this.refs[setter]).focus(); | ||
| }); | ||
| this.props.onChange(value); | ||
| } | ||
| onHourClick() { | ||
| this.setState({ | ||
| showHourPanel: 1, | ||
| showMinutePanel: 0, | ||
| showSecondPanel: 0 | ||
| }); | ||
| } | ||
| onMinuteClick() { | ||
| this.setState({ | ||
| showHourPanel: 0, | ||
| showMinutePanel: 1, | ||
| showSecondPanel: 0 | ||
| }); | ||
| } | ||
| onSecondClick() { | ||
| this.setState({ | ||
| showHourPanel: 0, | ||
| showMinutePanel: 0, | ||
| showSecondPanel: 1 | ||
| }); | ||
| } | ||
| shouldComponentUpdate() { | ||
| return rcUtil.PureRenderMixin.shouldComponentUpdate.apply(this, arguments); | ||
| } | ||
| render() { | ||
| var state = this.state; | ||
| var props = this.props; | ||
| var prefixClsFn = props.prefixClsFn; | ||
| var value = props.value; | ||
| var locale = props.locale; | ||
| var hour = value.getHourOfDay(); | ||
| var minute = value.getMinutes(); | ||
| var second = value.getSeconds(); | ||
| var panel; | ||
| var commonProps = { | ||
| value: value, | ||
| onSelect: this.onSelectPanel, | ||
| rootPrefixCls: props.rootPrefixCls | ||
| }; | ||
| if (state.showHourPanel) { | ||
| panel = <TimePanel rowCount={6} colCount={4} getter="getHourOfDay" setter={setHourOfDay} | ||
| title={locale.hourPanelTitle} | ||
| {...commonProps}/>; | ||
| } else if (state.showMinutePanel) { | ||
| panel = <TimePanel rowCount={6} colCount={10} getter="getMinutes" setter={setMinutes} | ||
| title={locale.minutePanelTitle} | ||
| {...commonProps}/>; | ||
| } else if (state.showSecondPanel) { | ||
| panel = <TimePanel rowCount={6} colCount={10} getter="getSeconds" setter={setSeconds} | ||
| title={locale.secondPanelTitle} | ||
| {...commonProps}/>; | ||
| } | ||
| return (<div> | ||
| <input className = {prefixClsFn('time-input')} title={locale.hourInput} | ||
| ref={setHourOfDay} | ||
| readOnly value={padding(hour)} | ||
| onClick={this.onHourClick} | ||
| onKeyDown={this.onHourKeyDown}/> | ||
| <span> : </span> | ||
| <input className = {prefixClsFn('time-input')} title={locale.minuteInput} | ||
| ref={setMinutes} | ||
| readOnly value={padding(minute)} | ||
| onClick={this.onMinuteClick} | ||
| onKeyDown = {this.onMinuteKeyDown}/> | ||
| <span> : </span> | ||
| <input className = {prefixClsFn('time-input')} title={locale.secondInput} | ||
| ref={setSeconds} | ||
| readOnly value={padding(second)} | ||
| onClick={this.onSecondClick} | ||
| onKeyDown = {this.onSecondKeyDown}/> | ||
| {panel} | ||
| </div>); | ||
| } | ||
| } | ||
| Time.prototype.onHourKeyDown = keyDownWrap('setHourOfDay', 0, 23); | ||
| Time.prototype.onMinuteKeyDown = keyDownWrap('setMinutes', 0, 59); | ||
| Time.prototype.onSecondKeyDown = keyDownWrap('setSeconds', 0, 59); | ||
| module.exports = Time; |
| 'use strict'; | ||
| var React = require('react'); | ||
| var cx = require('rc-util').classSet; | ||
| function choose(hour, e) { | ||
| var next = this.state.value.clone(); | ||
| var method = this.props.setter; | ||
| next[method](hour); | ||
| this.props.onSelect(next, method); | ||
| e.preventDefault(); | ||
| } | ||
| class TimePanel extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| this.state = { | ||
| value: props.value, | ||
| prefixCls: props.rootPrefixCls + '-time-panel' | ||
| }; | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| } | ||
| render() { | ||
| var value = this.state.value; | ||
| var props = this.props; | ||
| var method = props.getter; | ||
| var currentHour = value[method](); | ||
| var data = []; | ||
| var prefixClsFn = this.prefixClsFn; | ||
| var ROW = props.rowCount; | ||
| var COL = props.colCount; | ||
| for (var i = 0; i < ROW; i++) { | ||
| data[i] = []; | ||
| for (var j = 0; j < COL; j++) { | ||
| data[i][j] = i * COL + j; | ||
| } | ||
| } | ||
| var hoursEls = data.map((row, index)=> { | ||
| var tds = row.map(d => { | ||
| var classNameMap = {}; | ||
| classNameMap[prefixClsFn('cell')] = 1; | ||
| classNameMap[prefixClsFn('selected-cell')] = d === currentHour; | ||
| return (<td | ||
| key={d} | ||
| onClick={choose.bind(this, d)} | ||
| role="gridcell" | ||
| className = {cx(classNameMap)} > | ||
| <a | ||
| className={prefixClsFn('time')}> | ||
| {d} | ||
| </a> | ||
| </td>); | ||
| }); | ||
| return (<tr key={index} role="row">{tds}</tr>); | ||
| }); | ||
| return ( | ||
| <div className={this.state.prefixCls}> | ||
| <div className = {prefixClsFn('header')}> | ||
| <div className = {prefixClsFn('title')}> | ||
| {props.title} | ||
| </div> | ||
| </div> | ||
| <div className = {prefixClsFn('body')}> | ||
| <table className = {prefixClsFn('table')} cellSpacing="0" role="grid"> | ||
| <tbody className = {prefixClsFn('tbody')}> | ||
| {hoursEls} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| </div>); | ||
| } | ||
| } | ||
| TimePanel.defaultProps = { | ||
| onSelect() { | ||
| } | ||
| }; | ||
| module.exports = TimePanel; |
| 'use strict'; | ||
| var React = require('react'); | ||
| var DateTimeFormat = require('gregorian-calendar-format'); | ||
| var ROW = 3; | ||
| var COL = 4; | ||
| var cx = require('rc-util').classSet; | ||
| var DecadePanel = require('./DecadePanel'); | ||
| function goYear(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addYear(direction); | ||
| this.setState({value: next}); | ||
| } | ||
| function chooseYear(year) { | ||
| var next = this.state.value.clone(); | ||
| next.setYear(year); | ||
| this.props.onSelect(next); | ||
| } | ||
| class YearPanel extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| this.state = { | ||
| value: props.value, | ||
| prefixCls: props.rootPrefixCls + '-year-panel' | ||
| }; | ||
| this.nextDecade = goYear.bind(this, 10); | ||
| this.previousDecade = goYear.bind(this, -10); | ||
| ['showDecadePanel', 'onDecadePanelSelect'].forEach(m => { | ||
| this[m] = this[m].bind(this); | ||
| }); | ||
| } | ||
| showDecadePanel() { | ||
| this.setState({ | ||
| showDecadePanel: 1 | ||
| }); | ||
| } | ||
| onDecadePanelSelect(current) { | ||
| this.setState({ | ||
| value: current, | ||
| showDecadePanel: 0 | ||
| }); | ||
| } | ||
| getYears() { | ||
| var value = this.state.value; | ||
| var currentYear = value.getYear(); | ||
| var startYear = parseInt(currentYear / 10, 10) * 10; | ||
| var preYear = startYear - 1; | ||
| var current = value.clone(); | ||
| var locale = this.props.locale; | ||
| var yearFormat = locale.yearFormat; | ||
| var dateFormatter = new DateTimeFormat(yearFormat); | ||
| var years = []; | ||
| var index = 0; | ||
| for (var i = 0; i < ROW; i++) { | ||
| years[i] = []; | ||
| for (var j = 0; j < COL; j++) { | ||
| current.setYear(preYear + index); | ||
| years[i][j] = { | ||
| content: preYear + index, | ||
| title: dateFormatter.format(current) | ||
| }; | ||
| index++; | ||
| } | ||
| } | ||
| return years; | ||
| } | ||
| render() { | ||
| var props = this.props; | ||
| var value = this.state.value; | ||
| var locale = props.locale; | ||
| var years = this.getYears(); | ||
| var currentYear = value.getYear(); | ||
| var startYear = parseInt(currentYear / 10, 10) * 10; | ||
| var endYear = startYear + 9; | ||
| var prefixClsFn = this.prefixClsFn; | ||
| var yeasEls = years.map((row, index) => { | ||
| var tds = row.map(y => { | ||
| var classNameMap = {}; | ||
| classNameMap[prefixClsFn('cell')] = 1; | ||
| classNameMap[prefixClsFn('selected-cell')] = y.content === currentYear; | ||
| classNameMap[prefixClsFn('last-decade-cell')] = y.content < startYear; | ||
| classNameMap[prefixClsFn('next-decade-cell')] = y.content > endYear; | ||
| return ( | ||
| <td role="gridcell" | ||
| title={y.title} | ||
| key={y.content} | ||
| onClick={chooseYear.bind(this, y.content)} | ||
| className = {cx(classNameMap)} | ||
| > | ||
| <a | ||
| className={prefixClsFn('year')}> | ||
| {y.content} | ||
| </a> | ||
| </td>); | ||
| }); | ||
| return (<tr key={index} role="row">{tds}</tr>); | ||
| }); | ||
| var decadePanel; | ||
| if (this.state.showDecadePanel) { | ||
| decadePanel = <DecadePanel locale={locale} value={value} rootPrefixCls={props.rootPrefixCls} onSelect={this.onDecadePanelSelect}/>; | ||
| } | ||
| return ( | ||
| <div className={this.state.prefixCls}> | ||
| <div> | ||
| <div className = {prefixClsFn('header')}> | ||
| <a className = {prefixClsFn('prev-decade-btn')} | ||
| role="button" | ||
| onClick={this.previousDecade} | ||
| title={locale.previousDecade}> | ||
| « | ||
| </a> | ||
| <a className = {prefixClsFn('decade-select')} | ||
| role="button" | ||
| onClick={this.showDecadePanel} | ||
| title={locale.decadeSelect}> | ||
| <span className = {prefixClsFn('decade-select-content')}> | ||
| {startYear}-{endYear} | ||
| </span> | ||
| <span className = {prefixClsFn('decade-select-arrow')}>x</span> | ||
| </a> | ||
| <a className = {prefixClsFn('next-decade-btn')} | ||
| role="button" | ||
| onClick={this.nextDecade} | ||
| title={locale.nextDecade}> | ||
| » | ||
| </a> | ||
| </div> | ||
| <div className = {prefixClsFn('body')}> | ||
| <table className = {prefixClsFn('table')} cellSpacing="0" role="grid"> | ||
| <tbody className = {prefixClsFn('tbody')}> | ||
| {yeasEls} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| </div> | ||
| {decadePanel} | ||
| </div>); | ||
| } | ||
| } | ||
| YearPanel.defaultProps = { | ||
| onSelect() { | ||
| } | ||
| }; | ||
| module.exports = YearPanel; |
| var keyCode = require('rc-util').KeyCode; | ||
| var expect = require('expect.js'); | ||
| var Calendar = require('../index'); | ||
| var React = require('react/addons'); | ||
| var TestUtils = React.addons.TestUtils; | ||
| var Simulate = TestUtils.Simulate; | ||
| var async = require('async'); | ||
| describe('Calendar', function () { | ||
| var calendar; | ||
| var container = document.createElement('div'); | ||
| document.body.appendChild(container); | ||
| beforeEach(function (done) { | ||
| React.render(<Calendar showToday={true} showWeekNumber={true} showTime={true}/>, container, function () { | ||
| calendar = this; | ||
| done(); | ||
| }); | ||
| }); | ||
| afterEach(function () { | ||
| React.unmountComponentAtNode(container); | ||
| }); | ||
| describe('keyboard works', function () { | ||
| it('left works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addDayOfMonth(-1); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.LEFT | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getDayOfMonth()).to.be(expected.getDayOfMonth()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('right works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addDayOfMonth(1); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.RIGHT | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getDayOfMonth()).to.be(expected.getDayOfMonth()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('up works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addDayOfMonth(-7); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.UP | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getDayOfMonth()).to.be(expected.getDayOfMonth()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('down works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addDayOfMonth(7); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.DOWN | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getDayOfMonth()).to.be(expected.getDayOfMonth()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('pageDown works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addMonth(1); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.PAGE_DOWN | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getMonth()).to.be(expected.getMonth()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('pageUp works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addMonth(-1); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.PAGE_UP | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getMonth()).to.be(expected.getMonth()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('ctrl left works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addYear(-1); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.LEFT, | ||
| ctrlKey: 1 | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getYear()).to.be(expected.getYear()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('ctrl right works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addYear(1); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.RIGHT, | ||
| ctrlKey: 1 | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getYear()).to.be(expected.getYear()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| }); | ||
| it('next month works', function (done) { | ||
| var month = calendar.state.value.getMonth(); | ||
| if (month === 11) { | ||
| month = -1; | ||
| } | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-next-month-btn')[0]); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getMonth()).to.be(month + 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('previous month works', function (done) { | ||
| var month = calendar.state.value.getMonth(); | ||
| if (month === 0) { | ||
| month = 12; | ||
| } | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-prev-month-btn')[0]); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getMonth()).to.be(month - 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('next year works', function (done) { | ||
| var year = calendar.state.value.getYear(); | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-next-year-btn')[0]); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getYear()).to.be(year + 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('previous year works', function (done) { | ||
| var year = calendar.state.value.getYear(); | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-prev-year-btn')[0]); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getYear()).to.be(year - 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('render works', function () { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-cell').length).to.above(0); | ||
| }); | ||
| it('onSelect works', function (done) { | ||
| var day; | ||
| function onSelect(d) { | ||
| expect(d.getDayOfMonth()).to.be(parseInt(day.props.children), 10); | ||
| done(); | ||
| } | ||
| calendar = React.render(<Calendar showToday={true} | ||
| onSelect={onSelect} | ||
| showWeekNumber={true} showTime={true}/>, container); | ||
| day = TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-date')[5]; | ||
| Simulate.click(day); | ||
| }); | ||
| it('month panel shows', function (done) { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-month-panel').length).to.be(0); | ||
| Simulate.click(TestUtils.findRenderedDOMComponentWithClass(calendar, 'rc-calendar-month-select')); | ||
| async.series([function (next) { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-month-panel').length).to.be(1); | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-month-panel-month').length).to.be(12); | ||
| var m = TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-month-panel-month')[9]; | ||
| Simulate.click(m); | ||
| setTimeout(next, 10); | ||
| }, function (next) { | ||
| expect(calendar.state.value.getMonth()).to.be(9); | ||
| next(); | ||
| }], done); | ||
| }); | ||
| it('year panel works', function (done) { | ||
| var text; | ||
| async.series([function (done) { | ||
| Simulate.click(TestUtils.findRenderedDOMComponentWithClass(calendar, 'rc-calendar-month-select')); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| Simulate.click(TestUtils.findRenderedDOMComponentWithClass(calendar, 'rc-calendar-month-panel-year-select')); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-year-panel').length).to.be(1); | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-year-panel-year').length).to.be(12); | ||
| var year = TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-year-panel-year')[9]; | ||
| text = year.props.children; | ||
| Simulate.click(year); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| var m = TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-month-panel-month')[9]; | ||
| Simulate.click(m); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| expect(calendar.state.value.getYear()).to.be(text); | ||
| done(); | ||
| }], done); | ||
| }); | ||
| it('decade panel works', function (done) { | ||
| async.series([function (done) { | ||
| Simulate.click(TestUtils.findRenderedDOMComponentWithClass(calendar, 'rc-calendar-month-select')); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| Simulate.click(TestUtils.findRenderedDOMComponentWithClass(calendar, 'rc-calendar-month-panel-year-select')); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| Simulate.click(TestUtils.findRenderedDOMComponentWithClass(calendar, 'rc-calendar-year-panel-decade-select')); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-decade-panel').length).to.be(1); | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-decade-panel-decade').length).to.be(12); | ||
| done(); | ||
| }], done); | ||
| }); | ||
| }); |
| var keyCode = require('rc-util').KeyCode; | ||
| var expect = require('expect.js'); | ||
| var Calendar = require('../index'); | ||
| var React = require('react/addons'); | ||
| var TestUtils = React.addons.TestUtils; | ||
| var Simulate = TestUtils.Simulate; | ||
| var async = require('async'); | ||
| describe('Time', function () { | ||
| var calendar; | ||
| var container = document.createElement('div'); | ||
| document.body.appendChild(container); | ||
| beforeEach(function (done) { | ||
| React.render(<Calendar showToday={true} showWeekNumber={true} showTime={true}/>, container, function () { | ||
| calendar = this; | ||
| done(); | ||
| }); | ||
| }); | ||
| afterEach(function () { | ||
| React.unmountComponentAtNode(container); | ||
| }); | ||
| describe('keyboard', function () { | ||
| it('hour pane works for up', function (done) { | ||
| var hour = calendar.state.value.getHourOfDay(); | ||
| if (hour === 0) { | ||
| hour = 24; | ||
| } | ||
| Simulate.keyDown(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[0], { | ||
| keyCode: keyCode.UP | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getHourOfDay()).to.be(hour - 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('hour pane works for down', function (done) { | ||
| var hour = calendar.state.value.getHourOfDay(); | ||
| if (hour === 23) { | ||
| hour = -1; | ||
| } | ||
| Simulate.keyDown(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[0], { | ||
| keyCode: keyCode.DOWN | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getHourOfDay()).to.be(hour + 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('minute pane works for up', function (done) { | ||
| var minute = calendar.state.value.getMinutes(); | ||
| if (minute === 0) { | ||
| minute = 60; | ||
| } | ||
| Simulate.keyDown(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[1], { | ||
| keyCode: keyCode.UP | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getMinutes()).to.be(minute - 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('minute pane works for down', function (done) { | ||
| var minute = calendar.state.value.getMinutes(); | ||
| if (minute === 59) { | ||
| minute = -1; | ||
| } | ||
| Simulate.keyDown(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[1], { | ||
| keyCode: keyCode.DOWN | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getMinutes()).to.be(minute + 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('second pane works for up', function (done) { | ||
| var second = calendar.state.value.getSeconds(); | ||
| if (second === 0) { | ||
| second = 59; | ||
| } | ||
| Simulate.keyDown(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[2], { | ||
| keyCode: keyCode.UP | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getSeconds()).to.be(second - 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('second pane works for down', function (done) { | ||
| var second = calendar.state.value.getSeconds(); | ||
| if (second === 59) { | ||
| second = -1; | ||
| } | ||
| Simulate.keyDown(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[2], { | ||
| keyCode: keyCode.DOWN | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getSeconds()).to.be(second + 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| }); | ||
| it('hour pane shows', function (done) { | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[0]); | ||
| async.series([function (done) { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-panel-time').length).to.be(24); | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-panel-time')[2]); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| expect(calendar.state.value.getHourOfDay()).to.be(2); | ||
| done(); | ||
| }], done); | ||
| }); | ||
| it('minute pane shows', function (done) { | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[1]); | ||
| setTimeout(function () { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-panel-time').length).to.be(60); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('second pane shows', function (done) { | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[2]); | ||
| setTimeout(function () { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-panel-time').length).to.be(60); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| }); |
@@ -1,2 +0,1 @@ | ||
| /** @jsx React.DOM */ | ||
| require('rc-calendar/assets/index.css'); | ||
@@ -9,3 +8,3 @@ var React = require('react'); | ||
| var GregorianCalendar = require('gregorian-calendar'); | ||
| var CalendarLocale = require('../lib/locale/zh-cn'); | ||
| var CalendarLocale = require('rc-calendar/src/locale/zh-cn'); | ||
@@ -12,0 +11,0 @@ |
@@ -1,2 +0,2 @@ | ||
| /** @jsx React.DOM */ | ||
| require('rc-calendar/assets/index.css'); | ||
@@ -10,3 +10,3 @@ | ||
| var zhCn = require('gregorian-calendar/lib/locale/zh-cn'); | ||
| var CalendarLocale = require('../lib/locale/zh-cn'); | ||
| var CalendarLocale = require('rc-calendar/src/locale/zh-cn'); | ||
@@ -13,0 +13,0 @@ var value = new GregorianCalendar(zhCn); |
@@ -1,2 +0,2 @@ | ||
| /** @jsx React.DOM */ | ||
| require('bootstrap/dist/css/bootstrap.css'); | ||
@@ -10,3 +10,3 @@ require('rc-calendar/assets/bootstrap.css'); | ||
| var GregorianCalendar = require('gregorian-calendar'); | ||
| var CalendarLocale = require('../lib/locale/zh-cn'); | ||
| var CalendarLocale = require('rc-calendar/src/locale/zh-cn'); | ||
@@ -13,0 +13,0 @@ var Test = React.createClass({ |
@@ -1,2 +0,2 @@ | ||
| /** @jsx React.DOM */ | ||
| require('rc-calendar/assets/bootstrap.css'); | ||
@@ -3,0 +3,0 @@ var Calendar = require('rc-calendar'); |
@@ -1,2 +0,2 @@ | ||
| /** @jsx React.DOM */ | ||
| require('bootstrap/dist/css/bootstrap.css'); | ||
@@ -10,3 +10,3 @@ require('rc-calendar/assets/bootstrap.css'); | ||
| var GregorianCalendar = require('gregorian-calendar'); | ||
| var CalendarLocale = require('../lib/locale/zh-cn'); | ||
| var CalendarLocale = require('rc-calendar/src/locale/zh-cn'); | ||
@@ -13,0 +13,0 @@ var Test = React.createClass({ |
@@ -1,2 +0,2 @@ | ||
| /** @jsx React.DOM */ | ||
| require('rc-calendar/assets/bootstrap.css'); | ||
@@ -3,0 +3,0 @@ |
@@ -1,2 +0,2 @@ | ||
| /** @jsx React.DOM */ | ||
| require('rc-calendar/assets/classic.css'); | ||
@@ -3,0 +3,0 @@ var Calendar = require('rc-calendar'); |
+4
-0
| # History | ||
| ---- | ||
| ## 3.5.0 / 2015-05-26 | ||
| `new` publish transformed es5 code to npm | ||
| ## 3.4.0 / 2015-05-19 | ||
@@ -5,0 +9,0 @@ |
+1
-2
@@ -1,2 +0,1 @@ | ||
| module.exports = require('./lib/Calendar'); | ||
| module.exports.Picker = require('./lib/Picker'); | ||
| module.exports = require('./src/'); |
@@ -1,7 +0,4 @@ | ||
| /** | ||
| * i18n resources for date-picker | ||
| * @ignore | ||
| * @author yiminghe@gmail.com | ||
| */ | ||
| module.exports = ({ | ||
| 'use strict'; | ||
| module.exports = { | ||
| today: 'Today', | ||
@@ -29,3 +26,3 @@ clear: 'Clear', | ||
| nextCentury: 'Next century', | ||
| format: require('gregorian-calendar-format/lib/locale/en-us') | ||
| }); | ||
| format: require('gregorian-calendar-format/lib/locale/en-us') | ||
| }; |
+6
-11
@@ -1,8 +0,4 @@ | ||
| /** | ||
| * i18n resources for date-picker | ||
| * @ignore | ||
| * @author yiminghe@gmail.com | ||
| */ | ||
| 'use strict'; | ||
| module.exports = ({ | ||
| module.exports = { | ||
| today: '今天', | ||
@@ -21,6 +17,5 @@ clear: '清除', | ||
| secondPanelTitle: '选择秒', | ||
| /*jshint quotmark: false*/ | ||
| yearFormat: "yyyy'年'", | ||
| monthYearFormat: "yyyy'年'M'月'", | ||
| dateFormat: "yyyy'年'M'月'd'日'", | ||
| yearFormat: 'yyyy\'年\'', | ||
| monthYearFormat: 'yyyy\'年\'M\'月\'', | ||
| dateFormat: 'yyyy\'年\'M\'月\'d\'日\'', | ||
| previousYear: '上一年 (Control键加左方向键)', | ||
@@ -33,2 +28,2 @@ nextYear: '下一年 (Control键加右方向键)', | ||
| format: require('gregorian-calendar-format/lib/locale/zh-cn') | ||
| }); | ||
| }; |
@@ -0,7 +1,9 @@ | ||
| 'use strict'; | ||
| module.exports = function () { | ||
| var prefixCls = this.state.prefixCls; | ||
| var args = Array.prototype.slice.call(arguments, 0); | ||
| return args.map(s => { | ||
| return args.map(function (s) { | ||
| return prefixCls + '-' + s; | ||
| }).join(' '); | ||
| }; | ||
| }; |
+6
-5
| { | ||
| "name": "rc-calendar", | ||
| "version": "3.4.2", | ||
| "version": "3.5.0", | ||
| "description": "calendar ui component for react", | ||
@@ -14,2 +14,3 @@ "keywords": [ | ||
| ], | ||
| "main": "lib/index", | ||
| "homepage": "http://github.com/react-component/calendar", | ||
@@ -30,2 +31,3 @@ "author": "yiminghe@gmail.com", | ||
| "build": "rc-tools run build", | ||
| "precommit": "rc-tools run precommit", | ||
| "less": "rc-tools run less", | ||
@@ -46,5 +48,5 @@ "gh-pages": "rc-tools run gh-pages", | ||
| "precommit-hook": "^1.0.7", | ||
| "rc-server": "^2.0.0", | ||
| "rc-server": "3.x", | ||
| "rc-style": "1.0.x", | ||
| "rc-tools": "2.x", | ||
| "rc-tools": "3.x", | ||
| "react": "^0.13.0" | ||
@@ -64,4 +66,3 @@ }, | ||
| "precommit": [ | ||
| "lint", | ||
| "less" | ||
| "precommit" | ||
| ], | ||
@@ -68,0 +69,0 @@ "dependencies": { |
-27
| { | ||
| "requireCurlyBraces": ["if", "else", "for", "while", "do", "try", "catch"], | ||
| "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"], | ||
| "requireSpacesInFunctionExpression": { | ||
| "beforeOpeningCurlyBrace": true | ||
| }, | ||
| "disallowSpacesInsideArrayBrackets": true, | ||
| "disallowSpacesInsideObjectBrackets": true, | ||
| "disallowSpacesInsideParentheses": true, | ||
| "disallowQuotedKeysInObjects": "allButReserved", | ||
| "disallowSpaceAfterObjectKeys": true, | ||
| "requireSpaceBeforeBinaryOperators": ["-", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<=" ], | ||
| "requireSpacesInConditionalExpression": { | ||
| "afterTest": true, | ||
| "beforeConsequent": true, | ||
| "afterConsequent": true, | ||
| "beforeAlternate": true | ||
| }, | ||
| "requireSpaceAfterBinaryOperators": ["/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="], | ||
| "disallowKeywords": [ "with" ], | ||
| "disallowSpaceAfterPrefixUnaryOperators": [ "!" , "++", "--", "+", "-", "~"], | ||
| "disallowSpaceBeforePostfixUnaryOperators": ["++", "--", ","], | ||
| "disallowMultipleLineBreaks": true, | ||
| "disallowKeywordsOnNewLine": ["else"], | ||
| "safeContextKeyword": "self", | ||
| "excludeFiles": ["lib/**/parser.js"] | ||
| } |
-28
| { | ||
| "camelcase": true, | ||
| "curly": true, | ||
| "eqeqeq": true, | ||
| "freeze": true, | ||
| "indent": 4, | ||
| "latedef": "nofunc", | ||
| "quotmark": "false", | ||
| "nonew": true, | ||
| "newcap": false, | ||
| "immed": true, | ||
| "noarg": true, | ||
| "eqnull": true, | ||
| "trailing": true, | ||
| "undef": true, | ||
| "unused": true, | ||
| "browser": true, | ||
| "node": true, | ||
| "esnext": true, | ||
| "globals": { | ||
| "describe": false, | ||
| "expect": false, | ||
| "beforeEach": false, | ||
| "afterEach": false, | ||
| "modulex": false, | ||
| "it": false | ||
| } | ||
| } |
-513
| var React = require('react'); | ||
| var DATE_ROW_COUNT = 6; | ||
| var DATE_COL_COUNT = 7; | ||
| var DateTimeFormat = require('gregorian-calendar-format'); | ||
| var GregorianCalendar = require('gregorian-calendar'); | ||
| var rcUtil = require('rc-util'); | ||
| var KeyCode = rcUtil.KeyCode; | ||
| var MonthPanel = require('./MonthPanel'); | ||
| var Time = require('./Time'); | ||
| function noop() { | ||
| } | ||
| function getIdFromDate(d) { | ||
| return 'rc-calendar-' + d.getYear() + | ||
| '-' + d.getMonth() + '-' + | ||
| d.getDayOfMonth(); | ||
| } | ||
| function goStartMonth() { | ||
| var next = this.state.value.clone(); | ||
| next.setDayOfMonth(1); | ||
| this.setState({value: next}); | ||
| } | ||
| function goEndMonth() { | ||
| var next = this.state.value.clone(); | ||
| next.setDayOfMonth(next.getActualMaximum(GregorianCalendar.MONTH)); | ||
| this.setState({value: next}); | ||
| } | ||
| function goMonth(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addMonth(direction); | ||
| this.setState({value: next}); | ||
| } | ||
| function goYear(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addYear(direction); | ||
| this.setState({value: next}); | ||
| } | ||
| function goWeek(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addWeekOfYear(direction); | ||
| this.setState({value: next}); | ||
| } | ||
| function goDay(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addDayOfMonth(direction); | ||
| this.setState({value: next}); | ||
| } | ||
| function isSameDay(one, two) { | ||
| return one.getYear() === two.getYear() && | ||
| one.getMonth() === two.getMonth() && | ||
| one.getDayOfMonth() === two.getDayOfMonth(); | ||
| } | ||
| function beforeCurrentMonthYear(current, today) { | ||
| if (current.getYear() < today.getYear()) { | ||
| return 1; | ||
| } | ||
| return current.getYear() === today.getYear() && | ||
| current.getMonth() < today.getMonth(); | ||
| } | ||
| function afterCurrentMonthYear(current, today) { | ||
| if (current.getYear() > today.getYear()) { | ||
| return 1; | ||
| } | ||
| return current.getYear() === today.getYear() && | ||
| current.getMonth() > today.getMonth(); | ||
| } | ||
| function onFocus() { | ||
| if (this._blurTimer) { | ||
| clearTimeout(this._blurTimer); | ||
| this._blurTimer = null; | ||
| } else { | ||
| this.props.onFocus(); | ||
| } | ||
| } | ||
| function onBlur() { | ||
| if (this._blurTimer) { | ||
| clearTimeout(this._blurTimer); | ||
| } | ||
| this._blurTimer = setTimeout(()=> { | ||
| this.props.onBlur(); | ||
| }, 100); | ||
| } | ||
| function chooseToday() { | ||
| var today = this.state.value.clone(); | ||
| today.setTime(Date.now()); | ||
| this.handleSelect(today); | ||
| } | ||
| function handleDayClick(current) { | ||
| this.handleSelect(current); | ||
| } | ||
| function handleSelect(current, keyDownEvent) { | ||
| var props = this.props; | ||
| this.setState({ | ||
| value: current | ||
| }); | ||
| if (!keyDownEvent) { | ||
| props.onSelect(current); | ||
| } | ||
| } | ||
| function clear() { | ||
| this.props.onClear(); | ||
| } | ||
| function onMonthPanelSelect(current) { | ||
| this.setState({ | ||
| value: current, | ||
| showMonthPanel: 0 | ||
| }); | ||
| } | ||
| function handleKeyDown(e) { | ||
| var keyCode = e.keyCode; | ||
| // mac | ||
| var ctrlKey = e.ctrlKey || e.metaKey; | ||
| switch (keyCode) { | ||
| case KeyCode.DOWN: | ||
| goWeek.call(this, 1); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.UP: | ||
| goWeek.call(this, -1); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.LEFT: | ||
| if (ctrlKey) { | ||
| this.previousYear(); | ||
| } else { | ||
| goDay.call(this, -1); | ||
| } | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.RIGHT: | ||
| if (ctrlKey) { | ||
| this.nextYear(); | ||
| } else { | ||
| goDay.call(this, 1); | ||
| } | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.HOME: | ||
| goStartMonth.call(this); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.END: | ||
| goEndMonth.call(this); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.PAGE_DOWN: | ||
| this.nextMonth(); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.PAGE_UP: | ||
| this.previousMonth(); | ||
| e.preventDefault(); | ||
| return true; | ||
| case KeyCode.ENTER: | ||
| this.props.onSelect(this.state.value); | ||
| e.preventDefault(); | ||
| return true; | ||
| } | ||
| this.props.onKeyDown(e); | ||
| } | ||
| function showMonthPanel() { | ||
| this.setState({ | ||
| showMonthPanel: 1 | ||
| }); | ||
| } | ||
| class Calendar extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| var value = props.value || props.defaultValue; | ||
| if (!value) { | ||
| value = new GregorianCalendar(); | ||
| value.setTime(Date.now()); | ||
| } | ||
| this.dateFormatter = new DateTimeFormat(props.locale.dateFormat); | ||
| this.state = { | ||
| orient: props.orient, | ||
| prefixCls: props.prefixCls || 'rc-calendar', | ||
| value: value | ||
| }; | ||
| // bind methods | ||
| this.onBlur = onBlur.bind(this); | ||
| this.onFocus = onFocus.bind(this); | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| this.nextMonth = goMonth.bind(this, 1); | ||
| this.previousMonth = goMonth.bind(this, -1); | ||
| this.nextYear = goYear.bind(this, 1); | ||
| this.previousYear = goYear.bind(this, -1); | ||
| this.chooseToday = chooseToday.bind(this); | ||
| this.clear = clear.bind(this); | ||
| this.handleSelect = handleSelect.bind(this); | ||
| this.onMonthPanelSelect = onMonthPanelSelect.bind(this); | ||
| this.handleKeyDown = handleKeyDown.bind(this); | ||
| this.showMonthPanel = showMonthPanel.bind(this); | ||
| } | ||
| shouldComponentUpdate() { | ||
| return rcUtil.PureRenderMixin.shouldComponentUpdate.apply(this, arguments); | ||
| } | ||
| componentWillReceiveProps(nextProps) { | ||
| var value = nextProps.value; | ||
| if (value !== undefined) { | ||
| if (!value) { | ||
| value = this.state.value.clone(); | ||
| value.setTime(Date.now()); | ||
| } | ||
| this.setState({ | ||
| value: value | ||
| }); | ||
| } | ||
| if (nextProps.orient) { | ||
| this.setState({ | ||
| orient: nextProps.orient | ||
| }); | ||
| } | ||
| if (nextProps.locale !== this.props.locale) { | ||
| this.dateFormatter = new DateTimeFormat(nextProps.locale.dateFormat); | ||
| } | ||
| } | ||
| renderDates() { | ||
| var props = this.props; | ||
| var i, j, current; | ||
| var dateTable = []; | ||
| var showWeekNumber = props.showWeekNumber; | ||
| var value = this.state.value; | ||
| var today = value.clone(); | ||
| var prefixClsFn = this.prefixClsFn; | ||
| var cellClass = prefixClsFn('cell'); | ||
| var weekNumberCellClass = prefixClsFn('week-number-cell'); | ||
| var dateClass = prefixClsFn('date'); | ||
| var dateRender = props.dateRender; | ||
| var disabledDate = props.disabledDate; | ||
| var dateFormatter = this.dateFormatter; | ||
| var todayClass = prefixClsFn('today'); | ||
| var selectedClass = prefixClsFn('selected-day'); | ||
| var lastMonthDayClass = prefixClsFn('last-month-cell'); | ||
| var nextMonthDayClass = prefixClsFn('next-month-btn-day'); | ||
| var disabledClass = prefixClsFn('disabled-cell'); | ||
| today.setTime(Date.now()); | ||
| var month1 = value.clone(); | ||
| month1.set(value.getYear(), value.getMonth(), 1); | ||
| var day = month1.getDayOfWeek(); | ||
| var lastMonthDiffDay = (day + 7 - value.getFirstDayOfWeek()) % 7; | ||
| // calculate last month | ||
| var lastMonth1 = month1.clone(); | ||
| lastMonth1.addDayOfMonth(0 - lastMonthDiffDay); | ||
| var passed = 0; | ||
| for (i = 0; i < DATE_ROW_COUNT; i++) { | ||
| for (j = 0; j < DATE_COL_COUNT; j++) { | ||
| current = lastMonth1; | ||
| if (passed) { | ||
| current = current.clone(); | ||
| current.addDayOfMonth(passed); | ||
| } | ||
| dateTable.push(current); | ||
| passed++; | ||
| } | ||
| } | ||
| var tableHtml = []; | ||
| passed = 0; | ||
| for (i = 0; i < DATE_ROW_COUNT; i++) { | ||
| var weekNumberCell; | ||
| var dateCells = []; | ||
| if (showWeekNumber) { | ||
| weekNumberCell = (<td key={dateTable[passed].getWeekOfYear()} role="gridcell" className = {weekNumberCellClass}>{dateTable[passed].getWeekOfYear()}</td>); | ||
| } | ||
| for (j = 0; j < DATE_COL_COUNT; j++) { | ||
| current = dateTable[passed]; | ||
| var cls = cellClass; | ||
| var disabled = false; | ||
| var selected = false; | ||
| if (isSameDay(current, today)) { | ||
| cls += ' ' + todayClass; | ||
| } | ||
| if (isSameDay(current, value)) { | ||
| cls += ' ' + selectedClass; | ||
| selected = true; | ||
| } | ||
| if (beforeCurrentMonthYear(current, value)) { | ||
| cls += ' ' + lastMonthDayClass; | ||
| } | ||
| if (afterCurrentMonthYear(current, value)) { | ||
| cls += ' ' + nextMonthDayClass; | ||
| } | ||
| if (disabledDate && disabledDate(current, value)) { | ||
| cls += ' ' + disabledClass; | ||
| disabled = true; | ||
| } | ||
| var dateHtml; | ||
| if (!(dateRender && (dateHtml = dateRender(current, value)))) { | ||
| dateHtml = ( | ||
| <span | ||
| key={getIdFromDate(current)} | ||
| className = {dateClass} | ||
| aria-selected={selected} | ||
| aria-disabled={disabled}> | ||
| {current.getDayOfMonth()} | ||
| </span>); | ||
| } | ||
| dateCells.push( | ||
| <td key={passed} onClick={disabled ? noop : handleDayClick.bind(this, current)} role="gridcell" title={dateFormatter.format(current)} className = {cls}> | ||
| {dateHtml} | ||
| </td>); | ||
| passed++; | ||
| } | ||
| tableHtml.push( | ||
| <tr | ||
| key={i} | ||
| role="row"> | ||
| {weekNumberCell} | ||
| {dateCells} | ||
| </tr>); | ||
| } | ||
| this.dateTable = dateTable; | ||
| return tableHtml; | ||
| } | ||
| getTodayTime() { | ||
| var value = this.state.value; | ||
| var today = value.clone(); | ||
| today.setTime(Date.now()); | ||
| return this.dateFormatter.format(today); | ||
| } | ||
| getMonthYear() { | ||
| var locale = this.props.locale; | ||
| var value = this.state.value; | ||
| return new DateTimeFormat(locale.monthYearFormat).format(value); | ||
| } | ||
| render() { | ||
| // console.log('re render'); | ||
| var showWeekNumberEl; | ||
| var props = this.props; | ||
| var locale = props.locale; | ||
| var state = this.state; | ||
| var value = state.value; | ||
| var veryShortWeekdays = []; | ||
| var weekDays = []; | ||
| var firstDayOfWeek = value.getFirstDayOfWeek(); | ||
| var prefixCls = state.prefixCls; | ||
| var prefixClsFn = this.prefixClsFn; | ||
| for (var i = 0; i < DATE_COL_COUNT; i++) { | ||
| var index = (firstDayOfWeek + i) % DATE_COL_COUNT; | ||
| veryShortWeekdays[i] = locale.format.veryShortWeekdays[index]; | ||
| weekDays[i] = locale.format.weekdays[index]; | ||
| } | ||
| if (props.showWeekNumber) { | ||
| showWeekNumberEl = ( | ||
| <th role="columnheader" className = {prefixClsFn("column-header", "week-number-header")}> | ||
| <span className ={prefixClsFn("column-header-inner")}>x</span> | ||
| </th>); | ||
| } | ||
| var weekDaysEls = weekDays.map((value, xindex)=> { | ||
| return ( | ||
| <th key={xindex} role="columnheader" title={value} className ={prefixClsFn("column-header")}> | ||
| <span className = {prefixClsFn("column-header-inner")}> | ||
| {veryShortWeekdays[xindex]} | ||
| </span> | ||
| </th>); | ||
| }); | ||
| var footerEl; | ||
| if (props.showToday || props.showTime) { | ||
| var todayEl; | ||
| if (props.showToday) { | ||
| todayEl = (<a className = {prefixClsFn("today-btn")} | ||
| role="button" | ||
| onClick={this.chooseToday} | ||
| title={this.getTodayTime()}>{locale.today}</a>); | ||
| } | ||
| var clearEl; | ||
| if (props.showClear) { | ||
| clearEl = (<a className = {prefixClsFn("clear-btn")} | ||
| role="button" | ||
| onClick={this.clear}>{locale.clear}</a>); | ||
| } | ||
| var footerBtn; | ||
| if (todayEl || clearEl) { | ||
| footerBtn = <div className={prefixClsFn("footer-btn")}>{todayEl} {clearEl}</div>; | ||
| } | ||
| var timeEl; | ||
| if (props.showTime) { | ||
| timeEl = (<Time value={value} rootPrefixCls={prefixCls} prefixClsFn={prefixClsFn} locale={locale} onChange={this.handleSelect}/>); | ||
| } | ||
| footerEl = ( | ||
| <div className = {prefixClsFn("footer")}> | ||
| {timeEl} | ||
| {footerBtn} | ||
| </div>); | ||
| } | ||
| var monthPanel; | ||
| if (state.showMonthPanel) { | ||
| monthPanel = <MonthPanel locale={locale} value={value} rootPrefixCls={state.prefixCls} onSelect={this.onMonthPanelSelect}/>; | ||
| } | ||
| var className = prefixCls; | ||
| if (props.className) { | ||
| className += ' ' + props.className; | ||
| } | ||
| var orient = state.orient; | ||
| if (orient) { | ||
| orient.forEach(o => { | ||
| className += ' ' + prefixClsFn('orient-' + o); | ||
| }); | ||
| } | ||
| return ( | ||
| <div className = {className} tabIndex="0" onFocus={this.onFocus} onBlur={this.onBlur} onKeyDown={this.handleKeyDown}> | ||
| <div style={{outline: 'none'}}> | ||
| <div className = {prefixClsFn("header")}> | ||
| <a className ={prefixClsFn("prev-year-btn")} | ||
| role="button" | ||
| onClick={this.previousYear} | ||
| title={locale.previousYear}> | ||
| « | ||
| </a> | ||
| <a className = {prefixClsFn("prev-month-btn")} | ||
| role="button" | ||
| onClick={this.previousMonth} | ||
| title={locale.previousMonth}> | ||
| ‹ | ||
| </a> | ||
| <a className = {prefixClsFn("month-select")} | ||
| role="button" | ||
| onClick={this.showMonthPanel} | ||
| title={locale.monthSelect}> | ||
| <span className = {prefixClsFn("month-select-content")}>{this.getMonthYear()}</span> | ||
| <span className = {prefixClsFn("month-select-arrow")}>x</span> | ||
| </a> | ||
| <a className = {prefixClsFn("next-month-btn")} | ||
| onClick={this.nextMonth} | ||
| title={locale.nextMonth}> | ||
| › | ||
| </a> | ||
| <a className = {prefixClsFn("next-year-btn")} | ||
| onClick={this.nextYear} | ||
| title={locale.nextYear}> | ||
| » | ||
| </a> | ||
| </div> | ||
| <div className = {prefixClsFn("calendar-body")}> | ||
| <table className = {prefixClsFn("table")} cellSpacing="0" role="grid"> | ||
| <thead> | ||
| <tr role="row"> | ||
| {showWeekNumberEl} | ||
| {weekDaysEls} | ||
| </tr> | ||
| </thead> | ||
| <tbody className = {prefixClsFn("tbody")}> | ||
| {this.renderDates()} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| {footerEl} | ||
| </div> | ||
| {monthPanel} | ||
| </div>); | ||
| } | ||
| } | ||
| Calendar.propTypes = { | ||
| value: React.PropTypes.object, | ||
| defaultValue: React.PropTypes.object, | ||
| className: React.PropTypes.string, | ||
| orient: React.PropTypes.arrayOf(React.PropTypes.oneOf(['left', 'top', 'right', 'bottom'])), | ||
| locale: React.PropTypes.object, | ||
| showWeekNumber: React.PropTypes.bool, | ||
| showToday: React.PropTypes.bool, | ||
| showTime: React.PropTypes.bool, | ||
| onSelect: React.PropTypes.func, | ||
| onBlur: React.PropTypes.func | ||
| }; | ||
| Calendar.defaultProps = { | ||
| locale: require('./locale/en-us'), | ||
| onKeyDown: noop, | ||
| className: '', | ||
| showToday: true, | ||
| onSelect: noop, | ||
| onFocus: noop, | ||
| onBlur: noop, | ||
| onClear: noop | ||
| }; | ||
| module.exports = Calendar; |
| var React = require('react'); | ||
| var ROW = 4; | ||
| var COL = 3; | ||
| var cx = require('rc-util').classSet; | ||
| function goYear(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addYear(direction); | ||
| this.setState({ | ||
| value: next | ||
| }); | ||
| } | ||
| function chooseDecade(year, e) { | ||
| var next = this.state.value.clone(); | ||
| next.setYear(year); | ||
| this.props.onSelect(next); | ||
| e.preventDefault(); | ||
| } | ||
| class DecadePanel extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| this.state = { | ||
| value: props.value, | ||
| prefixCls: props.rootPrefixCls + '-decade-panel' | ||
| }; | ||
| // bind methods | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| this.nextCentury = goYear.bind(this, 100); | ||
| this.previousCentury = goYear.bind(this, -100); | ||
| } | ||
| render() { | ||
| var value = this.state.value; | ||
| var locale = this.props.locale; | ||
| var currentYear = value.getYear(); | ||
| var startYear = parseInt(currentYear / 100, 10) * 100; | ||
| var preYear = startYear - 10; | ||
| var endYear = startYear + 99; | ||
| var decades = []; | ||
| var index = 0; | ||
| var prefixClsFn = this.prefixClsFn; | ||
| for (var i = 0; i < ROW; i++) { | ||
| decades[i] = []; | ||
| for (var j = 0; j < COL; j++) { | ||
| decades[i][j] = { | ||
| startDecade: preYear + index * 10, | ||
| endDecade: preYear + index * 10 + 9 | ||
| }; | ||
| index++; | ||
| } | ||
| } | ||
| var decadesEls = decades.map((row, index) => { | ||
| var tds = row.map(d => { | ||
| var startDecade = d.startDecade; | ||
| var endDecade = d.endDecade; | ||
| var classNameMap = {}; | ||
| classNameMap[prefixClsFn('cell')] = 1; | ||
| classNameMap[prefixClsFn('selected-cell')] = startDecade <= currentYear && currentYear <= endDecade; | ||
| classNameMap[prefixClsFn('last-century-cell')] = startDecade < startYear; | ||
| classNameMap[prefixClsFn('next-century-cell')] = endDecade > endYear; | ||
| return (<td | ||
| key={startDecade} | ||
| onClick={chooseDecade.bind(this, startDecade)} | ||
| role="gridcell" | ||
| className = {cx(classNameMap)} | ||
| > | ||
| <a | ||
| className={prefixClsFn('decade')}> | ||
| {startDecade} - {endDecade} | ||
| </a> | ||
| </td>); | ||
| }); | ||
| return (<tr key={index} role="row">{tds}</tr>); | ||
| }); | ||
| return ( | ||
| <div className={this.state.prefixCls}> | ||
| <div className = {prefixClsFn('header')}> | ||
| <a className = {prefixClsFn('prev-century-btn')} | ||
| role="button" | ||
| onClick={this.previousCentury} | ||
| title={locale.previousCentury}> | ||
| « | ||
| </a> | ||
| <div className = {prefixClsFn('century')}> | ||
| {startYear}-{endYear} | ||
| </div> | ||
| <a className = {prefixClsFn('next-century-btn')} | ||
| role="button" | ||
| onClick={this.nextCentury} | ||
| title={locale.nextCentury}> | ||
| » | ||
| </a> | ||
| </div> | ||
| <div className = {prefixClsFn('body')}> | ||
| <table className = {prefixClsFn('table')} cellSpacing="0" role="grid"> | ||
| <tbody className = {prefixClsFn('tbody')}> | ||
| {decadesEls} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| </div>); | ||
| } | ||
| } | ||
| DecadePanel.defaultProps = { | ||
| onSelect() { | ||
| } | ||
| }; | ||
| module.exports = DecadePanel; |
| var React = require('react'); | ||
| var DateTimeFormat = require('gregorian-calendar-format'); | ||
| var ROW = 3; | ||
| var COL = 4; | ||
| var cx = require('rc-util').classSet; | ||
| var YearPanel = require('./YearPanel'); | ||
| function goYear(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addYear(direction); | ||
| this.setState({ | ||
| value: next | ||
| }); | ||
| } | ||
| function showYearPanel() { | ||
| this.setState({ | ||
| showYearPanel: 1 | ||
| }); | ||
| } | ||
| function chooseMonth(month) { | ||
| var next = this.state.value.clone(); | ||
| next.setMonth(month); | ||
| this.props.onSelect(next); | ||
| } | ||
| function onYearPanelSelect(current) { | ||
| this.setState({ | ||
| value: current, | ||
| showYearPanel: 0 | ||
| }); | ||
| } | ||
| class MonthPanel extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| this.state = { | ||
| value: this.props.value, | ||
| prefixCls: this.props.rootPrefixCls + '-month-panel' | ||
| }; | ||
| // bind methods | ||
| this.nextYear = goYear.bind(this, 1); | ||
| this.previousYear = goYear.bind(this, -1); | ||
| this.showYearPanel = showYearPanel.bind(this); | ||
| this.onYearPanelSelect = onYearPanelSelect.bind(this); | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| } | ||
| getMonths() { | ||
| var props = this.props; | ||
| var value = this.state.value; | ||
| var current = value.clone(); | ||
| var locale = props.locale; | ||
| var monthYearFormat = locale.monthYearFormat; | ||
| var dateFormatter = new DateTimeFormat(monthYearFormat); | ||
| var months = []; | ||
| var shortMonths = locale.format.shortMonths; | ||
| var index = 0; | ||
| for (var i = 0; i < ROW; i++) { | ||
| months[i] = []; | ||
| for (var j = 0; j < COL; j++) { | ||
| current.setMonth(index); | ||
| months[i][j] = { | ||
| value: index, | ||
| content: shortMonths[index], | ||
| title: dateFormatter.format(current) | ||
| }; | ||
| index++; | ||
| } | ||
| } | ||
| return months; | ||
| } | ||
| render() { | ||
| var props = this.props; | ||
| var value = this.state.value; | ||
| var locale = props.locale; | ||
| var months = this.getMonths(); | ||
| var year = value.getYear(); | ||
| var currentMonth = value.getMonth(); | ||
| var prefixClsFn = this.prefixClsFn; | ||
| var monthsEls = months.map((month, index)=> { | ||
| var tds = month.map(m => { | ||
| var classNameMap = {}; | ||
| classNameMap[prefixClsFn('cell')] = 1; | ||
| classNameMap[prefixClsFn('selected-cell')] = m.value === currentMonth; | ||
| return ( | ||
| <td role="gridcell" | ||
| key={m.value} | ||
| onClick={chooseMonth.bind(this, m.value)} | ||
| title={m.title} | ||
| className = {cx(classNameMap)}> | ||
| <a | ||
| className = {prefixClsFn('month')}> | ||
| {m.content} | ||
| </a> | ||
| </td>); | ||
| }); | ||
| return (<tr key={index} role="row">{tds}</tr>); | ||
| }); | ||
| var yearPanel; | ||
| if (this.state.showYearPanel) { | ||
| yearPanel = <YearPanel locale={locale} value={value} rootPrefixCls={props.rootPrefixCls} onSelect={this.onYearPanelSelect}/>; | ||
| } | ||
| return ( | ||
| <div className= {this.state.prefixCls}> | ||
| <div> | ||
| <div className = {prefixClsFn('header')}> | ||
| <a className = {prefixClsFn('prev-year-btn')} | ||
| role="button" | ||
| onClick={this.previousYear} | ||
| title={locale.previousYear}> | ||
| « | ||
| </a> | ||
| <a className = {prefixClsFn('year-select')} | ||
| role="button" | ||
| onClick={this.showYearPanel} | ||
| title={locale.yearSelect}> | ||
| <span className = {prefixClsFn('year-select-content')}>{year}</span> | ||
| <span className = {prefixClsFn('year-select-arrow')}>x</span> | ||
| </a> | ||
| <a className = {prefixClsFn('next-year-btn')} | ||
| role="button" | ||
| onClick={this.nextYear} | ||
| title={locale.nextYear}> | ||
| » | ||
| </a> | ||
| </div> | ||
| <div className = {prefixClsFn('body')}> | ||
| <table className = {prefixClsFn('table')} cellSpacing="0" role="grid"> | ||
| <tbody className = {prefixClsFn('tbody')}> | ||
| {monthsEls} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| </div> | ||
| {yearPanel} | ||
| </div>); | ||
| } | ||
| } | ||
| MonthPanel.defaultProps = { | ||
| onSelect() { | ||
| } | ||
| }; | ||
| module.exports = MonthPanel; |
-259
| var React = require('react'); | ||
| var DateTimeFormat = require('gregorian-calendar-format'); | ||
| var rcUtil = require('rc-util'); | ||
| var KeyCode = require('rc-util').KeyCode; | ||
| var domAlign = require('dom-align'); | ||
| var orientMap = { | ||
| tl: ['top', 'left'], | ||
| tr: ['top', 'right'], | ||
| bl: ['bottom', 'left'], | ||
| br: ['bottom', 'right'] | ||
| }; | ||
| function getImmutableOrient(orient) { | ||
| if (orient) { | ||
| for (var i in orientMap) { | ||
| var original = orientMap[i]; | ||
| if (original[0] === orient[0] && original[1] === orient[1]) { | ||
| return original; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| function refFn(field, component) { | ||
| this[field] = component; | ||
| } | ||
| /** | ||
| * DatePicker = wrap input using Calendar | ||
| */ | ||
| class Picker extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| this.state = { | ||
| open: props.open, | ||
| value: props.value || props.defaultValue | ||
| }; | ||
| // bind methods | ||
| [ | ||
| 'handleInputClick', 'handleCalendarBlur', 'handleTriggerClick', | ||
| 'handleCalendarClear', 'handleCalendarKeyDown', | ||
| 'handleKeyDown', 'handleCalendarSelect' | ||
| ].forEach(m => { | ||
| this[m] = this[m].bind(this); | ||
| }); | ||
| this.saveCalendarRef = refFn.bind(this, 'calendarInstance'); | ||
| this.saveInputRef = refFn.bind(this, 'inputInstance'); | ||
| } | ||
| componentWillReceiveProps(nextProps) { | ||
| if (nextProps.value) { | ||
| this.setState({ | ||
| value: nextProps.value | ||
| }); | ||
| } | ||
| } | ||
| open(callback) { | ||
| this.setState({ | ||
| open: true | ||
| }, callback); | ||
| } | ||
| close(callback) { | ||
| this.setState({ | ||
| open: false | ||
| }, callback); | ||
| } | ||
| handleInputClick() { | ||
| this.toggle(); | ||
| } | ||
| handleTriggerClick() { | ||
| this.toggle(); | ||
| } | ||
| toggle(callback) { | ||
| this.setState({ | ||
| open: !this.state.open | ||
| }, callback); | ||
| } | ||
| handleKeyDown(e) { | ||
| // down | ||
| if (e.keyCode === KeyCode.DOWN) { | ||
| e.preventDefault(); | ||
| this.open(); | ||
| } | ||
| } | ||
| handleCalendarKeyDown(e) { | ||
| if (e.keyCode === KeyCode.ESC) { | ||
| e.stopPropagation(); | ||
| this.close(() => { | ||
| React.findDOMNode(this.inputInstance).focus(); | ||
| }); | ||
| } | ||
| } | ||
| handleCalendarSelect(value) { | ||
| this.props.calendar.props.onSelect(value); | ||
| var currentValue = this.state.value; | ||
| if (this.props.calendar.props.showTime) { | ||
| this.setState({ | ||
| value: value | ||
| }); | ||
| } else { | ||
| this.setState({ | ||
| value: value, | ||
| open: false | ||
| }, () => { | ||
| React.findDOMNode(this.inputInstance).focus(); | ||
| }); | ||
| } | ||
| if (!currentValue || currentValue.getTime() !== value.getTime()) { | ||
| this.props.onChange(value); | ||
| } | ||
| } | ||
| handleCalendarBlur() { | ||
| // if invisible, will not trigger blur | ||
| this.setState({ | ||
| open: false | ||
| }); | ||
| } | ||
| handleCalendarClear() { | ||
| this.props.calendar.props.onClear(); | ||
| this.setState({ | ||
| open: false, | ||
| value: null | ||
| }, ()=> { | ||
| React.findDOMNode(this.inputInstance).focus(); | ||
| }); | ||
| if (this.state.value !== null) { | ||
| this.props.onChange(null); | ||
| } | ||
| } | ||
| componentDidMount() { | ||
| this.componentDidUpdate(); | ||
| } | ||
| componentDidUpdate() { | ||
| if (this.state.open && !this._lastOpen) { | ||
| var orient = this._cacheCalendar.props.orient; | ||
| var points = ['tl', 'bl']; | ||
| var offset = [0, 5]; | ||
| if (orient.indexOf('top') !== -1 && orient.indexOf('left') !== -1) { | ||
| points = ['tl', 'bl']; | ||
| } else if (orient.indexOf('top') !== -1 && orient.indexOf('right') !== -1) { | ||
| points = ['tr', 'br']; | ||
| } else if (orient.indexOf('bottom') !== -1 && orient.indexOf('left') !== -1) { | ||
| points = ['bl', 'tl']; | ||
| offset = [0, -5]; | ||
| } else if (orient.indexOf('bottom') !== -1 && orient.indexOf('right') !== -1) { | ||
| points = ['br', 'tr']; | ||
| offset = [0, -5]; | ||
| } | ||
| var align = domAlign(React.findDOMNode(this.calendarInstance), React.findDOMNode(this.inputInstance), { | ||
| points: points, | ||
| offset: offset, | ||
| overflow: { | ||
| adjustX: 1, | ||
| adjustY: 1 | ||
| } | ||
| }); | ||
| points = align.points; | ||
| var newOrient = orientMap[points[0]]; | ||
| this.calendarInstance.setState({ | ||
| orient: newOrient | ||
| }); | ||
| React.findDOMNode(this.calendarInstance).focus(); | ||
| } | ||
| this._lastOpen = this.state.open; | ||
| } | ||
| render() { | ||
| var props = this.props; | ||
| // var input = React.Children.only(props.children); bug 0.13.0 | ||
| /* | ||
| children: Object | ||
| .0: (...) | ||
| get .0: function () { | ||
| set .0: function (value) { | ||
| _reactDidWarn: false | ||
| _reactFragment: Object | ||
| __proto__: Object | ||
| */ | ||
| var input = props.children; | ||
| if (!React.isValidElement(input)) { | ||
| var children = input; | ||
| React.Children.forEach(children, m => { | ||
| input = m; | ||
| }); | ||
| } | ||
| var state = this.state; | ||
| var value = state.value; | ||
| var calendar = this._cacheCalendar; | ||
| if (state.open) { | ||
| var calendarInstance = this.calendarInstance; | ||
| var calendarProp = props.calendar; | ||
| this._cacheCalendar = calendar = React.cloneElement(calendarProp, { | ||
| ref: rcUtil.createChainedFunction(calendarProp.props.ref, this.saveCalendarRef), | ||
| value: value, | ||
| // focused: true, | ||
| orient: calendarInstance && calendarInstance.state.orient || getImmutableOrient(calendarProp.props.orient) || orientMap.tl, | ||
| onBlur: this.handleCalendarBlur, | ||
| onKeyDown: this.handleCalendarKeyDown, | ||
| onSelect: this.handleCalendarSelect, | ||
| onClear: this.handleCalendarClear | ||
| }); | ||
| } | ||
| var inputValue = ''; | ||
| if (value) { | ||
| inputValue = props.formatter.format(value); | ||
| } | ||
| input = React.cloneElement(input, { | ||
| ref: rcUtil.createChainedFunction(input.props.ref, this.saveInputRef), | ||
| readOnly: true, | ||
| onClick: this.handleInputClick, | ||
| value: inputValue, | ||
| onKeyDown: this.handleKeyDown | ||
| }); | ||
| var classes = [props.prefixCls]; | ||
| if (state.open) { | ||
| classes.push(props.prefixCls + '-open'); | ||
| } | ||
| var trigger = props.trigger; | ||
| if (trigger) { | ||
| trigger = React.cloneElement(trigger, { | ||
| onClick: this.handleTriggerClick, | ||
| unselectable: true, | ||
| onMouseDown: prevent | ||
| }); | ||
| } | ||
| return <span className={classes.join(' ')}>{[input, calendar, trigger]}</span>; | ||
| } | ||
| } | ||
| function prevent(e) { | ||
| e.preventDefault(); | ||
| } | ||
| Picker.propTypes = { | ||
| onChange: React.PropTypes.func | ||
| }; | ||
| Picker.defaultProps = { | ||
| prefixCls: 'rc-calendar-picker', | ||
| onChange() { | ||
| }, | ||
| formatter: new DateTimeFormat('yyyy-MM-dd') | ||
| }; | ||
| module.exports = Picker; |
-163
| var React = require('react'); | ||
| var rcUtil = require('rc-util'); | ||
| var KeyCode = rcUtil.KeyCode; | ||
| var TimePanel = require('./TimePanel'); | ||
| var setHourOfDay = 'setHourOfDay'; | ||
| var setMinutes = 'setMinutes'; | ||
| var setSeconds = 'setSeconds'; | ||
| function padding(number) { | ||
| if (number < 10) { | ||
| number = '0' + number; | ||
| } | ||
| return number; | ||
| } | ||
| function loop(value, min, max) { | ||
| if (value === min - 1) { | ||
| value = max; | ||
| } else if (value === max + 1) { | ||
| value = min; | ||
| } | ||
| return value; | ||
| } | ||
| function keyDownWrap(method, min, max) { | ||
| return function (e) { | ||
| var value = e.target.value; | ||
| var number = parseInt(value, 10); | ||
| var keyCode = e.keyCode; | ||
| var handled; | ||
| if (keyCode === KeyCode.DOWN) { | ||
| number++; | ||
| e.stopPropagation(); | ||
| e.preventDefault(); | ||
| handled = 1; | ||
| } else if (keyCode === KeyCode.UP) { | ||
| number--; | ||
| e.stopPropagation(); | ||
| e.preventDefault(); | ||
| handled = 1; | ||
| } | ||
| if (handled) { | ||
| number = loop(number, min, max); | ||
| var time = this.props.value.clone(); | ||
| time[method](number); | ||
| this.props.onChange(time, e); | ||
| } | ||
| }; | ||
| } | ||
| class Time extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| this.state = { | ||
| showHourPanel: 0, | ||
| showMinutePanel: 0, | ||
| showSecondPanel: 0 | ||
| }; | ||
| [ | ||
| 'onHourKeyDown', 'onMinuteKeyDown', 'onSecondKeyDown', 'onHourClick', 'onMinuteClick', 'onSecondClick', | ||
| 'onSelectPanel' | ||
| ].forEach(m => { | ||
| this[m] = this[m].bind(this); | ||
| }); | ||
| } | ||
| onSelectPanel(value, setter) { | ||
| this.setState({ | ||
| showHourPanel: 0, | ||
| showMinutePanel: 0, | ||
| showSecondPanel: 0 | ||
| }, ()=> { | ||
| // ie9 has broken focus | ||
| React.findDOMNode(this.refs[setter]).focus(); | ||
| }); | ||
| this.props.onChange(value); | ||
| } | ||
| onHourClick() { | ||
| this.setState({ | ||
| showHourPanel: 1, | ||
| showMinutePanel: 0, | ||
| showSecondPanel: 0 | ||
| }); | ||
| } | ||
| onMinuteClick() { | ||
| this.setState({ | ||
| showHourPanel: 0, | ||
| showMinutePanel: 1, | ||
| showSecondPanel: 0 | ||
| }); | ||
| } | ||
| onSecondClick() { | ||
| this.setState({ | ||
| showHourPanel: 0, | ||
| showMinutePanel: 0, | ||
| showSecondPanel: 1 | ||
| }); | ||
| } | ||
| shouldComponentUpdate() { | ||
| return rcUtil.PureRenderMixin.shouldComponentUpdate.apply(this, arguments); | ||
| } | ||
| render() { | ||
| var state = this.state; | ||
| var props = this.props; | ||
| var prefixClsFn = props.prefixClsFn; | ||
| var value = props.value; | ||
| var locale = props.locale; | ||
| var hour = value.getHourOfDay(); | ||
| var minute = value.getMinutes(); | ||
| var second = value.getSeconds(); | ||
| var panel; | ||
| var commonProps = { | ||
| value: value, | ||
| onSelect: this.onSelectPanel, | ||
| rootPrefixCls: props.rootPrefixCls | ||
| }; | ||
| if (state.showHourPanel) { | ||
| panel = <TimePanel rowCount={6} colCount={4} getter="getHourOfDay" setter={setHourOfDay} | ||
| title={locale.hourPanelTitle} | ||
| {...commonProps}/>; | ||
| } else if (state.showMinutePanel) { | ||
| panel = <TimePanel rowCount={6} colCount={10} getter="getMinutes" setter={setMinutes} | ||
| title={locale.minutePanelTitle} | ||
| {...commonProps}/>; | ||
| } else if (state.showSecondPanel) { | ||
| panel = <TimePanel rowCount={6} colCount={10} getter="getSeconds" setter={setSeconds} | ||
| title={locale.secondPanelTitle} | ||
| {...commonProps}/>; | ||
| } | ||
| return (<div> | ||
| <input className = {prefixClsFn("time-input")} title={locale.hourInput} | ||
| ref={setHourOfDay} | ||
| readOnly value={padding(hour)} | ||
| onClick={this.onHourClick} | ||
| onKeyDown={this.onHourKeyDown}/> | ||
| <span> : </span> | ||
| <input className = {prefixClsFn("time-input")} title={locale.minuteInput} | ||
| ref={setMinutes} | ||
| readOnly value={padding(minute)} | ||
| onClick={this.onMinuteClick} | ||
| onKeyDown = {this.onMinuteKeyDown}/> | ||
| <span> : </span> | ||
| <input className = {prefixClsFn("time-input")} title={locale.secondInput} | ||
| ref={setSeconds} | ||
| readOnly value={padding(second)} | ||
| onClick={this.onSecondClick} | ||
| onKeyDown = {this.onSecondKeyDown}/> | ||
| {panel} | ||
| </div>); | ||
| } | ||
| } | ||
| Time.prototype.onHourKeyDown = keyDownWrap('setHourOfDay', 0, 23); | ||
| Time.prototype.onMinuteKeyDown = keyDownWrap('setMinutes', 0, 59); | ||
| Time.prototype.onSecondKeyDown = keyDownWrap('setSeconds', 0, 59); | ||
| module.exports = Time; |
| var React = require('react'); | ||
| var cx = require('rc-util').classSet; | ||
| function choose(hour, e) { | ||
| var next = this.state.value.clone(); | ||
| var method = this.props.setter; | ||
| next[method](hour); | ||
| this.props.onSelect(next,method); | ||
| e.preventDefault(); | ||
| } | ||
| class TimePanel extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| this.state = { | ||
| value: props.value, | ||
| prefixCls: props.rootPrefixCls + '-time-panel' | ||
| }; | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| } | ||
| render() { | ||
| var value = this.state.value; | ||
| var props = this.props; | ||
| var method = props.getter; | ||
| var currentHour = value[method](); | ||
| var data = []; | ||
| var prefixClsFn = this.prefixClsFn; | ||
| var ROW = props.rowCount; | ||
| var COL = props.colCount; | ||
| for (var i = 0; i < ROW; i++) { | ||
| data[i] = []; | ||
| for (var j = 0; j < COL; j++) { | ||
| data[i][j] = i * COL + j; | ||
| } | ||
| } | ||
| var hoursEls = data.map((row, index)=> { | ||
| var tds = row.map(d => { | ||
| var classNameMap = {}; | ||
| classNameMap[prefixClsFn('cell')] = 1; | ||
| classNameMap[prefixClsFn('selected-cell')] = d === currentHour; | ||
| return (<td | ||
| key={d} | ||
| onClick={choose.bind(this, d)} | ||
| role="gridcell" | ||
| className = {cx(classNameMap)} > | ||
| <a | ||
| className={prefixClsFn('time')}> | ||
| {d} | ||
| </a> | ||
| </td>); | ||
| }); | ||
| return (<tr key={index} role="row">{tds}</tr>); | ||
| }); | ||
| return ( | ||
| <div className={this.state.prefixCls}> | ||
| <div className = {prefixClsFn('header')}> | ||
| <div className = {prefixClsFn('title')}> | ||
| {props.title} | ||
| </div> | ||
| </div> | ||
| <div className = {prefixClsFn('body')}> | ||
| <table className = {prefixClsFn('table')} cellSpacing="0" role="grid"> | ||
| <tbody className = {prefixClsFn('tbody')}> | ||
| {hoursEls} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| </div>); | ||
| } | ||
| } | ||
| TimePanel.defaultProps = { | ||
| onSelect() { | ||
| } | ||
| }; | ||
| module.exports = TimePanel; |
| var React = require('react'); | ||
| var DateTimeFormat = require('gregorian-calendar-format'); | ||
| var ROW = 3; | ||
| var COL = 4; | ||
| var cx = require('rc-util').classSet; | ||
| var DecadePanel = require('./DecadePanel'); | ||
| function goYear(direction) { | ||
| var next = this.state.value.clone(); | ||
| next.addYear(direction); | ||
| this.setState({value: next}); | ||
| } | ||
| function chooseYear(year) { | ||
| var next = this.state.value.clone(); | ||
| next.setYear(year); | ||
| this.props.onSelect(next); | ||
| } | ||
| class YearPanel extends React.Component { | ||
| constructor(props) { | ||
| super(props); | ||
| this.prefixClsFn = require('./prefixClsFn').bind(this); | ||
| this.state = { | ||
| value: props.value, | ||
| prefixCls: props.rootPrefixCls + '-year-panel' | ||
| }; | ||
| this.nextDecade = goYear.bind(this, 10); | ||
| this.previousDecade = goYear.bind(this, -10); | ||
| ['showDecadePanel', 'onDecadePanelSelect'].forEach(m => { | ||
| this[m] = this[m].bind(this); | ||
| }); | ||
| } | ||
| showDecadePanel() { | ||
| this.setState({ | ||
| showDecadePanel: 1 | ||
| }); | ||
| } | ||
| onDecadePanelSelect(current) { | ||
| this.setState({ | ||
| value: current, | ||
| showDecadePanel: 0 | ||
| }); | ||
| } | ||
| getYears() { | ||
| var value = this.state.value; | ||
| var currentYear = value.getYear(); | ||
| var startYear = parseInt(currentYear / 10, 10) * 10; | ||
| var preYear = startYear - 1; | ||
| var current = value.clone(); | ||
| var locale = this.props.locale; | ||
| var yearFormat = locale.yearFormat; | ||
| var dateFormatter = new DateTimeFormat(yearFormat); | ||
| var years = []; | ||
| var index = 0; | ||
| for (var i = 0; i < ROW; i++) { | ||
| years[i] = []; | ||
| for (var j = 0; j < COL; j++) { | ||
| current.setYear(preYear + index); | ||
| years[i][j] = { | ||
| content: preYear + index, | ||
| title: dateFormatter.format(current) | ||
| }; | ||
| index++; | ||
| } | ||
| } | ||
| return years; | ||
| } | ||
| render() { | ||
| var props = this.props; | ||
| var value = this.state.value; | ||
| var locale = props.locale; | ||
| var years = this.getYears(); | ||
| var currentYear = value.getYear(); | ||
| var startYear = parseInt(currentYear / 10, 10) * 10; | ||
| var endYear = startYear + 9; | ||
| var prefixClsFn = this.prefixClsFn; | ||
| var yeasEls = years.map((row, index) => { | ||
| var tds = row.map(y => { | ||
| var classNameMap = {}; | ||
| classNameMap[prefixClsFn('cell')] = 1; | ||
| classNameMap[prefixClsFn('selected-cell')] = y.content === currentYear; | ||
| classNameMap[prefixClsFn('last-decade-cell')] = y.content < startYear; | ||
| classNameMap[prefixClsFn('next-decade-cell')] = y.content > endYear; | ||
| return ( | ||
| <td role="gridcell" | ||
| title={y.title} | ||
| key={y.content} | ||
| onClick={chooseYear.bind(this, y.content)} | ||
| className = {cx(classNameMap)} | ||
| > | ||
| <a | ||
| className={prefixClsFn('year')}> | ||
| {y.content} | ||
| </a> | ||
| </td>); | ||
| }); | ||
| return (<tr key={index} role="row">{tds}</tr>); | ||
| }); | ||
| var decadePanel; | ||
| if (this.state.showDecadePanel) { | ||
| decadePanel = <DecadePanel locale={locale} value={value} rootPrefixCls={props.rootPrefixCls} onSelect={this.onDecadePanelSelect}/>; | ||
| } | ||
| return ( | ||
| <div className={this.state.prefixCls}> | ||
| <div> | ||
| <div className = {prefixClsFn('header')}> | ||
| <a className = {prefixClsFn('prev-decade-btn')} | ||
| role="button" | ||
| onClick={this.previousDecade} | ||
| title={locale.previousDecade}> | ||
| « | ||
| </a> | ||
| <a className = {prefixClsFn('decade-select')} | ||
| role="button" | ||
| onClick={this.showDecadePanel} | ||
| title={locale.decadeSelect}> | ||
| <span className = {prefixClsFn('decade-select-content')}> | ||
| {startYear}-{endYear} | ||
| </span> | ||
| <span className = {prefixClsFn('decade-select-arrow')}>x</span> | ||
| </a> | ||
| <a className = {prefixClsFn('next-decade-btn')} | ||
| role="button" | ||
| onClick={this.nextDecade} | ||
| title={locale.nextDecade}> | ||
| » | ||
| </a> | ||
| </div> | ||
| <div className = {prefixClsFn('body')}> | ||
| <table className = {prefixClsFn('table')} cellSpacing="0" role="grid"> | ||
| <tbody className = {prefixClsFn('tbody')}> | ||
| {yeasEls} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| </div> | ||
| {decadePanel} | ||
| </div>); | ||
| } | ||
| } | ||
| YearPanel.defaultProps = { | ||
| onSelect() { | ||
| } | ||
| }; | ||
| module.exports = YearPanel; |
| /** @jsx React.DOM */ | ||
| var keyCode = require('rc-util').KeyCode; | ||
| var expect = require('expect.js'); | ||
| var Calendar = require('../index'); | ||
| var React = require('react/addons'); | ||
| var TestUtils = React.addons.TestUtils; | ||
| var Simulate = TestUtils.Simulate; | ||
| var async = require('async'); | ||
| describe('Calendar', function () { | ||
| var calendar; | ||
| var container = document.createElement('div'); | ||
| document.body.appendChild(container); | ||
| beforeEach(function (done) { | ||
| React.render(<Calendar showToday={true} showWeekNumber={true} showTime={true}/>, container, function () { | ||
| calendar = this; | ||
| done(); | ||
| }); | ||
| }); | ||
| afterEach(function () { | ||
| React.unmountComponentAtNode(container); | ||
| }); | ||
| describe('keyboard works', function () { | ||
| it('left works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addDayOfMonth(-1); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.LEFT | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getDayOfMonth()).to.be(expected.getDayOfMonth()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('right works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addDayOfMonth(1); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.RIGHT | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getDayOfMonth()).to.be(expected.getDayOfMonth()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('up works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addDayOfMonth(-7); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.UP | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getDayOfMonth()).to.be(expected.getDayOfMonth()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('down works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addDayOfMonth(7); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.DOWN | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getDayOfMonth()).to.be(expected.getDayOfMonth()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('pageDown works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addMonth(1); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.PAGE_DOWN | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getMonth()).to.be(expected.getMonth()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('pageUp works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addMonth(-1); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.PAGE_UP | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getMonth()).to.be(expected.getMonth()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('ctrl left works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addYear(-1); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.LEFT, | ||
| ctrlKey: 1 | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getYear()).to.be(expected.getYear()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('ctrl right works', function (done) { | ||
| var original = calendar.state.value; | ||
| var expected = original.clone(); | ||
| expected.addYear(1); | ||
| Simulate.keyDown(React.findDOMNode(calendar), { | ||
| keyCode: keyCode.RIGHT, | ||
| ctrlKey: 1 | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getYear()).to.be(expected.getYear()); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| }); | ||
| it('next month works', function (done) { | ||
| var month = calendar.state.value.getMonth(); | ||
| if (month === 11) { | ||
| month = -1; | ||
| } | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-next-month-btn')[0]); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getMonth()).to.be(month + 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('previous month works', function (done) { | ||
| var month = calendar.state.value.getMonth(); | ||
| if (month === 0) { | ||
| month = 12; | ||
| } | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-prev-month-btn')[0]); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getMonth()).to.be(month - 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('next year works', function (done) { | ||
| var year = calendar.state.value.getYear(); | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-next-year-btn')[0]); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getYear()).to.be(year + 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('previous year works', function (done) { | ||
| var year = calendar.state.value.getYear(); | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-prev-year-btn')[0]); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getYear()).to.be(year - 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('render works', function () { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-cell').length).to.above(0); | ||
| }); | ||
| it('onSelect works', function (done) { | ||
| var day; | ||
| function onSelect(d) { | ||
| expect(d.getDayOfMonth()).to.be(parseInt(day.props.children), 10); | ||
| done(); | ||
| } | ||
| calendar = React.render(<Calendar showToday={true} | ||
| onSelect={onSelect} | ||
| showWeekNumber={true} showTime={true}/>, container); | ||
| day = TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-date')[5]; | ||
| Simulate.click(day); | ||
| }); | ||
| it('month panel shows', function (done) { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-month-panel').length).to.be(0); | ||
| Simulate.click(TestUtils.findRenderedDOMComponentWithClass(calendar, 'rc-calendar-month-select')); | ||
| async.series([function (next) { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-month-panel').length).to.be(1); | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-month-panel-month').length).to.be(12); | ||
| var m = TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-month-panel-month')[9]; | ||
| Simulate.click(m); | ||
| setTimeout(next, 10); | ||
| }, function (next) { | ||
| expect(calendar.state.value.getMonth()).to.be(9); | ||
| next(); | ||
| }], done); | ||
| }); | ||
| it('year panel works', function (done) { | ||
| var text; | ||
| async.series([function (done) { | ||
| Simulate.click(TestUtils.findRenderedDOMComponentWithClass(calendar, 'rc-calendar-month-select')); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| Simulate.click(TestUtils.findRenderedDOMComponentWithClass(calendar, 'rc-calendar-month-panel-year-select')); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-year-panel').length).to.be(1); | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-year-panel-year').length).to.be(12); | ||
| var year = TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-year-panel-year')[9]; | ||
| text = year.props.children; | ||
| Simulate.click(year); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| var m = TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-month-panel-month')[9]; | ||
| Simulate.click(m); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| expect(calendar.state.value.getYear()).to.be(text); | ||
| done(); | ||
| }], done); | ||
| }); | ||
| it('decade panel works', function (done) { | ||
| async.series([function (done) { | ||
| Simulate.click(TestUtils.findRenderedDOMComponentWithClass(calendar, 'rc-calendar-month-select')); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| Simulate.click(TestUtils.findRenderedDOMComponentWithClass(calendar, 'rc-calendar-month-panel-year-select')); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| Simulate.click(TestUtils.findRenderedDOMComponentWithClass(calendar, 'rc-calendar-year-panel-decade-select')); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-decade-panel').length).to.be(1); | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-decade-panel-decade').length).to.be(12); | ||
| done(); | ||
| }], done); | ||
| }); | ||
| }); |
| /** @jsx React.DOM */ | ||
| var keyCode = require('rc-util').KeyCode; | ||
| var expect = require('expect.js'); | ||
| var Calendar = require('../index'); | ||
| var React = require('react/addons'); | ||
| var TestUtils = React.addons.TestUtils; | ||
| var Simulate = TestUtils.Simulate; | ||
| var async = require('async'); | ||
| describe('Time', function () { | ||
| var calendar; | ||
| var container = document.createElement('div'); | ||
| document.body.appendChild(container); | ||
| beforeEach(function (done) { | ||
| React.render(<Calendar showToday={true} showWeekNumber={true} showTime={true}/>, container, function () { | ||
| calendar = this; | ||
| done(); | ||
| }); | ||
| }); | ||
| afterEach(function () { | ||
| React.unmountComponentAtNode(container); | ||
| }); | ||
| describe('keyboard', function () { | ||
| it('hour pane works for up', function (done) { | ||
| var hour = calendar.state.value.getHourOfDay(); | ||
| if (hour === 0) { | ||
| hour = 24; | ||
| } | ||
| Simulate.keyDown(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[0], { | ||
| keyCode: keyCode.UP | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getHourOfDay()).to.be(hour - 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('hour pane works for down', function (done) { | ||
| var hour = calendar.state.value.getHourOfDay(); | ||
| if (hour === 23) { | ||
| hour = -1; | ||
| } | ||
| Simulate.keyDown(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[0], { | ||
| keyCode: keyCode.DOWN | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getHourOfDay()).to.be(hour + 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('minute pane works for up', function (done) { | ||
| var minute = calendar.state.value.getMinutes(); | ||
| if (minute === 0) { | ||
| minute = 60; | ||
| } | ||
| Simulate.keyDown(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[1], { | ||
| keyCode: keyCode.UP | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getMinutes()).to.be(minute - 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('minute pane works for down', function (done) { | ||
| var minute = calendar.state.value.getMinutes(); | ||
| if (minute === 59) { | ||
| minute = -1; | ||
| } | ||
| Simulate.keyDown(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[1], { | ||
| keyCode: keyCode.DOWN | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getMinutes()).to.be(minute + 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('second pane works for up', function (done) { | ||
| var second = calendar.state.value.getSeconds(); | ||
| if (second === 0) { | ||
| second = 59; | ||
| } | ||
| Simulate.keyDown(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[2], { | ||
| keyCode: keyCode.UP | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getSeconds()).to.be(second - 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('second pane works for down', function (done) { | ||
| var second = calendar.state.value.getSeconds(); | ||
| if (second === 59) { | ||
| second = -1; | ||
| } | ||
| Simulate.keyDown(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[2], { | ||
| keyCode: keyCode.DOWN | ||
| }); | ||
| setTimeout(function () { | ||
| expect(calendar.state.value.getSeconds()).to.be(second + 1); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| }); | ||
| it('hour pane shows', function (done) { | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[0]); | ||
| async.series([function (done) { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-panel-time').length).to.be(24); | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-panel-time')[2]); | ||
| setTimeout(done, 10); | ||
| }, function (done) { | ||
| expect(calendar.state.value.getHourOfDay()).to.be(2); | ||
| done(); | ||
| }], done); | ||
| }); | ||
| it('minute pane shows', function (done) { | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[1]); | ||
| setTimeout(function () { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-panel-time').length).to.be(60); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| it('second pane shows', function (done) { | ||
| Simulate.click(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-input')[2]); | ||
| setTimeout(function () { | ||
| expect(TestUtils.scryRenderedDOMComponentsWithClass(calendar, 'rc-calendar-time-panel-time').length).to.be(60); | ||
| done(); | ||
| }, 10); | ||
| }); | ||
| }); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
221321
38.72%74
15.63%5538
44.82%1
Infinity%