mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(datepicker): allow for mat-datepicker-toggle icon to be customized (#9487)
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).
This commit is contained in:
committed by
Jeremy Elbourn
parent
83ca9a8b2d
commit
01867ada10
@@ -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,
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<button mat-icon-button type="button" [attr.aria-label]="_intl.openCalendarLabel"
|
||||
[disabled]="disabled" (click)="_open($event)">
|
||||
<mat-icon>
|
||||
<mat-icon *ngIf="!_customIcon">
|
||||
<svg viewBox="0 0 24 24" width="100%" height="100%" fill="currentColor"
|
||||
style="vertical-align: top" focusable="false">
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<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"/>
|
||||
</svg>
|
||||
</mat-icon>
|
||||
|
||||
<ng-content select="[matDatepickerToggleIcon]"></ng-content>
|
||||
</button>
|
||||
|
||||
@@ -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',
|
||||
@@ -54,6 +63,9 @@ export class MatDatepickerToggle<D> 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) {
|
||||
|
||||
@@ -32,6 +32,11 @@ can easily be used as a prefix or suffix on the material input:
|
||||
</mat-form-field>
|
||||
```
|
||||
|
||||
If you want to customize the icon that is rendered inside the `mat-datepicker-toggle`, you can do so
|
||||
by using the `matDatepickerToggleIcon` directive:
|
||||
|
||||
<!-- example(datepicker-custom-icon) -->
|
||||
|
||||
### Setting the calendar starting view
|
||||
|
||||
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:
|
||||
* 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.
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ describe('MatDatepicker', () => {
|
||||
}
|
||||
|
||||
afterEach(inject([OverlayContainer], (container: OverlayContainer) => {
|
||||
container.getContainerElement().parentNode!.removeChild(container.getContainerElement());
|
||||
container.ngOnDestroy();
|
||||
}));
|
||||
|
||||
describe('with MatNativeDateModule', () => {
|
||||
@@ -761,6 +761,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<FormFieldDatepicker>;
|
||||
let testComponent: FormFieldDatepicker;
|
||||
@@ -1308,6 +1321,16 @@ class DatepickerWithToggle {
|
||||
touchUI = true;
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<input [matDatepicker]="d">
|
||||
<mat-datepicker-toggle [for]="d">
|
||||
<div class="custom-icon" matDatepickerToggleIcon></div>
|
||||
</mat-datepicker-toggle>
|
||||
<mat-datepicker #d></mat-datepicker>
|
||||
`,
|
||||
})
|
||||
class DatepickerWithCustomIcon {}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/** No CSS for this example */
|
||||
@@ -0,0 +1,7 @@
|
||||
<mat-form-field class="example-full-width">
|
||||
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
|
||||
<mat-datepicker-toggle matSuffix [for]="picker">
|
||||
<mat-icon matDatepickerToggleIcon>keyboard_arrow_down</mat-icon>
|
||||
</mat-datepicker-toggle>
|
||||
<mat-datepicker #picker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
@@ -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 {}
|
||||
@@ -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';
|
||||
@@ -200,6 +201,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
|
||||
@@ -636,6 +641,7 @@ export const EXAMPLE_LIST = [
|
||||
ChipsOverviewExample,
|
||||
ChipsStackedExample,
|
||||
DatepickerApiExample,
|
||||
DatepickerCustomIconExample,
|
||||
DatepickerDisabledExample,
|
||||
DatepickerEventsExample,
|
||||
DatepickerFilterExample,
|
||||
|
||||
Reference in New Issue
Block a user