From 0f2c839be8d218cc75ee2f6689b09eca0c300f5b Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Wed, 16 Nov 2022 09:13:33 +0100 Subject: [PATCH] fix(material/datepicker): resolve typing issue when extending datepicker input in legacy app In the switch to MDC we kept the reference to `MatFormField` in the datepicker input's constructor which now has a slightly different public API, causing a compilation error for apps that were passing in the legacy form field. These changes replace the reference with an interface that contains only the common members that the datepicker cares about. Fixes #25977. --- src/material/datepicker/date-range-input.ts | 6 +++--- src/material/datepicker/datepicker-input-base.ts | 16 +++++++++++++++- src/material/datepicker/datepicker-input.ts | 6 +++--- tools/public_api_guard/material/datepicker.md | 5 ++--- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/material/datepicker/date-range-input.ts b/src/material/datepicker/date-range-input.ts index 3d9b0858a081..f9feb521171e 100644 --- a/src/material/datepicker/date-range-input.ts +++ b/src/material/datepicker/date-range-input.ts @@ -22,7 +22,7 @@ import { OnChanges, SimpleChanges, } from '@angular/core'; -import {MatFormFieldControl, MatFormField, MAT_FORM_FIELD} from '@angular/material/form-field'; +import {MatFormFieldControl, MAT_FORM_FIELD} from '@angular/material/form-field'; import {ThemePalette, DateAdapter} from '@angular/material/core'; import {NgControl, ControlContainer} from '@angular/forms'; import {Subject, merge, Subscription} from 'rxjs'; @@ -36,7 +36,7 @@ import { } from './date-range-input-parts'; import {MatDatepickerControl, MatDatepickerPanel} from './datepicker-base'; import {createMissingDateImplError} from './datepicker-errors'; -import {DateFilterFn, dateInputsHaveChanged} from './datepicker-input-base'; +import {DateFilterFn, dateInputsHaveChanged, _MatFormFieldPartial} from './datepicker-input-base'; import {MatDateRangePickerInput} from './date-range-picker'; import {DateRange, MatDateSelectionModel} from './date-selection-model'; @@ -255,7 +255,7 @@ export class MatDateRangeInput private _elementRef: ElementRef, @Optional() @Self() control: ControlContainer, @Optional() private _dateAdapter: DateAdapter, - @Optional() @Inject(MAT_FORM_FIELD) private _formField?: MatFormField, + @Optional() @Inject(MAT_FORM_FIELD) private _formField?: _MatFormFieldPartial, ) { if (!_dateAdapter && (typeof ngDevMode === 'undefined' || ngDevMode)) { throw createMissingDateImplError('DateAdapter'); diff --git a/src/material/datepicker/datepicker-input-base.ts b/src/material/datepicker/datepicker-input-base.ts index ff4f8b910ad2..e24e35d0d459 100644 --- a/src/material/datepicker/datepicker-input-base.ts +++ b/src/material/datepicker/datepicker-input-base.ts @@ -28,7 +28,7 @@ import { Validator, ValidatorFn, } from '@angular/forms'; -import {DateAdapter, MAT_DATE_FORMATS, MatDateFormats} from '@angular/material/core'; +import {DateAdapter, MAT_DATE_FORMATS, MatDateFormats, ThemePalette} from '@angular/material/core'; import {Subscription, Subject} from 'rxjs'; import {createMissingDateImplError} from './datepicker-errors'; import { @@ -59,6 +59,20 @@ export class MatDatepickerInputEvent { /** Function that can be used to filter out dates from a calendar. */ export type DateFilterFn = (date: D | null) => boolean; +/** + * Partial representation of `MatFormField` that is used for backwards-compatibility + * between the legacy and non-legacy variants. + */ +export interface _MatFormFieldPartial { + getConnectedOverlayOrigin(): ElementRef; + getLabelId(): string | null; + color: ThemePalette; + _elementRef: ElementRef; + _shouldLabelFloat(): boolean; + _hasFloatingLabel(): boolean; + _labelId: string; +} + /** Base class for datepicker inputs. */ @Directive() export abstract class MatDatepickerInputBase> diff --git a/src/material/datepicker/datepicker-input.ts b/src/material/datepicker/datepicker-input.ts index fee59cf0148b..83f03a9ee682 100644 --- a/src/material/datepicker/datepicker-input.ts +++ b/src/material/datepicker/datepicker-input.ts @@ -9,10 +9,10 @@ import {Directive, ElementRef, forwardRef, Inject, Input, OnDestroy, Optional} from '@angular/core'; import {NG_VALIDATORS, NG_VALUE_ACCESSOR, ValidatorFn, Validators} from '@angular/forms'; import {DateAdapter, MAT_DATE_FORMATS, MatDateFormats, ThemePalette} from '@angular/material/core'; -import {MatFormField, MAT_FORM_FIELD} from '@angular/material/form-field'; +import {MAT_FORM_FIELD} from '@angular/material/form-field'; import {MAT_INPUT_VALUE_ACCESSOR} from '@angular/material/input'; import {Subscription} from 'rxjs'; -import {MatDatepickerInputBase, DateFilterFn} from './datepicker-input-base'; +import {MatDatepickerInputBase, DateFilterFn, _MatFormFieldPartial} from './datepicker-input-base'; import {MatDatepickerControl, MatDatepickerPanel} from './datepicker-base'; import {DateSelectionModelChange} from './date-selection-model'; @@ -124,7 +124,7 @@ export class MatDatepickerInput elementRef: ElementRef, @Optional() dateAdapter: DateAdapter, @Optional() @Inject(MAT_DATE_FORMATS) dateFormats: MatDateFormats, - @Optional() @Inject(MAT_FORM_FIELD) private _formField?: MatFormField, + @Optional() @Inject(MAT_FORM_FIELD) private _formField?: _MatFormFieldPartial, ) { super(elementRef, dateAdapter, dateFormats); this._validator = Validators.compose(super._getValidators()); diff --git a/tools/public_api_guard/material/datepicker.md b/tools/public_api_guard/material/datepicker.md index a761685505fb..7664bbb1f0b8 100644 --- a/tools/public_api_guard/material/datepicker.md +++ b/tools/public_api_guard/material/datepicker.md @@ -40,7 +40,6 @@ import { InjectionToken } from '@angular/core'; import { Injector } from '@angular/core'; import { MatButton } from '@angular/material/button'; import { MatDateFormats } from '@angular/material/core'; -import { MatFormField } from '@angular/material/form-field'; import { MatFormFieldControl } from '@angular/material/form-field'; import { NgControl } from '@angular/forms'; import { NgForm } from '@angular/forms'; @@ -427,7 +426,7 @@ export interface MatDatepickerControl { // @public export class MatDatepickerInput extends MatDatepickerInputBase implements MatDatepickerControl, OnDestroy { - constructor(elementRef: ElementRef, dateAdapter: DateAdapter, dateFormats: MatDateFormats, _formField?: MatFormField | undefined); + constructor(elementRef: ElementRef, dateAdapter: DateAdapter, dateFormats: MatDateFormats, _formField?: _MatFormFieldPartial | undefined); // (undocumented) protected _assignValueToModel(value: D | null): void; get dateFilter(): DateFilterFn; @@ -557,7 +556,7 @@ export class MatDatepickerToggleIcon { // @public (undocumented) export class MatDateRangeInput implements MatFormFieldControl>, MatDatepickerControl, MatDateRangeInputParent, MatDateRangePickerInput, AfterContentInit, OnChanges, OnDestroy { - constructor(_changeDetectorRef: ChangeDetectorRef, _elementRef: ElementRef, control: ControlContainer, _dateAdapter: DateAdapter, _formField?: MatFormField | undefined); + constructor(_changeDetectorRef: ChangeDetectorRef, _elementRef: ElementRef, control: ControlContainer, _dateAdapter: DateAdapter, _formField?: _MatFormFieldPartial | undefined); _ariaDescribedBy: string | null; comparisonEnd: D | null; comparisonStart: D | null;