From 050cd828d3e76399c00ee8f937c5402a9205cd44 Mon Sep 17 00:00:00 2001 From: Ho Le Chi Hieu Date: Tue, 25 Sep 2018 15:24:07 +0700 Subject: [PATCH 001/114] Add Vietnamese translation (#418) --- src/locale/vi_VN.js | 28 + tests/__snapshots__/locale.spec.js.snap | 768 ++++++++++++++++++++++++ tests/locale.spec.js | 1 + 3 files changed, 797 insertions(+) create mode 100644 src/locale/vi_VN.js diff --git a/src/locale/vi_VN.js b/src/locale/vi_VN.js new file mode 100644 index 000000000..69cadd452 --- /dev/null +++ b/src/locale/vi_VN.js @@ -0,0 +1,28 @@ +export default { + today: 'Hôm nay', + now: 'Bây giờ', + backToToday: 'Trở về hôm nay', + ok: 'Ok', + clear: 'Xóa', + month: 'Tháng', + year: 'Năm', + timeSelect: 'Chọn thời gian', + dateSelect: 'Chọn ngày', + weekSelect: 'Chọn tuần', + monthSelect: 'Chọn tháng', + yearSelect: 'Chọn năm', + decadeSelect: 'Chọn thập kỷ', + yearFormat: 'YYYY', + dateFormat: 'D/M/YYYY', + dayFormat: 'D', + dateTimeFormat: 'D/M/YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Tháng trước (PageUp)', + nextMonth: 'Tháng sau (PageDown)', + previousYear: 'Năm trước (Control + left)', + nextYear: 'Năm sau (Control + right)', + previousDecade: 'Thập kỷ trước', + nextDecade: 'Thập kỷ sau', + previousCentury: 'Thế kỷ trước', + nextCentury: 'Thế kỷ sau', +}; diff --git a/tests/__snapshots__/locale.spec.js.snap b/tests/__snapshots__/locale.spec.js.snap index 4e911d385..d43e39205 100644 --- a/tests/__snapshots__/locale.spec.js.snap +++ b/tests/__snapshots__/locale.spec.js.snap @@ -27648,6 +27648,774 @@ exports[`locales renders uk_UA correctly 1`] = ` `; +exports[`locales renders vi_VN correctly 1`] = ` +
+ +
+`; + exports[`locales renders zh_CN correctly 1`] = `
Date: Sun, 30 Sep 2018 14:57:16 +0800 Subject: [PATCH 002/114] Bump 9.7.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 69f259078..50477beb5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.7.8", + "version": "9.7.9", "description": "React Calendar", "keywords": [ "react", From 8bb932749958ffa9310a2b47facba4bb227a0bcd Mon Sep 17 00:00:00 2001 From: vittoboa <38300176+vittoboa@users.noreply.github.com> Date: Tue, 9 Oct 2018 14:23:24 +0000 Subject: [PATCH 003/114] Fix wrong/odd italian translation (#421) * Fix wrong/odd italian translation * Update tests for italian translation --- src/locale/it_IT.js | 14 +++++++------- tests/__snapshots__/locale.spec.js.snap | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/locale/it_IT.js b/src/locale/it_IT.js index a6991c335..73accd357 100644 --- a/src/locale/it_IT.js +++ b/src/locale/it_IT.js @@ -1,16 +1,16 @@ export default { today: 'Oggi', - now: 'adesso', + now: 'Adesso', backToToday: 'Torna ad oggi', ok: 'Ok', - clear: 'Chiaro', + clear: 'Cancella', month: 'Mese', year: 'Anno', - timeSelect: 'Seleziona il tempo', - dateSelect: 'Select date', - monthSelect: 'Seleziona la data', - yearSelect: 'Scegli un anno', - decadeSelect: 'Scegli un decennio', + timeSelect: 'Seleziona l\'ora', + dateSelect: 'Seleziona la data', + monthSelect: 'Seleziona il mese', + yearSelect: 'Seleziona l\'anno', + decadeSelect: 'Seleziona il decennio', yearFormat: 'YYYY', dateFormat: 'D/M/YYYY', dayFormat: 'D', diff --git a/tests/__snapshots__/locale.spec.js.snap b/tests/__snapshots__/locale.spec.js.snap index d43e39205..17bbf647f 100644 --- a/tests/__snapshots__/locale.spec.js.snap +++ b/tests/__snapshots__/locale.spec.js.snap @@ -13077,7 +13077,7 @@ exports[`locales renders it_IT correctly 1`] = `
Mar 2017 From 5d990198b622d6d7dad3bb794c6022dba247b230 Mon Sep 17 00:00:00 2001 From: zombiej Date: Tue, 9 Oct 2018 22:24:21 +0800 Subject: [PATCH 004/114] Bump 9.7.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 50477beb5..382117c2d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.7.9", + "version": "9.7.10", "description": "React Calendar", "keywords": [ "react", From 480dcdecd460a568fadb6cfaf8957fa74b4a3143 Mon Sep 17 00:00:00 2001 From: Francesco Fortunati Date: Fri, 12 Oct 2018 17:12:36 +0200 Subject: [PATCH 005/114] Fix #404 (#424) * fix(#404): missing onOk documentation * fix(#404): missing onOk documentation for rangeCalendar --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 8febbe8b1..9efd31191 100644 --- a/README.md +++ b/README.md @@ -218,6 +218,12 @@ http://react-component.github.io/calendar/examples/index.html called when a date is changed inside calendar (next year/next month/keyboard) + + onOk + Function(date: moment) + + called when ok button is pressed, only if it's visible + dateInputPlaceholder String @@ -372,6 +378,12 @@ http://react-component.github.io/calendar/examples/index.html called when a date range is changed inside calendar (next year/next month/keyboard) + + onOk + Function(date: moment) + + called when ok button is pressed, only if it's visible + dateInputPlaceholder String[] From c962428723fd553debc9805e68358928e2db80b2 Mon Sep 17 00:00:00 2001 From: zombiej Date: Thu, 1 Nov 2018 00:19:37 +0800 Subject: [PATCH 006/114] When OK button is not display, check can be escaped fix ant-design/ant-design#12889 --- src/Calendar.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index cd4da4563..ad52050da 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -289,7 +289,7 @@ const Calendar = createReactClass({ selectedValue={selectedValue} value={value} disabledDate={disabledDate} - okDisabled={!this.isAllowedDate(selectedValue)} + okDisabled={props.showOk && !this.isAllowedDate(selectedValue)} onOk={this.onOk} onSelect={this.onSelect} onToday={this.onToday} From c92cf5789b8657013ba8cd6c5beed6898751dfc4 Mon Sep 17 00:00:00 2001 From: zombiej Date: Thu, 1 Nov 2018 00:20:05 +0800 Subject: [PATCH 007/114] bump 9.7.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 382117c2d..eb5d63335 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.7.10", + "version": "9.7.11", "description": "React Calendar", "keywords": [ "react", From c99075d06405bf60226dc8028d11d8e16a97908b Mon Sep 17 00:00:00 2001 From: Yann Normand Date: Fri, 30 Nov 2018 16:17:58 +1000 Subject: [PATCH 008/114] add multi format support to DateInput (#437) ref: ant-design/ant-design#13148 --- .gitignore | 3 ++- README.md | 5 +++-- examples/antd-calendar.js | 46 ++++++++++++++++++++++++++++++++++++--- src/date/DateInput.js | 29 +++++++++++++++++++----- src/util/index.js | 12 ++++++++++ tests/Calendar.spec.jsx | 46 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 129 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 04f78bff4..9146790c8 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,5 @@ lib es coverage yarn.lock -.vscode \ No newline at end of file +.vscode +package-lock.json \ No newline at end of file diff --git a/README.md b/README.md index 9efd31191..db464fedb 100644 --- a/README.md +++ b/README.md @@ -154,9 +154,10 @@ http://react-component.github.io/calendar/examples/index.html format - String + String | String[] depends on whether you set timePicker and your locale - use to format/parse date(without time) value to/from input + use to format/parse date(without time) value to/from input. + When an array is provided, all values are used for parsing and first value for display. disabledDate diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index 6e9172694..6f8bc8d6c 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -112,7 +112,7 @@ class Demo extends React.Component { locale={cn ? zhCN : enUS} style={{ zIndex: 1000 }} dateInputPlaceholder="please input" - formatter={getFormat(state.showTime)} + format={getFormat(state.showTime)} disabledTime={state.showTime ? disabledTime : null} timePicker={state.showTime ? timePickerElement : null} defaultValue={this.props.defaultCalendarValue} @@ -158,7 +158,6 @@ class Demo extends React.Component { > { + console.log('Calendar change: ', (value && value.format(format))); + this.setState({ + value, + }); + } + + render() { + const state = this.state; + return (
+
+ Accepts multiple input formats +
+ {multiFormats.join(', ')} +
+ +
); + } +} + function onStandaloneSelect(value) { console.log('onStandaloneSelect'); console.log(value && value.format(format)); @@ -213,7 +250,7 @@ ReactDOM.render((
+
+ +
), document.getElementById('__react-content')); diff --git a/src/date/DateInput.js b/src/date/DateInput.js index 09898cbc7..1ad4ce136 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom'; import createReactClass from 'create-react-class'; import PropTypes from 'prop-types'; import moment from 'moment'; +import { formatDate } from '../util'; const DateInput = createReactClass({ propTypes: { @@ -10,7 +11,7 @@ const DateInput = createReactClass({ timePicker: PropTypes.object, value: PropTypes.object, disabledTime: PropTypes.any, - format: PropTypes.string, + format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), locale: PropTypes.object, disabledDate: PropTypes.func, onChange: PropTypes.func, @@ -24,8 +25,9 @@ const DateInput = createReactClass({ getInitialState() { const selectedValue = this.props.selectedValue; return { - str: selectedValue && selectedValue.format(this.props.format) || '', + str: formatDate(selectedValue, this.props.format), invalid: false, + hasFocus: false, }; }, @@ -34,10 +36,12 @@ const DateInput = createReactClass({ this.cachedSelectionEnd = this.dateInputInstance.selectionEnd; // when popup show, click body will call this, bug! const selectedValue = nextProps.selectedValue; - this.setState({ - str: selectedValue && selectedValue.format(nextProps.format) || '', - invalid: false, - }); + if (!this.state.hasFocus) { + this.setState({ + str: formatDate(selectedValue, nextProps.format), + invalid: false, + }); + } }, componentDidUpdate() { @@ -115,6 +119,17 @@ const DateInput = createReactClass({ this.dateInputInstance = dateInput; }, + onFocus() { + this.setState({ hasFocus: true }); + }, + + onBlur() { + this.setState((prevState, prevProps) => ({ + hasFocus: false, + str: formatDate(prevProps.value, prevProps.format), + })); + }, + render() { const props = this.props; const { invalid, str } = this.state; @@ -130,6 +145,8 @@ const DateInput = createReactClass({ disabled={props.disabled} placeholder={placeholder} onChange={this.onInputChange} + onFocus={this.onFocus} + onBlur={this.onBlur} /> {props.showClear ? ( diff --git a/src/util/index.js b/src/util/index.js index d3e5db37a..260f3ba86 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -89,3 +89,15 @@ export function isAllowedDate(value, disabledDate, disabledTime) { } return true; } + +export function formatDate(value, format) { + if (!value) { + return ''; + } + + if (Array.isArray(format)) { + format = format[0]; + } + + return value.format(format); +} diff --git a/tests/Calendar.spec.jsx b/tests/Calendar.spec.jsx index 648e1e066..89ee03fdf 100644 --- a/tests/Calendar.spec.jsx +++ b/tests/Calendar.spec.jsx @@ -494,6 +494,52 @@ describe('Calendar', () => { expect(onSelect.mock.calls[0][0].format(format)).toBe(expected); expect(onChange.mock.calls[0][0].format(format)).toBe(expected); }); + + it('supports an array of formats when parsing and formats using the first format', () => { + const expected = '21/01/2017'; + const value = '21/01/17'; + + const onSelect = jest.fn(); + const onChange = jest.fn(); + + const calendar = mount(); + const input = calendar.find('.rc-calendar-input').hostNodes().at(0); + input.simulate('change', { target: { value } }); + + expect(onSelect.mock.calls[0][0].format('DD/MM/YYYY')).toBe(expected); + expect(onChange.mock.calls[0][0].format('DD/MM/YYYY')).toBe(expected); + }); + + it('only reformat the date when the input loses focus', () => { + const value = '21/01/17'; + + const onSelect = jest.fn(); + const onChange = jest.fn(); + + const calendar = mount(); + + const input = calendar.find('.rc-calendar-input').hostNodes().at(0); + input.simulate('focus'); + input.simulate('change', { target: { value } }); + + let inputValue = calendar.find('.rc-calendar-input').props().value; + expect(inputValue).toBe('21/01/17'); + + input.simulate('blur'); + + inputValue = calendar.find('.rc-calendar-input').props().value; + expect(inputValue).toBe('21/01/2017'); + }); }); it('handle clear', () => { From 717b66da0b7dd55730f58b43047fc1f707d1586e Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 30 Nov 2018 14:19:20 +0800 Subject: [PATCH 009/114] bump 9.8.0 --- HISTORY.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 6ac5a72ae..9ac9ba2aa 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,10 @@ # History ---- +## 9.8.0 / 2018-11-30 + +- DateInput support multiple date format + ## 9.7.0 / 2018-08-07 - Add clearIcon. diff --git a/package.json b/package.json index eb5d63335..dfa0e8a80 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.7.11", + "version": "9.8.0", "description": "React Calendar", "keywords": [ "react", From 3ed6add2a42a296d611b891be3dc0c11d6608224 Mon Sep 17 00:00:00 2001 From: afc163 Date: Thu, 6 Dec 2018 12:25:29 +0800 Subject: [PATCH 010/114] :bug: Fix infinite loop in safari close ant-design/ant-design#13424 and ant-design/ant-design#7443 is still not resolved --- src/date/DateInput.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/date/DateInput.js b/src/date/DateInput.js index 1ad4ce136..2b93e4159 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -45,7 +45,7 @@ const DateInput = createReactClass({ }, componentDidUpdate() { - if (!this.state.invalid && + if (this.state.hasFocus && !this.state.invalid && !(this.cachedSelectionStart === 0 && this.cachedSelectionEnd === 0)) { this.dateInputInstance.setSelectionRange(this.cachedSelectionStart, this.cachedSelectionEnd); } From ef3dc991bd9252c7d0e17112143d0701e0eef538 Mon Sep 17 00:00:00 2001 From: afc163 Date: Thu, 6 Dec 2018 12:27:01 +0800 Subject: [PATCH 011/114] 9.8.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dfa0e8a80..1fb175be7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.8.0", + "version": "9.8.1", "description": "React Calendar", "keywords": [ "react", From edd622ac521dfee8b291b8bc7fe567d812252f9a Mon Sep 17 00:00:00 2001 From: afc163 Date: Thu, 6 Dec 2018 17:08:01 +0800 Subject: [PATCH 012/114] refactor code --- src/date/DateInput.js | 80 +++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/src/date/DateInput.js b/src/date/DateInput.js index 2b93e4159..75d1e79ab 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -53,49 +53,47 @@ const DateInput = createReactClass({ onInputChange(event) { const str = event.target.value; - this.setState({ - str, - }); - let value; - const { disabledDate, format, onChange } = this.props; - if (str) { - const parsed = moment(str, format, true); - if (!parsed.isValid()) { - this.setState({ - invalid: true, - }); - return; - } - value = this.props.value.clone(); - value - .year(parsed.year()) - .month(parsed.month()) - .date(parsed.date()) - .hour(parsed.hour()) - .minute(parsed.minute()) - .second(parsed.second()); - - if (value && (!disabledDate || !disabledDate(value))) { - const originalValue = this.props.selectedValue; - if (originalValue && value) { - if (!originalValue.isSame(value)) { - onChange(value); - } - } else if (originalValue !== value) { - onChange(value); - } - } else { - this.setState({ - invalid: true, - }); - return; - } - } else { + const { disabledDate, format, onChange, selectedValue } = this.props; + + // 没有内容,合法并直接退出 + if (!str) { onChange(null); + this.setState({ + invalid: false, + }); + return; + } + + // 不合法直接退出 + const parsed = moment(str, format, true); + if (!parsed.isValid()) { + this.setState({ + invalid: true, + }); + return; + } + + const value = this.props.value.clone(); + value + .year(parsed.year()) + .month(parsed.month()) + .date(parsed.date()) + .hour(parsed.hour()) + .minute(parsed.minute()) + .second(parsed.second()); + + if (!value || (disabledDate && disabledDate(value))) { + this.setState({ + invalid: true, + }); + return; + } + + if (selectedValue !== value || ( + selectedValue && value && !selectedValue.isSame(value) + )) { + onChange(value); } - this.setState({ - invalid: false, - }); }, onClear() { From 74ac88ed936b7bdf2b54d3f571d7147568d570d8 Mon Sep 17 00:00:00 2001 From: afc163 Date: Thu, 6 Dec 2018 17:28:49 +0800 Subject: [PATCH 013/114] fix test case --- src/date/DateInput.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/date/DateInput.js b/src/date/DateInput.js index 75d1e79ab..ed6a1aabf 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -60,6 +60,7 @@ const DateInput = createReactClass({ onChange(null); this.setState({ invalid: false, + str, }); return; } @@ -69,6 +70,7 @@ const DateInput = createReactClass({ if (!parsed.isValid()) { this.setState({ invalid: true, + str, }); return; } @@ -85,6 +87,7 @@ const DateInput = createReactClass({ if (!value || (disabledDate && disabledDate(value))) { this.setState({ invalid: true, + str, }); return; } @@ -92,6 +95,9 @@ const DateInput = createReactClass({ if (selectedValue !== value || ( selectedValue && value && !selectedValue.isSame(value) )) { + this.setState({ + str, + }); onChange(value); } }, From e4d3c594bf7d443a3ef25e3487b0aeb0888ba540 Mon Sep 17 00:00:00 2001 From: afc163 Date: Fri, 7 Dec 2018 12:30:52 +0800 Subject: [PATCH 014/114] code style --- src/Picker.jsx | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Picker.jsx b/src/Picker.jsx index 2d8a7df51..22c24c5c1 100644 --- a/src/Picker.jsx +++ b/src/Picker.jsx @@ -197,24 +197,26 @@ const Picker = createReactClass({ transitionName, children, } = props; const state = this.state; - return ( - {React.cloneElement(children(state, props), { onKeyDown: this.onKeyDown })} - ); + return ( + + {React.cloneElement(children(state, props), { onKeyDown: this.onKeyDown })} + + ); }, }); From 37d654ba5304c33803958be9f80852950f484773 Mon Sep 17 00:00:00 2001 From: zombiej Date: Mon, 17 Dec 2018 23:52:26 +0800 Subject: [PATCH 015/114] ok button should not clickable when not selected value provided fix ant-design/ant-design#13201 --- src/Calendar.jsx | 4 +++- tests/Calendar.spec.jsx | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index ad52050da..24a0b97f7 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -289,7 +289,9 @@ const Calendar = createReactClass({ selectedValue={selectedValue} value={value} disabledDate={disabledDate} - okDisabled={props.showOk && !this.isAllowedDate(selectedValue)} + okDisabled={ + props.showOk !== false && (!selectedValue || !this.isAllowedDate(selectedValue)) + } onOk={this.onOk} onSelect={this.onSelect} onToday={this.onToday} diff --git a/tests/Calendar.spec.jsx b/tests/Calendar.spec.jsx index 89ee03fdf..839b340c0 100644 --- a/tests/Calendar.spec.jsx +++ b/tests/Calendar.spec.jsx @@ -563,6 +563,16 @@ describe('Calendar', () => { expect(handleOk).toHaveBeenCalledWith(selected); }); + it('Ok Button disabled', () => { + const calendar = mount( + + ); + + expect( + calendar.find('OkButton').props().okDisabled + ).toBe(true); + }); + it('does not triggers onOk if selected date is disabled', () => { const selected = moment().add(1, 'day'); const handleOk = jest.fn(); From 68612bff4730c545672856f4706bec2d84ed8808 Mon Sep 17 00:00:00 2001 From: zombiej Date: Mon, 17 Dec 2018 23:55:00 +0800 Subject: [PATCH 016/114] bump 9.8.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1fb175be7..c869b2c0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.8.1", + "version": "9.8.2", "description": "React Calendar", "keywords": [ "react", From 456152adadca4679458eabbe5c8845d752a69633 Mon Sep 17 00:00:00 2001 From: Harlan Date: Mon, 24 Dec 2018 13:34:23 +0800 Subject: [PATCH 017/114] show extra footer in all mode (#460) --- README.md | 2 +- assets/index/DecadePanel.less | 11 ++++++++--- assets/index/MonthPanel.less | 15 ++++++++++++--- assets/index/YearPanel.less | 15 ++++++++++++--- examples/antd-calendar.js | 2 +- src/Calendar.jsx | 4 +++- src/calendar/CalendarFooter.jsx | 5 +++-- src/calendar/CalendarHeader.jsx | 5 +++++ src/decade/DecadePanel.jsx | 10 +++++++++- src/month/MonthPanel.jsx | 11 ++++++++--- src/year/YearPanel.jsx | 9 ++++++++- tests/Calendar.spec.jsx | 32 ++++++++++++++++++++++++++++++++ 12 files changed, 102 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index db464fedb..642e32779 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ http://react-component.github.io/calendar/examples/index.html renderFooter - () => React.Node + (mode) => React.Node extra footer diff --git a/assets/index/DecadePanel.less b/assets/index/DecadePanel.less index 97ac157ce..f83c591d0 100644 --- a/assets/index/DecadePanel.less +++ b/assets/index/DecadePanel.less @@ -7,6 +7,8 @@ z-index: 10; position: absolute; outline: none; + display: flex; + flex-direction: column; } .@{prefixClass}-decade-panel-hidden { @@ -62,10 +64,13 @@ } .@{prefixClass}-decade-panel-body { + flex: 1; padding: 9px 10px 10px; - position: absolute; - bottom: 0; - top: 34px; +} + +.@{prefixClass}-decade-panel-footer { + border-top: 1px solid #ccc; + line-height: 38px; } .@{prefixClass}-decade-panel-table { diff --git a/assets/index/MonthPanel.less b/assets/index/MonthPanel.less index b65f4666a..1b35f0e6b 100644 --- a/assets/index/MonthPanel.less +++ b/assets/index/MonthPanel.less @@ -7,6 +7,12 @@ z-index: 10; position: absolute; outline: none; + + > div { + height: 100%; + display: flex; + flex-direction: column; + } } .@{prefixClass}-month-panel-hidden { @@ -71,10 +77,13 @@ } .@{prefixClass}-month-panel-body { + flex: 1; padding: 9px 10px 10px; - position: absolute; - top: 34px; - bottom: 0; +} + +.@{prefixClass}-month-panel-footer { + border-top: 1px solid #ccc; + line-height: 38px; } .@{prefixClass}-month-panel-table { diff --git a/assets/index/YearPanel.less b/assets/index/YearPanel.less index f629d2e9f..6b31dc8ec 100644 --- a/assets/index/YearPanel.less +++ b/assets/index/YearPanel.less @@ -7,6 +7,12 @@ z-index: 10; position: absolute; outline: none; + + > div { + height: 100%; + display: flex; + flex-direction: column; + } } .@{prefixClass}-year-panel-hidden { @@ -71,10 +77,13 @@ } .@{prefixClass}-year-panel-body { + flex: 1; padding: 9px 10px 10px; - position: absolute; - bottom: 0; - top: 34px; +} + +.@{prefixClass}-year-panel-footer { + border-top: 1px solid #ccc; + line-height: 38px; } .@{prefixClass}-year-panel-table { diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index 6f8bc8d6c..703785734 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -256,7 +256,7 @@ ReactDOM.render((
'extra footer'} + renderFooter={(mode) => ({mode} extra footer)} />
diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 24a0b97f7..0f3a77b49 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -197,7 +197,7 @@ const Calendar = createReactClass({ const { locale, prefixCls, disabledDate, dateInputPlaceholder, timePicker, - disabledTime, clearIcon, + disabledTime, clearIcon, renderFooter, } = props; const { value, selectedValue, mode } = state; const showTimePicker = mode === 'time'; @@ -253,6 +253,7 @@ const Calendar = createReactClass({ value={value} onValueChange={this.setValue} onPanelChange={this.onPanelChange} + renderFooter={renderFooter} showTimePicker={showTimePicker} prefixCls={prefixCls} /> @@ -278,6 +279,7 @@ const Calendar = createReactClass({ ); } @@ -168,6 +171,7 @@ const CalendarHeader = createReactClass({ rootPrefixCls={prefixCls} onSelect={this.onYearSelect} onDecadePanelShow={this.showDecadePanel} + renderFooter={renderFooter} /> ); } @@ -178,6 +182,7 @@ const CalendarHeader = createReactClass({ defaultValue={value} rootPrefixCls={prefixCls} onSelect={this.onDecadeSelect} + renderFooter={renderFooter} /> ); } diff --git a/src/decade/DecadePanel.jsx b/src/decade/DecadePanel.jsx index c70dfce64..03c672ef4 100644 --- a/src/decade/DecadePanel.jsx +++ b/src/decade/DecadePanel.jsx @@ -36,7 +36,7 @@ export default render() { const value = this.state.value; - const { locale } = this.props; + const { locale, renderFooter } = this.props; const currentYear = value.year(); const startYear = parseInt(currentYear / 100, 10) * 100; const preYear = startYear - 10; @@ -58,6 +58,8 @@ export default } } + const footer = renderFooter && renderFooter('decade'); + const decadesEls = decades.map((row, decadeIndex) => { const tds = row.map(decadeData => { const dStartDecade = decadeData.startDecade; @@ -122,6 +124,11 @@ export default
+ + {footer && ( +
+ {footer} +
)} ); } } @@ -131,6 +138,7 @@ DecadePanel.propTypes = { value: PropTypes.object, defaultValue: PropTypes.object, rootPrefixCls: PropTypes.string, + renderFooter: PropTypes.func, }; DecadePanel.defaultProps = { diff --git a/src/month/MonthPanel.jsx b/src/month/MonthPanel.jsx index 295d24cd6..8df402d98 100644 --- a/src/month/MonthPanel.jsx +++ b/src/month/MonthPanel.jsx @@ -18,6 +18,7 @@ const MonthPanel = createReactClass({ onChange: PropTypes.func, disabledDate: PropTypes.func, onSelect: PropTypes.func, + renderFooter: PropTypes.func, }, getDefaultProps() { @@ -67,12 +68,12 @@ const MonthPanel = createReactClass({ render() { const props = this.props; const value = this.state.value; - const cellRender = props.cellRender; - const contentRender = props.contentRender; - const { locale } = props; + const { locale, cellRender, contentRender, renderFooter } = props; const year = value.year(); const prefixCls = this.prefixCls; + const footer = renderFooter && renderFooter('month'); + return (
@@ -112,6 +113,10 @@ const MonthPanel = createReactClass({ prefixCls={prefixCls} />
+ {footer && ( +
+ {footer} +
)}
); }, diff --git a/src/year/YearPanel.jsx b/src/year/YearPanel.jsx index 0dc049356..ea2b46837 100644 --- a/src/year/YearPanel.jsx +++ b/src/year/YearPanel.jsx @@ -56,7 +56,7 @@ export default render() { const props = this.props; const value = this.state.value; - const { locale } = props; + const { locale, renderFooter } = props; const years = this.years(); const currentYear = value.year(); const startYear = parseInt(currentYear / 10, 10) * 10; @@ -97,6 +97,7 @@ export default return ({tds}); }); + const footer = renderFooter && renderFooter('year'); return (
@@ -134,6 +135,11 @@ export default
+ + {footer && ( +
+ {footer} +
)} ); } @@ -143,6 +149,7 @@ YearPanel.propTypes = { rootPrefixCls: PropTypes.string, value: PropTypes.object, defaultValue: PropTypes.object, + renderFooter: PropTypes.func, }; YearPanel.defaultProps = { diff --git a/tests/Calendar.spec.jsx b/tests/Calendar.spec.jsx index 839b340c0..89a65eedc 100644 --- a/tests/Calendar.spec.jsx +++ b/tests/Calendar.spec.jsx @@ -472,6 +472,38 @@ describe('Calendar', () => { expect(calendar.find('.rc-calendar-decade-panel').hostNodes().length).toBe(1); expect(calendar.find('.rc-calendar-decade-panel-decade').hostNodes().length).toBe(12); }); + + it('extra footer works', () => { + const renderFooter = (mode) => ({mode}); + + calendar = mount( + + ); + + let extraNode = calendar.find('.extra-node'); + expect(extraNode.length).toBe(1); + expect(extraNode.text()).toBe('date'); + + calendar.find('.rc-calendar-month-select').hostNodes().simulate('click'); + extraNode = calendar.find('.rc-calendar-month-panel .extra-node'); + expect(extraNode.length).toBe(1); + expect(extraNode.text()).toBe('month'); + + calendar.find('.rc-calendar-year-select').hostNodes().simulate('click'); + extraNode = calendar.find('.rc-calendar-year-panel .extra-node'); + expect(extraNode.length).toBe(1); + expect(extraNode.text()).toBe('year'); + + calendar.find('.rc-calendar-year-panel-decade-select').hostNodes().simulate('click'); + extraNode = calendar.find('.rc-calendar-decade-panel .extra-node'); + expect(extraNode.length).toBe(1); + expect(extraNode.text()).toBe('decade'); + }); }); From 974053b07d3cbd5c0f8b5b225aed5a773d4c2889 Mon Sep 17 00:00:00 2001 From: afc163 Date: Mon, 24 Dec 2018 13:35:39 +0800 Subject: [PATCH 018/114] 9.9.0 :tada: --- HISTORY.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 9ac9ba2aa..c4c72dddc 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,10 @@ # History ---- +## 9.9.0 / 2018-12-23 + +- `renderFooter(mode)` support all modes. + ## 9.8.0 / 2018-11-30 - DateInput support multiple date format diff --git a/package.json b/package.json index c869b2c0a..a3f91b0b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.8.2", + "version": "9.9.0", "description": "React Calendar", "keywords": [ "react", From 53e3fe47c593d5b0982dd050e652c3f04e26355b Mon Sep 17 00:00:00 2001 From: Early Date: Mon, 24 Dec 2018 16:11:09 +0800 Subject: [PATCH 019/114] feat:add custom sperator (#461) --- src/RangeCalendar.js | 6 ++++-- tests/RangeCalendar.spec.jsx | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index 0cdd57d45..1307e9435 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -76,6 +76,7 @@ const RangeCalendar = createReactClass({ propTypes: { prefixCls: PropTypes.string, dateInputPlaceholder: PropTypes.any, + seperator: PropTypes.string, defaultValue: PropTypes.any, value: PropTypes.any, hoverValue: PropTypes.any, @@ -107,6 +108,7 @@ const RangeCalendar = createReactClass({ getDefaultProps() { return { type: 'both', + seperator: '~', defaultSelectedValue: [], onValueChange: noop, onHoverChange: noop, @@ -593,7 +595,7 @@ const RangeCalendar = createReactClass({ render() { const { props, state } = this; const { - prefixCls, dateInputPlaceholder, + prefixCls, dateInputPlaceholder, seperator, timePicker, showOk, locale, showClear, showToday, type, clearIcon, } = props; @@ -699,7 +701,7 @@ const RangeCalendar = createReactClass({ enableNext={!isClosestMonths || this.isMonthYearPanelShow(mode[1])} clearIcon={clearIcon} /> - ~ + {seperator} { expect(wrapper.find('.rc-calendar-cell').length).toBeGreaterThan(0); }); + it('default sperator', () => { + const wrapper = render(); + expect(wrapper.find('.rc-calendar-range-middle').text()).toBe('~'); + }); + + it('custom sperator', () => { + const wrapper = render(); + expect(wrapper.find('.rc-calendar-range-middle').text()).toBe('至'); + }); + it('render hoverValue correctly', () => { const wrapper = render(); expect(wrapper).toMatchSnapshot(); From 9537ba73c09a428a39c06fbda46e70dff9d4cc4f Mon Sep 17 00:00:00 2001 From: afc163 Date: Mon, 24 Dec 2018 16:12:03 +0800 Subject: [PATCH 020/114] 9.9.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a3f91b0b2..8563a302a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.9.0", + "version": "9.9.1", "description": "React Calendar", "keywords": [ "react", From 3998c5f4f497276aad9706080b60370924bd7798 Mon Sep 17 00:00:00 2001 From: Aashutosh Rathi Date: Wed, 26 Dec 2018 20:06:03 +0530 Subject: [PATCH 021/114] Add Hindi Locale (#466) --- src/locale/hi_IN.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/locale/hi_IN.js diff --git a/src/locale/hi_IN.js b/src/locale/hi_IN.js new file mode 100644 index 000000000..a0b6b4e63 --- /dev/null +++ b/src/locale/hi_IN.js @@ -0,0 +1,28 @@ +export default { + today: 'आज', + now: 'अभी', + backToToday: 'आज तक', + ok: 'ठीक', + clear: 'स्पष्ट', + month: 'महीना', + year: 'साल', + timeSelect: 'समय का चयन करें', + dateSelect: 'तारीख़ चुनें', + weekSelect: 'एक सप्ताह चुनें', + monthSelect: 'एक महीना चुनें', + yearSelect: 'एक वर्ष चुनें', + decadeSelect: 'एक दशक चुनें', + yearFormat: 'YYYY', + dateFormat: 'M/D/YYYY', + dayFormat: 'D', + dateTimeFormat: 'M/D/YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'पिछला महीना (पेजअप)', + nextMonth: 'अगले महीने (पेजडाउन)', + previousYear: 'पिछले साल (Ctrl + बाएं)', + nextYear: 'अगले साल (Ctrl + दाहिना)', + previousDecade: 'पिछला दशक', + nextDecade: 'अगले दशक', + previousCentury: 'पीछ्ली शताब्दी', + nextCentury: 'अगली सदी', +}; From 37134184f09d636587acecef05f794557f31967f Mon Sep 17 00:00:00 2001 From: Rahul Gurung Date: Wed, 26 Dec 2018 21:01:58 +0530 Subject: [PATCH 022/114] #13576 - added Kannada locale (#467) --- src/locale/kn_IN.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/locale/kn_IN.js diff --git a/src/locale/kn_IN.js b/src/locale/kn_IN.js new file mode 100644 index 000000000..5acf5d698 --- /dev/null +++ b/src/locale/kn_IN.js @@ -0,0 +1,28 @@ +export default { + today: 'ಇಂದು', + now: 'ಈಗ', + backToToday: 'ಇಂದು ಹಿಂದಿರುಗಿ', + ok: 'ಸರಿ', + clear: 'ಸ್ಪಷ್ಟ', + month: 'ತಿಂಗಳು', + year: 'ವರ್ಷ', + timeSelect: 'ಸಮಯ ಆಯ್ಕೆಮಾಡಿ', + dateSelect: 'ದಿನಾಂಕವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ', + weekSelect: 'ಒಂದು ವಾರದ ಆರಿಸಿ', + monthSelect: 'ಒಂದು ತಿಂಗಳು ಆಯ್ಕೆಮಾಡಿ', + yearSelect: 'ಒಂದು ವರ್ಷ ಆರಿಸಿ', + decadeSelect: 'ಒಂದು ದಶಕದ ಆಯ್ಕೆಮಾಡಿ', + yearFormat: 'YYYY', + dateFormat: 'M/D/YYYY', + dayFormat: 'D', + dateTimeFormat: 'M/D/YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'ಹಿಂದಿನ ತಿಂಗಳು (ಪೇಜ್ಅಪ್)', + nextMonth: 'ಮುಂದಿನ ತಿಂಗಳು (ಪೇಜ್ಡೌನ್)', + previousYear: 'ಕಳೆದ ವರ್ಷ (Ctrl + ಎಡ)', + nextYear: 'ಮುಂದಿನ ವರ್ಷ (Ctrl + ಬಲ)', + previousDecade: 'ಕಳೆದ ದಶಕ', + nextDecade: 'ಮುಂದಿನ ದಶಕ', + previousCentury: 'ಕಳೆದ ಶತಮಾನ', + nextCentury: 'ಮುಂದಿನ ಶತಮಾನ', +}; From c3310b3cca0332c5620c3d0a9877a43b0b83299f Mon Sep 17 00:00:00 2001 From: afc163 Date: Wed, 26 Dec 2018 23:41:37 +0800 Subject: [PATCH 023/114] :tada: 9.9.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8563a302a..d63d309e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.9.1", + "version": "9.9.2", "description": "React Calendar", "keywords": [ "react", From 4bf06ae64fa88130ee5c92ccd489b958d161f212 Mon Sep 17 00:00:00 2001 From: orzorzorzorz Date: Sun, 30 Dec 2018 01:09:49 +0800 Subject: [PATCH 024/114] Remove createClass and migrate to new lifecycle methods (#470) * refactor: remove createClass and migrate to new lifecycle methods * pref: fix lint problems * pref: fix lint problems * pref: fix lint problems --- package.json | 8 +- src/Calendar.jsx | 252 +++++++++++++++++------------ src/FullCalendar.jsx | 106 +++++++----- src/MonthCalendar.jsx | 52 ++++-- src/Picker.jsx | 127 ++++++++------- src/RangeCalendar.js | 216 ++++++++++++------------- src/calendar/CalendarFooter.jsx | 19 +-- src/calendar/CalendarHeader.jsx | 69 ++++---- src/date/DateInput.js | 119 +++++++------- src/date/DateTBody.jsx | 21 +-- src/date/DateTHead.jsx | 3 +- src/date/DateTable.jsx | 3 +- src/decade/DecadePanel.jsx | 3 +- src/index.js | 3 + src/mixin/CalendarMixin.js | 83 ++++------ src/mixin/CommonMixin.js | 70 ++++---- src/month/MonthPanel.jsx | 61 +++---- src/range-calendar/CalendarPart.js | 14 +- src/year/YearPanel.jsx | 3 +- 19 files changed, 644 insertions(+), 588 deletions(-) diff --git a/package.json b/package.json index d63d309e1..a9ae823a7 100644 --- a/package.json +++ b/package.json @@ -80,8 +80,8 @@ "rc-select": "^7.1.0", "rc-time-picker": "^3.1.0", "rc-tools": "^7.0.3", - "react": "^16.0.0", - "react-dom": "^16.0.0", + "react": "^16.5.2", + "react-dom": "^16.5.2", "react-test-renderer": "^16.0.0", "tslint": "^5.9.1", "typescript": "^2.8.3" @@ -92,11 +92,11 @@ "dependencies": { "babel-runtime": "6.x", "classnames": "2.x", - "create-react-class": "^15.5.2", "moment": "2.x", "prop-types": "^15.5.8", "rc-trigger": "^2.2.0", - "rc-util": "^4.1.1" + "rc-util": "^4.1.1", + "react-lifecycles-compat": "^3.0.4" }, "types": "index.d.ts" } diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 0f3a77b49..e52591a97 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -1,28 +1,36 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import createReactClass from 'create-react-class'; import PropTypes from 'prop-types'; import KeyCode from 'rc-util/lib/KeyCode'; import DateTable from './date/DateTable'; import CalendarHeader from './calendar/CalendarHeader'; import CalendarFooter from './calendar/CalendarFooter'; -import CalendarMixin from './mixin/CalendarMixin'; -import CommonMixin from './mixin/CommonMixin'; +import { + calendarMixinWrapper, + calendarMixinPropTypes, + calendarMixinDefaultProps, + getNowByCurrentStateValue, +} from './mixin/CalendarMixin'; +import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; import DateInput from './date/DateInput'; import { getTimeConfig, getTodayTime, syncTime } from './util'; import { goStartMonth, goEndMonth, goTime } from './util/toTime'; +import moment from 'moment'; function noop() { } -const Calendar = createReactClass({ - propTypes: { +class Calendar extends React.Component { + static propTypes = { + ...calendarMixinPropTypes, + ...propType, prefixCls: PropTypes.string, className: PropTypes.string, style: PropTypes.object, defaultValue: PropTypes.object, value: PropTypes.object, selectedValue: PropTypes.object, + defaultSelectedValue: PropTypes.object, mode: PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade']), locale: PropTypes.object, showDateInput: PropTypes.bool, @@ -43,30 +51,37 @@ const Calendar = createReactClass({ renderFooter: PropTypes.func, renderSidebar: PropTypes.func, clearIcon: PropTypes.node, - }, + } - mixins: [CommonMixin, CalendarMixin], + static defaultProps = { + ...calendarMixinDefaultProps, + ...defaultProp, + showToday: true, + showDateInput: true, + timePicker: null, + onOk: noop, + onPanelChange: noop, + } - getDefaultProps() { - return { - showToday: true, - showDateInput: true, - timePicker: null, - onOk: noop, - onPanelChange: noop, - }; - }, - getInitialState() { - return { + constructor(props) { + super(props); + + this.state = { mode: this.props.mode || 'date', + value: props.value || props.defaultValue || moment(), + selectedValue: props.selectedValue || props.defaultSelectedValue, }; - }, - componentWillReceiveProps(nextProps) { - if ('mode' in nextProps && this.state.mode !== nextProps.mode) { - this.setState({ mode: nextProps.mode }); + } + + onPanelChange = (value, mode) => { + const { props, state } = this; + if (!('mode' in props)) { + this.setState({ mode }); } - }, - onKeyDown(event) { + props.onPanelChange(value || state.value, mode); + } + + onKeyDown = (event) => { if (event.target.nodeName.toLowerCase() === 'input') { return undefined; } @@ -132,26 +147,33 @@ const Calendar = createReactClass({ this.props.onKeyDown(event); return 1; } - }, + } - onClear() { + onClear = () => { this.onSelect(null); this.props.onClear(); - }, + } - onOk() { + onOk = () => { const { selectedValue } = this.state; if (this.isAllowedDate(selectedValue)) { this.props.onOk(selectedValue); } - }, + } - onDateInputChange(value) { + onDateInputChange = (value) => { this.onSelect(value, { source: 'dateInput', }); - }, - onDateTableSelect(value) { + } + + onDateInputChange = (value) => { + this.onSelect(value, { + source: 'dateInput', + }); + } + + onDateTableSelect = (value) => { const { timePicker } = this.props; const { selectedValue } = this.state; if (!selectedValue && timePicker) { @@ -161,36 +183,51 @@ const Calendar = createReactClass({ } } this.onSelect(value); - }, - onToday() { + } + + onToday = () => { const { value } = this.state; const now = getTodayTime(value); this.onSelect(now, { source: 'todayButton', }); - }, - onPanelChange(value, mode) { - const { props, state } = this; - if (!('mode' in props)) { - this.setState({ mode }); + } + + static getDerivedStateFromProps(nextProps, state) { + const { value, selectedValue } = nextProps; + let newState = {}; + + if ('mode' in nextProps && state.mode !== nextProps.mode) { + newState = { mode: nextProps.mode }; } - props.onPanelChange(value || state.value, mode); - }, - getRootDOMNode() { + if ('value' in nextProps) { + newState.value = value || nextProps.defaultValue || getNowByCurrentStateValue(state.value); + } + if ('selectedValue' in nextProps) { + newState.selectedValue = selectedValue; + } + + return newState; + } + + getRootDOMNode = () => { return ReactDOM.findDOMNode(this); - }, - openTimePicker() { + } + + openTimePicker = () => { this.onPanelChange(null, 'time'); - }, - closeTimePicker() { + } + + closeTimePicker = () => { this.onPanelChange(null, 'date'); - }, + } - goTime(direction, unit) { + + goTime = (direction, unit) => { this.setValue( goTime(this.state.value, direction, unit), ); - }, + } render() { const { props, state } = this; @@ -242,73 +279,74 @@ const Calendar = createReactClass({ clearIcon={clearIcon} /> ) : null; - const children = [ - props.renderSidebar(), - (
- {dateInputElement} -
- + {dateInputElement} +
+ + {timePicker && showTimePicker ? + (
+
+ {timePickerEle} +
+
) + : null} +
+ - {timePicker && showTimePicker ? - (
-
- {timePickerEle} -
-
) - : null} -
- -
- -
-
), - ]; + + +
+
); return this.renderRoot({ children, className: props.showWeekNumber ? `${prefixCls}-week-number` : '', }); - }, -}); + } +} -export default Calendar; +export default calendarMixinWrapper(commonMixinWrapper(Calendar)); diff --git a/src/FullCalendar.jsx b/src/FullCalendar.jsx index 141a590de..47a7fd573 100644 --- a/src/FullCalendar.jsx +++ b/src/FullCalendar.jsx @@ -1,14 +1,21 @@ import React from 'react'; -import createReactClass from 'create-react-class'; import PropTypes from 'prop-types'; import DateTable from './date/DateTable'; import MonthTable from './month/MonthTable'; -import CalendarMixin from './mixin/CalendarMixin'; -import CommonMixin from './mixin/CommonMixin'; +import { + calendarMixinWrapper, + calendarMixinPropTypes, + calendarMixinDefaultProps, + getNowByCurrentStateValue, +} from './mixin/CalendarMixin'; +import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; import CalendarHeader from './full-calendar/CalendarHeader'; +import moment from 'moment'; -const FullCalendar = createReactClass({ - propTypes: { +class FullCalendar extends React.Component { + static propTypes = { + ...calendarMixinPropTypes, + ...propType, defaultType: PropTypes.string, type: PropTypes.string, prefixCls: PropTypes.string, @@ -24,49 +31,74 @@ const FullCalendar = createReactClass({ headerRender: PropTypes.func, showHeader: PropTypes.bool, disabledDate: PropTypes.func, - }, - mixins: [CommonMixin, CalendarMixin], - getDefaultProps() { - return { - defaultType: 'date', - fullscreen: false, - showTypeSwitch: true, - showHeader: true, - onTypeChange() { - }, - }; - }, - getInitialState() { + value: PropTypes.object, + defaultValue: PropTypes.object, + selectedValue: PropTypes.object, + defaultSelectedValue: PropTypes.object, + } + + static defaultProps = { + ...calendarMixinDefaultProps, + ...defaultProp, + defaultType: 'date', + fullscreen: false, + showTypeSwitch: true, + showHeader: true, + onTypeChange() { + }, + } + + constructor(props) { + super(props); + let type; - if ('type' in this.props) { - type = this.props.type; + if ('type' in props) { + type = props.type; } else { - type = this.props.defaultType; + type = props.defaultType; } - return { + + this.state = { type, + value: props.value || props.defaultValue || moment(), + selectedValue: props.selectedValue || props.defaultSelectedValue, }; - }, - componentWillReceiveProps(nextProps) { - if ('type' in nextProps) { - this.setState({ - type: nextProps.type, - }); - } - }, - onMonthSelect(value) { + } + + onMonthSelect = (value) => { this.onSelect(value, { target: 'month', }); - }, - setType(type) { + } + + static getDerivedStateFromProps(nextProps, state) { + let newState = {}; + const { value, selectedValue } = nextProps; + + if ('type' in nextProps) { + newState = { + type: nextProps.type, + }; + } + if ('value' in nextProps) { + newState.value = value || nextProps.defaultValue || getNowByCurrentStateValue(state.value); + } + if ('selectedValue' in nextProps) { + newState.selectedValue = selectedValue; + } + + return newState; + } + + setType = (type) => { if (!('type' in this.props)) { this.setState({ type, }); } this.props.onTypeChange(type); - }, + } + render() { const props = this.props; const { @@ -140,7 +172,7 @@ const FullCalendar = createReactClass({ children, className: className.join(' '), }); - }, -}); + } +} -export default FullCalendar; +export default calendarMixinWrapper(commonMixinWrapper(FullCalendar)); diff --git a/src/MonthCalendar.jsx b/src/MonthCalendar.jsx index aa15220c1..fc9466966 100644 --- a/src/MonthCalendar.jsx +++ b/src/MonthCalendar.jsx @@ -1,24 +1,42 @@ import React from 'react'; -import createReactClass from 'create-react-class'; import PropTypes from 'prop-types'; import KeyCode from 'rc-util/lib/KeyCode'; import CalendarHeader from './calendar/CalendarHeader'; import CalendarFooter from './calendar/CalendarFooter'; -import CalendarMixin from './mixin/CalendarMixin'; -import CommonMixin from './mixin/CommonMixin'; +import { + calendarMixinWrapper, + calendarMixinPropTypes, + calendarMixinDefaultProps, +} from './mixin/CalendarMixin'; +import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; +import moment from 'moment'; -const MonthCalendar = createReactClass({ - propTypes: { +class MonthCalendar extends React.Component { + static propTypes = { + ...calendarMixinPropTypes, + ...propType, monthCellRender: PropTypes.func, dateCellRender: PropTypes.func, - }, - mixins: [CommonMixin, CalendarMixin], + value: PropTypes.object, + defaultValue: PropTypes.object, + selectedValue: PropTypes.object, + defaultSelectedValue: PropTypes.object, + disabledDate: PropTypes.object, + } - getInitialState() { - return { mode: 'month' }; - }, + static defaultProps = Object.assign({}, defaultProp, calendarMixinDefaultProps); - onKeyDown(event) { + constructor(props) { + super(props); + + this.state = { + mode: 'month', + value: props.value || props.defaultValue || moment(), + selectedValue: props.selectedValue || props.defaultSelectedValue, + }; + } + + onKeyDown = (event) => { const keyCode = event.keyCode; const ctrlKey = event.ctrlKey || event.metaKey; const stateValue = this.state.value; @@ -63,13 +81,13 @@ const MonthCalendar = createReactClass({ event.preventDefault(); return 1; } - }, + } - handlePanelChange(_, mode) { + handlePanelChange = (_, mode) => { if (mode !== 'date') { this.setState({ mode }); } - }, + } render() { const { props, state } = this; @@ -100,7 +118,7 @@ const MonthCalendar = createReactClass({ className: `${props.prefixCls}-month-calendar`, children, }); - }, -}); + } +} -export default MonthCalendar; +export default calendarMixinWrapper(commonMixinWrapper(MonthCalendar)); diff --git a/src/Picker.jsx b/src/Picker.jsx index 22c24c5c1..24edfb42e 100644 --- a/src/Picker.jsx +++ b/src/Picker.jsx @@ -1,6 +1,5 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import createReactClass from 'create-react-class'; import PropTypes from 'prop-types'; import createChainedFunction from 'rc-util/lib/createChainedFunction'; import KeyCode from 'rc-util/lib/KeyCode'; @@ -14,8 +13,8 @@ function refFn(field, component) { this[field] = component; } -const Picker = createReactClass({ - propTypes: { +export default class Picker extends React.Component { + static propTypes = { animation: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), disabled: PropTypes.bool, transitionName: PropTypes.string, @@ -38,22 +37,21 @@ const Picker = createReactClass({ PropTypes.array, ]), align: PropTypes.object, - }, - - getDefaultProps() { - return { - prefixCls: 'rc-calendar-picker', - style: {}, - align: {}, - placement: 'bottomLeft', - defaultOpen: false, - onChange: noop, - onOpenChange: noop, - }; - }, + } + + static defaultProps = { + prefixCls: 'rc-calendar-picker', + style: {}, + align: {}, + placement: 'bottomLeft', + defaultOpen: false, + onChange: noop, + onOpenChange: noop, + } + + constructor(props) { + super(props); - getInitialState() { - const props = this.props; let open; if ('open' in props) { open = props.open; @@ -62,45 +60,32 @@ const Picker = createReactClass({ } const value = props.value || props.defaultValue; this.saveCalendarRef = refFn.bind(this, 'calendarInstance'); - return { + + this.state = { open, value, }; - }, - - componentWillReceiveProps(nextProps) { - const { value, open } = nextProps; - if ('value' in nextProps) { - this.setState({ - value, - }); - } - if (open !== undefined) { - this.setState({ - open, - }); - } - }, + } componentDidUpdate(_, prevState) { if (!prevState.open && this.state.open) { // setTimeout is for making sure saveCalendarRef happen before focusCalendar this.focusTimeout = setTimeout(this.focusCalendar, 0, this); } - }, + } componentWillUnmount() { clearTimeout(this.focusTimeout); - }, + } - onCalendarKeyDown(event) { + onCalendarKeyDown = (event) => { if (event.keyCode === KeyCode.ESC) { event.stopPropagation(); this.close(this.focus); } - }, + } - onCalendarSelect(value, cause = {}) { + onCalendarSelect = (value, cause = {}) => { const props = this.props; if (!('value' in props)) { this.setState({ @@ -114,28 +99,44 @@ const Picker = createReactClass({ this.close(this.focus); } props.onChange(value); - }, + } - onKeyDown(event) { + onKeyDown = (event) => { if (event.keyCode === KeyCode.DOWN && !this.state.open) { this.open(); event.preventDefault(); } - }, + } - onCalendarOk() { + onCalendarOk = () => { this.close(this.focus); - }, + } - onCalendarClear() { + onCalendarClear = () => { this.close(this.focus); - }, + } - onVisibleChange(open) { + onVisibleChange = (open) => { this.setOpen(open); - }, + } - getCalendarElement() { + static getDerivedStateFromProps(nextProps) { + let newState = {}; + const { value, open } = nextProps; + if ('value' in nextProps) { + newState = { + value, + }; + } + if (open !== undefined) { + newState = { + open, + }; + } + return newState; + } + + getCalendarElement = () => { const props = this.props; const state = this.state; const calendarProps = props.calendar.props; @@ -152,9 +153,9 @@ const Picker = createReactClass({ }; return React.cloneElement(props.calendar, extraProps); - }, + } - setOpen(open, callback) { + setOpen = (open, callback) => { const { onOpenChange } = this.props; if (this.state.open !== open) { if (!('open' in this.props)) { @@ -164,27 +165,27 @@ const Picker = createReactClass({ } onOpenChange(open); } - }, + } - open(callback) { + open = (callback) => { this.setOpen(true, callback); - }, + } - close(callback) { + close = (callback) => { this.setOpen(false, callback); - }, + } - focus() { + focus = () => { if (!this.state.open) { ReactDOM.findDOMNode(this).focus(); } - }, + } - focusCalendar() { + focusCalendar = () => { if (this.state.open && !!this.calendarInstance) { this.calendarInstance.focus(); } - }, + } render() { const props = this.props; @@ -217,7 +218,5 @@ const Picker = createReactClass({ {React.cloneElement(children(state, props), { onKeyDown: this.onKeyDown })} ); - }, -}); - -export default Picker; + } +} diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index 1307e9435..180409954 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -1,5 +1,4 @@ import React from 'react'; -import createReactClass from 'create-react-class'; import PropTypes from 'prop-types'; import moment from 'moment'; import classnames from 'classnames'; @@ -8,7 +7,7 @@ import CalendarPart from './range-calendar/CalendarPart'; import TodayButton from './calendar/TodayButton'; import OkButton from './calendar/OkButton'; import TimePickerButton from './calendar/TimePickerButton'; -import CommonMixin from './mixin/CommonMixin'; +import { commonMixinWrapper, propType, defaultProp } from './mixin/CommonMixin'; import { syncTime, getTodayTime, isAllowedDate } from './util'; import { goTime, goStartMonth, goEndMonth, includesTime } from './util/toTime'; @@ -72,8 +71,9 @@ function onInputSelect(direction, value) { this.fireSelectValueChange(selectedValue); } -const RangeCalendar = createReactClass({ - propTypes: { +class RangeCalendar extends React.Component { + static propTypes = { + ...propType, prefixCls: PropTypes.string, dateInputPlaceholder: PropTypes.any, seperator: PropTypes.string, @@ -101,30 +101,28 @@ const RangeCalendar = createReactClass({ disabledDate: PropTypes.func, disabledTime: PropTypes.func, clearIcon: PropTypes.node, - }, - - mixins: [CommonMixin], - - getDefaultProps() { - return { - type: 'both', - seperator: '~', - defaultSelectedValue: [], - onValueChange: noop, - onHoverChange: noop, - onPanelChange: noop, - disabledTime: noop, - onInputSelect: noop, - showToday: true, - showDateInput: true, - }; - }, + onKeyDown: PropTypes.func, + } - getInitialState() { - const props = this.props; + static defaultProps = { + ...defaultProp, + type: 'both', + seperator: '~', + defaultSelectedValue: [], + onValueChange: noop, + onHoverChange: noop, + onPanelChange: noop, + disabledTime: noop, + onInputSelect: noop, + showToday: true, + showDateInput: true, + } + + constructor(props) { + super(props); const selectedValue = props.selectedValue || props.defaultSelectedValue; const value = normalizeAnchor(props, 1); - return { + this.state = { selectedValue, prevSelectedValue: selectedValue, firstSelectedValue: null, @@ -133,41 +131,21 @@ const RangeCalendar = createReactClass({ showTimePicker: false, mode: props.mode || ['date', 'date'], }; - }, - - componentWillReceiveProps(nextProps) { - const { state } = this; - const newState = {}; - if ('value' in nextProps) { - newState.value = normalizeAnchor(nextProps, 0); - this.setState(newState); - } - if ('hoverValue' in nextProps && !isArraysEqual(state.hoverValue, nextProps.hoverValue)) { - this.setState({ hoverValue: nextProps.hoverValue }); - } - if ('selectedValue' in nextProps) { - newState.selectedValue = nextProps.selectedValue; - newState.prevSelectedValue = nextProps.selectedValue; - this.setState(newState); - } - if ('mode' in nextProps && !isArraysEqual(state.mode, nextProps.mode)) { - this.setState({ mode: nextProps.mode }); - } - }, + } - onDatePanelEnter() { + onDatePanelEnter = () => { if (this.hasSelectedValue()) { this.fireHoverValueChange(this.state.selectedValue.concat()); } - }, + } - onDatePanelLeave() { + onDatePanelLeave = () => { if (this.hasSelectedValue()) { this.fireHoverValueChange([]); } - }, + } - onSelect(value) { + onSelect = (value) => { const { type } = this.props; const { selectedValue, prevSelectedValue, firstSelectedValue } = this.state; let nextSelectedValue; @@ -200,9 +178,9 @@ const RangeCalendar = createReactClass({ } this.fireSelectValueChange(nextSelectedValue); - }, + } - onKeyDown(event) { + onKeyDown = (event) => { if (event.target.nodeName.toLowerCase() === 'input') { return; } @@ -323,9 +301,9 @@ const RangeCalendar = createReactClass({ onKeyDown(event); } } - }, + } - onDayHover(value) { + onDayHover = (value) => { let hoverValue = []; const { selectedValue, firstSelectedValue } = this.state; @@ -349,55 +327,56 @@ const RangeCalendar = createReactClass({ this.fireHoverValueChange(hoverValue); return hoverValue; - }, + } - onToday() { + onToday = () => { const startValue = getTodayTime(this.state.value[0]); const endValue = startValue.clone().add(1, 'months'); this.setState({ value: [startValue, endValue] }); - }, + } - onOpenTimePicker() { + onOpenTimePicker = () => { this.setState({ showTimePicker: true, }); - }, - onCloseTimePicker() { + } + + onCloseTimePicker = () => { this.setState({ showTimePicker: false, }); - }, + } - onOk() { + onOk = () => { const { selectedValue } = this.state; if (this.isAllowedDateAndTime(selectedValue)) { this.props.onOk(this.state.selectedValue); } - }, + } - onStartInputSelect(...oargs) { + onStartInputSelect = (...oargs) => { const args = ['left'].concat(oargs); return onInputSelect.apply(this, args); - }, + } - onEndInputSelect(...oargs) { + onEndInputSelect = (...oargs) => { const args = ['right'].concat(oargs); return onInputSelect.apply(this, args); - }, + } - onStartValueChange(leftValue) { + onStartValueChange = (leftValue) => { const value = [...this.state.value]; value[0] = leftValue; return this.fireValueChange(value); - }, + } - onEndValueChange(rightValue) { + onEndValueChange = (rightValue) => { const value = [...this.state.value]; value[1] = rightValue; return this.fireValueChange(value); - }, + } - onStartPanelChange(value, mode) { + onStartPanelChange = (value, mode) => { const { props, state } = this; const newMode = [mode, state.mode[1]]; if (!('mode' in props)) { @@ -407,9 +386,9 @@ const RangeCalendar = createReactClass({ } const newValue = [value || state.value[0], state.value[1]]; props.onPanelChange(newValue, newMode); - }, + } - onEndPanelChange(value, mode) { + onEndPanelChange = (value, mode) => { const { props, state } = this; const newMode = [state.mode[0], mode]; if (!('mode' in props)) { @@ -419,9 +398,27 @@ const RangeCalendar = createReactClass({ } const newValue = [state.value[0], value || state.value[1]]; props.onPanelChange(newValue, newMode); - }, + } + + static getDerivedStateFromProps(nextProps, state) { + let newState = {}; + if ('value' in nextProps) { + newState.value = normalizeAnchor(nextProps, 0); + } + if ('hoverValue' in nextProps && !isArraysEqual(state.hoverValue, nextProps.hoverValue)) { + newState.hoverValue = nextProps.hoverValue; + } + if ('selectedValue' in nextProps) { + newState.selectedValue = nextProps.selectedValue; + newState.prevSelectedValue = nextProps.selectedValue; + } + if ('mode' in nextProps && !isArraysEqual(state.mode, nextProps.mode)) { + newState = { mode: nextProps.mode }; + } + return newState; + } - getStartValue() { + getStartValue = () => { let value = this.state.value[0]; const selectedValue = this.state.selectedValue; // keep selectedTime when select date @@ -433,9 +430,9 @@ const RangeCalendar = createReactClass({ return selectedValue[0]; } return value; - }, + } - getEndValue() { + getEndValue = () => { const { value, selectedValue, showTimePicker } = this.state; const endValue = value[1] ? value[1].clone() : value[0].clone().add(1, 'month'); // keep selectedTime when select date @@ -446,9 +443,10 @@ const RangeCalendar = createReactClass({ return selectedValue[1] ? selectedValue[1] : this.getStartValue(); } return endValue; - }, + } + // get disabled hours for second picker - getEndDisableTime() { + getEndDisableTime = () => { const { selectedValue, value } = this.state; const { disabledTime } = this.props; const userSettingDisabledTime = disabledTime(selectedValue, 'end') || {}; @@ -484,30 +482,30 @@ const RangeCalendar = createReactClass({ }; } return userSettingDisabledTime; - }, + } - isAllowedDateAndTime(selectedValue) { + isAllowedDateAndTime = (selectedValue) => { return isAllowedDate(selectedValue[0], this.props.disabledDate, this.disabledStartTime) && isAllowedDate(selectedValue[1], this.props.disabledDate, this.disabledEndTime); - }, + } - isMonthYearPanelShow(mode) { + isMonthYearPanelShow = (mode) => { return ['month', 'year', 'decade'].indexOf(mode) > -1; - }, + } - hasSelectedValue() { + hasSelectedValue = () => { const { selectedValue } = this.state; return !!selectedValue[1] && !!selectedValue[0]; - }, + } - compare(v1, v2) { + compare = (v1, v2) => { if (this.props.timePicker) { return v1.diff(v2); } return v1.diff(v2, 'days'); - }, + } - fireSelectValueChange(selectedValue, direct) { + fireSelectValueChange = (selectedValue, direct) => { const { timePicker } = this.props; const { prevSelectedValue } = this.state; if (timePicker && timePicker.props.defaultValue) { @@ -549,9 +547,9 @@ const RangeCalendar = createReactClass({ this.fireHoverValueChange([]); this.props.onSelect(selectedValue); } - }, + } - fireValueChange(value) { + fireValueChange = (value) => { const props = this.props; if (!('value' in props)) { this.setState({ @@ -559,38 +557,38 @@ const RangeCalendar = createReactClass({ }); } props.onValueChange(value); - }, + } - fireHoverValueChange(hoverValue) { + fireHoverValueChange = (hoverValue) => { const props = this.props; if (!('hoverValue' in props)) { this.setState({ hoverValue }); } props.onHoverChange(hoverValue); - }, + } - clear() { + clear = () => { this.fireSelectValueChange([], true); this.props.onClear(); - }, + } - disabledStartTime(time) { + disabledStartTime = (time) => { return this.props.disabledTime(time, 'start'); - }, + } - disabledEndTime(time) { + disabledEndTime = (time) => { return this.props.disabledTime(time, 'end'); - }, + } - disabledStartMonth(month) { + disabledStartMonth = (month) => { const { value } = this.state; return month.isSameOrAfter(value[1], 'month'); - }, + } - disabledEndMonth(month) { + disabledEndMonth = (month) => { const { value } = this.state; return month.isSameOrBefore(value[0], 'month'); - }, + } render() { const { props, state } = this; @@ -760,7 +758,7 @@ const RangeCalendar = createReactClass({ ); - }, -}); + } +} -export default RangeCalendar; +export default commonMixinWrapper(RangeCalendar); diff --git a/src/calendar/CalendarFooter.jsx b/src/calendar/CalendarFooter.jsx index 26f8b27b8..ca36bf30d 100644 --- a/src/calendar/CalendarFooter.jsx +++ b/src/calendar/CalendarFooter.jsx @@ -1,6 +1,5 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import createReactClass from 'create-react-class'; import PropTypes from 'prop-types'; import toFragment from 'rc-util/lib/Children/mapSelf'; import cx from 'classnames'; @@ -8,8 +7,8 @@ import TodayButton from '../calendar/TodayButton'; import OkButton from '../calendar/OkButton'; import TimePickerButton from '../calendar/TimePickerButton'; -const CalendarFooter = createReactClass({ - propTypes: { +export default class CalendarFooter extends React.Component { + static propTypes = { prefixCls: PropTypes.string, showDateInput: PropTypes.bool, disabledTime: PropTypes.any, @@ -21,21 +20,21 @@ const CalendarFooter = createReactClass({ renderFooter: PropTypes.func, defaultValue: PropTypes.object, mode: PropTypes.string, - }, + } onSelect(value) { this.props.onSelect(value); - }, + } getRootDOMNode() { return ReactDOM.findDOMNode(this); - }, + } render() { const props = this.props; const { value, prefixCls, showOk, timePicker, renderFooter, mode } = props; let footerEl = null; - const extraFooter = renderFooter(mode); + const extraFooter = renderFooter && renderFooter(mode); if (props.showToday || timePicker || extraFooter) { let nowEl; if (props.showToday) { @@ -69,7 +68,5 @@ const CalendarFooter = createReactClass({ ); } return footerEl; - }, -}); - -export default CalendarFooter; + } +} diff --git a/src/calendar/CalendarHeader.jsx b/src/calendar/CalendarHeader.jsx index 2d411209f..77862f173 100644 --- a/src/calendar/CalendarHeader.jsx +++ b/src/calendar/CalendarHeader.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import createReactClass from 'create-react-class'; import PropTypes from 'prop-types'; import toFragment from 'rc-util/lib/Children/mapSelf'; import MonthPanel from '../month/MonthPanel'; @@ -22,8 +21,8 @@ function showIf(condition, el) { return condition ? el : null; } -const CalendarHeader = createReactClass({ - propTypes: { +export default class CalendarHeader extends React.Component { + static propTypes = { prefixCls: PropTypes.string, value: PropTypes.object, onValueChange: PropTypes.func, @@ -34,47 +33,49 @@ const CalendarHeader = createReactClass({ enableNext: PropTypes.any, disabledMonth: PropTypes.func, renderFooter: PropTypes.func, - }, - - getDefaultProps() { - return { - enableNext: 1, - enablePrev: 1, - onPanelChange() { }, - onValueChange() { }, - }; - }, - - getInitialState() { + onMonthSelect: PropTypes.func, + } + + static defaultProps = { + enableNext: 1, + enablePrev: 1, + onPanelChange() { }, + onValueChange() { }, + } + + constructor(props) { + super(props); + this.nextMonth = goMonth.bind(this, 1); this.previousMonth = goMonth.bind(this, -1); this.nextYear = goYear.bind(this, 1); this.previousYear = goYear.bind(this, -1); - return { yearPanelReferer: null }; - }, - onMonthSelect(value) { + this.state = { yearPanelReferer: null }; + } + + onMonthSelect = (value) => { this.props.onPanelChange(value, 'date'); if (this.props.onMonthSelect) { this.props.onMonthSelect(value); } else { this.props.onValueChange(value); } - }, + } - onYearSelect(value) { + onYearSelect = (value) => { const referer = this.state.yearPanelReferer; this.setState({ yearPanelReferer: null }); this.props.onPanelChange(value, referer); this.props.onValueChange(value); - }, + } - onDecadeSelect(value) { + onDecadeSelect = (value) => { this.props.onPanelChange(value, 'year'); this.props.onValueChange(value); - }, + } - monthYearElement(showTimePicker) { + monthYearElement = (showTimePicker) => { const props = this.props; const prefixCls = props.prefixCls; const locale = props.locale; @@ -117,21 +118,21 @@ const CalendarHeader = createReactClass({ return ( {toFragment(my)} ); - }, + } - showMonthPanel() { + showMonthPanel = () => { // null means that users' interaction doesn't change value this.props.onPanelChange(null, 'month'); - }, + } - showYearPanel(referer) { + showYearPanel = (referer) => { this.setState({ yearPanelReferer: referer }); this.props.onPanelChange(null, 'year'); - }, + } - showDecadePanel() { + showDecadePanel = () => { this.props.onPanelChange(null, 'decade'); - }, + } render() { const { props } = this; @@ -219,7 +220,5 @@ const CalendarHeader = createReactClass({ {panel} ); - }, -}); - -export default CalendarHeader; + } +} diff --git a/src/date/DateInput.js b/src/date/DateInput.js index ed6a1aabf..9f8bf3c13 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -1,12 +1,15 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import createReactClass from 'create-react-class'; import PropTypes from 'prop-types'; import moment from 'moment'; import { formatDate } from '../util'; -const DateInput = createReactClass({ - propTypes: { +let cachedSelectionStart; +let cachedSelectionEnd; +let dateInputInstance; + +export default class DateInput extends React.Component { + static propTypes = { prefixCls: PropTypes.string, timePicker: PropTypes.object, value: PropTypes.object, @@ -20,38 +23,34 @@ const DateInput = createReactClass({ onSelect: PropTypes.func, selectedValue: PropTypes.object, clearIcon: PropTypes.node, - }, + } + + constructor(props) { + super(props); + const selectedValue = props.selectedValue; - getInitialState() { - const selectedValue = this.props.selectedValue; - return { + this.state = { str: formatDate(selectedValue, this.props.format), invalid: false, hasFocus: false, }; - }, - - componentWillReceiveProps(nextProps) { - this.cachedSelectionStart = this.dateInputInstance.selectionStart; - this.cachedSelectionEnd = this.dateInputInstance.selectionEnd; - // when popup show, click body will call this, bug! - const selectedValue = nextProps.selectedValue; - if (!this.state.hasFocus) { - this.setState({ - str: formatDate(selectedValue, nextProps.format), - invalid: false, - }); - } - }, + } componentDidUpdate() { if (this.state.hasFocus && !this.state.invalid && - !(this.cachedSelectionStart === 0 && this.cachedSelectionEnd === 0)) { - this.dateInputInstance.setSelectionRange(this.cachedSelectionStart, this.cachedSelectionEnd); + !(cachedSelectionStart === 0 && cachedSelectionEnd === 0)) { + dateInputInstance.setSelectionRange(cachedSelectionStart, cachedSelectionEnd); } - }, + } - onInputChange(event) { + onClear = () => { + this.setState({ + str: '', + }); + this.props.onClear(null); + } + + onInputChange = (event) => { const str = event.target.value; const { disabledDate, format, onChange, selectedValue } = this.props; @@ -100,39 +99,51 @@ const DateInput = createReactClass({ }); onChange(value); } - }, - - onClear() { - this.setState({ - str: '', - }); - this.props.onClear(null); - }, - - getRootDOMNode() { - return ReactDOM.findDOMNode(this); - }, - - focus() { - if (this.dateInputInstance) { - this.dateInputInstance.focus(); - } - }, - - saveDateInput(dateInput) { - this.dateInputInstance = dateInput; - }, + } - onFocus() { + onFocus = () => { this.setState({ hasFocus: true }); - }, + } - onBlur() { + onBlur = () => { this.setState((prevState, prevProps) => ({ hasFocus: false, str: formatDate(prevProps.value, prevProps.format), })); - }, + } + + static getDerivedStateFromProps(nextProps, state) { + let newState = {}; + + if (dateInputInstance) { + cachedSelectionStart = dateInputInstance.selectionStart; + cachedSelectionEnd = dateInputInstance.selectionEnd; + } + // when popup show, click body will call this, bug! + const selectedValue = nextProps.selectedValue; + if (!state.hasFocus) { + newState = { + str: formatDate(selectedValue, nextProps.format), + invalid: false, + }; + } + + return newState; + } + + getRootDOMNode = () => { + return ReactDOM.findDOMNode(this); + } + + focus = () => { + if (dateInputInstance) { + dateInputInstance.focus(); + } + } + + saveDateInput = (dateInput) => { + dateInputInstance = dateInput; + } render() { const props = this.props; @@ -164,7 +175,5 @@ const DateInput = createReactClass({ ) : null} ); - }, -}); - -export default DateInput; + } +} diff --git a/src/date/DateTBody.jsx b/src/date/DateTBody.jsx index d4a5c60aa..27dd33977 100644 --- a/src/date/DateTBody.jsx +++ b/src/date/DateTBody.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import createReactClass from 'create-react-class'; import PropTypes from 'prop-types'; import cx from 'classnames'; import DateConstants from './DateConstants'; @@ -29,8 +28,8 @@ function getIdFromDate(date) { return `rc-calendar-${date.year()}-${date.month()}-${date.date()}`; } -const DateTBody = createReactClass({ - propTypes: { +export default class DateTBody extends React.Component { + static propTypes = { contentRender: PropTypes.func, dateRender: PropTypes.func, disabledDate: PropTypes.func, @@ -39,13 +38,11 @@ const DateTBody = createReactClass({ value: PropTypes.object, hoverValue: PropTypes.any, showWeekNumber: PropTypes.bool, - }, + } - getDefaultProps() { - return { - hoverValue: [], - }; - }, + static defaultProps = { + hoverValue: [], + } render() { const props = this.props; @@ -251,7 +248,5 @@ const DateTBody = createReactClass({ return ( {tableHtml} ); - }, -}); - -export default DateTBody; + } +} diff --git a/src/date/DateTHead.jsx b/src/date/DateTHead.jsx index 86070c40d..90d675b3a 100644 --- a/src/date/DateTHead.jsx +++ b/src/date/DateTHead.jsx @@ -2,8 +2,7 @@ import React from 'react'; import DateConstants from './DateConstants'; import moment from 'moment'; -export default -class DateTHead extends React.Component { +export default class DateTHead extends React.Component { render() { const props = this.props; const value = props.value; diff --git a/src/date/DateTable.jsx b/src/date/DateTable.jsx index f64dacd62..73fd986ca 100644 --- a/src/date/DateTable.jsx +++ b/src/date/DateTable.jsx @@ -3,8 +3,7 @@ import React from 'react'; import DateTHead from './DateTHead'; import DateTBody from './DateTBody'; -export default -class DateTable extends React.Component { +export default class DateTable extends React.Component { render() { const props = this.props; const prefixCls = props.prefixCls; diff --git a/src/decade/DecadePanel.jsx b/src/decade/DecadePanel.jsx index 03c672ef4..2633ab304 100644 --- a/src/decade/DecadePanel.jsx +++ b/src/decade/DecadePanel.jsx @@ -20,8 +20,7 @@ function chooseDecade(year, event) { event.preventDefault(); } -export default - class DecadePanel extends React.Component { +export default class DecadePanel extends React.Component { constructor(props) { super(props); this.state = { diff --git a/src/index.js b/src/index.js index abd4428bf..424540905 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,6 @@ import Calendar from './Calendar'; +import { polyfill } from 'react-lifecycles-compat'; + +polyfill(Calendar); export default Calendar; diff --git a/src/mixin/CalendarMixin.js b/src/mixin/CalendarMixin.js index 59f927838..407ac067e 100644 --- a/src/mixin/CalendarMixin.js +++ b/src/mixin/CalendarMixin.js @@ -7,66 +7,37 @@ import { isAllowedDate, getTodayTime } from '../util/index'; function noop() { } -function getNow() { - return moment(); -} - -function getNowByCurrentStateValue(value) { +export function getNowByCurrentStateValue(value) { let ret; if (value) { ret = getTodayTime(value); } else { - ret = getNow(); + ret = moment(); } return ret; } -const CalendarMixin = { - propTypes: { - value: PropTypes.object, - defaultValue: PropTypes.object, - onKeyDown: PropTypes.func, - }, +export const calendarMixinPropTypes = { + value: PropTypes.object, + defaultValue: PropTypes.object, + onKeyDown: PropTypes.func, +}; - getDefaultProps() { - return { - onKeyDown: noop, - }; - }, +export const calendarMixinDefaultProps = { + onKeyDown: noop, +}; - getInitialState() { - const props = this.props; - const value = props.value || props.defaultValue || getNow(); - return { - value, - selectedValue: props.selectedValue || props.defaultSelectedValue, - }; - }, +export const calendarMixinWrapper = ComposeComponent => class extends ComposeComponent { + static displayName = 'CalendarMixinWrapper'; - componentWillReceiveProps(nextProps) { - let { value } = nextProps; - const { selectedValue } = nextProps; - if ('value' in nextProps) { - value = value || nextProps.defaultValue || getNowByCurrentStateValue(this.state.value); - this.setState({ - value, - }); - } - if ('selectedValue' in nextProps) { - this.setState({ - selectedValue, - }); - } - }, - - onSelect(value, cause) { + onSelect = (value, cause) => { if (value) { this.setValue(value); } this.setSelectedValue(value, cause); - }, + } - renderRoot(newProps) { + renderRoot = (newProps) => { const props = this.props; const prefixCls = props.prefixCls; @@ -88,20 +59,22 @@ const CalendarMixin = { {newProps.children} ); - }, + } - setSelectedValue(selectedValue, cause) { + setSelectedValue = (selectedValue, cause) => { // if (this.isAllowedDate(selectedValue)) { if (!('selectedValue' in this.props)) { this.setState({ selectedValue, }); } - this.props.onSelect(selectedValue, cause); + if (this.props.onSelect) { + this.props.onSelect(selectedValue, cause); + } // } - }, + } - setValue(value) { + setValue = (value) => { const originalValue = this.state.value; if (!('value' in this.props)) { this.setState({ @@ -110,18 +83,16 @@ const CalendarMixin = { } if ( originalValue && value && !originalValue.isSame(value) || - (!originalValue && value) || - (originalValue && !value) + (!originalValue && value) || + (originalValue && !value) ) { this.props.onChange(value); } - }, + } - isAllowedDate(value) { + isAllowedDate = (value) => { const disabledDate = this.props.disabledDate; const disabledTime = this.props.disabledTime; return isAllowedDate(value, disabledDate, disabledTime); - }, + } }; - -export default CalendarMixin; diff --git a/src/mixin/CommonMixin.js b/src/mixin/CommonMixin.js index 7c4039c41..5062ea736 100644 --- a/src/mixin/CommonMixin.js +++ b/src/mixin/CommonMixin.js @@ -4,42 +4,42 @@ import enUs from '../locale/en_US'; function noop() { } -export default { - propTypes: { - className: PropTypes.string, - locale: PropTypes.object, - style: PropTypes.object, - visible: PropTypes.bool, - onSelect: PropTypes.func, - prefixCls: PropTypes.string, - onChange: PropTypes.func, - onOk: PropTypes.func, - }, +export const propType = { + className: PropTypes.string, + locale: PropTypes.object, + style: PropTypes.object, + visible: PropTypes.bool, + onSelect: PropTypes.func, + prefixCls: PropTypes.string, + onChange: PropTypes.func, + onOk: PropTypes.func, +}; - getDefaultProps() { - return { - locale: enUs, - style: {}, - visible: true, - prefixCls: 'rc-calendar', - className: '', - onSelect: noop, - onChange: noop, - onClear: noop, - renderFooter() { - return null; - }, - renderSidebar() { - return null; - }, - }; +export const defaultProp = { + locale: enUs, + style: {}, + visible: true, + prefixCls: 'rc-calendar', + className: '', + onSelect: noop, + onChange: noop, + onClear: noop, + renderFooter() { + return null; + }, + renderSidebar() { + return null; }, +}; + +export const commonMixinWrapper = ComposeComponent => class extends ComposeComponent { + static displayName = 'CommonMixinWrapper'; shouldComponentUpdate(nextProps) { return this.props.visible || nextProps.visible; - }, + } - getFormat() { + getFormat = () => { let { format } = this.props; const { locale, timePicker } = this.props; if (!format) { @@ -50,15 +50,15 @@ export default { } } return format; - }, + } - focus() { + focus = () => { if (this.rootInstance) { this.rootInstance.focus(); } - }, + } - saveRoot(root) { + saveRoot = (root) => { this.rootInstance = root; - }, + } }; diff --git a/src/month/MonthPanel.jsx b/src/month/MonthPanel.jsx index 8df402d98..39297d374 100644 --- a/src/month/MonthPanel.jsx +++ b/src/month/MonthPanel.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import createReactClass from 'create-react-class'; import PropTypes from 'prop-types'; import MonthTable from './MonthTable'; @@ -13,57 +12,63 @@ function noop() { } -const MonthPanel = createReactClass({ - propTypes: { +export default class MonthPanel extends React.Component { + static propTypes = { onChange: PropTypes.func, disabledDate: PropTypes.func, onSelect: PropTypes.func, renderFooter: PropTypes.func, - }, + rootPrefixCls: PropTypes.string, + value: PropTypes.object, + defaultValue: PropTypes.object, + } - getDefaultProps() { - return { - onChange: noop, - onSelect: noop, - }; - }, + static defaultProps = { + onChange: noop, + onSelect: noop, + } + + constructor(props) { + super(props); - getInitialState() { - const props = this.props; - // bind methods this.nextYear = goYear.bind(this, 1); this.previousYear = goYear.bind(this, -1); this.prefixCls = `${props.rootPrefixCls}-month-panel`; - return { + + this.state = { value: props.value || props.defaultValue, }; - }, + } + + static getDerivedStateFromProps(nextProps) { + let newState = {}; - componentWillReceiveProps(nextProps) { if ('value' in nextProps) { - this.setState({ + newState = { value: nextProps.value, - }); + }; } - }, - setAndChangeValue(value) { + return newState; + } + + setAndChangeValue = (value) => { this.setValue(value); this.props.onChange(value); - }, + } - setAndSelectValue(value) { + setAndSelectValue = (value) => { this.setValue(value); this.props.onSelect(value); - }, + } - setValue(value) { + setValue = (value) => { if (!('value' in this.props)) { this.setState({ value, }); } - }, + } render() { const props = this.props; @@ -119,7 +124,5 @@ const MonthPanel = createReactClass({ )} ); - }, -}); - -export default MonthPanel; + } +} diff --git a/src/range-calendar/CalendarPart.js b/src/range-calendar/CalendarPart.js index 7282d99ca..bfd9ce401 100644 --- a/src/range-calendar/CalendarPart.js +++ b/src/range-calendar/CalendarPart.js @@ -1,13 +1,12 @@ import React from 'react'; -import createReactClass from 'create-react-class'; import PropTypes from 'prop-types'; import CalendarHeader from '../calendar/CalendarHeader'; import DateTable from '../date/DateTable'; import DateInput from '../date/DateInput'; import { getTimeConfig } from '../util/index'; -const CalendarPart = createReactClass({ - propTypes: { +export default class CalendarPart extends React.Component { + static propTypes = { prefixCls: PropTypes.string, value: PropTypes.any, hoverValue: PropTypes.any, @@ -26,7 +25,8 @@ const CalendarPart = createReactClass({ enableNext: PropTypes.any, enablePrev: PropTypes.any, clearIcon: PropTypes.node, - }, + } + render() { const props = this.props; const { @@ -116,7 +116,5 @@ const CalendarPart = createReactClass({ ); - }, -}); - -export default CalendarPart; + } +} diff --git a/src/year/YearPanel.jsx b/src/year/YearPanel.jsx index ea2b46837..b4dfc6e1c 100644 --- a/src/year/YearPanel.jsx +++ b/src/year/YearPanel.jsx @@ -19,8 +19,7 @@ function chooseYear(year) { this.props.onSelect(value); } -export default - class YearPanel extends React.Component { +export default class YearPanel extends React.Component { constructor(props) { super(props); this.prefixCls = `${props.rootPrefixCls}-year-panel`; From 33f45223ddf4000062d67c05c123e8e2388bc7ae Mon Sep 17 00:00:00 2001 From: Van Nguyen Date: Mon, 31 Dec 2018 09:24:22 -0800 Subject: [PATCH 025/114] Revise disabled callback interfaces --- index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.d.ts b/index.d.ts index 4f539f51d..879bac582 100644 --- a/index.d.ts +++ b/index.d.ts @@ -29,8 +29,8 @@ export interface Props { onClear?: () => void; onChange?: (date: Moment) => void; onPanelChange?: (date: Moment, mode: Mode) => void; - disabledDate?: (current: Moment) => boolean; - disabledTime?: (current: Moment) => object; + disabledDate?: (current: Moment | undefined) => boolean; + disabledTime?: (current: Moment | undefined) => object; dateRender?: (current: Moment, value: Moment) => React.ReactNode; renderFooter?: () => React.ReactNode; renderSidebar?: () => React.ReactNode; From e3b543ad2165d8f8da609081a797582e6f382292 Mon Sep 17 00:00:00 2001 From: Yann Normand Date: Wed, 2 Jan 2019 17:30:51 +1000 Subject: [PATCH 026/114] auto focus on calendar input when opening picker (#438) * auto focus calendar input when opening * calendar panel optionally focusable * default focusablePanel to true * update test calendar snapshots * add auto focus test --- examples/antd-calendar.js | 21 ++++++------ src/Calendar.jsx | 15 ++++++++- src/date/DateInput.js | 8 +++-- src/mixin/CommonMixin.js | 8 ++++- tests/Picker.spec.jsx | 23 +++++++++++-- tests/__snapshots__/Calendar.spec.jsx.snap | 5 +++ tests/__snapshots__/locale.spec.js.snap | 39 ++++++++++++++++++++++ 7 files changed, 103 insertions(+), 16 deletions(-) diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index 703785734..7a3bc37c1 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -166,15 +166,15 @@ class Demo extends React.Component { ({ value }) => { return ( - + ); } @@ -208,7 +208,7 @@ class DemoMultiFormat extends React.Component { return (
Accepts multiple input formats -
+
{multiFormats.join(', ')}
); } diff --git a/src/Calendar.jsx b/src/Calendar.jsx index e52591a97..2a896963b 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -51,6 +51,7 @@ class Calendar extends React.Component { renderFooter: PropTypes.func, renderSidebar: PropTypes.func, clearIcon: PropTypes.node, + focusablePanel: PropTypes.bool, } static defaultProps = { @@ -61,8 +62,10 @@ class Calendar extends React.Component { timePicker: null, onOk: noop, onPanelChange: noop, + focusablePanel: true, } + constructor(props) { super(props); @@ -73,6 +76,12 @@ class Calendar extends React.Component { }; } + componentDidMount() { + if (this.props.showDateInput) { + this.saveFocusElement(DateInput.getInstance()); + } + } + onPanelChange = (value, mode) => { const { props, state } = this; if (!('mode' in props)) { @@ -279,13 +288,17 @@ class Calendar extends React.Component { clearIcon={clearIcon} /> ) : null; + const children = []; if (props.renderSidebar) { children.push(props.renderSidebar()); } children.push(
{dateInputElement} -
+
{ return ReactDOM.findDOMNode(this); } @@ -170,7 +174,7 @@ export default class DateInput extends React.Component { title={locale.clear} onClick={this.onClear} > - {clearIcon || } + {clearIcon || } ) : null}
diff --git a/src/mixin/CommonMixin.js b/src/mixin/CommonMixin.js index 5062ea736..c99210c30 100644 --- a/src/mixin/CommonMixin.js +++ b/src/mixin/CommonMixin.js @@ -53,11 +53,17 @@ export const commonMixinWrapper = ComposeComponent => class extends ComposeCompo } focus = () => { - if (this.rootInstance) { + if (this.focusElement) { + this.focusElement.focus(); + } else if (this.rootInstance) { this.rootInstance.focus(); } } + saveFocusElement = (focusElement) => { + this.focusElement = focusElement; + } + saveRoot = (root) => { this.rootInstance = root; } diff --git a/tests/Picker.spec.jsx b/tests/Picker.spec.jsx index 0804353c7..ea95994da 100644 --- a/tests/Picker.spec.jsx +++ b/tests/Picker.spec.jsx @@ -29,11 +29,11 @@ describe('DatePicker', () => { onChange={noop} readOnly value={value && `${value[0] && - value[0].format(format)} - ${value[1] && value[1].format(format)}`} + value[0].format(format)} - ${value[1] && value[1].format(format)}`} />); } - function renderPicker(props) { + function renderPicker(props, calendarProps) { return mount( { locale={CalendarLocale} showOk showClear + {...calendarProps} /> } defaultValue={VALUE} @@ -184,4 +185,22 @@ describe('DatePicker', () => { picker.find('.rc-calendar-clear-btn').simulate('click'); expect(picker.state().open).toBe(false); }); + + it('auto focuses the calendar input when opening', () => { + jest.useFakeTimers(); + const picker = renderPicker({ value: moment() }); + picker.find('.rc-calendar-picker-input').simulate('click'); + jest.runAllTimers(); + expect(document.activeElement).toBeDefined(); + expect(document.activeElement.classList).toContain('rc-calendar-input'); + }); + + it('auto focuses the calendar div when date input is not shown', () => { + jest.useFakeTimers(); + const picker = renderPicker({ value: moment() }, { showDateInput: false }); + picker.find('.rc-calendar-picker-input').simulate('click'); + jest.runAllTimers(); + expect(document.activeElement).toBeDefined(); + expect(document.activeElement.classList).toContain('rc-calendar'); + }); }); diff --git a/tests/__snapshots__/Calendar.spec.jsx.snap b/tests/__snapshots__/Calendar.spec.jsx.snap index 3e4e710ed..025db555d 100644 --- a/tests/__snapshots__/Calendar.spec.jsx.snap +++ b/tests/__snapshots__/Calendar.spec.jsx.snap @@ -30,6 +30,7 @@ exports[`Calendar controlled panels render controlled panels correctly 1`] = `
Date: Wed, 2 Jan 2019 15:34:08 +0800 Subject: [PATCH 027/114] bump 9.10.0 --- HISTORY.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index c4c72dddc..62820f76e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,10 @@ # History ---- +## 9.10.0 / 2019-01-02 + +- add `focusablePanel` prop. + ## 9.9.0 / 2018-12-23 - `renderFooter(mode)` support all modes. diff --git a/package.json b/package.json index a9ae823a7..2e8c119d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.9.2", + "version": "9.10.0", "description": "React Calendar", "keywords": [ "react", From bca46ad3602c9427541f8d8782312586b6e312f4 Mon Sep 17 00:00:00 2001 From: zombiej Date: Wed, 2 Jan 2019 16:07:41 +0800 Subject: [PATCH 028/114] fix dateInputInstance if not ready --- src/date/DateInput.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/date/DateInput.js b/src/date/DateInput.js index 9ec1d9119..d00472985 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -37,7 +37,7 @@ export default class DateInput extends React.Component { } componentDidUpdate() { - if (this.state.hasFocus && !this.state.invalid && + if (dateInputInstance && this.state.hasFocus && !this.state.invalid && !(cachedSelectionStart === 0 && cachedSelectionEnd === 0)) { dateInputInstance.setSelectionRange(cachedSelectionStart, cachedSelectionEnd); } From 67d3bc09ba18e2209afac67568ba9ebc89545ea3 Mon Sep 17 00:00:00 2001 From: zombiej Date: Wed, 2 Jan 2019 16:09:21 +0800 Subject: [PATCH 029/114] bump 9.10.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2e8c119d5..335a4bf72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.10.0", + "version": "9.10.1", "description": "React Calendar", "keywords": [ "react", From a8797690d31cd1d3db0148f143b04085f0f81bd1 Mon Sep 17 00:00:00 2001 From: zombiej Date: Wed, 2 Jan 2019 16:20:56 +0800 Subject: [PATCH 030/114] fix getDerivedStateFromProps replace newState in Picker --- src/Picker.jsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Picker.jsx b/src/Picker.jsx index 24edfb42e..0854161a4 100644 --- a/src/Picker.jsx +++ b/src/Picker.jsx @@ -121,17 +121,13 @@ export default class Picker extends React.Component { } static getDerivedStateFromProps(nextProps) { - let newState = {}; + const newState = {}; const { value, open } = nextProps; if ('value' in nextProps) { - newState = { - value, - }; + newState.value = value; } if (open !== undefined) { - newState = { - open, - }; + newState.open = open; } return newState; } From ba87b6ca99e08509ecb73b86cae9d6aaa9fa4735 Mon Sep 17 00:00:00 2001 From: zombiej Date: Wed, 2 Jan 2019 16:21:20 +0800 Subject: [PATCH 031/114] bump 9.10.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 335a4bf72..7b6cf6974 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.10.1", + "version": "9.10.2", "description": "React Calendar", "keywords": [ "react", From 776928323b7ac3aa9426a3a2e9e7012587404f5b Mon Sep 17 00:00:00 2001 From: zombiej Date: Wed, 2 Jan 2019 22:32:28 +0800 Subject: [PATCH 032/114] add missing polyfill --- package.json | 2 +- src/Calendar.jsx | 3 +++ src/FullCalendar.jsx | 3 +++ src/Picker.jsx | 7 ++++++- src/RangeCalendar.js | 3 +++ src/date/DateInput.js | 7 ++++++- src/index.js | 3 --- src/month/MonthPanel.jsx | 7 ++++++- 8 files changed, 28 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 7b6cf6974..890e009ea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.10.2", + "version": "9.10.3", "description": "React Calendar", "keywords": [ "react", diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 2a896963b..17977e6ad 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -2,6 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import KeyCode from 'rc-util/lib/KeyCode'; +import { polyfill } from 'react-lifecycles-compat'; import DateTable from './date/DateTable'; import CalendarHeader from './calendar/CalendarHeader'; import CalendarFooter from './calendar/CalendarFooter'; @@ -362,4 +363,6 @@ class Calendar extends React.Component { } } +polyfill(Calendar); + export default calendarMixinWrapper(commonMixinWrapper(Calendar)); diff --git a/src/FullCalendar.jsx b/src/FullCalendar.jsx index 47a7fd573..90fdb7f66 100644 --- a/src/FullCalendar.jsx +++ b/src/FullCalendar.jsx @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { polyfill } from 'react-lifecycles-compat'; import DateTable from './date/DateTable'; import MonthTable from './month/MonthTable'; import { @@ -175,4 +176,6 @@ class FullCalendar extends React.Component { } } +polyfill(FullCalendar); + export default calendarMixinWrapper(commonMixinWrapper(FullCalendar)); diff --git a/src/Picker.jsx b/src/Picker.jsx index 0854161a4..9aa5501ca 100644 --- a/src/Picker.jsx +++ b/src/Picker.jsx @@ -1,6 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; +import { polyfill } from 'react-lifecycles-compat'; import createChainedFunction from 'rc-util/lib/createChainedFunction'; import KeyCode from 'rc-util/lib/KeyCode'; import placements from './picker/placements'; @@ -13,7 +14,7 @@ function refFn(field, component) { this[field] = component; } -export default class Picker extends React.Component { +class Picker extends React.Component { static propTypes = { animation: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), disabled: PropTypes.bool, @@ -216,3 +217,7 @@ export default class Picker extends React.Component { ); } } + +polyfill(Picker); + +export default Picker; diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index 180409954..10eb9693e 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import moment from 'moment'; import classnames from 'classnames'; +import { polyfill } from 'react-lifecycles-compat'; import KeyCode from 'rc-util/lib/KeyCode'; import CalendarPart from './range-calendar/CalendarPart'; import TodayButton from './calendar/TodayButton'; @@ -761,4 +762,6 @@ class RangeCalendar extends React.Component { } } +polyfill(RangeCalendar); + export default commonMixinWrapper(RangeCalendar); diff --git a/src/date/DateInput.js b/src/date/DateInput.js index d00472985..0321b2abe 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -1,6 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; +import { polyfill } from 'react-lifecycles-compat'; import moment from 'moment'; import { formatDate } from '../util'; @@ -8,7 +9,7 @@ let cachedSelectionStart; let cachedSelectionEnd; let dateInputInstance; -export default class DateInput extends React.Component { +class DateInput extends React.Component { static propTypes = { prefixCls: PropTypes.string, timePicker: PropTypes.object, @@ -181,3 +182,7 @@ export default class DateInput extends React.Component { ); } } + +polyfill(DateInput); + +export default DateInput; diff --git a/src/index.js b/src/index.js index 424540905..abd4428bf 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,3 @@ import Calendar from './Calendar'; -import { polyfill } from 'react-lifecycles-compat'; - -polyfill(Calendar); export default Calendar; diff --git a/src/month/MonthPanel.jsx b/src/month/MonthPanel.jsx index 39297d374..875db4122 100644 --- a/src/month/MonthPanel.jsx +++ b/src/month/MonthPanel.jsx @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { polyfill } from 'react-lifecycles-compat'; import MonthTable from './MonthTable'; function goYear(direction) { @@ -12,7 +13,7 @@ function noop() { } -export default class MonthPanel extends React.Component { +class MonthPanel extends React.Component { static propTypes = { onChange: PropTypes.func, disabledDate: PropTypes.func, @@ -126,3 +127,7 @@ export default class MonthPanel extends React.Component {
); } } + +polyfill(MonthPanel); + +export default MonthPanel; From bf030dd0626257679625594cb7f36e90eccb31b7 Mon Sep 17 00:00:00 2001 From: zombiej Date: Thu, 3 Jan 2019 17:21:38 +0800 Subject: [PATCH 033/114] fix PropTypes --- src/MonthCalendar.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MonthCalendar.jsx b/src/MonthCalendar.jsx index fc9466966..7f4c7eebf 100644 --- a/src/MonthCalendar.jsx +++ b/src/MonthCalendar.jsx @@ -21,7 +21,7 @@ class MonthCalendar extends React.Component { defaultValue: PropTypes.object, selectedValue: PropTypes.object, defaultSelectedValue: PropTypes.object, - disabledDate: PropTypes.object, + disabledDate: PropTypes.func, } static defaultProps = Object.assign({}, defaultProp, calendarMixinDefaultProps); From 633809c24460d603011fb54a1ad8a929e889e709 Mon Sep 17 00:00:00 2001 From: zombiej Date: Thu, 3 Jan 2019 17:21:55 +0800 Subject: [PATCH 034/114] bump 9.10.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 890e009ea..b8cd9480f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.10.3", + "version": "9.10.4", "description": "React Calendar", "keywords": [ "react", From 29613d76e70fb4d4be4ef8250e709e6659b32e33 Mon Sep 17 00:00:00 2001 From: muratayusuke Date: Sat, 5 Jan 2019 19:20:36 +0900 Subject: [PATCH 035/114] Add 'format' type to definitions --- index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/index.d.ts b/index.d.ts index 879bac582..027ea1095 100644 --- a/index.d.ts +++ b/index.d.ts @@ -17,6 +17,7 @@ export interface Props { selectedValue?: Moment; mode?: Mode; locale?: object; + format?: string; showDateInput?: boolean; showWeekNumber?: boolean; showToday?: boolean; From 928f0e4a22a8f3e608e8f026d4ceea95fe305ea2 Mon Sep 17 00:00:00 2001 From: zombiej Date: Mon, 7 Jan 2019 11:03:21 +0800 Subject: [PATCH 036/114] Support enter to open & close fix ant-design/ant-design#14136 --- src/Calendar.jsx | 5 +++-- src/Picker.jsx | 3 ++- src/date/DateInput.js | 10 ++++++++++ tests/Picker.spec.jsx | 26 +++++++++++++++++++++----- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 17977e6ad..6b184cc6f 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -177,9 +177,9 @@ class Calendar extends React.Component { }); } - onDateInputChange = (value) => { + onDateInputSelect = (value) => { this.onSelect(value, { - source: 'dateInput', + source: 'dateInputSelect', }); } @@ -286,6 +286,7 @@ class Calendar extends React.Component { prefixCls={prefixCls} selectedValue={selectedValue} onChange={this.onDateInputChange} + onSelect={this.onDateInputSelect} clearIcon={clearIcon} /> ) : null; diff --git a/src/Picker.jsx b/src/Picker.jsx index 9aa5501ca..955dc1ac8 100644 --- a/src/Picker.jsx +++ b/src/Picker.jsx @@ -95,6 +95,7 @@ class Picker extends React.Component { } if ( cause.source === 'keyboard' || + cause.source === 'dateInputSelect' || (!props.calendar.props.timePicker && cause.source !== 'dateInput') || cause.source === 'todayButton') { this.close(this.focus); @@ -103,7 +104,7 @@ class Picker extends React.Component { } onKeyDown = (event) => { - if (event.keyCode === KeyCode.DOWN && !this.state.open) { + if (!this.state.open && (event.keyCode === KeyCode.DOWN || event.keyCode === KeyCode.ENTER)) { this.open(); event.preventDefault(); } diff --git a/src/date/DateInput.js b/src/date/DateInput.js index 0321b2abe..296ec8d8a 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -1,6 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; +import KeyCode from 'rc-util/lib/KeyCode'; import { polyfill } from 'react-lifecycles-compat'; import moment from 'moment'; import { formatDate } from '../util'; @@ -96,6 +97,7 @@ class DateInput extends React.Component { selectedValue && value && !selectedValue.isSame(value) )) { this.setState({ + invalid: false, str, }); onChange(value); @@ -113,6 +115,13 @@ class DateInput extends React.Component { })); } + onKeyDown = ({ keyCode }) => { + const { onSelect, value } = this.props; + if (keyCode === KeyCode.ENTER && onSelect) { + onSelect(value.clone()); + } + }; + static getDerivedStateFromProps(nextProps, state) { let newState = {}; @@ -165,6 +174,7 @@ class DateInput extends React.Component { disabled={props.disabled} placeholder={placeholder} onChange={this.onInputChange} + onKeyDown={this.onKeyDown} onFocus={this.onFocus} onBlur={this.onBlur} /> diff --git a/tests/Picker.spec.jsx b/tests/Picker.spec.jsx index ea95994da..9882251ec 100644 --- a/tests/Picker.spec.jsx +++ b/tests/Picker.spec.jsx @@ -164,12 +164,19 @@ describe('DatePicker', () => { expect(picker.state().open).toBe(false); }); - it('open by DOWN key', () => { - const picker = renderPicker(); - picker.find('.rc-calendar-picker-input').simulate('keyDown', { - keyCode: keyCode.DOWN, + describe('open by key', () => { + [ + { name: 'Down', key: keyCode.DOWN }, + { name: 'Enter', key: keyCode.ENTER }, + ].forEach(({ name, key }) => { + it(`open by ${name} key`, () => { + const picker = renderPicker(); + picker.find('.rc-calendar-picker-input').simulate('keyDown', { + keyCode: key, + }); + expect(picker.state().open).toBe(true); + }); }); - expect(picker.state().open).toBe(true); }); it('close on ok', () => { @@ -186,6 +193,15 @@ describe('DatePicker', () => { expect(picker.state().open).toBe(false); }); + it('close on enter of DateInput', () => { + const picker = renderPicker({ value: moment() }); + picker.find('.rc-calendar-picker-input').simulate('click'); + picker.find('.rc-calendar-input').simulate('keyDown', { + keyCode: keyCode.ENTER, + }); + expect(picker.state().open).toBe(false); + }); + it('auto focuses the calendar input when opening', () => { jest.useFakeTimers(); const picker = renderPicker({ value: moment() }); From ebd5eec43b24e1a29219b4edfb039baf135483c8 Mon Sep 17 00:00:00 2001 From: zombiej Date: Mon, 7 Jan 2019 11:03:37 +0800 Subject: [PATCH 037/114] bump 9.10.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b8cd9480f..a4d0d986b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.10.4", + "version": "9.10.5", "description": "React Calendar", "keywords": [ "react", From ee24ca5b09d7fab95dc7173ff6973e2f209852ad Mon Sep 17 00:00:00 2001 From: zombiej Date: Wed, 16 Jan 2019 23:17:20 +0800 Subject: [PATCH 038/114] fix value not update fix ant-design/ant-design#14371 --- package.json | 2 +- src/mixin/CalendarMixin.js | 20 ++++++++++++++++++++ tests/MonthCalendar.spec.js | 8 ++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index a4d0d986b..cfdb867d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.10.5", + "version": "9.10.6", "description": "React Calendar", "keywords": [ "react", diff --git a/src/mixin/CalendarMixin.js b/src/mixin/CalendarMixin.js index 407ac067e..054f56e50 100644 --- a/src/mixin/CalendarMixin.js +++ b/src/mixin/CalendarMixin.js @@ -30,6 +30,26 @@ export const calendarMixinDefaultProps = { export const calendarMixinWrapper = ComposeComponent => class extends ComposeComponent { static displayName = 'CalendarMixinWrapper'; + static getDerivedStateFromProps(nextProps, prevState) { + // Use origin function if provided + if (ComposeComponent.getDerivedStateFromProps) { + return ComposeComponent.getDerivedStateFromProps(nextProps, prevState); + } + + const { value, selectedValue } = nextProps; + const newState = {}; + + if ('value' in nextProps) { + newState.value = + value || nextProps.defaultValue || getNowByCurrentStateValue(prevState.value); + } + if ('selectedValue' in nextProps) { + newState.selectedValue = selectedValue; + } + + return newState; + } + onSelect = (value, cause) => { if (value) { this.setValue(value); diff --git a/tests/MonthCalendar.spec.js b/tests/MonthCalendar.spec.js index 42b66efb1..2557ad102 100644 --- a/tests/MonthCalendar.spec.js +++ b/tests/MonthCalendar.spec.js @@ -106,4 +106,12 @@ describe('MonthCalendar', () => { expect(wrapper.state().value.year()).toBe(2017); }); }); + + it('controlled value should work', () => { + const wrapper = mount(); + expect(wrapper.state().value.format('YYYY-MM-DD')).toBe('2000-01-01'); + + wrapper.setProps({ value: moment('2049-09-03 00:00:00') }); + expect(wrapper.state().value.format('YYYY-MM-DD')).toBe('2049-09-03'); + }); }); From b567b9dc05ed56aa0eba6d39f8c8ee450e9e1c12 Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 18 Jan 2019 15:56:51 +0800 Subject: [PATCH 039/114] try to fix IE prototype ref ant-design/ant-design#14405 --- src/mixin/CommonMixin.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mixin/CommonMixin.js b/src/mixin/CommonMixin.js index c99210c30..de2cfda1f 100644 --- a/src/mixin/CommonMixin.js +++ b/src/mixin/CommonMixin.js @@ -34,6 +34,7 @@ export const defaultProp = { export const commonMixinWrapper = ComposeComponent => class extends ComposeComponent { static displayName = 'CommonMixinWrapper'; + static getDerivedStateFromProps = ComposeComponent.getDerivedStateFromProps; shouldComponentUpdate(nextProps) { return this.props.visible || nextProps.visible; From 39c1c2001753e19fac732bd053bfa95de61fa464 Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 18 Jan 2019 15:57:50 +0800 Subject: [PATCH 040/114] bump 9.10.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cfdb867d3..c2a2a8f1e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.10.6", + "version": "9.10.7", "description": "React Calendar", "keywords": [ "react", From 3c626414a0281740201b6c4714c45dbf46f5f10a Mon Sep 17 00:00:00 2001 From: zombiej Date: Mon, 21 Jan 2019 09:38:11 +0800 Subject: [PATCH 041/114] pass defaultProps to fix IE 10 ref ant-design/ant-design#14405 --- package.json | 2 +- src/mixin/CalendarMixin.js | 1 + src/mixin/CommonMixin.js | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c2a2a8f1e..9c0abcab2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.10.7", + "version": "9.10.8", "description": "React Calendar", "keywords": [ "react", diff --git a/src/mixin/CalendarMixin.js b/src/mixin/CalendarMixin.js index 054f56e50..72e8f52e1 100644 --- a/src/mixin/CalendarMixin.js +++ b/src/mixin/CalendarMixin.js @@ -29,6 +29,7 @@ export const calendarMixinDefaultProps = { export const calendarMixinWrapper = ComposeComponent => class extends ComposeComponent { static displayName = 'CalendarMixinWrapper'; + static defaultProps = ComposeComponent.defaultProps; static getDerivedStateFromProps(nextProps, prevState) { // Use origin function if provided diff --git a/src/mixin/CommonMixin.js b/src/mixin/CommonMixin.js index de2cfda1f..946f6c09a 100644 --- a/src/mixin/CommonMixin.js +++ b/src/mixin/CommonMixin.js @@ -34,6 +34,7 @@ export const defaultProp = { export const commonMixinWrapper = ComposeComponent => class extends ComposeComponent { static displayName = 'CommonMixinWrapper'; + static defaultProps = ComposeComponent.defaultProps; static getDerivedStateFromProps = ComposeComponent.getDerivedStateFromProps; shouldComponentUpdate(nextProps) { From b9f924fc7cc8b94586c6556999e7aa1672b0b221 Mon Sep 17 00:00:00 2001 From: zombieJ Date: Mon, 18 Feb 2019 09:15:25 +0800 Subject: [PATCH 042/114] Adjust RangePicker date input logic (#503) * range with key * test case * update node version --- .travis.yml | 2 +- src/RangeCalendar.js | 24 ++++++++++++++++++------ src/range-calendar/CalendarPart.js | 8 +++++--- tests/RangeCalendar.spec.jsx | 26 ++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index cc7daab5d..7aff03e0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ notifications: - hust2012jiangkai@gmail.com node_js: -- 6.9.1 +- 10 before_install: - | diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index 10eb9693e..a5c87b931 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -57,7 +57,7 @@ function generateOptions(length, extraOptionGen) { return arr; } -function onInputSelect(direction, value) { +function onInputSelect(direction, value, cause) { if (!value) { return; } @@ -69,7 +69,7 @@ function onInputSelect(direction, value) { selectedValue[1 - index] = this.state.showTimePicker ? selectedValue[index] : undefined; } this.props.onInputSelect(selectedValue); - this.fireSelectValueChange(selectedValue); + this.fireSelectValueChange(selectedValue, null, cause || { source: 'dateInput' }); } class RangeCalendar extends React.Component { @@ -355,16 +355,26 @@ class RangeCalendar extends React.Component { } } - onStartInputSelect = (...oargs) => { + onStartInputChange = (...oargs) => { const args = ['left'].concat(oargs); return onInputSelect.apply(this, args); } - onEndInputSelect = (...oargs) => { + onEndInputChange = (...oargs) => { const args = ['right'].concat(oargs); return onInputSelect.apply(this, args); } + onStartInputSelect = (value) => { + const args = ['left', value, { source: 'dateInputSelect' }]; + return onInputSelect.apply(this, args); + } + + onEndInputSelect = (value) => { + const args = ['right', value, { source: 'dateInputSelect' }]; + return onInputSelect.apply(this, args); + } + onStartValueChange = (leftValue) => { const value = [...this.state.value]; value[0] = leftValue; @@ -506,7 +516,7 @@ class RangeCalendar extends React.Component { return v1.diff(v2, 'days'); } - fireSelectValueChange = (selectedValue, direct) => { + fireSelectValueChange = (selectedValue, direct, cause) => { const { timePicker } = this.props; const { prevSelectedValue } = this.state; if (timePicker && timePicker.props.defaultValue) { @@ -546,7 +556,7 @@ class RangeCalendar extends React.Component { firstSelectedValue: null, }); this.fireHoverValueChange([]); - this.props.onSelect(selectedValue); + this.props.onSelect(selectedValue, cause); } } @@ -690,6 +700,7 @@ class RangeCalendar extends React.Component { value={startValue} mode={mode[0]} placeholder={placeholder1} + onInputChange={this.onStartInputChange} onInputSelect={this.onStartInputSelect} onValueChange={this.onStartValueChange} onPanelChange={this.onStartPanelChange} @@ -711,6 +722,7 @@ class RangeCalendar extends React.Component { placeholder={placeholder2} value={endValue} mode={mode[1]} + onInputChange={this.onEndInputChange} onInputSelect={this.onEndInputSelect} onValueChange={this.onEndValueChange} onPanelChange={this.onEndPanelChange} diff --git a/src/range-calendar/CalendarPart.js b/src/range-calendar/CalendarPart.js index bfd9ce401..7ae3877eb 100644 --- a/src/range-calendar/CalendarPart.js +++ b/src/range-calendar/CalendarPart.js @@ -20,6 +20,7 @@ export default class CalendarPart extends React.Component { disabledDate: PropTypes.any, timePicker: PropTypes.any, disabledTime: PropTypes.any, + onInputChange: PropTypes.func, onInputSelect: PropTypes.func, timePickerDisabledTime: PropTypes.object, enableNext: PropTypes.any, @@ -39,7 +40,7 @@ export default class CalendarPart extends React.Component { locale, format, placeholder, disabledDate, timePicker, disabledTime, timePickerDisabledTime, showTimePicker, - onInputSelect, enablePrev, enableNext, + onInputChange, onInputSelect, enablePrev, enableNext, clearIcon, } = props; const shouldShowTimePicker = showTimePicker && timePicker; @@ -61,7 +62,7 @@ export default class CalendarPart extends React.Component { ...timePicker.props, ...disabledTimeConfig, ...timePickerDisabledTime, - onChange: onInputSelect, + onChange: onInputChange, defaultOpenValue: value, value: selectedValue[index], }); @@ -78,7 +79,8 @@ export default class CalendarPart extends React.Component { value={value} showClear={false} selectedValue={selectedValue[index]} - onChange={onInputSelect} + onChange={onInputChange} + onSelect={onInputSelect} clearIcon={clearIcon} />; diff --git a/tests/RangeCalendar.spec.jsx b/tests/RangeCalendar.spec.jsx index 61fbc3a2a..82f4de5a7 100644 --- a/tests/RangeCalendar.spec.jsx +++ b/tests/RangeCalendar.spec.jsx @@ -639,4 +639,30 @@ describe('RangeCalendar', () => { expect(onSelect.mock.calls[0][0][0].format(format)).toEqual('2000-09-30'); expect(onSelect.mock.calls[0][0][1].format(format)).toEqual('2000-09-30'); }); + + it('change input trigger calendar close', () => { + const value = [moment(), moment().add(1, 'months')]; + const onSelect = jest.fn(); + + const wrapper = mount( + + ); + + wrapper.find('input').at(0).simulate('change', { + target: { + value: '1/1/2000', + }, + }); + + expect(onSelect.mock.calls[0][1].source).toEqual('dateInput'); + + wrapper.find('input').at(0).simulate('keyDown', { + keyCode: keyCode.ENTER, + }); + expect(onSelect.mock.calls[1][1].source).toEqual('dateInputSelect'); + }); }); From 371f4cc4c9bc3f3ffa3345243690bc45e88b1a47 Mon Sep 17 00:00:00 2001 From: zombiej Date: Mon, 18 Feb 2019 09:16:01 +0800 Subject: [PATCH 043/114] bump 9.10.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9c0abcab2..7a22a345b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.10.8", + "version": "9.10.9", "description": "React Calendar", "keywords": [ "react", From 2a08e93e2ad1077d435134f6c96f3cc1d98b56b8 Mon Sep 17 00:00:00 2001 From: David Furlong Date: Wed, 20 Feb 2019 14:19:41 +0100 Subject: [PATCH 044/114] Update index.d.ts --- index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.d.ts b/index.d.ts index 027ea1095..de50e7bba 100644 --- a/index.d.ts +++ b/index.d.ts @@ -28,8 +28,8 @@ export interface Props { timePicker?: React.ReactNode; dateInputPlaceholder?: string; onClear?: () => void; - onChange?: (date: Moment) => void; - onPanelChange?: (date: Moment, mode: Mode) => void; + onChange?: (date: Moment | null) => void; + onPanelChange?: (date: Moment | null, mode: Mode) => void; disabledDate?: (current: Moment | undefined) => boolean; disabledTime?: (current: Moment | undefined) => object; dateRender?: (current: Moment, value: Moment) => React.ReactNode; From e9b9e3dcd278e64188b92878526e84279e5a9dd9 Mon Sep 17 00:00:00 2001 From: zombiej Date: Sat, 23 Feb 2019 23:28:12 +0800 Subject: [PATCH 045/114] input should also pass by disabledDate check fix ant-design/ant-design#15015 --- src/date/DateInput.js | 7 +++++-- tests/Picker.spec.jsx | 23 +++++++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/date/DateInput.js b/src/date/DateInput.js index 296ec8d8a..fbc5d9306 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -116,9 +116,12 @@ class DateInput extends React.Component { } onKeyDown = ({ keyCode }) => { - const { onSelect, value } = this.props; + const { onSelect, value, disabledDate } = this.props; if (keyCode === KeyCode.ENTER && onSelect) { - onSelect(value.clone()); + const validateDate = !disabledDate || !disabledDate(value); + if (validateDate) { + onSelect(value.clone()); + } } }; diff --git a/tests/Picker.spec.jsx b/tests/Picker.spec.jsx index 9882251ec..850920ab3 100644 --- a/tests/Picker.spec.jsx +++ b/tests/Picker.spec.jsx @@ -193,13 +193,24 @@ describe('DatePicker', () => { expect(picker.state().open).toBe(false); }); - it('close on enter of DateInput', () => { - const picker = renderPicker({ value: moment() }); - picker.find('.rc-calendar-picker-input').simulate('click'); - picker.find('.rc-calendar-input').simulate('keyDown', { - keyCode: keyCode.ENTER, + describe('DateInput', () => { + it('close on enter', () => { + const picker = renderPicker({ value: moment() }); + picker.find('.rc-calendar-picker-input').simulate('click'); + picker.find('.rc-calendar-input').simulate('keyDown', { + keyCode: keyCode.ENTER, + }); + expect(picker.state().open).toBe(false); + }); + + it('not close on enter if disabled date', () => { + const picker = renderPicker({ value: moment() }, { disabledDate: () => true }); + picker.find('.rc-calendar-picker-input').simulate('click'); + picker.find('.rc-calendar-input').simulate('keyDown', { + keyCode: keyCode.ENTER, + }); + expect(picker.state().open).toBe(true); }); - expect(picker.state().open).toBe(false); }); it('auto focuses the calendar input when opening', () => { From 856f78189aca427ce4dc099230374206d78f9a32 Mon Sep 17 00:00:00 2001 From: zombiej Date: Sat, 23 Feb 2019 23:28:43 +0800 Subject: [PATCH 046/114] bump 9.10.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7a22a345b..9b57d7755 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.10.9", + "version": "9.10.10", "description": "React Calendar", "keywords": [ "react", From 8b51af7b73ed9319f2a2140e8dba3cc25b65e3e6 Mon Sep 17 00:00:00 2001 From: alex89lj <379118572@qq.com> Date: Thu, 14 Mar 2019 21:49:09 +0800 Subject: [PATCH 047/114] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9C=88=E4=BB=BD?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E6=97=B6=E4=B8=8D=E8=83=BD=E5=8F=AA=E9=80=89?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E6=9C=88=E7=9A=84=E9=97=AE=E9=A2=98=20(#478)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 修复月份选择时不能只选一个月的问题 * 根据修复完善test * 修复开始月份禁用、修复月份判断、修改对应test --- src/RangeCalendar.js | 7 ++-- tests/RangeCalendar.spec.jsx | 32 ++++--------------- .../__snapshots__/RangeCalendar.spec.jsx.snap | 4 +-- 3 files changed, 12 insertions(+), 31 deletions(-) diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index a5c87b931..f47b5ed60 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -33,8 +33,7 @@ function isArraysEqual(a, b) { function getValueFromSelectedValue(selectedValue) { const [start, end] = selectedValue; - const newEnd = end && end.isSame(start, 'month') ? end.clone().add(1, 'month') : end; - return [start, newEnd]; + return [start, end]; } function normalizeAnchor(props, init) { @@ -593,12 +592,12 @@ class RangeCalendar extends React.Component { disabledStartMonth = (month) => { const { value } = this.state; - return month.isSameOrAfter(value[1], 'month'); + return month.isAfter(value[1], 'month'); } disabledEndMonth = (month) => { const { value } = this.state; - return month.isSameOrBefore(value[0], 'month'); + return month.isBefore(value[0], 'month'); } render() { diff --git a/tests/RangeCalendar.spec.jsx b/tests/RangeCalendar.spec.jsx index 82f4de5a7..7ed1f6749 100644 --- a/tests/RangeCalendar.spec.jsx +++ b/tests/RangeCalendar.spec.jsx @@ -119,46 +119,28 @@ describe('RangeCalendar', () => { expect(wrapper.find('.rc-calendar-range-right .rc-calendar-next-month-btn').length).toBe(1); }); - it('left panel cannot select month same or after right panel', () => { + it('left panel cannot select month after right panel', () => { const wrapper = mount(); wrapper.find('.rc-calendar-range-left .rc-calendar-month-select').simulate('click'); const monthCells = wrapper.find('.rc-calendar-range-left .rc-calendar-month-panel-cell'); const rightPanelMonth = wrapper.state('value')[1].month(); expect(monthCells.get(rightPanelMonth).props.className) - .toMatch('rc-calendar-month-panel-cell-disabled'); + .toMatch('rc-calendar-month-panel-cell'); expect(monthCells.get(rightPanelMonth + 1).props.className) .toMatch('rc-calendar-month-panel-cell-disabled'); }); - it('right panel cannot select month same or before left panel', () => { + it('right panel cannot select month before left panel', () => { const wrapper = mount(); wrapper.find('.rc-calendar-range-right .rc-calendar-month-select').simulate('click'); const monthCells = wrapper.find('.rc-calendar-range-right .rc-calendar-month-panel-cell'); const leftPanelMonth = wrapper.state('value')[0].month(); expect(monthCells.get(leftPanelMonth).props.className) - .toMatch('rc-calendar-month-panel-cell-disabled'); + .toMatch('rc-calendar-month-panel-cell rc-calendar-month-panel-current-cell'); expect(monthCells.get(leftPanelMonth - 1).props.className) .toMatch('rc-calendar-month-panel-cell-disabled'); }); - it('left panel and right panel should not be the same month even we try to set it', () => { - const wrapper = mount(); - const value = wrapper.state('value'); - expect(value[0].isSame(moment())).toBe(true); - expect(value[1].isSame(moment().add(1, 'month'))).toBe(true); - }); - - it('left panel and right panel should not be the same month', () => { - const wrapper = mount(); - wrapper.find('.rc-calendar-range-left .rc-calendar-today').simulate('click').simulate('click'); - const selectedValue = wrapper.state('selectedValue'); - expect(selectedValue[0].isSame(moment())).toBe(true); - expect(selectedValue[1].isSame(moment())).toBe(true); - const value = wrapper.state('value'); - expect(value[0].isSame(moment())).toBe(true); - expect(value[1].isSame(moment().add(1, 'month'))).toBe(true); - }); - it('onSelect works', () => { function onSelect(d) { expect(d[0].format(format)).toBe('2015-09-04'); @@ -303,7 +285,7 @@ describe('RangeCalendar', () => { }; } const timePicker = ; - const wrapper = mount(); + const wrapper = mount(); wrapper.find('.rc-calendar-today').at(0).simulate('click').simulate('click'); wrapper.find('.rc-calendar-today').at(0).simulate('click').simulate('click'); @@ -490,11 +472,11 @@ describe('RangeCalendar', () => { it('controlled value works correctly', () => { const wrapper = mount(); const initialValue = wrapper.state('value'); - expect(initialValue[0].add(1, 'month').isSame(initialValue[1], 'month')).toBe(true); + expect(initialValue[0].isSame(initialValue[1], 'month')).toBe(true); wrapper.setProps({ value: [moment(), moment()] }); const updatedValue = wrapper.state('value'); - expect(updatedValue[0].add(1, 'month').isSame(updatedValue[1], 'month')).toBe(true); + expect(updatedValue[0].isSame(updatedValue[1], 'month')).toBe(true); }); }); diff --git a/tests/__snapshots__/RangeCalendar.spec.jsx.snap b/tests/__snapshots__/RangeCalendar.spec.jsx.snap index 7f5016de0..8735dae14 100644 --- a/tests/__snapshots__/RangeCalendar.spec.jsx.snap +++ b/tests/__snapshots__/RangeCalendar.spec.jsx.snap @@ -1626,7 +1626,7 @@ exports[`RangeCalendar controlled panels render controlled panels correctly 1`] role="row" > @@ -2551,7 +2551,7 @@ exports[`RangeCalendar controlled panels render controlled panels correctly 1`] From 3039ebbe68dfbcd9a65c3e084f7c8988ec841867 Mon Sep 17 00:00:00 2001 From: zombiej Date: Thu, 14 Mar 2019 21:53:18 +0800 Subject: [PATCH 048/114] bump 9.10.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9b57d7755..0c5d7d14f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.10.10", + "version": "9.10.11", "description": "React Calendar", "keywords": [ "react", From 720f12774e3f82c5d5bc004c0e5474c2d8d58192 Mon Sep 17 00:00:00 2001 From: zombiej Date: Thu, 14 Mar 2019 22:05:07 +0800 Subject: [PATCH 049/114] bump 9.11.0 --- HISTORY.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 62820f76e..e95df2093 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,10 @@ # History ---- +## 9.11.0 / 2019-03-14 + +- RangerPicker can select same month + ## 9.10.0 / 2019-01-02 - add `focusablePanel` prop. diff --git a/package.json b/package.json index 0c5d7d14f..6b334243b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.10.11", + "version": "9.11.0", "description": "React Calendar", "keywords": [ "react", From deb7c952200154467031f07eef4ccb8c76de63bc Mon Sep 17 00:00:00 2001 From: ztplz Date: Sat, 16 Mar 2019 12:51:48 +0800 Subject: [PATCH 050/114] Support start time or end time could be null in defaultValue (#520) * Support start time or end time could be null in defaultValue * Add missing brackets * Support undefined --- src/RangeCalendar.js | 9 ++++++- src/date/DateTBody.jsx | 8 +++++- tests/RangeCalendar.spec.jsx | 48 ++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index f47b5ed60..6d02d37b2 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -32,7 +32,14 @@ function isArraysEqual(a, b) { } function getValueFromSelectedValue(selectedValue) { - const [start, end] = selectedValue; + let [start, end] = selectedValue; + if (end && (start === undefined || start === null)) { + start = end.clone().subtract(1, 'month'); + } + + if (start && (end === undefined || end === null)) { + end = start.clone().add(1, 'month'); + } return [start, end]; } diff --git a/src/date/DateTBody.jsx b/src/date/DateTBody.jsx index 27dd33977..21ebc70e0 100644 --- a/src/date/DateTBody.jsx +++ b/src/date/DateTBody.jsx @@ -144,11 +144,17 @@ export default class DateTBody extends React.Component { cls += ` ${selectedStartDateClass}`; } } - if (startValue && endValue) { + if (startValue || endValue) { if (isSameDay(current, endValue)) { selected = true; isActiveWeek = true; cls += ` ${selectedEndDateClass}`; + } else if ((startValue === null || startValue === undefined) && + current.isBefore(endValue, 'day')) { + cls += ` ${inRangeClass}`; + } else if ((endValue === null || endValue === undefined) && + current.isAfter(startValue, 'day')) { + cls += ` ${inRangeClass}`; } else if (current.isAfter(startValue, 'day') && current.isBefore(endValue, 'day')) { cls += ` ${inRangeClass}`; diff --git a/tests/RangeCalendar.spec.jsx b/tests/RangeCalendar.spec.jsx index 7ed1f6749..f377c401c 100644 --- a/tests/RangeCalendar.spec.jsx +++ b/tests/RangeCalendar.spec.jsx @@ -416,6 +416,54 @@ describe('RangeCalendar', () => { expect(RangeYearPicker.find('.rc-calendar-year-panel').length).toBe(2); }); + it('should work when start time is null in defaultValue', () => { + let wrapper = null; + wrapper = mount(); + wrapper.find('.rc-calendar-range-right .rc-calendar-month-select').simulate('click'); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-year-btn').length).toBe(1); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-month-btn').length).toBe(1); + wrapper = mount(); + wrapper.find('.rc-calendar-range-right .rc-calendar-year-select').simulate('click'); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-year-btn').length).toBe(1); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-month-btn').length).toBe(1); + }); + + it('should work when end time is null in defaultValue', () => { + let wrapper = null; + wrapper = mount(); + wrapper.find('.rc-calendar-range-right .rc-calendar-month-select').simulate('click'); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-year-btn').length).toBe(1); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-month-btn').length).toBe(1); + wrapper = mount(); + wrapper.find('.rc-calendar-range-right .rc-calendar-year-select').simulate('click'); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-year-btn').length).toBe(1); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-month-btn').length).toBe(1); + }); + + it('should work when start time is undefined in defaultValue', () => { + let wrapper = null; + wrapper = mount(); + wrapper.find('.rc-calendar-range-right .rc-calendar-month-select').simulate('click'); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-year-btn').length).toBe(1); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-month-btn').length).toBe(1); + wrapper = mount(); + wrapper.find('.rc-calendar-range-right .rc-calendar-year-select').simulate('click'); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-year-btn').length).toBe(1); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-month-btn').length).toBe(1); + }); + + it('should work when end time is undefined in defaultValue', () => { + let wrapper = null; + wrapper = mount(); + wrapper.find('.rc-calendar-range-right .rc-calendar-month-select').simulate('click'); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-year-btn').length).toBe(1); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-month-btn').length).toBe(1); + wrapper = mount(); + wrapper.find('.rc-calendar-range-right .rc-calendar-year-select').simulate('click'); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-year-btn').length).toBe(1); + expect(wrapper.find('.rc-calendar-range-left .rc-calendar-next-month-btn').length).toBe(1); + }); + it('support controlled mode', () => { let value = null; class ControlledRangeCalendar extends React.Component { From 4252e5f053a651f8bde65c948a9fddb6d1ae42f9 Mon Sep 17 00:00:00 2001 From: zombiej Date: Sat, 16 Mar 2019 12:53:01 +0800 Subject: [PATCH 051/114] bump 9.12.0 --- HISTORY.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index e95df2093..0dcf833a7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,10 @@ # History ---- +## 9.12.0 / 2019-03-16 + +- RangerPicker support null as start or end + ## 9.11.0 / 2019-03-14 - RangerPicker can select same month diff --git a/package.json b/package.json index 6b334243b..df7a169eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.11.0", + "version": "9.12.0", "description": "React Calendar", "keywords": [ "react", From 4de9b499c80bba3aef2c6b7448bb0e0c286169be Mon Sep 17 00:00:00 2001 From: Franjo Date: Mon, 25 Mar 2019 17:56:22 +0100 Subject: [PATCH 052/114] Added Croatian localization --- src/locale/hr_HR.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/locale/hr_HR.js diff --git a/src/locale/hr_HR.js b/src/locale/hr_HR.js new file mode 100644 index 000000000..670c6cb02 --- /dev/null +++ b/src/locale/hr_HR.js @@ -0,0 +1,28 @@ +export default { + today: 'Danas', + now: 'Sad', + backToToday: 'Natrag na danas', + ok: 'Ok', + clear: 'Očisti', + month: 'Mjesec', + year: 'Godina', + timeSelect: 'odaberite vrijeme', + dateSelect: 'odaberite datum', + weekSelect: 'Odaberite tjedan', + monthSelect: 'Odaberite mjesec', + yearSelect: 'Odaberite godinu', + decadeSelect: 'Odaberite desetljeće', + yearFormat: 'YYYY', + dateFormat: 'D.M.YYYY', + dayFormat: 'D', + dateTimeFormat: 'D.M.YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Prošli mjesec (PageUp)', + nextMonth: 'Sljedeći mjesec (PageDown)', + previousYear: 'Prošla godina (Control + left)', + nextYear: 'Sljedeća godina (Control + right)', + previousDecade: 'Prošlo desetljeće', + nextDecade: 'Sljedeće desetljeće', + previousCentury: 'Prošlo stoljeće', + nextCentury: 'Sljedeće stoljeće', +}; From da421297a4263d7069ea0cd3f47bd9a034a64a57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 25 Mar 2019 21:19:13 +0000 Subject: [PATCH 053/114] Update dtslint requirement from ^0.3.0 to ^0.5.7 Updates the requirements on [dtslint](https://github.com/Microsoft/dtslint) to permit the latest version. - [Release notes](https://github.com/Microsoft/dtslint/releases) - [Commits](https://github.com/Microsoft/dtslint/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index df7a169eb..696a2c9c4 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "@types/react": "^16.3.13", "async": "~2.5.0", "bootstrap": "~3.3.2", - "dtslint": "^0.3.0", + "dtslint": "^0.5.7", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", "enzyme-to-json": "^3.3.1", From 984ece6f695e0a276f0b90ed4230fd76198bc2a5 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sat, 30 Mar 2019 20:33:15 +0800 Subject: [PATCH 054/114] 9.12.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 696a2c9c4..2823055bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.12.0", + "version": "9.12.1", "description": "React Calendar", "keywords": [ "react", From d2788f3121a4b1123c2648cdd431d7c5021cebac Mon Sep 17 00:00:00 2001 From: zombiej Date: Mon, 1 Apr 2019 20:36:34 +0800 Subject: [PATCH 055/114] fix RangePicker update logic fix https://github.com/ant-design/ant-design/issues/15659 --- package.json | 2 +- src/RangeCalendar.js | 4 ++-- tests/RangeCalendar.spec.jsx | 37 +++++++++++++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 2823055bc..aa32ce717 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.12.1", + "version": "9.12.2", "description": "React Calendar", "keywords": [ "react", diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index 6d02d37b2..2d9635624 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -418,7 +418,7 @@ class RangeCalendar extends React.Component { } static getDerivedStateFromProps(nextProps, state) { - let newState = {}; + const newState = {}; if ('value' in nextProps) { newState.value = normalizeAnchor(nextProps, 0); } @@ -430,7 +430,7 @@ class RangeCalendar extends React.Component { newState.prevSelectedValue = nextProps.selectedValue; } if ('mode' in nextProps && !isArraysEqual(state.mode, nextProps.mode)) { - newState = { mode: nextProps.mode }; + newState.mode = nextProps.mode; } return newState; } diff --git a/tests/RangeCalendar.spec.jsx b/tests/RangeCalendar.spec.jsx index f377c401c..fca9d3f25 100644 --- a/tests/RangeCalendar.spec.jsx +++ b/tests/RangeCalendar.spec.jsx @@ -1,4 +1,4 @@ -/* eslint-disable no-undef, max-len */ +/* eslint-disable no-undef, max-len, react/no-multi-comp */ import React from 'react'; import moment from 'moment'; import { mount, render } from 'enzyme'; @@ -526,6 +526,41 @@ describe('RangeCalendar', () => { const updatedValue = wrapper.state('value'); expect(updatedValue[0].isSame(updatedValue[1], 'month')).toBe(true); }); + + // https://github.com/ant-design/ant-design/issues/15659 + it('controlled value works correctly with mode', () => { + class Demo extends React.Component { + state = { + mode: ['month', 'month'], + value: [moment().add(-1, 'day'), moment()], + }; + + handlePanelChange = (value, mode) => { + this.setState({ + value, + mode: [mode[0] === 'date' ? 'month' : mode[0], mode[1] === 'date' ? 'month' : mode[1]], + }); + }; + + render() { + return ( + + ); + } + } + + const wrapper = mount(); + wrapper.find('.rc-calendar-month-panel-year-select').first().simulate('click'); + wrapper.find('.rc-calendar-year-panel-cell').at(1).simulate('click'); + expect( + wrapper.find('.rc-calendar-month-panel-year-select-content').first(0).text() + ).toBe('2010'); + }); }); it('can hide date inputs with showDateInput={false}', () => { From 18e0885bda0605f259e1e7240bf139519a1b7b69 Mon Sep 17 00:00:00 2001 From: zombiej Date: Mon, 1 Apr 2019 20:37:32 +0800 Subject: [PATCH 056/114] bump 9.12.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aa32ce717..7127d9059 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.12.2", + "version": "9.12.3", "description": "React Calendar", "keywords": [ "react", From b68c3e4416b6b17290107562efb8edbef5f42ac0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 1 Apr 2019 21:17:18 +0000 Subject: [PATCH 057/114] Update typescript requirement from ^2.8.3 to ^3.4.1 Updates the requirements on [typescript](https://github.com/Microsoft/TypeScript) to permit the latest version. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Commits](https://github.com/Microsoft/TypeScript/compare/v2.8.3...v3.4.1) Signed-off-by: dependabot[bot] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7127d9059..b9b1f77f7 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "react-dom": "^16.5.2", "react-test-renderer": "^16.0.0", "tslint": "^5.9.1", - "typescript": "^2.8.3" + "typescript": "^3.4.1" }, "pre-commit": [ "lint" From 46fc91eaffece4486cc60d25821f3745a444878f Mon Sep 17 00:00:00 2001 From: Yann Normand Date: Tue, 2 Apr 2019 18:56:27 +1000 Subject: [PATCH 058/114] Close calendar picker on blur (#495) * Close calendar picker on Tab for unfocusable panel * close date picker on blur * access elements in onBlur setTimeout --- examples/antd-calendar.js | 27 +++++++++++++- src/Calendar.jsx | 19 +++++++++- src/Picker.jsx | 7 ++++ src/mixin/CalendarMixin.js | 1 + tests/Picker.spec.jsx | 76 +++++++++++++++++++++++++++++++++++++- 5 files changed, 125 insertions(+), 5 deletions(-) diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index 7a3bc37c1..2d2e64cbc 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -73,10 +73,13 @@ class Demo extends React.Component { constructor(props) { super(props); + this.calendarContainerRef = React.createRef(); + this.state = { showTime: true, showDateInput: true, disabled: false, + open: false, value: props.defaultValue, }; } @@ -100,6 +103,20 @@ class Demo extends React.Component { }); } + onOpenChange = (open) => { + this.setState({ + open, + }); + } + + onReadOnlyFocus = () => { + this.setState({ + open: true, + }); + } + + getCalendarContainer = () => this.calendarContainerRef.current; + toggleDisabled = () => { this.setState({ disabled: !this.state.disabled, @@ -110,7 +127,7 @@ class Demo extends React.Component { const state = this.state; const calendar = (); return (
@@ -161,11 +179,15 @@ class Demo extends React.Component { calendar={calendar} value={state.value} onChange={this.onChange} + getCalendarContainer={this.getCalendarContainer} + onOpenChange={this.onOpenChange} + open={state.open} + style={{ zIndex: 1001 }} > { ({ value }) => { return ( - + +
); } diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 6b184cc6f..48585fd64 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -53,6 +53,7 @@ class Calendar extends React.Component { renderSidebar: PropTypes.func, clearIcon: PropTypes.node, focusablePanel: PropTypes.bool, + onBlur: PropTypes.func, } static defaultProps = { @@ -66,7 +67,6 @@ class Calendar extends React.Component { focusablePanel: true, } - constructor(props) { super(props); @@ -203,6 +203,23 @@ class Calendar extends React.Component { }); } + onBlur = (event) => { + setTimeout(() => { + const dateInput = DateInput.getInstance(); + const rootInstance = this.rootInstance; + + if (!rootInstance || rootInstance.contains(document.activeElement) || + (dateInput && dateInput.contains(document.activeElement))) { + // focused element is still part of Calendar + return; + } + + if (this.props.onBlur) { + this.props.onBlur(event); + } + }, 0); + } + static getDerivedStateFromProps(nextProps, state) { const { value, selectedValue } = nextProps; let newState = {}; diff --git a/src/Picker.jsx b/src/Picker.jsx index 955dc1ac8..5f0748ce9 100644 --- a/src/Picker.jsx +++ b/src/Picker.jsx @@ -38,6 +38,7 @@ class Picker extends React.Component { PropTypes.array, ]), align: PropTypes.object, + onBlur: PropTypes.func, } static defaultProps = { @@ -48,6 +49,7 @@ class Picker extends React.Component { defaultOpen: false, onChange: noop, onOpenChange: noop, + onBlur: noop, } constructor(props) { @@ -118,6 +120,10 @@ class Picker extends React.Component { this.close(this.focus); } + onCalendarBlur = () => { + this.setOpen(false); + } + onVisibleChange = (open) => { this.setOpen(open); } @@ -148,6 +154,7 @@ class Picker extends React.Component { onOk: createChainedFunction(calendarProps.onOk, this.onCalendarOk), onSelect: createChainedFunction(calendarProps.onSelect, this.onCalendarSelect), onClear: createChainedFunction(calendarProps.onClear, this.onCalendarClear), + onBlur: createChainedFunction(calendarProps.onBlur, this.onCalendarBlur), }; return React.cloneElement(props.calendar, extraProps); diff --git a/src/mixin/CalendarMixin.js b/src/mixin/CalendarMixin.js index 72e8f52e1..49a2fe3eb 100644 --- a/src/mixin/CalendarMixin.js +++ b/src/mixin/CalendarMixin.js @@ -76,6 +76,7 @@ export const calendarMixinWrapper = ComposeComponent => class extends ComposeCom style={this.props.style} tabIndex="0" onKeyDown={this.onKeyDown} + onBlur={this.onBlur} > {newProps.children}
diff --git a/tests/Picker.spec.jsx b/tests/Picker.spec.jsx index 850920ab3..2eed444d6 100644 --- a/tests/Picker.spec.jsx +++ b/tests/Picker.spec.jsx @@ -33,7 +33,7 @@ describe('DatePicker', () => { />); } - function renderPicker(props, calendarProps) { + function renderPicker(props, calendarProps, options) { return mount( { {...props} > {renderOne} - + , + options ); } @@ -213,6 +214,77 @@ describe('DatePicker', () => { }); }); + describe('on picker blur', () => { + let container; + + beforeEach(() => { + jest.useFakeTimers(); + container = document.createElement('div'); + container.setAttribute('tabindex', 0); + document.body.appendChild(container); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('close panel when focus is outside of picker', () => { + const picker = renderPicker({ value: moment() }, undefined, { + attachTo: container, + }); + picker.find('.rc-calendar-picker-input').simulate('click'); + + jest.runAllTimers(); + container.focus(); + jest.runAllTimers(); + expect(picker.state().open).toBe(false); + }); + + it('call onBlur when focus is outside of picker', () => { + const handleOnBlur = jest.fn(); + const picker = renderPicker({ value: moment() }, { onBlur: handleOnBlur }, { + attachTo: container, + }); + + picker.find('.rc-calendar-picker-input').simulate('click'); + jest.runAllTimers(); + container.focus(); + jest.runAllTimers(); + expect(handleOnBlur).toBeCalled(); + }); + + it('keep panel opened when clicking on calendar next month', () => { + const picker = renderPicker({ value: moment() }, undefined, { + attachTo: container, + }); + + picker.find('.rc-calendar-picker-input').simulate('click'); + + jest.runAllTimers(); + const day = picker.find('.rc-calendar-next-month-btn'); + day.simulate('click'); + jest.runAllTimers(); + + expect(picker.state().open).toBe(true); + }); + + it('does not call onBlur when clicking on calendar next month', () => { + const handleOnBlur = jest.fn(); + const picker = renderPicker({ value: moment() }, { onBlur: handleOnBlur }, { + attachTo: container, + }); + + picker.find('.rc-calendar-picker-input').simulate('click'); + jest.runAllTimers(); + + const day = picker.find('.rc-calendar-next-month-btn'); + day.simulate('click'); + jest.runAllTimers(); + + expect(handleOnBlur).not.toBeCalled(); + }); + }); + it('auto focuses the calendar input when opening', () => { jest.useFakeTimers(); const picker = renderPicker({ value: moment() }); From 6cefda5a5d3da7424b2bec257dde13fb43290488 Mon Sep 17 00:00:00 2001 From: zombiej Date: Tue, 2 Apr 2019 16:57:59 +0800 Subject: [PATCH 059/114] bump --- HISTORY.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 0dcf833a7..13665b7ff 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,10 @@ # History ---- +## 9.13.0 / 2019-04-02 + +- Support close onBlur + ## 9.12.0 / 2019-03-16 - RangerPicker support null as start or end diff --git a/package.json b/package.json index b9b1f77f7..479b61b6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.12.3", + "version": "9.13.0", "description": "React Calendar", "keywords": [ "react", From bcfb284d2cf4ffe1a052c3458ae342ac1a0343eb Mon Sep 17 00:00:00 2001 From: zombieJ Date: Mon, 8 Apr 2019 23:50:34 +0800 Subject: [PATCH 060/114] fix: Adjust date panel display logic in RangePicker (#549) * record prev trigger panel * add test case * always record last trigger --- src/RangeCalendar.js | 63 ++++++++++++++++++++++++------------ tests/RangeCalendar.spec.jsx | 22 +++++++++++++ 2 files changed, 65 insertions(+), 20 deletions(-) diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index 2d9635624..3cf140a25 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -137,6 +137,7 @@ class RangeCalendar extends React.Component { value, showTimePicker: false, mode: props.mode || ['date', 'date'], + panelTriggerSource: '', // Trigger by which picker panel: 'start' & 'end' }; } @@ -396,11 +397,13 @@ class RangeCalendar extends React.Component { onStartPanelChange = (value, mode) => { const { props, state } = this; const newMode = [mode, state.mode[1]]; + const newState = { + panelTriggerSource: 'start', + }; if (!('mode' in props)) { - this.setState({ - mode: newMode, - }); + newState.mode = newMode; } + this.setState(newState); const newValue = [value || state.value[0], state.value[1]]; props.onPanelChange(newValue, newMode); } @@ -408,11 +411,13 @@ class RangeCalendar extends React.Component { onEndPanelChange = (value, mode) => { const { props, state } = this; const newMode = [state.mode[0], mode]; + const newState = { + panelTriggerSource: 'end', + }; if (!('mode' in props)) { - this.setState({ - mode: newMode, - }); + newState.mode = newMode; } + this.setState(newState); const newValue = [state.value[0], value || state.value[1]]; props.onPanelChange(newValue, newMode); } @@ -436,29 +441,51 @@ class RangeCalendar extends React.Component { } getStartValue = () => { - let value = this.state.value[0]; - const selectedValue = this.state.selectedValue; + const { selectedValue, showTimePicker, value, mode, panelTriggerSource } = this.state; + let startValue = value[0]; // keep selectedTime when select date if (selectedValue[0] && this.props.timePicker) { - value = value.clone(); - syncTime(selectedValue[0], value); + startValue = startValue.clone(); + syncTime(selectedValue[0], startValue); } - if (this.state.showTimePicker && selectedValue[0]) { - return selectedValue[0]; + if (showTimePicker && selectedValue[0]) { + startValue = selectedValue[0]; } - return value; + + // Adjust month if date not align + if ( + panelTriggerSource === 'end' && + mode[0] === 'date' && + mode[1] === 'date' && + startValue.isSame(value[1], 'month') + ) { + startValue = startValue.clone().subtract(1, 'month'); + } + + return startValue; } getEndValue = () => { - const { value, selectedValue, showTimePicker } = this.state; - const endValue = value[1] ? value[1].clone() : value[0].clone().add(1, 'month'); + const { value, selectedValue, showTimePicker, mode, panelTriggerSource } = this.state; + let endValue = value[1] ? value[1].clone() : value[0].clone().add(1, 'month'); // keep selectedTime when select date if (selectedValue[1] && this.props.timePicker) { syncTime(selectedValue[1], endValue); } if (showTimePicker) { - return selectedValue[1] ? selectedValue[1] : this.getStartValue(); + endValue = selectedValue[1] ? selectedValue[1] : this.getStartValue(); + } + + // Adjust month if date not align + if ( + panelTriggerSource !== 'end' && + mode[0] === 'date' && + mode[1] === 'date' && + endValue.isSame(value[0], 'month') + ) { + endValue = endValue.clone().add(1, 'month'); } + return endValue; } @@ -666,10 +693,6 @@ class RangeCalendar extends React.Component { const isClosestMonths = nextMonthOfStart.year() === endValue.year() && nextMonthOfStart.month() === endValue.month(); - // console.warn('Render:', selectedValue.map(t => t.format('YYYY-MM-DD')).join(', ')); - // console.log('start:', startValue.format('YYYY-MM-DD')); - // console.log('end:', endValue.format('YYYY-MM-DD')); - const extraFooter = props.renderFooter(); return ( diff --git a/tests/RangeCalendar.spec.jsx b/tests/RangeCalendar.spec.jsx index fca9d3f25..848832b18 100644 --- a/tests/RangeCalendar.spec.jsx +++ b/tests/RangeCalendar.spec.jsx @@ -730,4 +730,26 @@ describe('RangeCalendar', () => { }); expect(onSelect.mock.calls[1][1].source).toEqual('dateInputSelect'); }); + + it('date mode should not display same month', () => { + const FORMAT = 'YYYY-MM-DD'; + const sameDay = moment('2000-01-01'); + const wrapper = mount(); + + // Should in different month + expect(wrapper.find('CalendarPart').at(0).props().value.format(FORMAT)).toEqual('2000-01-01'); + expect(wrapper.find('CalendarPart').at(1).props().value.format(FORMAT)).toEqual('2000-02-01'); + + // Back end to month panel + wrapper.find('CalendarPart').at(1).find('.rc-calendar-month-select').simulate('click'); + wrapper.find('CalendarPart').at(1).find('.rc-calendar-month-panel-month').at(0).simulate('click'); + expect(wrapper.find('CalendarPart').at(0).props().value.format(FORMAT)).toEqual('1999-12-01'); + expect(wrapper.find('CalendarPart').at(1).props().value.format(FORMAT)).toEqual('2000-01-01'); + + // Back start to month panel + wrapper.find('CalendarPart').at(0).find('.rc-calendar-month-select').simulate('click'); + wrapper.find('CalendarPart').at(0).find('.rc-calendar-month-panel-month').at(0).simulate('click'); + expect(wrapper.find('CalendarPart').at(0).props().value.format(FORMAT)).toEqual('2000-01-01'); + expect(wrapper.find('CalendarPart').at(1).props().value.format(FORMAT)).toEqual('2000-02-01'); + }); }); From 87417bd0f897eaf74132b6df780efef9f36588dc Mon Sep 17 00:00:00 2001 From: zombiej Date: Mon, 8 Apr 2019 23:53:51 +0800 Subject: [PATCH 061/114] bump 9.13.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 479b61b6f..60f8ea404 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.13.0", + "version": "9.13.1", "description": "React Calendar", "keywords": [ "react", From fb140f4f4740ce11c1d888223cadc29605ca821b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 9 Apr 2019 21:24:19 +0000 Subject: [PATCH 062/114] Update dtslint requirement from ^0.5.7 to ^0.6.1 Updates the requirements on [dtslint](https://github.com/Microsoft/dtslint) to permit the latest version. - [Release notes](https://github.com/Microsoft/dtslint/releases) - [Commits](https://github.com/Microsoft/dtslint/commits) Signed-off-by: dependabot[bot] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 60f8ea404..03ea34323 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "@types/react": "^16.3.13", "async": "~2.5.0", "bootstrap": "~3.3.2", - "dtslint": "^0.5.7", + "dtslint": "^0.6.1", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", "enzyme-to-json": "^3.3.1", From 6fac6a87e37fc8f16d85b704a2f0981dcbae948d Mon Sep 17 00:00:00 2001 From: susiwen8 Date: Mon, 29 Apr 2019 13:36:29 +0800 Subject: [PATCH 063/114] Rearrange getEndValue logic (#556) * Rearrange getEndValue logic * Rewrite one test case --- src/RangeCalendar.js | 1 + tests/RangeCalendar.spec.jsx | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index 3cf140a25..68147f710 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -478,6 +478,7 @@ class RangeCalendar extends React.Component { // Adjust month if date not align if ( + !showTimePicker && panelTriggerSource !== 'end' && mode[0] === 'date' && mode[1] === 'date' && diff --git a/tests/RangeCalendar.spec.jsx b/tests/RangeCalendar.spec.jsx index 848832b18..932f1ee3e 100644 --- a/tests/RangeCalendar.spec.jsx +++ b/tests/RangeCalendar.spec.jsx @@ -211,6 +211,18 @@ describe('RangeCalendar', () => { } }); + it('selected start and end date can be same', () => { + const timePicker = ; + const wrapper = mount(); + wrapper.find('.rc-calendar-time-picker-btn').simulate('click'); + expect(wrapper.find('.rc-calendar-year-select').at(0).text()).toBe('2000'); + expect(wrapper.find('.rc-calendar-month-select').at(0).text()).toBe('Sep'); + expect(wrapper.find('.rc-calendar-day-select').at(0).text()).toBe('3'); + expect(wrapper.find('.rc-calendar-year-select').at(1).text()).toBe('2000'); + expect(wrapper.find('.rc-calendar-month-select').at(1).text()).toBe('Sep'); + expect(wrapper.find('.rc-calendar-day-select').at(1).text()).toBe('3'); + }); + it('use timePicker\'s time', () => { const timePicker = ; const wrapper = mount(); From dcc3a76a07f426a089566d4c60587cad6f0e2f17 Mon Sep 17 00:00:00 2001 From: zombiej Date: Mon, 29 Apr 2019 13:37:01 +0800 Subject: [PATCH 064/114] bump 9.13.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 03ea34323..da08c4915 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.13.1", + "version": "9.13.2", "description": "React Calendar", "keywords": [ "react", From baee7886a844b98ac970b19f442316eefa56b8da Mon Sep 17 00:00:00 2001 From: susiwen8 Date: Thu, 9 May 2019 10:58:34 +0800 Subject: [PATCH 065/114] Fix Keyboard cannot control month calendar (#561) * Fix MonthPicker keyboard change not response * Add test case * Change props name --- src/calendar/CalendarHeader.jsx | 11 ++++++++++- src/month/MonthPanel.jsx | 16 +++++----------- tests/MonthCalendar.spec.js | 6 ++++++ 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/calendar/CalendarHeader.jsx b/src/calendar/CalendarHeader.jsx index 77862f173..a7eccfc17 100644 --- a/src/calendar/CalendarHeader.jsx +++ b/src/calendar/CalendarHeader.jsx @@ -75,6 +75,14 @@ export default class CalendarHeader extends React.Component { this.props.onValueChange(value); } + changeYear = (direction) => { + if (direction > 0) { + this.nextYear(); + } else { + this.previousYear(); + } + } + monthYearElement = (showTimePicker) => { const props = this.props; const prefixCls = props.prefixCls; @@ -153,7 +161,7 @@ export default class CalendarHeader extends React.Component { panel = ( this.showYearPanel('month')} @@ -161,6 +169,7 @@ export default class CalendarHeader extends React.Component { cellRender={props.monthCellRender} contentRender={props.monthCellContentRender} renderFooter={renderFooter} + changeYear={this.changeYear} /> ); } diff --git a/src/month/MonthPanel.jsx b/src/month/MonthPanel.jsx index 875db4122..5913ef59c 100644 --- a/src/month/MonthPanel.jsx +++ b/src/month/MonthPanel.jsx @@ -4,9 +4,7 @@ import { polyfill } from 'react-lifecycles-compat'; import MonthTable from './MonthTable'; function goYear(direction) { - const next = this.state.value.clone(); - next.add(direction, 'year'); - this.setAndChangeValue(next); + this.props.changeYear(direction); } function noop() { @@ -41,22 +39,18 @@ class MonthPanel extends React.Component { }; } - static getDerivedStateFromProps(nextProps) { + static getDerivedStateFromProps(props) { let newState = {}; - if ('value' in nextProps) { + if ('value' in props) { newState = { - value: nextProps.value, + value: props.value, }; } return newState; } - setAndChangeValue = (value) => { - this.setValue(value); - this.props.onChange(value); - } setAndSelectValue = (value) => { this.setValue(value); @@ -64,7 +58,7 @@ class MonthPanel extends React.Component { } setValue = (value) => { - if (!('value' in this.props)) { + if ('value' in this.props) { this.setState({ value, }); diff --git a/tests/MonthCalendar.spec.js b/tests/MonthCalendar.spec.js index 2557ad102..40e091024 100644 --- a/tests/MonthCalendar.spec.js +++ b/tests/MonthCalendar.spec.js @@ -87,6 +87,8 @@ describe('MonthCalendar', () => { }); expect(wrapper.state().value.month()).toBe(4); expect(wrapper.state().value.year()).toBe(2016); + const selectedYear = wrapper.find('.rc-calendar-month-panel-year-select-content'); + expect(selectedYear.at(0).text()).toBe('2016'); }); it('CTRL + RIGHT', () => { @@ -96,6 +98,8 @@ describe('MonthCalendar', () => { }); expect(wrapper.state().value.month()).toBe(4); expect(wrapper.state().value.year()).toBe(2018); + const selectedYear = wrapper.find('.rc-calendar-month-panel-year-select-content'); + expect(selectedYear.at(0).text()).toBe('2018'); }); it('ignore other keys', () => { @@ -104,6 +108,8 @@ describe('MonthCalendar', () => { }); expect(wrapper.state().value.month()).toBe(4); expect(wrapper.state().value.year()).toBe(2017); + const selectedYear = wrapper.find('.rc-calendar-month-panel-year-select-content'); + expect(selectedYear.at(0).text()).toBe('2017'); }); }); From 0b70c1009ef0621c31e3f94c8a2c33aaa32d3f9a Mon Sep 17 00:00:00 2001 From: zombiej Date: Thu, 9 May 2019 10:59:43 +0800 Subject: [PATCH 066/114] bump 9.13.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index da08c4915..777ef4c04 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.13.2", + "version": "9.13.3", "description": "React Calendar", "keywords": [ "react", From 2b2b2e8e42d1eeb5ca7106d40633cbf7daea8734 Mon Sep 17 00:00:00 2001 From: susiwen8 Date: Thu, 16 May 2019 11:10:59 +0800 Subject: [PATCH 067/114] RangePicker support time mode (#571) * RangePicker support time mode * Add test case * Remove useless code --- src/RangeCalendar.js | 6 +++--- tests/RangeCalendar.spec.jsx | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index 68147f710..6c9a62b5e 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -87,7 +87,7 @@ class RangeCalendar extends React.Component { defaultValue: PropTypes.any, value: PropTypes.any, hoverValue: PropTypes.any, - mode: PropTypes.arrayOf(PropTypes.oneOf(['date', 'month', 'year', 'decade'])), + mode: PropTypes.arrayOf(PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade'])), showDateInput: PropTypes.bool, timePicker: PropTypes.any, showOk: PropTypes.bool, @@ -736,7 +736,7 @@ class RangeCalendar extends React.Component { onPanelChange={this.onStartPanelChange} showDateInput={this.props.showDateInput} timePicker={timePicker} - showTimePicker={showTimePicker} + showTimePicker={showTimePicker || mode[0] === 'time'} enablePrev enableNext={!isClosestMonths || this.isMonthYearPanelShow(mode[1])} clearIcon={clearIcon} @@ -758,7 +758,7 @@ class RangeCalendar extends React.Component { onPanelChange={this.onEndPanelChange} showDateInput={this.props.showDateInput} timePicker={timePicker} - showTimePicker={showTimePicker} + showTimePicker={showTimePicker || mode[1] === 'time'} disabledTime={this.disabledEndTime} disabledMonth={this.disabledEndMonth} enablePrev={!isClosestMonths || this.isMonthYearPanelShow(mode[0])} diff --git a/tests/RangeCalendar.spec.jsx b/tests/RangeCalendar.spec.jsx index 932f1ee3e..1b43ea88d 100644 --- a/tests/RangeCalendar.spec.jsx +++ b/tests/RangeCalendar.spec.jsx @@ -426,6 +426,9 @@ describe('RangeCalendar', () => { RangeYearPicker.find('.rc-calendar-year-panel-decade-select').at(1).simulate('click'); expect(RangeYearPicker.find('.rc-calendar-decade-panel').length).toBe(0); expect(RangeYearPicker.find('.rc-calendar-year-panel').length).toBe(2); + + const RangeTimePicker = mount(); + expect(RangeTimePicker.find('.rc-calendar-time-picker').length).toBe(2); }); it('should work when start time is null in defaultValue', () => { From 2cf8c040c550e077e7012dbc988aae3307727e4a Mon Sep 17 00:00:00 2001 From: zombiej Date: Thu, 16 May 2019 11:13:23 +0800 Subject: [PATCH 068/114] bump 9.13.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 777ef4c04..696718361 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.13.3", + "version": "9.13.4", "description": "React Calendar", "keywords": [ "react", From ea49e22dbd5e92e7a5eba65a5d7aaed07b632d9d Mon Sep 17 00:00:00 2001 From: Rick Zhou Date: Fri, 17 May 2019 19:10:32 -0700 Subject: [PATCH 069/114] syncTime should also sync millisecond current implementation will cause the millisecond same as the now() value regardless of what's in defaultValue. Since millisecond is not shown in the UI, this will work like a unwanted hidden behavior and make things very hard to trouble shoot. --- src/util/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/index.js b/src/util/index.js index 260f3ba86..59665f68f 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -38,6 +38,7 @@ export function syncTime(from, to) { to.hour(from.hour()); to.minute(from.minute()); to.second(from.second()); + to.millisecond(from.millisecond()); } export function getTimeConfig(value, disabledTime) { From c68b549fa1412b5ff7d2030dca24c7f86e414612 Mon Sep 17 00:00:00 2001 From: Kimmo Saari Date: Fri, 24 May 2019 05:44:14 +0300 Subject: [PATCH 070/114] feat: Add Latvian locales (#578) * Add Latvian locales * Update HISTORY.md * Update package.json --- src/locale/lv_LV.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/locale/lv_LV.js diff --git a/src/locale/lv_LV.js b/src/locale/lv_LV.js new file mode 100644 index 000000000..f06ffcd4f --- /dev/null +++ b/src/locale/lv_LV.js @@ -0,0 +1,27 @@ +export default { + today: 'Šodien', + now: 'Tagad', + backToToday: 'Atpakaļ pie šodienas', + ok: 'Ok', + clear: 'Skaidrs', + month: 'Mēnesis', + year: 'Gads', + timeSelect: 'Izvēlieties laiku', + dateSelect: 'Izvēlieties datumu', + monthSelect: 'Izvēlieties mēnesi', + yearSelect: 'Izvēlieties gadu', + decadeSelect: 'Izvēlieties desmit gadus', + yearFormat: 'YYYY', + dateFormat: 'D.M.YYYY', + dayFormat: 'D', + dateTimeFormat: 'D.M.YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Iepriekšējais mēnesis (PageUp)', + nextMonth: 'Nākammēnes (PageDown)', + previousYear: 'Pagājušais gads (Control + left)', + nextYear: 'Nākamgad (Control + right)', + previousDecade: 'Pēdējā desmitgadē', + nextDecade: 'Nākamā desmitgade', + previousCentury: 'Pagājušajā gadsimtā', + nextCentury: 'Nākamajā gadsimtā', +}; From c83c316df26c6721d2a427e7dd37e3e667c9e75a Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 24 May 2019 10:45:20 +0800 Subject: [PATCH 071/114] bump 9.14.0 --- HISTORY.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 13665b7ff..034a149d1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,10 @@ # History ---- +## 9.14.0 / 2019-05-24 + +- Support Latvian locales + ## 9.13.0 / 2019-04-02 - Support close onBlur diff --git a/package.json b/package.json index 696718361..2ebfdef76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.13.4", + "version": "9.14.04.04.04.0", "description": "React Calendar", "keywords": [ "react", From 6d13d03674e38fa44449921c9803bcf329cf0b0f Mon Sep 17 00:00:00 2001 From: zombiej Date: Sat, 25 May 2019 21:15:08 +0800 Subject: [PATCH 072/114] bump 9.14.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ebfdef76..8f305ffc2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.14.04.04.04.0", + "version": "9.14.5", "description": "React Calendar", "keywords": [ "react", From a4262a5c62e24b97f09a3c07c32db56add64ce4c Mon Sep 17 00:00:00 2001 From: Parth Makadiya Date: Thu, 6 Jun 2019 08:47:28 +0200 Subject: [PATCH 073/114] added numeric keyboard support (#538) * added numeric keyboard support * change name and update documentations * suggested changes and clean minimal example * clean code from example --- README.md | 6 ++++++ examples/antd-calendar.js | 1 + index.d.ts | 1 + rc-calendar-tests.tsx | 1 + src/Calendar.jsx | 4 +++- src/date/DateInput.js | 4 +++- src/range-calendar/CalendarPart.js | 4 +++- tests/Calendar.spec.jsx | 5 +++++ 8 files changed, 23 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 642e32779..8d04d0bd9 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,12 @@ http://react-component.github.io/calendar/examples/index.html specific the clear icon. + + inputMode + string + text + Change the keyboard in mobile device + diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index 2d2e64cbc..2e8d8a221 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -233,6 +233,7 @@ class DemoMultiFormat extends React.Component { Accepts multiple input formats
{multiFormats.join(', ')} +
React.ReactNode; renderFooter?: () => React.ReactNode; renderSidebar?: () => React.ReactNode; + inputMode?:String } export default class ReactCalendar extends React.Component {} diff --git a/rc-calendar-tests.tsx b/rc-calendar-tests.tsx index 4e565aa05..b4e37931f 100644 --- a/rc-calendar-tests.tsx +++ b/rc-calendar-tests.tsx @@ -16,5 +16,6 @@ export default () => ( onChange={action} disabledDate={(now: moment.Moment) => false} onSelect={action} + inputMode="numeric" /> ); diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 48585fd64..bf25d81ca 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -53,6 +53,7 @@ class Calendar extends React.Component { renderSidebar: PropTypes.func, clearIcon: PropTypes.node, focusablePanel: PropTypes.bool, + inputMode: PropTypes.string, onBlur: PropTypes.func, } @@ -261,7 +262,7 @@ class Calendar extends React.Component { const { locale, prefixCls, disabledDate, dateInputPlaceholder, timePicker, - disabledTime, clearIcon, renderFooter, + disabledTime, clearIcon, renderFooter, inputMode, } = props; const { value, selectedValue, mode } = state; const showTimePicker = mode === 'time'; @@ -305,6 +306,7 @@ class Calendar extends React.Component { onChange={this.onDateInputChange} onSelect={this.onDateInputSelect} clearIcon={clearIcon} + inputMode={inputMode} /> ) : null; diff --git a/src/date/DateInput.js b/src/date/DateInput.js index fbc5d9306..5241a9662 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -25,6 +25,7 @@ class DateInput extends React.Component { onSelect: PropTypes.func, selectedValue: PropTypes.object, clearIcon: PropTypes.node, + inputMode: PropTypes.string, } constructor(props) { @@ -165,7 +166,7 @@ class DateInput extends React.Component { render() { const props = this.props; const { invalid, str } = this.state; - const { locale, prefixCls, placeholder, clearIcon } = props; + const { locale, prefixCls, placeholder, clearIcon, inputMode } = props; const invalidClass = invalid ? `${prefixCls}-input-invalid` : ''; return (
@@ -180,6 +181,7 @@ class DateInput extends React.Component { onKeyDown={this.onKeyDown} onFocus={this.onFocus} onBlur={this.onBlur} + inputMode={inputMode} />
{props.showClear ? ( diff --git a/src/range-calendar/CalendarPart.js b/src/range-calendar/CalendarPart.js index 7ae3877eb..784f79ea9 100644 --- a/src/range-calendar/CalendarPart.js +++ b/src/range-calendar/CalendarPart.js @@ -26,6 +26,7 @@ export default class CalendarPart extends React.Component { enableNext: PropTypes.any, enablePrev: PropTypes.any, clearIcon: PropTypes.node, + inputMode: PropTypes.string, } render() { @@ -41,7 +42,7 @@ export default class CalendarPart extends React.Component { disabledDate, timePicker, disabledTime, timePickerDisabledTime, showTimePicker, onInputChange, onInputSelect, enablePrev, enableNext, - clearIcon, + clearIcon, inputMode, } = props; const shouldShowTimePicker = showTimePicker && timePicker; const disabledTimeConfig = shouldShowTimePicker && disabledTime ? @@ -82,6 +83,7 @@ export default class CalendarPart extends React.Component { onChange={onInputChange} onSelect={onInputSelect} clearIcon={clearIcon} + inputMode={inputMode} />; return ( diff --git a/tests/Calendar.spec.jsx b/tests/Calendar.spec.jsx index 89a65eedc..b6f702713 100644 --- a/tests/Calendar.spec.jsx +++ b/tests/Calendar.spec.jsx @@ -473,6 +473,11 @@ describe('Calendar', () => { expect(calendar.find('.rc-calendar-decade-panel-decade').hostNodes().length).toBe(12); }); + it('numeric keyboard works', () => { + const newCalendar = mount(); + expect(newCalendar.find('.rc-calendar-input').props().inputMode).toBe('numeric'); + }); + it('extra footer works', () => { const renderFooter = (mode) => ({mode}); From ce64208074b6904fc8252ee48495e79f144a8676 Mon Sep 17 00:00:00 2001 From: zombiej Date: Thu, 6 Jun 2019 15:00:05 +0800 Subject: [PATCH 074/114] bump 9.15.0 --- HISTORY.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 034a149d1..522f02310 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,10 @@ # History ---- +## 9.15.0 / 2019-06-06 + +- Add numeric keyboard support + ## 9.14.0 / 2019-05-24 - Support Latvian locales diff --git a/package.json b/package.json index 8f305ffc2..864787033 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.14.5", + "version": "9.15.0", "description": "React Calendar", "keywords": [ "react", From 64d591421045420bdbef7408fd98dd756e0d8fbb Mon Sep 17 00:00:00 2001 From: Ahmad Abdelaziz Date: Sat, 15 Jun 2019 14:57:50 +0200 Subject: [PATCH 075/114] Removing chrome-test from README since it is deprecated --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 8d04d0bd9..54afa0384 100644 --- a/README.md +++ b/README.md @@ -737,7 +737,6 @@ http://react-component.github.io/calendar/examples/index.html ``` npm test -npm run chrome-test ``` ## Coverage From 7f4713f6cf707236eb22a9b66902b81198170c04 Mon Sep 17 00:00:00 2001 From: ZhaoXC Date: Tue, 25 Jun 2019 10:57:07 +0800 Subject: [PATCH 076/114] fix: RangePicker item not active when set mode year (#595) * fix: RangePicker item not active when set mode year * fix: RangePicker item not active when set mode year --- src/year/YearPanel.jsx | 3 +++ tests/RangeCalendar.spec.jsx | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/year/YearPanel.jsx b/src/year/YearPanel.jsx index b4dfc6e1c..f679a52bd 100644 --- a/src/year/YearPanel.jsx +++ b/src/year/YearPanel.jsx @@ -16,6 +16,9 @@ function chooseYear(year) { const value = this.state.value.clone(); value.year(year); value.month(this.state.value.month()); + this.setState({ + value, + }); this.props.onSelect(value); } diff --git a/tests/RangeCalendar.spec.jsx b/tests/RangeCalendar.spec.jsx index 1b43ea88d..384fa3b93 100644 --- a/tests/RangeCalendar.spec.jsx +++ b/tests/RangeCalendar.spec.jsx @@ -576,6 +576,38 @@ describe('RangeCalendar', () => { wrapper.find('.rc-calendar-month-panel-year-select-content').first(0).text() ).toBe('2010'); }); + + // https://github.com/ant-design/ant-design/issues/15659 + it('selected item style works correctly with mode year', () => { + class Demo extends React.Component { + state = { + value: [moment().add(-1, 'year'), moment()], + }; + + handlePanelChange = (value) => { + this.setState({ + value, + }); + }; + + render() { + return ( + + ); + } + } + + const wrapper = mount(); + wrapper.find('.rc-calendar-year-panel-cell').at(1).simulate('click'); + expect( + wrapper.find('.rc-calendar-year-panel-selected-cell').first(0).text() + ).toBe('2010'); + }); }); it('can hide date inputs with showDateInput={false}', () => { From a6d4a2c8b3309cdf07e1ea420c75f6e385718952 Mon Sep 17 00:00:00 2001 From: zombiej Date: Tue, 25 Jun 2019 10:58:09 +0800 Subject: [PATCH 077/114] bump 9.15.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 864787033..dccd3b254 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.15.0", + "version": "9.15.1", "description": "React Calendar", "keywords": [ "react", From 116e8827ae4ca4f665b1064b25d776875b5c0ea9 Mon Sep 17 00:00:00 2001 From: Buck Mayzes Date: Wed, 26 Jun 2019 15:42:24 -0400 Subject: [PATCH 078/114] Prevent form submit on enter. --- src/date/DateInput.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/date/DateInput.js b/src/date/DateInput.js index 5241a9662..df7c107f1 100644 --- a/src/date/DateInput.js +++ b/src/date/DateInput.js @@ -116,13 +116,15 @@ class DateInput extends React.Component { })); } - onKeyDown = ({ keyCode }) => { + onKeyDown = (event) => { + const { keyCode } = event; const { onSelect, value, disabledDate } = this.props; if (keyCode === KeyCode.ENTER && onSelect) { const validateDate = !disabledDate || !disabledDate(value); if (validateDate) { onSelect(value.clone()); } + event.preventDefault(); } }; From 02890614dac779d144ae81a1e8a9cb5d29c777da Mon Sep 17 00:00:00 2001 From: Ishan Date: Thu, 27 Jun 2019 08:12:52 +0530 Subject: [PATCH 079/114] showclear icon support for range-calendar (#536) * showclear icon support for range-calendar * showclear icon support for range-calendar --- src/range-calendar/CalendarPart.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/range-calendar/CalendarPart.js b/src/range-calendar/CalendarPart.js index 784f79ea9..97cc8b2f1 100644 --- a/src/range-calendar/CalendarPart.js +++ b/src/range-calendar/CalendarPart.js @@ -42,7 +42,9 @@ export default class CalendarPart extends React.Component { disabledDate, timePicker, disabledTime, timePickerDisabledTime, showTimePicker, onInputChange, onInputSelect, enablePrev, enableNext, - clearIcon, inputMode, + clearIcon, + showClear, + inputMode, } = props; const shouldShowTimePicker = showTimePicker && timePicker; const disabledTimeConfig = shouldShowTimePicker && disabledTime ? @@ -78,7 +80,7 @@ export default class CalendarPart extends React.Component { placeholder={placeholder} disabledTime={disabledTime} value={value} - showClear={false} + showClear={showClear || false} selectedValue={selectedValue[index]} onChange={onInputChange} onSelect={onInputSelect} From 290a0b1ad31cccdfc6dcace44e1b4d34312e05f4 Mon Sep 17 00:00:00 2001 From: Sebastian Busch Date: Thu, 27 Jun 2019 04:44:48 +0200 Subject: [PATCH 080/114] MonthCalendar has no dateCellRender (#518) * MonthCalendar has no dateCellRender prop * Add missing dateRender to some proptypes --- README.md | 6 ------ src/MonthCalendar.jsx | 1 - src/Picker.jsx | 1 + src/range-calendar/CalendarPart.js | 1 + 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 54afa0384..f02550fef 100644 --- a/README.md +++ b/README.md @@ -514,12 +514,6 @@ http://react-component.github.io/calendar/examples/index.html Custom month cell render method - - dateCellRender - function - - Custom date cell render method - monthCellContentRender function diff --git a/src/MonthCalendar.jsx b/src/MonthCalendar.jsx index 7f4c7eebf..67c0e2a52 100644 --- a/src/MonthCalendar.jsx +++ b/src/MonthCalendar.jsx @@ -16,7 +16,6 @@ class MonthCalendar extends React.Component { ...calendarMixinPropTypes, ...propType, monthCellRender: PropTypes.func, - dateCellRender: PropTypes.func, value: PropTypes.object, defaultValue: PropTypes.object, selectedValue: PropTypes.object, diff --git a/src/Picker.jsx b/src/Picker.jsx index 5f0748ce9..bce6db698 100644 --- a/src/Picker.jsx +++ b/src/Picker.jsx @@ -38,6 +38,7 @@ class Picker extends React.Component { PropTypes.array, ]), align: PropTypes.object, + dateRender: PropTypes.func, onBlur: PropTypes.func, } diff --git a/src/range-calendar/CalendarPart.js b/src/range-calendar/CalendarPart.js index 97cc8b2f1..714b01b19 100644 --- a/src/range-calendar/CalendarPart.js +++ b/src/range-calendar/CalendarPart.js @@ -26,6 +26,7 @@ export default class CalendarPart extends React.Component { enableNext: PropTypes.any, enablePrev: PropTypes.any, clearIcon: PropTypes.node, + dateRender: PropTypes.func, inputMode: PropTypes.string, } From 04cdffdf5bed1f8e90ceb67fc3c96d44c771d570 Mon Sep 17 00:00:00 2001 From: Aleksandr Chernokondratenko Date: Thu, 27 Jun 2019 05:45:16 +0300 Subject: [PATCH 081/114] Fix incorrect behaviour of the Calendar if we pass inValid moment object to defaultValue (#543) --- src/Calendar.jsx | 18 +- tests/Calendar.spec.jsx | 7 + tests/__snapshots__/Calendar.spec.jsx.snap | 769 +++++++++++++++++++++ 3 files changed, 791 insertions(+), 3 deletions(-) diff --git a/src/Calendar.jsx b/src/Calendar.jsx index bf25d81ca..2e8d89898 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -21,6 +21,13 @@ import moment from 'moment'; function noop() { } +const getMomentObjectIfValid = date => { + if (moment.isMoment(date) && date.isValid()) { + return date; + } + return false; +}; + class Calendar extends React.Component { static propTypes = { ...calendarMixinPropTypes, @@ -70,10 +77,12 @@ class Calendar extends React.Component { constructor(props) { super(props); - this.state = { mode: this.props.mode || 'date', - value: props.value || props.defaultValue || moment(), + value: + getMomentObjectIfValid(props.value) || + getMomentObjectIfValid(props.defaultValue) || + moment(), selectedValue: props.selectedValue || props.defaultSelectedValue, }; } @@ -229,7 +238,10 @@ class Calendar extends React.Component { newState = { mode: nextProps.mode }; } if ('value' in nextProps) { - newState.value = value || nextProps.defaultValue || getNowByCurrentStateValue(state.value); + newState.value = + getMomentObjectIfValid(value) || + getMomentObjectIfValid(nextProps.defaultValue) || + getNowByCurrentStateValue(state.value); } if ('selectedValue' in nextProps) { newState.selectedValue = selectedValue; diff --git a/tests/Calendar.spec.jsx b/tests/Calendar.spec.jsx index b6f702713..369eeb86b 100644 --- a/tests/Calendar.spec.jsx +++ b/tests/Calendar.spec.jsx @@ -33,6 +33,13 @@ describe('Calendar', () => { expect(enWrapperWithMonthFormatWrapper).toMatchSnapshot(); }); + it('render correctly with invalid moment object', () => { + const enWrapper = render( + + ); + expect(enWrapper).toMatchSnapshot(); + }); + it('render showToday false correctly', () => { const wrapper = mount(); expect(wrapper.find('.rc-calendar-today-btn').length).toBe(0); diff --git a/tests/__snapshots__/Calendar.spec.jsx.snap b/tests/__snapshots__/Calendar.spec.jsx.snap index 025db555d..d87e39193 100644 --- a/tests/__snapshots__/Calendar.spec.jsx.snap +++ b/tests/__snapshots__/Calendar.spec.jsx.snap @@ -4240,3 +4240,772 @@ exports[`Calendar render render correctly 3`] = `
`; + +exports[`Calendar render render correctly with invalid moment object 1`] = ` + +`; From 3a865ae3b95f249ae069239f390131f4d0611c45 Mon Sep 17 00:00:00 2001 From: Yusuke Murata Date: Thu, 27 Jun 2019 11:46:51 +0900 Subject: [PATCH 082/114] 'format' attribute accept array of string in type definition (#474) --- index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index f2fd9c78e..f1edde5e7 100644 --- a/index.d.ts +++ b/index.d.ts @@ -17,7 +17,7 @@ export interface Props { selectedValue?: Moment; mode?: Mode; locale?: object; - format?: string; + format?: string | string[]; showDateInput?: boolean; showWeekNumber?: boolean; showToday?: boolean; From 3ceed0270c77f60b88b018791dac1f71685eeb59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C8=98tefan=20Filip?= Date: Thu, 27 Jun 2019 05:48:41 +0300 Subject: [PATCH 083/114] Add Romanian locale (#432) --- src/locale/ro_RO.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/locale/ro_RO.js diff --git a/src/locale/ro_RO.js b/src/locale/ro_RO.js new file mode 100644 index 000000000..d69416804 --- /dev/null +++ b/src/locale/ro_RO.js @@ -0,0 +1,28 @@ +export default { + today: 'Azi', + now: 'Acum', + backToToday: 'Înapoi la azi', + ok: 'Ok', + clear: 'Șterge', + month: 'Lună', + year: 'An', + timeSelect: 'selectează timpul', + dateSelect: 'selectează data', + weekSelect: 'Alege o săptămână', + monthSelect: 'Alege o lună', + yearSelect: 'Alege un an', + decadeSelect: 'Alege un deceniu', + yearFormat: 'YYYY', + dateFormat: 'D/M/YYYY', + dayFormat: 'D', + dateTimeFormat: 'D/M/YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Luna anterioară (PageUp)', + nextMonth: 'Luna următoare (PageDown)', + previousYear: 'Anul anterior (Control + stânga)', + nextYear: 'Anul următor (Control + dreapta)', + previousDecade: 'Deceniul anterior', + nextDecade: 'Deceniul următor', + previousCentury: 'Secolul anterior', + nextCentury: 'Secolul următor', +}; From deb930173811d5657cbfe49b8d97fcc85f67154e Mon Sep 17 00:00:00 2001 From: austin-krave <51015176+austin-krave@users.noreply.github.com> Date: Thu, 27 Jun 2019 10:49:29 +0800 Subject: [PATCH 084/114] Added Malay locale (#580) --- HISTORY.md | 3 +++ src/locale/ms_MY.js | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/locale/ms_MY.js diff --git a/HISTORY.md b/HISTORY.md index 522f02310..90f09a35b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,8 @@ # History ---- +## 9.15.0 / 2019-05-26 + +- Support Malay locales ## 9.15.0 / 2019-06-06 diff --git a/src/locale/ms_MY.js b/src/locale/ms_MY.js new file mode 100644 index 000000000..a721e3e4c --- /dev/null +++ b/src/locale/ms_MY.js @@ -0,0 +1,27 @@ +export default { + today: 'Hari ini', + now: 'Sekarang', + backToToday: 'Kembali ke hari ini', + ok: 'Ok', + timeSelect: 'Pilih masa', + dateSelect: 'Pilih tarikh', + weekSelect: 'Pilih minggu', + clear: 'Padam', + month: 'Bulan', + year: 'Tahun', + previousMonth: 'Bulan lepas', + nextMonth: 'Bulan depan', + monthSelect: 'Pilih bulan', + yearSelect: 'Pilih tahun', + decadeSelect: 'Pilih dekad', + yearFormat: 'YYYY', + dayFormat: 'D', + dateFormat: 'M/D/YYYY', + dateTimeFormat: 'M/D/YYYY HH:mm:ss', + previousYear: 'Tahun lepas (Ctrl+left)', + nextYear: 'Tahun depan (Ctrl+right)', + previousDecade: 'Dekad lepas', + nextDecade: 'Dekad depan', + previousCentury: 'Abad lepas', + nextCentury: 'Abad depan', +}; From 8377ecc4e7213fd10bf892a826233fb8acd717c8 Mon Sep 17 00:00:00 2001 From: afc163 Date: Thu, 27 Jun 2019 10:50:01 +0800 Subject: [PATCH 085/114] :sparkles: 9.15.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dccd3b254..796c24714 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.15.1", + "version": "9.15.2", "description": "React Calendar", "keywords": [ "react", From 33ffcf990f31fa6251aef3a75c70d72d01b9833b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2019 10:51:19 +0800 Subject: [PATCH 086/114] Update async requirement from ~2.5.0 to ~3.1.0 (#596) Updates the requirements on [async](https://github.com/caolan/async) to permit the latest version. - [Release notes](https://github.com/caolan/async/releases) - [Changelog](https://github.com/caolan/async/blob/master/CHANGELOG.md) - [Commits](https://github.com/caolan/async/compare/v2.5.0...v3.1.0) Signed-off-by: dependabot-preview[bot] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dccd3b254..a6ad3ce9a 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ }, "devDependencies": { "@types/react": "^16.3.13", - "async": "~2.5.0", + "async": "~3.1.0", "bootstrap": "~3.3.2", "dtslint": "^0.6.1", "enzyme": "^3.3.0", From 2a69bf73f3bd0874e7490906c2a76825154da897 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2019 10:51:33 +0800 Subject: [PATCH 087/114] Update dtslint requirement from ^0.6.1 to ^0.8.0 (#590) Updates the requirements on [dtslint](https://github.com/Microsoft/dtslint) to permit the latest version. - [Release notes](https://github.com/Microsoft/dtslint/releases) - [Commits](https://github.com/Microsoft/dtslint/commits) Signed-off-by: dependabot-preview[bot] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a6ad3ce9a..153a98248 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "@types/react": "^16.3.13", "async": "~3.1.0", "bootstrap": "~3.3.2", - "dtslint": "^0.6.1", + "dtslint": "^0.8.0", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", "enzyme-to-json": "^3.3.1", From fe2405fc6fe826ca966f5b631d11d860aca2763a Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 27 Jun 2019 04:52:29 +0200 Subject: [PATCH 088/114] Adding tests to improve code coverage (#428) --- tests/RangeCalendar.spec.jsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/RangeCalendar.spec.jsx b/tests/RangeCalendar.spec.jsx index 384fa3b93..b49c829de 100644 --- a/tests/RangeCalendar.spec.jsx +++ b/tests/RangeCalendar.spec.jsx @@ -682,11 +682,13 @@ describe('RangeCalendar', () => { it('key control', () => { const onChange = jest.fn(); const onSelect = jest.fn(); + let keyDownEvent = 0; const wrapper = mount( keyDownEvent = 1} /> ); expect(wrapper.render()).toMatchSnapshot(); @@ -716,6 +718,9 @@ describe('RangeCalendar', () => { // 09-09 right 09-10 keySimulateCheck(keyCode.RIGHT, 'Sep', 10); + // 09-10 right 09-03 + keySimulateCheck(keyCode.UP, 'Sep', 3); + // 09-10 home 09-01 keySimulateCheck(keyCode.HOME, 'Sep', 1); @@ -728,6 +733,9 @@ describe('RangeCalendar', () => { // 08-30 page down 09-30 keySimulateCheck(keyCode.PAGE_DOWN, 'Sep', 30); + keyDown(keyCode.BACKSLASH); + expect(keyDownEvent).toEqual(1); + keyDown(keyCode.ENTER); expect(onChange.mock.calls[0][0][0].format(format)).toEqual('2000-09-30'); From 7d035bac3b76ee103f1dcaeb80b736403d28cb12 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2019 10:52:47 +0800 Subject: [PATCH 089/114] Update rc-select requirement from ^7.1.0 to ^9.1.5 (#593) Updates the requirements on [rc-select](https://github.com/react-component/select) to permit the latest version. - [Release notes](https://github.com/react-component/select/releases) - [Changelog](https://github.com/react-component/select/blob/master/HISTORY.md) - [Commits](https://github.com/react-component/select/compare/7.1.0...9.1.5) Signed-off-by: dependabot-preview[bot] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 153a98248..d69ae16f3 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "mockdate": "^2.0.1", "pre-commit": "1.x", "rc-dialog": "^7.0.0", - "rc-select": "^7.1.0", + "rc-select": "^9.1.5", "rc-time-picker": "^3.1.0", "rc-tools": "^7.0.3", "react": "^16.5.2", From 22e4746742cf7fa71d1eced2d08b0dc101b99201 Mon Sep 17 00:00:00 2001 From: afc163 Date: Thu, 27 Jun 2019 10:55:12 +0800 Subject: [PATCH 090/114] :white_check_mark: update snapshots --- tests/__snapshots__/FullCalendar.spec.js.snap | 57 +++++++++++++------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/tests/__snapshots__/FullCalendar.spec.js.snap b/tests/__snapshots__/FullCalendar.spec.js.snap index b14e5a696..69df28ea9 100644 --- a/tests/__snapshots__/FullCalendar.spec.js.snap +++ b/tests/__snapshots__/FullCalendar.spec.js.snap @@ -711,6 +711,7 @@ exports[`FullCalendar renders date mode correctly 1`] = ` >
@@ -743,6 +746,7 @@ exports[`FullCalendar renders date mode correctly 1`] = ` > @@ -764,9 +768,11 @@ exports[`FullCalendar renders date mode correctly 1`] = ` - +
@@ -1474,6 +1480,7 @@ exports[`FullCalendar renders fullscreen correctly 1`] = ` >
@@ -1506,6 +1515,7 @@ exports[`FullCalendar renders fullscreen correctly 1`] = ` > @@ -1527,9 +1537,11 @@ exports[`FullCalendar renders fullscreen correctly 1`] = ` - +
@@ -2237,6 +2249,7 @@ exports[`FullCalendar renders month mode correctly 1`] = ` > @@ -2258,9 +2271,11 @@ exports[`FullCalendar renders month mode correctly 1`] = ` - +
@@ -2457,6 +2472,7 @@ exports[`FullCalendar type renders defaultType correctly 1`] = ` >
@@ -2489,6 +2507,7 @@ exports[`FullCalendar type renders defaultType correctly 1`] = ` > @@ -2510,9 +2529,11 @@ exports[`FullCalendar type renders defaultType correctly 1`] = ` - +
From 809960e3179126509a8178f7aadcf3c9edb76752 Mon Sep 17 00:00:00 2001 From: afc163 Date: Thu, 27 Jun 2019 10:56:06 +0800 Subject: [PATCH 091/114] remove bootstrap dep --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 33ca630ef..198145976 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,6 @@ "devDependencies": { "@types/react": "^16.3.13", "async": "~3.1.0", - "bootstrap": "~3.3.2", "dtslint": "^0.8.0", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", From f95fc2ccf2c5496d8752097c8d04d661bb422afc Mon Sep 17 00:00:00 2001 From: leijingdao Date: Sat, 29 Jun 2019 12:58:04 +0800 Subject: [PATCH 092/114] month calendar compatible to react v15.x (#598) --- src/MonthCalendar.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MonthCalendar.jsx b/src/MonthCalendar.jsx index 67c0e2a52..857f2f617 100644 --- a/src/MonthCalendar.jsx +++ b/src/MonthCalendar.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import KeyCode from 'rc-util/lib/KeyCode'; +import { polyfill } from 'react-lifecycles-compat'; import CalendarHeader from './calendar/CalendarHeader'; import CalendarFooter from './calendar/CalendarFooter'; import { @@ -120,4 +121,4 @@ class MonthCalendar extends React.Component { } } -export default calendarMixinWrapper(commonMixinWrapper(MonthCalendar)); +export default polyfill(calendarMixinWrapper(commonMixinWrapper(MonthCalendar))); From f8f3f16ef2f0c6702794b2cf325a69490a6ac5af Mon Sep 17 00:00:00 2001 From: Yann Normand Date: Sun, 30 Jun 2019 16:18:54 +1000 Subject: [PATCH 093/114] fix example to open calendar on click (#583) --- examples/antd-calendar.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index 2e8d8a221..ea2314114 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -109,9 +109,23 @@ class Demo extends React.Component { }); } - onReadOnlyFocus = () => { + onFocus = () => { + if (!this.state.open && this.state.isMouseDown) { + // focus from a "click" event, let the picker trigger automatically open the calendar + this.setState({ + isMouseDown: false, + }); + } else { + // focus not caused by "click" (such as programmatic or via keyboard) + this.setState({ + open: true, + }); + } + } + + onMouseDown = () => { this.setState({ - open: true, + isMouseDown: true, }); } @@ -187,7 +201,7 @@ class Demo extends React.Component { { ({ value }) => { return ( - + Date: Mon, 1 Jul 2019 16:21:04 +0800 Subject: [PATCH 094/114] :sparkles: 9.15.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 198145976..d1a7209cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.15.2", + "version": "9.15.3", "description": "React Calendar", "keywords": [ "react", From 72a957398b4e19ab8f6824f61cd1ac5313fa37e1 Mon Sep 17 00:00:00 2001 From: zombiej Date: Mon, 15 Jul 2019 10:58:27 +0800 Subject: [PATCH 095/114] fix: Show correct switch text when both mode is time fix ant-design/ant-design#17625 --- src/RangeCalendar.js | 2 +- tests/RangeCalendar.spec.jsx | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index 6c9a62b5e..0c2f938da 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -782,7 +782,7 @@ class RangeCalendar extends React.Component { {props.timePicker ? { expect(wrapper.find('CalendarPart').at(0).props().value.format(FORMAT)).toEqual('2000-01-01'); expect(wrapper.find('CalendarPart').at(1).props().value.format(FORMAT)).toEqual('2000-02-01'); }); + + it('render text correctly when range mode is both time', () => { + const RangeTimePicker = mount( + + } + />, + ); + expect(RangeTimePicker.find('.rc-calendar-time-picker-btn').text()).toBe('select date'); + }); }); From 1d5a091aa6837bb2a2a1f6cd9eec4d9fc6feabed Mon Sep 17 00:00:00 2001 From: zombiej Date: Mon, 15 Jul 2019 10:59:07 +0800 Subject: [PATCH 096/114] bump 9.15.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d1a7209cc..8f0556c54 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.15.3", + "version": "9.15.4", "description": "React Calendar", "keywords": [ "react", From d090a7e5a4212e3fffef8b9b7c8bfba9435795e9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 19 Jul 2019 10:20:24 +0800 Subject: [PATCH 097/114] Update dtslint requirement from ^0.8.0 to ^0.9.0 (#602) Updates the requirements on [dtslint](https://github.com/Microsoft/dtslint) to permit the latest version. - [Release notes](https://github.com/Microsoft/dtslint/releases) - [Commits](https://github.com/Microsoft/dtslint/commits) Signed-off-by: dependabot-preview[bot] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8f0556c54..d85607675 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "devDependencies": { "@types/react": "^16.3.13", "async": "~3.1.0", - "dtslint": "^0.8.0", + "dtslint": "^0.9.0", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", "enzyme-to-json": "^3.3.1", From 60f44edb6b1b98e1c7d3c5eca80828122ab93ef8 Mon Sep 17 00:00:00 2001 From: Sivaraj Date: Mon, 29 Jul 2019 15:55:51 +0530 Subject: [PATCH 098/114] Added Tamil Locale (#607) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tamil locale (தமிழ்/செம்மொழி) added --- src/locale/ta_IN.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/locale/ta_IN.js diff --git a/src/locale/ta_IN.js b/src/locale/ta_IN.js new file mode 100644 index 000000000..20ac8316b --- /dev/null +++ b/src/locale/ta_IN.js @@ -0,0 +1,28 @@ +export default { + today: 'இன்று', + now: 'இப்போது', + backToToday: 'இன்றுக்கு திரும்பு', + ok: 'சரி', + clear: 'அழி', + month: 'மாதம்', + year: 'வருடம்', + timeSelect: 'நேரத்தைத் தேர்ந்தெடு', + dateSelect: 'தேதியைத் தேர்ந்தெடு', + weekSelect: 'வாரத்தைத் தேர்வுசெய்க', + monthSelect: 'மாதத்தைத் தேர்வுசெய்க', + yearSelect: 'வருடத்தைத் தேர்வுசெய்க', + decadeSelect: 'தசாப்தத்தைத் தேர்வுசெய்க', + yearFormat: 'YYYY', + dateFormat: 'M/D/YYYY', + dayFormat: 'D', + dateTimeFormat: 'M/D/YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'முந்தைய மாதம் (PageUp)', + nextMonth: 'அடுத்த மாதம் (PageDown)', + previousYear: 'முந்தைய வருடம் (Control + left)', + nextYear: 'அடுத்த வருடம் (Control + right)', + previousDecade: 'முந்தைய தசாப்தம்', + nextDecade: 'அடுத்த தசாப்தம்', + previousCentury: 'முந்தைய நூற்றாண்டு', + nextCentury: 'அடுத்த நூற்றாண்டு', +}; From d486704af3357741bb150628d206a956a5d1cd61 Mon Sep 17 00:00:00 2001 From: afc163 Date: Wed, 31 Jul 2019 11:19:02 +0800 Subject: [PATCH 099/114] :sparkles: 9.15.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d85607675..e614f3eff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.15.4", + "version": "9.15.5", "description": "React Calendar", "keywords": [ "react", From 3a01cd6c26942ef131deb6cd3ffa19c10b855d40 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 29 Sep 2019 11:20:30 +0800 Subject: [PATCH 100/114] :bug: Fix format array prop type warning close ant-design/ant-design#19037 --- package.json | 2 +- src/RangeCalendar.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e614f3eff..9dd4c32b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.15.5", + "version": "9.15.6", "description": "React Calendar", "keywords": [ "react", diff --git a/src/RangeCalendar.js b/src/RangeCalendar.js index 0c2f938da..d4b15bb23 100644 --- a/src/RangeCalendar.js +++ b/src/RangeCalendar.js @@ -102,7 +102,7 @@ class RangeCalendar extends React.Component { onValueChange: PropTypes.func, onHoverChange: PropTypes.func, onPanelChange: PropTypes.func, - format: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), + format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), onClear: PropTypes.func, type: PropTypes.any, disabledDate: PropTypes.func, From c32299ab60a62e3508f9bc2f9be1e256149b18b6 Mon Sep 17 00:00:00 2001 From: asad <32115289+asadnq@users.noreply.github.com> Date: Sat, 19 Oct 2019 13:54:01 +0700 Subject: [PATCH 101/114] modify locale id_ID.js (#624) --- src/locale/id_ID.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/locale/id_ID.js b/src/locale/id_ID.js index 2004bfcdd..1c9df774f 100644 --- a/src/locale/id_ID.js +++ b/src/locale/id_ID.js @@ -13,14 +13,14 @@ export default { yearSelect: 'Pilih satu tahun', decadeSelect: 'Pilih satu dekade', yearFormat: 'YYYY', - dateFormat: 'M/D/YYYY', + dateFormat: 'D/M/YYYY', dayFormat: 'D', - dateTimeFormat: 'M/D/YYYY HH:mm:ss', + dateTimeFormat: 'D/M/YYYY HH:mm:ss', monthBeforeYear: true, previousMonth: 'Bulan sebelumnya (PageUp)', - nextMonth: 'Bulan depan (PageDown)', + nextMonth: 'Bulan selanjutnya (PageDown)', previousYear: 'Tahun lalu (Control + kiri)', - nextYear: 'Tahun depan (Kontrol + kanan)', + nextYear: 'Tahun selanjutnya (Kontrol + kanan)', previousDecade: 'Dekade terakhir', nextDecade: 'Dekade berikutnya', previousCentury: 'Abad terakhir', From f73c2737789824595e1752b2358ff574acfabf10 Mon Sep 17 00:00:00 2001 From: Kilian Ciuffolo <385716+kilianc@users.noreply.github.com> Date: Sat, 26 Oct 2019 23:17:48 -0700 Subject: [PATCH 102/114] Fix monthCellRender and monthCellContentRender not being passed (#626) --- index.d.ts | 4 +++- src/Calendar.jsx | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index f1edde5e7..b8f8c16ba 100644 --- a/index.d.ts +++ b/index.d.ts @@ -35,7 +35,9 @@ export interface Props { dateRender?: (current: Moment, value: Moment) => React.ReactNode; renderFooter?: () => React.ReactNode; renderSidebar?: () => React.ReactNode; - inputMode?:String + inputMode?: String; + monthCellRender?: (current: Moment, locale: Object) => string; + monthCellContentRender?: (current: Moment, locale: Object) => React.ReactNode; } export default class ReactCalendar extends React.Component {} diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 2e8d89898..1c895c359 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -275,6 +275,7 @@ class Calendar extends React.Component { locale, prefixCls, disabledDate, dateInputPlaceholder, timePicker, disabledTime, clearIcon, renderFooter, inputMode, + monthCellRender, monthCellContentRender, } = props; const { value, selectedValue, mode } = state; const showTimePicker = mode === 'time'; @@ -341,6 +342,8 @@ class Calendar extends React.Component { renderFooter={renderFooter} showTimePicker={showTimePicker} prefixCls={prefixCls} + monthCellRender={monthCellRender} + monthCellContentRender={monthCellContentRender} /> {timePicker && showTimePicker ? (
From 57e1f5ad8fee7ecc4c2271ab4ec179f0b830dc54 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2019 10:46:17 +0800 Subject: [PATCH 103/114] Bump dtslint from 0.9.9 to 1.0.3 (#629) Bumps [dtslint](https://github.com/Microsoft/dtslint) from 0.9.9 to 1.0.3. - [Release notes](https://github.com/Microsoft/dtslint/releases) - [Commits](https://github.com/Microsoft/dtslint/commits) Signed-off-by: dependabot-preview[bot] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9dd4c32b2..013bf4d41 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "devDependencies": { "@types/react": "^16.3.13", "async": "~3.1.0", - "dtslint": "^0.9.0", + "dtslint": "^1.0.3", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", "enzyme-to-json": "^3.3.1", From ece6a60c7077b4dcd9e5ec4d2f360a088c5b9ba7 Mon Sep 17 00:00:00 2001 From: Stevche Radevski Date: Sat, 9 Nov 2019 11:37:51 +0100 Subject: [PATCH 104/114] Add Macedonian translation (#631) --- src/locale/mk_MK.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/locale/mk_MK.js diff --git a/src/locale/mk_MK.js b/src/locale/mk_MK.js new file mode 100644 index 000000000..91d9188a8 --- /dev/null +++ b/src/locale/mk_MK.js @@ -0,0 +1,27 @@ +export default { + today: 'Денес', + now: 'Сега', + backToToday: 'Назад до денес', + ok: 'ОК', + clear: 'Избриши', + month: 'Месец', + year: 'Година', + timeSelect: 'Избери време', + dateSelect: 'Избери датум', + monthSelect: 'Избери месец', + yearSelect: 'Избери година', + decadeSelect: 'Избери деценија', + yearFormat: 'YYYY', + dateFormat: 'D.M.YYYY', + dayFormat: 'D', + dateTimeFormat: 'D.M.YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Претходен месец (PageUp)', + nextMonth: 'Нареден месец (PageDown)', + previousYear: 'Претходна година (Control + left)', + nextYear: 'Наредна година (Control + right)', + previousDecade: 'Претходна деценија', + nextDecade: 'Наредна деценија', + previousCentury: 'Претходен век', + nextCentury: 'Нареден век', +}; From 81a277a8141a828ac7f520570573fa9e7a73587c Mon Sep 17 00:00:00 2001 From: afc163 Date: Sat, 9 Nov 2019 20:54:17 +0800 Subject: [PATCH 105/114] :sparkles: Release 9.15.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 013bf4d41..b83638591 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.15.6", + "version": "9.15.7", "description": "React Calendar", "keywords": [ "react", From 385a51567c1b6028d2cafa88c34a4805b01f8229 Mon Sep 17 00:00:00 2001 From: Martin Litvaj Date: Mon, 18 Nov 2019 14:51:53 +0100 Subject: [PATCH 106/114] Update sk_SK locales (#636) --- src/locale/sk_SK.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/locale/sk_SK.js b/src/locale/sk_SK.js index fadd50b49..a543172ce 100644 --- a/src/locale/sk_SK.js +++ b/src/locale/sk_SK.js @@ -8,6 +8,7 @@ export default { year: 'Rok', timeSelect: 'Vybrať čas', dateSelect: 'Vybrať dátum', + weekSelect: 'Vybrať týždeň', monthSelect: 'Vybrať mesiac', yearSelect: 'Vybrať rok', decadeSelect: 'Vybrať dekádu', From 0cabf958a85a58b18a97e71085ef62cd4b9ed106 Mon Sep 17 00:00:00 2001 From: afc163 Date: Mon, 18 Nov 2019 21:54:02 +0800 Subject: [PATCH 107/114] bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b83638591..fff9f27bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-calendar", - "version": "9.15.7", + "version": "9.15.8", "description": "React Calendar", "keywords": [ "react", From 91a157f7e343ffb46c2e68872db3090c01e79db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B8=85?= Date: Tue, 19 Nov 2019 13:33:35 +0800 Subject: [PATCH 108/114] refactoring: refactoring code into typescript (#635) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * style: change to ts * refactor: change form to ts * refactor: fix all eslint error and ts error * chore: fix build error * fix: fix demo bug * temp * step commit * fix test * remove ugly mix * use mew father * fix lint error * fix lint error * add eslint version * fix test * set theme=dark dark is good 👩🏿👨🏿🧑🏿👧🏿👦🏿👦🏿🧒🏿👶🏿👵🏿 * close react/jsx-boolean-value * use beta eslint --- .eslintrc.js | 13 + .fatherrc.js | 8 + .gitignore | 4 +- HISTORY.md | 21 +- README.md | 34 +- examples/antd-calendar.html | 1 - examples/antd-calendar.js | 332 +++---- examples/antd-month-calendar.html | 1 - examples/antd-month-calendar.js | 128 ++- examples/antd-range-calendar.html | 1 - examples/antd-range-calendar.js | 79 +- examples/baisc.js | 14 + examples/control-panel.html | 0 examples/control-panel.js | 44 +- examples/custom-clear-icon.html | 1 - examples/custom-clear-icon.js | 99 +- examples/full-calendar.html | 1 - examples/full-calendar.js | 24 +- examples/getCalendarContainer.html | 0 examples/getCalendarContainer.js | 85 +- examples/start-end-range.html | 1 - examples/start-end-range.js | 81 +- examples/start-end.html | 1 - examples/start-end.js | 135 ++- examples/week.html | 0 examples/week.js | 157 ++- index.d.ts | 43 - index.js | 2 - index.ts | 3 + jest.config.js | 4 + package.json | 113 +-- src/Calendar.jsx | 403 -------- src/Calendar.tsx | 516 ++++++++++ src/FullCalendar.jsx | 181 ---- src/FullCalendar.tsx | 284 ++++++ src/MonthCalendar.jsx | 124 --- src/MonthCalendar.tsx | 214 +++++ src/{Picker.jsx => Picker.tsx} | 165 ++-- src/{RangeCalendar.js => RangeCalendar.tsx} | 458 +++++---- src/calendar/CalendarFooter.jsx | 72 -- src/calendar/CalendarFooter.tsx | 81 ++ src/calendar/CalendarHeader.jsx | 233 ----- src/calendar/CalendarHeader.tsx | 249 +++++ src/calendar/OkButton.jsx | 15 - src/calendar/OkButton.tsx | 21 + src/calendar/TimePickerButton.jsx | 24 - src/calendar/TimePickerButton.tsx | 36 + src/calendar/TodayButton.jsx | 30 - src/calendar/TodayButton.tsx | 43 + .../{DateConstants.js => DateConstants.ts} | 0 src/date/{DateInput.js => DateInput.tsx} | 97 +- src/date/DateTBody.jsx | 258 ----- src/date/DateTBody.tsx | 273 ++++++ src/date/DateTHead.jsx | 52 - src/date/DateTHead.tsx | 63 ++ src/date/DateTable.jsx | 15 - src/date/DateTable.tsx | 20 + src/decade/DecadePanel.jsx | 146 --- src/decade/DecadePanel.tsx | 141 +++ ...{CalendarHeader.jsx => CalendarHeader.tsx} | 140 +-- src/{index.js => index.ts} | 0 src/mixin/CalendarMixin.js | 120 --- src/mixin/CalendarMixin.tsx | 25 + src/mixin/CommonMixin.js | 72 -- src/mixin/CommonMixin.tsx | 32 + src/month/{MonthPanel.jsx => MonthPanel.tsx} | 78 +- src/month/{MonthTable.js => MonthTable.tsx} | 77 +- src/picker/{placements.js => placements.ts} | 0 src/range-calendar/CalendarPart.js | 127 --- src/range-calendar/CalendarPart.tsx | 168 ++++ src/util/{index.js => index.ts} | 14 +- src/util/{toTime.js => toTime.ts} | 0 src/year/{YearPanel.jsx => YearPanel.tsx} | 122 +-- tests/Calendar.spec.jsx | 284 +++--- tests/EnzymeExt.js | 4 +- tests/FullCalendar.spec.js | 54 +- tests/Picker.spec.jsx | 145 ++- tests/RangeCalendar.spec.jsx | 904 ++++++++++++++---- tests/__mocks__/rc-trigger.js | 20 - tests/__mocks__/rc-trigger.ts | 3 + tests/__snapshots__/FullCalendar.spec.js.snap | 385 ++++---- tests/locale.spec.js | 3 +- tests/setup.js | 11 +- tsconfig.json | 18 - tslint.json | 10 - 85 files changed, 4691 insertions(+), 3769 deletions(-) create mode 100644 .eslintrc.js create mode 100644 .fatherrc.js delete mode 100644 examples/antd-calendar.html delete mode 100644 examples/antd-month-calendar.html delete mode 100644 examples/antd-range-calendar.html create mode 100644 examples/baisc.js delete mode 100644 examples/control-panel.html delete mode 100644 examples/custom-clear-icon.html delete mode 100644 examples/full-calendar.html delete mode 100644 examples/getCalendarContainer.html delete mode 100644 examples/start-end-range.html delete mode 100644 examples/start-end.html delete mode 100644 examples/week.html delete mode 100644 index.d.ts delete mode 100644 index.js create mode 100644 index.ts create mode 100644 jest.config.js delete mode 100644 src/Calendar.jsx create mode 100644 src/Calendar.tsx delete mode 100644 src/FullCalendar.jsx create mode 100644 src/FullCalendar.tsx delete mode 100644 src/MonthCalendar.jsx create mode 100644 src/MonthCalendar.tsx rename src/{Picker.jsx => Picker.tsx} (65%) rename src/{RangeCalendar.js => RangeCalendar.tsx} (68%) delete mode 100644 src/calendar/CalendarFooter.jsx create mode 100644 src/calendar/CalendarFooter.tsx delete mode 100644 src/calendar/CalendarHeader.jsx create mode 100644 src/calendar/CalendarHeader.tsx delete mode 100644 src/calendar/OkButton.jsx create mode 100644 src/calendar/OkButton.tsx delete mode 100644 src/calendar/TimePickerButton.jsx create mode 100644 src/calendar/TimePickerButton.tsx delete mode 100644 src/calendar/TodayButton.jsx create mode 100644 src/calendar/TodayButton.tsx rename src/date/{DateConstants.js => DateConstants.ts} (100%) rename src/date/{DateInput.js => DateInput.tsx} (72%) delete mode 100644 src/date/DateTBody.jsx create mode 100644 src/date/DateTBody.tsx delete mode 100644 src/date/DateTHead.jsx create mode 100644 src/date/DateTHead.tsx delete mode 100644 src/date/DateTable.jsx create mode 100644 src/date/DateTable.tsx delete mode 100644 src/decade/DecadePanel.jsx create mode 100644 src/decade/DecadePanel.tsx rename src/full-calendar/{CalendarHeader.jsx => CalendarHeader.tsx} (52%) rename src/{index.js => index.ts} (100%) delete mode 100644 src/mixin/CalendarMixin.js create mode 100644 src/mixin/CalendarMixin.tsx delete mode 100644 src/mixin/CommonMixin.js create mode 100644 src/mixin/CommonMixin.tsx rename src/month/{MonthPanel.jsx => MonthPanel.tsx} (61%) rename src/month/{MonthTable.js => MonthTable.tsx} (64%) rename src/picker/{placements.js => placements.ts} (100%) delete mode 100644 src/range-calendar/CalendarPart.js create mode 100644 src/range-calendar/CalendarPart.tsx rename src/util/{index.js => index.ts} (88%) rename src/util/{toTime.js => toTime.ts} (100%) rename src/year/{YearPanel.jsx => YearPanel.tsx} (59%) delete mode 100644 tests/__mocks__/rc-trigger.js create mode 100644 tests/__mocks__/rc-trigger.ts delete mode 100644 tsconfig.json delete mode 100644 tslint.json diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..714a80b40 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,13 @@ +module.exports = { + extends: [require.resolve('@umijs/fabric/dist/eslint')], + rules: { + 'default-case': 0, + 'react/sort-comp': 0, + 'jsx-a11y/no-noninteractive-tabindex': 0, + 'jsx-a11y/interactive-supports-focus': 0, + 'react/no-array-index-key': 0, + 'react/jsx-boolean-value': 0, + 'jsx-a11y/anchor-has-content': 0, + 'import/no-extraneous-dependencies': ['error', { devDependencies: true }], + }, +}; diff --git a/.fatherrc.js b/.fatherrc.js new file mode 100644 index 000000000..767a2abfe --- /dev/null +++ b/.fatherrc.js @@ -0,0 +1,8 @@ +export default { + cjs: 'babel', + esm: { type: 'babel', importLibToEs: true }, + preCommit: { + eslint: true, + prettier: true, + }, +}; diff --git a/.gitignore b/.gitignore index 9146790c8..8d13dccbe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.storybook *.iml *.log .idea/ @@ -28,4 +29,5 @@ es coverage yarn.lock .vscode -package-lock.json \ No newline at end of file +package-lock.json +.doc diff --git a/HISTORY.md b/HISTORY.md index 90f09a35b..d9ba8dc31 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,7 @@ # History ----- + +--- + ## 9.15.0 / 2019-05-26 - Support Malay locales @@ -57,9 +59,11 @@ - React 16 support ## 9.1.0 / 2017-07-27 + - Support control panel [#284](https://github.com/react-component/calendar/pull/284) ## 9.0.0 / 2017-07-27 + - Replace react string refs with function way [#282](https://github.com/react-component/calendar/pull/282) ## 8.4.0 / 2017-05-31 @@ -237,8 +241,7 @@ upgrade to react 0.13 and es6 ## 2.0.0 / 2015-03-04 -`new` [#15](https://github.com/react-component/calendar/issues/15) support defaultValue -`improved` upgrade gregorian-calendar and gregorian-calendar-format to 3.x +`new` [#15](https://github.com/react-component/calendar/issues/15) support defaultValue `improved` upgrade gregorian-calendar and gregorian-calendar-format to 3.x ## 1.5.0 / 2015-01-22 @@ -246,18 +249,18 @@ upgrade to react 0.13 and es6 ## 1.4.0 / 2015-01-05 -`new` [#12](https://github.com/react-component/calendar/issues/12) support time select ([@yiminghe](https://github.com/yiminghe)) +`new` [#12](https://github.com/react-component/calendar/issues/12) support time select ([@yiminghe](https://github.com/yiminghe)) -`new` [#11](https://github.com/react-component/calendar/issues/11) support prefixCls ([@yiminghe](https://github.com/yiminghe)) +`new` [#11](https://github.com/react-component/calendar/issues/11) support prefixCls ([@yiminghe](https://github.com/yiminghe)) -`new` [#10](https://github.com/react-component/calendar/issues/10) support nextMonth previousMonth in calendar panel ([@yiminghe](https://github.com/yiminghe)) +`new` [#10](https://github.com/react-component/calendar/issues/10) support nextMonth previousMonth in calendar panel ([@yiminghe](https://github.com/yiminghe)) ## 1.3.0 / 2014-12-30 -`new` [#9](https://github.com/react-component/calendar/issues/9) support className prop ([@yiminghe](https://github.com/yiminghe)) +`new` [#9](https://github.com/react-component/calendar/issues/9) support className prop ([@yiminghe](https://github.com/yiminghe)) -`new` [#8](https://github.com/react-component/calendar/issues/8) support orient prop ([@yiminghe](https://github.com/yiminghe)) +`new` [#8](https://github.com/react-component/calendar/issues/8) support orient prop ([@yiminghe](https://github.com/yiminghe)) ## 1.2.4 / 2014-12-26 -`new` [#7](https://github.com/react-component/calendar/issues/7) release 1.2.4 ([@yiminghe](https://github.com/yiminghe)) +`new` [#7](https://github.com/react-component/calendar/issues/7) release 1.2.4 ([@yiminghe](https://github.com/yiminghe)) diff --git a/README.md b/README.md index f02550fef..39ad55477 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,8 @@ # rc-calendar ---- React Calendar -[![NPM version][npm-image]][npm-url] -[![build status][travis-image]][travis-url] -[![Test coverage][codecov-image]][codecov-url] -[![gemnasium deps][gemnasium-image]][gemnasium-url] -[![npm download][download-image]][download-url] -[![Code Quality: Javascript][lgtm-badge]][lgtm-badge-url] -[![Total alerts][lgtm-alerts]][lgtm-alerts-url] +[![NPM version][npm-image]][npm-url] [![build status][travis-image]][travis-url] [![Test coverage][codecov-image]][codecov-url] [![gemnasium deps][gemnasium-image]][gemnasium-url] [![npm download][download-image]][download-url] [![Code Quality: Javascript][lgtm-badge]][lgtm-badge-url] [![Total alerts][lgtm-alerts]][lgtm-alerts-url] [npm-image]: http://img.shields.io/npm/v/rc-calendar.svg?style=flat-square [npm-url]: http://npmjs.org/package/rc-calendar @@ -40,21 +33,21 @@ React Calendar ## Feature -* support ie9,ie9+,chrome,firefox,safari -* support date, month, year, decade select panel -* support week number -* support en_US and zh_CN locale(UI), use moment.utcOffset to set timezone -* support aria and keyboard accessibility +- support ie9,ie9+,chrome,firefox,safari +- support date, month, year, decade select panel +- support week number +- support en_US and zh_CN locale(UI), use moment.utcOffset to set timezone +- support aria and keyboard accessibility ### Keyboard -* Previous month (PageUp) -* Next month (PageDown) -* tab into hour input: Last hour(Up), Next hour(Down) -* tab into hour input: Last minute(Up), Next minute(Down) -* tab into hour input: Last second(Up), Next second(Down) -* Last year (Control + left) -* Next year (Control + right) +- Previous month (PageUp) +- Next month (PageDown) +- tab into hour input: Last hour(Up), Next hour(Down) +- tab into hour input: Last minute(Up), Next minute(Down) +- tab into hour input: Last second(Up), Next second(Down) +- Last year (Control + left) +- Next year (Control + right) ## install @@ -258,7 +251,6 @@ http://react-component.github.io/calendar/examples/index.html - ### rc-calendar/lib/RangeCalendar props diff --git a/examples/antd-calendar.html b/examples/antd-calendar.html deleted file mode 100644 index b3a425249..000000000 --- a/examples/antd-calendar.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/antd-calendar.js b/examples/antd-calendar.js index ea2314114..181b56b0b 100644 --- a/examples/antd-calendar.js +++ b/examples/antd-calendar.js @@ -1,22 +1,21 @@ /* eslint react/no-multi-comp:0, no-console:0 */ -import 'rc-calendar/assets/index.less'; +import '../assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; -import PropTypes from 'prop-types'; -import Calendar from 'rc-calendar'; -import DatePicker from 'rc-calendar/src/Picker'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; -import 'rc-time-picker/assets/index.css'; +import moment from 'moment'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; -import moment from 'moment'; +import Calendar from '../src'; +import DatePicker from '../src/Picker'; +import zhCN from '../src/locale/zh_CN'; +import enUS from '../src/locale/en_US'; +import 'rc-time-picker/assets/index.css'; + import 'moment/locale/zh-cn'; import 'moment/locale/en-gb'; const format = 'YYYY-MM-DD HH:mm:ss'; -const cn = location.search.indexOf('cn') !== -1; +const cn = window.location.search.indexOf('cn') !== -1; const now = moment(); if (cn) { @@ -29,7 +28,6 @@ function getFormat(time) { return time ? format : 'YYYY-MM-DD'; } - const defaultCalendarValue = now.clone(); defaultCalendarValue.add(-1, 'month'); @@ -37,7 +35,7 @@ const timePickerElement = { - console.log('DatePicker change: ', (value && value.format(format))); + onChange = value => { + console.log('DatePicker change: ', value && value.format(format)); this.setState({ value, }); - } + }; - onShowTimeChange = (e) => { + onShowTimeChange = e => { this.setState({ showTime: e.target.checked, }); - } + }; - onShowDateInputChange = (e) => { + onShowDateInputChange = e => { this.setState({ showDateInput: e.target.checked, }); - } + }; - onOpenChange = (open) => { + onOpenChange = open => { this.setState({ open, }); - } + }; onFocus = () => { if (!this.state.open && this.state.isMouseDown) { @@ -121,104 +113,109 @@ class Demo extends React.Component { open: true, }); } - } + }; onMouseDown = () => { this.setState({ isMouseDown: true, }); - } + }; getCalendarContainer = () => this.calendarContainerRef.current; toggleDisabled = () => { + const { disabled } = this.state; this.setState({ - disabled: !this.state.disabled, + disabled: !disabled, }); - } + }; render() { - const state = this.state; - const calendar = (); - return (
-
- -      - -      - -
-
- + ); + return ( +
+
+ +      + +      + +
+
- { - ({ value }) => { - return ( - - -
- - ); - } - } - + + {({ value }) => ( + + +
+ + )} + +
-
); + ); } } @@ -233,32 +230,34 @@ class DemoMultiFormat extends React.Component { }; } - onChange = (value) => { - console.log('Calendar change: ', (value && value.format(format))); + onChange = value => { + console.log('Calendar change: ', value && value.format(format)); this.setState({ value, }); - } + }; render() { - const state = this.state; - return (
-
- Accepts multiple input formats -
- {multiFormats.join(', ')} -
+ const { state } = this; + return ( +
+
+ Accepts multiple input formats +
+ {multiFormats.join(', ')} +
+
+
- -
); + ); } } @@ -272,41 +271,42 @@ function onStandaloneChange(value) { console.log(value && value.format(format)); } - -ReactDOM.render((
-
-
- ({mode} extra footer)} - /> -
-
- -
-
- -
-
+export default () => ( +
- +
+ {mode} extra footer} + /> +
+
+ +
+
+ +
+
+
+ +
-
), document.getElementById('__react-content')); +); diff --git a/examples/antd-month-calendar.html b/examples/antd-month-calendar.html deleted file mode 100644 index b3a425249..000000000 --- a/examples/antd-month-calendar.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/antd-month-calendar.js b/examples/antd-month-calendar.js index 15ed13f29..a84a0f971 100644 --- a/examples/antd-month-calendar.js +++ b/examples/antd-month-calendar.js @@ -1,21 +1,19 @@ /* eslint react/no-multi-comp:0, no-console:0 */ -import 'rc-calendar/assets/index.less'; +import '../assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; -import PropTypes from 'prop-types'; -import MonthCalendar from 'rc-calendar/src/MonthCalendar'; -import DatePicker from 'rc-calendar/src/Picker'; +import moment from 'moment'; +import MonthCalendar from '../src/MonthCalendar'; +import DatePicker from '../src/Picker'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import zhCN from '../src/locale/zh_CN'; +import enUS from '../src/locale/en_US'; -import moment from 'moment'; import 'moment/locale/zh-cn'; import 'moment/locale/en-gb'; const format = 'YYYY-MM'; -const cn = location.search.indexOf('cn') !== -1; +const cn = window.location.search.indexOf('cn') !== -1; const now = moment(); if (cn) { @@ -28,100 +26,88 @@ const defaultCalendarValue = now.clone(); defaultCalendarValue.add(-1, 'month'); class Demo extends React.Component { - static propTypes = { - defaultValue: PropTypes.object, - } - constructor(props) { super(props); this.state = { - showTime: true, disabled: false, value: props.defaultValue, }; } - onChange = (value) => { + onChange = value => { console.log(`DatePicker change: ${value && value.format(format)}`); this.setState({ value, }); - } - - onShowTimeChange = (e) => { - this.setState({ - showTime: e.target.checked, - }); - } + }; toggleDisabled = () => { + const { disabled } = this.state; this.setState({ - disabled: !this.state.disabled, + disabled: !disabled, }); - } + }; render() { - const state = this.state; - const calendar = (); - return (
-
-      - -
-
- ; + return ( +
+
+      + +
+
- { - ({ value }) => { - return ( + {({ value }) => ( + ); - } - } - - + /> + )} + +
-
); + ); } } function onStandaloneSelect(value) { - console.log('month-calendar select', (value && value.format(format))); + console.log('month-calendar select', value && value.format(format)); } function onStandaloneChange(value) { - console.log('month-calendar change', (value && value.format(format))); + console.log('month-calendar change', value && value.format(format)); } function disabledDate(value) { - return value.year() > now.year() || - value.year() === now.year() && value.month() > now.month(); + return value.year() > now.year() || (value.year() === now.year() && value.month() > now.month()); } function onMonthCellContentRender(value) { @@ -129,8 +115,8 @@ function onMonthCellContentRender(value) { return `${value.month() + 1}月`; } -ReactDOM.render( - (
( +
-
) - , document.getElementById('__react-content')); +
+); diff --git a/examples/antd-range-calendar.html b/examples/antd-range-calendar.html deleted file mode 100644 index b3a425249..000000000 --- a/examples/antd-range-calendar.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/antd-range-calendar.js b/examples/antd-range-calendar.js index 717d77a19..ec7e52486 100644 --- a/examples/antd-range-calendar.js +++ b/examples/antd-range-calendar.js @@ -1,20 +1,20 @@ /* eslint react/no-multi-comp:0, no-console:0 */ import React from 'react'; -import ReactDOM from 'react-dom'; -import Picker from 'rc-calendar/src/Picker'; -import RangeCalendar from 'rc-calendar/src/RangeCalendar'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import moment from 'moment'; import TimePickerPanel from 'rc-time-picker/lib/Panel'; -import 'rc-calendar/assets/index.less'; + +import Picker from '../src/Picker'; +import RangeCalendar from '../src/RangeCalendar'; +import zhCN from '../src/locale/zh_CN'; +import enUS from '../src/locale/en_US'; +import '../assets/index.less'; import 'rc-time-picker/assets/index.css'; -import moment from 'moment'; import 'moment/locale/zh-cn'; import 'moment/locale/en-gb'; -const cn = location.search.indexOf('cn') !== -1; +const cn = window.location.search.indexOf('cn') !== -1; if (cn) { moment.locale('zh-cn'); @@ -40,7 +40,7 @@ const timePickerElement = ( function newArray(start, end) { const result = []; - for (let i = start; i < end; i++) { + for (let i = start; i < end; i += 1) { result.push(i); } return result; @@ -51,7 +51,7 @@ function disabledDate(current) { date.hour(0); date.minute(0); date.second(0); - return current.isBefore(date); // can not select days before today + return current.isBefore(date); // can not select days before today } function disabledTime(time, type) { @@ -66,7 +66,8 @@ function disabledTime(time, type) { disabledMinutes(h) { if (h === 20) { return newArray(0, 31); - } else if (h === 23) { + } + if (h === 23) { return newArray(30, 60); } return []; @@ -85,7 +86,8 @@ function disabledTime(time, type) { disabledMinutes(h) { if (h === 20) { return newArray(0, 31); - } else if (h === 23) { + } + if (h === 23) { return newArray(30, 60); } return []; @@ -119,19 +121,19 @@ class Demo extends React.Component { state = { value: [], hoverValue: [], - } + }; - onChange = (value) => { + onChange = value => { console.log('onChange', value); this.setState({ value }); - } + }; - onHoverChange = (hoverValue) => { + onHoverChange = hoverValue => { this.setState({ hoverValue }); - } + }; render() { - const state = this.state; + const { state } = this; const calendar = ( ); return ( - - { - ({ value }) => { - return ( - - ); - } - } - ); + + {({ value }) => ( + + + + )} + + ); } } -ReactDOM.render( +export default () => (

calendar

@@ -194,4 +190,5 @@ ReactDOM.render(
-
, document.getElementById('__react-content')); +
+); diff --git a/examples/baisc.js b/examples/baisc.js new file mode 100644 index 000000000..1333b4626 --- /dev/null +++ b/examples/baisc.js @@ -0,0 +1,14 @@ +import React from 'react'; +import Calendar from '../src'; +import MonthCalendar from '../src/MonthCalendar'; + +export default () => ( + <> + { + console.log(value); + }} + /> + console.log(rest, ca)} /> + +); diff --git a/examples/control-panel.html b/examples/control-panel.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/control-panel.js b/examples/control-panel.js index 0a8ac633f..32e314fac 100644 --- a/examples/control-panel.js +++ b/examples/control-panel.js @@ -1,12 +1,10 @@ /* eslint react/no-multi-comp:0, no-console:0, no-unused-vars:0 */ -import 'rc-calendar/assets/index.less'; +import '../assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; -import Calendar from 'rc-calendar/src'; -import RangeCalendar from 'rc-calendar/src/RangeCalendar'; +import Calendar from '../src'; +import RangeCalendar from '../src/RangeCalendar'; -import Select, { Option } from 'rc-select'; -import 'rc-select/assets/index.css'; +import 'rc-select/assets/index.less'; class Demo extends React.Component { state = { @@ -15,8 +13,8 @@ class Demo extends React.Component { rangeEndMode: 'date', }; - onModeChange = (key) => { - return function _handleChange(e) { + onModeChange = key => + function _handleChange(e) { let mode; if (e && e.target) { mode = e.target.value; @@ -28,33 +26,27 @@ class Demo extends React.Component { [key]: mode, }); }.bind(this); - } handlePanelChange = (...args) => { console.log('on panel change', ...args); - } + }; handleRangePanelChange = (...args) => { console.log('on range panel change', ...args); - } + }; render() { return (

controle Calendar panel

- {['time', 'date', 'month', 'year', 'decade'].map(item => ( - + ))} - +

controle RangeCalendar panel

, document.getElementById('__react-content')); +export default Demo; diff --git a/examples/custom-clear-icon.html b/examples/custom-clear-icon.html deleted file mode 100644 index b3a425249..000000000 --- a/examples/custom-clear-icon.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/custom-clear-icon.js b/examples/custom-clear-icon.js index 93b8d4c36..6ea94fe9a 100644 --- a/examples/custom-clear-icon.js +++ b/examples/custom-clear-icon.js @@ -1,16 +1,16 @@ /* eslint react/no-multi-comp:0, no-console:0 */ -import 'rc-calendar/assets/index.less'; +import '../assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; -import Calendar from 'rc-calendar'; -import RangeCalendar from 'rc-calendar/src/RangeCalendar'; +import Calendar from '../src'; +import RangeCalendar from '../src/RangeCalendar'; import 'rc-time-picker/assets/index.css'; import 'moment/locale/zh-cn'; import 'moment/locale/en-gb'; -const clearPath = 'M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 ' + +const clearPath = + 'M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 ' + '290 92 102.3 279.5 102 511.5 101.7 743.7 289.8 932 521.9 932c181.3 0' + ' 335.8-115 394.6-276.1 1.5-4.2-0.7-8.9-4.9-10.3l-56.7-19.5c-4.1-1.4-8.6' + ' 0.7-10.1 4.8-1.8 5-3.8 10-5.9 14.9-17.3 41-42.1 77.8-73.7 109.4-31.6' + @@ -23,23 +23,24 @@ const clearPath = 'M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 ' + '-7.7l0.8-180.9c-0.1-6.6-7.8-10.3-13-6.2z'; const svg = ( - ); -const calendars = ['time', 'date', 'month', 'year', 'decade'].map((mode) => { - return ( -
-
{mode}
- -
- ); -}); +const calendars = ['time', 'date', 'month', 'year', 'decade'].map(mode => ( +
+
{mode}
+ +
+)); -ReactDOM.render((
-
-
- +export default () => ( +
+
+
+ +
+ {calendars} +
+
- {calendars} -
-
-
), document.getElementById('__react-content')); +); diff --git a/examples/full-calendar.html b/examples/full-calendar.html deleted file mode 100644 index b3a425249..000000000 --- a/examples/full-calendar.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/full-calendar.js b/examples/full-calendar.js index 2cf7ed64b..0bdf985b1 100644 --- a/examples/full-calendar.js +++ b/examples/full-calendar.js @@ -1,22 +1,22 @@ /* eslint react/no-multi-comp:0, no-console:0 */ -import 'rc-calendar/assets/index.less'; +import '../assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; -import FullCalendar from 'rc-calendar/src/FullCalendar'; - -import 'rc-select/assets/index.css'; import Select from 'rc-select'; +import moment from 'moment'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import FullCalendar from '../src/FullCalendar'; + +import 'rc-select/assets/index.less'; + +import zhCN from '../src/locale/zh_CN'; +import enUS from '../src/locale/en_US'; -import moment from 'moment'; import 'moment/locale/zh-cn'; import 'moment/locale/en-gb'; const format = 'YYYY-MM-DD'; -const cn = location.search.indexOf('cn') !== -1; +const cn = window.location.search.indexOf('cn') !== -1; const now = moment(); if (cn) { @@ -37,11 +37,11 @@ class Demo extends React.Component { type: 'month', }; - onTypeChange = (type) => { + onTypeChange = type => { this.setState({ type, }); - } + }; render() { return ( @@ -69,4 +69,4 @@ class Demo extends React.Component { } } -ReactDOM.render(, document.getElementById('__react-content')); +export default Demo; diff --git a/examples/getCalendarContainer.html b/examples/getCalendarContainer.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/getCalendarContainer.js b/examples/getCalendarContainer.js index fe3c4fd1a..088f35e6b 100644 --- a/examples/getCalendarContainer.js +++ b/examples/getCalendarContainer.js @@ -1,20 +1,20 @@ -import 'rc-calendar/assets/index.less'; +import '../assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; -import Calendar from 'rc-calendar'; -import DatePicker from 'rc-calendar/src/Picker'; import Dialog from 'rc-dialog'; +import moment from 'moment'; + +import Calendar from '../src'; +import DatePicker from '../src/Picker'; import 'rc-dialog/assets/index.css'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import zhCN from '../src/locale/zh_CN'; +import enUS from '../src/locale/en_US'; -import moment from 'moment'; import 'moment/locale/zh-cn'; import 'moment/locale/en-gb'; const format = 'YYYY-MM-DD'; -const cn = location.search.indexOf('cn') !== -1; +const cn = window.location.search.indexOf('cn') !== -1; const now = moment(); if (cn) { @@ -44,51 +44,58 @@ class Demo extends React.Component { open = () => { this.setVisible(true); - } + }; close = () => { this.setVisible(false); - } + }; destroy = () => { this.setState({ destroy: true, }); - } + }; render() { if (this.state.destroy) { return null; } - return (
- -   - - -
(this.d = n)} /> -
- } - > - { - ({ value }) => { - return ( - - + return ( +
+ +   + + +
{ + this.d = n; + }} + /> +
+ } + > + {({ value }) => ( + + - ); - } - } - -
-
-
); + )} +
+
+
+
+ ); } } -ReactDOM.render(, document.getElementById('__react-content')); +export default Demo; diff --git a/examples/start-end-range.html b/examples/start-end-range.html deleted file mode 100644 index b3a425249..000000000 --- a/examples/start-end-range.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/start-end-range.js b/examples/start-end-range.js index 013dfd1de..c5bb963ea 100644 --- a/examples/start-end-range.js +++ b/examples/start-end-range.js @@ -1,22 +1,21 @@ /* eslint react/no-multi-comp:0, no-console:0, react/prop-types:0 */ -import 'rc-calendar/assets/index.less'; +import '../assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; -import RangeCalendar from 'rc-calendar/src/RangeCalendar'; -import DatePicker from 'rc-calendar/src/Picker'; +import moment from 'moment'; +import RangeCalendar from '../src/RangeCalendar'; +import DatePicker from '../src/Picker'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import zhCN from '../src/locale/zh_CN'; +import enUS from '../src/locale/en_US'; -import moment from 'moment'; import 'moment/locale/zh-cn'; import 'moment/locale/en-gb'; const format = 'YYYY-MM-DD'; const fullFormat = 'YYYY-MM-DD dddd'; -const cn = location.search.indexOf('cn') !== -1; +const cn = window.location.search.indexOf('cn') !== -1; const now = moment(); if (cn) { @@ -30,13 +29,13 @@ class Picker extends React.Component { hoverValue: [], }; - onHoverChange = (hoverValue) => { + onHoverChange = hoverValue => { console.log(hoverValue); this.setState({ hoverValue }); - } + }; render() { - const props = this.props; + const { props } = this; const { showValue } = props; const calendar = ( ); + /> + ); return ( - { - () => { - return ( - - - - ); - } - } - ); + {() => ( + + + + )} + + ); } } @@ -82,45 +79,45 @@ class Demo extends React.Component { endOpen: false, }; - onStartOpenChange = (startOpen) => { + onStartOpenChange = startOpen => { this.setState({ startOpen, }); - } + }; - onEndOpenChange = (endOpen) => { + onEndOpenChange = endOpen => { this.setState({ endOpen, }); - } + }; - onStartChange = (value) => { + onStartChange = value => { this.setState({ startValue: value[0], startOpen: false, endOpen: true, }); - } + }; - onEndChange = (value) => { + onEndChange = value => { this.setState({ endValue: value[1], }); - } + }; - disabledStartDate = (endValue) => { + disabledStartDate = endValue => { if (!endValue) { return false; } - const startValue = this.state.startValue; + const { startValue } = this.state; if (!startValue) { return false; } return endValue.diff(startValue, 'days') < 0; - } + }; render() { - const state = this.state; + const { state } = this; return (

@@ -147,9 +144,9 @@ class Demo extends React.Component { onChange={this.onEndChange} />

-
); +
+ ); } } - -ReactDOM.render(, document.getElementById('__react-content')); +export default Demo; diff --git a/examples/start-end.html b/examples/start-end.html deleted file mode 100644 index b3a425249..000000000 --- a/examples/start-end.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/start-end.js b/examples/start-end.js index 8014be62b..fedf50657 100644 --- a/examples/start-end.js +++ b/examples/start-end.js @@ -1,22 +1,22 @@ /* eslint react/no-multi-comp:0, no-console:0 */ -import 'rc-calendar/assets/index.less'; +import '../assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; -import Calendar from 'rc-calendar'; -import DatePicker from 'rc-calendar/src/Picker'; +import moment from 'moment'; +import TimePickerPanel from 'rc-time-picker/lib/Panel'; + +import Calendar from '../src'; +import DatePicker from '../src/Picker'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; +import zhCN from '../src/locale/zh_CN'; +import enUS from '../src/locale/en_US'; import 'rc-time-picker/assets/index.css'; -import TimePickerPanel from 'rc-time-picker/lib/Panel'; -import moment from 'moment'; import 'moment/locale/zh-cn'; import 'moment/locale/en-gb'; const format = 'YYYY-MM-DD HH:mm:ss'; -const cn = location.search.indexOf('cn') !== -1; +const cn = window.location.search.indexOf('cn') !== -1; const now = moment(); if (cn) { @@ -29,54 +29,44 @@ function getFormat(time) { return time ? format : 'YYYY-MM-DD'; } - const defaultCalendarValue = now.clone(); defaultCalendarValue.add(-1, 'month'); const timePickerElement = ; - const SHOW_TIME = true; -class Picker extends React.Component { - state = { - showTime: SHOW_TIME, - disabled: false, - }; - - render() { - const props = this.props; - const calendar = ( { + const calendar = ( + ); - return ( + ); + return ( + - { - ({ value }) => { - return ( - - - - ); - } - } - ); - } -} + {({ value }) => ( + + + + )} + + ); +}; class Demo extends React.Component { state = { @@ -89,55 +79,54 @@ class Demo extends React.Component { this.setState({ [field]: value, }); - } + }; - disabledEndDate = (endValue) => { + disabledEndDate = endValue => { if (!endValue) { return false; } - const startValue = this.state.startValue; + const { startValue } = this.state; if (!startValue) { return false; } - return SHOW_TIME ? endValue.isBefore(startValue) : - endValue.diff(startValue, 'days') <= 0; - } + return SHOW_TIME ? endValue.isBefore(startValue) : endValue.diff(startValue, 'days') <= 0; + }; - disabledStartDate = (startValue) => { + disabledStartDate = startValue => { if (!startValue) { return false; } - const endValue = this.state.endValue; + const { endValue } = this.state; if (!endValue) { return false; } - return SHOW_TIME ? endValue.isBefore(startValue) : - endValue.diff(startValue, 'days') <= 0; - } + return SHOW_TIME ? endValue.isBefore(startValue) : endValue.diff(startValue, 'days') <= 0; + }; render() { - const state = this.state; - return (
-

- 开始时间: - -

- -

- 结束时间: - -

-
); + const { state } = this; + return ( +
+

+ 开始时间: + this.onChange('startValue', value)} + /> +

+ +

+ 结束时间: + this.onChange('endValue', value)} + /> +

+
+ ); } } - -ReactDOM.render(, document.getElementById('__react-content')); +export default Demo; diff --git a/examples/week.html b/examples/week.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/week.js b/examples/week.js index 245b98e02..27384dc3f 100644 --- a/examples/week.js +++ b/examples/week.js @@ -1,20 +1,18 @@ /* eslint react/no-multi-comp:0, no-console:0 */ -import 'rc-calendar/assets/index.less'; +import '../assets/index.less'; import React from 'react'; -import ReactDOM from 'react-dom'; -import PropTypes from 'prop-types'; -import Calendar from 'rc-calendar'; -import DatePicker from 'rc-calendar/src/Picker'; -import zhCN from 'rc-calendar/src/locale/zh_CN'; -import enUS from 'rc-calendar/src/locale/en_US'; - import moment from 'moment'; +import Calendar from '../src'; +import DatePicker from '../src/Picker'; +import zhCN from '../src/locale/zh_CN'; +import enUS from '../src/locale/en_US'; + import 'moment/locale/zh-cn'; import 'moment/locale/en-gb'; const format = 'YYYY-Wo'; -const cn = location.search.indexOf('cn') !== -1; +const cn = window.location.search.indexOf('cn') !== -1; const now = moment(); if (cn) { @@ -51,63 +49,60 @@ const style = ` `; class Demo extends React.Component { - static propTypes = { - defaultValue: PropTypes.object, - defaultCalendarValue: PropTypes.object, - } - state = { value: undefined, open: false, }; - onChange = (value) => { - console.log('DatePicker change: ', (value && value.format(format))); + onChange = value => { + console.log('DatePicker change: ', value && value.format(format)); this.setState({ value, }); - } + }; - onOpenChange = (open) => { + onOpenChange = open => { this.setState({ open, }); - } + }; - dateRender = (current) => { + dateRender = current => { const selectedValue = this.state.value; - if (selectedValue && current.year() === selectedValue.year() && - current.week() === selectedValue.week()) { - return (
-
- {current.date()} + if ( + selectedValue && + current.year() === selectedValue.year() && + current.week() === selectedValue.week() + ) { + return ( +
+
{current.date()}
-
); + ); } - return ( -
- {current.date()} -
); - } + return
{current.date()}
; + }; lastWeek = () => { - const value = this.state.value || now; + const { state } = this; + const value = state.value || now; value.add(-1, 'weeks'); this.setState({ value, open: false, }); - } + }; - renderSidebar() { - return ( -
- -
); - } + renderSidebar = () => ( +
+ +
+ ); render() { - const state = this.state; + const { state } = this; const calendar = ( ); - return (
-
- + ); + return ( +
+
- { - ({ value }) => { - return ( - + + {({ value }) => ( + - - ); - } - } - + + )} + +
-
); + ); } } -ReactDOM.render((
-