diff --git a/core/src/components.d.ts b/core/src/components.d.ts
index ebc0ff8660..999ef1a898 100644
--- a/core/src/components.d.ts
+++ b/core/src/components.d.ts
@@ -3541,7 +3541,7 @@ export namespace Components {
/**
* Adds the ripple effect to the parent element
*/
- 'addRipple': (pageX: number, pageY: number) => void;
+ 'addRipple': (pageX: number, pageY: number) => Promise<() => void>;
}
interface IonRippleEffectAttributes extends StencilHTMLAttributes {}
diff --git a/core/src/components/action-sheet/action-sheet.md.scss b/core/src/components/action-sheet/action-sheet.md.scss
index da50b7a361..f87d7931e8 100644
--- a/core/src/components/action-sheet/action-sheet.md.scss
+++ b/core/src/components/action-sheet/action-sheet.md.scss
@@ -60,10 +60,6 @@
overflow: hidden;
}
-.action-sheet-button.activated {
- background: $action-sheet-md-button-background-activated;
-}
-
.action-sheet-icon {
@include padding(null, null, 4px, null);
@include margin($action-sheet-md-icon-margin-top, $action-sheet-md-icon-margin-end, $action-sheet-md-icon-margin-bottom, $action-sheet-md-icon-margin-start);
diff --git a/core/src/components/action-sheet/action-sheet.tsx b/core/src/components/action-sheet/action-sheet.tsx
index a7602fcb17..fb7656c9be 100644
--- a/core/src/components/action-sheet/action-sheet.tsx
+++ b/core/src/components/action-sheet/action-sheet.tsx
@@ -241,6 +241,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
{b.icon && }
{b.text}
+ {this.mode === 'md' && }
)}
diff --git a/core/src/components/alert/alert.md.scss b/core/src/components/alert/alert.md.scss
index 28dc7057df..5f2ee1a296 100644
--- a/core/src/components/alert/alert.md.scss
+++ b/core/src/components/alert/alert.md.scss
@@ -290,10 +290,6 @@
overflow: hidden;
}
-.alert-button.activated {
- background-color: $alert-md-button-background-color-activated;
-}
-
.alert-button-inner {
justify-content: $alert-md-button-group-justify-content;
}
diff --git a/core/src/components/alert/alert.tsx b/core/src/components/alert/alert.tsx
index 9d7b419a52..6bac0364f8 100644
--- a/core/src/components/alert/alert.tsx
+++ b/core/src/components/alert/alert.tsx
@@ -369,7 +369,6 @@ export class Alert implements ComponentInterface, OverlayInterface {
{i.label}
- {this.mode === 'md' && }
))}
@@ -429,6 +428,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
{button.text}
+ {this.mode === 'md' && }
)}
diff --git a/core/src/components/button/button.ios.scss b/core/src/components/button/button.ios.scss
index 9e04406781..351373c7fa 100644
--- a/core/src/components/button/button.ios.scss
+++ b/core/src/components/button/button.ios.scss
@@ -26,6 +26,11 @@
// iOS Solid Button
// --------------------------------------------------
+
+:host(.button-solid) {
+ --background-activated: #{ion-color(primary, shade)};
+}
+
@media (any-hover: hover) {
:host(.button-solid:hover) {
--opacity: #{$button-ios-opacity-hover};
diff --git a/core/src/components/button/button.md.scss b/core/src/components/button/button.md.scss
index 20f70ccd0c..b16279a7e3 100644
--- a/core/src/components/button/button.md.scss
+++ b/core/src/components/button/button.md.scss
@@ -31,6 +31,7 @@
// --------------------------------------------------
:host(.button-solid) {
+ --background-activated: var(--background);
--box-shadow: #{$button-md-box-shadow};
}
diff --git a/core/src/components/button/button.scss b/core/src/components/button/button.scss
index b6950840c1..9cfdc69ab5 100644
--- a/core/src/components/button/button.scss
+++ b/core/src/components/button/button.scss
@@ -73,7 +73,6 @@
// Default Solid Color
:host(.button-solid) {
--background: #{ion-color(primary, base)};
- --background-activated: #{ion-color(primary, shade)};
--background-focused: #{ion-color(primary, shade)};
--color: #{ion-color(primary, contrast)};
--color-activated: #{ion-color(primary, contrast)};
@@ -87,8 +86,7 @@
}
// Focused/Activated Solid Button with Color
-:host(.button-solid.ion-color.focused) .button-native,
-:host(.button-solid.ion-color.activated) .button-native {
+:host(.button-solid.ion-color.focused) .button-native {
background: #{current-color(shade)};
}
diff --git a/core/src/components/fab-button/fab-button.md.scss b/core/src/components/fab-button/fab-button.md.scss
index 4d4648ef56..8757d76685 100755
--- a/core/src/components/fab-button/fab-button.md.scss
+++ b/core/src/components/fab-button/fab-button.md.scss
@@ -6,7 +6,7 @@
:host {
--background: #{$fab-md-background-color};
- --background-activated: #{$fab-md-background-color-activated};
+ --background-activated: var(--background);
--background-focused: var(--background-activated);
--color: #{$fab-md-text-color};
--color-activated: #{$fab-md-text-color};
@@ -45,4 +45,4 @@
:host(.fab-button-in-list) ::slotted(ion-icon) {
font-size: $fab-md-list-button-icon-font-size;
-}
\ No newline at end of file
+}
diff --git a/core/src/components/item/item.md.scss b/core/src/components/item/item.md.scss
index 220cb60bdc..a798a6ff41 100644
--- a/core/src/components/item/item.md.scss
+++ b/core/src/components/item/item.md.scss
@@ -8,13 +8,11 @@
:host {
--min-height: #{$item-md-min-height};
--background: var(--ion-item-background, transparent);
- --background-activated: #{$item-md-background-activated};
+ --background-activated: var(--background);
--border-color: #{$item-md-border-bottom-color};
--color: #{$item-md-color};
--transition: background-color 300ms cubic-bezier(.4, 0, .2, 1);
--padding-start: #{$item-md-padding-start};
- --background: #{$item-md-background};
- --background-activated: #{$item-md-background-activated};
--color: #{$item-md-color};
--border-color: #{$item-md-border-bottom-color};
--inner-padding-end: #{$item-md-padding-end};
diff --git a/core/src/components/ripple-effect/readme.md b/core/src/components/ripple-effect/readme.md
index adffbb0a3d..7c66c666d6 100644
--- a/core/src/components/ripple-effect/readme.md
+++ b/core/src/components/ripple-effect/readme.md
@@ -8,7 +8,7 @@ The ripple effect component adds the [Material Design ink ripple interaction eff
## Methods
-### `addRipple(pageX: number, pageY: number) => void`
+### `addRipple(pageX: number, pageY: number) => Promise<() => void>`
Adds the ripple effect to the parent element
@@ -21,7 +21,7 @@ Adds the ripple effect to the parent element
#### Returns
-Type: `void`
+Type: `Promise<() => void>`
diff --git a/core/src/components/ripple-effect/ripple-effect.scss b/core/src/components/ripple-effect/ripple-effect.scss
index d45d1197d7..cfd26c9e89 100644
--- a/core/src/components/ripple-effect/ripple-effect.scss
+++ b/core/src/components/ripple-effect/ripple-effect.scss
@@ -4,6 +4,11 @@
// Material Design Ripple Effect
// --------------------------------------------------
+$scale-duration: 225ms;
+$fade-in-duration: 75ms;
+$fade-out-duration: 150ms;
+$opacity-duration: $fade-in-duration + $fade-out-duration;
+
:host {
@include position(0, 0, 0, 0);
@@ -23,23 +28,51 @@
contain: strict;
opacity: 0;
- animation-name: rippleAnimation;
- animation-duration: 200ms;
- animation-timing-function: ease-out;
+ animation:
+ $scale-duration rippleAnimation forwards,
+ $fade-in-duration fadeInAnimation forwards;
+
will-change: transform, opacity;
pointer-events: none;
}
-@keyframes rippleAnimation {
- 0% {
- transform: scale(.1);
+.fade-out {
+ transform: translate(var(--translate-end)) scale(var(--final-scale, 1));
+ animation: $fade-out-duration fadeOutAnimation forwards;
+}
- opacity: .2;
+@keyframes rippleAnimation {
+ from {
+ animation-timing-function: cubic-bezier(.4, 0, .2, 1);
+
+ transform: scale(1);
}
- 100% {
- transform: scale(1);
+ to {
+ transform: translate(var(--translate-end)) scale(var(--final-scale, 1));
+ }
+}
+
+@keyframes fadeInAnimation {
+ from {
+ animation-timing-function: linear;
opacity: 0;
}
+
+ to {
+ opacity: 0.16;
+ }
+}
+
+@keyframes fadeOutAnimation {
+ from {
+ animation-timing-function: linear;
+
+ opacity: 0.16;
+ }
+
+ to {
+ opacity: 0;
+ }
}
diff --git a/core/src/components/ripple-effect/ripple-effect.tsx b/core/src/components/ripple-effect/ripple-effect.tsx
index 4514714b8d..d823ada6b2 100644
--- a/core/src/components/ripple-effect/ripple-effect.tsx
+++ b/core/src/components/ripple-effect/ripple-effect.tsx
@@ -1,7 +1,6 @@
import { Component, ComponentInterface, Element, Method, Prop, QueueApi } from '@stencil/core';
import { Config } from '../../interface';
-import { rIC } from '../../utils/helpers';
@Component({
tag: 'ion-ripple-effect',
@@ -20,42 +19,61 @@ export class RippleEffect implements ComponentInterface {
* Adds the ripple effect to the parent element
*/
@Method()
- addRipple(pageX: number, pageY: number) {
+ async addRipple(pageX: number, pageY: number) {
if (this.config.getBoolean('animated', true)) {
- rIC(() => this.prepareRipple(pageX, pageY));
+ return this.prepareRipple(pageX, pageY);
}
+ return () => { return; };
}
private prepareRipple(pageX: number, pageY: number) {
- let x: number;
- let y: number;
- let size: number;
+ return new Promise<() => void>(resolve => {
+ this.queue.read(() => {
+ const rect = this.el.getBoundingClientRect();
+ const width = rect.width;
+ const height = rect.height;
+ const hypotenuse = Math.sqrt(width * width + height * height);
+ const maxRadius = hypotenuse + PADDING;
+ const maxDim = Math.max(height, width);
+ const posX = pageX - rect.left;
+ const posY = pageY - rect.top;
- this.queue.read(() => {
- const rect = this.el.getBoundingClientRect();
- const width = rect.width;
- const height = rect.height;
- size = Math.min(Math.sqrt(width * width + height * height) * 2, MAX_RIPPLE_DIAMETER);
- x = pageX - rect.left - (size * 0.5);
- y = pageY - rect.top - (size * 0.5);
- });
- this.queue.write(() => {
- const div = this.win.document.createElement('div');
- div.classList.add('ripple-effect');
- const style = div.style;
- const duration = Math.max(RIPPLE_FACTOR * Math.sqrt(size), MIN_RIPPLE_DURATION);
- style.top = y + 'px';
- style.left = x + 'px';
- style.width = style.height = size + 'px';
- style.animationDuration = duration + 'ms';
+ const initialSize = Math.floor(maxDim * INITIAL_ORIGIN_SCALE);
+ const finalScale = maxRadius / initialSize;
+ const x = posX - initialSize * 0.5;
+ const y = posY - initialSize * 0.5;
+ const moveX = width * 0.5 - posX;
+ const moveY = height * 0.5 - posY;
- const container = this.el.shadowRoot || this.el;
- container.appendChild(div);
- setTimeout(() => div.remove(), duration + 50);
+ this.queue.write(() => {
+ const div = this.win.document.createElement('div');
+ div.classList.add('ripple-effect');
+ const style = div.style;
+ style.top = y + 'px';
+ style.left = x + 'px';
+ style.width = style.height = initialSize + 'px';
+ style.setProperty('--final-scale', `${finalScale}`);
+ style.setProperty('--translate-end', `${moveX}px, ${moveY}px`);
+
+ const container = this.el.shadowRoot || this.el;
+ container.appendChild(div);
+ setTimeout(() => {
+ resolve(() => {
+ removeRipple(div);
+ });
+ }, 225 + 100);
+ });
+ });
});
}
}
-const RIPPLE_FACTOR = 35;
-const MIN_RIPPLE_DURATION = 260;
-const MAX_RIPPLE_DIAMETER = 550;
+function removeRipple(ripple: HTMLElement) {
+ ripple.classList.add('fade-out');
+ setTimeout(() => {
+ ripple.remove();
+ }, 200);
+}
+
+const PADDING = 10;
+const INITIAL_ORIGIN_SCALE = 0.5;
diff --git a/core/src/utils/tap-click.ts b/core/src/utils/tap-click.ts
index 5e20538091..cf4efb9b12 100644
--- a/core/src/utils/tap-click.ts
+++ b/core/src/utils/tap-click.ts
@@ -8,6 +8,7 @@ export function startTapClick(doc: Document) {
let scrolling = false;
let activatableEle: HTMLElement | undefined;
+ let activeRipple: Promise<() => void> | undefined;
let activeDefer: any;
const clearDefers = new WeakMap();
@@ -116,11 +117,14 @@ export function startTapClick(doc: Document) {
const rippleEffect = getRippleEffect(el);
if (rippleEffect && rippleEffect.addRipple) {
- rippleEffect.addRipple(x, y);
+ activeRipple = rippleEffect.addRipple(x, y);
}
}
function removeActivated(smooth: boolean) {
+ if (activeRipple !== undefined) {
+ activeRipple.then(remove => remove());
+ }
const active = activatableEle;
if (!active) {
return;