diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 3b8181d824..5276e6d601 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -1,4 +1,3 @@ -/* eslint-disable */ /* tslint:disable */ /** * This is an autogenerated file created by the Stencil compiler. diff --git a/core/src/index.ts b/core/src/index.ts index 139f129a95..e837900517 100644 --- a/core/src/index.ts +++ b/core/src/index.ts @@ -3,6 +3,8 @@ import 'ionicons'; export { createAnimation } from './utils/animation/animation'; export { getTimeGivenProgression } from './utils/animation/cubic-bezier'; export { createGesture } from './utils/gesture'; +export { createPressRecognizer } from './utils/gesture/recognizers/press'; + export { isPlatform, Platforms, getPlatforms } from './utils/platform'; export * from './utils/config'; diff --git a/core/src/interface.d.ts b/core/src/interface.d.ts index dd3fedc029..9806a4b71a 100644 --- a/core/src/interface.d.ts +++ b/core/src/interface.d.ts @@ -35,6 +35,7 @@ export { Animation, AnimationBuilder } from './utils/animation/animation-interfa export * from './utils/overlays-interface'; export * from './global/config'; export { Gesture, GestureDetail } from './utils/gesture'; +export { PressRecognizerOptions } from './utils/gesture/recognizers/press'; // Global aux types export type TextFieldTypes = 'date' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'url' | 'time'; diff --git a/core/src/utils/gesture/recognizers/press.ts b/core/src/utils/gesture/recognizers/press.ts new file mode 100644 index 0000000000..e9f5b3933b --- /dev/null +++ b/core/src/utils/gesture/recognizers/press.ts @@ -0,0 +1,46 @@ +import { GestureDetail, createGesture } from '../index'; + +export interface PressRecognizerOptions { + el: HTMLElement; + time: number; + threshold: number; + onPressHandler: () => void; +} + +export const createPressRecognizer = (opts: PressRecognizerOptions) => { + const THRESHOLD = opts.threshold || 10; + let timeout: any; + + const onStart = () => { + clearGestureTimeout(); + + timeout = setTimeout(() => { + opts.onPressHandler(); + clearGestureTimeout(); + }, opts.time || 500); + }; + + const onMove = (detail: GestureDetail) => { + if (Math.abs(detail.deltaX) + Math.abs(detail.deltaY) <= THRESHOLD) { + return; + } + + clearGestureTimeout(); + }; + + const clearGestureTimeout = () => { + if (timeout) { + clearTimeout(timeout); + timeout = undefined; + } + }; + + return createGesture({ + el: opts.el, + gestureName: 'press', + threshold: 0, + onStart, + onMove, + onEnd: () => clearGestureTimeout() + }); +}; diff --git a/core/src/utils/gesture/recognizers/tests/press/e2e.ts b/core/src/utils/gesture/recognizers/tests/press/e2e.ts new file mode 100644 index 0000000000..30c4f522b3 --- /dev/null +++ b/core/src/utils/gesture/recognizers/tests/press/e2e.ts @@ -0,0 +1,76 @@ +import { newE2EPage } from '@stencil/core/testing'; + +test(`gesture: press`, async () => { + const page = await newE2EPage({ url: '/src/utils/gesture/recognizers/tests/press' }); + const screenshotCompares = []; + + screenshotCompares.push(await page.compareScreenshot()); + + const square = await page.$('.square'); + const { x, y } = await coords(square); + + page.mouse.move(x, y); + page.mouse.down(); + await page.waitFor(300); + page.mouse.up(); + + const squareAgain = await page.find('.square'); + expect(squareAgain).toHaveClass('pressed'); + + screenshotCompares.push(await page.compareScreenshot('end press')); + + for (const screenshotCompare of screenshotCompares) { + expect(screenshotCompare).toMatchScreenshot(); + } +}); + +test(`gesture: press:short press`, async () => { + const page = await newE2EPage({ url: '/src/utils/gesture/recognizers/tests/press' }); + const screenshotCompares = []; + + screenshotCompares.push(await page.compareScreenshot()); + + const square = await page.$('.square'); + const { x, y } = await coords(square); + + page.mouse.move(x, y); + page.mouse.down(); + await page.waitFor(50); + page.mouse.up(); + + const squareAgain = await page.find('.square'); + expect(squareAgain).not.toHaveClass('pressed'); + + screenshotCompares.push(await page.compareScreenshot('end press')); + + for (const screenshotCompare of screenshotCompares) { + expect(screenshotCompare).toMatchScreenshot(); + } +}); + +test(`gesture: press:click`, async () => { + const page = await newE2EPage({ url: '/src/utils/gesture/recognizers/tests/press' }); + const screenshotCompares = []; + + screenshotCompares.push(await page.compareScreenshot()); + + await page.click('.square'); + + const square = await page.find('.square'); + expect(square).not.toHaveClass('pressed'); + + screenshotCompares.push(await page.compareScreenshot('end press')); + + for (const screenshotCompare of screenshotCompares) { + expect(screenshotCompare).toMatchScreenshot(); + } +}); + +const coords = async el => { + const box = await el.boundingBox(); + + return { + x: Math.floor(box.x + (box.width / 2)), + y: Math.floor(box.y + (box.height / 2)) + }; +}; diff --git a/core/src/utils/gesture/recognizers/tests/press/index.html b/core/src/utils/gesture/recognizers/tests/press/index.html new file mode 100644 index 0000000000..0c8a39c332 --- /dev/null +++ b/core/src/utils/gesture/recognizers/tests/press/index.html @@ -0,0 +1,69 @@ + + + + + + Gesture - Press + + + + + + + + + + + + + + + + Gesture - Press + + + + +
+
Hello
+
+
+
+ + +