Skip to content

Commit bff5e19

Browse files
committed
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).
1 parent 4523556 commit bff5e19

File tree

9 files changed

+73
-6
lines changed

9 files changed

+73
-6
lines changed

src/lib/datepicker/datepicker-module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
} from './datepicker';
2323
import {MatDatepickerInput} from './datepicker-input';
2424
import {MatDatepickerIntl} from './datepicker-intl';
25-
import {MatDatepickerToggle} from './datepicker-toggle';
25+
import {MatDatepickerToggle, MatDatepickerToggleIcon} from './datepicker-toggle';
2626
import {MatMonthView} from './month-view';
2727
import {MatMultiYearView} from './multi-year-view';
2828
import {MatYearView} from './year-view';
@@ -44,6 +44,7 @@ import {MatYearView} from './year-view';
4444
MatDatepickerContent,
4545
MatDatepickerInput,
4646
MatDatepickerToggle,
47+
MatDatepickerToggleIcon,
4748
MatMonthView,
4849
MatYearView,
4950
MatMultiYearView,
@@ -55,6 +56,7 @@ import {MatYearView} from './year-view';
5556
MatDatepickerContent,
5657
MatDatepickerInput,
5758
MatDatepickerToggle,
59+
MatDatepickerToggleIcon,
5860
MatMonthView,
5961
MatYearView,
6062
MatMultiYearView,
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<button mat-icon-button type="button" [attr.aria-label]="_intl.openCalendarLabel"
22
[disabled]="disabled" (click)="_open($event)">
3-
<mat-icon>
3+
<mat-icon *ngIf="!_customIcon">
44
<svg viewBox="0 0 24 24" width="100%" height="100%" fill="currentColor"
55
style="vertical-align: top" focusable="false">
66
<path d="M0 0h24v24H0z" fill="none"/>
77
<path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z"/>
88
</svg>
99
</mat-icon>
10+
11+
<ng-content select="[matDatepickerToggleIcon]"></ng-content>
1012
</button>

src/lib/datepicker/datepicker-toggle.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import {
1717
OnDestroy,
1818
SimpleChanges,
1919
ViewEncapsulation,
20+
Directive,
21+
ContentChild,
2022
} from '@angular/core';
2123
import {merge} from 'rxjs/observable/merge';
2224
import {of as observableOf} from 'rxjs/observable/of';
@@ -25,6 +27,13 @@ import {MatDatepicker} from './datepicker';
2527
import {MatDatepickerIntl} from './datepicker-intl';
2628

2729

30+
/** Can be used to override the icon of a `matDatepickerToggle`. */
31+
@Directive({
32+
selector: '[matDatepickerToggleIcon]'
33+
})
34+
export class MatDatepickerToggleIcon {}
35+
36+
2837
@Component({
2938
moduleId: module.id,
3039
selector: 'mat-datepicker-toggle',
@@ -53,6 +62,9 @@ export class MatDatepickerToggle<D> implements AfterContentInit, OnChanges, OnDe
5362
}
5463
private _disabled: boolean;
5564

65+
/** Custom icon set by the consumer. */
66+
@ContentChild(MatDatepickerToggleIcon) _customIcon: MatDatepickerToggleIcon;
67+
5668
constructor(public _intl: MatDatepickerIntl, private _changeDetectorRef: ChangeDetectorRef) {}
5769

5870
ngOnChanges(changes: SimpleChanges) {

src/lib/datepicker/datepicker.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ can easily be used as a prefix or suffix on the material input:
3232
</mat-form-field>
3333
```
3434

35+
If you want to customize the icon that is rendered inside the `mat-datepicker-toggle`, you can do so
36+
by using the `matDatepickerToggleIcon` directive:
37+
38+
<!-- example(datepicker-custom-icon) -->
39+
3540
### Setting the calendar starting view
3641

3742
The `startView` property of `<mat-datepicker>` 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:
99104
* A value that violates the `min` property will have a `matDatepickerMin` error.
100105
* A value that violates the `max` property will have a `matDatepickerMax` error.
101106
* A value that violates the `matDatepickerFilter` property will have a `matDatepickerFilter` error.
102-
107+
103108
### Input and change events
104109

105110
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
171176
The datepicker was built to be date implementation agnostic. This means that it can be made to work
172177
with a variety of different date implementations. However it also means that developers need to make
173178
sure to provide the appropriate pieces for the datepicker to work with their chosen implementation.
174-
The easiest way to ensure this is just to import one of the pre-made modules:
179+
The easiest way to ensure this is just to import one of the pre-made modules:
175180

176181
|Module |Date type|Supported locales |Dependencies |Import from |
177182
|---------------------|---------|-----------------------------------------------------------------------|----------------------------------|----------------------------------|
@@ -338,7 +343,7 @@ In multi-year view:
338343

339344
This error is thrown if you have not provided all of the injectables the datepicker needs to work.
340345
The easiest way to resolve this is to import the `MatNativeDateModule` or `MatMomentDateModule` in
341-
your application's root module. See
346+
your application's root module. See
342347
[_Choosing a date implementation_](#choosing-a-date-implementation-and-date-format-settings)) for
343348
more information.
344349

src/lib/datepicker/datepicker.spec.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ describe('MatDatepicker', () => {
4949
}
5050

5151
afterEach(inject([OverlayContainer], (container: OverlayContainer) => {
52-
container.getContainerElement().parentNode!.removeChild(container.getContainerElement());
52+
container.ngOnDestroy();
5353
}));
5454

5555
describe('with MatNativeDateModule', () => {
@@ -742,6 +742,19 @@ describe('MatDatepicker', () => {
742742
}));
743743
});
744744

745+
describe('datepicker with custom mat-datepicker-toggle icon', () => {
746+
it('should be able to override the mat-datepicker-toggle icon', fakeAsync(() => {
747+
const fixture = createComponent(DatepickerWithCustomIcon, [MatNativeDateModule]);
748+
fixture.detectChanges();
749+
750+
expect(fixture.nativeElement.querySelector('.mat-datepicker-toggle .custom-icon'))
751+
.toBeTruthy('Expected custom icon to be rendered.');
752+
753+
expect(fixture.nativeElement.querySelector('.mat-datepicker-toggle mat-icon'))
754+
.toBeFalsy('Expected default icon to be removed.');
755+
}));
756+
});
757+
745758
describe('datepicker inside mat-form-field', () => {
746759
let fixture: ComponentFixture<FormFieldDatepicker>;
747760
let testComponent: FormFieldDatepicker;
@@ -1289,6 +1302,16 @@ class DatepickerWithToggle {
12891302
touchUI = true;
12901303
}
12911304

1305+
@Component({
1306+
template: `
1307+
<input [matDatepicker]="d">
1308+
<mat-datepicker-toggle [for]="d">
1309+
<div class="custom-icon" matDatepickerToggleIcon></div>
1310+
</mat-datepicker-toggle>
1311+
<mat-datepicker #d></mat-datepicker>
1312+
`,
1313+
})
1314+
class DatepickerWithCustomIcon {}
12921315

12931316
@Component({
12941317
template: `
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/** No CSS for this example */
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<mat-form-field class="example-full-width">
2+
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
3+
<mat-datepicker-toggle matSuffix [for]="picker">
4+
<mat-icon matDatepickerToggleIcon>keyboard_arrow_down</mat-icon>
5+
</mat-datepicker-toggle>
6+
<mat-datepicker #picker></mat-datepicker>
7+
</mat-form-field>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import {Component} from '@angular/core';
2+
3+
/** @title Datepicker with custom icon */
4+
@Component({
5+
selector: 'datepicker-custom-icon-example',
6+
templateUrl: 'datepicker-custom-icon-example.html',
7+
styleUrls: ['datepicker-custom-icon-example.css'],
8+
})
9+
export class DatepickerCustomIconExample {}

src/material-examples/example-module.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {ChipsInputExample} from './chips-input/chips-input-example';
2222
import {ChipsOverviewExample} from './chips-overview/chips-overview-example';
2323
import {ChipsStackedExample} from './chips-stacked/chips-stacked-example';
2424
import {DatepickerApiExample} from './datepicker-api/datepicker-api-example';
25+
import {DatepickerCustomIconExample} from './datepicker-custom-icon/datepicker-custom-icon-example';
2526
import {DatepickerDisabledExample} from './datepicker-disabled/datepicker-disabled-example';
2627
import {DatepickerEventsExample} from './datepicker-events/datepicker-events-example';
2728
import {DatepickerFilterExample} from './datepicker-filter/datepicker-filter-example';
@@ -197,6 +198,10 @@ export const EXAMPLE_COMPONENTS: {[key: string]: LiveExample} = {
197198
title: 'Datepicker open method',
198199
component: DatepickerApiExample
199200
},
201+
'datepicker-custom-icon': {
202+
title: 'Datepicker with custom icon',
203+
component: DatepickerCustomIconExample
204+
},
200205
'datepicker-disabled': {
201206
title: 'Disabled datepicker',
202207
component: DatepickerDisabledExample
@@ -621,6 +626,7 @@ export const EXAMPLE_LIST = [
621626
ChipsOverviewExample,
622627
ChipsStackedExample,
623628
DatepickerApiExample,
629+
DatepickerCustomIconExample,
624630
DatepickerDisabledExample,
625631
DatepickerEventsExample,
626632
DatepickerFilterExample,

0 commit comments

Comments
 (0)