From 82697adaec241dffc89dc45974525cc37d6b8308 Mon Sep 17 00:00:00 2001 From: Emil Hartz Date: Thu, 31 Dec 2020 13:51:13 -0700 Subject: [PATCH 1/3] setup onSwipeStart prop --- __tests__/useSwipeable.spec.tsx | 41 ++++++++++++++++++++++++++------- src/index.ts | 4 ++++ src/types.ts | 1 + 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/__tests__/useSwipeable.spec.tsx b/__tests__/useSwipeable.spec.tsx index 9ffd8cb5..44a8852a 100644 --- a/__tests__/useSwipeable.spec.tsx +++ b/__tests__/useSwipeable.spec.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { render, fireEvent, act } from "@testing-library/react"; import { useSwipeable } from "../src/index"; -import { LEFT, RIGHT, UP, DOWN } from "../src/types"; +import { LEFT, RIGHT, UP, DOWN, SwipeableProps } from "../src/types"; import { expectSwipeFuncsDir } from "./helpers"; const DIRECTIONS: [typeof LEFT, typeof RIGHT, typeof UP, typeof DOWN] = [ @@ -34,7 +34,7 @@ const TESTING_TEXT = "touch here"; /* * Wrapping component for the hook testing */ -function SwipeableUsingHook({ nodeName = "div", ...rest }) { +function SwipeableUsingHook({ nodeName = "div", ...rest }: SwipeableProps & {nodeName?: string}) { const eventHandlers = useSwipeable(rest); const Elem = nodeName as React.ElementType; return ( @@ -222,6 +222,31 @@ describe("useSwipeable", () => { ); }); + it("correctly calls onSwipeStart for first swipe event", () => { + const onSwipeStart = jest.fn(); + const { getByText } = render(); + + const touchArea = getByText(TESTING_TEXT); + + // first swipe + fireEvent[TS](touchArea, cte({ x: 100, y: 100 })); + fireEvent[TM](touchArea, cte({ x: 100, y: 125 })); + fireEvent[TM](touchArea, cte({ x: 100, y: 150 })); + fireEvent[TM](touchArea, cte({ x: 100, y: 175 })); + fireEvent[TE](touchArea, cte({})); + + expect(onSwipeStart).toHaveBeenCalledTimes(1); + + // second swipe + fireEvent[TS](touchArea, cte({ x: 100, y: 100 })); + fireEvent[TM](touchArea, cte({ x: 125, y: 125 })); + fireEvent[TM](touchArea, cte({ x: 150, y: 150 })); + fireEvent[TM](touchArea, cte({ x: 175, y: 175 })); + fireEvent[TE](touchArea, cte({})); + + expect(onSwipeStart).toHaveBeenCalledTimes(2); + }); + it("calls preventDefault when swiping in direction that has a callback", () => { const onSwipedDown = jest.fn(); @@ -346,22 +371,22 @@ describe("useSwipeable", () => { expectSwipeFuncsDir(swipeFuncsLeft, LEFT); // check up - const swipeFunsUp = getMockedSwipeFunctions(); - rerender(); + const swipeFuncsUp = getMockedSwipeFunctions(); + rerender(); fireEvent[TS](touchArea, cte({ x: 100, y: 100 })); fireEvent[TM](touchArea, cte({ x: 125, y: 100 })); fireEvent[TM](touchArea, cte({ x: 150, y: 100 })); fireEvent[TE](touchArea, cte({})); - expectSwipeFuncsDir(swipeFunsUp, UP); + expectSwipeFuncsDir(swipeFuncsUp, UP); // check down - const swipeFunsDown = getMockedSwipeFunctions(); - rerender(); + const swipeFuncsDown = getMockedSwipeFunctions(); + rerender(); fireEvent[TS](touchArea, cte({ x: 100, y: 100 })); fireEvent[TM](touchArea, cte({ x: 75, y: 100 })); fireEvent[TM](touchArea, cte({ x: 50, y: 100 })); fireEvent[TE](touchArea, cte({})); - expectSwipeFuncsDir(swipeFunsDown, DOWN); + expectSwipeFuncsDir(swipeFuncsDown, DOWN); }); it('Handle "odd" rotations', () => { diff --git a/src/index.ts b/src/index.ts index fd90aeab..2d3d9755 100644 --- a/src/index.ts +++ b/src/index.ts @@ -149,6 +149,10 @@ function getHandlers( vxvy, }; + // call onSwipeStart if present and is first swipe event + eventData.first && props.onSwipeStart && props.onSwipeStart(eventData); + + // Call onSwiping if present props.onSwiping && props.onSwiping(eventData); // track if a swipe is cancelable(handler for swiping or swiped(dir) exists) diff --git a/src/types.ts b/src/types.ts index 77785d2b..7d5cec7a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -29,6 +29,7 @@ export type TapCallback = ({ event }: { event: HandledEvents }) => void; export type SwipeableCallbacks = { // Event handler/callbacks + onSwipeStart: SwipeCallback; onSwiped: SwipeCallback; onSwipedDown: SwipeCallback; onSwipedLeft: SwipeCallback; From 0d7a368abf7f074220c1ae25305ed09fbbd72da3 Mon Sep 17 00:00:00 2001 From: Emil Hartz Date: Thu, 31 Dec 2020 13:55:35 -0700 Subject: [PATCH 2/3] format --- __tests__/useSwipeable.spec.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/__tests__/useSwipeable.spec.tsx b/__tests__/useSwipeable.spec.tsx index 44a8852a..513e0ced 100644 --- a/__tests__/useSwipeable.spec.tsx +++ b/__tests__/useSwipeable.spec.tsx @@ -34,7 +34,10 @@ const TESTING_TEXT = "touch here"; /* * Wrapping component for the hook testing */ -function SwipeableUsingHook({ nodeName = "div", ...rest }: SwipeableProps & {nodeName?: string}) { +function SwipeableUsingHook({ + nodeName = "div", + ...rest +}: SwipeableProps & { nodeName?: string }) { const eventHandlers = useSwipeable(rest); const Elem = nodeName as React.ElementType; return ( @@ -224,7 +227,9 @@ describe("useSwipeable", () => { it("correctly calls onSwipeStart for first swipe event", () => { const onSwipeStart = jest.fn(); - const { getByText } = render(); + const { getByText } = render( + + ); const touchArea = getByText(TESTING_TEXT); From dffdda2b9e74b27ba5826082791843ea644457b9 Mon Sep 17 00:00:00 2001 From: Emil Hartz Date: Thu, 4 Mar 2021 15:49:29 -0700 Subject: [PATCH 3/3] update readme for onSwipeStart --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index b4fe799c..1b6f40e3 100644 --- a/README.md +++ b/README.md @@ -33,11 +33,16 @@ Spread `handlers` onto the element you wish to track swipes on. onSwipedRight, // After RIGHT swipe (SwipeEventData) => void onSwipedUp, // After UP swipe (SwipeEventData) => void onSwipedDown, // After DOWN swipe (SwipeEventData) => void + onSwipeStart, // Start of swipe (SwipeEventData) => void *see details* onSwiping, // During swiping (SwipeEventData) => void onTap, // After a tap ({ event }) => void } ``` +#### Details +- `onSwipeStart` - called only once per swipe at the start and before the first `onSwiping` callback + - The `first` property of the `SwipeEventData` will be `true` + ### Configuration props and default values ```js