Skip to content

Commit

Permalink
Merge 8b44a7d into 3f6ef0d
Browse files Browse the repository at this point in the history
  • Loading branch information
magom001 committed May 16, 2018
2 parents 3f6ef0d + 8b44a7d commit 84ed45d
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 178 deletions.
237 changes: 137 additions & 100 deletions lib/DatePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,123 +2,160 @@
* @module DatePicker Component
*/

import React, { Component } from 'react';
import DatePickerItem from './DatePickerItem.js';
import PureRender from './pureRender.js';
import { convertDate, nextDate } from './time.js';
import React, { Component } from "react";
import DatePickerItem from "./DatePickerItem.js";
import PureRender from "./pureRender.js";
import { convertDate, nextDate } from "./time.js";

type Props = {
theme: string,
value: Object,
min: Object,
max: Object,
customHeader?: React.Element<*>,
showHeader: boolean,
dateFormat: Array<*>,
dateSteps: Array<*>,
showFormat: string,
confirmText: string,
cancelText: string,
onSelect: Function,
onCancel: Function,
}
theme: string,
value: Object,
min: Object,
max: Object,
customHeader?: React.Element<*>,
showHeader: boolean,
dateFormat: Array<*>,
dateSteps: Array<*>,
showFormat: string,
confirmText: string,
cancelText: string,
onSelect: Function,
onCancel: Function
};

type State = {
value: Date,
}
value: Date
};

/**
* Class DatePicker Component Class
* @extends Component
*/
class DatePicker extends Component<void, Props, State> {
constructor(props) {
super(props);
this.state = {
value: nextDate(this.props.value),
};
constructor(props) {
super(props);
this.state = {
value: nextDate(this.props.value)
};

this.handleFinishBtnClick = this.handleFinishBtnClick.bind(this);
this.handleDateSelect = this.handleDateSelect.bind(this);
}
this.handleFinishBtnClick = this.handleFinishBtnClick.bind(this);
this.handleDateSelect = this.handleDateSelect.bind(this);
}

componentWillReceiveProps(nextProps) {
// update value of state
const date = nextDate(nextProps.value);
if (date.getTime() !== this.state.value.getTime()) {
this.setState({ value: date });
}
componentDidUpdate() {
const value = this.state.value;
const { min, max } = this.props;
if (value.getTime() > max.getTime()) {
this.setState({ value: max });
}

/**
* Optimization component, Prevents unnecessary rendering
* Only props or state change or value before re-rendering
*
* @param {Object} nextProps next props
* @param {Object} nextState next state
* @return {Boolean} Whether re-rendering
*/
shouldComponentUpdate(nextProps, nextState) {
const date = nextDate(nextState.value);
return date.getTime() !== this.state.value.getTime() ||
PureRender.shouldComponentUpdate(nextProps, nextState, this.props, this.state);
if (value.getTime() < min.getTime()) {
this.setState({ value: min });
}
}

/**
* 点击完成按钮事件
* @return {undefined}
*/
handleFinishBtnClick() {
this.props.onSelect(this.state.value);
componentWillReceiveProps(nextProps) {
// update value of state
const date = nextDate(nextProps.value);
if (date.getTime() !== this.state.value.getTime()) {
this.setState({ value: date });
}
}

/**
* 选择下一个日期
* @return {undefined}
*/
handleDateSelect(value) {
this.setState({ value });
}
/**
* Optimization component, Prevents unnecessary rendering
* Only props or state change or value before re-rendering
*
* @param {Object} nextProps next props
* @param {Object} nextState next state
* @return {Boolean} Whether re-rendering
*/
shouldComponentUpdate(nextProps, nextState) {
const date = nextDate(nextState.value);
return (
date.getTime() !== this.state.value.getTime() ||
PureRender.shouldComponentUpdate(
nextProps,
nextState,
this.props,
this.state
)
);
}

/**
* render函数
* @return {Object} JSX对象
*/
render() {
const { min, max, theme, dateFormat, confirmText, cancelText, showFormat, showHeader, customHeader, dateSteps } = this.props;
const value = this.state.value;
const themeClassName =
['default', 'dark', 'ios', 'android', 'android-dark'].indexOf(theme) === -1 ?
'default' : theme;

return (
<div
className={`datepicker ${themeClassName}`}>
{showHeader &&
<div className="datepicker-header">{customHeader || convertDate(value, showFormat)}</div>}
<div className="datepicker-content">
{dateFormat.map((format, index) => (
<DatePickerItem
key={index}
step={dateSteps[index] || 1}
value={value}
min={min}
max={max}
format={format}
onSelect={this.handleDateSelect} />
))}
</div>
<div className="datepicker-navbar">
<a
className="datepicker-navbar-btn"
onClick={this.handleFinishBtnClick}>{confirmText}</a>
<a
className="datepicker-navbar-btn"
onClick={this.props.onCancel}>{cancelText}</a>
</div>
</div>
);
}
}
/**
* 点击完成按钮事件
* @return {undefined}
*/
handleFinishBtnClick() {
this.props.onSelect(this.state.value);
}

/**
* 选择下一个日期
* @return {undefined}
*/
handleDateSelect(value) {
this.setState({ value });
}

/**
* render函数
* @return {Object} JSX对象
*/
render() {
const {
min,
max,
theme,
dateFormat,
confirmText,
cancelText,
showFormat,
showHeader,
customHeader,
dateSteps
} = this.props;
const value = this.state.value;
const themeClassName =
["default", "dark", "ios", "android", "android-dark"].indexOf(theme) ===
-1
? "default"
: theme;

return (
<div className={`datepicker ${themeClassName}`}>
{showHeader && (
<div className="datepicker-header">
{customHeader || convertDate(value, showFormat)}
</div>
)}
<div className="datepicker-content">
{dateFormat.map((format, index) => (
<DatePickerItem
key={index}
step={dateSteps[index] || 1}
value={value}
min={min}
max={max}
format={format}
onSelect={this.handleDateSelect}
/>
))}
</div>
<div className="datepicker-navbar">
<a
className="datepicker-navbar-btn"
onClick={this.handleFinishBtnClick}
>
{confirmText}
</a>
<a className="datepicker-navbar-btn" onClick={this.props.onCancel}>
{cancelText}
</a>
</div>
</div>
);
}
}

export default DatePicker;
Loading

0 comments on commit 84ed45d

Please sign in to comment.