77 */
88
99import { FocusMonitor , FocusOrigin } from '@angular/cdk/a11y' ;
10+ import { coerceBooleanProperty } from '@angular/cdk/coercion' ;
1011import { Platform } from '@angular/cdk/platform' ;
1112import {
1213 AfterViewInit ,
1314 Directive ,
1415 ElementRef ,
1516 inject ,
1617 NgZone ,
17- OnChanges ,
1818 OnDestroy ,
1919 OnInit ,
2020} from '@angular/core' ;
@@ -26,8 +26,8 @@ import {
2626 mixinColor ,
2727 mixinDisabled ,
2828 mixinDisableRipple ,
29+ MatRippleLoader ,
2930} from '@angular/material/core' ;
30- import { MAT_BUTTON_RIPPLE_UNINITIALIZED , MatButtonLazyLoader } from './button-lazy-loader' ;
3131
3232/** Inputs common to all buttons. */
3333export const MAT_BUTTON_INPUTS = [ 'disabled' , 'disableRipple' , 'color' ] ;
@@ -43,7 +43,6 @@ export const MAT_BUTTON_HOST = {
4343 // Add a class that applies to all buttons. This makes it easier to target if somebody
4444 // wants to target all Material buttons.
4545 '[class.mat-mdc-button-base]' : 'true' ,
46- [ MAT_BUTTON_RIPPLE_UNINITIALIZED ] : '' ,
4746} ;
4847
4948/** List of classes to add to buttons instances based on host attribute selector. */
@@ -94,15 +93,15 @@ export const _MatButtonMixin = mixinColor(
9493@Directive ( )
9594export class MatButtonBase
9695 extends _MatButtonMixin
97- implements CanDisable , CanColor , CanDisableRipple , AfterViewInit , OnChanges , OnDestroy
96+ implements CanDisable , CanColor , CanDisableRipple , AfterViewInit , OnDestroy
9897{
9998 private readonly _focusMonitor = inject ( FocusMonitor ) ;
10099
101100 /**
102101 * Handles the lazy creation of the MatButton ripple.
103102 * Used to improve initial load time of large applications.
104103 */
105- _rippleLoader : MatButtonLazyLoader = inject ( MatButtonLazyLoader ) ;
104+ _rippleLoader : MatRippleLoader = inject ( MatRippleLoader ) ;
106105
107106 /** Whether this button is a FAB. Used to apply the correct class on the ripple. */
108107 _isFab = false ;
@@ -113,17 +112,33 @@ export class MatButtonBase
113112 * @breaking -change 17.0.0
114113 */
115114 get ripple ( ) : MatRipple {
116- if ( ! this . _ripple && this . _rippleLoader ) {
117- this . _ripple = this . _rippleLoader . _createMatRipple ( this . _elementRef . nativeElement ) ;
118- }
119- return this . _ripple ! ;
115+ return this . _rippleLoader ?. getRipple ( this . _elementRef . nativeElement ) ! ;
120116 }
121117 set ripple ( v : MatRipple ) {
122- this . _ripple = v ;
118+ this . _rippleLoader ?. attachRipple ( this . _elementRef . nativeElement , v ) ;
123119 }
124120
125- /** @docs -private Reference to the MatRipple instance of the button. */
126- protected _ripple ?: MatRipple ;
121+ // We override `disableRipple` and `disabled` so we can hook into
122+ // their setters and update the ripple disabled state accordingly.
123+
124+ /** Whether the ripple effect is disabled or not. */
125+ override get disableRipple ( ) : boolean {
126+ return this . _disableRipple ;
127+ }
128+ override set disableRipple ( value : any ) {
129+ this . _disableRipple = coerceBooleanProperty ( value ) ;
130+ this . _updateRippleDisabled ( ) ;
131+ }
132+ private _disableRipple : boolean = false ;
133+
134+ override get disabled ( ) : boolean {
135+ return this . _disabled ;
136+ }
137+ override set disabled ( value : any ) {
138+ this . _disabled = coerceBooleanProperty ( value ) ;
139+ this . _updateRippleDisabled ( ) ;
140+ }
141+ private _disabled : boolean = false ;
127142
128143 constructor (
129144 elementRef : ElementRef ,
@@ -133,6 +148,10 @@ export class MatButtonBase
133148 ) {
134149 super ( elementRef ) ;
135150
151+ this . _rippleLoader ?. configureRipple ( this . _elementRef . nativeElement , {
152+ className : 'mat-mdc-button-ripple' ,
153+ } ) ;
154+
136155 const classList = ( elementRef . nativeElement as HTMLElement ) . classList ;
137156
138157 // For each of the variant selectors that is present in the button's host
@@ -150,12 +169,6 @@ export class MatButtonBase
150169 this . _focusMonitor . monitor ( this . _elementRef , true ) ;
151170 }
152171
153- ngOnChanges ( ) {
154- if ( this . _ripple ) {
155- this . _ripple . disabled = this . disableRipple || this . disabled ;
156- }
157- }
158-
159172 ngOnDestroy ( ) {
160173 this . _focusMonitor . stopMonitoring ( this . _elementRef ) ;
161174 }
@@ -173,6 +186,13 @@ export class MatButtonBase
173186 private _hasHostAttributes ( ...attributes : string [ ] ) {
174187 return attributes . some ( attribute => this . _elementRef . nativeElement . hasAttribute ( attribute ) ) ;
175188 }
189+
190+ private _updateRippleDisabled ( ) : void {
191+ this . _rippleLoader ?. setDisabled (
192+ this . _elementRef . nativeElement ,
193+ this . disableRipple || this . disabled ,
194+ ) ;
195+ }
176196}
177197
178198/** Shared inputs by buttons using the `<a>` tag */
@@ -195,7 +215,6 @@ export const MAT_ANCHOR_HOST = {
195215 // Add a class that applies to all buttons. This makes it easier to target if somebody
196216 // wants to target all Material buttons.
197217 '[class.mat-mdc-button-base]' : 'true' ,
198- [ MAT_BUTTON_RIPPLE_UNINITIALIZED ] : '' ,
199218} ;
200219
201220/**
0 commit comments