fix(tap-click): works inside shadow-dom

adds private ion-activable attribute

fixes #15128
This commit is contained in:
Manu Mtz.-Almeida
2018-08-12 22:48:58 +02:00
parent 270ece0b5e
commit 0dc70f7f6d
10 changed files with 28 additions and 21 deletions

View File

@ -1,8 +1,8 @@
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
import { ActionSheetButton, Animation, AnimationBuilder, Color, Config, CssClassMap, Mode, OverlayEventDetail, OverlayInterface } from '../../interface';
import { ActionSheetButton, Animation, AnimationBuilder, Config, CssClassMap, Mode, OverlayEventDetail, OverlayInterface } from '../../interface';
import { BACKDROP, dismiss, eventMethod, isCancel, present } from '../../utils/overlays';
import { createColorClasses, getClassMap } from '../../utils/theme';
import { getClassMap } from '../../utils/theme';
import { iosEnterAnimation } from './animations/ios.enter';
import { iosLeaveAnimation } from './animations/ios.leave';
@ -20,7 +20,6 @@ import { mdLeaveAnimation } from './animations/md.leave';
export class ActionSheet implements OverlayInterface {
mode!: Mode;
color?: Color;
presented = false;
animation?: Animation;
@ -208,7 +207,6 @@ export class ActionSheet implements OverlayInterface {
zIndex: 20000 + this.overlayId,
},
class: {
...createColorClasses(this.color),
...getClassMap(this.cssClass),
'action-sheet-translucent': this.translucent
}
@ -237,7 +235,7 @@ export class ActionSheet implements OverlayInterface {
</div>
}
{buttons.map(b =>
<button type="button" class={buttonClass(b)} onClick={() => this.buttonClick(b)}>
<button type="button" ion-activable class={buttonClass(b)} onClick={() => this.buttonClick(b)}>
<span class="action-sheet-button-inner">
{b.icon && <ion-icon icon={b.icon} lazy={false} class="action-sheet-icon" />}
{b.text}
@ -249,6 +247,7 @@ export class ActionSheet implements OverlayInterface {
{cancelButton &&
<div class="action-sheet-group action-sheet-group-cancel">
<button
ion-activable
type="button"
class={buttonClass(cancelButton)}
onClick={() => this.buttonClick(cancelButton)}

View File

@ -1,8 +1,8 @@
import { Component, Element, Event, EventEmitter, Listen, Method, Prop, Watch } from '@stencil/core';
import { AlertButton, AlertInput, Animation, AnimationBuilder, Color, Config, CssClassMap, Mode, OverlayEventDetail, OverlayInterface } from '../../interface';
import { AlertButton, AlertInput, Animation, AnimationBuilder, Config, CssClassMap, Mode, OverlayEventDetail, OverlayInterface } from '../../interface';
import { BACKDROP, dismiss, eventMethod, isCancel, present } from '../../utils/overlays';
import { createColorClasses, getClassMap } from '../../utils/theme';
import { getClassMap } from '../../utils/theme';
import { iosEnterAnimation } from './animations/ios.enter';
import { iosLeaveAnimation } from './animations/ios.leave';
@ -27,7 +27,6 @@ export class Alert implements OverlayInterface {
presented = false;
animation?: Animation;
color!: Color;
@Prop() mode!: Mode;
@Element() el!: HTMLStencilElement;
@ -399,7 +398,6 @@ export class Alert implements OverlayInterface {
zIndex: 20000 + this.overlayId,
},
class: {
...createColorClasses(this.color),
...getClassMap(this.cssClass),
'alert-translucent': this.translucent
}
@ -415,7 +413,7 @@ export class Alert implements OverlayInterface {
return (
<div class={alertButtonGroupClass}>
{buttons.map(button =>
<button type="button" class={buttonClass(button)} tabIndex={0} onClick={() => this.buttonClick(button)}>
<button type="button" ion-activable class={buttonClass(button)} tabIndex={0} onClick={() => this.buttonClick(button)}>
<span class="alert-button-inner">
{button.text}
</span>

View File

@ -67,7 +67,7 @@ export class BackButton {
'button': true,
'show-back-button': showBackButton
},
'tappable': true,
'ion-activable': true,
};
}

View File

@ -157,7 +157,7 @@ export class Button {
...getColorClassMap(buttonType, color, fill, mode),
'focused': this.keyFocus,
},
'tappable': true,
'ion-activable': true,
};
}

View File

@ -77,7 +77,7 @@ export class FabButton {
hostData() {
return {
'tappable': !this.disabled,
'ion-activable': !this.disabled,
class: {
...createColorClasses(this.color),
...this.getFabClassMap(),

View File

@ -126,7 +126,7 @@ export class Item {
});
return {
'tappable': this.isClickable(),
'ion-activable': this.isClickable(),
class: {
...childStyles,
...createColorClasses(this.color),

View File

@ -62,7 +62,7 @@ export class SegmentButton {
'segment-button-disabled': disabled,
'segment-checked': checked,
},
'tappable': true,
'ion-activable': true,
};
}

View File

@ -1,6 +1,6 @@
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
import { Animation, AnimationBuilder, Color, Config, Mode, OverlayEventDetail, OverlayInterface } from '../../interface';
import { Animation, AnimationBuilder, Config, Mode, OverlayEventDetail, OverlayInterface } from '../../interface';
import { dismiss, eventMethod, present } from '../../utils/overlays';
import { createThemedClasses, getClassMap } from '../../utils/theme';
@ -25,7 +25,6 @@ export class Toast implements OverlayInterface {
@Element() el!: HTMLElement;
mode!: Mode;
color?: Color;
animation: Animation | undefined;
@Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement;
@ -203,7 +202,7 @@ export class Toast implements OverlayInterface {
? <div class="toast-message">{this.message}</div>
: null}
{this.showCloseButton
? <ion-button fill="clear" color="light" class="toast-button" onClick={() => this.dismiss()}>
? <ion-button fill="clear" color="light" ion-activable class="toast-button" onClick={() => this.dismiss()}>
{this.closeButtonText || 'Close'}
</ion-button>
: null}

View File

@ -53,6 +53,7 @@ declare global {
// for ion-menu and ion-split-pane
main?: boolean;
tappable?: boolean;
'ion-activable'?: boolean;
padding?: boolean;
['padding-top']?: boolean;

View File

@ -57,7 +57,7 @@ export function startTapClick(doc: Document) {
return;
}
cancelled = false;
setActivatedElement(getActivatableTarget(ev.target), ev);
setActivatedElement(getActivatableTarget(ev), ev);
}
function pointerUp(ev: UIEvent) {
@ -145,8 +145,18 @@ export function startTapClick(doc: Document) {
doc.addEventListener('mouseup', onMouseUp, true);
}
function getActivatableTarget(el: HTMLElement): any {
return el.closest(':not([tappable]) > a, :not([tappable]) > button, [tappable]');
function getActivatableTarget(ev: any): any {
if (ev.composedPath) {
const path = ev.composedPath() as HTMLElement[];
for (let i = path.length - 3; i >= 0; i--) {
const el = path[i];
if (el.hasAttribute && el.hasAttribute('ion-activable')) {
return el;
}
}
} else {
return ev.target.closest('[ion-activable]');
}
}
const ACTIVATED = 'activated';