Skip to content

Commit 9a4bdba

Browse files
committed
fix(material/core): avoid having to manually load ripple styles
Makes it so the ripple loads the necessary styles itself, instead of requiring the user to do it.
1 parent cb1450f commit 9a4bdba

File tree

10 files changed

+58
-8
lines changed

10 files changed

+58
-8
lines changed

src/material/core/BUILD.bazel

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ ng_module(
2424
":option/option.css",
2525
":option/optgroup.css",
2626
":internal-form-field/internal-form-field.css",
27+
":ripple/ripple-structure.css",
2728
] + glob(["**/*.html"]),
2829
deps = [
2930
"//src:dev_mode_types",
@@ -33,6 +34,7 @@ ng_module(
3334
"//src/cdk/coercion",
3435
"//src/cdk/keycodes",
3536
"//src/cdk/platform",
37+
"//src/cdk/private",
3638
"@npm//@angular/animations",
3739
"@npm//@angular/core",
3840
"@npm//@angular/forms",
@@ -94,6 +96,12 @@ sass_binary(
9496
deps = [":core_scss_lib"],
9597
)
9698

99+
sass_binary(
100+
name = "ripple_structure_scss",
101+
src = "ripple/ripple-structure.scss",
102+
deps = [":core_scss_lib"],
103+
)
104+
97105
# M3 themes
98106
sass_binary(
99107
name = "azure_blue_prebuilt",

src/material/core/_core.scss

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
@use '@angular/cdk';
22
@use './tokens/m2/mat/app' as tokens-mat-app;
33
@use './tokens/token-utils';
4-
@use './ripple/ripple';
54
@use './style/elevation';
65
@use './focus-indicators/private';
76

@@ -15,7 +14,6 @@
1514
--mat-app-on-surface: initial;
1615
}
1716

18-
@include ripple.ripple();
1917
@include cdk.a11y-visually-hidden();
2018
@include cdk.overlay();
2119
@include cdk.text-field-autosize();

src/material/core/private/ripple-loader.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
} from '@angular/core';
1818
import {MAT_RIPPLE_GLOBAL_OPTIONS, MatRipple} from '../ripple';
1919
import {Platform, _getEventTarget} from '@angular/cdk/platform';
20+
import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
2021

2122
/** The options for the MatRippleLoader's event listeners. */
2223
const eventListenerOptions = {capture: true};
@@ -56,6 +57,7 @@ export class MatRippleLoader implements OnDestroy {
5657
private _platform = inject(Platform);
5758
private _ngZone = inject(NgZone);
5859
private _hosts = new Map<HTMLElement, MatRipple>();
60+
private _styleLoader = inject(_CdkPrivateStyleLoader);
5961

6062
constructor() {
6163
this._ngZone.runOutsideAngular(() => {
@@ -177,6 +179,7 @@ export class MatRippleLoader implements OnDestroy {
177179
this._platform,
178180
this._globalRippleOptions ? this._globalRippleOptions : undefined,
179181
this._animationMode ? this._animationMode : undefined,
182+
this._styleLoader,
180183
);
181184
ripple._isInitialized = true;
182185
ripple.trigger = host;

src/material/core/ripple/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {MatRipple} from './ripple';
1212

1313
export * from './ripple';
1414
export * from './ripple-ref';
15-
export * from './ripple-renderer';
15+
export {RippleRenderer, RippleTarget, defaultRippleAnimationConfig} from './ripple-renderer';
1616

1717
@NgModule({
1818
imports: [MatCommonModule, MatRipple],

src/material/core/ripple/ripple-renderer.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import {ElementRef, NgZone} from '@angular/core';
8+
import {
9+
ElementRef,
10+
NgZone,
11+
Component,
12+
ChangeDetectionStrategy,
13+
ViewEncapsulation,
14+
} from '@angular/core';
915
import {Platform, normalizePassiveListenerOptions, _getEventTarget} from '@angular/cdk/platform';
1016
import {isFakeMousedownFromScreenReader, isFakeTouchstartFromScreenReader} from '@angular/cdk/a11y';
1117
import {coerceElement} from '@angular/cdk/coercion';
18+
import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
1219
import {RippleRef, RippleState, RippleConfig} from './ripple-ref';
1320
import {RippleEventManager} from './ripple-event-manager';
1421

@@ -58,6 +65,16 @@ const pointerDownEvents = ['mousedown', 'touchstart'];
5865
/** Events that signal that the pointer is up. */
5966
const pointerUpEvents = ['mouseup', 'mouseleave', 'touchend', 'touchcancel'];
6067

68+
@Component({
69+
template: '',
70+
changeDetection: ChangeDetectionStrategy.OnPush,
71+
encapsulation: ViewEncapsulation.None,
72+
standalone: true,
73+
styleUrl: 'ripple-structure.css',
74+
host: {'mat-ripple-style-loader': ''},
75+
})
76+
export class _MatRippleStylesLoader {}
77+
6178
/**
6279
* Helper service that performs DOM manipulations. Not intended to be used outside this module.
6380
* The constructor takes a reference to the ripple directive's host element and a map of DOM
@@ -105,11 +122,14 @@ export class RippleRenderer implements EventListenerObject {
105122
private _ngZone: NgZone,
106123
elementOrElementRef: HTMLElement | ElementRef<HTMLElement>,
107124
private _platform: Platform,
125+
styleLoader: _CdkPrivateStyleLoader,
108126
) {
109127
// Only do anything if we're on the browser.
110128
if (_platform.isBrowser) {
111129
this._containerElement = coerceElement(elementOrElementRef);
112130
}
131+
132+
styleLoader.load(_MatRippleStylesLoader);
113133
}
114134

115135
/**
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@use './ripple';
2+
3+
@include ripple.ripple;

src/material/core/ripple/ripple.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ import {
1818
OnInit,
1919
Optional,
2020
ANIMATION_MODULE_TYPE,
21+
inject,
2122
} from '@angular/core';
23+
import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
2224
import {RippleAnimationConfig, RippleConfig, RippleRef} from './ripple-ref';
2325
import {RippleRenderer, RippleTarget} from './ripple-renderer';
2426

@@ -136,9 +138,21 @@ export class MatRipple implements OnInit, OnDestroy, RippleTarget {
136138
platform: Platform,
137139
@Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) globalOptions?: RippleGlobalOptions,
138140
@Optional() @Inject(ANIMATION_MODULE_TYPE) private _animationMode?: string,
141+
private _styleLoader?: _CdkPrivateStyleLoader,
139142
) {
140143
this._globalOptions = globalOptions || {};
141-
this._rippleRenderer = new RippleRenderer(this, ngZone, _elementRef, platform);
144+
145+
if (!this._styleLoader) {
146+
this._styleLoader = inject(_CdkPrivateStyleLoader);
147+
}
148+
149+
this._rippleRenderer = new RippleRenderer(
150+
this,
151+
ngZone,
152+
_elementRef,
153+
platform,
154+
this._styleLoader,
155+
);
142156
}
143157

144158
ngOnInit() {

src/material/list/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ ng_module(
2626
"//src:dev_mode_types",
2727
"//src/cdk/coercion",
2828
"//src/cdk/collections",
29+
"//src/cdk/private",
2930
"//src/cdk/observers",
3031
"//src/material/core",
3132
"//src/material/divider",

src/material/list/list-base.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
RippleRenderer,
3030
RippleTarget,
3131
} from '@angular/material/core';
32+
import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
3233
import {Subscription, merge} from 'rxjs';
3334
import {
3435
MatListItemLine,
@@ -223,6 +224,7 @@ export abstract class MatListItemBase implements AfterViewInit, OnDestroy, Rippl
223224
this._ngZone,
224225
this._hostElement,
225226
this._platform,
227+
inject(_CdkPrivateStyleLoader),
226228
);
227229
this._rippleRenderer.setupTriggerEvents(this._hostElement);
228230
}

tools/public_api_guard/material/core.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import { AbstractControl } from '@angular/forms';
88
import { AfterViewChecked } from '@angular/core';
9+
import { _CdkPrivateStyleLoader } from '@angular/cdk/private';
910
import { ChangeDetectorRef } from '@angular/core';
1011
import { ElementRef } from '@angular/core';
1112
import { EventEmitter } from '@angular/core';
@@ -372,7 +373,7 @@ export type MatPseudoCheckboxState = 'unchecked' | 'checked' | 'indeterminate';
372373

373374
// @public (undocumented)
374375
export class MatRipple implements OnInit, OnDestroy, RippleTarget {
375-
constructor(_elementRef: ElementRef<HTMLElement>, ngZone: NgZone, platform: Platform, globalOptions?: RippleGlobalOptions, _animationMode?: string | undefined);
376+
constructor(_elementRef: ElementRef<HTMLElement>, ngZone: NgZone, platform: Platform, globalOptions?: RippleGlobalOptions, _animationMode?: string | undefined, _styleLoader?: _CdkPrivateStyleLoader | undefined);
376377
animation: RippleAnimationConfig;
377378
centered: boolean;
378379
color: string;
@@ -396,7 +397,7 @@ export class MatRipple implements OnInit, OnDestroy, RippleTarget {
396397
// (undocumented)
397398
static ɵdir: i0.ɵɵDirectiveDeclaration<MatRipple, "[mat-ripple], [matRipple]", ["matRipple"], { "color": { "alias": "matRippleColor"; "required": false; }; "unbounded": { "alias": "matRippleUnbounded"; "required": false; }; "centered": { "alias": "matRippleCentered"; "required": false; }; "radius": { "alias": "matRippleRadius"; "required": false; }; "animation": { "alias": "matRippleAnimation"; "required": false; }; "disabled": { "alias": "matRippleDisabled"; "required": false; }; "trigger": { "alias": "matRippleTrigger"; "required": false; }; }, {}, never, never, true, never>;
398399
// (undocumented)
399-
static ɵfac: i0.ɵɵFactoryDeclaration<MatRipple, [null, null, null, { optional: true; }, { optional: true; }]>;
400+
static ɵfac: i0.ɵɵFactoryDeclaration<MatRipple, [null, null, null, { optional: true; }, { optional: true; }, null]>;
400401
}
401402

402403
// @public
@@ -560,7 +561,7 @@ export class RippleRef {
560561

561562
// @public
562563
export class RippleRenderer implements EventListenerObject {
563-
constructor(_target: RippleTarget, _ngZone: NgZone, elementOrElementRef: HTMLElement | ElementRef<HTMLElement>, _platform: Platform);
564+
constructor(_target: RippleTarget, _ngZone: NgZone, elementOrElementRef: HTMLElement | ElementRef<HTMLElement>, _platform: Platform, styleLoader: _CdkPrivateStyleLoader);
564565
fadeInRipple(x: number, y: number, config?: RippleConfig): RippleRef;
565566
fadeOutAll(): void;
566567
fadeOutAllNonPersistent(): void;

0 commit comments

Comments
 (0)