Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Controlled Panels #284

Merged
merged 7 commits into from
Aug 1, 2017
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

新增 API mode & onPanelChange 用于控制当前展示的面板。

<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>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RangeCalendar 还不支持受控展示 timePicker,交互有点冲突。

<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
49 changes: 31 additions & 18 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',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaultProps?

Copy link
Member Author

@benjycui benjycui Aug 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

高阶用法,就不提供非受控的模式了。

我更新下。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里还是不能改,mode 这种可是受控属性,不能设置默认值的。

由于受控面板属于高阶用法,也不准备支持 defaultMode

};
},
componentWillReceiveProps(nextProps) {
if ('mode' in nextProps) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

判断一下 nextProps.mode !== this.state.mode 再 setState 吧,vdom 的计算也是成本

this.setState({ mode: nextProps.mode });
}
},
onKeyDown(event) {
if (event.target.nodeName.toLowerCase() === 'input') {
return undefined;
Expand Down Expand Up @@ -189,18 +196,21 @@ const Calendar = createReactClass({
source: 'todayButton',
});
},
onPanelChange(mode) {
const { props, state } = this;
if (!('mode' in props)) {
this.setState({ mode });
}
props.onPanelChange(state.value, mode);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里其实有个小争议点,文档写的 onPanelChange 是 panel change 的回到。

但比如我刚加的 demo, 在 受控模式下,认为的改变 props.mode 引发的 panel change 是否要触发这个回调呢?目前是没有的

Copy link
Member Author

@benjycui benjycui Aug 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

但比如我刚加的 demo, 在 受控模式下,认为的改变 props.mode 引发的 panel change 是否要触发这个回调呢?目前是没有的

这种先忽略,目前我们不少的表单控件都不会因为人工重置 value 而触发 onChange

},
getRootDOMNode() {
return ReactDOM.findDOMNode(this);
},
openTimePicker() {
this.setState({
showTimePicker: true,
});
this.onPanelChange('time');
},
closeTimePicker() {
this.setState({
showTimePicker: false,
});
this.onPanelChange('date');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里可以把默认的 mode 抽离成全局变量 defaultMode = 'date', 可维护性好一点

Copy link
Member Author

@benjycui benjycui Aug 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个 +1,不过现在 rc-calendar 里面直接使用字符串的地方太多了,你后边再单独一个 commit 更新这些 code style 吧,顺便熟悉 rc-calendar 的代码。

},
render() {
const props = this.props;
Expand All @@ -210,7 +220,8 @@ const Calendar = createReactClass({
disabledTime,
} = props;
const state = this.state;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

冗余的赋值,直接解构好了

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 +259,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
47 changes: 36 additions & 11 deletions src/RangeCalendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import TimePickerButton from './calendar/TimePickerButton';
import CommonMixin from './mixin/CommonMixin';
import { syncTime, getTodayTime, isAllowedDate } from './util/';

function noop() {
}
function noop() {}

function isEmptyArray(arr) {
return Array.isArray(arr) && (arr.length === 0 || arr.every(i => !i));
Expand Down Expand Up @@ -62,6 +61,7 @@ const RangeCalendar = createReactClass({
defaultValue: PropTypes.any,
value: PropTypes.any,
hoverValue: PropTypes.any,
mode: PropTypes.arrayOf(PropTypes.oneOf(['date', 'month', 'year', 'decade'])),
timePicker: PropTypes.any,
showOk: PropTypes.bool,
showToday: PropTypes.bool,
Expand All @@ -74,6 +74,7 @@ const RangeCalendar = createReactClass({
onSelect: PropTypes.func,
onValueChange: PropTypes.func,
onHoverChange: PropTypes.func,
onPanelChange: PropTypes.func,
format: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
onClear: PropTypes.func,
type: PropTypes.any,
Expand All @@ -89,6 +90,7 @@ const RangeCalendar = createReactClass({
defaultSelectedValue: [],
onValueChange: noop,
onHoverChange: noop,
onPanelChange: noop,
disabledTime: noop,
showToday: true,
};
Expand All @@ -105,8 +107,7 @@ const RangeCalendar = createReactClass({
hoverValue: props.hoverValue || [],
value,
showTimePicker: false,
isStartMonthYearPanelShow: false,
isEndMonthYearPanelShow: false,
mode: props.mode || ['date', 'date'],
};
},

Expand All @@ -128,6 +129,9 @@ const RangeCalendar = createReactClass({
newState.prevSelectedValue = nextProps.selectedValue;
this.setState(newState);
}
if ('mode' in nextProps) {
this.setState({ mode: nextProps.mode });
}
},

onDatePanelEnter() {
Expand Down Expand Up @@ -243,12 +247,26 @@ const RangeCalendar = createReactClass({
return this.fireValueChange(value);
},

onStartPanelChange({ showMonthPanel, showYearPanel }) {
this.setState({ isStartMonthYearPanelShow: showMonthPanel || showYearPanel });
onStartPanelChange(mode) {
const { props, state } = this;
const newMode = [mode, state.mode[1]];
if (!('mode' in props)) {
this.setState({
mode: newMode,
});
}
props.onPanelChange(state.value, newMode);
},

onEndPanelChange({ showMonthPanel, showYearPanel }) {
this.setState({ isEndMonthYearPanelShow: showMonthPanel || showYearPanel });
onEndPanelChange(mode) {
const { props, state } = this;
const newMode = [state.mode[0], mode];
if (!('mode' in props)) {
this.setState({
mode: newMode,
});
}
props.onPanelChange(state.value, newMode);
},

getStartValue() {
Expand Down Expand Up @@ -316,6 +334,10 @@ const RangeCalendar = createReactClass({
isAllowedDate(selectedValue[1], this.props.disabledDate, this.disabledEndTime);
},

isMonthYearPanelShow(mode) {
return ['month', 'year', 'decade'].includes(mode);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

includes 是 es6 的方法 http://kangax.github.io/compat-table/es2016plus/

改用 indexOf ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

现在 antd 会要求低版本浏览器引入 polyfill 的。

Copy link
Member

@paranoidjk paranoidjk Aug 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里还是建议改一下,毕竟是底层的 rc-components, 小坑埋得越少越好

},

hasSelectedValue() {
const { selectedValue } = this.state;
return !!selectedValue[1] && !!selectedValue[0];
Expand Down Expand Up @@ -416,7 +438,6 @@ const RangeCalendar = createReactClass({
render() {
const props = this.props;
const state = this.state;
const { showTimePicker, isStartMonthYearPanelShow, isEndMonthYearPanelShow } = state;
const {
prefixCls, dateInputPlaceholder,
timePicker, showOk, locale, showClear,
Expand All @@ -425,6 +446,8 @@ const RangeCalendar = createReactClass({
const {
hoverValue,
selectedValue,
mode,
showTimePicker,
} = state;
const className = {
[props.className]: !!props.className,
Expand Down Expand Up @@ -501,14 +524,15 @@ const RangeCalendar = createReactClass({
disabledMonth={this.disabledStartMonth}
format={this.getFormat()}
value={startValue}
mode={mode[0]}
placeholder={placeholder1}
onInputSelect={this.onStartInputSelect}
onValueChange={this.onStartValueChange}
onPanelChange={this.onStartPanelChange}
timePicker={timePicker}
showTimePicker={showTimePicker}
enablePrev
enableNext={!isClosestMonths || isEndMonthYearPanelShow}
enableNext={!isClosestMonths || this.isMonthYearPanelShow(mode[1])}
/>
<span className={`${prefixCls}-range-middle`}>~</span>
<CalendarPart
Expand All @@ -520,14 +544,15 @@ const RangeCalendar = createReactClass({
timePickerDisabledTime={this.getEndDisableTime()}
placeholder={placeholder2}
value={endValue}
mode={mode[1]}
onInputSelect={this.onEndInputSelect}
onValueChange={this.onEndValueChange}
onPanelChange={this.onEndPanelChange}
timePicker={timePicker}
showTimePicker={showTimePicker}
disabledTime={this.disabledEndTime}
disabledMonth={this.disabledEndMonth}
enablePrev={!isClosestMonths || isStartMonthYearPanelShow}
enablePrev={!isClosestMonths || this.isMonthYearPanelShow(mode[0])}
enableNext
/>
</div>
Expand Down
Loading