Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit a1844f7

Browse files
committed
feat(datepicker): opening animation and better shadow
1 parent c4f9f50 commit a1844f7

File tree

5 files changed

+55
-47
lines changed

5 files changed

+55
-47
lines changed

src/components/calendar/calendar-theme.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@
3232
.md-calendar-date:focus.md-calendar-selected-date {
3333
.md-calendar-date-selection-indicator {
3434
background-color: '{{primary-500}}'; // blue-500
35-
color: '{{primary-500-contrast}}'; // SHOULD BE WHITE (ish)
35+
color: '{{primary-500-contrast}}'; // white
3636
}
3737
}

src/components/calendar/datePicker-theme.scss

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121

2222
// Open state for all of the elements of the picker.
2323
.md-datepicker-open {
24-
.md-datepicker-input-container {
25-
border-color: '{{background-300}}';
26-
}
27-
2824
.md-datepicker-calendar-icon {
2925
fill: '{{primary-500}}';
3026
}
3127
}
28+
29+
.md-datepicker-calendar {
30+
background: white;
31+
}

src/components/calendar/datePicker.js

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,13 @@
3737
'</md-button>' +
3838
'</div>' +
3939

40-
// This pane (and its shadow) will be detached from here and re-attached to the
41-
// document body.
42-
'<div class="md-datepicker-calendar-pane">' +
43-
'<md-calendar ng-model="ctrl.date" ng-if="ctrl.isCalendarOpen"></md-calendar>' +
44-
'</div>' +
45-
46-
// We have a separate shadow element in order to wrap both the floating pane and the
47-
// inline input / trigger as one shadowed whole.
48-
'<div class="md-datepicker-calendar-pane-shadow md-whiteframe-z1"></div>',
40+
// This pane will be detached from here and re-attached to the document body.
41+
'<div class="md-datepicker-calendar-pane md-whiteframe-z1">' +
42+
'<div class="md-datepicker-input-mask"></div>' +
43+
'<div class="md-datepicker-calendar">' +
44+
'<md-calendar ng-model="ctrl.date" ng-if="ctrl.isCalendarOpen"></md-calendar>' +
45+
'</div>' +
46+
'</div>',
4947
require: ['ngModel', 'mdDatePicker'],
5048
scope: {
5149
placeholder: '@mdPlaceholder'
@@ -71,7 +69,7 @@
7169
* @ngInject @constructor
7270
*/
7371
function DatePickerCtrl($scope, $element, $attrs, $compile, $timeout, $mdConstant, $mdUtil,
74-
$$mdDateLocale, $$mdDateUtil) {
72+
$$mdDateLocale, $$mdDateUtil, $mdMenu, $$rAF) {
7573
/** @final */
7674
this.$compile = $compile;
7775

@@ -90,6 +88,11 @@
9088
/* @final */
9189
this.$mdUtil = $mdUtil;
9290

91+
/** @final */
92+
this.$mdMenu = $mdMenu;
93+
94+
this.$$rAF = $$rAF;
95+
9396
/** @type {!angular.NgModelController} */
9497
this.ngModelCtrl = null;
9598

@@ -102,9 +105,6 @@
102105
/** @type {HTMLElement} Floating calendar pane. */
103106
this.calendarPane = $element[0].querySelector('.md-datepicker-calendar-pane');
104107

105-
/** @type {HTMLElement} Shadow for floating calendar pane and input trigger. */
106-
this.calendarShadow = $element[0].querySelector('.md-datepicker-calendar-pane-shadow');
107-
108108
/** @type {HTMLElement} Calendar icon button. */
109109
this.calendarButton = $element[0].querySelector('.md-datepicker-button');
110110

@@ -240,26 +240,20 @@
240240

241241
/** Position and attach the floating calendar to the document. */
242242
DatePickerCtrl.prototype.attachCalendarPane = function() {
243+
var calendarPane = this.calendarPane;
243244
this.$element.addClass('md-datepicker-open');
244245

245246
var elementRect = this.inputContainer.getBoundingClientRect();
246247
var bodyRect = document.body.getBoundingClientRect();
247248

248-
this.calendarPane.style.left = (elementRect.left - bodyRect.left) + 'px';
249-
this.calendarPane.style.top = (elementRect.bottom - bodyRect.top) + 'px';
249+
calendarPane.style.left = (elementRect.left - bodyRect.left) + 'px';
250+
calendarPane.style.top = (elementRect.top - bodyRect.top) + 'px';
250251
document.body.appendChild(this.calendarPane);
251252

252-
// Add shadow to the calendar pane only after the UI thread has reached idle, allowing the
253-
// content of the calender pane to be rendered.
254-
this.$timeout(function() {
255-
this.calendarPane.classList.add('md-pane-open');
256-
257-
this.calendarShadow.style.top = (elementRect.top - bodyRect.top) + 'px';
258-
this.calendarShadow.style.left = this.calendarPane.style.left;
259-
this.calendarShadow.style.height =
260-
(this.calendarPane.getBoundingClientRect().bottom - elementRect.top) + 'px';
261-
document.body.appendChild(this.calendarShadow);
262-
}.bind(this), 0, false);
253+
// Add CSS class after one frame to trigger animation.
254+
this.$$rAF(function() {
255+
calendarPane.classList.add('md-pane-open');
256+
});
263257
};
264258

265259
/** Detach the floating calendar pane from the document. */
@@ -270,7 +264,6 @@
270264
// Use native DOM removal because we do not want any of the angular state of this element
271265
// to be disposed.
272266
this.calendarPane.parentNode.removeChild(this.calendarPane);
273-
this.calendarShadow.parentNode.removeChild(this.calendarShadow);
274267
};
275268

276269
/** Open the floating calendar pane. */

src/components/calendar/datePicker.scss

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ $md-datepicker-button-gap: 12px;
3636
// Container for the datepicker input.
3737
.md-datepicker-input-container {
3838
position: relative;
39-
z-index: $z-index-datepicker-trigger;
4039

41-
display: inline-block;
4240
border-bottom-width: 1px;
4341
border-bottom-style: solid;
42+
43+
display: inline-block;
4444
width: 120px;
4545
margin-left: $md-datepicker-button-gap;
4646
}
@@ -55,15 +55,35 @@ $md-datepicker-button-gap: 12px;
5555

5656
border-width: 1px;
5757
border-style: solid;
58-
border-top: none;
59-
background: white;
58+
background: transparent;
59+
60+
transform: scale(0);
61+
transform-origin: 0 0;
62+
transition: transform 0.2s $swift-ease-out-timing-function;
63+
64+
&.md-pane-open {
65+
transform: scale(1);
66+
}
6067
}
6168

62-
// Shadow that wraps around both the floating calendar pane and the in-line input.
63-
.md-datepicker-calendar-pane-shadow {
64-
position: absolute;
65-
z-index: $z-index-datepicker-shadow;
69+
// Portion of the floating panel that sits, invisibly, on top of the input.
70+
.md-datepicker-input-mask {
71+
height: 40px;
6672
width: $md-calendar-width;
73+
74+
background: transparent;
75+
pointer-events: none;
76+
cursor: text;
77+
}
78+
79+
// The calendar portion of the floating pane (vs. the input mask).
80+
.md-datepicker-calendar {
81+
opacity: 0;
82+
transition: opacity 0.2s cubic-bezier(0.5, 0, 0.25, 1);
83+
84+
.md-pane-open & {
85+
opacity: 1;
86+
}
6787
}
6888

6989
// Down triangle/arrow indicating that the datepicker can be opened.
@@ -97,17 +117,16 @@ $md-date-arrow-size: 6px;
97117
// Only apply this high specifiy to the property we need to override.
98118
.md-datepicker-triangle-button.md-button.md-icon-button {
99119
height: 100%;
120+
position: absolute;
100121
}
101122

102123

103124
// Open state for all of the elements of the picker.
104125
.md-datepicker-open {
105126
.md-datepicker-input-container {
106-
border-width: 1px;
107-
border-style: solid;
108-
border-bottom: none;
109127
min-width: $md-calendar-width;
110128
margin-left: -$md-datepicker-button-gap;
129+
border: none;
111130
}
112131

113132
.md-datepicker-input {

src/core/style/variables.scss

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,6 @@ $z-index-sidenav: 60 !default;
7373
$z-index-backdrop: 50 !default;
7474
$z-index-fab: 20 !default;
7575

76-
// It is important that datepicker shadow is underneath both the trigger and the floating pane.
77-
$z-index-datepicker-trigger: 5 !default;
78-
$z-index-datepicker-shadow: 4 !default;
79-
8076
// Easing Curves
8177
//--------------------------------------------
8278

0 commit comments

Comments
 (0)