From bff5e197c4525892fe4c8a3b466f1e1499f4ea0e Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sat, 20 Jan 2018 09:14:18 +0100 Subject: [PATCH] feat(datepicker): allow for mat-datepicker-toggle icon to be customized Allows for the consumer to set a different icon for the `mat-datepicker-icon` via the `matDatepickerToggleIcon` directive. The reasoning for the change is that not all consumers might be using the Material icons or they may want to set something different (e.g. a chevron). --- src/lib/datepicker/datepicker-module.ts | 4 ++- src/lib/datepicker/datepicker-toggle.html | 4 ++- src/lib/datepicker/datepicker-toggle.ts | 12 +++++++++ src/lib/datepicker/datepicker.md | 11 +++++--- src/lib/datepicker/datepicker.spec.ts | 25 ++++++++++++++++++- .../datepicker-custom-icon-example.css | 1 + .../datepicker-custom-icon-example.html | 7 ++++++ .../datepicker-custom-icon-example.ts | 9 +++++++ src/material-examples/example-module.ts | 6 +++++ 9 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 src/material-examples/datepicker-custom-icon/datepicker-custom-icon-example.css create mode 100644 src/material-examples/datepicker-custom-icon/datepicker-custom-icon-example.html create mode 100644 src/material-examples/datepicker-custom-icon/datepicker-custom-icon-example.ts diff --git a/src/lib/datepicker/datepicker-module.ts b/src/lib/datepicker/datepicker-module.ts index cdee74a9691b..b74d52604d25 100644 --- a/src/lib/datepicker/datepicker-module.ts +++ b/src/lib/datepicker/datepicker-module.ts @@ -22,7 +22,7 @@ import { } from './datepicker'; import {MatDatepickerInput} from './datepicker-input'; import {MatDatepickerIntl} from './datepicker-intl'; -import {MatDatepickerToggle} from './datepicker-toggle'; +import {MatDatepickerToggle, MatDatepickerToggleIcon} from './datepicker-toggle'; import {MatMonthView} from './month-view'; import {MatMultiYearView} from './multi-year-view'; import {MatYearView} from './year-view'; @@ -44,6 +44,7 @@ import {MatYearView} from './year-view'; MatDatepickerContent, MatDatepickerInput, MatDatepickerToggle, + MatDatepickerToggleIcon, MatMonthView, MatYearView, MatMultiYearView, @@ -55,6 +56,7 @@ import {MatYearView} from './year-view'; MatDatepickerContent, MatDatepickerInput, MatDatepickerToggle, + MatDatepickerToggleIcon, MatMonthView, MatYearView, MatMultiYearView, diff --git a/src/lib/datepicker/datepicker-toggle.html b/src/lib/datepicker/datepicker-toggle.html index 18c2b17f19e8..09d41a5c633f 100644 --- a/src/lib/datepicker/datepicker-toggle.html +++ b/src/lib/datepicker/datepicker-toggle.html @@ -1,10 +1,12 @@ diff --git a/src/lib/datepicker/datepicker-toggle.ts b/src/lib/datepicker/datepicker-toggle.ts index 147a680a3081..117f49293564 100644 --- a/src/lib/datepicker/datepicker-toggle.ts +++ b/src/lib/datepicker/datepicker-toggle.ts @@ -17,6 +17,8 @@ import { OnDestroy, SimpleChanges, ViewEncapsulation, + Directive, + ContentChild, } from '@angular/core'; import {merge} from 'rxjs/observable/merge'; import {of as observableOf} from 'rxjs/observable/of'; @@ -25,6 +27,13 @@ import {MatDatepicker} from './datepicker'; import {MatDatepickerIntl} from './datepicker-intl'; +/** Can be used to override the icon of a `matDatepickerToggle`. */ +@Directive({ + selector: '[matDatepickerToggleIcon]' +}) +export class MatDatepickerToggleIcon {} + + @Component({ moduleId: module.id, selector: 'mat-datepicker-toggle', @@ -53,6 +62,9 @@ export class MatDatepickerToggle implements AfterContentInit, OnChanges, OnDe } private _disabled: boolean; + /** Custom icon set by the consumer. */ + @ContentChild(MatDatepickerToggleIcon) _customIcon: MatDatepickerToggleIcon; + constructor(public _intl: MatDatepickerIntl, private _changeDetectorRef: ChangeDetectorRef) {} ngOnChanges(changes: SimpleChanges) { diff --git a/src/lib/datepicker/datepicker.md b/src/lib/datepicker/datepicker.md index 95eddfc04eb3..e9cd81db7c3f 100644 --- a/src/lib/datepicker/datepicker.md +++ b/src/lib/datepicker/datepicker.md @@ -32,6 +32,11 @@ can easily be used as a prefix or suffix on the material input: ``` +If you want to customize the icon that is rendered inside the `mat-datepicker-toggle`, you can do so +by using the `matDatepickerToggleIcon` directive: + + + ### Setting the calendar starting view The `startView` property of `` can be used to set the view that will show up when @@ -99,7 +104,7 @@ Each validation property has a different error that can be checked: * A value that violates the `min` property will have a `matDatepickerMin` error. * A value that violates the `max` property will have a `matDatepickerMax` error. * A value that violates the `matDatepickerFilter` property will have a `matDatepickerFilter` error. - + ### Input and change events The input's native `(input)` and `(change)` events will only trigger due to user interaction with @@ -171,7 +176,7 @@ It's also possible to set the locale at runtime using the `setLocale` method of The datepicker was built to be date implementation agnostic. This means that it can be made to work with a variety of different date implementations. However it also means that developers need to make sure to provide the appropriate pieces for the datepicker to work with their chosen implementation. -The easiest way to ensure this is just to import one of the pre-made modules: +The easiest way to ensure this is just to import one of the pre-made modules: |Module |Date type|Supported locales |Dependencies |Import from | |---------------------|---------|-----------------------------------------------------------------------|----------------------------------|----------------------------------| @@ -338,7 +343,7 @@ In multi-year view: This error is thrown if you have not provided all of the injectables the datepicker needs to work. The easiest way to resolve this is to import the `MatNativeDateModule` or `MatMomentDateModule` in -your application's root module. See +your application's root module. See [_Choosing a date implementation_](#choosing-a-date-implementation-and-date-format-settings)) for more information. diff --git a/src/lib/datepicker/datepicker.spec.ts b/src/lib/datepicker/datepicker.spec.ts index 5a9e3398cdad..b8c33acb6407 100644 --- a/src/lib/datepicker/datepicker.spec.ts +++ b/src/lib/datepicker/datepicker.spec.ts @@ -49,7 +49,7 @@ describe('MatDatepicker', () => { } afterEach(inject([OverlayContainer], (container: OverlayContainer) => { - container.getContainerElement().parentNode!.removeChild(container.getContainerElement()); + container.ngOnDestroy(); })); describe('with MatNativeDateModule', () => { @@ -742,6 +742,19 @@ describe('MatDatepicker', () => { })); }); + describe('datepicker with custom mat-datepicker-toggle icon', () => { + it('should be able to override the mat-datepicker-toggle icon', fakeAsync(() => { + const fixture = createComponent(DatepickerWithCustomIcon, [MatNativeDateModule]); + fixture.detectChanges(); + + expect(fixture.nativeElement.querySelector('.mat-datepicker-toggle .custom-icon')) + .toBeTruthy('Expected custom icon to be rendered.'); + + expect(fixture.nativeElement.querySelector('.mat-datepicker-toggle mat-icon')) + .toBeFalsy('Expected default icon to be removed.'); + })); + }); + describe('datepicker inside mat-form-field', () => { let fixture: ComponentFixture; let testComponent: FormFieldDatepicker; @@ -1289,6 +1302,16 @@ class DatepickerWithToggle { touchUI = true; } +@Component({ + template: ` + + +
+
+ + `, +}) +class DatepickerWithCustomIcon {} @Component({ template: ` diff --git a/src/material-examples/datepicker-custom-icon/datepicker-custom-icon-example.css b/src/material-examples/datepicker-custom-icon/datepicker-custom-icon-example.css new file mode 100644 index 000000000000..7432308753e6 --- /dev/null +++ b/src/material-examples/datepicker-custom-icon/datepicker-custom-icon-example.css @@ -0,0 +1 @@ +/** No CSS for this example */ diff --git a/src/material-examples/datepicker-custom-icon/datepicker-custom-icon-example.html b/src/material-examples/datepicker-custom-icon/datepicker-custom-icon-example.html new file mode 100644 index 000000000000..a1b4e5d50744 --- /dev/null +++ b/src/material-examples/datepicker-custom-icon/datepicker-custom-icon-example.html @@ -0,0 +1,7 @@ + + + + keyboard_arrow_down + + + diff --git a/src/material-examples/datepicker-custom-icon/datepicker-custom-icon-example.ts b/src/material-examples/datepicker-custom-icon/datepicker-custom-icon-example.ts new file mode 100644 index 000000000000..115dab669d13 --- /dev/null +++ b/src/material-examples/datepicker-custom-icon/datepicker-custom-icon-example.ts @@ -0,0 +1,9 @@ +import {Component} from '@angular/core'; + +/** @title Datepicker with custom icon */ +@Component({ + selector: 'datepicker-custom-icon-example', + templateUrl: 'datepicker-custom-icon-example.html', + styleUrls: ['datepicker-custom-icon-example.css'], +}) +export class DatepickerCustomIconExample {} diff --git a/src/material-examples/example-module.ts b/src/material-examples/example-module.ts index 99e1b2d13496..c223944d4b2a 100644 --- a/src/material-examples/example-module.ts +++ b/src/material-examples/example-module.ts @@ -22,6 +22,7 @@ import {ChipsInputExample} from './chips-input/chips-input-example'; import {ChipsOverviewExample} from './chips-overview/chips-overview-example'; import {ChipsStackedExample} from './chips-stacked/chips-stacked-example'; import {DatepickerApiExample} from './datepicker-api/datepicker-api-example'; +import {DatepickerCustomIconExample} from './datepicker-custom-icon/datepicker-custom-icon-example'; import {DatepickerDisabledExample} from './datepicker-disabled/datepicker-disabled-example'; import {DatepickerEventsExample} from './datepicker-events/datepicker-events-example'; import {DatepickerFilterExample} from './datepicker-filter/datepicker-filter-example'; @@ -197,6 +198,10 @@ export const EXAMPLE_COMPONENTS: {[key: string]: LiveExample} = { title: 'Datepicker open method', component: DatepickerApiExample }, + 'datepicker-custom-icon': { + title: 'Datepicker with custom icon', + component: DatepickerCustomIconExample + }, 'datepicker-disabled': { title: 'Disabled datepicker', component: DatepickerDisabledExample @@ -621,6 +626,7 @@ export const EXAMPLE_LIST = [ ChipsOverviewExample, ChipsStackedExample, DatepickerApiExample, + DatepickerCustomIconExample, DatepickerDisabledExample, DatepickerEventsExample, DatepickerFilterExample,