diff --git a/src/cdk/clipboard/BUILD.bazel b/src/cdk/clipboard/BUILD.bazel
index dc8f762aca61..cbfdf2b45778 100644
--- a/src/cdk/clipboard/BUILD.bazel
+++ b/src/cdk/clipboard/BUILD.bazel
@@ -10,6 +10,7 @@ ng_module(
),
assets = glob(["**/*.html"]),
deps = [
+ "//src/cdk/coercion",
"@npm//@angular/core",
"@npm//rxjs",
],
diff --git a/src/cdk/clipboard/copy-to-clipboard.ts b/src/cdk/clipboard/copy-to-clipboard.ts
index a672b7d18f84..6f728f4dc4db 100644
--- a/src/cdk/clipboard/copy-to-clipboard.ts
+++ b/src/cdk/clipboard/copy-to-clipboard.ts
@@ -17,6 +17,7 @@ import {
Optional,
OnDestroy,
} from '@angular/core';
+import {coerceNumberProperty, NumberInput} from '@angular/cdk/coercion';
import {Clipboard} from './clipboard';
import {PendingCopy} from './pending-copy';
@@ -48,7 +49,10 @@ export class CdkCopyToClipboard implements OnDestroy {
* How many times to attempt to copy the text. This may be necessary for longer text, because
* the browser needs time to fill an intermediate textarea element and copy the content.
*/
- @Input('cdkCopyToClipboardAttempts') attempts: number = 1;
+ @Input('cdkCopyToClipboardAttempts')
+ get attempts(): number { return this._attempts; }
+ set attempts(value: number) { this._attempts = coerceNumberProperty(value); }
+ private _attempts = 1;
/**
* Emits when some text is copied to the clipboard. The
@@ -109,4 +113,6 @@ export class CdkCopyToClipboard implements OnDestroy {
this._pending.clear();
this._destroyed = true;
}
+
+ static ngAcceptInputType_attempts: NumberInput;
}
diff --git a/src/cdk/drag-drop/directives/drop-list.ts b/src/cdk/drag-drop/directives/drop-list.ts
index 691b313e7584..db2105f65445 100644
--- a/src/cdk/drag-drop/directives/drop-list.ts
+++ b/src/cdk/drag-drop/directives/drop-list.ts
@@ -8,10 +8,10 @@
import {
BooleanInput,
+ NumberInput,
coerceArray,
- coerceNumberProperty,
coerceBooleanProperty,
- NumberInput,
+ coerceNumberProperty,
} from '@angular/cdk/coercion';
import {
ElementRef,
diff --git a/src/cdk/overlay/overlay-directives.ts b/src/cdk/overlay/overlay-directives.ts
index bcebf3c5a82d..a94b38f0b742 100644
--- a/src/cdk/overlay/overlay-directives.ts
+++ b/src/cdk/overlay/overlay-directives.ts
@@ -7,7 +7,12 @@
*/
import {Direction, Directionality} from '@angular/cdk/bidi';
-import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty,
+} from '@angular/cdk/coercion';
import {ESCAPE, hasModifierKey} from '@angular/cdk/keycodes';
import {TemplatePortal} from '@angular/cdk/portal';
import {
@@ -100,6 +105,9 @@ export class CdkOverlayOrigin {
export class CdkConnectedOverlay implements OnDestroy, OnChanges {
private _overlayRef: OverlayRef;
private _templatePortal: TemplatePortal;
+ private _viewportMargin = 0;
+ private _open = false;
+ private _disableClose = false;
private _hasBackdrop = false;
private _lockPosition = false;
private _growAfterOpen = false;
@@ -131,7 +139,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
@Input('cdkConnectedOverlayOffsetX')
get offsetX(): number { return this._offsetX; }
set offsetX(offsetX: number) {
- this._offsetX = offsetX;
+ this._offsetX = coerceNumberProperty(offsetX);
if (this._position) {
this._updatePositionStrategy(this._position);
@@ -142,7 +150,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
@Input('cdkConnectedOverlayOffsetY')
get offsetY() { return this._offsetY; }
set offsetY(offsetY: number) {
- this._offsetY = offsetY;
+ this._offsetY = coerceNumberProperty(offsetY);
if (this._position) {
this._updatePositionStrategy(this._position);
@@ -168,16 +176,22 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
@Input('cdkConnectedOverlayPanelClass') panelClass: string | string[];
/** Margin between the overlay and the viewport edges. */
- @Input('cdkConnectedOverlayViewportMargin') viewportMargin: number = 0;
+ @Input('cdkConnectedOverlayViewportMargin')
+ get viewportMargin(): number { return this._viewportMargin; }
+ set viewportMargin(value: number) { this._viewportMargin = coerceNumberProperty(value); }
/** Strategy to be used when handling scroll events while the overlay is open. */
@Input('cdkConnectedOverlayScrollStrategy') scrollStrategy: ScrollStrategy;
/** Whether the overlay is open. */
- @Input('cdkConnectedOverlayOpen') open: boolean = false;
+ @Input('cdkConnectedOverlayOpen')
+ get open() { return this._open; }
+ set open(value: any) { this._open = coerceBooleanProperty(value); }
/** Whether the overlay can be closed by user interaction. */
- @Input('cdkConnectedOverlayDisableClose') disableClose: boolean = false;
+ @Input('cdkConnectedOverlayDisableClose')
+ get disableClose() { return this._disableClose; }
+ set disableClose(value: any) { this._disableClose = coerceBooleanProperty(value); }
/** CSS selector which to set the transform origin. */
@Input('cdkConnectedOverlayTransformOriginOn') transformOriginSelector: string;
@@ -428,6 +442,11 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
this._positionSubscription.unsubscribe();
}
+ static ngAcceptInputType_offsetX: NumberInput;
+ static ngAcceptInputType_offsetY: NumberInput;
+ static ngAcceptInputType_viewportMargin: NumberInput;
+ static ngAcceptInputType_open: BooleanInput;
+ static ngAcceptInputType_disableClose: BooleanInput;
static ngAcceptInputType_hasBackdrop: BooleanInput;
static ngAcceptInputType_lockPosition: BooleanInput;
static ngAcceptInputType_flexibleDimensions: BooleanInput;
diff --git a/src/google-maps/BUILD.bazel b/src/google-maps/BUILD.bazel
index 474cc720258d..721870d7e397 100644
--- a/src/google-maps/BUILD.bazel
+++ b/src/google-maps/BUILD.bazel
@@ -12,6 +12,7 @@ ng_module(
),
deps = [
"//src:dev_mode_types",
+ "//src/cdk/coercion",
"@npm//@angular/common",
"@npm//@angular/core",
"@npm//@types/googlemaps",
diff --git a/src/google-maps/google-map/google-map.ts b/src/google-maps/google-map/google-map.ts
index e88cfbd68ae2..fc8e3db4ff74 100644
--- a/src/google-maps/google-map/google-map.ts
+++ b/src/google-maps/google-map/google-map.ts
@@ -26,6 +26,7 @@ import {
EventEmitter,
} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';
+import {NumberInput, coerceNumberProperty} from '@angular/cdk/coercion';
import {Observable} from 'rxjs';
import {MapEventManager} from '../map-event-manager';
@@ -93,10 +94,10 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
private _center: google.maps.LatLngLiteral|google.maps.LatLng;
@Input()
- set zoom(zoom: number) {
- this._zoom = zoom;
+ set zoom(zoom: number | undefined) {
+ this._zoom = zoom === undefined ? zoom : coerceNumberProperty(zoom);
}
- private _zoom: number;
+ private _zoom: number | undefined;
@Input()
set options(options: google.maps.MapOptions) {
@@ -505,6 +506,8 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
'Please wait for the API to load before trying to interact with it.');
}
}
+
+ static ngAcceptInputType_zoom: NumberInput;
}
const cssUnitsPattern = /([A-Za-z%]+)$/;
diff --git a/src/google-maps/map-circle/map-circle.ts b/src/google-maps/map-circle/map-circle.ts
index 78a3de30f423..9e897636b68c 100644
--- a/src/google-maps/map-circle/map-circle.ts
+++ b/src/google-maps/map-circle/map-circle.ts
@@ -10,6 +10,7 @@
///
import {Directive, Input, NgZone, OnDestroy, OnInit, Output} from '@angular/core';
+import {NumberInput, coerceNumberProperty} from '@angular/cdk/coercion';
import {BehaviorSubject, combineLatest, Observable, Subject} from 'rxjs';
import {map, take, takeUntil} from 'rxjs/operators';
@@ -51,8 +52,8 @@ export class MapCircle implements OnInit, OnDestroy {
}
@Input()
- set radius(radius: number) {
- this._radius.next(radius);
+ set radius(radius: number | undefined) {
+ this._radius.next(radius === undefined ? radius : coerceNumberProperty(radius));
}
/**
@@ -282,4 +283,6 @@ export class MapCircle implements OnInit, OnDestroy {
}
}
}
+
+ static ngAcceptInputType_radius: NumberInput;
}
diff --git a/src/google-maps/map-ground-overlay/map-ground-overlay.ts b/src/google-maps/map-ground-overlay/map-ground-overlay.ts
index 5c8afcb79843..105ef8eb32f9 100644
--- a/src/google-maps/map-ground-overlay/map-ground-overlay.ts
+++ b/src/google-maps/map-ground-overlay/map-ground-overlay.ts
@@ -10,6 +10,12 @@
///
import {Directive, Input, NgZone, OnDestroy, OnInit, Output} from '@angular/core';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty
+} from '@angular/cdk/coercion';
import {BehaviorSubject, Observable, Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
@@ -27,6 +33,7 @@ import {MapEventManager} from '../map-event-manager';
})
export class MapGroundOverlay implements OnInit, OnDestroy {
private _eventManager = new MapEventManager(this._ngZone);
+ private _clickable = false;
private readonly _opacity = new BehaviorSubject(1);
private readonly _url = new BehaviorSubject('');
@@ -58,12 +65,14 @@ export class MapGroundOverlay implements OnInit, OnDestroy {
}
/** Whether the overlay is clickable */
- @Input() clickable: boolean = false;
+ @Input()
+ get clickable() { return this._clickable; }
+ set clickable(value: any) { this._clickable = coerceBooleanProperty(value); }
/** Opacity of the overlay. */
@Input()
set opacity(opacity: number) {
- this._opacity.next(opacity);
+ this._opacity.next(coerceNumberProperty(opacity));
}
/**
@@ -189,4 +198,7 @@ export class MapGroundOverlay implements OnInit, OnDestroy {
}
}
}
+
+ static ngAcceptInputType_clickable: BooleanInput;
+ static ngAcceptInputType_opacity: NumberInput;
}
diff --git a/src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts b/src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts
index 551e092aa416..46144ed0749c 100644
--- a/src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts
+++ b/src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts
@@ -80,11 +80,11 @@ describe('MapMarkerClusterer', () => {
imagePath: undefined,
imageSizes: undefined,
maxZoom: undefined,
- minimumClusterSize: undefined,
+ minimumClusterSize: 0,
styles: undefined,
title: undefined,
zIndex: undefined,
- zoomOnClick: undefined,
+ zoomOnClick: false,
});
});
diff --git a/src/google-maps/map-marker-clusterer/map-marker-clusterer.ts b/src/google-maps/map-marker-clusterer/map-marker-clusterer.ts
index 0ae2e1ecb6ef..6cd1e141cdb4 100644
--- a/src/google-maps/map-marker-clusterer/map-marker-clusterer.ts
+++ b/src/google-maps/map-marker-clusterer/map-marker-clusterer.ts
@@ -25,6 +25,13 @@ import {
SimpleChanges,
ViewEncapsulation
} from '@angular/core';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceArray,
+ coerceBooleanProperty,
+ coerceNumberProperty
+} from '@angular/cdk/coercion';
import {Observable, Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
@@ -59,18 +66,25 @@ export class MapMarkerClusterer implements OnInit, AfterContentInit, OnChanges,
ariaLabelFn: AriaLabelFn = () => ''
@Input()
- set averageCenter(averageCenter: boolean) {
- this._averageCenter = averageCenter;
+ set averageCenter(averageCenter: boolean | undefined) {
+ this._averageCenter = averageCenter === undefined
+ ? averageCenter
+ : coerceBooleanProperty(averageCenter);
}
- private _averageCenter: boolean;
+ private _averageCenter: boolean | undefined;
- @Input() batchSize?: number;
+ @Input()
+ get batchSize(): number | undefined { return this._batchSize; }
+ set batchSize(batchSize: any) {
+ this._batchSize = batchSize === undefined ? batchSize : coerceNumberProperty(batchSize);
+ }
+ private _batchSize?: number;
@Input()
- set batchSizeIE(batchSizeIE: number) {
- this._batchSizeIE = batchSizeIE;
+ set batchSizeIE(batchSizeIE: number | undefined) {
+ this._batchSizeIE = batchSizeIE === undefined ? batchSizeIE : coerceNumberProperty(batchSizeIE);
}
- private _batchSizeIE: number;
+ private _batchSizeIE?: number;
@Input()
set calculator(calculator: Calculator) {
@@ -85,22 +99,26 @@ export class MapMarkerClusterer implements OnInit, AfterContentInit, OnChanges,
private _clusterClass: string;
@Input()
- set enableRetinaIcons(enableRetinaIcons: boolean) {
- this._enableRetinaIcons = enableRetinaIcons;
+ set enableRetinaIcons(enableRetinaIcons: boolean | undefined) {
+ this._enableRetinaIcons = enableRetinaIcons === undefined
+ ? enableRetinaIcons
+ : coerceBooleanProperty(enableRetinaIcons);
}
- private _enableRetinaIcons: boolean;
+ private _enableRetinaIcons: boolean | undefined;
@Input()
- set gridSize(gridSize: number) {
- this._gridSize = gridSize;
+ set gridSize(gridSize: number | undefined) {
+ this._gridSize = gridSize === undefined ? gridSize : coerceNumberProperty(gridSize);
}
- private _gridSize: number;
+ private _gridSize: number | undefined;
@Input()
- set ignoreHidden(ignoreHidden: boolean) {
- this._ignoreHidden = ignoreHidden;
+ set ignoreHidden(ignoreHidden: boolean | undefined) {
+ this._ignoreHidden = ignoreHidden === undefined
+ ? ignoreHidden
+ : coerceBooleanProperty(ignoreHidden);
}
- private _ignoreHidden: boolean;
+ private _ignoreHidden: boolean | undefined;
@Input()
set imageExtension(imageExtension: string) {
@@ -115,20 +133,20 @@ export class MapMarkerClusterer implements OnInit, AfterContentInit, OnChanges,
private _imagePath: string;
@Input()
- set imageSizes(imageSizes: number[]) {
- this._imageSizes = imageSizes;
+ set imageSizes(imageSizes: number | number[] | undefined) {
+ this._imageSizes = imageSizes === undefined ? imageSizes : coerceArray(imageSizes);
}
- private _imageSizes: number[];
+ private _imageSizes: number[] | undefined;
@Input()
- set maxZoom(maxZoom: number) {
- this._maxZoom = maxZoom;
+ set maxZoom(maxZoom: number | undefined) {
+ this._maxZoom = maxZoom === undefined ? maxZoom : coerceNumberProperty(maxZoom);
}
- private _maxZoom: number;
+ private _maxZoom: number | undefined;
@Input()
set minimumClusterSize(minimumClusterSize: number) {
- this._minimumClusterSize = minimumClusterSize;
+ this._minimumClusterSize = coerceNumberProperty(minimumClusterSize);
}
private _minimumClusterSize: number;
@@ -145,14 +163,14 @@ export class MapMarkerClusterer implements OnInit, AfterContentInit, OnChanges,
private _title: string;
@Input()
- set zIndex(zIndex: number) {
- this._zIndex = zIndex;
+ set zIndex(zIndex: number | undefined) {
+ this._zIndex = zIndex === undefined ? zIndex : coerceNumberProperty(zIndex);
}
- private _zIndex: number;
+ private _zIndex: number | undefined;
@Input()
set zoomOnClick(zoomOnClick: boolean) {
- this._zoomOnClick = zoomOnClick;
+ this._zoomOnClick = coerceBooleanProperty(zoomOnClick);
}
private _zoomOnClick: boolean;
@@ -480,4 +498,15 @@ export class MapMarkerClusterer implements OnInit, AfterContentInit, OnChanges,
}
}
}
+
+ static ngAcceptInputType_averageCenter: BooleanInput;
+ static ngAcceptInputType_batchSize: NumberInput;
+ static ngAcceptInputType_batchSizeIE: NumberInput;
+ static ngAcceptInputType_enableRetinaIcons: BooleanInput;
+ static ngAcceptInputType_gridSize: NumberInput;
+ static ngAcceptInputType_ignoreHidden: BooleanInput;
+ static ngAcceptInputType_maxZoom: NumberInput;
+ static ngAcceptInputType_minimumClusterSize: NumberInput;
+ static ngAcceptInputType_zIndex: NumberInput;
+ static ngAcceptInputType_zoomOnClick: BooleanInput;
}
diff --git a/src/google-maps/map-marker/map-marker.spec.ts b/src/google-maps/map-marker/map-marker.spec.ts
index 178663864027..c8f73b48e358 100644
--- a/src/google-maps/map-marker/map-marker.spec.ts
+++ b/src/google-maps/map-marker/map-marker.spec.ts
@@ -44,9 +44,9 @@ describe('MapMarker', () => {
...DEFAULT_MARKER_OPTIONS,
title: undefined,
label: undefined,
- clickable: undefined,
+ clickable: false,
icon: undefined,
- visible: undefined,
+ visible: false,
map: mapSpy,
});
});
@@ -83,7 +83,7 @@ describe('MapMarker', () => {
label: 'marker label',
clickable: false,
icon: 'icon name',
- visible: undefined
+ visible: false
};
const markerSpy = createMarkerSpy(options);
const markerConstructorSpy = createMarkerConstructorSpy(markerSpy).and.callThrough();
@@ -110,7 +110,7 @@ describe('MapMarker', () => {
clickable: true,
icon: 'icon name',
map: mapSpy,
- visible: undefined
+ visible: false
};
const markerSpy = createMarkerSpy(options);
const markerConstructorSpy = createMarkerConstructorSpy(markerSpy).and.callThrough();
diff --git a/src/google-maps/map-marker/map-marker.ts b/src/google-maps/map-marker/map-marker.ts
index d02e0cd30679..2077da51ab91 100644
--- a/src/google-maps/map-marker/map-marker.ts
+++ b/src/google-maps/map-marker/map-marker.ts
@@ -19,6 +19,7 @@ import {
OnChanges,
SimpleChanges,
} from '@angular/core';
+import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
import {Observable} from 'rxjs';
import {GoogleMap} from '../google-map/google-map';
@@ -81,7 +82,7 @@ export class MapMarker implements OnInit, OnChanges, OnDestroy, MapAnchorPoint {
*/
@Input()
set clickable(clickable: boolean) {
- this._clickable = clickable;
+ this._clickable = coerceBooleanProperty(clickable);
}
private _clickable: boolean;
@@ -111,7 +112,7 @@ export class MapMarker implements OnInit, OnChanges, OnDestroy, MapAnchorPoint {
*/
@Input()
set visible(value: boolean) {
- this._visible = value;
+ this._visible = coerceBooleanProperty(value);
}
private _visible: boolean;
@@ -471,4 +472,7 @@ export class MapMarker implements OnInit, OnChanges, OnDestroy, MapAnchorPoint {
}
}
}
+
+ static ngAcceptInputType_clickable: BooleanInput;
+ static ngAcceptInputType_visible: BooleanInput;
}
diff --git a/src/google-maps/map-traffic-layer/map-traffic-layer.ts b/src/google-maps/map-traffic-layer/map-traffic-layer.ts
index 47c6988aa98e..50ec9c9836ce 100644
--- a/src/google-maps/map-traffic-layer/map-traffic-layer.ts
+++ b/src/google-maps/map-traffic-layer/map-traffic-layer.ts
@@ -10,6 +10,7 @@
///
import {Directive, Input, NgZone, OnDestroy, OnInit} from '@angular/core';
+import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
import {BehaviorSubject, Observable, Subject} from 'rxjs';
import {map, take, takeUntil} from 'rxjs/operators';
@@ -40,7 +41,7 @@ export class MapTrafficLayer implements OnInit, OnDestroy {
*/
@Input()
set autoRefresh(autoRefresh: boolean) {
- this._autoRefresh.next(autoRefresh);
+ this._autoRefresh.next(coerceBooleanProperty(autoRefresh));
}
constructor(private readonly _map: GoogleMap, private readonly _ngZone: NgZone) {}
@@ -94,4 +95,6 @@ export class MapTrafficLayer implements OnInit, OnDestroy {
'Please wait for the Traffic Layer to load before trying to interact with it.');
}
}
+
+ static ngAcceptInputType_autoRefresh: BooleanInput;
}
diff --git a/src/google-maps/package.json b/src/google-maps/package.json
index 242f18504ae1..c66cc55c56a7 100644
--- a/src/google-maps/package.json
+++ b/src/google-maps/package.json
@@ -21,6 +21,7 @@
"tslib": "0.0.0-TSLIB"
},
"peerDependencies": {
+ "@angular/cdk": "0.0.0-PLACEHOLDER",
"@angular/core": "0.0.0-NG",
"@angular/common": "0.0.0-NG",
"rxjs": "0.0.0-RXJS"
diff --git a/src/google-maps/tsconfig-tests.json b/src/google-maps/tsconfig-tests.json
index 0b483e5010b7..f234a9721924 100644
--- a/src/google-maps/tsconfig-tests.json
+++ b/src/google-maps/tsconfig-tests.json
@@ -1,5 +1,10 @@
{
"extends": "../bazel-tsconfig-build.json",
+ "references": [
+ {
+ "path": "../cdk/tsconfig-tests.json"
+ }
+ ],
"compilerOptions": {
"baseUrl": ".",
"outDir": "../../dist/packages/google-maps",
@@ -13,7 +18,10 @@
"target": "es5",
"types": ["jasmine"],
"experimentalDecorators": true,
- "emitDecoratorMetadata": true
+ "emitDecoratorMetadata": true,
+ "paths": {
+ "@angular/cdk/*": ["../../dist/packages/cdk/*"]
+ }
},
"include": [
"**/*.spec.ts",
diff --git a/src/google-maps/tsconfig.json b/src/google-maps/tsconfig.json
index d57281895299..deabd52aa26e 100644
--- a/src/google-maps/tsconfig.json
+++ b/src/google-maps/tsconfig.json
@@ -4,7 +4,9 @@
"compilerOptions": {
"rootDir": "..",
"baseUrl": ".",
- "paths": {},
+ "paths": {
+ "@angular/cdk/*": ["../cdk/*"]
+ },
"types": [
"jasmine"
]
diff --git a/src/material-experimental/mdc-checkbox/checkbox.ts b/src/material-experimental/mdc-checkbox/checkbox.ts
index 5056ce39d26d..e443fd33315b 100644
--- a/src/material-experimental/mdc-checkbox/checkbox.ts
+++ b/src/material-experimental/mdc-checkbox/checkbox.ts
@@ -6,7 +6,12 @@
* found in the LICENSE file at https://angular.io/license
*/
-import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty,
+} from '@angular/cdk/coercion';
import {
AfterViewInit,
Attribute,
@@ -102,7 +107,10 @@ export class MatCheckbox extends _MatCheckboxBase implements AfterViewInit, OnDe
@Input() name: string|null = null;
/** The `tabindex` attribute to use for the input element. */
- @Input() tabIndex: number;
+ @Input()
+ get tabIndex(): number { return this._tabIndex; }
+ set tabIndex(value: number) { this._tabIndex = coerceNumberProperty(value); }
+ private _tabIndex: number;
/** The `value` attribute to use for the input element */
@Input() value: string;
@@ -385,6 +393,7 @@ export class MatCheckbox extends _MatCheckboxBase implements AfterViewInit, OnDe
}
}
+ static ngAcceptInputType_tabIndex: NumberInput;
static ngAcceptInputType_checked: BooleanInput;
static ngAcceptInputType_indeterminate: BooleanInput;
static ngAcceptInputType_disabled: BooleanInput;
diff --git a/src/material-experimental/mdc-chips/chip-row.ts b/src/material-experimental/mdc-chips/chip-row.ts
index a879ee84b09a..d31524f5a2f4 100644
--- a/src/material-experimental/mdc-chips/chip-row.ts
+++ b/src/material-experimental/mdc-chips/chip-row.ts
@@ -7,7 +7,7 @@
*/
import {Directionality} from '@angular/cdk/bidi';
-import {BooleanInput} from '@angular/cdk/coercion';
+import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
import {BACKSPACE, DELETE} from '@angular/cdk/keycodes';
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
import {
@@ -78,7 +78,10 @@ export class MatChipRow extends MatChip implements AfterContentInit, AfterViewIn
GridKeyManagerRow {
protected override basicChipAttrName = 'mat-basic-chip-row';
- @Input() editable: boolean = false;
+ @Input()
+ get editable(): boolean { return this._editable; }
+ set editable(value: boolean) { this._editable = coerceBooleanProperty(value); }
+ private _editable = false;
/** Emitted when the chip is edited. */
@Output() readonly edited: EventEmitter =
diff --git a/src/material-experimental/mdc-form-field/directives/floating-label.ts b/src/material-experimental/mdc-form-field/directives/floating-label.ts
index e0932abb3d3b..bfc30775d4b3 100644
--- a/src/material-experimental/mdc-form-field/directives/floating-label.ts
+++ b/src/material-experimental/mdc-form-field/directives/floating-label.ts
@@ -7,6 +7,7 @@
*/
import {Directive, ElementRef, Input} from '@angular/core';
+import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
import {ponyfill} from '@material/dom';
/**
@@ -31,10 +32,21 @@ import {ponyfill} from '@material/dom';
},
})
export class MatFormFieldFloatingLabel {
+ private _floating = false;
+ private _required = false;
+
/** Whether the label is floating. */
- @Input() floating: boolean = false;
+ @Input()
+ get floating(): boolean { return this._floating; }
+ set floating(value: boolean) { this._floating = coerceBooleanProperty(value); }
+
/** Whether the label is required. */
- @Input() required: boolean = false;
+ @Input()
+ get required(): boolean { return this._required; }
+ set required(value: boolean) { this._required = coerceBooleanProperty(value); }
+
+ /** Gets the HTML element for the floating label. */
+ get element(): HTMLElement { return this._elementRef.nativeElement; }
constructor(private _elementRef: ElementRef) {}
@@ -43,8 +55,6 @@ export class MatFormFieldFloatingLabel {
return ponyfill.estimateScrollWidth(this._elementRef.nativeElement);
}
- /** Gets the HTML element for the floating label. */
- get element(): HTMLElement {
- return this._elementRef.nativeElement;
- }
+ static ngAcceptInputType_floating: BooleanInput;
+ static ngAcceptInputType_required: BooleanInput;
}
diff --git a/src/material-experimental/mdc-form-field/directives/notched-outline.ts b/src/material-experimental/mdc-form-field/directives/notched-outline.ts
index 63eac20ee532..81de2499d5fe 100644
--- a/src/material-experimental/mdc-form-field/directives/notched-outline.ts
+++ b/src/material-experimental/mdc-form-field/directives/notched-outline.ts
@@ -6,6 +6,12 @@
* found in the LICENSE file at https://angular.io/license
*/
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty,
+} from '@angular/cdk/coercion';
import {Platform} from '@angular/cdk/platform';
import {
AfterViewInit,
@@ -42,10 +48,16 @@ import {MDCNotchedOutline} from '@material/notched-outline';
})
export class MatFormFieldNotchedOutline implements AfterViewInit, OnChanges, OnDestroy {
/** Width of the notch. */
- @Input('matFormFieldNotchedOutlineWidth') width: number = 0;
+ @Input('matFormFieldNotchedOutlineWidth')
+ get width(): number { return this._width; }
+ set width(value: number) { this._width = coerceNumberProperty(value); }
+ private _width = 0;
/** Whether the notch should be opened. */
- @Input('matFormFieldNotchedOutlineOpen') open: boolean = false;
+ @Input('matFormFieldNotchedOutlineOpen')
+ get open(): boolean { return this._open; }
+ set open(value: boolean) { this._open = coerceBooleanProperty(value); }
+ private _open = false;
/** Instance of the MDC notched outline. */
private _mdcNotchedOutline: MDCNotchedOutline|null = null;
@@ -89,4 +101,7 @@ export class MatFormFieldNotchedOutline implements AfterViewInit, OnChanges, OnD
this._mdcNotchedOutline.closeNotch();
}
}
+
+ static ngAcceptInputType_width: NumberInput;
+ static ngAcceptInputType_open: BooleanInput;
}
diff --git a/src/material-experimental/mdc-progress-bar/progress-bar.ts b/src/material-experimental/mdc-progress-bar/progress-bar.ts
index fdda55384a87..98a6e2d6d1ef 100644
--- a/src/material-experimental/mdc-progress-bar/progress-bar.ts
+++ b/src/material-experimental/mdc-progress-bar/progress-bar.ts
@@ -20,6 +20,7 @@ import {
AfterViewInit,
OnDestroy,
} from '@angular/core';
+import {NumberInput, coerceNumberProperty} from '@angular/cdk/coercion';
import {CanColor, mixinColor} from '@angular/material-experimental/mdc-core';
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
import {
@@ -148,7 +149,7 @@ export class MatProgressBar extends _MatProgressBarBase implements AfterViewInit
@Input()
get value(): number { return this._value; }
set value(v: number) {
- this._value = clamp(v || 0);
+ this._value = clamp(coerceNumberProperty(v, 0));
this._syncFoundation();
}
private _value = 0;
@@ -157,7 +158,7 @@ export class MatProgressBar extends _MatProgressBarBase implements AfterViewInit
@Input()
get bufferValue(): number { return this._bufferValue || 0; }
set bufferValue(v: number) {
- this._bufferValue = clamp(v || 0);
+ this._bufferValue = clamp(coerceNumberProperty(v, 0));
this._syncFoundation();
}
private _bufferValue = 0;
@@ -243,6 +244,9 @@ export class MatProgressBar extends _MatProgressBarBase implements AfterViewInit
}
}
}
+
+ static ngAcceptInputType_value: NumberInput;
+ static ngAcceptInputType_bufferValue: NumberInput;
}
/** Clamps a value to be between two numbers, by default 0 and 100. */
diff --git a/src/material-experimental/mdc-slider/slider.ts b/src/material-experimental/mdc-slider/slider.ts
index 287641d4ad9b..1e6c2b7dbe65 100644
--- a/src/material-experimental/mdc-slider/slider.ts
+++ b/src/material-experimental/mdc-slider/slider.ts
@@ -90,7 +90,10 @@ export interface MatSliderDragEvent {
})
export class MatSliderVisualThumb implements AfterViewInit, OnDestroy {
/** Whether the slider displays a numeric value label upon pressing the thumb. */
- @Input() discrete: boolean;
+ @Input()
+ get discrete(): boolean { return this._discrete; }
+ set discrete(value: boolean) { this._discrete = coerceBooleanProperty(value); }
+ private _discrete: boolean;
/** Indicates which slider thumb this input corresponds to. */
@Input() thumbPosition: Thumb;
@@ -99,7 +102,10 @@ export class MatSliderVisualThumb implements AfterViewInit, OnDestroy {
@Input() valueIndicatorText: string;
/** Whether ripples on the slider thumb should be disabled. */
- @Input() disableRipple: boolean = false;
+ @Input()
+ get disableRipple(): boolean { return this._disableRipple; }
+ set disableRipple(value: boolean) { this._disableRipple = coerceBooleanProperty(value); }
+ private _disableRipple = false;
/** The MatRipple for this slider thumb. */
@ViewChild(MatRipple) private readonly _ripple: MatRipple;
@@ -260,6 +266,9 @@ export class MatSliderVisualThumb implements AfterViewInit, OnDestroy {
_getKnob(): HTMLElement {
return this._knob.nativeElement;
}
+
+ static ngAcceptInputType_discrete: BooleanInput;
+ static ngAcceptInputType_disableRipple: BooleanInput;
}
/**
diff --git a/src/material/button-toggle/button-toggle.ts b/src/material/button-toggle/button-toggle.ts
index 8211689b7edb..225b04ee45d7 100644
--- a/src/material/button-toggle/button-toggle.ts
+++ b/src/material/button-toggle/button-toggle.ts
@@ -7,7 +7,12 @@
*/
import {FocusMonitor} from '@angular/cdk/a11y';
-import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty
+} from '@angular/cdk/coercion';
import {SelectionModel} from '@angular/cdk/collections';
import {
AfterContentInit,
@@ -445,7 +450,10 @@ export class MatButtonToggle extends _MatButtonToggleBase implements OnInit, Aft
@Input() value: any;
/** Tabindex for the toggle. */
- @Input() tabIndex: number | null;
+ @Input()
+ get tabIndex(): number | null { return this._tabIndex; }
+ set tabIndex(value: number | null) { this._tabIndex = coerceNumberProperty(value); }
+ private _tabIndex: number | null;
/** The appearance style of the button. */
@Input()
@@ -573,6 +581,7 @@ export class MatButtonToggle extends _MatButtonToggleBase implements OnInit, Aft
this._changeDetectorRef.markForCheck();
}
+ static ngAcceptInputType_tabIndex: NumberInput;
static ngAcceptInputType_checked: BooleanInput;
static ngAcceptInputType_disabled: BooleanInput;
static ngAcceptInputType_vertical: BooleanInput;
diff --git a/src/material/button/button.ts b/src/material/button/button.ts
index 74abd5d24b9d..a63b744c8cd4 100644
--- a/src/material/button/button.ts
+++ b/src/material/button/button.ts
@@ -7,7 +7,7 @@
*/
import {FocusMonitor, FocusableOption, FocusOrigin} from '@angular/cdk/a11y';
-import {BooleanInput} from '@angular/cdk/coercion';
+import {BooleanInput, NumberInput, coerceNumberProperty} from '@angular/cdk/coercion';
import {
ChangeDetectionStrategy,
Component,
@@ -172,7 +172,10 @@ export class MatButton extends _MatButtonBase
})
export class MatAnchor extends MatButton {
/** Tabindex of the button. */
- @Input() tabIndex: number;
+ @Input()
+ get tabIndex(): number { return this._tabIndex; }
+ set tabIndex(value: number) { this._tabIndex = coerceNumberProperty(value); }
+ private _tabIndex: number;
constructor(
focusMonitor: FocusMonitor,
@@ -188,4 +191,6 @@ export class MatAnchor extends MatButton {
event.stopImmediatePropagation();
}
}
+
+ static ngAcceptInputType_tabIndex: NumberInput;
}
diff --git a/src/material/checkbox/checkbox.ts b/src/material/checkbox/checkbox.ts
index 27e109cc59f1..c5a24be3b7ca 100644
--- a/src/material/checkbox/checkbox.ts
+++ b/src/material/checkbox/checkbox.ts
@@ -7,7 +7,12 @@
*/
import {FocusableOption, FocusMonitor, FocusOrigin} from '@angular/cdk/a11y';
-import {BooleanInput, coerceBooleanProperty, NumberInput} from '@angular/cdk/coercion';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty
+} from '@angular/cdk/coercion';
import {
AfterViewChecked,
Attribute,
@@ -199,7 +204,7 @@ export class MatCheckbox extends _MatCheckboxBase implements ControlValueAccesso
super(elementRef);
this._options = this._options || defaults;
this.color = this.defaultColor = this._options.color || defaults.color;
- this.tabIndex = parseInt(tabIndex) || 0;
+ this.tabIndex = coerceNumberProperty(tabIndex, 0);
}
ngAfterViewInit() {
@@ -233,8 +238,10 @@ export class MatCheckbox extends _MatCheckboxBase implements ControlValueAccesso
@Input()
get checked(): boolean { return this._checked; }
set checked(value: boolean) {
- if (value != this.checked) {
- this._checked = value;
+ const newValue = coerceBooleanProperty(value);
+
+ if (newValue != this.checked) {
+ this._checked = newValue;
this._changeDetectorRef.markForCheck();
}
}
@@ -265,8 +272,9 @@ export class MatCheckbox extends _MatCheckboxBase implements ControlValueAccesso
@Input()
get indeterminate(): boolean { return this._indeterminate; }
set indeterminate(value: boolean) {
- const changed = value != this._indeterminate;
- this._indeterminate = coerceBooleanProperty(value);
+ const newValue = coerceBooleanProperty(value);
+ const changed = newValue != this._indeterminate;
+ this._indeterminate = coerceBooleanProperty(newValue);
if (changed) {
if (this._indeterminate) {
@@ -489,9 +497,10 @@ export class MatCheckbox extends _MatCheckboxBase implements ControlValueAccesso
}
}
- static ngAcceptInputType_disabled: BooleanInput;
static ngAcceptInputType_required: BooleanInput;
static ngAcceptInputType_disableRipple: BooleanInput;
- static ngAcceptInputType_indeterminate: BooleanInput;
static ngAcceptInputType_tabIndex: NumberInput;
+ static ngAcceptInputType_checked: BooleanInput;
+ static ngAcceptInputType_disabled: BooleanInput;
+ static ngAcceptInputType_indeterminate: BooleanInput;
}
diff --git a/src/material/chips/chip-list.ts b/src/material/chips/chip-list.ts
index de95edc14aee..141dbbfcc628 100644
--- a/src/material/chips/chip-list.ts
+++ b/src/material/chips/chip-list.ts
@@ -8,7 +8,12 @@
import {FocusKeyManager} from '@angular/cdk/a11y';
import {Directionality} from '@angular/cdk/bidi';
-import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty,
+} from '@angular/cdk/coercion';
import {SelectionModel} from '@angular/cdk/collections';
import {
AfterContentInit,
@@ -294,8 +299,9 @@ export class MatChipList extends _MatChipListBase implements MatFormFieldControl
@Input()
set tabIndex(value: number) {
- this._userTabIndex = value;
- this._tabIndex = value;
+ const newValue = coerceNumberProperty(value);
+ this._userTabIndex = newValue;
+ this._tabIndex = newValue;
}
/** Combined stream of all of the child chips' selection change events. */
@@ -800,4 +806,5 @@ export class MatChipList extends _MatChipListBase implements MatFormFieldControl
static ngAcceptInputType_required: BooleanInput;
static ngAcceptInputType_disabled: BooleanInput;
static ngAcceptInputType_selectable: BooleanInput;
+ static ngAcceptInputType_tabIndex: NumberInput;
}
diff --git a/src/material/chips/chip.ts b/src/material/chips/chip.ts
index 235e8b632cbb..ab659a741471 100644
--- a/src/material/chips/chip.ts
+++ b/src/material/chips/chip.ts
@@ -7,7 +7,12 @@
*/
import {FocusableOption} from '@angular/cdk/a11y';
-import {BooleanInput, coerceBooleanProperty, NumberInput} from '@angular/cdk/coercion';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty,
+} from '@angular/cdk/coercion';
import {BACKSPACE, DELETE, SPACE} from '@angular/cdk/keycodes';
import {Platform} from '@angular/cdk/platform';
import {DOCUMENT} from '@angular/common';
@@ -297,7 +302,7 @@ export class MatChip extends _MatChipMixinBase implements FocusableOption, OnDes
this.rippleConfig = globalRippleOptions || {};
this._animationsDisabled = animationMode === 'NoopAnimations';
- this.tabIndex = tabIndex != null ? (parseInt(tabIndex) || -1) : -1;
+ this.tabIndex = coerceNumberProperty(tabIndex, -1);
}
_addHostClassName() {
diff --git a/src/material/core/ripple/ripple.ts b/src/material/core/ripple/ripple.ts
index e2357b86b280..eb9081ab59b7 100644
--- a/src/material/core/ripple/ripple.ts
+++ b/src/material/core/ripple/ripple.ts
@@ -18,6 +18,12 @@ import {
OnInit,
Optional,
} from '@angular/core';
+import {
+ BooleanInput,
+ coerceBooleanProperty,
+ NumberInput,
+ coerceNumberProperty
+} from '@angular/cdk/coercion';
import {RippleAnimationConfig, RippleConfig, RippleRef} from './ripple-ref';
import {RippleRenderer, RippleTarget} from './ripple-renderer';
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
@@ -62,20 +68,29 @@ export class MatRipple implements OnInit, OnDestroy, RippleTarget {
@Input('matRippleColor') color: string;
/** Whether the ripples should be visible outside the component's bounds. */
- @Input('matRippleUnbounded') unbounded: boolean;
+ @Input('matRippleUnbounded')
+ get unbounded(): boolean { return this._unbounded; }
+ set unbounded(value: boolean) { this._unbounded = coerceBooleanProperty(value); }
+ private _unbounded = false;
/**
* Whether the ripple always originates from the center of the host element's bounds, rather
* than originating from the location of the click event.
*/
- @Input('matRippleCentered') centered: boolean;
+ @Input('matRippleCentered')
+ get centered(): boolean { return this._centered; }
+ set centered(value: boolean) { this._centered = coerceBooleanProperty(value); }
+ private _centered = false;
/**
* If set, the radius in pixels of foreground ripples when fully expanded. If unset, the radius
* will be the distance from the center of the ripple to the furthest corner of the host element's
* bounding rectangle.
*/
- @Input('matRippleRadius') radius: number = 0;
+ @Input('matRippleRadius')
+ get radius(): number { return this._radius; }
+ set radius(value: number) { this._radius = coerceNumberProperty(value, 0); }
+ private _radius = 0;
/**
* Configuration for the ripple animation. Allows modifying the enter and exit animation
@@ -91,13 +106,14 @@ export class MatRipple implements OnInit, OnDestroy, RippleTarget {
@Input('matRippleDisabled')
get disabled() { return this._disabled; }
set disabled(value: boolean) {
- if (value) {
+ const newValue = coerceBooleanProperty(value);
+ if (newValue) {
this.fadeOutAllNonPersistent();
}
- this._disabled = value;
+ this._disabled = newValue;
this._setupTriggerEventsIfEnabled();
}
- private _disabled: boolean = false;
+ private _disabled = false;
/**
* The element that triggers the ripple when click events are received.
@@ -118,14 +134,13 @@ export class MatRipple implements OnInit, OnDestroy, RippleTarget {
private _globalOptions: RippleGlobalOptions;
/** Whether ripple directive is initialized and the input bindings are set. */
- private _isInitialized: boolean = false;
+ private _isInitialized = false;
constructor(private _elementRef: ElementRef,
ngZone: NgZone,
platform: Platform,
@Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) globalOptions?: RippleGlobalOptions,
@Optional() @Inject(ANIMATION_MODULE_TYPE) private _animationMode?: string) {
-
this._globalOptions = globalOptions || {};
this._rippleRenderer = new RippleRenderer(this, ngZone, _elementRef, platform);
}
@@ -206,5 +221,9 @@ export class MatRipple implements OnInit, OnDestroy, RippleTarget {
return this._rippleRenderer.fadeInRipple(0, 0, {...this.rippleConfig, ...configOrX});
}
}
-}
+ static ngAcceptInputType_unbounded: BooleanInput;
+ static ngAcceptInputType_centered: BooleanInput;
+ static ngAcceptInputType_radius: NumberInput;
+ static ngAcceptInputType_disabled: BooleanInput;
+}
diff --git a/src/material/core/selection/pseudo-checkbox/pseudo-checkbox.ts b/src/material/core/selection/pseudo-checkbox/pseudo-checkbox.ts
index 55f20d014366..ccc1f98b0970 100644
--- a/src/material/core/selection/pseudo-checkbox/pseudo-checkbox.ts
+++ b/src/material/core/selection/pseudo-checkbox/pseudo-checkbox.ts
@@ -15,6 +15,7 @@ import {
Optional,
} from '@angular/core';
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
+import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
/**
* Possible states for a pseudo checkbox.
@@ -52,9 +53,14 @@ export type MatPseudoCheckboxState = 'unchecked' | 'checked' | 'indeterminate';
export class MatPseudoCheckbox {
/** Display state of the checkbox. */
@Input() state: MatPseudoCheckboxState = 'unchecked';
+ private _disabled = false;
/** Whether the checkbox is disabled. */
- @Input() disabled: boolean = false;
+ @Input()
+ get disabled(): boolean { return this._disabled; }
+ set disabled(value: boolean) { this._disabled = coerceBooleanProperty(value); }
constructor(@Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string) { }
+
+ static ngAcceptInputType_disabled: BooleanInput;
}
diff --git a/src/material/datepicker/calendar-body.ts b/src/material/datepicker/calendar-body.ts
index e3601a8e884a..54770385f539 100644
--- a/src/material/datepicker/calendar-body.ts
+++ b/src/material/datepicker/calendar-body.ts
@@ -358,7 +358,6 @@ export class MatCalendarBody implements OnChanges, OnDestroy {
return null;
}
-
}
/** Checks whether a node is a table cell element. */
diff --git a/src/material/datepicker/datepicker-toggle.ts b/src/material/datepicker/datepicker-toggle.ts
index 34c8e9fbc16b..95a3a64d1112 100644
--- a/src/material/datepicker/datepicker-toggle.ts
+++ b/src/material/datepicker/datepicker-toggle.ts
@@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
-import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
import {
AfterContentInit,
Attribute,
@@ -22,6 +21,12 @@ import {
ViewEncapsulation,
ViewChild,
} from '@angular/core';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty,
+} from '@angular/cdk/coercion';
import {MatButton} from '@angular/material/button';
import {merge, Observable, of as observableOf, Subscription} from 'rxjs';
import {MatDatepickerIntl} from './datepicker-intl';
@@ -63,7 +68,10 @@ export class MatDatepickerToggle implements AfterContentInit, OnChanges, OnDe
@Input('for') datepicker: MatDatepickerPanel, D>;
/** Tabindex for the toggle. */
- @Input() tabIndex: number | null;
+ @Input()
+ get tabIndex(): number | null { return this._tabIndex; }
+ set tabIndex(value: number | null) { this._tabIndex = coerceNumberProperty(value); }
+ private _tabIndex: number | null;
/** Screenreader label for the button. */
@Input('aria-label') ariaLabel: string;
@@ -83,7 +91,10 @@ export class MatDatepickerToggle implements AfterContentInit, OnChanges, OnDe
private _disabled: boolean;
/** Whether ripples on the toggle should be disabled. */
- @Input() disableRipple: boolean;
+ @Input()
+ get disableRipple(): boolean { return this._disableRipple; }
+ set disableRipple(value: boolean) { this._disableRipple = coerceBooleanProperty(value); }
+ private _disableRipple: boolean;
/** Custom icon set by the consumer. */
@ContentChild(MatDatepickerToggleIcon) _customIcon: MatDatepickerToggleIcon;
@@ -138,5 +149,7 @@ export class MatDatepickerToggle implements AfterContentInit, OnChanges, OnDe
).subscribe(() => this._changeDetectorRef.markForCheck());
}
+ static ngAcceptInputType_tabIndex: NumberInput;
static ngAcceptInputType_disabled: BooleanInput;
+ static ngAcceptInputType_disableRipple: BooleanInput;
}
diff --git a/src/material/list/selection-list.ts b/src/material/list/selection-list.ts
index c3310355c713..74a190492200 100644
--- a/src/material/list/selection-list.ts
+++ b/src/material/list/selection-list.ts
@@ -7,7 +7,12 @@
*/
import {FocusableOption, FocusKeyManager, FocusMonitor} from '@angular/cdk/a11y';
-import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty,
+} from '@angular/cdk/coercion';
import {SelectionModel} from '@angular/cdk/collections';
import {
A,
@@ -341,7 +346,7 @@ export class MatListOption extends _MatListOptionBase implements AfterContentIni
'(keydown)': '_keydown($event)',
'[attr.aria-multiselectable]': 'multiple',
'[attr.aria-disabled]': 'disabled.toString()',
- '[attr.tabindex]': '_tabIndex',
+ '[attr.tabindex]': 'tabIndex',
},
template: '',
styleUrls: ['list.css'],
@@ -368,7 +373,10 @@ export class MatSelectionList extends _MatSelectionListBase implements CanDisabl
* Tabindex of the selection list.
* @breaking-change 11.0.0 Remove `tabIndex` input.
*/
- @Input() tabIndex: number = 0;
+ @Input()
+ get tabIndex(): number { return this._tabIndex; }
+ set tabIndex(value: number) { this._tabIndex = coerceNumberProperty(value); }
+ private _tabIndex = -1;
/** Theme color of the selection list. This sets the checkbox color for all list options. */
@Input() color: ThemePalette = 'accent';
@@ -414,9 +422,6 @@ export class MatSelectionList extends _MatSelectionListBase implements CanDisabl
/** The currently selected options. */
selectedOptions = new SelectionModel(this._multiple);
- /** The tabindex of the selection list. */
- _tabIndex = -1;
-
/** View to model callback that should be called whenever the selected options change. */
private _onChange: (value: any) => void = (_: any) => {};
@@ -739,6 +744,7 @@ export class MatSelectionList extends _MatSelectionListBase implements CanDisabl
this._tabIndex = (this.options.length === 0) ? -1 : 0;
}
+ static ngAcceptInputType_tabIndex: NumberInput;
static ngAcceptInputType_disabled: BooleanInput;
static ngAcceptInputType_disableRipple: BooleanInput;
static ngAcceptInputType_multiple: BooleanInput;
diff --git a/src/material/menu/menu-trigger.ts b/src/material/menu/menu-trigger.ts
index 747d62579cba..de7716b73bff 100644
--- a/src/material/menu/menu-trigger.ts
+++ b/src/material/menu/menu-trigger.ts
@@ -13,6 +13,7 @@ import {
isFakeTouchstartFromScreenReader,
} from '@angular/cdk/a11y';
import {Direction, Directionality} from '@angular/cdk/bidi';
+import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
import {ENTER, LEFT_ARROW, RIGHT_ARROW, SPACE} from '@angular/cdk/keycodes';
import {
FlexibleConnectedPositionStrategy,
@@ -165,7 +166,10 @@ export abstract class _MatMenuTriggerBase implements AfterContentInit, OnDestroy
* Note that disabling this option can have accessibility implications
* and it's up to you to manage focus, if you decide to turn it off.
*/
- @Input('matMenuTriggerRestoreFocus') restoreFocus: boolean = true;
+ @Input('matMenuTriggerRestoreFocus')
+ get restoreFocus(): boolean { return this._restoreFocus; }
+ set restoreFocus(value: boolean) { this._restoreFocus = coerceBooleanProperty(value); }
+ private _restoreFocus = true;
/** Event emitted when the associated menu is opened. */
@Output() readonly menuOpened: EventEmitter = new EventEmitter();
@@ -604,6 +608,7 @@ export abstract class _MatMenuTriggerBase implements AfterContentInit, OnDestroy
return this._portal;
}
+ static ngAcceptInputType_restoreFocus: BooleanInput;
}
/** Directive applied to an element that should trigger a `mat-menu`. */
diff --git a/src/material/progress-bar/progress-bar.ts b/src/material/progress-bar/progress-bar.ts
index d4ddc06016ca..4cfa56af6a5d 100644
--- a/src/material/progress-bar/progress-bar.ts
+++ b/src/material/progress-bar/progress-bar.ts
@@ -164,7 +164,7 @@ export class MatProgressBar extends _MatProgressBarBase implements CanColor,
/** Buffer value of the progress bar. Defaults to zero. */
@Input()
get bufferValue(): number { return this._bufferValue; }
- set bufferValue(v: number) { this._bufferValue = clamp(v || 0); }
+ set bufferValue(v: number) { this._bufferValue = clamp(coerceNumberProperty(v) || 0); }
private _bufferValue: number = 0;
@ViewChild('primaryValueBar') _primaryValueBar: ElementRef;
@@ -236,6 +236,7 @@ export class MatProgressBar extends _MatProgressBarBase implements CanColor,
}
static ngAcceptInputType_value: NumberInput;
+ static ngAcceptInputType_bufferValue: NumberInput;
}
/** Clamps a value to be between two numbers, by default 0 and 100. */
diff --git a/src/material/stepper/stepper.ts b/src/material/stepper/stepper.ts
index d04de8b70fc4..39702a572daf 100644
--- a/src/material/stepper/stepper.ts
+++ b/src/material/stepper/stepper.ts
@@ -7,6 +7,7 @@
*/
import {Directionality} from '@angular/cdk/bidi';
+import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
import {
CdkStep,
CdkStepper,
@@ -190,7 +191,10 @@ export class MatStepper extends CdkStepper implements AfterContentInit {
@Output() readonly animationDone: EventEmitter = new EventEmitter();
/** Whether ripples should be disabled for the step headers. */
- @Input() disableRipple: boolean;
+ @Input()
+ get disableRipple(): boolean { return this._disableRipple; }
+ set disableRipple(value: boolean) { this._disableRipple = coerceBooleanProperty(value); }
+ private _disableRipple: boolean;
/** Theme color for all of the steps in stepper. */
@Input() color: ThemePalette;
@@ -243,4 +247,6 @@ export class MatStepper extends CdkStepper implements AfterContentInit {
_stepIsNavigable(index: number, step: MatStep): boolean {
return step.completed || this.selectedIndex === index || !this.linear;
}
+
+ static ngAcceptInputType_disableRipple: BooleanInput;
}
diff --git a/src/material/tabs/paginated-tab-header.ts b/src/material/tabs/paginated-tab-header.ts
index 946dc06fa239..8b107aaa612e 100644
--- a/src/material/tabs/paginated-tab-header.ts
+++ b/src/material/tabs/paginated-tab-header.ts
@@ -22,7 +22,12 @@ import {
Input,
} from '@angular/core';
import {Direction, Directionality} from '@angular/cdk/bidi';
-import {coerceNumberProperty, NumberInput} from '@angular/cdk/coercion';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty,
+} from '@angular/cdk/coercion';
import {ViewportRuler} from '@angular/cdk/scrolling';
import {FocusKeyManager, FocusableOption} from '@angular/cdk/a11y';
import {ENTER, SPACE, hasModifierKey} from '@angular/cdk/keycodes';
@@ -119,7 +124,9 @@ export abstract class MatPaginatedTabHeader implements AfterContentChecked, Afte
* layout recalculations if it's known that pagination won't be required.
*/
@Input()
- disablePagination: boolean = false;
+ get disablePagination(): boolean { return this._disablePagination; }
+ set disablePagination(value: boolean) { this._disablePagination = coerceBooleanProperty(value); }
+ private _disablePagination = false;
/** The index of the active tab. */
get selectedIndex(): number { return this._selectedIndex; }
@@ -586,5 +593,6 @@ export abstract class MatPaginatedTabHeader implements AfterContentChecked, Afte
return {maxScrollDistance, distance: this._scrollDistance};
}
+ static ngAcceptInputType_disablePagination: BooleanInput;
static ngAcceptInputType_selectedIndex: NumberInput;
}
diff --git a/src/material/tabs/tab-body.ts b/src/material/tabs/tab-body.ts
index 648fbf4360bb..a9aed444e91e 100644
--- a/src/material/tabs/tab-body.ts
+++ b/src/material/tabs/tab-body.ts
@@ -28,6 +28,7 @@ import {
import {AnimationEvent} from '@angular/animations';
import {TemplatePortal, CdkPortalOutlet} from '@angular/cdk/portal';
import {Directionality, Direction} from '@angular/cdk/bidi';
+import {NumberInput, coerceNumberProperty} from '@angular/cdk/coercion';
import {DOCUMENT} from '@angular/common';
import {Subscription, Subject} from 'rxjs';
import {matTabsAnimations} from './tabs-animations';
@@ -137,7 +138,12 @@ export abstract class _MatTabBodyBase implements OnInit, OnDestroy {
@Input('content') _content: TemplatePortal;
/** Position that will be used when the tab is immediately becoming visible after creation. */
- @Input() origin: number | null;
+ @Input()
+ get origin(): number | null { return this._origin; }
+ set origin(value: number | null) {
+ this._origin = value == null ? null : coerceNumberProperty(value);
+ }
+ private _origin: number | null;
// Note that the default value will always be overwritten by `MatTabBody`, but we need one
// anyway to prevent the animations module from throwing an error if the body is used on its own.
@@ -147,7 +153,7 @@ export abstract class _MatTabBodyBase implements OnInit, OnDestroy {
/** The shifted index position of the tab body, where zero represents the active center tab. */
@Input()
set position(position: number) {
- this._positionIndex = position;
+ this._positionIndex = coerceNumberProperty(position);
this._computePositionAnimationState();
}
@@ -237,6 +243,9 @@ export abstract class _MatTabBodyBase implements OnInit, OnDestroy {
return 'right-origin-center';
}
+
+ static ngAcceptInputType_origin: NumberInput;
+ static ngAcceptInputType_position: NumberInput;
}
/**
diff --git a/src/material/tabs/tab-group.ts b/src/material/tabs/tab-group.ts
index e719fca94dd7..2c48193cdc1a 100644
--- a/src/material/tabs/tab-group.ts
+++ b/src/material/tabs/tab-group.ts
@@ -8,9 +8,9 @@
import {
BooleanInput,
+ NumberInput,
coerceBooleanProperty,
coerceNumberProperty,
- NumberInput
} from '@angular/cdk/coercion';
import {
AfterContentChecked,
@@ -145,7 +145,9 @@ export abstract class _MatTabGroupBase extends _MatTabGroupMixinBase implements
* layout recalculations if it's known that pagination won't be required.
*/
@Input()
- disablePagination: boolean;
+ get disablePagination(): boolean { return this._disablePagination; }
+ set disablePagination(value: boolean) { this._disablePagination = coerceBooleanProperty(value); }
+ private _disablePagination: boolean;
/** Background color of the tab group. */
@Input()
@@ -421,6 +423,7 @@ export abstract class _MatTabGroupBase extends _MatTabGroupMixinBase implements
static ngAcceptInputType_selectedIndex: NumberInput;
static ngAcceptInputType_disableRipple: BooleanInput;
static ngAcceptInputType_contentTabIndex: NumberInput;
+ static ngAcceptInputType_disablePagination: BooleanInput;
}
/**
diff --git a/src/material/tabs/tab-nav-bar/tab-nav-bar.ts b/src/material/tabs/tab-nav-bar/tab-nav-bar.ts
index 832239903323..c584e8888f8a 100644
--- a/src/material/tabs/tab-nav-bar/tab-nav-bar.ts
+++ b/src/material/tabs/tab-nav-bar/tab-nav-bar.ts
@@ -7,7 +7,12 @@
*/
import {FocusableOption, FocusMonitor} from '@angular/cdk/a11y';
import {Directionality} from '@angular/cdk/bidi';
-import {BooleanInput, coerceBooleanProperty, NumberInput} from '@angular/cdk/coercion';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty,
+} from '@angular/cdk/coercion';
import {Platform} from '@angular/cdk/platform';
import {ViewportRuler} from '@angular/cdk/scrolling';
import {
@@ -223,7 +228,7 @@ export class _MatTabLinkBase extends _MatTabLinkMixinBase implements AfterViewIn
super();
this.rippleConfig = globalRippleOptions || {};
- this.tabIndex = parseInt(tabIndex) || 0;
+ this.tabIndex = coerceNumberProperty(tabIndex, 0);
if (animationMode === 'NoopAnimations') {
this.rippleConfig.animation = {enterDuration: 0, exitDuration: 0};
diff --git a/src/material/tooltip/tooltip.ts b/src/material/tooltip/tooltip.ts
index 3685dd0b0285..8c9c8f20b166 100644
--- a/src/material/tooltip/tooltip.ts
+++ b/src/material/tooltip/tooltip.ts
@@ -8,7 +8,12 @@
import {AnimationEvent} from '@angular/animations';
import {AriaDescriber, FocusMonitor} from '@angular/cdk/a11y';
import {Directionality} from '@angular/cdk/bidi';
-import {BooleanInput, coerceBooleanProperty, NumberInput} from '@angular/cdk/coercion';
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty,
+} from '@angular/cdk/coercion';
import {ESCAPE, hasModifierKey} from '@angular/cdk/keycodes';
import {BreakpointObserver, Breakpoints, BreakpointState} from '@angular/cdk/layout';
import {
@@ -180,10 +185,16 @@ export abstract class _MatTooltipBase implement
}
/** The default delay in ms before showing the tooltip after show is called */
- @Input('matTooltipShowDelay') showDelay: number = this._defaultOptions.showDelay;
+ @Input('matTooltipShowDelay')
+ get showDelay(): number { return this._showDelay; }
+ set showDelay(value: number) { this._showDelay = coerceNumberProperty(value); }
+ private _showDelay = this._defaultOptions.showDelay;
/** The default delay in ms before hiding the tooltip after hide is called */
- @Input('matTooltipHideDelay') hideDelay: number = this._defaultOptions.hideDelay;
+ @Input('matTooltipHideDelay')
+ get hideDelay(): number { return this._hideDelay; }
+ set hideDelay(value: number) { this._hideDelay = coerceNumberProperty(value); }
+ private _hideDelay = this._defaultOptions.hideDelay;
/**
* How touch gestures should be handled by the tooltip. On touch devices the tooltip directive
@@ -718,8 +729,8 @@ export abstract class _MatTooltipBase implement
}
static ngAcceptInputType_disabled: BooleanInput;
- static ngAcceptInputType_hideDelay: NumberInput;
static ngAcceptInputType_showDelay: NumberInput;
+ static ngAcceptInputType_hideDelay: NumberInput;
}
/**
diff --git a/src/material/tree/node.ts b/src/material/tree/node.ts
index 04e78b32304e..40c989d2e091 100644
--- a/src/material/tree/node.ts
+++ b/src/material/tree/node.ts
@@ -6,6 +6,12 @@
* found in the LICENSE file at https://angular.io/license
*/
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty,
+} from '@angular/cdk/coercion';
import {
CDK_TREE_NODE_OUTLET_NODE,
CdkNestedTreeNode,
@@ -29,7 +35,6 @@ import {
mixinDisabled,
mixinTabIndex,
} from '@angular/material/core';
-import {BooleanInput, coerceBooleanProperty, NumberInput} from '@angular/cdk/coercion';
const _MatTreeNodeBase = mixinTabIndex(mixinDisabled(CdkTreeNode));
@@ -120,7 +125,7 @@ export class MatNestedTreeNode extends CdkNestedTreeNode
get tabIndex(): number { return this.disabled ? -1 : this._tabIndex; }
set tabIndex(value: number) {
// If the specified tabIndex value is null or undefined, fall back to the default value.
- this._tabIndex = value != null ? value : 0;
+ this._tabIndex = coerceNumberProperty(value, 0);
}
private _tabIndex: number;
@@ -157,4 +162,5 @@ export class MatNestedTreeNode extends CdkNestedTreeNode
}
static ngAcceptInputType_disabled: BooleanInput;
+ static ngAcceptInputType_tabIndex: NumberInput;
}
diff --git a/src/youtube-player/BUILD.bazel b/src/youtube-player/BUILD.bazel
index eaa79c409abb..1ad9e6d6b063 100644
--- a/src/youtube-player/BUILD.bazel
+++ b/src/youtube-player/BUILD.bazel
@@ -19,6 +19,7 @@ ng_module(
),
deps = [
"//src:dev_mode_types",
+ "//src/cdk/coercion",
"@npm//@angular/common",
"@npm//@angular/core",
"@npm//@types/youtube",
diff --git a/src/youtube-player/package.json b/src/youtube-player/package.json
index a33dad7eaaec..ff0ed05f00ef 100644
--- a/src/youtube-player/package.json
+++ b/src/youtube-player/package.json
@@ -21,6 +21,7 @@
"tslib": "0.0.0-TSLIB"
},
"peerDependencies": {
+ "@angular/cdk": "0.0.0-PLACEHOLDER",
"@angular/core": "0.0.0-NG",
"@angular/common": "0.0.0-NG",
"rxjs": "0.0.0-RXJS"
diff --git a/src/youtube-player/tsconfig-tests.json b/src/youtube-player/tsconfig-tests.json
index 42801e3fe93a..6015039071eb 100644
--- a/src/youtube-player/tsconfig-tests.json
+++ b/src/youtube-player/tsconfig-tests.json
@@ -1,5 +1,10 @@
{
"extends": "../bazel-tsconfig-build.json",
+ "references": [
+ {
+ "path": "../cdk/tsconfig-tests.json"
+ }
+ ],
"compilerOptions": {
"baseUrl": ".",
"outDir": "../../dist/packages/youtube-player",
@@ -13,7 +18,10 @@
"target": "es5",
"types": ["jasmine"],
"experimentalDecorators": true,
- "emitDecoratorMetadata": true
+ "emitDecoratorMetadata": true,
+ "paths": {
+ "@angular/cdk/*": ["../../dist/packages/cdk/*"]
+ }
},
"include": [
"**/*.ts",
diff --git a/src/youtube-player/tsconfig.json b/src/youtube-player/tsconfig.json
index 19ef7205e54f..8f792cb549cf 100644
--- a/src/youtube-player/tsconfig.json
+++ b/src/youtube-player/tsconfig.json
@@ -4,7 +4,9 @@
"compilerOptions": {
"rootDir": "..",
"baseUrl": ".",
- "paths": {},
+ "paths": {
+ "@angular/cdk/*": ["../cdk/*"]
+ },
"types": ["jasmine"]
},
"include": ["*.ts", "../dev-mode-types.d.ts"]
diff --git a/src/youtube-player/youtube-player.ts b/src/youtube-player/youtube-player.ts
index b5624d8248b9..46ad91207024 100644
--- a/src/youtube-player/youtube-player.ts
+++ b/src/youtube-player/youtube-player.ts
@@ -25,7 +25,12 @@ import {
PLATFORM_ID,
} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';
-
+import {
+ BooleanInput,
+ NumberInput,
+ coerceBooleanProperty,
+ coerceNumberProperty
+} from '@angular/cdk/coercion';
import {
combineLatest,
ConnectableObservable,
@@ -40,7 +45,6 @@ import {
BehaviorSubject,
fromEventPattern,
} from 'rxjs';
-
import {
combineLatest as combineLatestOp,
distinctUntilChanged,
@@ -125,7 +129,7 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
@Input()
get height(): number | undefined { return this._height.value; }
set height(height: number | undefined) {
- this._height.next(height || DEFAULT_PLAYER_HEIGHT);
+ this._height.next(coerceNumberProperty(height, DEFAULT_PLAYER_HEIGHT));
}
private readonly _height = new BehaviorSubject(DEFAULT_PLAYER_HEIGHT);
@@ -133,21 +137,21 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
@Input()
get width(): number | undefined { return this._width.value; }
set width(width: number | undefined) {
- this._width.next(width || DEFAULT_PLAYER_WIDTH);
+ this._width.next(coerceNumberProperty(width, DEFAULT_PLAYER_WIDTH));
}
private readonly _width = new BehaviorSubject(DEFAULT_PLAYER_WIDTH);
/** The moment when the player is supposed to start playing */
@Input()
set startSeconds(startSeconds: number | undefined) {
- this._startSeconds.next(startSeconds);
+ this._startSeconds.next(coerceNumberProperty(startSeconds));
}
private readonly _startSeconds = new BehaviorSubject(undefined);
/** The moment when the player is supposed to stop playing */
@Input()
set endSeconds(endSeconds: number | undefined) {
- this._endSeconds.next(endSeconds);
+ this._endSeconds.next(coerceNumberProperty(endSeconds));
}
private readonly _endSeconds = new BehaviorSubject(undefined);
@@ -175,7 +179,12 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
* page. Set this to true if you don't want the `onYouTubeIframeAPIReady` field to be
* set on the global window.
*/
- @Input() showBeforeIframeApiLoads: boolean | undefined;
+ @Input()
+ get showBeforeIframeApiLoads(): boolean | undefined { return this._showBeforeIframeApiLoads; }
+ set showBeforeIframeApiLoads(value: boolean | undefined) {
+ this._showBeforeIframeApiLoads = coerceBooleanProperty(value);
+ }
+ private _showBeforeIframeApiLoads: boolean | undefined;
/** Outputs are direct proxies from the player itself. */
@Output() readonly ready: Observable =
@@ -546,6 +555,12 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
takeUntil(this._destroyed)
);
}
+
+ static ngAcceptInputType_height: NumberInput;
+ static ngAcceptInputType_width: NumberInput;
+ static ngAcceptInputType_startSeconds: NumberInput;
+ static ngAcceptInputType_endSeconds: NumberInput;
+ static ngAcceptInputType_showBeforeIframeApiLoads: BooleanInput;
}
/** Listens to changes to the given width and height and sets it on the player. */