Skip to content

Commit

Permalink
fix(datepicker): some misc cleanup (#4106)
Browse files Browse the repository at this point in the history
* prev & next icons with css

* add some a11y labels

* small fixes

* fix sizing
  • Loading branch information
mmalerba committed May 9, 2017
1 parent 776a10a commit 5f39247
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 55 deletions.
33 changes: 31 additions & 2 deletions src/lib/core/datetime/calendar-locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {Injectable} from '@angular/core';


/** Whether the browser supports the Intl API. */
const SUPPORTS_INTL_API = !!Intl;
const SUPPORTS_INTL_API = typeof Intl != 'undefined';


/** Creates an array and fills it with values. */
Expand Down Expand Up @@ -52,6 +52,24 @@ export abstract class CalendarLocale {
/** A label for the button used to open the calendar popup (used by screen readers). */
openCalendarLabel: string;

/** A label for the previous month button (used by screen readers). */
prevMonthLabel: string;

/** A label for the next month button (used by screen readers). */
nextMonthLabel: string;

/** A label for the previous year button (used by screen readers). */
prevYearLabel: string;

/** A label for the next year button (used by screen readers). */
nextYearLabel: string;

/** A label for the 'switch to month view' button (used by screen readers). */
switchToMonthViewLabel: string;

/** A label for the 'switch to year view' button (used by screen readers). */
switchToYearViewLabel: string;

/**
* Parses a SimpleDate from a value.
* @param value The value to parse.
Expand Down Expand Up @@ -124,6 +142,18 @@ export class DefaultCalendarLocale implements CalendarLocale {

openCalendarLabel = 'Open calendar';

prevMonthLabel = 'Previous month';

nextMonthLabel = 'Next month';

prevYearLabel = 'Previous year';

nextYearLabel = 'Next year';

switchToMonthViewLabel = 'Change to month view';

switchToYearViewLabel = 'Change to year view';

parseDate(value: any) {
if (value instanceof SimpleDate) {
return value;
Expand Down Expand Up @@ -160,7 +190,6 @@ export class DefaultCalendarLocale implements CalendarLocale {
* Creates a function to format SimpleDates as strings using Intl.DateTimeFormat.
* @param options The options to use for Intl.DateTimeFormat.
* @returns The newly created format function, or null if the Intl API is not available.
* @private
*/
private _createFormatFunction(options: Object): (date: SimpleDate) => string {
if (SUPPORTS_INTL_API) {
Expand Down
5 changes: 3 additions & 2 deletions src/lib/core/datetime/simple-date.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* A replacement for the native JS Date class that allows us to avoid dealing with time zone
* details and the time component of the native Date.
* A wrapper for the native JS Date class that deals with some quirks for us:
* 1) The native Date constructor treats years in the range [0-99] as 19xx not 00xx.
* 2) ... (Eventually need to add support for other quirks related to time zones, DST).
*/
export class SimpleDate {
/**
Expand Down
24 changes: 7 additions & 17 deletions src/lib/datepicker/calendar.html
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
<div class="mat-calendar-header">
<div class="mat-calendar-controls">
<button class="mat-calendar-button mat-calendar-period-button"
(click)="_currentPeriodClicked()">
{{_label}}
<button md-button class="mat-calendar-period-button" (click)="_currentPeriodClicked()"
[attr.aria-label]="_periodButtonLabel">
{{_periodButtonText}}
<div class="mat-calendar-arrow" [class.mat-calendar-invert]="!_monthView"></div>
</button>
<div class="mat-calendar-spacer"></div>
<button class="mat-calendar-button mat-calendar-previous-button"
[class.mat-calendar-disabled]="!_previousEnabled()" (click)="_previousClicked()">
<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24"
fill="currentColor">
<path d="M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z"/>
<path d="M0-.5h24v24H0z" fill="none"/>
</svg>
<button md-icon-button class="mat-calendar-previous-button" [disabled]="!_previousEnabled()"
(click)="_previousClicked()" [attr.aria-label]="_prevButtonLabel">
</button>
<button class="mat-calendar-button mat-calendar-next-button"
[class.mat-calendar-disabled]="!_nextEnabled()" (click)="_nextClicked()">
<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24"
fill="currentColor">
<path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"/>
<path d="M0-.25h24v24H0z" fill="none"/>
</svg>
<button md-icon-button class="mat-calendar-next-button" [disabled]="!_nextEnabled()"
(click)="_nextClicked()" [attr.aria-label]="_nextButtonLabel">
</button>
</div>

Expand Down
55 changes: 39 additions & 16 deletions src/lib/datepicker/calendar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@ $mat-calendar-header-divider-width: 1px !default;
$mat-calendar-controls-vertical-padding: 5%;
// We want to indent to the middle of the first tile. There are 7 tiles, so 100% / 7 / 2.
// Then we back up a little bit since the text in the cells is center-aligned.
$mat-calendar-controls-start-padding: calc(100% / 14 - 6px);
// Same as above, but we back up a little more since the arrow buttons have more padding.
$mat-calendar-controls-end-padding: calc(100% / 14 - 12px);
$mat-calendar-controls-start-padding: calc(100% / 14 - 22px);
// Same as above, but on other side for arrows.
$mat-calendar-controls-end-padding: calc(100% / 14 - 22px);
$mat-calendar-period-font-size: 14px;
$mat-calendar-arrow-size: 5px !default;
$mat-calendar-arrow-disabled-opacity: 0.5 !default;
$mat-calendar-weekday-table-font-size: 11px !default;

// Values chosen to approximate https://material.io/icons/#ic_navigate_before and
// https://material.io/icons/#ic_navigate_next as closely as possible.
$mat-calendar-prev-next-icon-border-width: 2px;
$mat-calendar-prev-next-icon-margin: 15.5px;
$mat-calendar-prev-icon-transform: translateX(2px) rotate(-45deg);
$mat-calendar-next-icon-transform: translateX(-2px) rotate(45deg);


.mat-calendar {
display: block;
Expand All @@ -37,22 +44,11 @@ $mat-calendar-weekday-table-font-size: 11px !default;
flex: 1 1 auto;
}

.mat-calendar-button {
background: transparent;
padding: 0;
margin: 0;
border: none;
outline: none;

&.mat-calendar-disabled {
opacity: $mat-calendar-arrow-disabled-opacity;
}
}

.mat-calendar-period-button {
font: inherit;
font-size: $mat-calendar-period-font-size;
font-weight: bold;
min-width: 0;
}

.mat-calendar-button > svg {
Expand All @@ -67,7 +63,7 @@ $mat-calendar-weekday-table-font-size: 11px !default;
border-right: $mat-calendar-arrow-size solid transparent;
border-top-width: $mat-calendar-arrow-size;
border-top-style: solid;
margin: 0 $mat-calendar-arrow-size;
margin: 0 0 0 $mat-calendar-arrow-size;
vertical-align: middle;

&.mat-calendar-invert {
Expand All @@ -80,3 +76,30 @@ $mat-calendar-weekday-table-font-size: 11px !default;
text-align: center;
font-size: $mat-calendar-weekday-table-font-size;
}

.mat-calendar-previous-button,
.mat-calendar-next-button {
position: relative;

&::after {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: $mat-calendar-prev-next-icon-margin;
border: 0 solid currentColor;
border-top-width: $mat-calendar-prev-next-icon-border-width;
}
}

.mat-calendar-previous-button::after {
border-left-width: $mat-calendar-prev-next-icon-border-width;
transform: $mat-calendar-prev-icon-transform;
}

.mat-calendar-next-button::after {
border-right-width: $mat-calendar-prev-next-icon-border-width;
transform: $mat-calendar-next-icon-transform;
}
18 changes: 17 additions & 1 deletion src/lib/datepicker/calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,28 @@ export class MdCalendar implements AfterContentInit {
_weekdays: string[];

/** The label for the current calendar view. */
get _label(): string {
get _periodButtonText(): string {
return this._monthView ?
this._locale.getCalendarMonthHeaderLabel(this._activeDate).toLocaleUpperCase() :
this._locale.getCalendarYearHeaderLabel(this._activeDate);
}

get _periodButtonLabel(): string {
return this._monthView ?
this._locale.switchToYearViewLabel :
this._locale.switchToMonthViewLabel;
}

/** The label for the the previous button. */
get _prevButtonLabel(): string {
return this._monthView ? this._locale.prevMonthLabel : this._locale.prevYearLabel;
}

/** The label for the the next button. */
get _nextButtonLabel(): string {
return this._monthView ? this._locale.nextMonthLabel : this._locale.nextYearLabel;
}

constructor(private _locale: CalendarLocale) {
this._weekdays = this._locale.narrowDays.slice(this._locale.firstDayOfWeek)
.concat(this._locale.narrowDays.slice(0, this._locale.firstDayOfWeek));
Expand Down
10 changes: 5 additions & 5 deletions src/lib/datepicker/datepicker-content.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ $md-datepicker-non-touch-calendar-width:
// the calendar grows, since some of the elements have pixel-based sizes. These numbers have been
// chosen to minimize extra whitespace at larger sizes, while still ensuring we won't need
// scrollbars at smaller sizes.
$md-datepicker-touch-width: 67vmin;
$md-datepicker-touch-width: 64vmin;
$md-datepicker-touch-height: 80vmin;
$md-datepicker-touch-min-width: 253px;
$md-datepicker-touch-min-height: 300px;
$md-datepicker-touch-max-width: 778px;
$md-datepicker-touch-max-height: 800px;
$md-datepicker-touch-min-width: 250px;
$md-datepicker-touch-min-height: 312px;
$md-datepicker-touch-max-width: 750px;
$md-datepicker-touch-max-height: 788px;


.mat-calendar {
Expand Down
4 changes: 4 additions & 0 deletions src/lib/datepicker/datepicker-toggle.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {ChangeDetectionStrategy, Component, Input, ViewEncapsulation} from '@angular/core';
import {MdDatepicker} from './datepicker';
import {CalendarLocale} from '../core/datetime/calendar-locale';


@Component({
Expand All @@ -9,6 +10,7 @@ import {MdDatepicker} from './datepicker';
styleUrls: ['datepicker-toggle.css'],
host: {
'[class.mat-datepicker-toggle]': 'true',
'[attr.aria-label]': '_locale.openCalendarLabel',
'(click)': '_open($event)',
},
encapsulation: ViewEncapsulation.None,
Expand All @@ -21,6 +23,8 @@ export class MdDatepickerToggle {
get _datepicker() { return this.datepicker; }
set _datepicker(v: MdDatepicker) { this.datepicker = v; }

constructor(public _locale: CalendarLocale) {}

_open(event: Event): void {
if (this.datepicker) {
this.datepicker.open();
Expand Down
15 changes: 3 additions & 12 deletions src/lib/datepicker/datepicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,7 @@ export class MdDatepicker implements OnDestroy {
get startAt(): SimpleDate {
// If an explicit startAt is set we start there, otherwise we start at whatever the currently
// selected value is.
if (this._startAt) {
return this._startAt;
}
if (this._datepickerInput) {
return this._datepickerInput.value;
}
return null;
return this._startAt || (this._datepickerInput ? this._datepickerInput.value : null);
}
set startAt(date: SimpleDate) { this._startAt = this._locale.parseDate(date); }
private _startAt: SimpleDate;
Expand Down Expand Up @@ -166,7 +160,7 @@ export class MdDatepicker implements OnDestroy {

/**
* Register an input with this datepicker.
* @param inputElementRef An ElementRef for the input.
* @param input The datepicker input to register with this datepicker.
*/
_registerInput(input: MdDatepickerInput): void {
if (this._datepickerInput) {
Expand All @@ -177,10 +171,7 @@ export class MdDatepicker implements OnDestroy {
this._datepickerInput._valueChange.subscribe((value: SimpleDate) => this._selected = value);
}

/**
* Open the calendar.
* @param touchUi Whether to use the touch UI.
*/
/** Open the calendar. */
open(): void {
if (this.opened) {
return;
Expand Down
2 changes: 2 additions & 0 deletions src/lib/datepicker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {MdDialogModule} from '../dialog/index';
import {MdCalendar} from './calendar';
import {MdDatepickerToggle} from './datepicker-toggle';
import {StyleModule} from '../core/style/index';
import {MdButtonModule} from '../button/index';


export * from './calendar';
Expand All @@ -25,6 +26,7 @@ export * from './year-view';
imports: [
CommonModule,
DatetimeModule,
MdButtonModule,
MdDialogModule,
OverlayModule,
StyleModule,
Expand Down

0 comments on commit 5f39247

Please sign in to comment.