Skip to content

feat(material-experimental/mdc-button): fix ripples #16773

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/material-experimental/mdc-button/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ng_module(
deps = [
"//src/cdk/platform",
"//src/material/core",
"@npm//@material/ripple",
],
)

Expand Down Expand Up @@ -105,6 +106,7 @@ ng_test_library(

ng_web_test_suite(
name = "unit_tests",
static_files = ["@npm//:node_modules/@material/ripple/dist/mdc.ripple.js"],
deps = [
":button_tests_lib",
"//src/material-experimental:mdc_require_config.js",
Expand Down
40 changes: 14 additions & 26 deletions src/material-experimental/mdc-button/button-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import {Platform} from '@angular/cdk/platform';
import {ElementRef, NgZone, OnChanges, SimpleChanges} from '@angular/core';
import {ElementRef, NgZone} from '@angular/core';
import {
CanColor,
CanColorCtor,
Expand All @@ -18,9 +18,9 @@ import {
mixinColor,
mixinDisabled,
mixinDisableRipple,
RippleRenderer,
RippleTarget
RippleAnimationConfig
} from '@angular/material/core';
import {numbers} from '@material/ripple';

/** Inputs common to all buttons. */
export const MAT_BUTTON_INPUTS = ['disabled', 'disableRipple', 'color'];
Expand Down Expand Up @@ -74,30 +74,20 @@ export const _MatButtonBaseMixin: CanDisableRippleCtor&CanDisableCtor&CanColorCt

/** Base class for all buttons. */
export class MatButtonBase extends _MatButtonBaseMixin implements CanDisable, CanColor,
CanDisableRipple, OnChanges {
rippleTarget: RippleTarget = {
rippleConfig: {
animation: {
// TODO(mmalerba): Use the MDC constants once they are exported separately from the
// foundation. Grabbing them off the foundation prevents the foundation class from being
// tree-shaken. There is an open PR for this:
// https://github.com/material-components/material-components-web/pull/4593
enterDuration: 225 /* MDCRippleFoundation.numbers.DEACTIVATION_TIMEOUT_MS */,
exitDuration: 150 /* MDCRippleFoundation.numbers.FG_DEACTIVATION_MS */,
},
},
rippleDisabled: false,
CanDisableRipple {
/** The ripple animation configuration to use for the buttons. */
_rippleAnimation: RippleAnimationConfig = {
enterDuration: numbers.DEACTIVATION_TIMEOUT_MS,
exitDuration: numbers.FG_DEACTIVATION_MS
};

/** The ripple renderer for the button. */
private _rippleRenderer =
new RippleRenderer(this.rippleTarget, this._ngZone, this._elementRef, this._platform);
/** Whether the ripple is centered on the button. */
_isRippleCentered = false;

constructor(
elementRef: ElementRef, public _platform: Platform, public _ngZone: NgZone,
public _animationMode?: string) {
super(elementRef);
this._rippleRenderer.setupTriggerEvents(this._elementRef.nativeElement);

// For each of the variant selectors that is present in the button's host
// attributes, add the correct corresponding MDC classes.
Expand All @@ -108,12 +98,6 @@ export class MatButtonBase extends _MatButtonBaseMixin implements CanDisable, Ca
}
}

ngOnChanges(simpleChanges: SimpleChanges) {
if (simpleChanges['disableRipple'] || simpleChanges['disabled']) {
this.rippleTarget.rippleDisabled = this.disableRipple || this.disabled;
}
}

/** Focuses the button. */
focus(): void {
this._elementRef.nativeElement.focus();
Expand All @@ -123,6 +107,10 @@ export class MatButtonBase extends _MatButtonBaseMixin implements CanDisable, Ca
private _hasHostAttributes(...attributes: string[]) {
return attributes.some(attribute => this._elementRef.nativeElement.hasAttribute(attribute));
}

_isRippleDisabled() {
return this.disableRipple || this.disabled;
}
}

/** Shared inputs by buttons using the `<a>` tag */
Expand Down
6 changes: 6 additions & 0 deletions src/material-experimental/mdc-button/button.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@

<ng-content select=".material-icons[iconPositionEnd], mat-icon[iconPositionEnd]">
</ng-content>

<div matRipple class="mat-button-ripple"
[matRippleAnimation]="_rippleAnimation"
[matRippleDisabled]="_isRippleDisabled()"
[matRippleCentered]="_isRippleCentered"
[matRippleTrigger]="_elementRef.nativeElement"></div>
9 changes: 0 additions & 9 deletions src/material-experimental/mdc-button/button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,7 @@

@include mdc-button-without-ripple($query: $mat-base-styles-query);

$_mat-button-ripple-opacity: 0.1;

.mat-mdc-button, .mat-mdc-unelevated-button, .mat-mdc-raised-button, .mat-mdc-outlined-button {
// The ripple element is created from the RippleRenderer rather than the MDC ripple, so it is
// necessary to provide the color and opacity styling manually.
.mat-ripple-element {
opacity: $_mat-button-ripple-opacity;
background-color: currentColor;
}

// Add an outline to make buttons more visible in high contrast mode. Stroked buttons
// don't need a special look in high-contrast mode, because those already have an outline.
@include cdk-high-contrast {
Expand Down
11 changes: 0 additions & 11 deletions src/material-experimental/mdc-button/fab.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,6 @@

@include mdc-fab-without-ripple($query: $mat-base-styles-query);

$_mat-button-ripple-opacity: 0.1;

.mat-mdc-fab, .mat-mdc-mini-fab {
// The ripple element is created from the RippleRenderer rather than the MDC ripple, so it is
// necessary to provide the color and opacity styling manually.
.mat-ripple-element {
opacity: $_mat-button-ripple-opacity;
background-color: currentColor;
}
}

// MDC expects the fab icon to contain this HTML content:
// ```html
// <span class="mdc-fab__icon material-icons">favorite</span>
Expand Down
10 changes: 2 additions & 8 deletions src/material-experimental/mdc-button/icon-button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@

@include mdc-icon-button-without-ripple($query: $mat-base-styles-query);

$_mat-button-ripple-opacity: 0.1;

.mat-mdc-icon-button {
// The ripple element is created from the RippleRenderer rather than the MDC ripple, so it is
// necessary to provide the color and opacity styling manually.
.mat-ripple-element {
opacity: $_mat-button-ripple-opacity;
background-color: currentColor;
}
// Border radius is inherited by ripple to know its shape. Set to 50% so the ripple is round.
border-radius: 50%;
}
8 changes: 4 additions & 4 deletions src/material-experimental/mdc-button/icon-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ import {
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MatIconButton extends MatButtonBase {
_isRippleCentered = true;

constructor(
elementRef: ElementRef, platform: Platform, ngZone: NgZone,
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string) {
super(elementRef, platform, ngZone, animationMode);
this.rippleTarget.rippleConfig.centered = true;
this.rippleTarget.rippleConfig.radius = 24;
}
}

Expand All @@ -61,11 +61,11 @@ export class MatIconButton extends MatButtonBase {
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MatIconAnchor extends MatAnchorBase {
_isRippleCentered = true;

constructor(
elementRef: ElementRef, platform: Platform, ngZone: NgZone,
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string) {
super(elementRef, platform, ngZone, animationMode);
this.rippleTarget.rippleConfig.centered = true;
this.rippleTarget.rippleConfig.radius = 24;
}
}
4 changes: 2 additions & 2 deletions src/material-experimental/mdc-button/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {MatCommonModule} from '@angular/material/core';
import {MatCommonModule, MatRippleModule} from '@angular/material/core';
import {MatAnchor, MatButton} from './button';
import {MatFabAnchor, MatFabButton} from './fab';
import {MatIconAnchor, MatIconButton} from './icon-button';

@NgModule({
imports: [MatCommonModule, CommonModule],
imports: [MatCommonModule, CommonModule, MatRippleModule],
exports: [
MatAnchor,
MatButton,
Expand Down