Skip to content

Commit 744e726

Browse files
committed
fix(multiple): stop exposing internal ripple implementation
Removes the code that exposes the ripple implementations of some components since they are internal details and they require some hacky workarounds to keep exposed. BREAKING CHANGES: * `MatButton.ripple` is no longer available. * `MatCheckbox.ripple` is no longer available. * `MatChip.ripple` is no longer available.
1 parent cb1450f commit 744e726

File tree

11 files changed

+5
-184
lines changed

11 files changed

+5
-184
lines changed

src/material/button/button-base.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -93,22 +93,10 @@ export class MatButtonBase implements AfterViewInit, OnDestroy {
9393
* Handles the lazy creation of the MatButton ripple.
9494
* Used to improve initial load time of large applications.
9595
*/
96-
_rippleLoader: MatRippleLoader = inject(MatRippleLoader);
96+
protected _rippleLoader: MatRippleLoader = inject(MatRippleLoader);
9797

9898
/** Whether this button is a FAB. Used to apply the correct class on the ripple. */
99-
_isFab = false;
100-
101-
/**
102-
* Reference to the MatRipple instance of the button.
103-
* @deprecated Considered an implementation detail. To be removed.
104-
* @breaking-change 17.0.0
105-
*/
106-
get ripple(): MatRipple {
107-
return this._rippleLoader?.getRipple(this._elementRef.nativeElement)!;
108-
}
109-
set ripple(v: MatRipple) {
110-
this._rippleLoader?.attachRipple(this._elementRef.nativeElement, v);
111-
}
99+
protected _isFab = false;
112100

113101
/**
114102
* Theme color of the button. This API is supported in M2 themes only, it has

src/material/button/button.spec.ts

Lines changed: 2 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import {createMouseEvent, dispatchEvent} from '@angular/cdk/testing/private';
2-
import {ApplicationRef, Component, DebugElement} from '@angular/core';
2+
import {ApplicationRef, Component} from '@angular/core';
33
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
4-
import {MatRipple, ThemePalette} from '@angular/material/core';
4+
import {ThemePalette} from '@angular/material/core';
55
import {By} from '@angular/platform-browser';
66
import {
77
MAT_BUTTON_CONFIG,
88
MAT_FAB_DEFAULT_OPTIONS,
9-
MatButton,
109
MatButtonModule,
1110
MatFabDefaultOptions,
1211
} from './index';
@@ -62,14 +61,6 @@ describe('MatButton', () => {
6261
expect(anchor.classList).toContain('mat-mdc-button-disabled');
6362
});
6463

65-
it('should expose the ripple instance', () => {
66-
const fixture = TestBed.createComponent(TestApp);
67-
fixture.detectChanges();
68-
69-
const button = fixture.debugElement.query(By.directive(MatButton))!.componentInstance;
70-
expect(button.ripple).toBeTruthy();
71-
});
72-
7364
it('should not clear previous defined classes', () => {
7465
let fixture = TestBed.createComponent(TestApp);
7566
let testComponent = fixture.debugElement.componentInstance;
@@ -287,86 +278,6 @@ describe('MatButton', () => {
287278
});
288279
});
289280

290-
// Ripple tests.
291-
describe('button ripples', () => {
292-
let fixture: ComponentFixture<TestApp>;
293-
let testComponent: TestApp;
294-
let buttonDebugElement: DebugElement;
295-
let buttonRippleInstance: MatRipple;
296-
let anchorDebugElement: DebugElement;
297-
let anchorRippleInstance: MatRipple;
298-
299-
beforeEach(() => {
300-
fixture = TestBed.createComponent(TestApp);
301-
fixture.detectChanges();
302-
303-
testComponent = fixture.componentInstance;
304-
305-
buttonDebugElement = fixture.debugElement.query(By.css('button[mat-button]'))!;
306-
buttonRippleInstance = buttonDebugElement.componentInstance.ripple;
307-
308-
anchorDebugElement = fixture.debugElement.query(By.css('a[mat-button]'))!;
309-
anchorRippleInstance = anchorDebugElement.componentInstance.ripple;
310-
});
311-
312-
it('should disable the ripple if matRippleDisabled input is set', () => {
313-
expect(buttonRippleInstance.disabled).toBeFalsy();
314-
315-
testComponent.rippleDisabled = true;
316-
fixture.changeDetectorRef.markForCheck();
317-
fixture.detectChanges();
318-
319-
expect(buttonRippleInstance.disabled).toBeTruthy();
320-
});
321-
322-
it('should disable the ripple when the button is disabled', () => {
323-
expect(buttonRippleInstance.disabled).toBeFalsy(
324-
'Expected an enabled button[mat-button] to have an enabled ripple',
325-
);
326-
expect(anchorRippleInstance.disabled).toBeFalsy(
327-
'Expected an enabled a[mat-button] to have an enabled ripple',
328-
);
329-
330-
testComponent.isDisabled = true;
331-
fixture.changeDetectorRef.markForCheck();
332-
fixture.detectChanges();
333-
334-
expect(buttonRippleInstance.disabled).toBeTruthy(
335-
'Expected a disabled button[mat-button] not to have an enabled ripple',
336-
);
337-
expect(anchorRippleInstance.disabled).toBeTruthy(
338-
'Expected a disabled a[mat-button] not to have an enabled ripple',
339-
);
340-
});
341-
342-
it('should render the ripple once it is referenced', () => {
343-
const fab = fixture.debugElement.query(By.css('button[mat-fab]'))!;
344-
let ripple = fab.nativeElement.querySelector('.mat-mdc-button-ripple');
345-
expect(ripple).withContext('Expect ripple to be absent before user interaction').toBeNull();
346-
347-
// Referencing the ripple should instantiate the ripple.
348-
expect(fab.componentInstance.ripple).toBeDefined();
349-
350-
ripple = fab.nativeElement.querySelector('.mat-mdc-button-ripple');
351-
expect(ripple)
352-
.withContext('Expect ripple to be present after user interaction')
353-
.not.toBeNull();
354-
});
355-
356-
// Ensure each of these events triggers the initialization of the button ripple.
357-
for (const event of ['mousedown', 'touchstart', 'mouseenter', 'focus']) {
358-
it(`should render the ripple once a button has received a "${event}" event`, () => {
359-
const fab = fixture.debugElement.query(By.css('button[mat-fab]'))!;
360-
let ripple = fab.nativeElement.querySelector('.mat-mdc-button-ripple');
361-
expect(ripple).toBeNull();
362-
363-
dispatchEvent(fab.nativeElement, createMouseEvent(event));
364-
ripple = fab.nativeElement.querySelector('.mat-mdc-button-ripple');
365-
expect(ripple).not.toBeNull();
366-
});
367-
}
368-
});
369-
370281
it('should have a focus indicator', () => {
371282
const fixture = TestBed.createComponent(TestApp);
372283
const buttonNativeElements = [

src/material/checkbox/checkbox.spec.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ describe('MatCheckbox', () => {
6767
expect(inputElement.checked).toBe(false);
6868
}));
6969

70-
it('should expose the ripple instance', () => {
71-
expect(checkboxInstance.ripple).toBeTruthy();
72-
});
73-
7470
it('should hide the internal SVG', () => {
7571
const svg = checkboxNativeElement.querySelector('svg')!;
7672
expect(svg.getAttribute('aria-hidden')).toBe('true');

src/material/checkbox/checkbox.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,6 @@ export class MatCheckbox
216216
@Input({transform: booleanAttribute})
217217
disabledInteractive: boolean;
218218

219-
/**
220-
* Reference to the MatRipple instance of the checkbox.
221-
* @deprecated Considered an implementation detail. To be removed.
222-
* @breaking-change 17.0.0
223-
*/
224-
@ViewChild(MatRipple) ripple: MatRipple;
225-
226219
/**
227220
* Called when the checkbox is blurred. Needed to properly implement ControlValueAccessor.
228221
* @docs-private

src/material/chips/chip.spec.ts

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,6 @@ describe('MatChip', () => {
6565

6666
expect(chip.getAttribute('tabindex')).toBe('15');
6767
});
68-
69-
it('should have its ripple disabled', () => {
70-
fixture = TestBed.createComponent(BasicChip);
71-
fixture.detectChanges();
72-
chipDebugElement = fixture.debugElement.query(By.directive(MatChip))!;
73-
chipInstance = chipDebugElement.injector.get<MatChip>(MatChip);
74-
expect(chipInstance.ripple.disabled)
75-
.withContext('Expected basic chip ripples to be disabled.')
76-
.toBe(true);
77-
});
7868
});
7969

8070
describe('MatChip', () => {
@@ -131,34 +121,6 @@ describe('MatChip', () => {
131121
expect(testComponent.chipRemove).toHaveBeenCalledWith({chip: chipInstance});
132122
});
133123

134-
it('should be able to disable ripples with the `[rippleDisabled]` input', () => {
135-
expect(chipInstance.ripple.disabled)
136-
.withContext('Expected chip ripples to be enabled.')
137-
.toBe(false);
138-
139-
testComponent.rippleDisabled = true;
140-
fixture.changeDetectorRef.markForCheck();
141-
fixture.detectChanges();
142-
143-
expect(chipInstance.ripple.disabled)
144-
.withContext('Expected chip ripples to be disabled.')
145-
.toBe(true);
146-
});
147-
148-
it('should disable ripples when the chip is disabled', () => {
149-
expect(chipInstance.ripple.disabled)
150-
.withContext('Expected chip ripples to be enabled.')
151-
.toBe(false);
152-
153-
testComponent.disabled = true;
154-
fixture.changeDetectorRef.markForCheck();
155-
fixture.detectChanges();
156-
157-
expect(chipInstance.ripple.disabled)
158-
.withContext('Expected chip ripples to be disabled.')
159-
.toBe(true);
160-
});
161-
162124
it('should make disabled chips non-focusable', () => {
163125
testComponent.disabled = true;
164126
fixture.changeDetectorRef.markForCheck();

src/material/chips/chip.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -216,26 +216,14 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck
216216
/** The chip's trailing remove icon. */
217217
@ContentChild(MAT_CHIP_REMOVE) removeIcon: MatChipRemove;
218218

219-
/**
220-
* Reference to the MatRipple instance of the chip.
221-
* @deprecated Considered an implementation detail. To be removed.
222-
* @breaking-change 17.0.0
223-
*/
224-
get ripple(): MatRipple {
225-
return this._rippleLoader?.getRipple(this._elementRef.nativeElement)!;
226-
}
227-
set ripple(v: MatRipple) {
228-
this._rippleLoader?.attachRipple(this._elementRef.nativeElement, v);
229-
}
230-
231219
/** Action receiving the primary set of user interactions. */
232220
@ViewChild(MatChipAction) primaryAction: MatChipAction;
233221

234222
/**
235223
* Handles the lazy creation of the MatChip ripple.
236224
* Used to improve initial load time of large applications.
237225
*/
238-
_rippleLoader: MatRippleLoader = inject(MatRippleLoader);
226+
private _rippleLoader: MatRippleLoader = inject(MatRippleLoader);
239227

240228
protected _injector = inject(Injector);
241229

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,6 @@ export class MatRippleLoader implements OnDestroy {
109109
}
110110
}
111111

112-
/** Returns the ripple instance for the given host element. */
113-
getRipple(host: HTMLElement): MatRipple | undefined {
114-
const ripple = this._hosts.get(host);
115-
return ripple || this._createRipple(host);
116-
}
117-
118112
/** Sets the disabled state on the ripple instance corresponding to the given host element. */
119113
setDisabled(host: HTMLElement, disabled: boolean): void {
120114
const ripple = this._hosts.get(host);

tools/public_api_guard/material/button.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { FocusOrigin } from '@angular/cdk/a11y';
1010
import * as i0 from '@angular/core';
1111
import * as i1 from '@angular/material/core';
1212
import { InjectionToken } from '@angular/core';
13-
import { MatRipple } from '@angular/material/core';
1413
import { MatRippleLoader } from '@angular/material/core';
1514
import { NgZone } from '@angular/core';
1615
import { OnDestroy } from '@angular/core';

tools/public_api_guard/material/checkbox.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { FocusableOption } from '@angular/cdk/a11y';
1515
import * as i0 from '@angular/core';
1616
import * as i3 from '@angular/material/core';
1717
import { InjectionToken } from '@angular/core';
18-
import { MatRipple } from '@angular/material/core';
1918
import { NgZone } from '@angular/core';
2019
import { OnChanges } from '@angular/core';
2120
import { Provider } from '@angular/core';
@@ -114,8 +113,6 @@ export class MatCheckbox implements AfterViewInit, OnChanges, ControlValueAccess
114113
// (undocumented)
115114
registerOnValidatorChange(fn: () => void): void;
116115
required: boolean;
117-
// @deprecated
118-
ripple: MatRipple;
119116
// (undocumented)
120117
setDisabledState(isDisabled: boolean): void;
121118
tabIndex: number;

tools/public_api_guard/material/chips.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ import { InjectionToken } from '@angular/core';
2222
import { Injector } from '@angular/core';
2323
import { MatFormField } from '@angular/material/form-field';
2424
import { MatFormFieldControl } from '@angular/material/form-field';
25-
import { MatRipple } from '@angular/material/core';
26-
import { MatRippleLoader } from '@angular/material/core';
2725
import { NgControl } from '@angular/forms';
2826
import { NgForm } from '@angular/forms';
2927
import { NgZone } from '@angular/core';
@@ -116,10 +114,6 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck
116114
remove(): void;
117115
readonly removed: EventEmitter<MatChipEvent>;
118116
removeIcon: MatChipRemove;
119-
// @deprecated
120-
get ripple(): MatRipple;
121-
set ripple(v: MatRipple);
122-
_rippleLoader: MatRippleLoader;
123117
role: string | null;
124118
trailingIcon: MatChipTrailingIcon;
125119
get value(): any;

0 commit comments

Comments
 (0)