Skip to content

Commit 66632c9

Browse files
committed
fix(material/tabs): avoid reference error (#25928)
Moves the `_MatTabNavBase` class a bit further up in the file to try and avoid a reference error in some test setups. Fixes #25918. (cherry picked from commit f08f3aa)
1 parent a64186a commit 66632c9

File tree

1 file changed

+110
-110
lines changed

1 file changed

+110
-110
lines changed

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

Lines changed: 110 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,116 @@ import {MatPaginatedTabHeader, MatPaginatedTabHeaderItem} from '../paginated-tab
5555
// Increasing integer for generating unique ids for tab nav components.
5656
let nextUniqueId = 0;
5757

58+
/**
59+
* Base class with all of the `MatTabNav` functionality.
60+
* @docs-private
61+
*/
62+
@Directive()
63+
export abstract class _MatTabNavBase
64+
extends MatPaginatedTabHeader
65+
implements AfterContentChecked, AfterContentInit, OnDestroy
66+
{
67+
/** Query list of all tab links of the tab navigation. */
68+
abstract override _items: QueryList<MatPaginatedTabHeaderItem & {active: boolean; id: string}>;
69+
70+
/** Background color of the tab nav. */
71+
@Input()
72+
get backgroundColor(): ThemePalette {
73+
return this._backgroundColor;
74+
}
75+
76+
set backgroundColor(value: ThemePalette) {
77+
const classList = this._elementRef.nativeElement.classList;
78+
classList.remove(`mat-background-${this.backgroundColor}`);
79+
80+
if (value) {
81+
classList.add(`mat-background-${value}`);
82+
}
83+
84+
this._backgroundColor = value;
85+
}
86+
87+
private _backgroundColor: ThemePalette;
88+
89+
/** Whether the ripple effect is disabled or not. */
90+
@Input()
91+
get disableRipple(): boolean {
92+
return this._disableRipple;
93+
}
94+
95+
set disableRipple(value: BooleanInput) {
96+
this._disableRipple = coerceBooleanProperty(value);
97+
}
98+
99+
private _disableRipple: boolean = false;
100+
101+
/** Theme color of the nav bar. */
102+
@Input() color: ThemePalette = 'primary';
103+
104+
/**
105+
* Associated tab panel controlled by the nav bar. If not provided, then the nav bar
106+
* follows the ARIA link / navigation landmark pattern. If provided, it follows the
107+
* ARIA tabs design pattern.
108+
*/
109+
@Input() tabPanel?: MatTabNavPanel;
110+
111+
constructor(
112+
elementRef: ElementRef,
113+
@Optional() dir: Directionality,
114+
ngZone: NgZone,
115+
changeDetectorRef: ChangeDetectorRef,
116+
viewportRuler: ViewportRuler,
117+
platform: Platform,
118+
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string,
119+
) {
120+
super(elementRef, changeDetectorRef, viewportRuler, dir, ngZone, platform, animationMode);
121+
}
122+
123+
protected _itemSelected() {
124+
// noop
125+
}
126+
127+
override ngAfterContentInit() {
128+
// We need this to run before the `changes` subscription in parent to ensure that the
129+
// selectedIndex is up-to-date by the time the super class starts looking for it.
130+
this._items.changes.pipe(startWith(null), takeUntil(this._destroyed)).subscribe(() => {
131+
this.updateActiveLink();
132+
});
133+
134+
super.ngAfterContentInit();
135+
}
136+
137+
/** Notifies the component that the active link has been changed. */
138+
updateActiveLink() {
139+
if (!this._items) {
140+
return;
141+
}
142+
143+
const items = this._items.toArray();
144+
145+
for (let i = 0; i < items.length; i++) {
146+
if (items[i].active) {
147+
this.selectedIndex = i;
148+
this._changeDetectorRef.markForCheck();
149+
150+
if (this.tabPanel) {
151+
this.tabPanel._activeTabId = items[i].id;
152+
}
153+
154+
return;
155+
}
156+
}
157+
158+
// The ink bar should hide itself if no items are active.
159+
this.selectedIndex = -1;
160+
this._inkBar.hide();
161+
}
162+
163+
_getRole(): string | null {
164+
return this.tabPanel ? 'tablist' : this._elementRef.nativeElement.getAttribute('role');
165+
}
166+
}
167+
58168
// Boilerplate for applying mixins to MatTabLink.
59169
const _MatTabLinkMixinBase = mixinTabIndex(mixinDisableRipple(mixinDisabled(class {})));
60170

@@ -189,116 +299,6 @@ export class _MatTabLinkBase
189299

190300
const _MatTabLinkBaseWithInkBarItem = mixinInkBarItem(_MatTabLinkBase);
191301

192-
/**
193-
* Base class with all of the `MatTabNav` functionality.
194-
* @docs-private
195-
*/
196-
@Directive()
197-
export abstract class _MatTabNavBase
198-
extends MatPaginatedTabHeader
199-
implements AfterContentChecked, AfterContentInit, OnDestroy
200-
{
201-
/** Query list of all tab links of the tab navigation. */
202-
abstract override _items: QueryList<MatPaginatedTabHeaderItem & {active: boolean; id: string}>;
203-
204-
/** Background color of the tab nav. */
205-
@Input()
206-
get backgroundColor(): ThemePalette {
207-
return this._backgroundColor;
208-
}
209-
210-
set backgroundColor(value: ThemePalette) {
211-
const classList = this._elementRef.nativeElement.classList;
212-
classList.remove(`mat-background-${this.backgroundColor}`);
213-
214-
if (value) {
215-
classList.add(`mat-background-${value}`);
216-
}
217-
218-
this._backgroundColor = value;
219-
}
220-
221-
private _backgroundColor: ThemePalette;
222-
223-
/** Whether the ripple effect is disabled or not. */
224-
@Input()
225-
get disableRipple(): boolean {
226-
return this._disableRipple;
227-
}
228-
229-
set disableRipple(value: BooleanInput) {
230-
this._disableRipple = coerceBooleanProperty(value);
231-
}
232-
233-
private _disableRipple: boolean = false;
234-
235-
/** Theme color of the nav bar. */
236-
@Input() color: ThemePalette = 'primary';
237-
238-
/**
239-
* Associated tab panel controlled by the nav bar. If not provided, then the nav bar
240-
* follows the ARIA link / navigation landmark pattern. If provided, it follows the
241-
* ARIA tabs design pattern.
242-
*/
243-
@Input() tabPanel?: MatTabNavPanel;
244-
245-
constructor(
246-
elementRef: ElementRef,
247-
@Optional() dir: Directionality,
248-
ngZone: NgZone,
249-
changeDetectorRef: ChangeDetectorRef,
250-
viewportRuler: ViewportRuler,
251-
platform: Platform,
252-
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string,
253-
) {
254-
super(elementRef, changeDetectorRef, viewportRuler, dir, ngZone, platform, animationMode);
255-
}
256-
257-
protected _itemSelected() {
258-
// noop
259-
}
260-
261-
override ngAfterContentInit() {
262-
// We need this to run before the `changes` subscription in parent to ensure that the
263-
// selectedIndex is up-to-date by the time the super class starts looking for it.
264-
this._items.changes.pipe(startWith(null), takeUntil(this._destroyed)).subscribe(() => {
265-
this.updateActiveLink();
266-
});
267-
268-
super.ngAfterContentInit();
269-
}
270-
271-
/** Notifies the component that the active link has been changed. */
272-
updateActiveLink() {
273-
if (!this._items) {
274-
return;
275-
}
276-
277-
const items = this._items.toArray();
278-
279-
for (let i = 0; i < items.length; i++) {
280-
if (items[i].active) {
281-
this.selectedIndex = i;
282-
this._changeDetectorRef.markForCheck();
283-
284-
if (this.tabPanel) {
285-
this.tabPanel._activeTabId = items[i].id;
286-
}
287-
288-
return;
289-
}
290-
}
291-
292-
// The ink bar should hide itself if no items are active.
293-
this.selectedIndex = -1;
294-
this._inkBar.hide();
295-
}
296-
297-
_getRole(): string | null {
298-
return this.tabPanel ? 'tablist' : this._elementRef.nativeElement.getAttribute('role');
299-
}
300-
}
301-
302302
/**
303303
* Navigation component matching the styles of the tab group header.
304304
* Provides anchored navigation with animated ink bar.

0 commit comments

Comments
 (0)