mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-17 18:54:11 +08:00
fix(tap-click): works inside shadow-dom
adds private ion-activable attribute fixes #15128
This commit is contained in:
@ -1,8 +1,8 @@
|
|||||||
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
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 { 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 { iosEnterAnimation } from './animations/ios.enter';
|
||||||
import { iosLeaveAnimation } from './animations/ios.leave';
|
import { iosLeaveAnimation } from './animations/ios.leave';
|
||||||
@ -20,7 +20,6 @@ import { mdLeaveAnimation } from './animations/md.leave';
|
|||||||
export class ActionSheet implements OverlayInterface {
|
export class ActionSheet implements OverlayInterface {
|
||||||
|
|
||||||
mode!: Mode;
|
mode!: Mode;
|
||||||
color?: Color;
|
|
||||||
|
|
||||||
presented = false;
|
presented = false;
|
||||||
animation?: Animation;
|
animation?: Animation;
|
||||||
@ -208,7 +207,6 @@ export class ActionSheet implements OverlayInterface {
|
|||||||
zIndex: 20000 + this.overlayId,
|
zIndex: 20000 + this.overlayId,
|
||||||
},
|
},
|
||||||
class: {
|
class: {
|
||||||
...createColorClasses(this.color),
|
|
||||||
...getClassMap(this.cssClass),
|
...getClassMap(this.cssClass),
|
||||||
'action-sheet-translucent': this.translucent
|
'action-sheet-translucent': this.translucent
|
||||||
}
|
}
|
||||||
@ -237,7 +235,7 @@ export class ActionSheet implements OverlayInterface {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{buttons.map(b =>
|
{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">
|
<span class="action-sheet-button-inner">
|
||||||
{b.icon && <ion-icon icon={b.icon} lazy={false} class="action-sheet-icon" />}
|
{b.icon && <ion-icon icon={b.icon} lazy={false} class="action-sheet-icon" />}
|
||||||
{b.text}
|
{b.text}
|
||||||
@ -249,6 +247,7 @@ export class ActionSheet implements OverlayInterface {
|
|||||||
{cancelButton &&
|
{cancelButton &&
|
||||||
<div class="action-sheet-group action-sheet-group-cancel">
|
<div class="action-sheet-group action-sheet-group-cancel">
|
||||||
<button
|
<button
|
||||||
|
ion-activable
|
||||||
type="button"
|
type="button"
|
||||||
class={buttonClass(cancelButton)}
|
class={buttonClass(cancelButton)}
|
||||||
onClick={() => this.buttonClick(cancelButton)}
|
onClick={() => this.buttonClick(cancelButton)}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Component, Element, Event, EventEmitter, Listen, Method, Prop, Watch } from '@stencil/core';
|
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 { 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 { iosEnterAnimation } from './animations/ios.enter';
|
||||||
import { iosLeaveAnimation } from './animations/ios.leave';
|
import { iosLeaveAnimation } from './animations/ios.leave';
|
||||||
@ -27,7 +27,6 @@ export class Alert implements OverlayInterface {
|
|||||||
presented = false;
|
presented = false;
|
||||||
animation?: Animation;
|
animation?: Animation;
|
||||||
|
|
||||||
color!: Color;
|
|
||||||
@Prop() mode!: Mode;
|
@Prop() mode!: Mode;
|
||||||
|
|
||||||
@Element() el!: HTMLStencilElement;
|
@Element() el!: HTMLStencilElement;
|
||||||
@ -399,7 +398,6 @@ export class Alert implements OverlayInterface {
|
|||||||
zIndex: 20000 + this.overlayId,
|
zIndex: 20000 + this.overlayId,
|
||||||
},
|
},
|
||||||
class: {
|
class: {
|
||||||
...createColorClasses(this.color),
|
|
||||||
...getClassMap(this.cssClass),
|
...getClassMap(this.cssClass),
|
||||||
'alert-translucent': this.translucent
|
'alert-translucent': this.translucent
|
||||||
}
|
}
|
||||||
@ -415,7 +413,7 @@ export class Alert implements OverlayInterface {
|
|||||||
return (
|
return (
|
||||||
<div class={alertButtonGroupClass}>
|
<div class={alertButtonGroupClass}>
|
||||||
{buttons.map(button =>
|
{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">
|
<span class="alert-button-inner">
|
||||||
{button.text}
|
{button.text}
|
||||||
</span>
|
</span>
|
||||||
|
@ -67,7 +67,7 @@ export class BackButton {
|
|||||||
'button': true,
|
'button': true,
|
||||||
'show-back-button': showBackButton
|
'show-back-button': showBackButton
|
||||||
},
|
},
|
||||||
'tappable': true,
|
'ion-activable': true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ export class Button {
|
|||||||
...getColorClassMap(buttonType, color, fill, mode),
|
...getColorClassMap(buttonType, color, fill, mode),
|
||||||
'focused': this.keyFocus,
|
'focused': this.keyFocus,
|
||||||
},
|
},
|
||||||
'tappable': true,
|
'ion-activable': true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ export class FabButton {
|
|||||||
hostData() {
|
hostData() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'tappable': !this.disabled,
|
'ion-activable': !this.disabled,
|
||||||
class: {
|
class: {
|
||||||
...createColorClasses(this.color),
|
...createColorClasses(this.color),
|
||||||
...this.getFabClassMap(),
|
...this.getFabClassMap(),
|
||||||
|
@ -126,7 +126,7 @@ export class Item {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'tappable': this.isClickable(),
|
'ion-activable': this.isClickable(),
|
||||||
class: {
|
class: {
|
||||||
...childStyles,
|
...childStyles,
|
||||||
...createColorClasses(this.color),
|
...createColorClasses(this.color),
|
||||||
|
@ -62,7 +62,7 @@ export class SegmentButton {
|
|||||||
'segment-button-disabled': disabled,
|
'segment-button-disabled': disabled,
|
||||||
'segment-checked': checked,
|
'segment-checked': checked,
|
||||||
},
|
},
|
||||||
'tappable': true,
|
'ion-activable': true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
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 { dismiss, eventMethod, present } from '../../utils/overlays';
|
||||||
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
||||||
|
|
||||||
@ -25,7 +25,6 @@ export class Toast implements OverlayInterface {
|
|||||||
@Element() el!: HTMLElement;
|
@Element() el!: HTMLElement;
|
||||||
|
|
||||||
mode!: Mode;
|
mode!: Mode;
|
||||||
color?: Color;
|
|
||||||
animation: Animation | undefined;
|
animation: Animation | undefined;
|
||||||
|
|
||||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement;
|
@Prop({ connect: 'ion-animation-controller' }) animationCtrl!: HTMLIonAnimationControllerElement;
|
||||||
@ -203,7 +202,7 @@ export class Toast implements OverlayInterface {
|
|||||||
? <div class="toast-message">{this.message}</div>
|
? <div class="toast-message">{this.message}</div>
|
||||||
: null}
|
: null}
|
||||||
{this.showCloseButton
|
{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'}
|
{this.closeButtonText || 'Close'}
|
||||||
</ion-button>
|
</ion-button>
|
||||||
: null}
|
: null}
|
||||||
|
1
core/src/interface.d.ts
vendored
1
core/src/interface.d.ts
vendored
@ -53,6 +53,7 @@ declare global {
|
|||||||
// for ion-menu and ion-split-pane
|
// for ion-menu and ion-split-pane
|
||||||
main?: boolean;
|
main?: boolean;
|
||||||
tappable?: boolean;
|
tappable?: boolean;
|
||||||
|
'ion-activable'?: boolean;
|
||||||
|
|
||||||
padding?: boolean;
|
padding?: boolean;
|
||||||
['padding-top']?: boolean;
|
['padding-top']?: boolean;
|
||||||
|
@ -57,7 +57,7 @@ export function startTapClick(doc: Document) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cancelled = false;
|
cancelled = false;
|
||||||
setActivatedElement(getActivatableTarget(ev.target), ev);
|
setActivatedElement(getActivatableTarget(ev), ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pointerUp(ev: UIEvent) {
|
function pointerUp(ev: UIEvent) {
|
||||||
@ -145,8 +145,18 @@ export function startTapClick(doc: Document) {
|
|||||||
doc.addEventListener('mouseup', onMouseUp, true);
|
doc.addEventListener('mouseup', onMouseUp, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActivatableTarget(el: HTMLElement): any {
|
function getActivatableTarget(ev: any): any {
|
||||||
return el.closest(':not([tappable]) > a, :not([tappable]) > button, [tappable]');
|
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';
|
const ACTIVATED = 'activated';
|
||||||
|
Reference in New Issue
Block a user