Skip to content

Commit

Permalink
User pure render and refactoring for time picker
Browse files Browse the repository at this point in the history
  • Loading branch information
javivelasco committed Sep 7, 2015
1 parent 1839f83 commit 0d22fa2
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 61 deletions.
35 changes: 19 additions & 16 deletions components/clock/face.jsx
Original file line number Diff line number Diff line change
@@ -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 () {
Expand All @@ -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>
);
}
Expand Down
37 changes: 20 additions & 17 deletions components/clock/hand.jsx
Original file line number Diff line number Diff line change
@@ -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: {
Expand Down Expand Up @@ -40,71 +43,71 @@ module.exports = React.createClass({
}
},

_getMouseEventMap () {
getMouseEventMap () {
return {
mousemove: this.onMouseMove,
mouseup: this.onMouseUp
};
},

_getTouchEventMap () {
getTouchEventMap () {
return {
touchmove: this.onTouchMove,
touchend: this.onTouchEnd
};
},

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 () {
Expand Down
27 changes: 15 additions & 12 deletions components/clock/hours.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const React = window.React;
const PureRenderMixin = require('react/addons').addons.PureRenderMixin;
const utils = require('../utils');

const Face = require('./face');
Expand All @@ -9,6 +10,8 @@ const innerNumbers = [12, ...utils.range(1, 12)];
const step = 360 / 12;

module.exports = React.createClass({
mixins: [PureRenderMixin],

displayName: 'Hours',

propTypes: {
Expand All @@ -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 {
Expand All @@ -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}
Expand All @@ -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}
Expand All @@ -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>
Expand Down
19 changes: 12 additions & 7 deletions components/clock/index.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
const React = window.React;
const PureRenderMixin = require('react/addons').addons.PureRenderMixin;
const css = require('./style');
const time = require('../utils/time');

const Hours = require('./hours');
const Minutes = require('./minutes');

module.exports = React.createClass({
mixins: [PureRenderMixin],

displayName: 'Clock',

propTypes: {
Expand Down Expand Up @@ -44,21 +47,27 @@ 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);
}
},

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;
Expand All @@ -78,10 +87,6 @@ module.exports = React.createClass({
});
},

toggleTimeMode () {
this.setState({time: time.toggleTimeMode(this.state.time)});
},

renderHours () {
return (
<Hours
Expand Down
15 changes: 9 additions & 6 deletions components/clock/minutes.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const React = window.React;
const PureRenderMixin = require('react/addons').addons.PureRenderMixin;
const utils = require('../utils');

const Face = require('./face');
Expand All @@ -8,6 +9,8 @@ const minutes = utils.range(0, 60, 5);
const step = 360 / 60;

module.exports = React.createClass({
mixins: [PureRenderMixin],

displayName: 'Minutes',

propTypes: {
Expand All @@ -22,24 +25,24 @@ 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);
},

render () {
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}
Expand All @@ -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>
Expand Down
9 changes: 6 additions & 3 deletions components/time_picker/dialog.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
const React = window.React;
const PureRenderMixin = require('react/addons').addons.PureRenderMixin;
const css = require('./style');
const time = require('../utils/time');

const Clock = require('../clock');
const Dialog = require('../dialog');

module.exports = React.createClass({
mixins: [PureRenderMixin],

displayName: 'TimePickerDialog',

propTypes: {
Expand Down Expand Up @@ -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 {
Expand All @@ -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}>
Expand Down
Loading

0 comments on commit 0d22fa2

Please sign in to comment.