Skip to content

Commit bff8798

Browse files
committed
attach touch listeners to ref el
1 parent e543107 commit bff8798

File tree

1 file changed

+66
-49
lines changed

1 file changed

+66
-49
lines changed

Diff for: src/index.js

+66-49
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const LEFT = 'Left'
1919
export const RIGHT = 'Right'
2020
export const UP = 'Up'
2121
export const DOWN = 'Down'
22+
const touchStart = 'touchstart'
2223
const touchMove = 'touchmove'
2324
const touchEnd = 'touchend'
2425
const mouseMove = 'mousemove'
@@ -46,22 +47,19 @@ function rotateXYByAngle(pos, angle) {
4647
return [x, y]
4748
}
4849

49-
const getTouchHandlerOption = props => {
50-
if (props.touchHandlerOption) return props.touchHandlerOption
51-
return props.preventDefaultTouchmoveEvent
52-
? { passive: false }
53-
: { passive: true }
54-
}
55-
5650
function getHandlers(set, props) {
5751
const onStart = event => {
5852
// if more than a single touch don't track, for now...
5953
if (event.touches && event.touches.length > 1) return
6054

61-
set(() => {
55+
set(state => {
56+
if (state.props.trackMouse) {
57+
document.addEventListener(mouseMove, onMove)
58+
document.addEventListener(mouseUp, onUp)
59+
}
6260
const { clientX, clientY } = event.touches ? event.touches[0] : event
63-
const xy = rotateXYByAngle([clientX, clientY], props.rotationAngle)
64-
return { ...initialState, xy, start: event.timeStamp || 0 }
61+
const xy = rotateXYByAngle([clientX, clientY], state.props.rotationAngle)
62+
return { ...state, ...initialState, xy, start: event.timeStamp || 0 }
6563
})
6664
}
6765

@@ -75,7 +73,10 @@ function getHandlers(set, props) {
7573
return state
7674
}
7775
const { clientX, clientY } = event.touches ? event.touches[0] : event
78-
const [x, y] = rotateXYByAngle([clientX, clientY], props.rotationAngle)
76+
const [x, y] = rotateXYByAngle(
77+
[clientX, clientY],
78+
state.props.rotationAngle
79+
)
7980
const deltaX = state.xy[0] - x
8081
const deltaY = state.xy[1] - y
8182
const absX = Math.abs(deltaX)
@@ -90,19 +91,23 @@ function getHandlers(set, props) {
9091
const dir = getDirection(absX, absY, deltaX, deltaY)
9192
const eventData = { event, absX, absY, deltaX, deltaY, velocity, dir }
9293

93-
props.onSwiping && props.onSwiping(eventData)
94+
state.props.onSwiping && state.props.onSwiping(eventData)
9495

9596
// track if a swipe is cancelable(handler for swiping or swiped(dir) exists)
9697
// so we can call preventDefault if needed
9798
let cancelablePageSwipe = false
98-
if (props.onSwiping || props.onSwiped || props[`onSwiped${dir}`]) {
99+
if (
100+
state.props.onSwiping ||
101+
state.props.onSwiped ||
102+
state.props[`onSwiped${dir}`]
103+
) {
99104
cancelablePageSwipe = true
100105
}
101106

102107
if (
103108
cancelablePageSwipe &&
104-
props.preventDefaultTouchmoveEvent &&
105-
props.trackTouch
109+
state.props.preventDefaultTouchmoveEvent &&
110+
state.props.trackTouch
106111
)
107112
event.preventDefault()
108113

@@ -115,58 +120,69 @@ function getHandlers(set, props) {
115120
if (state.swiping) {
116121
const eventData = { ...state.lastEventData, event }
117122

118-
props.onSwiped && props.onSwiped(eventData)
123+
state.props.onSwiped && state.props.onSwiped(eventData)
119124

120-
props[`onSwiped${eventData.dir}`] &&
121-
props[`onSwiped${eventData.dir}`](eventData)
125+
state.props[`onSwiped${eventData.dir}`] &&
126+
state.props[`onSwiped${eventData.dir}`](eventData)
122127
}
123-
return { ...initialState }
128+
return { ...state, ...initialState }
124129
})
125130
}
126131

127-
const onDown = e => {
128-
if (props.trackMouse) {
129-
document.addEventListener(mouseMove, onMove)
130-
document.addEventListener(mouseUp, onUp)
131-
}
132-
if (props.trackTouch) {
133-
const touchHandlerOption = getTouchHandlerOption(props)
134-
document.addEventListener(touchMove, onMove, touchHandlerOption)
135-
document.addEventListener(touchEnd, onUp, touchHandlerOption)
136-
}
137-
onStart(e)
138-
}
139-
140132
const stop = () => {
141-
if (props.trackMouse) {
142-
document.removeEventListener(mouseMove, onMove)
143-
document.removeEventListener(mouseUp, onUp)
144-
}
145-
if (props.trackTouch) {
146-
const touchHandlerOption = getTouchHandlerOption(props)
147-
document.removeEventListener(touchMove, onMove, touchHandlerOption)
148-
document.removeEventListener(touchEnd, onUp, touchHandlerOption)
149-
}
133+
set(state => {
134+
if (state.props.trackMouse) {
135+
document.removeEventListener(mouseMove, onMove)
136+
document.removeEventListener(mouseUp, onUp)
137+
}
138+
return state
139+
})
150140
}
151141

152142
const onUp = e => {
153143
stop()
154144
onEnd(e)
155145
}
156146

157-
const output = {}
158-
if (props.trackMouse) {
159-
output.onMouseDown = onDown
147+
const cleanUp = el => {
148+
if (el && el.removeEventListener) {
149+
el.removeEventListener(touchStart, onStart)
150+
el.removeEventListener(touchMove, onMove)
151+
el.removeEventListener(touchEnd, onUp)
152+
}
160153
}
161-
if (props.trackTouch) {
162-
output.onTouchStart = onDown
154+
155+
const onRef = el => {
156+
if (el === null) return
157+
set(state => {
158+
if (state.el === el) return state
159+
if (state.el && state.el !== el) cleanUp(state.el)
160+
if (state.props.trackTouch) {
161+
if (el && el.addEventListener) {
162+
el.addEventListener(touchStart, onStart)
163+
el.addEventListener(touchMove, onMove)
164+
el.addEventListener(touchEnd, onUp)
165+
return { ...state, el }
166+
}
167+
}
168+
return state
169+
})
170+
}
171+
172+
// set ref callback to attach touch event listeners
173+
const output = { ref: onRef }
174+
if (props.trackMouse) {
175+
output.onMouseDown = onStart
163176
}
164177

178+
// update props
179+
set(state => ({ ...state, props }))
180+
165181
return output
166182
}
167183

168184
export function useSwipeable(props) {
169-
const transientState = React.useRef(initialState)
185+
const transientState = React.useRef({ ...initialState, type: 'hook' })
170186
const [spread] = React.useState(() => currentProps =>
171187
getHandlers(cb => (transientState.current = cb(transientState.current)), {
172188
...defaultProps,
@@ -200,7 +216,7 @@ export class Swipeable extends React.PureComponent {
200216

201217
constructor(props) {
202218
super(props)
203-
this._state = initialState
219+
this._state = { ...initialState, type: 'class' }
204220
this._set = cb => (this._state = cb(this._state))
205221
}
206222

@@ -214,9 +230,10 @@ export class Swipeable extends React.PureComponent {
214230
...rest
215231
} = this.props
216232
const handlers = getHandlers(this._set, rest)
233+
const ref = innerRef ? el => (innerRef(el), handlers.ref(el)) : handlers.ref
217234
return React.createElement(
218235
nodeName,
219-
{ ...handlers, className, style, ref: innerRef },
236+
{ ...handlers, className, style, ref },
220237
children
221238
)
222239
}

0 commit comments

Comments
 (0)