From ca542838370259b1602ba874b97932e9cb52e12b Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Tue, 27 Sep 2022 08:45:57 -0700 Subject: [PATCH] feat(material/datepicker): make compatible with MDC & legacy components (#25648) BREAKING CHANGE: Buttons inside the datepicker popup and datepicker toggle now use the MDC-based button implementation. They have different CSS classes and styles, so custom style overrides may need to be updated --- .github/CODEOWNERS | 1 + src/dev-app/BUILD.bazel | 1 + src/dev-app/datepicker/BUILD.bazel | 10 +- src/dev-app/datepicker/datepicker-demo.html | 30 ++ src/dev-app/datepicker/datepicker-demo.ts | 20 +- src/dev-app/dev-app/dev-app-layout.ts | 1 + src/dev-app/legacy-datepicker/BUILD.bazel | 38 ++ .../legacy-datepicker/custom-header.html | 17 + .../legacy-datepicker/custom-header.scss | 16 + .../legacy-datepicker/datepicker-demo.html | 352 ++++++++++++++++++ .../legacy-datepicker/datepicker-demo.scss | 14 + .../legacy-datepicker/datepicker-demo.ts | 254 +++++++++++++ src/dev-app/routes.ts | 5 + src/material/datepicker/BUILD.bazel | 15 +- .../datepicker/_datepicker-legacy-compat.scss | 85 +++++ .../datepicker/_datepicker-theme.scss | 10 +- src/material/datepicker/calendar.scss | 6 +- src/material/datepicker/date-range-input.scss | 2 +- .../datepicker/date-range-input.spec.ts | 20 +- src/material/datepicker/date-range-input.ts | 12 +- .../datepicker/datepicker-actions.scss | 2 +- .../datepicker/datepicker-actions.spec.ts | 8 +- src/material/datepicker/datepicker-input.ts | 8 +- src/material/datepicker/datepicker-module.ts | 4 +- .../datepicker/datepicker-toggle.scss | 24 -- src/material/datepicker/datepicker-toggle.ts | 4 +- src/material/datepicker/datepicker.spec.ts | 18 +- src/material/legacy-button/BUILD.bazel | 6 +- src/material/legacy-button/_button-theme.scss | 21 +- src/material/legacy-button/button.scss | 3 + src/material/legacy-form-field/BUILD.bazel | 1 + .../legacy-form-field/form-field.scss | 3 + tools/public_api_guard/material/datepicker.md | 18 +- 33 files changed, 926 insertions(+), 103 deletions(-) create mode 100644 src/dev-app/legacy-datepicker/BUILD.bazel create mode 100644 src/dev-app/legacy-datepicker/custom-header.html create mode 100644 src/dev-app/legacy-datepicker/custom-header.scss create mode 100644 src/dev-app/legacy-datepicker/datepicker-demo.html create mode 100644 src/dev-app/legacy-datepicker/datepicker-demo.scss create mode 100644 src/dev-app/legacy-datepicker/datepicker-demo.ts create mode 100644 src/material/datepicker/_datepicker-legacy-compat.scss diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6cbffe5d4317..009b558d8ee5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -186,6 +186,7 @@ /src/dev-app/layout/** @andrewseguin /src/dev-app/legacy-card/** @mmalerba /src/dev-app/legacy-checkbox/** @mmalerba +/src/dev-app/legacy-datepicker/** @mmalerba /src/dev-app/legacy-dialog/** @devversion /src/dev-app/legacy-input/** @mmalerba /src/dev-app/legacy-list/** @mmalerba diff --git a/src/dev-app/BUILD.bazel b/src/dev-app/BUILD.bazel index 623ad311f355..95ba7f3e6b6a 100644 --- a/src/dev-app/BUILD.bazel +++ b/src/dev-app/BUILD.bazel @@ -52,6 +52,7 @@ ng_module( "//src/dev-app/legacy-button", "//src/dev-app/legacy-card", "//src/dev-app/legacy-checkbox", + "//src/dev-app/legacy-datepicker", "//src/dev-app/legacy-dialog", "//src/dev-app/legacy-input", "//src/dev-app/legacy-list", diff --git a/src/dev-app/datepicker/BUILD.bazel b/src/dev-app/datepicker/BUILD.bazel index f5612da83d46..0f2d16e95e2d 100644 --- a/src/dev-app/datepicker/BUILD.bazel +++ b/src/dev-app/datepicker/BUILD.bazel @@ -12,14 +12,14 @@ ng_module( ":custom_header_scss", ], deps = [ + "//src/material/button", + "//src/material/checkbox", "//src/material/core", "//src/material/datepicker", + "//src/material/form-field", "//src/material/icon", - "//src/material/legacy-button", - "//src/material/legacy-checkbox", - "//src/material/legacy-form-field", - "//src/material/legacy-input", - "//src/material/legacy-select", + "//src/material/input", + "//src/material/select", ], ) diff --git a/src/dev-app/datepicker/datepicker-demo.html b/src/dev-app/datepicker/datepicker-demo.html index b3fa9d6b4df6..84daa482f83c 100644 --- a/src/dev-app/datepicker/datepicker-demo.html +++ b/src/dev-app/datepicker/datepicker-demo.html @@ -302,3 +302,33 @@

Range picker with custom selection strategy

+ +

With custom icon

+

+ + Custom icon + + + add + + + +
+ + Custom icon + + + add + + + +
+ + Custom icon + + + + + add + +

diff --git a/src/dev-app/datepicker/datepicker-demo.ts b/src/dev-app/datepicker/datepicker-demo.ts index 58c4e77a9d5f..f7a4fefa1d67 100644 --- a/src/dev-app/datepicker/datepicker-demo.ts +++ b/src/dev-app/datepicker/datepicker-demo.ts @@ -20,8 +20,8 @@ import { } from '@angular/core'; import {CommonModule} from '@angular/common'; import {FormControl, FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {MatLegacyButtonModule} from '@angular/material/legacy-button'; -import {MatLegacyCheckboxModule} from '@angular/material/legacy-checkbox'; +import {MatButtonModule} from '@angular/material/button'; +import {MatCheckboxModule} from '@angular/material/checkbox'; import { DateAdapter, MAT_DATE_FORMATS, @@ -38,10 +38,10 @@ import { DateRange, MatDatepickerModule, } from '@angular/material/datepicker'; -import {MatLegacyFormFieldModule} from '@angular/material/legacy-form-field'; +import {MatFormFieldModule} from '@angular/material/form-field'; import {MatIconModule} from '@angular/material/icon'; -import {MatLegacyInputModule} from '@angular/material/legacy-input'; -import {MatLegacySelectModule} from '@angular/material/legacy-select'; +import {MatInputModule} from '@angular/material/input'; +import {MatSelectModule} from '@angular/material/select'; import {Subject} from 'rxjs'; import {takeUntil} from 'rxjs/operators'; @@ -185,14 +185,14 @@ export class CustomHeaderNgContent { imports: [ CommonModule, FormsModule, - MatLegacyButtonModule, - MatLegacyCheckboxModule, + MatButtonModule, + MatCheckboxModule, MatDatepickerModule, - MatLegacyFormFieldModule, + MatFormFieldModule, MatIconModule, - MatLegacyInputModule, + MatInputModule, MatNativeDateModule, - MatLegacySelectModule, + MatSelectModule, ReactiveFormsModule, CustomHeader, CustomHeaderNgContent, diff --git a/src/dev-app/dev-app/dev-app-layout.ts b/src/dev-app/dev-app/dev-app-layout.ts index 1a8d5b5800c1..71c998e85a5e 100644 --- a/src/dev-app/dev-app/dev-app-layout.ts +++ b/src/dev-app/dev-app/dev-app-layout.ts @@ -109,6 +109,7 @@ export class DevAppLayout { {name: 'Legacy Button', route: '/legacy-button'}, {name: 'Legacy Card', route: '/legacy-card'}, {name: 'Legacy Checkbox', route: '/legacy-checkbox'}, + {name: 'Legacy Datepicker', route: '/legacy-datepicker'}, {name: 'Legacy Dialog', route: '/legacy-dialog'}, {name: 'Legacy Input', route: '/legacy-input'}, {name: 'Legacy List', route: '/legacy-list'}, diff --git a/src/dev-app/legacy-datepicker/BUILD.bazel b/src/dev-app/legacy-datepicker/BUILD.bazel new file mode 100644 index 000000000000..c0bec9385f37 --- /dev/null +++ b/src/dev-app/legacy-datepicker/BUILD.bazel @@ -0,0 +1,38 @@ +load("//tools:defaults.bzl", "ng_module", "sass_binary") + +package(default_visibility = ["//visibility:public"]) + +ng_module( + name = "legacy-datepicker", + srcs = glob(["**/*.ts"]), + assets = [ + "datepicker-demo.html", + "custom-header.html", + ":datepicker_demo_scss", + ":custom_header_scss", + ], + deps = [ + "//src/material/core", + "//src/material/datepicker", + "//src/material/icon", + "//src/material/legacy-button", + "//src/material/legacy-checkbox", + "//src/material/legacy-form-field", + "//src/material/legacy-input", + "//src/material/legacy-select", + ], +) + +sass_binary( + name = "datepicker_demo_scss", + src = "datepicker-demo.scss", + deps = [ + "//:mdc_sass_lib", + "//src/material:sass_lib", + ], +) + +sass_binary( + name = "custom_header_scss", + src = "custom-header.scss", +) diff --git a/src/dev-app/legacy-datepicker/custom-header.html b/src/dev-app/legacy-datepicker/custom-header.html new file mode 100644 index 000000000000..c6e04e16c839 --- /dev/null +++ b/src/dev-app/legacy-datepicker/custom-header.html @@ -0,0 +1,17 @@ +
+ + + {{periodLabel}} + + +
diff --git a/src/dev-app/legacy-datepicker/custom-header.scss b/src/dev-app/legacy-datepicker/custom-header.scss new file mode 100644 index 000000000000..96f28600f90c --- /dev/null +++ b/src/dev-app/legacy-datepicker/custom-header.scss @@ -0,0 +1,16 @@ +.demo-calendar-header { + display: flex; + align-items: center; + padding: 0.5em; +} + +.demo-calendar-header-label { + flex: 1; + height: 1em; + font-weight: bold; + text-align: center; +} + +.demo-double-arrow .mat-icon { + margin: -22%; +} diff --git a/src/dev-app/legacy-datepicker/datepicker-demo.html b/src/dev-app/legacy-datepicker/datepicker-demo.html new file mode 100644 index 000000000000..c3d34c6f932c --- /dev/null +++ b/src/dev-app/legacy-datepicker/datepicker-demo.html @@ -0,0 +1,352 @@ +

Options

+

+ Use touch UI + Filter odd years, months and dates + Start in year view + Disable datepicker + Disable input + Show action buttons + + + Primary + Accent + Warn + + +

+

+ + Min date + + + + + + + + + + + Max date + + + + + + + + + +

+

+ + Start at date + + + + + + + + + +

+ +

Result

+ +

+ + + Pick a date + + + + + + + + + "{{resultPickerModel.getError('matDatepickerParse').text}}" is not a valid date! + + Too early! + Too late! + Date unavailable! + +

+

Last input: {{lastDateInput}}

+

Last change: {{lastDateChange}}

+
+

+ + + + + + + + +

+ +

Input disabled datepicker

+

+ + + Input disabled + + + +

+ +

Input disabled via FormControl

+

+ + + FormControl disabled + + + + + +

+ +

Input disabled, datepicker popup enabled

+

+ + + Input disabled, datepicker enabled + + + +

+ +

Datepicker with value property binding

+

+ + + Value binding + + + + +

+ +

Datepicker with custom header

+

+ + Custom calendar header + + + + +

+ +

Datepicker with custom header extending the default header

+

+ + Custom calendar header extending default + + + + +

+ +

Range picker

+ +
+ + Enter a date range + + + + + + + + + + + + +
{{range1.value | json}}
+
+ +
+ + Enter a date range + + + + + + + + + + + + +
{{range2.value | json}}
+
+ +
+ + Enter a date range + + + + + + + + + + + + +
{{range3.value | json}}
+
+ + +

Range picker with custom selection strategy

+
+ + Enter a date range + + + + + + + + + + + + +
+ +

With custom icon

+

+ + Custom icon + + + add + + + +
+ + Custom icon + + + add + + + +
+ + Custom icon + + + + + add + +
+ + Custom icon + + + add + + + +
+ + Custom icon + + + add + + + +

diff --git a/src/dev-app/legacy-datepicker/datepicker-demo.scss b/src/dev-app/legacy-datepicker/datepicker-demo.scss new file mode 100644 index 000000000000..b2f4bbb00177 --- /dev/null +++ b/src/dev-app/legacy-datepicker/datepicker-demo.scss @@ -0,0 +1,14 @@ +@use '@angular/material' as mat; + +mat-calendar { + width: 300px; +} + +.demo-range-group { + margin-bottom: 30px; +} + +.demo-custom-range { + @include mat.datepicker-date-range-colors( + hotpink, teal, yellow, purple); +} diff --git a/src/dev-app/legacy-datepicker/datepicker-demo.ts b/src/dev-app/legacy-datepicker/datepicker-demo.ts new file mode 100644 index 000000000000..59e957852d78 --- /dev/null +++ b/src/dev-app/legacy-datepicker/datepicker-demo.ts @@ -0,0 +1,254 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + Inject, + OnDestroy, + Optional, + ViewChild, + ViewEncapsulation, + Directive, + Injectable, +} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {FormControl, FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {MatLegacyButtonModule} from '@angular/material/legacy-button'; +import {MatLegacyCheckboxModule} from '@angular/material/legacy-checkbox'; +import { + DateAdapter, + MAT_DATE_FORMATS, + MatDateFormats, + ThemePalette, + MatNativeDateModule, +} from '@angular/material/core'; +import { + MatCalendar, + MatCalendarHeader, + MatDatepickerInputEvent, + MAT_DATE_RANGE_SELECTION_STRATEGY, + MatDateRangeSelectionStrategy, + DateRange, + MatDatepickerModule, +} from '@angular/material/datepicker'; +import {MatLegacyFormFieldModule} from '@angular/material/legacy-form-field'; +import {MatIconModule} from '@angular/material/icon'; +import {MatLegacyInputModule} from '@angular/material/legacy-input'; +import {MatLegacySelectModule} from '@angular/material/legacy-select'; +import {Subject} from 'rxjs'; +import {takeUntil} from 'rxjs/operators'; + +/** Range selection strategy that preserves the current range. */ +@Injectable() +export class PreserveRangeStrategy implements MatDateRangeSelectionStrategy { + constructor(private _dateAdapter: DateAdapter) {} + + selectionFinished(date: D, currentRange: DateRange) { + let {start, end} = currentRange; + + if (start && end) { + return this._getRangeRelativeToDate(date, start, end); + } + + if (start == null) { + start = date; + } else if (end == null) { + end = date; + } + + return new DateRange(start, end); + } + + createPreview(activeDate: D | null, currentRange: DateRange): DateRange { + if (activeDate) { + if (currentRange.start && currentRange.end) { + return this._getRangeRelativeToDate(activeDate, currentRange.start, currentRange.end); + } else if (currentRange.start && !currentRange.end) { + return new DateRange(currentRange.start, activeDate); + } + } + + return new DateRange(null, null); + } + + private _getRangeRelativeToDate(date: D | null, start: D, end: D): DateRange { + let rangeStart: D | null = null; + let rangeEnd: D | null = null; + + if (date) { + const delta = Math.round(Math.abs(this._dateAdapter.compareDate(start, end)) / 2); + rangeStart = this._dateAdapter.addCalendarDays(date, -delta); + rangeEnd = this._dateAdapter.addCalendarDays(date, delta); + } + + return new DateRange(rangeStart, rangeEnd); + } +} + +@Directive({ + selector: '[customRangeStrategy]', + standalone: true, + providers: [ + { + provide: MAT_DATE_RANGE_SELECTION_STRATEGY, + useClass: PreserveRangeStrategy, + }, + ], +}) +export class CustomRangeStrategy {} + +// Custom header component for datepicker +@Component({ + selector: 'custom-header', + templateUrl: 'custom-header.html', + styleUrls: ['custom-header.css'], + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [MatIconModule], +}) +export class CustomHeader implements OnDestroy { + private readonly _destroyed = new Subject(); + + constructor( + private _calendar: MatCalendar, + private _dateAdapter: DateAdapter, + @Inject(MAT_DATE_FORMATS) private _dateFormats: MatDateFormats, + cdr: ChangeDetectorRef, + ) { + _calendar.stateChanges.pipe(takeUntil(this._destroyed)).subscribe(() => cdr.markForCheck()); + } + + ngOnDestroy() { + this._destroyed.next(); + this._destroyed.complete(); + } + + get periodLabel() { + return this._dateAdapter + .format(this._calendar.activeDate, this._dateFormats.display.monthYearLabel) + .toLocaleUpperCase(); + } + + previousClicked(mode: 'month' | 'year') { + this._calendar.activeDate = + mode === 'month' + ? this._dateAdapter.addCalendarMonths(this._calendar.activeDate, -1) + : this._dateAdapter.addCalendarYears(this._calendar.activeDate, -1); + } + + nextClicked(mode: 'month' | 'year') { + this._calendar.activeDate = + mode === 'month' + ? this._dateAdapter.addCalendarMonths(this._calendar.activeDate, 1) + : this._dateAdapter.addCalendarYears(this._calendar.activeDate, 1); + } +} + +@Component({ + selector: 'customer-header-ng-content', + template: ` + + + + `, + standalone: true, + imports: [MatDatepickerModule], +}) +export class CustomHeaderNgContent { + @ViewChild(MatCalendarHeader) + header: MatCalendarHeader; + + constructor(@Optional() private _dateAdapter: DateAdapter) {} + + todayClicked() { + let calendar = this.header.calendar; + + calendar.activeDate = this._dateAdapter.today(); + calendar.currentView = 'month'; + } +} + +@Component({ + selector: 'legacy-datepicker-demo', + templateUrl: 'datepicker-demo.html', + styleUrls: ['datepicker-demo.css'], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: true, + imports: [ + CommonModule, + FormsModule, + MatLegacyButtonModule, + MatLegacyCheckboxModule, + MatDatepickerModule, + MatLegacyFormFieldModule, + MatIconModule, + MatLegacyInputModule, + MatNativeDateModule, + MatLegacySelectModule, + ReactiveFormsModule, + CustomHeader, + CustomHeaderNgContent, + CustomRangeStrategy, + ], +}) +export class LegacyDatepickerDemo { + touch: boolean; + filterOdd: boolean; + yearView: boolean; + inputDisabled: boolean; + datepickerDisabled: boolean; + minDate: Date; + maxDate: Date; + startAt: Date; + date: any; + lastDateInput: Date | null; + lastDateChange: Date | null; + color: ThemePalette; + showActions = false; + + dateCtrl = new FormControl(null); + range1 = new FormGroup({ + start: new FormControl(null), + end: new FormControl(null), + }); + range2 = new FormGroup({ + start: new FormControl(null), + end: new FormControl(null), + }); + range3 = new FormGroup({ + start: new FormControl(null), + end: new FormControl(null), + }); + comparisonStart: Date; + comparisonEnd: Date; + + constructor() { + const today = new Date(); + const year = today.getFullYear(); + const month = today.getMonth(); + this.comparisonStart = new Date(year, month, 9); + this.comparisonEnd = new Date(year, month, 13); + } + + dateFilter: (date: Date | null) => boolean = (date: Date | null) => { + if (date === null) { + return true; + } + return !(date.getFullYear() % 2) && Boolean(date.getMonth() % 2) && !(date.getDate() % 2); + }; + + onDateInput = (e: MatDatepickerInputEvent) => (this.lastDateInput = e.value); + onDateChange = (e: MatDatepickerInputEvent) => (this.lastDateChange = e.value); + + // pass custom header component type as input + customHeader = CustomHeader; + customHeaderNgContent = CustomHeaderNgContent; +} diff --git a/src/dev-app/routes.ts b/src/dev-app/routes.ts index 5323105904b3..30ff6db79e0e 100644 --- a/src/dev-app/routes.ts +++ b/src/dev-app/routes.ts @@ -82,6 +82,11 @@ export const DEV_APP_ROUTES: Routes = [ path: 'datepicker', loadComponent: () => import('./datepicker/datepicker-demo').then(m => m.DatepickerDemo), }, + { + path: 'legacy-datepicker', + loadComponent: () => + import('./legacy-datepicker/datepicker-demo').then(m => m.LegacyDatepickerDemo), + }, { path: 'dialog', loadComponent: () => import('./dialog/dialog-demo').then(m => m.DialogDemo), diff --git a/src/material/datepicker/BUILD.bazel b/src/material/datepicker/BUILD.bazel index d50de7583c8f..f672f09c7a45 100644 --- a/src/material/datepicker/BUILD.bazel +++ b/src/material/datepicker/BUILD.bazel @@ -33,10 +33,10 @@ ng_module( "//src/cdk/overlay", "//src/cdk/platform", "//src/cdk/portal", + "//src/material/button", "//src/material/core", - "//src/material/legacy-button", - "//src/material/legacy-form-field", - "//src/material/legacy-input", + "//src/material/form-field", + "//src/material/input", "@npm//@angular/animations", "@npm//@angular/common", "@npm//@angular/core", @@ -48,7 +48,10 @@ ng_module( sass_library( name = "datepicker_scss_lib", srcs = glob(["**/_*.scss"]), - deps = ["//src/material/core:core_scss_lib"], + deps = [ + "//src/material/button:button_scss_lib", + "//src/material/core:core_scss_lib", + ], ) sass_binary( @@ -110,8 +113,8 @@ ng_test_library( "//src/cdk/scrolling", "//src/cdk/testing/private", "//src/material/core", - "//src/material/legacy-form-field", - "//src/material/legacy-input", + "//src/material/form-field", + "//src/material/input", "//src/material/testing", "@npm//@angular/common", "@npm//@angular/forms", diff --git a/src/material/datepicker/_datepicker-legacy-compat.scss b/src/material/datepicker/_datepicker-legacy-compat.scss new file mode 100644 index 000000000000..bd290f4a6269 --- /dev/null +++ b/src/material/datepicker/_datepicker-legacy-compat.scss @@ -0,0 +1,85 @@ +@use '../button/button-theme'; +@use '../button/icon-button-theme'; + +@mixin legacy-button-compat-theme($theme) { + .mat-datepicker-content { + @include button-theme.theme($theme); + @include icon-button-theme.theme($theme); + } +} + +@mixin legacy-button-compat() { + .mat-datepicker-toggle .mat-mdc-button-base { + width: 40px; + height: 40px; + padding: 8px 0; + } + + .mat-datepicker-actions { + $spacing: 8px; + + .mat-button-base + .mat-button-base { + margin-left: $spacing; + + [dir='rtl'] & { + margin-left: 0; + margin-right: $spacing; + } + } + } +} + +@mixin legacy-form-field-compat() { + .mat-form-field { + .mat-form-field-prefix, + .mat-form-field-suffix { + .mat-datepicker-toggle .mat-mdc-button-base { + width: 40px; + height: 40px; + padding: 8px 0; + } + } + + .mat-datepicker-toggle .mat-mdc-icon-button .mat-icon { + font-size: 1em; + display: inline-block; + margin: -2px 0 1px; + } + } + + .mat-form-field-type-mat-date-range-input .mat-form-field-infix { + // Bump the default width slightly since it's somewhat cramped with two inputs and a separator. + width: 200px; + } + + .mat-form-field-appearance-legacy { + .mat-form-field-prefix, + .mat-form-field-suffix { + .mat-datepicker-toggle .mat-mdc-icon-button { + font-size: inherit; + width: 1.5em; + height: 1.5em; + padding: 0; + } + + .mat-datepicker-toggle-default-icon { + width: 1em; + } + + .mat-datepicker-toggle .mat-mdc-icon-button .mat-icon { + line-height: 1.5em; + margin: 0; + } + } + } + + .mat-form-field { + .mat-datepicker-toggle .mat-mdc-button-base { + vertical-align: middle; + } + + &:not(.mat-form-field-appearance-legacy) .mat-datepicker-toggle .mat-mdc-button-base { + vertical-align: baseline; + } + } +} diff --git a/src/material/datepicker/_datepicker-theme.scss b/src/material/datepicker/_datepicker-theme.scss index 1613423c42f2..083337b27dc9 100644 --- a/src/material/datepicker/_datepicker-theme.scss +++ b/src/material/datepicker/_datepicker-theme.scss @@ -6,7 +6,7 @@ @use '../core/theming/theming'; @use '../core/typography/typography'; @use '../core/typography/typography-utils'; - +@use '../button/icon-button-theme'; $selected-today-box-shadow-width: 1px; $selected-fade-amount: 0.6; @@ -252,7 +252,13 @@ $calendar-weekday-table-font-size: 11px !default; } } -@mixin _density($config-or-theme) {} +@mixin _density($config-or-theme) { + // Regardless of the user-passed density, we want the calendar previous/next buttons to remain at + // density -2 + .mat-calendar-controls { + @include icon-button-theme.density(-2); + } +} @mixin theme($theme-or-color-config) { $theme: theming.private-legacy-get-theme($theme-or-color-config); diff --git a/src/material/datepicker/calendar.scss b/src/material/datepicker/calendar.scss index 3c0e989e5784..cb0922a94969 100644 --- a/src/material/datepicker/calendar.scss +++ b/src/material/datepicker/calendar.scss @@ -36,11 +36,8 @@ $calendar-next-icon-transform: translateX(-2px) rotate(45deg); .mat-calendar-controls { display: flex; + align-items: center; margin: $calendar-controls-vertical-padding $calendar-controls-side-margin; - - .mat-icon-button:hover .mat-button-focus-overlay { - opacity: 0.04; - } } .mat-calendar-spacer { @@ -49,6 +46,7 @@ $calendar-next-icon-transform: translateX(-2px) rotate(45deg); .mat-calendar-period-button { min-width: 0; + margin: 0 8px; } .mat-calendar-arrow { diff --git a/src/material/datepicker/date-range-input.scss b/src/material/datepicker/date-range-input.scss index 93055b627f97..6d7ce41f2d06 100644 --- a/src/material/datepicker/date-range-input.scss +++ b/src/material/datepicker/date-range-input.scss @@ -141,7 +141,7 @@ $date-range-input-part-max-width: calc(50% - #{$date-range-input-separator-spaci max-width: $date-range-input-part-max-width; } -.mat-form-field-type-mat-date-range-input .mat-form-field-infix { +.mat-mdc-form-field-type-mat-date-range-input .mat-mdc-form-field-infix { // Bump the default width slightly since it's somewhat cramped with two inputs and a separator. width: 200px; } diff --git a/src/material/datepicker/date-range-input.spec.ts b/src/material/datepicker/date-range-input.spec.ts index 4418b27fb2e7..2bef6dad2c5c 100644 --- a/src/material/datepicker/date-range-input.spec.ts +++ b/src/material/datepicker/date-range-input.spec.ts @@ -14,8 +14,8 @@ import {Directionality} from '@angular/cdk/bidi'; import {OverlayContainer} from '@angular/cdk/overlay'; import {ErrorStateMatcher, MatNativeDateModule} from '@angular/material/core'; import {MatDatepickerModule} from './datepicker-module'; -import {MatLegacyFormFieldModule} from '@angular/material/legacy-form-field'; -import {MatLegacyInputModule} from '@angular/material/legacy-input'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {MatInputModule} from '@angular/material/input'; import {dispatchFakeEvent, dispatchKeyboardEvent} from '../../cdk/testing/private'; import {FocusMonitor} from '@angular/cdk/a11y'; import {BACKSPACE, LEFT_ARROW, RIGHT_ARROW} from '@angular/cdk/keycodes'; @@ -34,8 +34,8 @@ describe('MatDateRangeInput', () => { imports: [ FormsModule, MatDatepickerModule, - MatLegacyFormFieldModule, - MatLegacyInputModule, + MatFormFieldModule, + MatInputModule, NoopAnimationsModule, ReactiveFormsModule, MatNativeDateModule, @@ -163,7 +163,7 @@ describe('MatDateRangeInput', () => { it('should point the label aria-owns to the ', () => { const fixture = createComponent(StandardRangePicker); fixture.detectChanges(); - const label = fixture.nativeElement.querySelector('label.mat-form-field-label'); + const label = fixture.nativeElement.querySelector('label'); const rangeInput = fixture.componentInstance.rangeInput; expect(rangeInput.id).toBeTruthy(); @@ -173,7 +173,7 @@ describe('MatDateRangeInput', () => { it('should point the range input aria-labelledby to the form field label', () => { const fixture = createComponent(StandardRangePicker); fixture.detectChanges(); - const labelId = fixture.nativeElement.querySelector('label.mat-form-field-label').id; + const labelId = fixture.nativeElement.querySelector('label').id; const rangeInput = fixture.nativeElement.querySelector('.mat-date-range-input'); expect(labelId).toBeTruthy(); @@ -183,7 +183,7 @@ describe('MatDateRangeInput', () => { it('should point the range input aria-labelledby to the form field hint element', () => { const fixture = createComponent(StandardRangePicker); fixture.detectChanges(); - const labelId = fixture.nativeElement.querySelector('.mat-hint').id; + const labelId = fixture.nativeElement.querySelector('.mat-mdc-form-field-hint').id; const rangeInput = fixture.nativeElement.querySelector('.mat-date-range-input'); expect(labelId).toBeTruthy(); @@ -203,7 +203,7 @@ describe('MatDateRangeInput', () => { const fixture = createComponent(StandardRangePicker); fixture.detectChanges(); - const label: HTMLElement = fixture.nativeElement.querySelector('.mat-form-field-label'); + const label: HTMLElement = fixture.nativeElement.querySelector('label'); expect(label).toBeTruthy(); expect(label.getAttribute('id')).toBeTruthy(); @@ -417,7 +417,7 @@ describe('MatDateRangeInput', () => { const fixture = createComponent(StandardRangePicker); fixture.detectChanges(); const startInput = fixture.componentInstance.start.nativeElement; - const formFieldContainer = fixture.nativeElement.querySelector('.mat-form-field-flex'); + const formFieldContainer = fixture.nativeElement.querySelector('.mat-mdc-text-field-wrapper'); spyOn(startInput, 'focus').and.callThrough(); @@ -432,7 +432,7 @@ describe('MatDateRangeInput', () => { fixture.detectChanges(); tick(); const endInput = fixture.componentInstance.end.nativeElement; - const formFieldContainer = fixture.nativeElement.querySelector('.mat-form-field-flex'); + const formFieldContainer = fixture.nativeElement.querySelector('.mat-mdc-text-field-wrapper'); spyOn(endInput, 'focus').and.callThrough(); diff --git a/src/material/datepicker/date-range-input.ts b/src/material/datepicker/date-range-input.ts index ce1fe6844826..3d9b0858a081 100644 --- a/src/material/datepicker/date-range-input.ts +++ b/src/material/datepicker/date-range-input.ts @@ -22,11 +22,7 @@ import { OnChanges, SimpleChanges, } from '@angular/core'; -import { - MatLegacyFormFieldControl, - MatLegacyFormField, - MAT_LEGACY_FORM_FIELD, -} from '@angular/material/legacy-form-field'; +import {MatFormFieldControl, MatFormField, 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'; @@ -66,13 +62,13 @@ let nextUniqueId = 0; changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [ - {provide: MatLegacyFormFieldControl, useExisting: MatDateRangeInput}, + {provide: MatFormFieldControl, useExisting: MatDateRangeInput}, {provide: MAT_DATE_RANGE_INPUT_PARENT, useExisting: MatDateRangeInput}, ], }) export class MatDateRangeInput implements - MatLegacyFormFieldControl>, + MatFormFieldControl>, MatDatepickerControl, MatDateRangeInputParent, MatDateRangePickerInput, @@ -259,7 +255,7 @@ export class MatDateRangeInput private _elementRef: ElementRef, @Optional() @Self() control: ControlContainer, @Optional() private _dateAdapter: DateAdapter, - @Optional() @Inject(MAT_LEGACY_FORM_FIELD) private _formField?: MatLegacyFormField, + @Optional() @Inject(MAT_FORM_FIELD) private _formField?: MatFormField, ) { if (!_dateAdapter && (typeof ngDevMode === 'undefined' || ngDevMode)) { throw createMissingDateImplError('DateAdapter'); diff --git a/src/material/datepicker/datepicker-actions.scss b/src/material/datepicker/datepicker-actions.scss index ae0059882d44..ddb4fed95519 100644 --- a/src/material/datepicker/datepicker-actions.scss +++ b/src/material/datepicker/datepicker-actions.scss @@ -5,7 +5,7 @@ align-items: center; padding: 0 $spacing $spacing $spacing; - .mat-button-base + .mat-button-base { + .mat-mdc-button-base + .mat-mdc-button-base { margin-left: $spacing; [dir='rtl'] & { diff --git a/src/material/datepicker/datepicker-actions.spec.ts b/src/material/datepicker/datepicker-actions.spec.ts index 9ec0563b0a14..e4fd8fb34104 100644 --- a/src/material/datepicker/datepicker-actions.spec.ts +++ b/src/material/datepicker/datepicker-actions.spec.ts @@ -3,8 +3,8 @@ import {ComponentFixture, TestBed, flush, fakeAsync, tick} from '@angular/core/t import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; import {MatNativeDateModule} from '@angular/material/core'; -import {MatLegacyFormFieldModule} from '@angular/material/legacy-form-field'; -import {MatLegacyInputModule} from '@angular/material/legacy-input'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {MatInputModule} from '@angular/material/input'; import {CommonModule} from '@angular/common'; import {MatDatepickerModule} from './datepicker-module'; import {MatDatepicker} from './datepicker'; @@ -16,8 +16,8 @@ describe('MatDatepickerActions', () => { CommonModule, FormsModule, MatDatepickerModule, - MatLegacyFormFieldModule, - MatLegacyInputModule, + MatFormFieldModule, + MatInputModule, NoopAnimationsModule, ReactiveFormsModule, MatNativeDateModule, diff --git a/src/material/datepicker/datepicker-input.ts b/src/material/datepicker/datepicker-input.ts index 873862b96118..fee59cf0148b 100644 --- a/src/material/datepicker/datepicker-input.ts +++ b/src/material/datepicker/datepicker-input.ts @@ -9,8 +9,8 @@ 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 {MatLegacyFormField, MAT_LEGACY_FORM_FIELD} from '@angular/material/legacy-form-field'; -import {MAT_LEGACY_INPUT_VALUE_ACCESSOR} from '@angular/material/legacy-input'; +import {MatFormField, 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 {MatDatepickerControl, MatDatepickerPanel} from './datepicker-base'; @@ -36,7 +36,7 @@ export const MAT_DATEPICKER_VALIDATORS: any = { providers: [ MAT_DATEPICKER_VALUE_ACCESSOR, MAT_DATEPICKER_VALIDATORS, - {provide: MAT_LEGACY_INPUT_VALUE_ACCESSOR, useExisting: MatDatepickerInput}, + {provide: MAT_INPUT_VALUE_ACCESSOR, useExisting: MatDatepickerInput}, ], host: { 'class': 'mat-datepicker-input', @@ -124,7 +124,7 @@ export class MatDatepickerInput elementRef: ElementRef, @Optional() dateAdapter: DateAdapter, @Optional() @Inject(MAT_DATE_FORMATS) dateFormats: MatDateFormats, - @Optional() @Inject(MAT_LEGACY_FORM_FIELD) private _formField?: MatLegacyFormField, + @Optional() @Inject(MAT_FORM_FIELD) private _formField?: MatFormField, ) { super(elementRef, dateAdapter, dateFormats); this._validator = Validators.compose(super._getValidators()); diff --git a/src/material/datepicker/datepicker-module.ts b/src/material/datepicker/datepicker-module.ts index 43cb7fd66ac1..4732992723eb 100644 --- a/src/material/datepicker/datepicker-module.ts +++ b/src/material/datepicker/datepicker-module.ts @@ -11,7 +11,7 @@ import {OverlayModule} from '@angular/cdk/overlay'; import {PortalModule} from '@angular/cdk/portal'; import {CommonModule} from '@angular/common'; import {NgModule} from '@angular/core'; -import {MatLegacyButtonModule} from '@angular/material/legacy-button'; +import {MatButtonModule} from '@angular/material/button'; import {CdkScrollableModule} from '@angular/cdk/scrolling'; import {MatCommonModule} from '@angular/material/core'; import {MatCalendar, MatCalendarHeader} from './calendar'; @@ -35,7 +35,7 @@ import {MatDatepickerActions, MatDatepickerApply, MatDatepickerCancel} from './d @NgModule({ imports: [ CommonModule, - MatLegacyButtonModule, + MatButtonModule, OverlayModule, A11yModule, PortalModule, diff --git a/src/material/datepicker/datepicker-toggle.scss b/src/material/datepicker/datepicker-toggle.scss index c94a1e84bece..9c8db69f9218 100644 --- a/src/material/datepicker/datepicker-toggle.scss +++ b/src/material/datepicker/datepicker-toggle.scss @@ -1,29 +1,5 @@ @use '@angular/cdk'; -.mat-form-field-appearance-legacy { - .mat-form-field-prefix, - .mat-form-field-suffix { - .mat-datepicker-toggle-default-icon { - width: 1em; - } - } -} - -.mat-form-field:not(.mat-form-field-appearance-legacy) { - .mat-form-field-prefix, - .mat-form-field-suffix { - .mat-datepicker-toggle-default-icon { - display: block; - width: 1.5em; - height: 1.5em; - } - - .mat-icon-button .mat-datepicker-toggle-default-icon { - margin: auto; - } - } -} - @include cdk.high-contrast(active, off) { .mat-datepicker-toggle-default-icon { // On Chromium-based browsers the icon doesn't appear to inherit the text color in high diff --git a/src/material/datepicker/datepicker-toggle.ts b/src/material/datepicker/datepicker-toggle.ts index e2f0a69bfd1d..61913c703be9 100644 --- a/src/material/datepicker/datepicker-toggle.ts +++ b/src/material/datepicker/datepicker-toggle.ts @@ -22,7 +22,7 @@ import { ViewEncapsulation, ViewChild, } from '@angular/core'; -import {MatLegacyButton} from '@angular/material/legacy-button'; +import {MatButton} from '@angular/material/button'; import {merge, Observable, of as observableOf, Subscription} from 'rxjs'; import {MatDatepickerIntl} from './datepicker-intl'; import {MatDatepickerControl, MatDatepickerPanel} from './datepicker-base'; @@ -87,7 +87,7 @@ export class MatDatepickerToggle implements AfterContentInit, OnChanges, OnDe @ContentChild(MatDatepickerToggleIcon) _customIcon: MatDatepickerToggleIcon; /** Underlying button element. */ - @ViewChild('button') _button: MatLegacyButton; + @ViewChild('button') _button: MatButton; constructor( public _intl: MatDatepickerIntl, diff --git a/src/material/datepicker/datepicker.spec.ts b/src/material/datepicker/datepicker.spec.ts index 22f449f7f750..45abba0c5329 100644 --- a/src/material/datepicker/datepicker.spec.ts +++ b/src/material/datepicker/datepicker.spec.ts @@ -30,13 +30,13 @@ import { NG_VALIDATORS, } from '@angular/forms'; import {MAT_DATE_LOCALE, MatNativeDateModule, NativeDateModule} from '@angular/material/core'; -import {MatLegacyFormField, MatLegacyFormFieldModule} from '@angular/material/legacy-form-field'; +import {MatFormField, MatFormFieldModule} from '@angular/material/form-field'; import {DEC, JAN, JUL, JUN, SEP} from '../testing'; import {By} from '@angular/platform-browser'; import {_supportsShadowDom} from '@angular/cdk/platform'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; import {Subject} from 'rxjs'; -import {MatLegacyInputModule} from '../legacy-input/index'; +import {MatInputModule} from '@angular/material/input'; import {MatDatepicker} from './datepicker'; import {MatDatepickerInput} from './datepicker-input'; import {MatDatepickerToggle} from './datepicker-toggle'; @@ -62,8 +62,8 @@ describe('MatDatepicker', () => { imports: [ FormsModule, MatDatepickerModule, - MatLegacyFormFieldModule, - MatLegacyInputModule, + MatFormFieldModule, + MatInputModule, NoopAnimationsModule, ReactiveFormsModule, ...imports, @@ -1443,9 +1443,9 @@ describe('MatDatepicker', () => { fixture.debugElement.nativeElement.querySelector('input').value = 'totally-not-a-date'; fixture.detectChanges(); - expect( - fixture.debugElement.nativeElement.querySelector('mat-form-field').classList, - ).toContain('mat-form-field-should-float'); + expect(fixture.debugElement.nativeElement.querySelector('label').classList).toContain( + 'mdc-floating-label--float-above', + ); }); it('should pass the form field theme color to the overlay', fakeAsync(() => { @@ -1490,7 +1490,7 @@ describe('MatDatepicker', () => { })); it('should set aria-labelledby of the overlay to the form field label', fakeAsync(() => { - const label: HTMLElement = fixture.nativeElement.querySelector('.mat-form-field-label'); + const label: HTMLElement = fixture.nativeElement.querySelector('label'); expect(label).toBeTruthy(); expect(label.getAttribute('id')).toBeTruthy(); @@ -2597,7 +2597,7 @@ class DatepickerWithCustomIcon {} class FormFieldDatepicker { @ViewChild('d') datepicker: MatDatepicker; @ViewChild(MatDatepickerInput) datepickerInput: MatDatepickerInput; - @ViewChild(MatLegacyFormField) formField: MatLegacyFormField; + @ViewChild(MatFormField) formField: MatFormField; } @Component({ diff --git a/src/material/legacy-button/BUILD.bazel b/src/material/legacy-button/BUILD.bazel index bb3489249937..1030d8ec2ac9 100644 --- a/src/material/legacy-button/BUILD.bazel +++ b/src/material/legacy-button/BUILD.bazel @@ -28,7 +28,10 @@ ng_module( sass_library( name = "legacy_button_scss_lib", srcs = glob(["**/_*.scss"]), - deps = ["//src/material/core:core_scss_lib"], + deps = [ + "//src/material/core:core_scss_lib", + "//src/material/datepicker:datepicker_scss_lib", + ], ) sass_binary( @@ -38,6 +41,7 @@ sass_binary( ":legacy_button_scss_lib", "//src/cdk:sass_lib", "//src/material/core:core_scss_lib", + "//src/material/datepicker:datepicker_scss_lib", ], ) diff --git a/src/material/legacy-button/_button-theme.scss b/src/material/legacy-button/_button-theme.scss index dcf7b5072388..548e1b5c7334 100644 --- a/src/material/legacy-button/_button-theme.scss +++ b/src/material/legacy-button/_button-theme.scss @@ -4,6 +4,7 @@ @use '../core/style/private'; @use '../core/typography/typography'; @use '../core/typography/typography-utils'; +@use '../datepicker/datepicker-legacy-compat'; $_ripple-opacity: 0.1; @@ -163,6 +164,12 @@ $_ripple-opacity: 0.1; @include private.private-theme-overridable-elevation(0, $config); } } + + @include datepicker-legacy-compat.legacy-button-compat-theme(( + color: $config, + typography: null, + density: null, + )); } /// @deprecated Use `mat.button-typography` instead. See https://material.angular.io/guide/mdc-migration for information about migrating. @@ -178,9 +185,21 @@ $_ripple-opacity: 0.1; weight: typography-utils.font-weight($config, button); } } + + @include datepicker-legacy-compat.legacy-button-compat-theme(( + color: null, + typography: $config, + density: null, + )); } -@mixin _density($config-or-theme) {} +@mixin _density($config-or-theme) { + @include datepicker-legacy-compat.legacy-button-compat-theme(( + color: null, + typography: null, + density: theming.get-density-config($config-or-theme) + )); +} /// @deprecated Use `mat.button-theme` instead. See https://material.angular.io/guide/mdc-migration for information about migrating. /// @breaking-change 17.0.0 diff --git a/src/material/legacy-button/button.scss b/src/material/legacy-button/button.scss index c4b61d7b8749..8bd174d6f27c 100644 --- a/src/material/legacy-button/button.scss +++ b/src/material/legacy-button/button.scss @@ -3,6 +3,7 @@ @use './button-base'; @use '../core/style/layout-common'; @use '../core/focus-indicators/private'; +@use '../datepicker/datepicker-legacy-compat'; // TODO(jelbourn): Measure perf benefits for translate3d and will-change. // TODO(jelbourn): Figure out if anchor hover underline actually happens in any browser. @@ -182,3 +183,5 @@ outline: solid 1px; } } + +@include datepicker-legacy-compat.legacy-button-compat(); diff --git a/src/material/legacy-form-field/BUILD.bazel b/src/material/legacy-form-field/BUILD.bazel index f678cfaf05be..fbed0faa133f 100644 --- a/src/material/legacy-form-field/BUILD.bazel +++ b/src/material/legacy-form-field/BUILD.bazel @@ -50,6 +50,7 @@ sass_binary( deps = [ "//src/cdk:sass_lib", "//src/material/core:core_scss_lib", + "//src/material/datepicker:datepicker_scss_lib", ], ) diff --git a/src/material/legacy-form-field/form-field.scss b/src/material/legacy-form-field/form-field.scss index 9455b53098d4..c1af04d4374f 100644 --- a/src/material/legacy-form-field/form-field.scss +++ b/src/material/legacy-form-field/form-field.scss @@ -1,6 +1,7 @@ @use '@angular/cdk'; @use '../core/style/variables'; +@use '../datepicker/datepicker-legacy-compat'; // Styles that apply to all appearances of the form-field. @@ -251,3 +252,5 @@ $default-infix-width: 180px !default; transition: none; } } + +@include datepicker-legacy-compat.legacy-form-field-compat(); diff --git a/tools/public_api_guard/material/datepicker.md b/tools/public_api_guard/material/datepicker.md index 4db59c131111..973b55c42d28 100644 --- a/tools/public_api_guard/material/datepicker.md +++ b/tools/public_api_guard/material/datepicker.md @@ -29,7 +29,7 @@ import { FocusOrigin } from '@angular/cdk/a11y'; import { FormGroupDirective } from '@angular/forms'; import * as i0 from '@angular/core'; import * as i14 from '@angular/common'; -import * as i15 from '@angular/material/legacy-button'; +import * as i15 from '@angular/material/button'; import * as i16 from '@angular/cdk/overlay'; import * as i17 from '@angular/cdk/a11y'; import * as i18 from '@angular/cdk/portal'; @@ -37,10 +37,10 @@ import * as i19 from '@angular/material/core'; import * as i20 from '@angular/cdk/scrolling'; import { InjectionToken } from '@angular/core'; import { Injector } from '@angular/core'; +import { MatButton } from '@angular/material/button'; import { MatDateFormats } from '@angular/material/core'; -import { MatLegacyButton } from '@angular/material/legacy-button'; -import { MatLegacyFormField } from '@angular/material/legacy-form-field'; -import { MatLegacyFormFieldControl } from '@angular/material/legacy-form-field'; +import { MatFormField } from '@angular/material/form-field'; +import { MatFormFieldControl } from '@angular/material/form-field'; import { NgControl } from '@angular/forms'; import { NgForm } from '@angular/forms'; import { NgZone } from '@angular/core'; @@ -489,7 +489,7 @@ export interface MatDatepickerControl { // @public export class MatDatepickerInput extends MatDatepickerInputBase implements MatDatepickerControl, OnDestroy { - constructor(elementRef: ElementRef, dateAdapter: DateAdapter, dateFormats: MatDateFormats, _formField?: MatLegacyFormField | undefined); + constructor(elementRef: ElementRef, dateAdapter: DateAdapter, dateFormats: MatDateFormats, _formField?: MatFormField | undefined); // (undocumented) protected _assignValueToModel(value: D | null): void; get dateFilter(): DateFilterFn; @@ -563,7 +563,7 @@ export class MatDatepickerModule { // (undocumented) static ɵinj: i0.ɵɵInjectorDeclaration; // (undocumented) - static ɵmod: i0.ɵɵNgModuleDeclaration; + static ɵmod: i0.ɵɵNgModuleDeclaration; } // @public @@ -584,7 +584,7 @@ export interface MatDatepickerPanel, S, D = Ex export class MatDatepickerToggle implements AfterContentInit, OnChanges, OnDestroy { constructor(_intl: MatDatepickerIntl, _changeDetectorRef: ChangeDetectorRef, defaultTabIndex: string); ariaLabel: string; - _button: MatLegacyButton; + _button: MatButton; _customIcon: MatDatepickerToggleIcon; datepicker: MatDatepickerPanel, D>; get disabled(): boolean; @@ -616,8 +616,8 @@ export class MatDatepickerToggleIcon { } // @public (undocumented) -export class MatDateRangeInput implements MatLegacyFormFieldControl>, MatDatepickerControl, MatDateRangeInputParent, MatDateRangePickerInput, AfterContentInit, OnChanges, OnDestroy { - constructor(_changeDetectorRef: ChangeDetectorRef, _elementRef: ElementRef, control: ControlContainer, _dateAdapter: DateAdapter, _formField?: MatLegacyFormField | undefined); +export class MatDateRangeInput implements MatFormFieldControl>, MatDatepickerControl, MatDateRangeInputParent, MatDateRangePickerInput, AfterContentInit, OnChanges, OnDestroy { + constructor(_changeDetectorRef: ChangeDetectorRef, _elementRef: ElementRef, control: ControlContainer, _dateAdapter: DateAdapter, _formField?: MatFormField | undefined); _ariaDescribedBy: string | null; comparisonEnd: D | null; comparisonStart: D | null;