Skip to content

Commit

Permalink
fix(material/core): avoid having to manually load ripple styles
Browse files Browse the repository at this point in the history
Makes it so the ripple loads the necessary styles itself, instead of requiring the user to do it.

BREAKING CHANGE:
* The ripples styles are now loaded slightly later than before which can change their specificity. You may have to update any ripple style overrides.
  • Loading branch information
crisbeto committed Aug 25, 2024
1 parent fcb76d3 commit 855ed49
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 8 deletions.
8 changes: 8 additions & 0 deletions src/material/core/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ ng_module(
":option/option.css",
":option/optgroup.css",
":internal-form-field/internal-form-field.css",
":ripple/ripple-structure.css",
] + glob(["**/*.html"]),
deps = [
"//src:dev_mode_types",
Expand All @@ -33,6 +34,7 @@ ng_module(
"//src/cdk/coercion",
"//src/cdk/keycodes",
"//src/cdk/platform",
"//src/cdk/private",
"@npm//@angular/animations",
"@npm//@angular/core",
"@npm//@angular/forms",
Expand Down Expand Up @@ -94,6 +96,12 @@ sass_binary(
deps = [":core_scss_lib"],
)

sass_binary(
name = "ripple_structure_scss",
src = "ripple/ripple-structure.scss",
deps = [":core_scss_lib"],
)

# M3 themes
sass_binary(
name = "azure_blue_prebuilt",
Expand Down
2 changes: 0 additions & 2 deletions src/material/core/_core.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
@use '@angular/cdk';
@use './tokens/m2/mat/app' as tokens-mat-app;
@use './tokens/token-utils';
@use './ripple/ripple';
@use './style/elevation';
@use './focus-indicators/private';

Expand All @@ -15,7 +14,6 @@
--mat-app-on-surface: initial;
}

@include ripple.ripple();
@include cdk.a11y-visually-hidden();
@include cdk.overlay();
@include cdk.text-field-autosize();
Expand Down
1 change: 1 addition & 0 deletions src/material/core/private/ripple-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
defaultRippleAnimationConfig,
} from '../ripple';
import {Platform, _getEventTarget} from '@angular/cdk/platform';
import {_CdkPrivateStyleLoader} from '@angular/cdk/private';

/** The options for the MatRippleLoader's event listeners. */
const eventListenerOptions = {capture: true};
Expand Down
2 changes: 1 addition & 1 deletion src/material/core/ripple/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {MatRipple} from './ripple';

export * from './ripple';
export * from './ripple-ref';
export * from './ripple-renderer';
export {RippleRenderer, RippleTarget, defaultRippleAnimationConfig} from './ripple-renderer';

@NgModule({
imports: [MatCommonModule, MatRipple],
Expand Down
25 changes: 24 additions & 1 deletion src/material/core/ripple/ripple-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {ElementRef, NgZone} from '@angular/core';
import {
ElementRef,
NgZone,
Component,
ChangeDetectionStrategy,
ViewEncapsulation,
Injector,
} from '@angular/core';
import {Platform, normalizePassiveListenerOptions, _getEventTarget} from '@angular/cdk/platform';
import {isFakeMousedownFromScreenReader, isFakeTouchstartFromScreenReader} from '@angular/cdk/a11y';
import {coerceElement} from '@angular/cdk/coercion';
import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
import {RippleRef, RippleState, RippleConfig} from './ripple-ref';
import {RippleEventManager} from './ripple-event-manager';

Expand Down Expand Up @@ -58,6 +66,16 @@ const pointerDownEvents = ['mousedown', 'touchstart'];
/** Events that signal that the pointer is up. */
const pointerUpEvents = ['mouseup', 'mouseleave', 'touchend', 'touchcancel'];

@Component({
template: '',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
standalone: true,
styleUrl: 'ripple-structure.css',
host: {'mat-ripple-style-loader': ''},
})
export class _MatRippleStylesLoader {}

/**
* Helper service that performs DOM manipulations. Not intended to be used outside this module.
* The constructor takes a reference to the ripple directive's host element and a map of DOM
Expand Down Expand Up @@ -105,11 +123,16 @@ export class RippleRenderer implements EventListenerObject {
private _ngZone: NgZone,
elementOrElementRef: HTMLElement | ElementRef<HTMLElement>,
private _platform: Platform,
injector?: Injector,
) {
// Only do anything if we're on the browser.
if (_platform.isBrowser) {
this._containerElement = coerceElement(elementOrElementRef);
}

if (injector) {
injector.get(_CdkPrivateStyleLoader).load(_MatRippleStylesLoader);
}
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/material/core/ripple/ripple-structure.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@use './ripple';

@include ripple.ripple;
7 changes: 6 additions & 1 deletion src/material/core/ripple/ripple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import {
OnInit,
Optional,
ANIMATION_MODULE_TYPE,
Injector,
} from '@angular/core';
import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
import {RippleAnimationConfig, RippleConfig, RippleRef} from './ripple-ref';
import {RippleRenderer, RippleTarget} from './ripple-renderer';

Expand Down Expand Up @@ -136,9 +138,12 @@ export class MatRipple implements OnInit, OnDestroy, RippleTarget {
platform: Platform,
@Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) globalOptions?: RippleGlobalOptions,
@Optional() @Inject(ANIMATION_MODULE_TYPE) private _animationMode?: string,
injector?: Injector,
) {
// Note: cannot use `inject()` here, because this class
// gets instantiated manually in the ripple loader.
this._globalOptions = globalOptions || {};
this._rippleRenderer = new RippleRenderer(this, ngZone, _elementRef, platform);
this._rippleRenderer = new RippleRenderer(this, ngZone, _elementRef, platform, injector);
}

ngOnInit() {
Expand Down
1 change: 1 addition & 0 deletions src/material/list/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ ng_module(
"//src/cdk/coercion",
"//src/cdk/collections",
"//src/cdk/observers",
"//src/cdk/private",
"//src/material/core",
"//src/material/divider",
"@npm//@angular/core",
Expand Down
3 changes: 3 additions & 0 deletions src/material/list/list-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
Optional,
QueryList,
ANIMATION_MODULE_TYPE,
Injector,
} from '@angular/core';
import {
MAT_RIPPLE_GLOBAL_OPTIONS,
Expand All @@ -29,6 +30,7 @@ import {
RippleRenderer,
RippleTarget,
} from '@angular/material/core';
import {_CdkPrivateStyleLoader} from '@angular/cdk/private';
import {Subscription, merge} from 'rxjs';
import {
MatListItemLine,
Expand Down Expand Up @@ -223,6 +225,7 @@ export abstract class MatListItemBase implements AfterViewInit, OnDestroy, Rippl
this._ngZone,
this._hostElement,
this._platform,
inject(Injector),
);
this._rippleRenderer.setupTriggerEvents(this._hostElement);
}
Expand Down
7 changes: 4 additions & 3 deletions tools/public_api_guard/material/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { HighContrastModeDetector } from '@angular/cdk/a11y';
import * as i0 from '@angular/core';
import * as i1 from '@angular/cdk/bidi';
import { InjectionToken } from '@angular/core';
import { Injector } from '@angular/core';
import { NgControl } from '@angular/forms';
import { NgForm } from '@angular/forms';
import { NgZone } from '@angular/core';
Expand Down Expand Up @@ -372,7 +373,7 @@ export type MatPseudoCheckboxState = 'unchecked' | 'checked' | 'indeterminate';

// @public (undocumented)
export class MatRipple implements OnInit, OnDestroy, RippleTarget {
constructor(_elementRef: ElementRef<HTMLElement>, ngZone: NgZone, platform: Platform, globalOptions?: RippleGlobalOptions, _animationMode?: string | undefined);
constructor(_elementRef: ElementRef<HTMLElement>, ngZone: NgZone, platform: Platform, globalOptions?: RippleGlobalOptions, _animationMode?: string | undefined, injector?: Injector);
animation: RippleAnimationConfig;
centered: boolean;
color: string;
Expand All @@ -396,7 +397,7 @@ export class MatRipple implements OnInit, OnDestroy, RippleTarget {
// (undocumented)
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>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<MatRipple, [null, null, null, { optional: true; }, { optional: true; }]>;
static ɵfac: i0.ɵɵFactoryDeclaration<MatRipple, [null, null, null, { optional: true; }, { optional: true; }, null]>;
}

// @public
Expand Down Expand Up @@ -557,7 +558,7 @@ export class RippleRef {

// @public
export class RippleRenderer implements EventListenerObject {
constructor(_target: RippleTarget, _ngZone: NgZone, elementOrElementRef: HTMLElement | ElementRef<HTMLElement>, _platform: Platform);
constructor(_target: RippleTarget, _ngZone: NgZone, elementOrElementRef: HTMLElement | ElementRef<HTMLElement>, _platform: Platform, injector?: Injector);
fadeInRipple(x: number, y: number, config?: RippleConfig): RippleRef;
fadeOutAll(): void;
fadeOutAllNonPersistent(): void;
Expand Down

0 comments on commit 855ed49

Please sign in to comment.