react-mobile-datepicker
Advanced tools
Comparing version 1.0.16 to 2.0.0
@@ -0,1 +1,7 @@ | ||
v2.0.0 - Mon, 04 Jul 2016 10:48:22 GMT | ||
-------------------------------------- | ||
- | ||
v1.0.16 - Mon, 27 Jun 2016 09:08:47 GMT | ||
@@ -2,0 +8,0 @@ --------------------------------------- |
@@ -6,8 +6,4 @@ /** | ||
import React, { Component, PropTypes } from 'react'; | ||
import { nextTime, getTimeName } from './time.js'; | ||
import { | ||
TRANSITION, | ||
TRANSFORM, | ||
TRANSFORM_CSS, | ||
} from './transition'; | ||
import DatePickerItem from './DatePickerItem.js'; | ||
import { nextDate, getTime } from './time.js'; | ||
@@ -20,86 +16,27 @@ /** | ||
constructor(props) { | ||
super(props); | ||
const dates = Array(...Array(5)).map((value, index) => { | ||
const now = nextTime(props.startDate, index - 2); | ||
return { | ||
name: getTimeName(now), | ||
value: now, | ||
angle: (2 - index) * 22.5, | ||
}; | ||
}); | ||
this.animating = false; // 判断是否在transition过渡动画之中 | ||
this.touchY = 0; // 保存touchstart的pageY | ||
this.angle = 0; // 容器转过的角度 | ||
super(props); // 容器转过的角度 | ||
this.state = { | ||
angle: 0, | ||
dates, | ||
date: this._productDate(props.date), | ||
minDate: this._productDate(props.minDate), | ||
maxDate: this._productDate(props.maxDate), | ||
}; | ||
this.handleFinishBtnClick = this.handleFinishBtnClick.bind(this); | ||
this.renderDatepickerItem = this.renderDatepickerItem.bind(this); | ||
this.handleContentTouch = this.handleContentTouch.bind(this); | ||
this.handleContentTransitionEnd = this.handleContentTransitionEnd.bind(this); | ||
this._moveToNext = this._moveToNext.bind(this); | ||
this.handleDateSelect = this.handleDateSelect.bind(this); | ||
} | ||
/** | ||
* 根据角度返回透明度(0-1之间) | ||
* @param {number} angle 角度 | ||
* @return | ||
*/ | ||
_setOpacity(angle) { | ||
return angle > 0 | ||
? ((40 - angle) / 40 * 100 | 0) / 100 | ||
: ((40 + angle) / 40 * 100 | 0) / 100; | ||
} | ||
/** | ||
* 清除对象的transition样式 | ||
* @param {Dom} obj 指定的对象 | ||
* @return {undefined} | ||
*/ | ||
_clearTransition(obj) { | ||
obj.style[TRANSITION] = ''; // eslint-disable-line | ||
_productDate(date) { | ||
const nDate = nextDate(date, 0); | ||
return { | ||
value: nDate, | ||
timestamp: nDate.getTime(), | ||
Year: getTime(nDate, 'Year'), | ||
Month: getTime(nDate, 'Month'), | ||
Date: getTime(nDate, 'Date'), | ||
}; | ||
} | ||
/** | ||
* 滑动到下一日期 | ||
* @param {number} direction 滑动方向 | ||
* @return {undefined} | ||
*/ | ||
_moveToNext(direction) { | ||
const scroll = this.refs.scroll; | ||
const angle = this.angle; | ||
const { maxDate, minDate } = this.props; | ||
const date = (direction === 1) ? | ||
this.state.dates.find(value => | ||
value.value.getTime() > nextTime(maxDate, 0).getTime() && | ||
angle + direction * 22.5 + value.angle === 0) : | ||
this.state.dates.find(value => | ||
value.value.getTime() < nextTime(minDate, 0).getTime() && | ||
angle + direction * 22.5 + value.angle === 0); | ||
if (date) { | ||
this._moveTo(scroll, angle); | ||
} else { | ||
this._moveTo(scroll, angle + direction * 22.5); | ||
} | ||
} | ||
/** | ||
* 添加滑动动画 | ||
* @param {DOM} obj DOM对象 | ||
* @param {number} angle 角度 | ||
* @return {undefined} | ||
*/ | ||
_moveTo(obj, angle) { | ||
this.animating = true; | ||
obj.style[TRANSITION] = `${TRANSFORM_CSS} .2s ease-out`; // eslint-disable-line | ||
this.setState({ | ||
angle, | ||
}); | ||
} | ||
/** | ||
* 点击完成按钮事件 | ||
@@ -109,79 +46,14 @@ * @return {undefined} | ||
handleFinishBtnClick() { | ||
const date = this.state.dates.find(value => value.angle + this.state.angle === 0); | ||
this.props.onSelect(date.value); | ||
this.props.onSelect(this.state.date.value); | ||
} | ||
/** | ||
* 滑动日期选择器事件 | ||
* @param {Object} event 事件对象 | ||
* 选择下一个日期 | ||
* @return {undefined} | ||
*/ | ||
handleContentTouch(event) { | ||
event.preventDefault(); | ||
if (this.animating) return; | ||
if (event.type === 'touchstart') { | ||
this.touchY = event.targetTouches[0].pageY; | ||
this.angle = this.state.angle; | ||
} else if (event.type === 'touchmove') { | ||
const touchY = event.targetTouches[0].pageY; | ||
const dir = touchY - this.touchY; | ||
const angle = this.angle - parseInt(22.5 * dir / 180, 10); | ||
this.setState({ angle }); | ||
} else if (event.type === 'touchend') { | ||
const touchY = event.changedTouches[0].pageY; | ||
const dir = touchY - this.touchY; | ||
const direction = dir > 0 ? -1 : 1; | ||
if ((direction === 1 && this.props.touchLen < -dir) || | ||
(direction === -1 && this.props.touchLen < dir)) { | ||
this._moveToNext(direction); | ||
} else { | ||
this._moveTo(this.refs.scroll, this.angle); | ||
} | ||
} | ||
handleDateSelect(date) { | ||
this.setState({ date: this._productDate(date) }); | ||
} | ||
/** | ||
* transition过渡完成事件 | ||
* @return {undefined} | ||
*/ | ||
handleContentTransitionEnd() { | ||
const { dates, angle } = this.state; | ||
const date = dates.find(value => value.angle + angle === 0); | ||
const newDates = Array(...Array(5)).map((value, index) => { | ||
const now = nextTime(date.value, index - 2); | ||
return { | ||
name: getTimeName(now), | ||
value: now, | ||
angle: (2 - index) * 22.5, | ||
}; | ||
}); | ||
this.animating = false; | ||
this._clearTransition(this.refs.scroll); | ||
this.setState({ | ||
dates: newDates, | ||
angle: 0, | ||
}); | ||
} | ||
/** | ||
* 渲染一个日期DOM对象 | ||
* @param {Object} date date数据 | ||
* @return {Object} JSX对象 | ||
*/ | ||
renderDatepickerItem(date) { | ||
const itemStyle = { | ||
[TRANSFORM]: `rotateX(${date.angle}deg) translate3d(0,0,100px)`, | ||
opacity: this._setOpacity(date.angle + this.state.angle), | ||
color: this.props.dateColor, | ||
}; | ||
return ( | ||
<li | ||
key={date.value} | ||
style={itemStyle}> | ||
{date.name} | ||
</li> | ||
); | ||
} | ||
/** | ||
* render函数 | ||
@@ -191,7 +63,4 @@ * @return {Object} JSX对象 | ||
render() { | ||
const { layerBackground, btnColor } = this.props; | ||
const scrollStyle = { | ||
[TRANSFORM]: `rotateX(${this.state.angle}deg)`, | ||
}; | ||
const { layerBackground, btnColor, touchLen, dateColor } = this.props; | ||
const { date, minDate, maxDate } = this.state; | ||
const datePickerStyle = { | ||
@@ -211,17 +80,27 @@ backgroundColor: layerBackground, | ||
</p> | ||
<div | ||
ref="parent" | ||
className="datepicker-content" | ||
onTouchStart={this.handleContentTouch} | ||
onTouchMove={this.handleContentTouch} | ||
onTouchEnd={this.handleContentTouch} | ||
onTransitionEnd={this.handleContentTransitionEnd}> | ||
<div className="datepicker-viewport"> | ||
<ul | ||
ref="scroll" | ||
className="datepicker-scroll" | ||
style={scrollStyle}> | ||
{this.state.dates.map(this.renderDatepickerItem)} | ||
</ul> | ||
</div> | ||
<div className="datepicker-content"> | ||
<DatePickerItem | ||
date={date} | ||
typeName="Year" | ||
minDate={minDate} | ||
maxDate={maxDate} | ||
touchLen={touchLen} | ||
dateColor={dateColor} | ||
onSelect={this.handleDateSelect} /> | ||
<DatePickerItem | ||
date={date} | ||
typeName="Month" | ||
minDate={minDate} | ||
maxDate={maxDate} | ||
touchLen={touchLen} | ||
dateColor={dateColor} | ||
onSelect={this.handleDateSelect} /> | ||
<DatePickerItem | ||
date={date} | ||
typeName="Date" | ||
minDate={minDate} | ||
maxDate={maxDate} | ||
touchLen={touchLen} | ||
dateColor={dateColor} | ||
onSelect={this.handleDateSelect} /> | ||
</div> | ||
@@ -238,3 +117,3 @@ </div> | ||
layerBackground: PropTypes.string, | ||
startDate: PropTypes.object, | ||
date: PropTypes.object, | ||
minDate: PropTypes.object, | ||
@@ -250,5 +129,5 @@ maxDate: PropTypes.object, | ||
layerBackground: '#ffa70b', | ||
startDate: nextTime(new Date(), 0), | ||
minDate: nextTime(new Date(), -30), | ||
maxDate: nextTime(new Date(), 0), | ||
date: new Date(), | ||
minDate: new Date(1970, 0, 1), | ||
maxDate: new Date(2050, 0, 1), | ||
onSelect: () => {}, | ||
@@ -255,0 +134,0 @@ }; |
@@ -5,4 +5,3 @@ /** | ||
function convertDate(timestamp, formate) { | ||
const date = new Date(timestamp); | ||
function convertDate(date, formate) { | ||
const year = date.getFullYear(); | ||
@@ -24,2 +23,9 @@ const month = date.getMonth() + 1; | ||
function throwIfInvalidDate(date) { | ||
if (Object.prototype.toString.call(date, null) !== '[object Date]') { | ||
throw new Error('参数类型不对'); | ||
} | ||
} | ||
/** | ||
@@ -30,34 +36,41 @@ * 获取相对日期的偏移日期 | ||
*/ | ||
export function nextTime(now = new Date(), index = 1) { | ||
if (Object.prototype.toString.call(now, null) !== '[object Date]') { | ||
throw new Error('参数类型不对'); | ||
} | ||
export function nextYear(now, index = 0) { | ||
throwIfInvalidDate(now); | ||
const date = new Date(now.getFullYear() + index, now.getMonth(), now.getDate()); | ||
return date; | ||
} | ||
const date = new Date(now.getFullYear(), now.getMonth(), now.getDate()); | ||
date.setDate(now.getDate() + index); | ||
export function nextMonth(now, index = 0) { | ||
throwIfInvalidDate(now); | ||
const date = new Date(now.getFullYear(), now.getMonth() + index, now.getDate()); | ||
return date; | ||
} | ||
export function nextDate(now, index = 0) { | ||
throwIfInvalidDate(now); | ||
const date = new Date(now.getFullYear(), now.getMonth(), now.getDate() + index); | ||
return date; | ||
} | ||
/** | ||
* 获取指定日期的格式化日期名称 | ||
* 获取指定日期年,月或日 | ||
* @param {Date} 日期 | ||
* @return {String} 格式化日期名称 | ||
*/ | ||
export function getTimeName(now) { | ||
if (Object.prototype.toString.call(now, null) !== '[object Date]') { | ||
throw new Error('参数类型不对'); | ||
} | ||
const expection = { | ||
[convertDate(new Date().getTime(), 'YYYY-MM-DD')]: '今天', | ||
[convertDate(nextTime(new Date(), -1).getTime(), 'YYYY-MM-DD')]: '昨天', | ||
export function getTime(date, type) { | ||
throwIfInvalidDate(date); | ||
const units = { | ||
Year: ['YYYY', '年'], | ||
Month: ['MM', '月'], | ||
Date: ['DD', '日'], | ||
}; | ||
const timeStamp = now.getTime(); | ||
const result = convertDate(timeStamp, 'YYYY-MM-DD'); | ||
if (!units[type]) throw new Error('类型不对'); | ||
if (expection[result]) { | ||
return expection[result]; | ||
} | ||
const result = { | ||
value: parseInt(convertDate(date, units[type][0]), 10), | ||
suffix: units[type][1], | ||
}; | ||
return result; | ||
} |
{ | ||
"name": "react-mobile-datepicker", | ||
"version": "1.0.16", | ||
"version": "2.0.0", | ||
"description": "一个移动端时间选择器react组件", | ||
@@ -55,2 +55,3 @@ "main": "./dist/mobile-datepicker.js", | ||
"postcss-nested": "^1.0.0", | ||
"react-addons-perf": "^15.2.0", | ||
"react-addons-test-utils": "^15.1.0", | ||
@@ -65,6 +66,6 @@ "rf-release": "^0.4.0", | ||
"dependencies": { | ||
"react": "^15.1.0", | ||
"react-dom": "^15.1.0" | ||
"react": "^15.2.0", | ||
"react-dom": "^15.2.0" | ||
}, | ||
"license": "ISC" | ||
} |
@@ -66,3 +66,3 @@ # react-mobile-datepicker | ||
| layerBackground | String | #ffa70b | 背景颜色 | | ||
| startDate | Date | new Date() | 初始日期 | | ||
| date | Date | new Date() | 初始日期 | | ||
| minDate | Date | 前一周 | 最小日期 | | ||
@@ -69,0 +69,0 @@ | maxDate | Date | new Date() | 最大日期 | |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
23
1030
91906
35
Updatedreact@^15.2.0
Updatedreact-dom@^15.2.0