Skip to content

Commit

Permalink
refactor(material/button-toggle): switch to lazy ripple rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
wagnermaciel committed Jul 19, 2023
1 parent 73ba2c0 commit c752808
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 8 deletions.
4 changes: 0 additions & 4 deletions src/material/button-toggle/button-toggle.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,3 @@
</button>

<span class="mat-button-toggle-focus-overlay"></span>
<span class="mat-button-toggle-ripple" matRipple
[matRippleTrigger]="button"
[matRippleDisabled]="this.disableRipple || this.disabled">
</span>
10 changes: 10 additions & 0 deletions src/material/button-toggle/button-toggle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,20 @@ describe('MatButtonToggle with forms', () => {
expect(testComponent.modelValue).toBe('green');
}));

it('should lazily render the mat-ripple', () => {
const groupElement = groupDebugElement.nativeElement;

expect(groupElement.querySelectorAll('.mat-ripple').length).toBe(0);
dispatchMouseEvent(innerButtons[0], 'mouseenter');
expect(groupElement.querySelectorAll('.mat-ripple').length).toBe(1);
});

it('should show a ripple on label click', () => {
const groupElement = groupDebugElement.nativeElement;

expect(groupElement.querySelectorAll('.mat-ripple-element').length).toBe(0);

dispatchMouseEvent(innerButtons[0], 'mouseenter');
dispatchMouseEvent(innerButtons[0], 'mousedown');
dispatchMouseEvent(innerButtons[0], 'mouseup');

Expand All @@ -215,6 +224,7 @@ describe('MatButtonToggle with forms', () => {

expect(groupElement.querySelectorAll('.mat-ripple-element').length).toBe(0);

dispatchMouseEvent(innerButtons[0], 'mouseenter');
dispatchMouseEvent(innerButtons[0], 'mousedown');
dispatchMouseEvent(innerButtons[0], 'mouseup');

Expand Down
27 changes: 25 additions & 2 deletions src/material/button-toggle/button-toggle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ import {
InjectionToken,
Inject,
AfterViewInit,
inject,
DoCheck,
} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import {CanDisableRipple, mixinDisableRipple} from '@angular/material/core';
import {CanDisableRipple, MatRippleLoader, mixinDisableRipple} from '@angular/material/core';

/**
* @deprecated No longer used.
Expand Down Expand Up @@ -414,7 +416,7 @@ const _MatButtonToggleBase = mixinDisableRipple(class {});
})
export class MatButtonToggle
extends _MatButtonToggleBase
implements OnInit, AfterViewInit, CanDisableRipple, OnDestroy
implements OnInit, AfterViewInit, CanDisableRipple, OnDestroy, DoCheck
{
private _checked = false;

Expand Down Expand Up @@ -495,6 +497,12 @@ export class MatButtonToggle
@Output() readonly change: EventEmitter<MatButtonToggleChange> =
new EventEmitter<MatButtonToggleChange>();

/**
* Handles the lazy creation of the MatButtonToggle ripple.
* Used to improve initial load time of large applications.
*/
_rippleLoader: MatRippleLoader = inject(MatRippleLoader);

constructor(
@Optional() @Inject(MAT_BUTTON_TOGGLE_GROUP) toggleGroup: MatButtonToggleGroup,
private _changeDetectorRef: ChangeDetectorRef,
Expand Down Expand Up @@ -533,6 +541,12 @@ export class MatButtonToggle

ngAfterViewInit() {
this._focusMonitor.monitor(this._elementRef, true);

this._rippleLoader?.configureRipple(this._elementRef.nativeElement, {
className: 'mat-button-toggle-ripple',
disabled: this.disableRipple || this.disabled,
trigger: this._buttonElement.nativeElement,
});
}

ngOnDestroy() {
Expand All @@ -547,6 +561,15 @@ export class MatButtonToggle
}
}

ngDoCheck(): void {
if (this._buttonElement) {
this._rippleLoader.setDisabled(
this._elementRef.nativeElement,
this.disableRipple || this.disabled,
);
}
}

/** Focuses the button. */
focus(options?: FocusOptions): void {
this._buttonElement.nativeElement.focus(options);
Expand Down
7 changes: 6 additions & 1 deletion src/material/core/private/ripple-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export class MatRippleLoader implements OnDestroy {
className?: string;
centered?: boolean;
disabled?: boolean;
trigger?: HTMLElement;
},
): void {
// Indicates that the ripple has not yet been rendered for this component.
Expand All @@ -94,6 +95,10 @@ export class MatRippleLoader implements OnDestroy {
if (config.disabled) {
host.setAttribute(matRippleDisabled, '');
}

if (config.trigger) {
(host as any).matRippleTrigger = config.trigger;
}
}

/** Returns the ripple instance for the given host element. */
Expand Down Expand Up @@ -159,7 +164,7 @@ export class MatRippleLoader implements OnDestroy {
this._animationMode ? this._animationMode : undefined,
);
ripple._isInitialized = true;
ripple.trigger = host;
ripple.trigger = (host as any).matRippleTrigger || host;
ripple.centered = host.hasAttribute(matRippleCentered);
ripple.disabled = host.hasAttribute(matRippleDisabled);
this.attachRipple(host, ripple);
Expand Down
7 changes: 6 additions & 1 deletion tools/public_api_guard/material/button-toggle.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import { CanDisableRipple } from '@angular/material/core';
import { ChangeDetectorRef } from '@angular/core';
import { _Constructor } from '@angular/material/core';
import { ControlValueAccessor } from '@angular/forms';
import { DoCheck } from '@angular/core';
import { ElementRef } from '@angular/core';
import { EventEmitter } from '@angular/core';
import { FocusMonitor } from '@angular/cdk/a11y';
import * as i0 from '@angular/core';
import * as i2 from '@angular/material/core';
import { InjectionToken } from '@angular/core';
import { MatRippleLoader } from '@angular/material/core';
import { OnDestroy } from '@angular/core';
import { OnInit } from '@angular/core';
import { QueryList } from '@angular/core';
Expand All @@ -32,7 +34,7 @@ export const MAT_BUTTON_TOGGLE_GROUP: InjectionToken<MatButtonToggleGroup>;
export const MAT_BUTTON_TOGGLE_GROUP_VALUE_ACCESSOR: any;

// @public
export class MatButtonToggle extends _MatButtonToggleBase implements OnInit, AfterViewInit, CanDisableRipple, OnDestroy {
export class MatButtonToggle extends _MatButtonToggleBase implements OnInit, AfterViewInit, CanDisableRipple, OnDestroy, DoCheck {
constructor(toggleGroup: MatButtonToggleGroup, _changeDetectorRef: ChangeDetectorRef, _elementRef: ElementRef<HTMLElement>, _focusMonitor: FocusMonitor, defaultTabIndex: string, defaultOptions?: MatButtonToggleDefaultOptions);
get appearance(): MatButtonToggleAppearance;
set appearance(value: MatButtonToggleAppearance);
Expand All @@ -54,10 +56,13 @@ export class MatButtonToggle extends _MatButtonToggleBase implements OnInit, Aft
// (undocumented)
ngAfterViewInit(): void;
// (undocumented)
ngDoCheck(): void;
// (undocumented)
ngOnDestroy(): void;
// (undocumented)
ngOnInit(): void;
_onButtonClick(): void;
_rippleLoader: MatRippleLoader;
tabIndex: number | null;
value: any;
// (undocumented)
Expand Down
1 change: 1 addition & 0 deletions tools/public_api_guard/material/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ export class MatRippleLoader implements OnDestroy {
className?: string;
centered?: boolean;
disabled?: boolean;
trigger?: HTMLElement;
}): void;
createRipple(host: HTMLElement): MatRipple | undefined;
getRipple(host: HTMLElement): MatRipple | undefined;
Expand Down

0 comments on commit c752808

Please sign in to comment.