Skip to content

Commit

Permalink
feat: new type for preventWheelAction: true | 'x' | 'y' | 'z' | false (
Browse files Browse the repository at this point in the history
  • Loading branch information
xiel authored May 6, 2020
1 parent a46d663 commit 0d2a4b0
Show file tree
Hide file tree
Showing 20 changed files with 58 additions and 35 deletions.
18 changes: 14 additions & 4 deletions docs/src/components/SimpleWheelDrag/SimpleWheelDrag.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useRef, useState } from 'react'
import { animated, useSpring } from 'react-spring'
import { useDrag } from 'react-use-gesture'
import { addVectors } from 'wheel-gestures'
import { addVectors, WheelGesturesConfig } from 'wheel-gestures'

import useWheelDrag from '../../hooks/useWheelDrag'
import { Plot, PlotData } from '../Plot/Plot'
Expand All @@ -14,7 +14,7 @@ export default function SimpleWheelDrag() {
const posRef = useRef([0, 0, 0])
const [{ xyz }, set] = useSpring(() => ({ xyz: [0, 0, 0] }))
const [springMomentum, setSpringMomentum] = useSpring(() => ({ xyz: [0, 0, 0] }))
const [preventWheelAction, setPreventWheelAction] = useState<'all' | 'x' | 'y'>('all')
const [preventWheelAction, setPreventWheelAction] = useState<WheelGesturesConfig['preventWheelAction']>(true)
const [wheelSource, wheelSourceSet] = useState('-')
const plotData = useRef<PlotData[]>([])

Expand Down Expand Up @@ -81,8 +81,18 @@ export default function SimpleWheelDrag() {
<WheelRecorder domTarget={containerRef} />
<label>
preventWheelAction{' '}
<select value={preventWheelAction} onChange={(e) => setPreventWheelAction(e.target.value as any)}>
<option>all</option>
<select
value={preventWheelAction.toString()}
onChange={({ target }) => {
try {
setPreventWheelAction(JSON.parse(target.value))
} catch (e) {
setPreventWheelAction(target.value as WheelGesturesConfig['preventWheelAction'])
}
}}
>
<option>true</option>
<option>false</option>
<option>x</option>
<option>y</option>
</select>
Expand Down
10 changes: 5 additions & 5 deletions src/test/helper/recordPhases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ export function subscribeAndFeedWheelEvents({ beforeFeed, callback, wheelEvents
// need to use fake timers, so we can run the debounced end function after feeding all events
jest.useFakeTimers()

const wheelAnalyzer = WheelGestures({ reverseSign: false })
const wheelGestures = WheelGestures({ reverseSign: false })

callback && wheelAnalyzer.on('wheel', callback)
wheelAnalyzer.on('wheel', (data) => allPhaseData.push(data))
callback && wheelGestures.on('wheel', callback)
wheelGestures.on('wheel', (data) => allPhaseData.push(data))

let prevTimeStamp = 0

Expand All @@ -27,7 +27,7 @@ export function subscribeAndFeedWheelEvents({ beforeFeed, callback, wheelEvents
}

beforeFeed && beforeFeed(e, i)
wheelAnalyzer.feedWheel(e)
wheelGestures.feedWheel(e)

prevTimeStamp = e.timeStamp
})
Expand All @@ -38,7 +38,7 @@ export function subscribeAndFeedWheelEvents({ beforeFeed, callback, wheelEvents

feedEvents(wheelEvents)

return { wheelAnalyzer, allPhaseData, feedEvents }
return { wheelGestures, allPhaseData, feedEvents }
}

export type Range = [number, number]
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import { EventListener, WheelEventData, WheelGestures, WheelGesturesEventMap, WheelGesturesOptions } from '../..'
import { WheelEventData, WheelGestures, WheelGesturesOptions } from '../..'
import slowDragRight from '../fixtures/slow-drag-right.json'
import squareMoveTrackpad from '../fixtures/square-move-trackpad.json'
import swipeUpTrackpad from '../fixtures/swipe-up-trackpad.json'
import { generateEvents } from '../helper/generateEvents'

interface Opts {
callback?: EventListener<WheelGesturesEventMap['wheel']>
options?: WheelGesturesOptions
}

function feedWheelEvents(wheelEvents: WheelEventData[], { callback = () => undefined, options }: Opts = {}) {
function feedWheelEvents(wheelEvents: WheelEventData[], { options }: Opts = {}) {
// need to use fake timers, so we can run the debounced end function after feeding all events
jest.useFakeTimers()
const wA = WheelGestures(options)
const unsubscribe = wA.on('wheel', callback)
wA.feedWheel(wheelEvents)
// fast forward and exhaust currently pending timers
jest.runOnlyPendingTimers()
unsubscribe()
}

function testPreventWheelActionWithOptions(wheelEvents: WheelEventData[], opts: Opts = {}) {
Expand Down Expand Up @@ -93,6 +91,17 @@ describe('preventDefault should be called when drag is on defined axis', () => {
})
})

test('can disable calling preventDefault using preventWheelAction: false', () => {
const { wheelEventsWithPreventDefault, preventDefault } = testPreventWheelActionWithOptions(
generateEvents({ deltaTotal: [100, 100, 100], durationMs: 100 }).wheelEvents,
{ options: { preventWheelAction: false } }
)

// preventDefault should never be called
expect(wheelEventsWithPreventDefault.length).toBe(6)
expect(preventDefault).toBeCalledTimes(0)
})

test('should warn about unsupported preventWheelAction in debug mode', () => {
const logWarn = spyOn(console, 'warn')

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { subscribeAndFeedWheelEvents } from '../helper/recordPhases'

describe('updateOptions', () => {
it('should be able to switch option (preventWheelAction)', function() {
const { feedEvents, wheelAnalyzer } = subscribeAndFeedWheelEvents()
const { feedEvents, wheelGestures } = subscribeAndFeedWheelEvents()
const preventDefault = jest.fn()

function feedDeltaYEvent() {
Expand All @@ -17,27 +17,27 @@ describe('updateOptions', () => {
])
}

wheelAnalyzer.updateOptions({ preventWheelAction: 'x' })
wheelGestures.updateOptions({ preventWheelAction: 'x' })
feedDeltaYEvent()
expect(preventDefault).toHaveBeenCalledTimes(0)

wheelAnalyzer.updateOptions({ preventWheelAction: 'y' })
wheelGestures.updateOptions({ preventWheelAction: 'y' })
feedDeltaYEvent()
expect(preventDefault).toHaveBeenCalledTimes(1)

wheelAnalyzer.updateOptions({})
wheelGestures.updateOptions({})
feedDeltaYEvent()
expect(preventDefault).toHaveBeenCalledTimes(2)

wheelAnalyzer.updateOptions({ preventWheelAction: 'x' })
wheelGestures.updateOptions({ preventWheelAction: 'x' })
feedDeltaYEvent()
expect(preventDefault).toHaveBeenCalledTimes(2)
})

it('should return default config by creating & calling updateOptions empty', () => {
expect(WheelGestures().updateOptions()).toMatchInlineSnapshot(`
Object {
"preventWheelAction": "all",
"preventWheelAction": true,
"reverseSign": Array [
true,
true,
Expand Down
4 changes: 2 additions & 2 deletions src/wheel-gestures/options.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { deepFreeze } from '../utils'
import { BooleanXYZ } from './wheel-gestures-types'

export type PreventWheelActionType = 'all' | 'x' | 'y'
export type PreventWheelActionType = true | 'x' | 'y' | 'z' | false
export type ReverseSign = BooleanXYZ | boolean

export interface WheelGesturesConfig {
Expand All @@ -13,6 +13,6 @@ export interface WheelGesturesConfig {
export type WheelGesturesOptions = Partial<WheelGesturesConfig>

export const configDefaults: WheelGesturesConfig = deepFreeze({
preventWheelAction: 'all',
preventWheelAction: true,
reverseSign: [true, true, false],
})
2 changes: 1 addition & 1 deletion src/wheel-gestures/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { WheelGesturesInternalState } from './wheel-gestures-types'
*/
const WILL_END_TIMEOUT_DEFAULT = 400

export function createWheelAnalyzerState(): WheelGesturesInternalState {
export function createWheelGesturesState(): WheelGesturesInternalState {
return {
isStarted: false,
isStartPublished: false,
Expand Down
28 changes: 16 additions & 12 deletions src/wheel-gestures/wheel-gestures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import EventBus from '../events/EventBus'
import { absMax, addVectors, average, deepFreeze, lastOf } from '../utils'
import { clampAxisDelta, normalizeWheel, reverseAxisDeltaSign } from '../wheel-normalizer/wheel-normalizer'
import { configDefaults, WheelGesturesConfig, WheelGesturesOptions } from './options'
import { createWheelAnalyzerState } from './state'
import { createWheelGesturesState } from './state'
import {
MergedScrollPoint,
Unobserve,
Expand All @@ -21,7 +21,7 @@ const WHEELEVENTS_TO_ANALAZE = 5
export function WheelGestures(optionsParam: WheelGesturesOptions = {}) {
const { on, off, dispatch } = EventBus<WheelGesturesEventMap>()
let config = configDefaults
let state = createWheelAnalyzerState()
let state = createWheelGesturesState()
let targets: EventTarget[] = []
let currentEvent: WheelEventData
let negativeZeroFingerUpSpecialEvent = false
Expand Down Expand Up @@ -83,20 +83,24 @@ export function WheelGestures(optionsParam: WheelGesturesOptions = {}) {
return (config = deepFreeze({ ...configDefaults, ...config, ...newOptions }))
}

const shouldPreventDefault = (e: WheelEventData) => {
// should prevent when there is mainly movement on the desired axis
const shouldPreventDefault = (deltaMaxAbs: number, axisDelta: VectorXYZ): boolean => {
const { preventWheelAction } = config
const { deltaX, deltaY } = e
const [deltaX, deltaY, deltaZ] = axisDelta

if (typeof preventWheelAction === 'boolean') return preventWheelAction

switch (preventWheelAction) {
case 'all':
return true
case 'x':
return Math.abs(deltaX) >= Math.abs(deltaY)
return Math.abs(deltaX) >= deltaMaxAbs
case 'y':
return Math.abs(deltaY) >= Math.abs(deltaX)
return Math.abs(deltaY) >= deltaMaxAbs
case 'z':
return Math.abs(deltaZ) >= deltaMaxAbs
default:
isDev && console.warn('unsupported preventWheelAction value: ' + preventWheelAction, 'warn')
return false
}

isDev && console.warn('unsupported preventWheelAction value: ' + preventWheelAction, 'warn')
}

const processWheelEventData = (wheelEvent: WheelEventData) => {
Expand All @@ -105,7 +109,7 @@ export function WheelGestures(optionsParam: WheelGesturesOptions = {}) {
)
const deltaMaxAbs = absMax(axisDelta)

if (wheelEvent.preventDefault && shouldPreventDefault(wheelEvent)) {
if (wheelEvent.preventDefault && shouldPreventDefault(deltaMaxAbs, axisDelta)) {
wheelEvent.preventDefault()
}

Expand Down Expand Up @@ -261,7 +265,7 @@ export function WheelGestures(optionsParam: WheelGesturesOptions = {}) {
}

const start = () => {
state = createWheelAnalyzerState()
state = createWheelGesturesState()
state.isStarted = true
state.startTime = Date.now()
prevWheelEventState = undefined
Expand Down

0 comments on commit 0d2a4b0

Please sign in to comment.