Skip to content

Commit b7db96c

Browse files
authored
fix(material/badge): avoid emitting the structural styles more than once (#23011)
The badge structural styles are currently in the theme, because the badge is a directive and Angular doesn't support associating styles with directives. The problem is that it'll cause the same structural styles to be emitted multiple times unnecessarily. These changes add some logic that will try to prevent the structural styles from being emitted more than once. **Disclaimer:** this change might not work across multiple compilation units, however I still think it's worthwhile, because the apps that only have one global stylesheet for their theme will get the benefit, while everybody else will work the same as before. These changes shave off more than 4kb of minified CSS.
1 parent 136fb5a commit b7db96c

File tree

1 file changed

+64
-45
lines changed

1 file changed

+64
-45
lines changed

src/material/badge/_badge-theme.scss

Lines changed: 64 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ $font-weight: 600;
1515
$default-size: 22px !default;
1616
$small-size: $default-size - 6;
1717
$large-size: $default-size + 6;
18+
$_badge-structure-emitted: false !default;
1819

1920
// Mixin for building offset given different sizes
2021
@mixin _badge-size($size) {
@@ -94,6 +95,57 @@ $large-size: $default-size + 6;
9495
// stylelint-enable
9596
}
9697

98+
// Structural styles for the badge. They have to be included as a part of the theme,
99+
// because the badge is a directive and we have no other way of attaching styles to it.
100+
@mixin _badge-structure {
101+
.mat-badge {
102+
position: relative;
103+
}
104+
105+
.mat-badge-hidden {
106+
.mat-badge-content {
107+
display: none;
108+
}
109+
}
110+
111+
.mat-badge-content {
112+
position: absolute;
113+
text-align: center;
114+
display: inline-block;
115+
border-radius: 50%;
116+
transition: transform 200ms ease-in-out;
117+
transform: scale(0.6);
118+
overflow: hidden;
119+
white-space: nowrap;
120+
text-overflow: ellipsis;
121+
pointer-events: none;
122+
}
123+
124+
.ng-animate-disabled .mat-badge-content,
125+
.mat-badge-content._mat-animation-noopable {
126+
transition: none;
127+
}
128+
129+
// The active class is added after the element is added
130+
// so it can animate scale to default
131+
.mat-badge-content.mat-badge-active {
132+
// Scale to `none` instead of `1` to avoid blurry text in some browsers.
133+
transform: none;
134+
}
135+
136+
.mat-badge-small {
137+
@include _badge-size($small-size);
138+
}
139+
140+
.mat-badge-medium {
141+
@include _badge-size($default-size);
142+
}
143+
144+
.mat-badge-large {
145+
@include _badge-size($large-size);
146+
}
147+
}
148+
97149
@mixin color($config-or-theme) {
98150
$config: theming.get-color-config($config-or-theme);
99151
$accent: map.get($config, accent);
@@ -126,16 +178,6 @@ $large-size: $default-size + 6;
126178
}
127179
}
128180

129-
.mat-badge {
130-
position: relative;
131-
}
132-
133-
.mat-badge-hidden {
134-
.mat-badge-content {
135-
display: none;
136-
}
137-
}
138-
139181
.mat-badge-disabled {
140182
.mat-badge-content {
141183
$app-background: theming.get-color-from-palette($background, 'background');
@@ -157,41 +199,6 @@ $large-size: $default-size + 6;
157199
color: theming.get-color-from-palette($foreground, disabled-text);
158200
}
159201
}
160-
161-
.mat-badge-content {
162-
position: absolute;
163-
text-align: center;
164-
display: inline-block;
165-
border-radius: 50%;
166-
transition: transform 200ms ease-in-out;
167-
transform: scale(0.6);
168-
overflow: hidden;
169-
white-space: nowrap;
170-
text-overflow: ellipsis;
171-
pointer-events: none;
172-
}
173-
174-
.ng-animate-disabled .mat-badge-content,
175-
.mat-badge-content._mat-animation-noopable {
176-
transition: none;
177-
}
178-
179-
// The active class is added after the element is added
180-
// so it can animate scale to default
181-
.mat-badge-content.mat-badge-active {
182-
// Scale to `none` instead of `1` to avoid blurry text in some browsers.
183-
transform: none;
184-
}
185-
186-
.mat-badge-small {
187-
@include _badge-size($small-size);
188-
}
189-
.mat-badge-medium {
190-
@include _badge-size($default-size);
191-
}
192-
.mat-badge-large {
193-
@include _badge-size($large-size);
194-
}
195202
}
196203

197204
@mixin typography($config-or-theme) {
@@ -222,6 +229,18 @@ $large-size: $default-size + 6;
222229
$density: theming.get-density-config($theme);
223230
$typography: theming.get-typography-config($theme);
224231

232+
// Try to reduce the number of times that the structural styles are emitted.
233+
@if not $_badge-structure-emitted {
234+
@include _badge-structure;
235+
236+
// Only flip the flag if the mixin is included at the top level. Otherwise the first
237+
// inclusion might be inside of a theme class which will exclude the structural styles
238+
// from all other themes.
239+
@if not & {
240+
$_badge-structure-emitted: true !global;
241+
}
242+
}
243+
225244
@if $color != null {
226245
@include color($color);
227246
}

0 commit comments

Comments
 (0)