From a67fe70397bd6faf553b6a7eed952bb9b4c0e3da Mon Sep 17 00:00:00 2001 From: Michael Prentice Date: Mon, 14 Oct 2019 10:21:19 -0400 Subject: [PATCH] refactor: enable Ivy and fix template type checking issues fix buggy show bounding box checkbox in connected-overlay-demo fix stylelint to work with WebStorm plugin Fixes #16606. Closes #16373. --- .bazelrc | 5 +- .circleci/config.yml | 8 - stylelint-config.json => .stylelintrc.json | 0 package.json | 40 +- src/a11y-demo/checkbox/checkbox-a11y.ts | 10 +- src/a11y-demo/chips/chips-a11y.ts | 3 +- src/a11y-demo/grid-list/grid-list-a11y.ts | 2 +- src/a11y-demo/input/input-a11y.ts | 2 +- src/cdk/stepper/stepper.ts | 34 +- src/dev-app/badge/badge-demo.html | 2 +- src/dev-app/checkbox/checkbox-demo.ts | 27 +- src/dev-app/chips/chips-demo.ts | 2 +- .../connected-overlay-demo.html | 12 +- .../connected-overlay-demo.scss | 10 +- .../connected-overlay-demo.ts | 22 +- src/dev-app/datepicker/datepicker-demo.html | 17 +- src/dev-app/datepicker/datepicker-demo.ts | 11 +- src/dev-app/expansion/expansion-demo.ts | 8 +- src/dev-app/grid-list/grid-list-demo.ts | 2 +- src/dev-app/input/input-demo.html | 8 +- src/dev-app/input/input-demo.ts | 8 +- src/dev-app/mdc-checkbox/mdc-checkbox-demo.ts | 25 +- .../mdc-progress-bar/mdc-progress-bar-demo.ts | 3 +- src/dev-app/progress-bar/progress-bar-demo.ts | 3 +- .../progress-spinner/progress-spinner-demo.ts | 4 +- src/dev-app/radio/radio-demo.html | 2 +- src/dev-app/select/select-demo.ts | 30 +- src/dev-app/sidenav/sidenav-demo.ts | 5 +- src/dev-app/stepper/stepper-demo.html | 5 +- .../dynamic-tree-demo/dynamic-database.ts | 6 +- .../example-custom-stepper.html | 2 +- .../autocomplete-display-example.ts | 4 +- .../checkbox-configurable-example.html | 1 - .../checkbox-configurable-example.ts | 2 +- .../datepicker-date-class-example.ts | 5 +- .../progress-bar-configurable-example.ts | 6 +- .../progress-spinner-configurable-example.ts | 6 +- .../slide-toggle-configurable-example.ts | 3 +- .../table-text-column-advanced-example.ts | 5 +- .../tab-nav-bar-basic-example.ts | 5 +- .../tree/tree-dynamic/tree-dynamic-example.ts | 6 +- .../mdc-progress-bar/progress-bar.ts | 2 +- .../mdc-tabs/tab-group.html | 16 +- src/material/core/option/option.html | 2 +- src/material/datepicker/month-view.html | 4 +- src/material/datepicker/multi-year-view.html | 2 +- src/material/datepicker/year-view.html | 4 +- .../progress-bar/progress-bar.spec.ts | 6 +- src/material/progress-bar/progress-bar.ts | 5 +- src/material/select/select.ts | 9 +- src/material/sidenav/drawer.ts | 9 +- src/material/stepper/stepper-horizontal.html | 4 +- src/material/stepper/stepper-vertical.html | 2 +- src/material/stepper/stepper.ts | 6 +- src/material/tabs/tab-body.ts | 8 +- src/material/tabs/tab-group.html | 10 +- src/material/tabs/tab-group.ts | 13 +- tools/defaults.bzl | 7 +- tools/gulp/tasks/lint.ts | 2 +- yarn.lock | 1621 ++++++----------- 60 files changed, 832 insertions(+), 1261 deletions(-) rename stylelint-config.json => .stylelintrc.json (100%) diff --git a/.bazelrc b/.bazelrc index c5f13f75da26..0e0cd9a1a737 100644 --- a/.bazelrc +++ b/.bazelrc @@ -40,9 +40,8 @@ build:release --workspace_status_command="node ./tools/bazel-stamp-vars.js" # Temporary Settings for Ivy # ################################ -# Use the legacy AOT compiler strategy. We don't want to compile with Ivy nor with "ngtsc" which -# does not generate factory files which are needed for AOT. -build --define=compile=legacy +# We want to compile with Ivy and with "ngtsc". +build --define=compile=aot ####################### # Remote HTTP Caching # diff --git a/.circleci/config.yml b/.circleci/config.yml index 4231d9c8d2e8..d735c82079e7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -406,10 +406,6 @@ jobs: # Setup ngcc to make the Angular packages compatible with ngtsc (i.e. creating # directive and component definitions as static class members). - run: node ./scripts/circleci/setup-ivy-ngcc.js - # Disable type checking when building with Ivy. This is necessary because - # type checking is not complete yet and can incorrectly break compilation. - # Issue is tracked with FW-1004. - - run: sed -i "s/\(_ENABLE_NG_TYPE_CHECKING = \)True/\1False/g" tools/defaults.bzl # Run project tests with ngtsc and the Ivy Angular packages. - run: bazel build src/... --build_tag_filters=-docs-package,-e2e --define=compile=aot - run: bazel test src/... --build_tag_filters=-docs-package,-e2e --test_tag_filters=-e2e --define=compile=aot @@ -433,10 +429,6 @@ jobs: # Setup Angular ivy snapshots built with ngtsc. - run: node ./scripts/circleci/setup-angular-snapshots.js --tag master-ivy-aot - # Disable type checking when building with Ivy. This is necessary because - # type checking is not complete yet and can incorrectly break compilation. - # Issue is tracked with FW-1004. - - run: sed -i "s/\(_ENABLE_NG_TYPE_CHECKING = \)True/\1False/g" tools/defaults.bzl # Run project tests with ngtsc and the Ivy Angular packages. - run: bazel build src/... --build_tag_filters=-docs-package,-e2e --define=compile=aot - run: bazel test src/... --build_tag_filters=-docs-package,-e2e --test_tag_filters=-e2e --define=compile=aot diff --git a/stylelint-config.json b/.stylelintrc.json similarity index 100% rename from stylelint-config.json rename to .stylelintrc.json diff --git a/package.json b/package.json index d5b5ffe02d94..6fc8b663e746 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,11 @@ }, "license": "MIT", "engines": { - "node": ">= 5.4.1", + "node": "10", "yarn": ">= 1.17.3" }, "scripts": { - "postinstall": "node --preserve-symlinks --preserve-symlinks-main tools/bazel/postinstall-patches.js", + "postinstall": "node --preserve-symlinks --preserve-symlinks-main tools/bazel/postinstall-patches.js | ivy-ngcc --properties main", "build": "bash ./scripts/build-packages-dist.sh", "bazel:buildifier": "find . -type f \\( -name \"*.bzl\" -or -name WORKSPACE -or -name BUILD -or -name BUILD.bazel \\) ! -path \"*/node_modules/*\" | xargs buildifier -v --warnings=attr-cfg,attr-license,attr-non-empty,attr-output-default,attr-single-file,constant-glob,ctx-args,depset-iteration,depset-union,dict-concatenation,duplicated-name,filetype,git-repository,http-archive,integer-division,load,load-on-top,native-build,native-package,output-group,package-name,package-on-top,redefined-variable,repository-name,same-origin-load,string-iteration,unused-variable,unsorted-dict-items,out-of-order-load", "bazel:format-lint": "yarn -s bazel:buildifier --lint=warn --mode=check", @@ -41,33 +41,33 @@ "requiredAngularVersion": "^8.0.0 || ^9.0.0-0", "requiredMDCVersion": "^4.0.0-alpha.0", "dependencies": { - "@angular/animations": "^9.0.0-next.10", - "@angular/common": "^9.0.0-next.10", - "@angular/compiler": "^9.0.0-next.10", - "@angular/core": "^9.0.0-next.10", - "@angular/elements": "^9.0.0-next.10", - "@angular/forms": "^9.0.0-next.10", - "@angular/platform-browser": "^9.0.0-next.10", + "@angular/animations": "9.0.0-next.10", + "@angular/common": "9.0.0-next.10", + "@angular/compiler": "9.0.0-next.10", + "@angular/core": "9.0.0-next.10", + "@angular/elements": "9.0.0-next.10", + "@angular/forms": "9.0.0-next.10", + "@angular/platform-browser": "9.0.0-next.10", "@types/googlemaps": "^3.37.0", "@types/youtube": "^0.0.38", "@webcomponents/custom-elements": "^1.1.0", - "core-js": "^2.6.1", + "core-js": "^2.6.9", "material-components-web": "^4.0.0-canary.e851d4f40.0", "rxjs": "^6.5.3", "systemjs": "0.19.43", "tsickle": "^0.35.0", - "tslib": "^1.9.3", + "tslib": "^1.10.0", "zone.js": "~0.10.2" }, "devDependencies": { "@angular-devkit/core": "^9.0.0-next.9", "@angular-devkit/schematics": "^9.0.0-next.9", - "@angular/bazel": "^9.0.0-next.10", - "@angular/compiler-cli": "^9.0.0-next.10", - "@angular/platform-browser-dynamic": "^9.0.0-next.10", - "@angular/platform-server": "^9.0.0-next.10", - "@angular/router": "^9.0.0-next.10", - "@angular/upgrade": "^9.0.0-next.10", + "@angular/bazel": "9.0.0-next.10", + "@angular/compiler-cli": "9.0.0-next.10", + "@angular/platform-browser-dynamic": "9.0.0-next.10", + "@angular/platform-server": "9.0.0-next.10", + "@angular/router": "9.0.0-next.10", + "@angular/upgrade": "9.0.0-next.10", "@bazel/bazel": "^0.29.0", "@bazel/buildifier": "^0.29.0", "@bazel/ibazel": "^0.10.3", @@ -98,11 +98,11 @@ "browser-sync": "^2.26.7", "chalk": "^2.4.2", "clang-format": "^1.2.4", - "codelyzer": "^5.1.1", + "codelyzer": "^5.1.2", "conventional-changelog": "^3.0.5", "dgeni": "^0.4.11", "dgeni-packages": "^0.27.1", - "firebase-tools": "^4.1.0", + "firebase-tools": "^7.5.0", "fs-extra": "^3.0.1", "glob": "^7.1.2", "gulp": "^3.9.1", @@ -151,7 +151,7 @@ "ts-api-guardian": "^0.4.6", "ts-node": "^3.0.4", "tsconfig-paths": "^2.3.0", - "tslint": "^5.19.0", + "tslint": "^5.20.0", "tsutils": "^3.0.0", "typescript": "3.5.3", "uglify-js": "^2.8.14" diff --git a/src/a11y-demo/checkbox/checkbox-a11y.ts b/src/a11y-demo/checkbox/checkbox-a11y.ts index 68cca8af6e18..e9ad24810a4c 100644 --- a/src/a11y-demo/checkbox/checkbox-a11y.ts +++ b/src/a11y-demo/checkbox/checkbox-a11y.ts @@ -50,12 +50,18 @@ export class CheckboxAccessibilityDemo { return task.completed || (subtasks != null && subtasks.every(t => t.completed)); } - someComplete(tasks: Task[]): boolean { + someComplete(tasks: Task[] | undefined | null): boolean { + if (tasks == null) { + return false; + } const numComplete = tasks.filter(t => t.completed).length; return numComplete > 0 && numComplete < tasks.length; } - setAllCompleted(tasks: Task[], completed: boolean) { + setAllCompleted(tasks: Task[] | undefined | null, completed: boolean): void { + if (tasks == null) { + return; + } tasks.forEach(t => t.completed = completed); } } diff --git a/src/a11y-demo/chips/chips-a11y.ts b/src/a11y-demo/chips/chips-a11y.ts index a0241158f801..3701221e931d 100644 --- a/src/a11y-demo/chips/chips-a11y.ts +++ b/src/a11y-demo/chips/chips-a11y.ts @@ -9,6 +9,7 @@ import {Component} from '@angular/core'; import {MatChipInputEvent} from '@angular/material/chips'; import {MatSnackBar} from '@angular/material/snack-bar'; +import {ThemePalette} from '@angular/material/core'; export interface Person { @@ -23,7 +24,7 @@ export interface Person { }) export class ChipsAccessibilityDemo { visible: boolean = true; - color: string = ''; + color: ThemePalette; selectable: boolean = true; removable: boolean = true; addOnBlur: boolean = true; diff --git a/src/a11y-demo/grid-list/grid-list-a11y.ts b/src/a11y-demo/grid-list/grid-list-a11y.ts index 7eab81f67ae1..7a80cbd5cadc 100644 --- a/src/a11y-demo/grid-list/grid-list-a11y.ts +++ b/src/a11y-demo/grid-list/grid-list-a11y.ts @@ -39,7 +39,7 @@ export class GridListAccessibilityDemo { fixedCols = 4; fixedRowHeight = 100; - ratioGutter = 1; + ratioGutter = '1px'; fitListHeight = '400px'; ratio = '4:1'; } diff --git a/src/a11y-demo/input/input-a11y.ts b/src/a11y-demo/input/input-a11y.ts index 249f5a85dde9..49a003b1e99d 100644 --- a/src/a11y-demo/input/input-a11y.ts +++ b/src/a11y-demo/input/input-a11y.ts @@ -24,7 +24,7 @@ export class InputAccessibilityDemo { email: string; usd: number; comment: string; - commentMax = 200; + commentMax = '200'; get passwordType() { return this.showPassword ? 'text' : 'password'; } diff --git a/src/cdk/stepper/stepper.ts b/src/cdk/stepper/stepper.ts index f5a2e59cf349..f43d8e81a82c 100644 --- a/src/cdk/stepper/stepper.ts +++ b/src/cdk/stepper/stepper.ts @@ -34,7 +34,7 @@ import { ViewChild, ViewEncapsulation, } from '@angular/core'; -import {Observable, of as obaservableOf, Subject} from 'rxjs'; +import {Observable, of as observableOf, Subject} from 'rxjs'; import {startWith, takeUntil} from 'rxjs/operators'; import {CdkStepHeader} from './step-header'; @@ -124,7 +124,7 @@ export class CdkStep implements OnChanges { @ViewChild(TemplateRef, {static: true}) content: TemplateRef; /** The top level abstract control of the step. */ - @Input() stepControl: FormControlLike; + @Input() stepControl: AbstractControlLike; /** Whether user has seen the expanded step content or not. */ interacted = false; @@ -257,6 +257,12 @@ export class CdkStepper implements AfterViewInit, OnDestroy { */ @ContentChildren(CdkStep) _steps: QueryList; + /** + * We need to store the steps in an Iterable due to strict template type checking with *ngFor and + * https://github.com/angular/angular/issues/29842. + */ + _stepsArray: CdkStep[] = []; + /** The list of step components that the stepper is holding. */ get steps(): QueryList { return this._steps; @@ -332,13 +338,13 @@ export class CdkStepper implements AfterViewInit, OnDestroy { ngAfterViewInit() { // Note that while the step headers are content children by default, any components that - // extend this one might have them as view chidren. We initialize the keyboard handling in + // extend this one might have them as view children. We initialize the keyboard handling in // AfterViewInit so we're guaranteed for both view and content children to be defined. this._keyManager = new FocusKeyManager(this._stepHeader) .withWrap() .withVerticalOrientation(this._orientation === 'vertical'); - (this._dir ? (this._dir.change as Observable) : obaservableOf()) + (this._dir ? (this._dir.change as Observable) : observableOf()) .pipe(startWith(this._layoutDirection()), takeUntil(this._destroyed)) .subscribe(direction => this._keyManager.withHorizontalOrientation(direction)); @@ -517,12 +523,12 @@ export class CdkStepper implements AfterViewInit, OnDestroy { /** - * Simplified representation of a FormControl from @angular/forms. + * Simplified representation of an "AbstractControl" from @angular/forms. * Used to avoid having to bring in @angular/forms for a single optional interface. * @docs-private */ -interface FormControlLike { - asyncValidator: () => any | null; +interface AbstractControlLike { + asyncValidator: ((control: any) => any) | null; dirty: boolean; disabled: boolean; enabled: boolean; @@ -531,21 +537,21 @@ interface FormControlLike { parent: any; pending: boolean; pristine: boolean; - root: FormControlLike; + root: AbstractControlLike; status: string; statusChanges: Observable; touched: boolean; untouched: boolean; updateOn: any; valid: boolean; - validator: () => any | null; + validator: ((control: any) => any) | null; value: any; valueChanges: Observable; clearAsyncValidators(): void; clearValidators(): void; disable(opts?: any): void; enable(opts?: any): void; - get(path: (string | number)[] | string): FormControlLike | null; + get(path: (string | number)[] | string): AbstractControlLike | null; getError(errorCode: string, path?: (string | number)[] | string): any; hasError(errorCode: string, path?: (string | number)[] | string): boolean; markAllAsTouched(): void; @@ -556,15 +562,15 @@ interface FormControlLike { markAsUntouched(opts?: any): void; patchValue(value: any, options?: Object): void; reset(value?: any, options?: Object): void; - setAsyncValidators(newValidator: () => any | (() => any)[] | null): void; + setAsyncValidators(newValidator: (control: any) => any | + ((control: any) => any)[] | null): void; setErrors(errors: {[key: string]: any} | null, opts?: any): void; setParent(parent: any): void; - setValidators(newValidator: () => any | (() => any)[] | null): void; + setValidators(newValidator: (control: any) => any | + ((control: any) => any)[] | null): void; setValue(value: any, options?: Object): void; updateValueAndValidity(opts?: any): void; patchValue(value: any, options?: any): void; - registerOnChange(fn: Function): void; - registerOnDisabledChange(fn: (isDisabled: boolean) => void): void; reset(formState?: any, options?: any): void; setValue(value: any, options?: any): void; } diff --git a/src/dev-app/badge/badge-demo.html b/src/dev-app/badge/badge-demo.html index 029c183d6bdd..c07828170996 100644 --- a/src/dev-app/badge/badge-demo.html +++ b/src/dev-app/badge/badge-demo.html @@ -6,7 +6,7 @@

Text

Hello - + Hello diff --git a/src/dev-app/checkbox/checkbox-demo.ts b/src/dev-app/checkbox/checkbox-demo.ts index a56c4d3afa27..846ac9451003 100644 --- a/src/dev-app/checkbox/checkbox-demo.ts +++ b/src/dev-app/checkbox/checkbox-demo.ts @@ -9,6 +9,7 @@ import {Component, Directive} from '@angular/core'; import {MAT_CHECKBOX_CLICK_ACTION} from '@angular/material/checkbox'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; +import {ThemePalette} from '@angular/material/core'; export interface Task { @@ -46,7 +47,7 @@ export class AnimationsNoop { margin-bottom: 4px; } `], - templateUrl: 'nested-checklist.html', + templateUrl: './nested-checklist.html', }) export class MatCheckboxDemoNestedChecklist { tasks: Task[] = [ @@ -76,12 +77,18 @@ export class MatCheckboxDemoNestedChecklist { return task.completed || (subtasks != null && subtasks.every(t => t.completed)); } - someComplete(tasks: Task[]): boolean { + someComplete(tasks: Task[] | undefined | null): boolean { + if (tasks == null) { + return false; + } const numComplete = tasks.filter(t => t.completed).length; return numComplete > 0 && numComplete < tasks.length; } - setAllCompleted(tasks: Task[], completed: boolean) { + setAllCompleted(tasks: Task[] | undefined | null, completed: boolean): void { + if (tasks == null) { + return; + } tasks.forEach(t => t.completed = completed); } } @@ -96,7 +103,7 @@ export class CheckboxDemo { isIndeterminate: boolean = false; isChecked: boolean = false; isDisabled: boolean = false; - labelPosition: string = 'after'; + labelPosition: 'after' | 'before' = 'after'; useAlternativeColor: boolean = false; demoRequired = false; @@ -104,12 +111,12 @@ export class CheckboxDemo { demoChecked = false; demoDisabled = false; demoIndeterminate = false; - demoLabel = null; - demoLabelledBy = null; - demoId = null; - demoName = null; - demoValue = null; - demoColor = 'primary'; + demoLabel: string; + demoLabelledBy: string; + demoId: string; + demoName: string; + demoValue: string; + demoColor: ThemePalette = 'primary'; demoDisableRipple = false; demoHideLabel = false; diff --git a/src/dev-app/chips/chips-demo.ts b/src/dev-app/chips/chips-demo.ts index 8a5c79572367..8de6a7bcdfd0 100644 --- a/src/dev-app/chips/chips-demo.ts +++ b/src/dev-app/chips/chips-demo.ts @@ -30,7 +30,7 @@ export interface DemoColor { export class ChipsDemo { tabIndex = 0; visible = true; - color = ''; + color: ThemePalette; selectable = true; removable = true; addOnBlur = true; diff --git a/src/dev-app/connected-overlay/connected-overlay-demo.html b/src/dev-app/connected-overlay/connected-overlay-demo.html index 77dd7445d092..20985f7aeaeb 100644 --- a/src/dev-app/connected-overlay/connected-overlay-demo.html +++ b/src/dev-app/connected-overlay/connected-overlay-demo.html @@ -1,6 +1,6 @@
-
+

Origin X

@@ -81,8 +81,8 @@

Options

- + Show bounding box
@@ -93,18 +93,18 @@

Options

-
+
-
+
  • {{itemText}} {{i}}
diff --git a/src/dev-app/connected-overlay/connected-overlay-demo.scss b/src/dev-app/connected-overlay/connected-overlay-demo.scss index 0f46359f1cfe..e3bca738bb47 100644 --- a/src/dev-app/connected-overlay/connected-overlay-demo.scss +++ b/src/dev-app/connected-overlay/connected-overlay-demo.scss @@ -1,4 +1,4 @@ -.demo-options { +.demo-options-connected-overlay { display: flex; margin: 20px; @@ -12,7 +12,7 @@ } } -.demo-overlay { +.demo-overlay-connected-overlay { display: block; background: lightblue; @@ -23,9 +23,13 @@ overflow: auto; } -.demo-trigger { +.demo-trigger-connected-overlay { display: flex; justify-content: center; align-items: center; padding: 10px; } + +.cdk-overlay-connected-position-bounding-box.demo-bounding-box-visible { + background: rgb(255, 69, 0, 0.2); +} diff --git a/src/dev-app/connected-overlay/connected-overlay-demo.ts b/src/dev-app/connected-overlay/connected-overlay-demo.ts index 5db4f3691b38..3a57b8abfe12 100644 --- a/src/dev-app/connected-overlay/connected-overlay-demo.ts +++ b/src/dev-app/connected-overlay/connected-overlay-demo.ts @@ -15,7 +15,13 @@ import { VerticalConnectionPos } from '@angular/cdk/overlay'; import {TemplatePortal} from '@angular/cdk/portal'; -import {Component, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core'; +import { + Component, + TemplateRef, + ViewChild, + ViewContainerRef, + ViewEncapsulation +} from '@angular/core'; @Component({ @@ -23,6 +29,7 @@ import {Component, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core selector: 'overlay-demo', templateUrl: 'connected-overlay-demo.html', styleUrls: ['connected-overlay-demo.css'], + encapsulation: ViewEncapsulation.None }) export class ConnectedOverlayDemo { @ViewChild(CdkOverlayOrigin, {static: false}) _overlayOrigin: CdkOverlayOrigin; @@ -34,7 +41,7 @@ export class ConnectedOverlayDemo { overlayY: VerticalConnectionPos = 'top'; isFlexible = true; canPush = true; - showBoundingBox = false; + isBoundingBoxVisible = false; offsetX = 0; offsetY = 0; itemCount = 25; @@ -92,16 +99,19 @@ export class ConnectedOverlayDemo { if (this.overlayRef) { this.overlayRef.dispose(); this.overlayRef = null; - this.showBoundingBox = false; + this.isBoundingBoxVisible = false; } } - toggleShowBoundingBox() { + showBoundingBox(showBoundingBox: boolean) { const box = document.querySelector('.cdk-overlay-connected-position-bounding-box'); if (box) { - this.showBoundingBox = !this.showBoundingBox; - box.style.background = this.showBoundingBox ? 'rgb(255, 69, 0, 0.2)' : ''; + if (showBoundingBox) { + box.classList.add('demo-bounding-box-visible'); + } else { + box.classList.remove('demo-bounding-box-visible'); + } } } } diff --git a/src/dev-app/datepicker/datepicker-demo.html b/src/dev-app/datepicker/datepicker-demo.html index 3abeedf1d183..abd02e63e8d8 100644 --- a/src/dev-app/datepicker/datepicker-demo.html +++ b/src/dev-app/datepicker/datepicker-demo.html @@ -51,7 +51,7 @@

Result

[(ngModel)]="date" [min]="minDate" [max]="maxDate" - [matDatepickerFilter]="filterOdd ? dateFilter : null" + [matDatepickerFilter]="filterOdd ? dateFilter : undefined" [disabled]="inputDisabled" (dateInput)="onDateInput($event)" (dateChange)="onDateChange($event)"> @@ -81,7 +81,7 @@

Result

[min]="minDate" [max]="maxDate" [disabled]="inputDisabled" - [matDatepickerFilter]="filterOdd ? dateFilter : null" + [matDatepickerFilter]="filterOdd ? dateFilter : undefined" placeholder="Pick a date"> Input disabled datepicker Input disabled + [matDatepickerFilter]="filterOdd ? dateFilter : undefined" disabled> @@ -111,7 +111,7 @@

Input disabled via FormControl

FormControl disabled + [max]="maxDate" [matDatepickerFilter]="filterOdd ? dateFilter : undefined"> @@ -127,7 +127,7 @@

Input disabled, datepicker popup enabled

Input disabled, datepicker enabled + [max]="maxDate" [matDatepickerFilter]="filterOdd ? dateFilter : undefined"> @@ -138,8 +138,13 @@

Datepicker with value property binding

Value binding + + [max]="maxDate" [matDatepickerFilter]="filterOdd ? dateFilter : undefined"> diff --git a/src/dev-app/datepicker/datepicker-demo.ts b/src/dev-app/datepicker/datepicker-demo.ts index d30a8c19ab87..d8a60193a224 100644 --- a/src/dev-app/datepicker/datepicker-demo.ts +++ b/src/dev-app/datepicker/datepicker-demo.ts @@ -42,15 +42,20 @@ export class DatepickerDemo { minDate: Date; maxDate: Date; startAt: Date; - date: Date; + date: any; lastDateInput: Date | null; lastDateChange: Date | null; color: ThemePalette; dateCtrl = new FormControl(); - dateFilter = - (date: Date) => !(date.getFullYear() % 2) && (date.getMonth() % 2) && !(date.getDate() % 2) + 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; diff --git a/src/dev-app/expansion/expansion-demo.ts b/src/dev-app/expansion/expansion-demo.ts index 42d289c30e2b..3622645a2896 100644 --- a/src/dev-app/expansion/expansion-demo.ts +++ b/src/dev-app/expansion/expansion-demo.ts @@ -7,7 +7,9 @@ */ import {Component, ViewChild} from '@angular/core'; -import {MatAccordion} from '@angular/material/expansion'; +import { + MatAccordion, MatAccordionDisplayMode, MatAccordionTogglePosition +} from '@angular/material/expansion'; @Component({ @@ -19,12 +21,12 @@ import {MatAccordion} from '@angular/material/expansion'; export class ExpansionDemo { @ViewChild(MatAccordion, {static: false}) accordion: MatAccordion; - displayMode = 'default'; + displayMode: MatAccordionDisplayMode = 'default'; multi = false; hideToggle = false; disabled = false; showPanel3 = true; - togglePosition = 'after'; + togglePosition: MatAccordionTogglePosition = 'after'; expandedHeight: string; collapsedHeight: string; events: string[] = []; diff --git a/src/dev-app/grid-list/grid-list-demo.ts b/src/dev-app/grid-list/grid-list-demo.ts index be82d7b85196..4039530112ad 100644 --- a/src/dev-app/grid-list/grid-list-demo.ts +++ b/src/dev-app/grid-list/grid-list-demo.ts @@ -35,7 +35,7 @@ export class GridListDemo { basicRowHeight = 80; fixedCols = 4; fixedRowHeight = 100; - ratioGutter = 1; + ratioGutter = '1px'; fitListHeight = '400px'; ratio = '4:1'; diff --git a/src/dev-app/input/input-demo.html b/src/dev-app/input/input-demo.html index 5defa027774d..90cbe268c5d6 100644 --- a/src/dev-app/input/input-demo.html +++ b/src/dev-app/input/input-demo.html @@ -362,7 +362,7 @@

Textarea

Both: Email address - + email   @gmail.com @@ -550,9 +550,9 @@

Regular <textarea> with maxRows and minRows

- + [cdkAutosizeMinRows]="parseNumber(minRows.value)" + [cdkAutosizeMaxRows]="parseNumber(maxRows.value)"> +

<textarea> with mat-form-field

diff --git a/src/dev-app/input/input-demo.ts b/src/dev-app/input/input-demo.ts index b8708115820f..6e5ab3d76fb0 100644 --- a/src/dev-app/input/input-demo.ts +++ b/src/dev-app/input/input-demo.ts @@ -8,7 +8,7 @@ import {ChangeDetectionStrategy, Component} from '@angular/core'; import {FormControl, Validators} from '@angular/forms'; -import {ErrorStateMatcher} from '@angular/material/core'; +import {ErrorStateMatcher, FloatLabelType} from '@angular/material/core'; let max = 5; @@ -23,7 +23,7 @@ const EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA styleUrls: ['input-demo.css'], }) export class InputDemo { - floatingLabel = 'auto'; + floatingLabel: FloatLabelType = 'auto'; color: boolean; requiredField: boolean; hideRequiredMarker: boolean; @@ -92,4 +92,8 @@ export class InputDemo { this.placeholderTestControl.markAsUntouched() : this.placeholderTestControl.markAsTouched(); } + + parseNumber(value: string): number { + return Number(value); + } } diff --git a/src/dev-app/mdc-checkbox/mdc-checkbox-demo.ts b/src/dev-app/mdc-checkbox/mdc-checkbox-demo.ts index 1329135bb3a6..d3e5b9b87848 100644 --- a/src/dev-app/mdc-checkbox/mdc-checkbox-demo.ts +++ b/src/dev-app/mdc-checkbox/mdc-checkbox-demo.ts @@ -9,6 +9,7 @@ import {Component, Directive} from '@angular/core'; import {MAT_CHECKBOX_CLICK_ACTION} from '@angular/material/checkbox'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; +import {ThemePalette} from '@angular/material/core'; export interface Task { @@ -77,12 +78,18 @@ export class MatCheckboxDemoNestedChecklist { return task.completed || (subtasks != null && subtasks.every(t => t.completed)); } - someComplete(tasks: Task[]): boolean { + someComplete(tasks: Task[] | undefined | null): boolean { + if (tasks == null) { + return false; + } const numComplete = tasks.filter(t => t.completed).length; return numComplete > 0 && numComplete < tasks.length; } - setAllCompleted(tasks: Task[], completed: boolean) { + setAllCompleted(tasks: Task[] | undefined | null, completed: boolean): void { + if (tasks == null) { + return; + } tasks.forEach(t => t.completed = completed); } } @@ -97,7 +104,7 @@ export class MdcCheckboxDemo { isIndeterminate: boolean = false; isChecked: boolean = false; isDisabled: boolean = false; - labelPosition: string = 'after'; + labelPosition: 'before' | 'after' = 'after'; useAlternativeColor: boolean = false; demoRequired = false; @@ -105,12 +112,12 @@ export class MdcCheckboxDemo { demoChecked = false; demoDisabled = false; demoIndeterminate = false; - demoLabel = null; - demoLabelledBy = null; - demoId = null; - demoName = null; - demoValue = null; - demoColor = 'primary'; + demoLabel: string; + demoLabelledBy: string; + demoId: string; + demoName: string; + demoValue: string; + demoColor: ThemePalette = 'primary'; demoDisableRipple = false; demoHideLabel = false; diff --git a/src/dev-app/mdc-progress-bar/mdc-progress-bar-demo.ts b/src/dev-app/mdc-progress-bar/mdc-progress-bar-demo.ts index 349ee2e60cf2..49d38302d37b 100644 --- a/src/dev-app/mdc-progress-bar/mdc-progress-bar-demo.ts +++ b/src/dev-app/mdc-progress-bar/mdc-progress-bar-demo.ts @@ -7,6 +7,7 @@ */ import {Component} from '@angular/core'; +import {ThemePalette} from '@angular/material/core'; @Component({ moduleId: module.id, @@ -15,7 +16,7 @@ import {Component} from '@angular/core'; styleUrls: ['mdc-progress-bar-demo.css'], }) export class MdcProgressBarDemo { - color: string = 'primary'; + color: ThemePalette = 'primary'; determinateProgressValue: number = 30; determinateAnimationEndValue: number; bufferAnimationEndValue: number; diff --git a/src/dev-app/progress-bar/progress-bar-demo.ts b/src/dev-app/progress-bar/progress-bar-demo.ts index 20038ee88934..b17f2a218ec0 100644 --- a/src/dev-app/progress-bar/progress-bar-demo.ts +++ b/src/dev-app/progress-bar/progress-bar-demo.ts @@ -7,6 +7,7 @@ */ import {Component} from '@angular/core'; +import {ThemePalette} from '@angular/material/core'; // TODO(josephperrott): Add an automatically filling example progress bar. @@ -18,7 +19,7 @@ import {Component} from '@angular/core'; styleUrls: ['progress-bar-demo.css'], }) export class ProgressBarDemo { - color: string = 'primary'; + color: ThemePalette = 'primary'; determinateProgressValue: number = 30; determinateAnimationEndValue: number; bufferAnimationEndValue: number; diff --git a/src/dev-app/progress-spinner/progress-spinner-demo.ts b/src/dev-app/progress-spinner/progress-spinner-demo.ts index 8ed811215bc5..8b7f78ba27ed 100644 --- a/src/dev-app/progress-spinner/progress-spinner-demo.ts +++ b/src/dev-app/progress-spinner/progress-spinner-demo.ts @@ -7,6 +7,7 @@ */ import {Component} from '@angular/core'; +import {ThemePalette} from '@angular/material/core'; @Component({ @@ -17,11 +18,10 @@ import {Component} from '@angular/core'; }) export class ProgressSpinnerDemo { progressValue = 60; - color = 'primary'; + color: ThemePalette = 'primary'; isDeterminate = true; step(val: number) { this.progressValue = Math.max(0, Math.min(100, val + this.progressValue)); } - } diff --git a/src/dev-app/radio/radio-demo.html b/src/dev-app/radio/radio-demo.html index 2a8c2ac757d0..19b51db6abd1 100644 --- a/src/dev-app/radio/radio-demo.html +++ b/src/dev-app/radio/radio-demo.html @@ -44,7 +44,7 @@

Dynamic Example

name="my_options" [disabled]="isDisabled" [required]="isRequired" - [labelPosition]="isAlignEnd ? 'end' : 'start'"> + [labelPosition]="isAlignEnd ? 'after' : 'before'"> Option 1 Option 2 Option 3 diff --git a/src/dev-app/select/select-demo.ts b/src/dev-app/select/select-demo.ts index 21469fbc7bd4..b23adc2d7955 100644 --- a/src/dev-app/select/select-demo.ts +++ b/src/dev-app/select/select-demo.ts @@ -8,7 +8,7 @@ import {Component} from '@angular/core'; import {FormControl, Validators} from '@angular/forms'; -import {ErrorStateMatcher} from '@angular/material/core'; +import {ErrorStateMatcher, ThemePalette, FloatLabelType} from '@angular/material/core'; import {MatSelectChange} from '@angular/material/select'; /** Error any time control is invalid */ @@ -41,12 +41,12 @@ export class SelectDemo { currentDigimon: string; currentAppearanceValue: string | null; latestChangeEvent: MatSelectChange; - floatLabel = 'auto'; + floatLabel: FloatLabelType = 'auto'; drinksWidth = 'default'; foodControl = new FormControl('pizza-1'); topHeightCtrl = new FormControl(0); - drinksTheme = 'primary'; - pokemonTheme = 'primary'; + drinksTheme: ThemePalette = 'primary'; + pokemonTheme: ThemePalette = 'primary'; compareByValue = true; selectFormControl = new FormControl('', Validators.required); @@ -58,15 +58,19 @@ export class SelectDemo { ]; drinks = [ - {value: 'coke-0', viewValue: 'Coke'}, - {value: 'long-name-1', viewValue: 'Decaf Chocolate Brownie Vanilla Gingerbread Frappuccino'}, - {value: 'water-2', viewValue: 'Water'}, - {value: 'pepper-3', viewValue: 'Dr. Pepper'}, - {value: 'coffee-4', viewValue: 'Coffee'}, - {value: 'tea-5', viewValue: 'Tea'}, - {value: 'juice-6', viewValue: 'Orange juice'}, - {value: 'wine-7', viewValue: 'Wine'}, - {value: 'milk-8', viewValue: 'Milk'}, + {value: 'coke-0', viewValue: 'Coke', disabled: false}, + { + value: 'long-name-1', + viewValue: 'Decaf Chocolate Brownie Vanilla Gingerbread Frappuccino', + disabled: false + }, + {value: 'water-2', viewValue: 'Water', disabled: false}, + {value: 'pepper-3', viewValue: 'Dr. Pepper', disabled: false}, + {value: 'coffee-4', viewValue: 'Coffee', disabled: false}, + {value: 'tea-5', viewValue: 'Tea', disabled: false}, + {value: 'juice-6', viewValue: 'Orange juice', disabled: false}, + {value: 'wine-7', viewValue: 'Wine', disabled: false}, + {value: 'milk-8', viewValue: 'Milk', disabled: true}, ]; pokemon = [ diff --git a/src/dev-app/sidenav/sidenav-demo.ts b/src/dev-app/sidenav/sidenav-demo.ts index 950ace5e8134..933bc498c69e 100644 --- a/src/dev-app/sidenav/sidenav-demo.ts +++ b/src/dev-app/sidenav/sidenav-demo.ts @@ -7,6 +7,7 @@ */ import {Component} from '@angular/core'; +import {MatDrawerMode} from '@angular/material/sidenav'; @Component({ @@ -25,7 +26,9 @@ export class SidenavDemo { showFooter = false; modeIndex = 0; hasBackdrop: boolean; - get mode() { return ['side', 'over', 'push'][this.modeIndex]; } + get mode(): MatDrawerMode { + return (['side', 'over', 'push'] as MatDrawerMode[])[this.modeIndex]; + } get fixedTop() { return this.fixed && this.showHeader && !this.coverHeader ? 64 : 0; } get fixedBottom() { return this.fixed && this.showFooter && !this.coverHeader ? 64 : 0; } } diff --git a/src/dev-app/stepper/stepper-demo.html b/src/dev-app/stepper/stepper-demo.html index d932ec3c1be6..e1741fb234db 100644 --- a/src/dev-app/stepper/stepper-demo.html +++ b/src/dev-app/stepper/stepper-demo.html @@ -5,7 +5,7 @@

Linear Vertical Stepper Demo using a single form

- + Fill out your name First name @@ -23,7 +23,8 @@

Linear Vertical Stepper Demo using a single form

- +
Fill out your email address
diff --git a/src/dev-app/tree/dynamic-tree-demo/dynamic-database.ts b/src/dev-app/tree/dynamic-tree-demo/dynamic-database.ts index c51d609e4243..452134ee612a 100644 --- a/src/dev-app/tree/dynamic-tree-demo/dynamic-database.ts +++ b/src/dev-app/tree/dynamic-tree-demo/dynamic-database.ts @@ -7,7 +7,7 @@ */ import {Injectable} from '@angular/core'; import {FlatTreeControl} from '@angular/cdk/tree'; -import {CollectionViewer, SelectionChange} from '@angular/cdk/collections'; +import {CollectionViewer, DataSource, SelectionChange} from '@angular/cdk/collections'; import {BehaviorSubject, merge, Observable} from 'rxjs'; import {map} from 'rxjs/operators'; @@ -54,7 +54,7 @@ export class DynamicDatabase { * the output is a list of `FileNode`-s with a nested structure. */ @Injectable() -export class DynamicDataSource { +export class DynamicDataSource implements DataSource { dataChange: BehaviorSubject = new BehaviorSubject([]); @@ -77,6 +77,8 @@ export class DynamicDataSource { return merge(collectionViewer.viewChange, this.dataChange).pipe(map(() => this.data)); } + disconnect(collectionViewer: CollectionViewer): void {} + /** Handle expand/collapse behaviors */ handleTreeControl(change: SelectionChange) { if (change.added) { diff --git a/src/material-examples/cdk/stepper/cdk-custom-stepper-without-form/example-custom-stepper.html b/src/material-examples/cdk/stepper/cdk-custom-stepper-without-form/example-custom-stepper.html index 0f956035ae8a..f82710782f54 100644 --- a/src/material-examples/cdk/stepper/cdk-custom-stepper-without-form/example-custom-stepper.html +++ b/src/material-examples/cdk/stepper/cdk-custom-stepper-without-form/example-custom-stepper.html @@ -11,7 +11,7 @@

Step {{ selectedIndex + 1 }}/{{ steps.length }}