User pure render and refactoring for time picker

old
Javi Velasco 2015-09-07 23:58:14 +02:00
parent 1839f838a4
commit 0d22fa2115
7 changed files with 84 additions and 61 deletions

View File

@ -1,7 +1,10 @@
const React = window.React;
const PureRenderMixin = require('react/addons').addons.PureRenderMixin;
const css = require('./style');
module.exports = React.createClass({
mixins: [PureRenderMixin],
displayName: 'Face',
getDefaultProps () {
@ -13,39 +16,39 @@ module.exports = React.createClass({
};
},
_numberStyle (radius, num) {
numberStyle (rad, num) {
return {
position: 'absolute',
left: (radius + radius * Math.sin(360 * (Math.PI / 180) / 12 * (num - 1)) + this.props.spacing),
top: (radius - radius * Math.cos(360 * (Math.PI / 180) / 12 * (num - 1)) + this.props.spacing)
left: (rad + rad * Math.sin(360 * (Math.PI / 180) / 12 * (num - 1)) + this.props.spacing),
top: (rad - rad * Math.cos(360 * (Math.PI / 180) / 12 * (num - 1)) + this.props.spacing)
};
},
_faceStyle () {
faceStyle () {
return {
height: this.props.radius * 2,
width: this.props.radius * 2
};
},
renderNumber (number, idx) {
return (
<span className={css.number + (number === this.props.active ? ' active' : '')}
style={this.numberStyle(this.props.radius - this.props.spacing, idx + 1)}
key={number}>
{ this.props.twoDigits ? ('0' + number).slice(-2) : number }
</span>
);
},
render () {
return (
<div ref="root"
className={css.face}
onTouchStart={this.props.onTouchStart}
onMouseDown={this.props.onMouseDown}
style={this._faceStyle()}>
{
this.props.numbers.map((i, k) => {
return (
<span className={css.number + (i === this.props.active ? ' active' : '')}
style={this._numberStyle(this.props.radius - this.props.spacing, k + 1)}
key={i}>
{ this.props.twoDigits ? ('0' + i).slice(-2) : i }
</span>
);
})
}
style={this.faceStyle()}>
{ this.props.numbers.map(this.renderNumber)}
</div>
);
}

View File

@ -1,8 +1,11 @@
const React = window.React;
const PureRenderMixin = require('react/addons').addons.PureRenderMixin;
const css = require('./style');
const utils = require('../utils');
module.exports = React.createClass({
mixins: [PureRenderMixin],
displayName: 'Hand',
propTypes: {
@ -40,14 +43,14 @@ module.exports = React.createClass({
}
},
_getMouseEventMap () {
getMouseEventMap () {
return {
mousemove: this.onMouseMove,
mouseup: this.onMouseUp
};
},
_getTouchEventMap () {
getTouchEventMap () {
return {
touchmove: this.onTouchMove,
touchend: this.onTouchEnd
@ -55,56 +58,56 @@ module.exports = React.createClass({
},
onMouseMove (event) {
this._move(utils.events.getMousePosition(event));
this.move(utils.events.getMousePosition(event));
},
onTouchMove (event) {
this._move(utils.events.getTouchPosition(event));
this.move(utils.events.getTouchPosition(event));
},
onMouseUp () {
this._end(this._getMouseEventMap());
this.end(this.getMouseEventMap());
},
onTouchEnd () {
this._end(this._getTouchEventMap());
this.end(this.getTouchEventMap());
},
mouseStart (event) {
utils.events.addEventsToDocument(this._getMouseEventMap());
this._move(utils.events.getMousePosition(event));
utils.events.addEventsToDocument(this.getMouseEventMap());
this.move(utils.events.getMousePosition(event));
},
touchStart (event) {
utils.events.addEventsToDocument(this._getTouchEventMap());
this._move(utils.events.getTouchPosition(event));
utils.events.addEventsToDocument(this.getTouchEventMap());
this.move(utils.events.getTouchPosition(event));
utils.events.pauseEvent(event);
},
_getPositionRadius (position) {
getPositionRadius (position) {
let x = this.props.origin.x - position.x;
let y = this.props.origin.y - position.y;
return Math.sqrt(x * x + y * y);
},
_trimAngleToValue (angle) {
trimAngleToValue (angle) {
return this.props.step * Math.round(angle / this.props.step);
},
_positionToAngle (position) {
positionToAngle (position) {
return utils.angle360FromPositions(this.props.origin.x, this.props.origin.y, position.x, position.y);
},
_end (events) {
end (events) {
if (this.props.onHandMoved) this.props.onHandMoved();
utils.events.removeEventsFromDocument(events);
},
_move (position) {
let degrees = this._trimAngleToValue(this._positionToAngle(position));
move (position) {
let degrees = this.trimAngleToValue(this.positionToAngle(position));
degrees = degrees === 360 ? 0 : degrees;
if (this.state.angle !== degrees) this.setState({angle: degrees});
if (this.props.onHandMove) this.props.onHandMove(this._getPositionRadius(position));
if (this.props.onHandMove) this.props.onHandMove(this.getPositionRadius(position));
},
render () {

View File

@ -1,4 +1,5 @@
const React = window.React;
const PureRenderMixin = require('react/addons').addons.PureRenderMixin;
const utils = require('../utils');
const Face = require('./face');
@ -9,6 +10,8 @@ const innerNumbers = [12, ...utils.range(1, 12)];
const step = 360 / 12;
module.exports = React.createClass({
mixins: [PureRenderMixin],
displayName: 'Hours',
propTypes: {
@ -24,26 +27,26 @@ module.exports = React.createClass({
};
},
_onHandMove (radius) {
onHandMove (radius) {
let currentInner = radius < this.props.radius - this.props.spacing * 2;
if (this.props.format === '24hr' && this.state.inner !== currentInner) {
this.setState({inner: currentInner});
}
},
_onHandChange (degrees) {
this.props.onChange(this._valueFromDegrees(degrees));
onHandChange (degrees) {
this.props.onChange(this.valueFromDegrees(degrees));
},
_onMouseDown (event) {
onMouseDown (event) {
this.refs.hand.mouseStart(event);
},
_onTouchStart (event) {
onTouchStart (event) {
this.refs.hand.touchStart(event);
},
_valueFromDegrees (degrees) {
valueFromDegrees (degrees) {
if (this.props.format === 'ampm' || this.props.format === '24hr' && this.state.inner) {
return innerNumbers[degrees / step];
} else {
@ -55,8 +58,8 @@ module.exports = React.createClass({
if (this.props.format === '24hr') {
return (
<Face
onTouchStart={this._onTouchStart}
onMouseDown={this._onMouseDown}
onTouchStart={this.onTouchStart}
onMouseDown={this.onMouseDown}
numbers={innerNumbers}
spacing={this.props.spacing}
radius={innerRadius}
@ -72,8 +75,8 @@ module.exports = React.createClass({
return (
<div>
<Face
onTouchStart={this._onTouchStart}
onMouseDown={this._onMouseDown}
onTouchStart={this.onTouchStart}
onMouseDown={this.onMouseDown}
numbers={is24hr ? outerNumbers : innerNumbers}
spacing={spacing}
radius={radius}
@ -83,9 +86,9 @@ module.exports = React.createClass({
<Hand ref='hand'
initialAngle={selected * step}
length={(this.state.inner ? radius - spacing * 2 : radius) - spacing}
onHandMove={this._onHandMove}
onHandMove={this.onHandMove}
onHandMoved={onHandMoved}
onHandChange={this._onHandChange}
onHandChange={this.onHandChange}
origin={center}
step={step} />
</div>

View File

@ -1,4 +1,5 @@
const React = window.React;
const PureRenderMixin = require('react/addons').addons.PureRenderMixin;
const css = require('./style');
const time = require('../utils/time');
@ -6,6 +7,8 @@ const Hours = require('./hours');
const Minutes = require('./minutes');
module.exports = React.createClass({
mixins: [PureRenderMixin],
displayName: 'Clock',
propTypes: {
@ -44,7 +47,7 @@ module.exports = React.createClass({
onHourChange (hours) {
if (this.state.time.getHours() !== hours) {
const newTime = time.setHours(this.state.time, this._adaptHourToFormat(hours));
const newTime = time.setHours(this.state.time, this.adaptHourToFormat(hours));
this.setState({time: newTime});
if (this.props.onChange) this.props.onChange(newTime);
}
@ -52,13 +55,19 @@ module.exports = React.createClass({
onMinuteChange (minutes) {
if (this.state.time.getMinutes() !== minutes) {
let newTime = time.setMinutes(this.state.time, minutes);
const newTime = time.setMinutes(this.state.time, minutes);
this.setState({time: newTime});
if (this.props.onChange) this.props.onChange(newTime);
}
},
_adaptHourToFormat (hour) {
toggleTimeMode () {
const newTime = time.toggleTimeMode(this.state.time);
this.setState({time: newTime});
if (this.props.onChange) this.props.onChange(newTime);
},
adaptHourToFormat (hour) {
if (this.props.format === 'ampm') {
if (time.getTimeMode(this.state.time) === 'pm') {
return hour < 12 ? hour + 12 : hour;
@ -78,10 +87,6 @@ module.exports = React.createClass({
});
},
toggleTimeMode () {
this.setState({time: time.toggleTimeMode(this.state.time)});
},
renderHours () {
return (
<Hours

View File

@ -1,4 +1,5 @@
const React = window.React;
const PureRenderMixin = require('react/addons').addons.PureRenderMixin;
const utils = require('../utils');
const Face = require('./face');
@ -8,6 +9,8 @@ const minutes = utils.range(0, 60, 5);
const step = 360 / 60;
module.exports = React.createClass({
mixins: [PureRenderMixin],
displayName: 'Minutes',
propTypes: {
@ -22,15 +25,15 @@ module.exports = React.createClass({
};
},
_onHandChange (degrees) {
onHandChange (degrees) {
this.props.onChange(degrees / step);
},
_onMouseDown (event) {
onMouseDown (event) {
this.refs.hand.mouseStart(event);
},
_onTouchStart (event) {
onTouchStart (event) {
this.refs.hand.touchStart(event);
},
@ -38,8 +41,8 @@ module.exports = React.createClass({
return (
<div>
<Face
onTouchStart={this._onTouchStart}
onMouseDown={this._onMouseDown}
onTouchStart={this.onTouchStart}
onMouseDown={this.onMouseDown}
numbers={minutes}
spacing={this.props.spacing}
radius={this.props.radius}
@ -49,7 +52,7 @@ module.exports = React.createClass({
className={minutes.indexOf(this.props.selected) === -1 ? 'smallKnob' : ''}
initialAngle={this.props.selected * step}
length={this.props.radius - this.props.spacing}
onHandChange={this._onHandChange}
onHandChange={this.onHandChange}
origin={this.props.center}
step={step} />
</div>

View File

@ -1,4 +1,5 @@
const React = window.React;
const PureRenderMixin = require('react/addons').addons.PureRenderMixin;
const css = require('./style');
const time = require('../utils/time');
@ -6,6 +7,8 @@ const Clock = require('../clock');
const Dialog = require('../dialog');
module.exports = React.createClass({
mixins: [PureRenderMixin],
displayName: 'TimePickerDialog',
propTypes: {
@ -61,10 +64,10 @@ module.exports = React.createClass({
show () {
this.refs.dialog.show();
setTimeout(this.refs.clock.calculateShape, 500);
setTimeout(this.refs.clock.calculateShape, 1000);
},
_formatHours () {
formatHours () {
if (this.props.format === 'ampm') {
return this.state.time.getHours() % 12 || 12;
} else {
@ -89,7 +92,7 @@ module.exports = React.createClass({
<Dialog ref="dialog" className={className} type={css.dialog} actions={this.state.actions}>
<header className={css.header}>
<span className={css.hours} onClick={this.displayHours}>
{ ('0' + this._formatHours()).slice(-2) }
{ ('0' + this.formatHours()).slice(-2) }
</span>
<span className={css.separator}>:</span>
<span className={css.minutes} onClick={this.displayMinutes}>

View File

@ -1,10 +1,13 @@
const React = window.React;
const PureRenderMixin = require('react/addons').addons.PureRenderMixin;
const time = require('../utils/time');
const Input = require('../input');
const TimeDialog = require('./dialog');
module.exports = React.createClass({
mixins: [PureRenderMixin],
displayName: 'TimePicker',
propTypes: {