Skip to content

Commit 58a7807

Browse files
authored
fix(material/tabs): validate animation duration (#33452)
Adds some logic to validate the animation duration for the data before assigning it to the DOM. Along the same lines as 0df0042.
1 parent 8002bce commit 58a7807

4 files changed

Lines changed: 24 additions & 21 deletions

File tree

goldens/material/tabs/index.api.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,7 @@ export class MatTabLink extends InkBarItem implements AfterViewInit, OnDestroy,
446446
// @public
447447
export class MatTabNav extends MatPaginatedTabHeader implements AfterContentInit, AfterViewInit {
448448
constructor();
449-
// (undocumented)
450-
get animationDuration(): string;
451-
set animationDuration(value: string | number);
449+
animationDuration: string;
452450
get backgroundColor(): ThemePalette;
453451
set backgroundColor(value: ThemePalette);
454452
color: ThemePalette;
@@ -472,6 +470,8 @@ export class MatTabNav extends MatPaginatedTabHeader implements AfterContentInit
472470
// (undocumented)
473471
_nextPaginator: ElementRef<HTMLElement>;
474472
// (undocumented)
473+
static ngAcceptInputType_animationDuration: string | number;
474+
// (undocumented)
475475
static ngAcceptInputType_disableRipple: unknown;
476476
// (undocumented)
477477
static ngAcceptInputType_fitInkBarToContent: unknown;

src/material/tabs/paginated-tab-header.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,19 @@ const HEADER_SCROLL_INTERVAL = 100;
6363
/** Item inside a paginated tab header. */
6464
export type MatPaginatedTabHeaderItem = FocusableOption & {elementRef: ElementRef};
6565

66+
/** Normalizes an animation duration value. */
67+
export function normalizeDuration(value: string | number): string {
68+
const stringValue = value + '';
69+
70+
if (/^[0-9]+(?:\.[0-9]+)?$/.test(stringValue)) {
71+
return `${value}ms`;
72+
} else if (/^[0-9]+(?:\.[0-9]+)?(?:ms|s)$/.test(stringValue)) {
73+
return stringValue;
74+
} else {
75+
return '';
76+
}
77+
}
78+
6679
/**
6780
* Base class for a tab header that supported pagination.
6881
* @docs-private

src/material/tabs/tab-group.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {MatTabBody} from './tab-body';
3939
import {CdkPortalOutlet} from '@angular/cdk/portal';
4040
import {MatTabLabelWrapper} from './tab-label-wrapper';
4141
import {Platform} from '@angular/cdk/platform';
42+
import {normalizeDuration} from './paginated-tab-header';
4243

4344
/** @docs-private */
4445
export interface MatTabGroupBaseHeader {
@@ -606,9 +607,3 @@ export class MatTabChangeEvent {
606607
/** Reference to the currently-selected tab. */
607608
tab!: MatTab;
608609
}
609-
610-
/** Normalizes an animation duration value. */
611-
function normalizeDuration(value: string | number): string {
612-
const stringValue = value + '';
613-
return /^\d+$/.test(stringValue) ? value + 'ms' : stringValue;
614-
}

src/material/tabs/tab-nav-bar/tab-nav-bar.ts

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ import {BehaviorSubject, Subject} from 'rxjs';
4141
import {startWith, takeUntil} from 'rxjs/operators';
4242
import {ENTER, SPACE} from '@angular/cdk/keycodes';
4343
import {MAT_TABS_CONFIG, MatTabsConfig} from '../tab-config';
44-
import {MatPaginatedTabHeader, MatPaginatedTabHeaderItem} from '../paginated-tab-header';
44+
import {
45+
MatPaginatedTabHeader,
46+
MatPaginatedTabHeaderItem,
47+
normalizeDuration,
48+
} from '../paginated-tab-header';
4549
import {CdkObserveContent} from '@angular/cdk/observers';
4650
import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
4751

@@ -89,17 +93,8 @@ export class MatTabNav extends MatPaginatedTabHeader implements AfterContentInit
8993
@Input({alias: 'mat-stretch-tabs', transform: booleanAttribute})
9094
stretchTabs: boolean = true;
9195

92-
@Input()
93-
get animationDuration(): string {
94-
return this._animationDuration;
95-
}
96-
97-
set animationDuration(value: string | number) {
98-
const stringValue = value + '';
99-
this._animationDuration = /^\d+$/.test(stringValue) ? value + 'ms' : stringValue;
100-
}
101-
102-
private _animationDuration!: string;
96+
/** Duration for the header animation. Will be normalized to milliseconds if no units are set. */
97+
@Input({transform: normalizeDuration}) animationDuration: string = '';
10398

10499
/** Query list of all tab links of the tab navigation. */
105100
@ContentChildren(forwardRef(() => MatTabLink), {descendants: true})

0 commit comments

Comments
 (0)