From 491927f81e0da923b59f53aa7bd07a9cd3bac499 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Thu, 16 Apr 2020 11:16:20 -0400 Subject: [PATCH 1/7] action sheet hover --- .../action-sheet/action-sheet.ios.scss | 2 + .../components/action-sheet/action-sheet.scss | 3 +- .../components/action-sheet/action-sheet.tsx | 58 ++++++++++++++++++- 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/core/src/components/action-sheet/action-sheet.ios.scss b/core/src/components/action-sheet/action-sheet.ios.scss index 6eb41fd99c2..126e346f8e6 100644 --- a/core/src/components/action-sheet/action-sheet.ios.scss +++ b/core/src/components/action-sheet/action-sheet.ios.scss @@ -134,6 +134,8 @@ @include margin-horizontal(null, $action-sheet-ios-button-icon-padding-right); font-size: $action-sheet-ios-button-icon-font-size; + + pointer-events: none; } .action-sheet-button:last-child { diff --git a/core/src/components/action-sheet/action-sheet.scss b/core/src/components/action-sheet/action-sheet.scss index 227a182c921..fa2ce51899a 100644 --- a/core/src/components/action-sheet/action-sheet.scss +++ b/core/src/components/action-sheet/action-sheet.scss @@ -110,6 +110,7 @@ flex-shrink: 0; align-items: center; justify-content: center; + pointer-events: none; width: 100%; height: 100%; @@ -210,4 +211,4 @@ opacity: var(--button-background-hover-opacity); } } -} \ No newline at end of file +} diff --git a/core/src/components/action-sheet/action-sheet.tsx b/core/src/components/action-sheet/action-sheet.tsx index 47d31552e1e..e33e753dab6 100644 --- a/core/src/components/action-sheet/action-sheet.tsx +++ b/core/src/components/action-sheet/action-sheet.tsx @@ -4,6 +4,9 @@ import { getIonMode } from '../../global/ionic-global'; import { ActionSheetButton, AnimationBuilder, CssClassMap, OverlayEventDetail, OverlayInterface } from '../../interface'; import { BACKDROP, dismiss, eventMethod, isCancel, prepareOverlay, present, safeCall } from '../../utils/overlays'; import { getClassMap } from '../../utils/theme'; +import { raf } from '../../utils/helpers' +import { createGesture, Gesture } from '../../utils/gesture'; +import { hapticImpact } from '../../utils/native/haptic'; import { iosEnterAnimation } from './animations/ios.enter'; import { iosLeaveAnimation } from './animations/ios.leave'; @@ -25,6 +28,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface { presented = false; animation?: any; + wrapperEl?: HTMLElement; @Element() el!: HTMLIonActionSheetElement; @@ -192,6 +196,58 @@ export class ActionSheet implements ComponentInterface, OverlayInterface { } } + private gesture?: Gesture; + private touchedButton?: HTMLElement; + + private clearActiveButton(dispatchClick: boolean = false) { + const { touchedButton } = this; + if (!touchedButton) { return; } + + raf(() => touchedButton.classList.remove('ion-activated')); + + if (dispatchClick) { + touchedButton.click(); + } + + this.touchedButton = undefined; + } + + private setActiveButton(button: HTMLElement) { + this.touchedButton = button; + raf(() => this.touchedButton!.classList.add('ion-activated')); + hapticImpact({ style: 'light' }); + } + + componentDidLoad() { + if (!this.wrapperEl) { return; } + + this.gesture = createGesture({ + el: this.wrapperEl, + gestureName: 'pointerDrag', + gesturePriority: 100, + threshold: 0, + onMove: (ev) => { + const target = document.elementFromPoint(ev.currentX, ev.currentY) as HTMLElement | null; + const { touchedButton } = this; + if (!target) { + this.clearActiveButton(); + } else { + if (target.classList.contains('action-sheet-button')) { + if (target !== touchedButton) { + this.clearActiveButton(); + this.setActiveButton(target); + } + } else { + this.clearActiveButton(); + } + } + }, + onEnd: () => { this.clearActiveButton(true) } + }); + + this.gesture.enable(true); + } + render() { const mode = getIonMode(this); const allButtons = this.getButtons(); @@ -215,7 +271,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface { onIonBackdropTap={this.onBackdropTap} > -