fix(ripple): using ripple effect in all button components

This commit is contained in:
Manu Mtz.-Almeida
2018-01-17 15:44:17 +01:00
parent 3fce77ea6a
commit e0cf1325b7
15 changed files with 86 additions and 72 deletions

View File

@ -330,36 +330,6 @@ declare global {
} }
import {
ButtonEffect as IonButtonEffect
} from './components/button-effect/button-effect';
declare global {
interface HTMLIonButtonEffectElement extends IonButtonEffect, HTMLElement {
}
var HTMLIonButtonEffectElement: {
prototype: HTMLIonButtonEffectElement;
new (): HTMLIonButtonEffectElement;
};
interface HTMLElementTagNameMap {
"ion-button-effect": HTMLIonButtonEffectElement;
}
interface ElementTagNameMap {
"ion-button-effect": HTMLIonButtonEffectElement;
}
namespace JSX {
interface IntrinsicElements {
"ion-button-effect": JSXElements.IonButtonEffectAttributes;
}
}
namespace JSXElements {
export interface IonButtonEffectAttributes extends HTMLAttributes {
}
}
}
import { import {
Button as IonButton Button as IonButton
} from './components/button/button'; } from './components/button/button';
@ -2301,6 +2271,36 @@ declare global {
} }
import {
RippleEffect as IonRippleEffect
} from './components/ripple-effect/ripple-effect';
declare global {
interface HTMLIonRippleEffectElement extends IonRippleEffect, HTMLElement {
}
var HTMLIonRippleEffectElement: {
prototype: HTMLIonRippleEffectElement;
new (): HTMLIonRippleEffectElement;
};
interface HTMLElementTagNameMap {
"ion-ripple-effect": HTMLIonRippleEffectElement;
}
interface ElementTagNameMap {
"ion-ripple-effect": HTMLIonRippleEffectElement;
}
namespace JSX {
interface IntrinsicElements {
"ion-ripple-effect": JSXElements.IonRippleEffectAttributes;
}
}
namespace JSXElements {
export interface IonRippleEffectAttributes extends HTMLAttributes {
}
}
}
import { import {
RouteLink as IonRouteLink RouteLink as IonRouteLink
} from './components/route-link/route-link'; } from './components/route-link/route-link';
@ -2851,6 +2851,7 @@ declare global {
} }
namespace JSXElements { namespace JSXElements {
export interface IonTabButtonAttributes extends HTMLAttributes { export interface IonTabButtonAttributes extends HTMLAttributes {
mode?: 'ios' | 'md';
selected?: boolean; selected?: boolean;
tab?: HTMLIonTabElement; tab?: HTMLIonTabElement;
} }

View File

@ -42,7 +42,7 @@
background-color: $button-md-background-color-focused; background-color: $button-md-background-color-focused;
} }
.button-md .button-effect { .button-md .ripple-effect {
background-color: $button-md-text-color; background-color: $button-md-text-color;
} }
@ -74,7 +74,7 @@
background-color: $bg-color-focused; background-color: $bg-color-focused;
} }
.button-md-#{$color-name} .button-effect { .button-md-#{$color-name} .ripple-effect {
background-color: $fg-color; background-color: $fg-color;
} }
} }
@ -143,7 +143,7 @@
background-color: $button-md-outline-background-color-focused; background-color: $button-md-outline-background-color-focused;
} }
.button-outline-md .button-effect { .button-outline-md .ripple-effect {
background-color: $button-md-outline-ripple-background-color; background-color: $button-md-outline-ripple-background-color;
} }
@ -173,7 +173,7 @@
background-color: $bg-color-focused; background-color: $bg-color-focused;
} }
.button-outline-md-#{$color-name} .button-effect { .button-outline-md-#{$color-name} .ripple-effect {
background-color: $fg-color; background-color: $fg-color;
} }
} }
@ -203,7 +203,7 @@
background-color: $button-md-clear-background-color-hover; background-color: $button-md-clear-background-color-hover;
} }
.button-clear-md .button-effect { .button-clear-md .ripple-effect {
background-color: $button-md-clear-ripple-background-color; background-color: $button-md-clear-ripple-background-color;
} }

View File

@ -143,7 +143,7 @@ export class Button {
<slot></slot> <slot></slot>
<slot name='end'></slot> <slot name='end'></slot>
</span> </span>
<ion-button-effect /> { this.mode === 'md' && <ion-ripple-effect /> }
</TagType> </TagType>
); );
} }

View File

@ -101,7 +101,7 @@ export class ChipButton {
<span class='button-inner'> <span class='button-inner'>
<slot></slot> <slot></slot>
</span> </span>
<div class='button-effect'></div> { this.mode === 'md' && <ion-ripple-effect /> }
</TagType> </TagType>
); );
} }

View File

@ -51,7 +51,7 @@
// Material Design FAB Ripple // Material Design FAB Ripple
// -------------------------------------------------- // --------------------------------------------------
.fab-button-md .button-effect { .fab-button-md .ripple-effect {
background-color: color-contrast($colors-md, $fab-md-background-color); background-color: color-contrast($colors-md, $fab-md-background-color);
} }
@ -78,7 +78,7 @@
background-color: $bg-color-activated; background-color: $bg-color-activated;
} }
.fab-button-md-#{$color-name} .button-effect { .fab-button-md-#{$color-name} .ripple-effect {
background-color: $fg-color; background-color: $fg-color;
} }
} }

View File

@ -139,7 +139,7 @@ export class FabButton {
<span class='button-inner'> <span class='button-inner'>
<slot></slot> <slot></slot>
</span> </span>
<div class='button-effect'></div> { this.mode === 'md' && <ion-ripple-effect /> }
</TagType> </TagType>
); );
} }

View File

@ -99,7 +99,7 @@ export class Item {
</div> </div>
<slot name='end'></slot> <slot name='end'></slot>
</div> </div>
<div class='button-effect'></div> { this.href && this.mode === 'md' && <ion-ripple-effect /> }
</TagType> </TagType>
); );
} }

View File

@ -5,10 +5,7 @@
// Only Material uses the button effect, so by default // Only Material uses the button effect, so by default
// it's display none, and .md sets to display block. // it's display none, and .md sets to display block.
/// @prop - Background color of the ripple on the button ion-ripple-effect {
$button-effect-ripple-background-color: #000 !default;
ion-button-effect {
@include position(0, 0, 0, 0); @include position(0, 0, 0, 0);
position: absolute; position: absolute;
@ -16,11 +13,11 @@ ion-button-effect {
contain: strict; contain: strict;
} }
.button-effect { .ripple-effect {
@include border-radius(50%); @include border-radius(50%);
position: absolute; position: absolute;
background: $button-effect-ripple-background-color; background: #000;
opacity: 0; opacity: 0;
will-change: transform, opacity; will-change: transform, opacity;

View File

@ -1,18 +1,16 @@
import { Component, Element, Listen, Prop, State } from '@stencil/core'; import { Component, Element, Listen, Prop } from '@stencil/core';
import { now } from '../../utils/helpers'; import { now } from '../../utils/helpers';
import { DomController } from '../../global/dom-controller'; import { DomController } from '../../global/dom-controller';
@Component({ @Component({
tag: 'ion-button-effect', tag: 'ion-ripple-effect',
styleUrl: 'button-effect.scss' styleUrl: 'ripple-effect.scss'
}) })
export class ButtonEffect { export class RippleEffect {
private lastClick = -10000; private lastClick = -10000;
@Element() el: HTMLElement; @Element() el: HTMLElement;
@State() state = 0;
@Prop({context: 'dom'}) dom: DomController; @Prop({context: 'dom'}) dom: DomController;
@Listen('touchstart') @Listen('touchstart')
@ -37,13 +35,13 @@ export class ButtonEffect {
const rect = this.el.getBoundingClientRect(); const rect = this.el.getBoundingClientRect();
const width = rect.width; const width = rect.width;
const height = rect.height; const height = rect.height;
size = Math.sqrt(width * width + height * height) * 2; size = Math.min(Math.sqrt(width * width + height * height) * 2, 600);
x = pageX - rect.left - (size / 2); x = pageX - rect.left - (size / 2);
y = pageY - rect.top - (size / 2); y = pageY - rect.top - (size / 2);
}); });
this.dom.write(() => { this.dom.write(() => {
const div = document.createElement('div'); const div = document.createElement('div');
div.classList.add('button-effect'); div.classList.add('ripple-effect');
const style = div.style; const style = div.style;
const duration = Math.max(800 * Math.sqrt(size / 350) + 0.5, 260); const duration = Math.max(800 * Math.sqrt(size / 350) + 0.5, 260);
style.top = y + 'px'; style.top = y + 'px';

View File

@ -40,19 +40,19 @@
<ion-button size="large" fill="clear">Large</ion-button> <ion-button size="large" fill="clear">Large</ion-button>
</p> </p>
<div class="my-block"> <div class="my-block">
<ion-button-effect></ion-button-effect> <ion-ripple-effect></ion-ripple-effect>
This is just a div + effect behind This is just a div + effect behind
<ion-button onclick="buttonClicked()">Nested button</ion-button> <ion-button onclick="buttonClicked()">Nested button</ion-button>
</div> </div>
<div class="my-block"> <div class="my-block">
This is just a div + effect on top This is just a div + effect on top
<ion-button onclick="buttonClicked()">Nested button</ion-button> <ion-button onclick="buttonClicked()">Nested button</ion-button>
<ion-button-effect></ion-button-effect> <ion-ripple-effect></ion-ripple-effect>
</div> </div>
<div class="my-block"> <div class="my-block">
This is just a div + effect This is just a div + effect
<ion-button-effect></ion-button-effect> <ion-ripple-effect></ion-ripple-effect>
</div> </div>
</ion-content> </ion-content>
</ion-page> </ion-page>

View File

@ -7,6 +7,11 @@
## Properties ## Properties
#### mode
any
#### selected #### selected
boolean boolean
@ -19,6 +24,11 @@ any
## Attributes ## Attributes
#### mode
any
#### selected #### selected
boolean boolean

View File

@ -8,6 +8,13 @@ export class TabButton {
@Element() el: HTMLElement; @Element() el: HTMLElement;
/**
* @input {string} The mode determines which platform styles to use.
* Possible values are: `"ios"` or `"md"`.
* For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
*/
@Prop() mode: 'ios' | 'md';
@Prop() selected = false; @Prop() selected = false;
@Prop() tab: HTMLIonTabElement; @Prop() tab: HTMLIonTabElement;
@ -67,8 +74,9 @@ export class TabButton {
if (tab.badge) { if (tab.badge) {
items.push(<ion-badge class='tab-badge' color={tab.badgeStyle}>{tab.badge}</ion-badge>); items.push(<ion-badge class='tab-badge' color={tab.badgeStyle}>{tab.badge}</ion-badge>);
} }
items.push(<div class='button-effect'></div>); if (this.mode === 'md') {
items.push(<ion-ripple-effect />);
}
return items; return items;
} }
} }

View File

@ -90,7 +90,7 @@
.bar-button-clear-md, .bar-button-clear-md,
.bar-button-default-md, .bar-button-default-md,
.bar-button-outline-md { .bar-button-outline-md {
.button-effect { .ripple-effect {
background-color: $color-contrast; background-color: $color-contrast;
} }
} }
@ -202,7 +202,7 @@
background-color: transparent; background-color: transparent;
} }
.button-effect { .ripple-effect {
background-color: $toolbar-md-button-color; background-color: $toolbar-md-button-color;
} }
} }
@ -219,7 +219,7 @@
background-color: transparent; background-color: transparent;
} }
.button-effect { .ripple-effect {
background-color: $fg-color; background-color: $fg-color;
} }
} }

View File

@ -1,4 +1,4 @@
const _engine = (window as any).TapticEngine; const engine = (window as any).TapticEngine;
/** /**
* Check to see if the Haptic Plugin is available * Check to see if the Haptic Plugin is available
@ -6,7 +6,7 @@ const _engine = (window as any).TapticEngine;
* *
*/ */
export function hapticAvailable() { export function hapticAvailable() {
return !!_engine; return !!engine;
} }
/** /**
@ -14,21 +14,21 @@ export function hapticAvailable() {
* (not for gestures) * (not for gestures)
*/ */
export function hapticSelection() { export function hapticSelection() {
_engine && _engine.selection(); engine && engine.selection();
} }
/** /**
* Tell the haptic engine that a gesture for a selection change is starting. * Tell the haptic engine that a gesture for a selection change is starting.
*/ */
export function hapticSelectionStart() { export function hapticSelectionStart() {
_engine && _engine.gestureSelectionStart(); engine && engine.gestureSelectionStart();
} }
/** /**
* Tell the haptic engine that a selection changed during a gesture. * Tell the haptic engine that a selection changed during a gesture.
*/ */
export function hapticSelectionChanged() { export function hapticSelectionChanged() {
_engine && _engine.gestureSelectionChanged(); engine && engine.gestureSelectionChanged();
} }
/** /**
@ -36,7 +36,7 @@ export function hapticSelectionChanged() {
* called lest resources are not properly recycled. * called lest resources are not properly recycled.
*/ */
export function hapticSelectionEnd() { export function hapticSelectionEnd() {
_engine && _engine.gestureSelectionEnd(); engine && engine.gestureSelectionEnd();
} }
/** /**
@ -44,7 +44,7 @@ export function hapticSelectionEnd() {
* options should be of the type `{ type: 'success' }` (or `warning`/`error`) * options should be of the type `{ type: 'success' }` (or `warning`/`error`)
*/ */
export function hapticNotification(options: { type: string }) { export function hapticNotification(options: { type: string }) {
_engine && _engine.notification(options); engine && engine.notification(options);
} }
/** /**
@ -52,5 +52,5 @@ export function hapticNotification(options: { type: string }) {
* options should be of the type `{ style: 'light' }` (or `medium`/`heavy`) * options should be of the type `{ style: 'light' }` (or `medium`/`heavy`)
*/ */
export function hapticImpact(options: { style: string }) { export function hapticImpact(options: { style: string }) {
_engine && _engine.impact(options); engine && engine.impact(options);
} }