Skip to content

Commit 211d542

Browse files
committed
Add animated auto transition from hours to minutes in TimePicker
1 parent a88868a commit 211d542

File tree

9 files changed

+99
-15
lines changed

9 files changed

+99
-15
lines changed

components/animations/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
export SlideLeft from './slide-left';
22
export SlideRight from './slide-right';
3+
export ZoomIn from './zoom-in';
4+
export ZoomOut from './zoom-out';

components/animations/slide-left.scss

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
@import "../base";
2-
31
.enter, .leave {
42
position: absolute;
53
transition-timing-function: ease-in-out;
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
1-
@import "../base";
2-
31
.enter, .leave {
42
position: absolute;
3+
}
4+
5+
.enterActive, .leaveActive {
56
transition-timing-function: ease-in-out;
6-
transition-duration: .35s;
7+
transition-duration: 350ms;
78
transition-property: transform, opacity;
89
}
910

1011
.enter {
1112
opacity: 0;
12-
transform: translate3d(100%, 0, 0);
13+
transform: translateX(100%);
1314

1415
&.enterActive {
1516
opacity: 1;
16-
transform: translate3d(0, 0, 0);
17+
transform: translateX(0);
1718
}
1819
}
1920

2021
.leave {
2122
opacity: 1;
22-
transform: translate3d(0, 0, 0);
23+
transform: translateX(0);
2324

2425
&.leaveActive {
2526
opacity: 0;
26-
transform: translate3d(-100%, 0, 0);
27+
transform: translateX(-100%);
2728
}
2829
}

components/animations/zoom-in.scss

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
@import "../base";
2+
3+
.enter, .leave {
4+
position: absolute;
5+
}
6+
7+
.enterActive, .leaveActive {
8+
transition-timing-function: $animation-curve-fast-out-slow-in;
9+
transition-duration: 500ms;
10+
transition-property: transform, opacity;
11+
}
12+
13+
.enter {
14+
opacity: 0;
15+
transform: scale(0.85);
16+
17+
&.enterActive {
18+
opacity: 1;
19+
transform: scale(1);
20+
}
21+
}
22+
23+
.leave {
24+
opacity: 1;
25+
transform: scale(1);
26+
27+
&.leaveActive {
28+
opacity: 0;
29+
transform: scale(1.25);
30+
}
31+
}

components/animations/zoom-out.scss

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
@import "../base";
2+
3+
.enter, .leave {
4+
position: absolute;
5+
}
6+
7+
.enterActive, .leaveActive {
8+
transition-timing-function: $animation-curve-fast-out-slow-in;
9+
transition-duration: 500ms;
10+
transition-property: transform, opacity;
11+
}
12+
13+
.enter {
14+
opacity: 0;
15+
transform: scale(1.25);
16+
17+
&.enterActive {
18+
opacity: 1;
19+
transform: scale(1);
20+
}
21+
}
22+
23+
.leave {
24+
opacity: 1;
25+
transform: scale(1);
26+
27+
&.leaveActive {
28+
opacity: 0;
29+
transform: scale(0.85);
30+
}
31+
}

components/time_picker/Clock.jsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import React from 'react';
2+
import CssTransitionGroup from 'react-addons-css-transition-group';
3+
import { ZoomIn, ZoomOut } from '../animations';
24
import style from './style.clock';
35
import time from '../utils/time';
46
import Hours from './ClockHours';
@@ -10,6 +12,7 @@ class Clock extends React.Component {
1012
display: React.PropTypes.oneOf(['hours', 'minutes']),
1113
format: React.PropTypes.oneOf(['24hr', 'ampm']),
1214
onChange: React.PropTypes.func,
15+
onHandMoved: React.PropTypes.func,
1316
time: React.PropTypes.object
1417
};
1518

@@ -47,7 +50,7 @@ class Clock extends React.Component {
4750
};
4851

4952
handleCalculateShape = () => {
50-
const { top, left, width } = this.refs.wrapper.getBoundingClientRect();
53+
const { top, left, width } = this.refs.placeholder.getBoundingClientRect();
5154
this.setState({
5255
center: { x: left + width / 2, y: top + width / 2 },
5356
radius: width / 2
@@ -75,6 +78,7 @@ class Clock extends React.Component {
7578
radius={this.state.radius}
7679
selected={this.props.time.getHours()}
7780
spacing={this.state.radius * 0.18}
81+
onHandMoved={this.props.onHandMoved}
7882
/>
7983
);
8084
}
@@ -87,16 +91,22 @@ class Clock extends React.Component {
8791
radius={this.state.radius}
8892
selected={this.props.time.getMinutes()}
8993
spacing={this.state.radius * 0.18}
94+
onHandMoved={this.props.onHandMoved}
9095
/>
9196
);
9297
}
9398

9499
render () {
100+
const animation = this.props.display === 'hours' ? ZoomOut : ZoomIn;
95101
return (
96102
<div data-react-toolbox='clock' className={style.root}>
97-
<div ref='wrapper' className={style.wrapper} style={{height: this.state.radius * 2}}>
98-
{this.props.display === 'hours' ? this.renderHours() : null}
99-
{this.props.display === 'minutes' ? this.renderMinutes() : null}
103+
<div ref='placeholder' className={style.placeholder} style={{height: this.state.radius * 2}}>
104+
<CssTransitionGroup transitionName={animation} transitionEnterTimeout={500} transitionLeaveTimeout={500}>
105+
<div key={this.props.display} className={style.wrapper} style={{height: this.state.radius * 2}}>
106+
{this.props.display === 'hours' ? this.renderHours() : null}
107+
{this.props.display === 'minutes' ? this.renderMinutes() : null}
108+
</div>
109+
</CssTransitionGroup>
100110
</div>
101111
</div>
102112
);

components/time_picker/TimePickerDialog.jsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ class TimePickerDialog extends React.Component {
4242
this.setState({displayTime: time.toggleTimeMode(this.state.displayTime)});
4343
};
4444

45+
handleHandMoved = () => {
46+
if (this.state.display === 'hours') this.setState({display: 'minutes'});
47+
};
48+
4549
switchDisplay = (display) => {
4650
this.setState({display});
4751
};
@@ -90,8 +94,9 @@ class TimePickerDialog extends React.Component {
9094
ref='clock'
9195
display={this.state.display}
9296
format={this.props.format}
93-
time={this.state.displayTime}
9497
onChange={this.handleClockChange}
98+
onHandMoved={this.handleHandMoved}
99+
time={this.state.displayTime}
95100
/>
96101
</Dialog>
97102
);

components/time_picker/style.clock.scss

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@
55
padding: $clock-padding;
66
}
77

8-
.wrapper {
8+
.placeholder {
99
position: relative;
1010
z-index: $z-index-high;
11+
}
12+
13+
.wrapper {
14+
position: absolute;
15+
width: 100%;
1116
background-color: $color-divider;
1217
border-radius: 50%;
1318
}

components/time_picker/style.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
width: $timepicker-dialog-width;
4949
> [role="body"] {
5050
padding: 0;
51+
overflow-y: visible;
5152
}
5253
> [role="navigation"] > .button {
5354
color: $timepicker-primary-color;

0 commit comments

Comments
 (0)