Skip to content

Commit db1d51f

Browse files
crisbetojelbourn
authored andcommitted
fix(badge): apply view encapsulation attributes on badge element (#12870)
Since we create the badge content element dynamically, the view encapsulation attributes won't be applied. These changes use the renderer to create the element, which will respect view encapsulation.
1 parent 0d406b3 commit db1d51f

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

src/lib/badge/badge.spec.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {ComponentFixture, TestBed, fakeAsync} from '@angular/core/testing';
2-
import {Component, DebugElement} from '@angular/core';
2+
import {Component, DebugElement, ViewEncapsulation} from '@angular/core';
33
import {By} from '@angular/platform-browser';
44
import {MatBadge, MatBadgeModule} from './index';
55
import {ThemePalette} from '@angular/material/core';
@@ -140,10 +140,27 @@ describe('MatBadge', () => {
140140
expect(classList.contains('mat-badge-hidden')).toBe(false);
141141
});
142142

143+
it('should apply view encapsulation on create badge content', () => {
144+
const badge = badgeNativeElement.querySelector('.mat-badge-content')!;
145+
let encapsulationAttr: Attr | undefined;
146+
147+
for (let i = 0; i < badge.attributes.length; i++) {
148+
if (badge.attributes[i].name.startsWith('_ngcontent-')) {
149+
encapsulationAttr = badge.attributes[i];
150+
break;
151+
}
152+
}
153+
154+
expect(encapsulationAttr).toBeTruthy();
155+
});
156+
143157
});
144158

145159
/** Test component that contains a MatBadge. */
146160
@Component({
161+
// Explicitly set the view encapsulation since we have a test that checks for it.
162+
encapsulation: ViewEncapsulation.Emulated,
163+
styles: ['span { color: hotpink; }'],
147164
template: `
148165
<span [matBadge]="badgeContent"
149166
[matBadgeColor]="badgeColor"

src/lib/badge/badge.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,16 @@
99
import {AriaDescriber} from '@angular/cdk/a11y';
1010
import {coerceBooleanProperty} from '@angular/cdk/coercion';
1111
import {DOCUMENT} from '@angular/common';
12-
import {Directive, ElementRef, Inject, Input, NgZone, OnDestroy, Optional} from '@angular/core';
12+
import {
13+
Directive,
14+
ElementRef,
15+
Inject,
16+
Input,
17+
NgZone,
18+
OnDestroy,
19+
Optional,
20+
Renderer2,
21+
} from '@angular/core';
1322
import {ThemePalette} from '@angular/material/core';
1423

1524

@@ -102,7 +111,9 @@ export class MatBadge implements OnDestroy {
102111
@Optional() @Inject(DOCUMENT) private _document: any,
103112
private _ngZone: NgZone,
104113
private _elementRef: ElementRef<HTMLElement>,
105-
private _ariaDescriber: AriaDescriber) {}
114+
private _ariaDescriber: AriaDescriber,
115+
/** @breaking-change 8.0.0 Make _renderer a required param and remove _document. */
116+
private _renderer?: Renderer2) {}
106117

107118
/** Whether the badge is above the host or not */
108119
isAbove(): boolean {
@@ -132,7 +143,9 @@ export class MatBadge implements OnDestroy {
132143

133144
/** Creates the badge element */
134145
private _createBadgeElement(): HTMLElement {
135-
const badgeElement = this._document.createElement('span');
146+
// @breaking-change 8.0.0 Remove null check for _renderer
147+
const rootNode = this._renderer || this._document;
148+
const badgeElement = rootNode.createElement('span');
136149
const activeClass = 'mat-badge-active';
137150

138151
badgeElement.setAttribute('id', `mat-badge-content-${this._id}`);

0 commit comments

Comments
 (0)