Skip to content

Commit

Permalink
Controlled Panels (#284)
Browse files Browse the repository at this point in the history
* refactor: simply relation between header and panels

* feat: make DatePicker's mode and onPanelChange works

* feat: make RangePicker's mode and onPanelChange works

* test: add test cases and fix some bugs

* chore: update API and API docs

* docs: add demo about control panel

* chore: update details
  • Loading branch information
benjycui authored and paranoidjk committed Aug 1, 2017
1 parent 4f9d518 commit 329186a
Show file tree
Hide file tree
Showing 13 changed files with 6,111 additions and 131 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,18 @@ http://react-component.github.io/calendar/examples/index.html
<td></td>
<td>date input's placeholder</td>
</tr>
<tr>
<td>mode</td>
<td>enum('time', 'date', 'month', 'year', 'decade')</td>
<td>'date'</td>
<td>controll which kind of panel should be shown</td>
</tr>
<tr>
<td>onPanelChange</td>
<td>Function(date: moment, mode)</td>
<td></td>
<td>called when panel changed</td>
</tr>
</tbody>
</table>

Expand Down Expand Up @@ -348,6 +360,18 @@ http://react-component.github.io/calendar/examples/index.html
<td>both</td>
<td>whether fix start or end selected value. check start-end-range example</td>
</tr>
<tr>
<td>mode</td>
<td>enum('date', 'month', 'year', 'decade')[]</td>
<td>['date', 'date']</td>
<td>controll which kind of panels should be shown</td>
</tr>
<tr>
<td>onPanelChange</td>
<td>Function(date: moment[], mode)</td>
<td></td>
<td>called when panels changed</td>
</tr>
</tbody>
</table>

Expand Down
Empty file added examples/control-panel.html
Empty file.
84 changes: 84 additions & 0 deletions examples/control-panel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* eslint react/no-multi-comp:0, no-console:0, no-unused-vars:0 */
import 'rc-calendar/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 Select, { Option } from 'rc-select';
import 'rc-select/assets/index.css';

const App = React.createClass({
getInitialState() {
return {
mode: 'month',
rangeStartMode: 'date',
rangeEndMode: 'date',
};
},
onModeChange(key) {
return function _handleChange(e) {
let mode;
if (e && e.target) {
mode = e.target.value;
} else {
mode = e;
}
console.log('change to: ', mode);
this.setState({
[key]: mode,
});
}.bind(this);
},
handlePanelChange(...args) {
console.log('on panel change', ...args);
},
handleRangePanelChange(...args) {
console.log('on range panel change', ...args);
},
render() {
return (
<div style={{ zIndex: 1000, position: 'relative' }}>
<h2>controle Calendar panel</h2>
<select
value={this.state.mode}
style={{ width: 500 }}
onChange={this.onModeChange('mode')}
>
{['time', 'date', 'month', 'year', 'decade'].map(item => (
<option value={item} key={item}>{item}</option>
))}
</select>
<Calendar
mode={this.state.mode}
onPanelChange={this.handlePanelChange}
/>
<h2>controle RangeCalendar panel</h2>
<select
value={this.state.rangeStartMode}
style={{ width: 500 }}
onChange={this.onModeChange('rangeStartMode')}
>
{['date', 'month', 'year', 'decade'].map(item => (
<option value={item} key={item}>{item}</option>
))}
</select>
<select
value={this.state.rangeEndMode}
style={{ width: 500 }}
onChange={this.onModeChange('rangeEndMode')}
>
{['date', 'month', 'year', 'decade'].map(item => (
<option value={item} key={item}>{item}</option>
))}
</select>
<RangeCalendar
mode={[this.state.rangeStartMode, this.state.rangeEndMode]}
onPanelChange={this.handleRangePanelChange}
/>
</div>
);
},
});

ReactDOM.render(<App />, document.getElementById('__react-content'));
52 changes: 32 additions & 20 deletions src/Calendar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,27 +50,28 @@ function goDay(direction) {

const Calendar = createReactClass({
propTypes: {
disabledDate: PropTypes.func,
disabledTime: PropTypes.any,
prefixCls: PropTypes.string,
className: PropTypes.string,
style: PropTypes.object,
defaultValue: PropTypes.object,
value: PropTypes.object,
selectedValue: PropTypes.object,
defaultValue: PropTypes.object,
className: PropTypes.string,
mode: PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade']),
locale: PropTypes.object,
showDateInput: PropTypes.bool,
showWeekNumber: PropTypes.bool,
style: PropTypes.object,
showToday: PropTypes.bool,
showDateInput: PropTypes.bool,
visible: PropTypes.bool,
showOk: PropTypes.bool,
onSelect: PropTypes.func,
onOk: PropTypes.func,
showOk: PropTypes.bool,
prefixCls: PropTypes.string,
onKeyDown: PropTypes.func,
timePicker: PropTypes.element,
dateInputPlaceholder: PropTypes.any,
onClear: PropTypes.func,
onChange: PropTypes.func,
onPanelChange: PropTypes.func,
disabledDate: PropTypes.func,
disabledTime: PropTypes.any,
renderFooter: PropTypes.func,
renderSidebar: PropTypes.func,
},
Expand All @@ -83,13 +84,19 @@ const Calendar = createReactClass({
showDateInput: true,
timePicker: null,
onOk: noop,
onPanelChange: noop,
};
},
getInitialState() {
return {
showTimePicker: false,
mode: this.props.mode || 'date',
};
},
componentWillReceiveProps(nextProps) {
if ('mode' in nextProps && this.state.mode !== nextProps.mode) {
this.setState({ mode: nextProps.mode });
}
},
onKeyDown(event) {
if (event.target.nodeName.toLowerCase() === 'input') {
return undefined;
Expand Down Expand Up @@ -189,28 +196,31 @@ const Calendar = createReactClass({
source: 'todayButton',
});
},
onPanelChange(mode) {
const { props, state } = this;
if (!('mode' in props)) {
this.setState({ mode });
}
props.onPanelChange(state.value, mode);
},
getRootDOMNode() {
return ReactDOM.findDOMNode(this);
},
openTimePicker() {
this.setState({
showTimePicker: true,
});
this.onPanelChange('time');
},
closeTimePicker() {
this.setState({
showTimePicker: false,
});
this.onPanelChange('date');
},
render() {
const props = this.props;
const { props, state } = this;
const {
locale, prefixCls, disabledDate,
dateInputPlaceholder, timePicker,
disabledTime,
} = props;
const state = this.state;
const { value, selectedValue, showTimePicker } = state;
const { value, selectedValue, mode } = state;
const showTimePicker = mode === 'time';
const disabledTimeConfig = showTimePicker && disabledTime && timePicker ?
getTimeConfig(selectedValue, disabledTime) : null;

Expand Down Expand Up @@ -248,8 +258,10 @@ const Calendar = createReactClass({
<div className={`${prefixCls}-date-panel`}>
<CalendarHeader
locale={locale}
onValueChange={this.setValue}
mode={mode}
value={value}
onValueChange={this.setValue}
onPanelChange={this.onPanelChange}
showTimePicker={showTimePicker}
prefixCls={prefixCls}
/>
Expand Down
Loading

0 comments on commit 329186a

Please sign in to comment.