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

Commit

Permalink
feat(datepicker): opening animation and better shadow
Browse files Browse the repository at this point in the history
  • Loading branch information
jelbourn committed Aug 13, 2015
1 parent c4f9f50 commit a1844f7
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 47 deletions.
2 changes: 1 addition & 1 deletion src/components/calendar/calendar-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@
.md-calendar-date:focus.md-calendar-selected-date {
.md-calendar-date-selection-indicator {
background-color: '{{primary-500}}'; // blue-500
color: '{{primary-500-contrast}}'; // SHOULD BE WHITE (ish)
color: '{{primary-500-contrast}}'; // white
}
}
8 changes: 4 additions & 4 deletions src/components/calendar/datePicker-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@

// Open state for all of the elements of the picker.
.md-datepicker-open {
.md-datepicker-input-container {
border-color: '{{background-300}}';
}

.md-datepicker-calendar-icon {
fill: '{{primary-500}}';
}
}

.md-datepicker-calendar {
background: white;
}
47 changes: 20 additions & 27 deletions src/components/calendar/datePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,13 @@
'</md-button>' +
'</div>' +

// This pane (and its shadow) will be detached from here and re-attached to the
// document body.
'<div class="md-datepicker-calendar-pane">' +
'<md-calendar ng-model="ctrl.date" ng-if="ctrl.isCalendarOpen"></md-calendar>' +
'</div>' +

// We have a separate shadow element in order to wrap both the floating pane and the
// inline input / trigger as one shadowed whole.
'<div class="md-datepicker-calendar-pane-shadow md-whiteframe-z1"></div>',
// This pane will be detached from here and re-attached to the document body.
'<div class="md-datepicker-calendar-pane md-whiteframe-z1">' +
'<div class="md-datepicker-input-mask"></div>' +
'<div class="md-datepicker-calendar">' +
'<md-calendar ng-model="ctrl.date" ng-if="ctrl.isCalendarOpen"></md-calendar>' +
'</div>' +
'</div>',
require: ['ngModel', 'mdDatePicker'],
scope: {
placeholder: '@mdPlaceholder'
Expand All @@ -71,7 +69,7 @@
* @ngInject @constructor
*/
function DatePickerCtrl($scope, $element, $attrs, $compile, $timeout, $mdConstant, $mdUtil,
$$mdDateLocale, $$mdDateUtil) {
$$mdDateLocale, $$mdDateUtil, $mdMenu, $$rAF) {
/** @final */
this.$compile = $compile;

Expand All @@ -90,6 +88,11 @@
/* @final */
this.$mdUtil = $mdUtil;

/** @final */
this.$mdMenu = $mdMenu;

this.$$rAF = $$rAF;

/** @type {!angular.NgModelController} */
this.ngModelCtrl = null;

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

/** @type {HTMLElement} Shadow for floating calendar pane and input trigger. */
this.calendarShadow = $element[0].querySelector('.md-datepicker-calendar-pane-shadow');

/** @type {HTMLElement} Calendar icon button. */
this.calendarButton = $element[0].querySelector('.md-datepicker-button');

Expand Down Expand Up @@ -240,26 +240,20 @@

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

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

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

// Add shadow to the calendar pane only after the UI thread has reached idle, allowing the
// content of the calender pane to be rendered.
this.$timeout(function() {
this.calendarPane.classList.add('md-pane-open');

this.calendarShadow.style.top = (elementRect.top - bodyRect.top) + 'px';
this.calendarShadow.style.left = this.calendarPane.style.left;
this.calendarShadow.style.height =
(this.calendarPane.getBoundingClientRect().bottom - elementRect.top) + 'px';
document.body.appendChild(this.calendarShadow);
}.bind(this), 0, false);
// Add CSS class after one frame to trigger animation.
this.$$rAF(function() {
calendarPane.classList.add('md-pane-open');
});
};

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

/** Open the floating calendar pane. */
Expand Down
41 changes: 30 additions & 11 deletions src/components/calendar/datePicker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ $md-datepicker-button-gap: 12px;
// Container for the datepicker input.
.md-datepicker-input-container {
position: relative;
z-index: $z-index-datepicker-trigger;

display: inline-block;
border-bottom-width: 1px;
border-bottom-style: solid;

display: inline-block;
width: 120px;
margin-left: $md-datepicker-button-gap;
}
Expand All @@ -55,15 +55,35 @@ $md-datepicker-button-gap: 12px;

border-width: 1px;
border-style: solid;
border-top: none;
background: white;
background: transparent;

transform: scale(0);
transform-origin: 0 0;
transition: transform 0.2s $swift-ease-out-timing-function;

&.md-pane-open {
transform: scale(1);
}
}

// Shadow that wraps around both the floating calendar pane and the in-line input.
.md-datepicker-calendar-pane-shadow {
position: absolute;
z-index: $z-index-datepicker-shadow;
// Portion of the floating panel that sits, invisibly, on top of the input.
.md-datepicker-input-mask {
height: 40px;
width: $md-calendar-width;

background: transparent;
pointer-events: none;
cursor: text;
}

// The calendar portion of the floating pane (vs. the input mask).
.md-datepicker-calendar {
opacity: 0;
transition: opacity 0.2s cubic-bezier(0.5, 0, 0.25, 1);

.md-pane-open & {
opacity: 1;
}
}

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


// Open state for all of the elements of the picker.
.md-datepicker-open {
.md-datepicker-input-container {
border-width: 1px;
border-style: solid;
border-bottom: none;
min-width: $md-calendar-width;
margin-left: -$md-datepicker-button-gap;
border: none;
}

.md-datepicker-input {
Expand Down
4 changes: 0 additions & 4 deletions src/core/style/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,6 @@ $z-index-sidenav: 60 !default;
$z-index-backdrop: 50 !default;
$z-index-fab: 20 !default;

// It is important that datepicker shadow is underneath both the trigger and the floating pane.
$z-index-datepicker-trigger: 5 !default;
$z-index-datepicker-shadow: 4 !default;

// Easing Curves
//--------------------------------------------

Expand Down

0 comments on commit a1844f7

Please sign in to comment.