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

Commit

Permalink
feat(calendar): improve datepicker css
Browse files Browse the repository at this point in the history
  • Loading branch information
jelbourn committed Aug 13, 2015
1 parent 1e28d52 commit 56df8d5
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 56 deletions.
6 changes: 3 additions & 3 deletions src/components/calendar/calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,18 @@
function calendarDirective() {
return {
template:
'<div class="md-calendar-month-floating-label"></div>' +
'<table class="md-calendar-day-header"><thead></thead></table>' +
'<div class="md-calendar-scroll-mask">' +
'<md-virtual-repeat-container class="md-calendar-scroller">' +
'<table class="md-calendar">' +
'<tbody md-virtual-repeat="i in ctrl.items" md-calendar-month ' +
'md-month-offset="$index" class="md-calendar-month" aria-hidden="true" ' +
'md-start-index="1000" ' +
'md-item-size="' + TBODY_HEIGHT + '"></tbody>' +
'</table>' +
'</md-virtual-repeat-container>' +
'</div>' +
'<div aria-live="polite" class="md-visually-hidden"></div>',
'<div aria-live="assertive" aria-atomic="true" class="md-visually-hidden"></div>',
scope: {},
restrict: 'E',
require: ['ngModel', 'mdCalendar'],
Expand Down Expand Up @@ -186,7 +186,7 @@

// Do a one-time scroll to the selected date once the months have done their initial render.
var off = $scope.$on('md-calendar-month-initial-render', function() {
self.scrollToMonth(self.selectedDate);
//self.scrollToMonth(self.selectedDate);
off();
});

Expand Down
2 changes: 1 addition & 1 deletion src/components/calendar/datePicker-theme.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.md-date-picker-root.md-THEME_NAME-theme {
.md-datepicker-root.md-THEME_NAME-theme {
background: white;
&[disabled] {
background: '{{background-100}}';
Expand Down
25 changes: 13 additions & 12 deletions src/components/calendar/datePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
function datePickerDirective() {
return {
template:
'<md-button class="md-date-picker-button md-icon-button" type="button" ' +
'<md-button class="md-datepicker-button md-icon-button" type="button" ' +
'ng-click="ctrl.openCalendarPane()">' +
'<md-icon md-svg-icon="md-calendar"></md-icon>' +
'<md-icon class="md-datepicker-calendar-icon" md-svg-icon="md-calendar"></md-icon>' +
'</md-button>' +
'<div class="md-datepicker-input-container">' +
'<input class="md-datepicker-input">' +
Expand All @@ -38,13 +38,13 @@

// This pane (and its shadow) will be detached from here and re-attached to the
// document body.
'<div class="md-date-calendar-pane">' +
'<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-date-calendar-pane-shadow md-whiteframe-z1"></div>',
'<div class="md-datepicker-calendar-pane-shadow md-whiteframe-z1"></div>',
require: ['ngModel', 'mdDatePicker'],
scope: {
placeholder: '@mdPlaceholder'
Expand Down Expand Up @@ -99,13 +99,13 @@
this.inputContainer = $element[0].querySelector('.md-datepicker-input-container');

/** @type {HTMLElement} Floating calendar pane. */
this.calendarPane = $element[0].querySelector('.md-date-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-date-calendar-pane-shadow');
this.calendarShadow = $element[0].querySelector('.md-datepicker-calendar-pane-shadow');

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

/** @final {!angular.JQLite} */
this.$element = $element;
Expand All @@ -123,6 +123,8 @@
/** @type {boolean} Whether the date-picker's calendar pane is open. */
this.isCalendarOpen = false;

this.calendarPane.id = 'md-date-pane' + $mdUtil.nextUid();

/** Pre-bound click handler is saved so that the event listener can be removed. */
this.bodyClickHandler = this.handleBodyClick.bind(this);

Expand Down Expand Up @@ -232,12 +234,12 @@
DatePickerCtrl.prototype.setDisabled = function(isDisabled) {
this.isDisabled = isDisabled;
this.inputElement.disabled = isDisabled;
this.calendarButton.disabled = isDisabled;
};

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

var elementRect = this.inputContainer.getBoundingClientRect();
var bodyRect = document.body.getBoundingClientRect();
Expand All @@ -249,7 +251,7 @@
// 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.calendarShadow.style.top = (elementRect.top + window.pageYOffset) + 'px';
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';
Expand All @@ -259,8 +261,7 @@

/** Detach the floating calendar pane from the document. */
DatePickerCtrl.prototype.detachCalendarPane = function() {
this.inputContainer.classList.remove('md-open');
this.calendarButton.classList.remove('md-open');
this.$element.removeClass('md-datepicker-open');

// Use native DOM removal because we do not want any of the angular state of this element
// to be disposed.
Expand Down
87 changes: 47 additions & 40 deletions src/components/calendar/datePicker.scss
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
$md-datepicker-button-size: 48px;
// Space between the text input and the calendar-icon button.
$md-datepicker-button-gap: 12px;


// Mixin for a "flat" input that can be used for components that contain an input
// (datepicker, autocomplete).
// TODO(jelbourn): actually use this w/ autocomplete.
@mixin md-flat-input() {
font-size: 14px;

Expand All @@ -20,21 +21,16 @@ $md-datepicker-button-gap: 12px;

// The calendar icon button used to open the calendar pane.
// Need absurd specificty to override md-button.md-icon-button.
.md-date-picker-button {
.md-datepicker-button {
display: inline-block;
box-sizing: border-box;
background: none;

&.md-open {
fill: lightblue;
}
}

// The input into which the user can type the date.
.md-datepicker-input {
@include md-flat-input();
width: 100%;
line-height: 21px;
}

// Container for the datepicker input.
Expand All @@ -46,28 +42,11 @@ $md-datepicker-button-gap: 12px;
border-bottom: 1px solid #e0e0e0;
width: 120px;
margin-left: $md-datepicker-button-gap;

&.md-open {
border: 1px solid #e0e0e0;
border-bottom: none;
min-width: $md-calendar-width;
margin-left: -$md-datepicker-button-gap;

.md-datepicker-input {
margin-left: 24px;
//line-height: 40px;
height: 40px;
}

.md-datepicker-expand-triangle {
display: none;
}
}
}


// Floating pane that contains the calendar at the bottom of the input.
.md-date-calendar-pane {
.md-datepicker-calendar-pane {
position: absolute;
top: 0;
left: 0;
Expand All @@ -79,13 +58,32 @@ $md-datepicker-button-gap: 12px;
}

// Shadow that wraps around both the floating calendar pane and the in-line input.
.md-date-calendar-pane-shadow {
.md-datepicker-calendar-pane-shadow {
position: absolute;
z-index: $z-index-datepicker-shadow;
width: $md-calendar-width;
}

// Down "disclosure" triangle/arrow indicating that the datepicker can be opened.
// We can do this entirely with CSS without needing to load an icon.
// See https://css-tricks.com/snippets/css/css-triangle/
$md-date-arrow-size: 6px;
.md-datepicker-expand-triangle {
// Center the triangle inside of the button so that the
// ink ripple origin looks correct.
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

width: 0;
height: 0;
border-left: $md-date-arrow-size solid transparent;
border-right: $md-date-arrow-size solid transparent;
border-top: $md-date-arrow-size solid rgba(black, 0.20);
}

// Button containing the down "disclosure" triangle/arrow.
.md-datepicker-triangle-button {
position: absolute;
right: 0;
Expand All @@ -97,23 +95,32 @@ $md-datepicker-button-gap: 12px;
}
}

// Need crazy specificity to override .md-button.md-icon-button
// Need crazy specificity to override .md-button.md-icon-button.
// Only apply this high specifiy to the property we need to override.
.md-datepicker-triangle-button.md-button.md-icon-button {
height: 100%;
}

$md-date-arrow-size: 6px;
.md-datepicker-expand-triangle {
// Center the triangle inside of the button so that the
// ink ripple origin looks correct.
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

width: 0;
height: 0;
border-left: $md-date-arrow-size solid transparent;
border-right: $md-date-arrow-size solid transparent;
border-top: $md-date-arrow-size solid rgba(black, 0.20);
// Open state for all of the elements of the picker.
.md-datepicker-open {
.md-datepicker-input-container {
border: 1px solid #e0e0e0;
border-bottom: none;
min-width: $md-calendar-width;
margin-left: -$md-datepicker-button-gap;
}

.md-datepicker-input {
margin-left: 24px;
height: 40px;
}

.md-datepicker-expand-triangle {
display: none;
}

.md-datepicker-calendar-icon {
fill: #2196f3;
}
}

0 comments on commit 56df8d5

Please sign in to comment.