@uxf/core-react 11.70.0 → 11.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/swipeable/types.d.ts +152 -0
- package/swipeable/types.js +7 -0
- package/swipeable/use-swipeable.d.ts +3 -0
- package/swipeable/use-swipeable.js +314 -0
package/package.json
CHANGED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { MouseEvent as ReactMouseEvent } from "react";
|
|
2
|
+
export declare const LEFT = "Left";
|
|
3
|
+
export declare const RIGHT = "Right";
|
|
4
|
+
export declare const UP = "Up";
|
|
5
|
+
export declare const DOWN = "Down";
|
|
6
|
+
export type HandledEvents = ReactMouseEvent | TouchEvent | MouseEvent;
|
|
7
|
+
export type Vector2 = [number, number];
|
|
8
|
+
export type SwipeDirections = typeof LEFT | typeof RIGHT | typeof UP | typeof DOWN;
|
|
9
|
+
export interface SwipeEventData {
|
|
10
|
+
/**
|
|
11
|
+
* Absolute displacement of swipe in x. Math.abs(deltaX);
|
|
12
|
+
*/
|
|
13
|
+
absX: number;
|
|
14
|
+
/**
|
|
15
|
+
* Absolute displacement of swipe in y. Math.abs(deltaY);
|
|
16
|
+
*/
|
|
17
|
+
absY: number;
|
|
18
|
+
/**
|
|
19
|
+
* Displacement of swipe in x. (current.x - initial.x)
|
|
20
|
+
*/
|
|
21
|
+
deltaX: number;
|
|
22
|
+
/**
|
|
23
|
+
* Displacement of swipe in y. (current.y - initial.y)
|
|
24
|
+
*/
|
|
25
|
+
deltaY: number;
|
|
26
|
+
/**
|
|
27
|
+
* Direction of swipe - Left | Right | Up | Down
|
|
28
|
+
*/
|
|
29
|
+
dir: SwipeDirections;
|
|
30
|
+
/**
|
|
31
|
+
* Source event.
|
|
32
|
+
*/
|
|
33
|
+
event: HandledEvents;
|
|
34
|
+
/**
|
|
35
|
+
* True for the first event of a tracked swipe.
|
|
36
|
+
*/
|
|
37
|
+
first: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Location where swipe started - [x, y].
|
|
40
|
+
*/
|
|
41
|
+
initial: Vector2;
|
|
42
|
+
/**
|
|
43
|
+
* "Absolute velocity" (speed) - √(absX^2 + absY^2) / time
|
|
44
|
+
*/
|
|
45
|
+
velocity: number;
|
|
46
|
+
/**
|
|
47
|
+
* Velocity per axis - [ deltaX/time, deltaY/time ]
|
|
48
|
+
*/
|
|
49
|
+
vxvy: Vector2;
|
|
50
|
+
}
|
|
51
|
+
export type SwipeCallback = (eventData: SwipeEventData) => void;
|
|
52
|
+
export type TapCallback = ({ event }: {
|
|
53
|
+
event: HandledEvents;
|
|
54
|
+
}) => void;
|
|
55
|
+
export type SwipeableDirectionCallbacks = {
|
|
56
|
+
/**
|
|
57
|
+
* Called after a DOWN swipe
|
|
58
|
+
*/
|
|
59
|
+
onSwipedDown: SwipeCallback;
|
|
60
|
+
/**
|
|
61
|
+
* Called after a LEFT swipe
|
|
62
|
+
*/
|
|
63
|
+
onSwipedLeft: SwipeCallback;
|
|
64
|
+
/**
|
|
65
|
+
* Called after a RIGHT swipe
|
|
66
|
+
*/
|
|
67
|
+
onSwipedRight: SwipeCallback;
|
|
68
|
+
/**
|
|
69
|
+
* Called after a UP swipe
|
|
70
|
+
*/
|
|
71
|
+
onSwipedUp: SwipeCallback;
|
|
72
|
+
};
|
|
73
|
+
export type SwipeableCallbacks = SwipeableDirectionCallbacks & {
|
|
74
|
+
/**
|
|
75
|
+
* Called at start of a tracked swipe.
|
|
76
|
+
*/
|
|
77
|
+
onSwipeStart: SwipeCallback;
|
|
78
|
+
/**
|
|
79
|
+
* Called after any swipe.
|
|
80
|
+
*/
|
|
81
|
+
onSwiped: SwipeCallback;
|
|
82
|
+
/**
|
|
83
|
+
* Called for each move event during a tracked swipe.
|
|
84
|
+
*/
|
|
85
|
+
onSwiping: SwipeCallback;
|
|
86
|
+
/**
|
|
87
|
+
* Called after a tap. A touch under the min distance, `delta`.
|
|
88
|
+
*/
|
|
89
|
+
onTap: TapCallback;
|
|
90
|
+
/**
|
|
91
|
+
* Called for `touchstart` and `mousedown`.
|
|
92
|
+
*/
|
|
93
|
+
onTouchStartOrOnMouseDown: TapCallback;
|
|
94
|
+
/**
|
|
95
|
+
* Called for `touchend` and `mouseup`.
|
|
96
|
+
*/
|
|
97
|
+
onTouchEndOrOnMouseUp: TapCallback;
|
|
98
|
+
};
|
|
99
|
+
export type ConfigurationOptionDelta = number | {
|
|
100
|
+
[key in Lowercase<SwipeDirections>]?: number;
|
|
101
|
+
};
|
|
102
|
+
export interface ConfigurationOptions {
|
|
103
|
+
/**
|
|
104
|
+
* Min distance(px) before a swipe starts. **Default**: `10`
|
|
105
|
+
*/
|
|
106
|
+
delta: ConfigurationOptionDelta;
|
|
107
|
+
/**
|
|
108
|
+
* Prevents scroll during swipe in most cases. **Default**: `false`
|
|
109
|
+
*/
|
|
110
|
+
preventScrollOnSwipe: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Set a rotation angle. **Default**: `0`
|
|
113
|
+
*/
|
|
114
|
+
rotationAngle: number;
|
|
115
|
+
/**
|
|
116
|
+
* Track mouse input. **Default**: `false`
|
|
117
|
+
*/
|
|
118
|
+
trackMouse: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Track touch input. **Default**: `true`
|
|
121
|
+
*/
|
|
122
|
+
trackTouch: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Allowable duration of a swipe (ms). **Default**: `Infinity`
|
|
125
|
+
*/
|
|
126
|
+
swipeDuration: number;
|
|
127
|
+
/**
|
|
128
|
+
* Options for touch event listeners
|
|
129
|
+
*/
|
|
130
|
+
touchEventOptions: {
|
|
131
|
+
passive: boolean;
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
export type SwipeableProps = Partial<SwipeableCallbacks & ConfigurationOptions>;
|
|
135
|
+
export type SwipeablePropsWithDefaultOptions = Partial<SwipeableCallbacks> & ConfigurationOptions;
|
|
136
|
+
export interface SwipeableHandlers {
|
|
137
|
+
ref(element: HTMLElement | null): void;
|
|
138
|
+
onMouseDown?(event: React.MouseEvent): void;
|
|
139
|
+
}
|
|
140
|
+
export type SwipeableState = {
|
|
141
|
+
cleanUpTouch?: () => void;
|
|
142
|
+
el?: HTMLElement;
|
|
143
|
+
eventData?: SwipeEventData;
|
|
144
|
+
first: boolean;
|
|
145
|
+
initial: Vector2;
|
|
146
|
+
start: number;
|
|
147
|
+
swiping: boolean;
|
|
148
|
+
xy: Vector2;
|
|
149
|
+
};
|
|
150
|
+
export type StateSetter = (state: SwipeableState, props: SwipeablePropsWithDefaultOptions) => SwipeableState;
|
|
151
|
+
export type Setter = (stateSetter: StateSetter) => void;
|
|
152
|
+
export type AttachTouch = (el: HTMLElement, props: SwipeablePropsWithDefaultOptions) => () => void;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { DOWN, LEFT, RIGHT, SwipeableDirectionCallbacks, SwipeableHandlers, SwipeableProps, SwipeCallback, SwipeDirections, SwipeEventData, TapCallback, UP, Vector2 } from "./types";
|
|
2
|
+
export { DOWN, LEFT, RIGHT, UP, type SwipeableDirectionCallbacks, type SwipeableHandlers, type SwipeableProps, type SwipeCallback, type SwipeDirections, type SwipeEventData, type TapCallback, type Vector2, };
|
|
3
|
+
export declare function useSwipeable(options: SwipeableProps): SwipeableHandlers;
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UP = exports.RIGHT = exports.LEFT = exports.DOWN = void 0;
|
|
4
|
+
exports.useSwipeable = useSwipeable;
|
|
5
|
+
const is_not_nil_1 = require("@uxf/core/utils/is-not-nil");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const types_1 = require("./types");
|
|
8
|
+
Object.defineProperty(exports, "DOWN", { enumerable: true, get: function () { return types_1.DOWN; } });
|
|
9
|
+
Object.defineProperty(exports, "LEFT", { enumerable: true, get: function () { return types_1.LEFT; } });
|
|
10
|
+
Object.defineProperty(exports, "RIGHT", { enumerable: true, get: function () { return types_1.RIGHT; } });
|
|
11
|
+
Object.defineProperty(exports, "UP", { enumerable: true, get: function () { return types_1.UP; } });
|
|
12
|
+
const defaultProps = {
|
|
13
|
+
delta: 10,
|
|
14
|
+
preventScrollOnSwipe: false,
|
|
15
|
+
rotationAngle: 0,
|
|
16
|
+
trackMouse: false,
|
|
17
|
+
trackTouch: true,
|
|
18
|
+
swipeDuration: Infinity,
|
|
19
|
+
touchEventOptions: { passive: true },
|
|
20
|
+
};
|
|
21
|
+
const initialState = {
|
|
22
|
+
first: true,
|
|
23
|
+
initial: [0, 0],
|
|
24
|
+
start: 0,
|
|
25
|
+
swiping: false,
|
|
26
|
+
xy: [0, 0],
|
|
27
|
+
};
|
|
28
|
+
const mouseMove = "mousemove";
|
|
29
|
+
const mouseUp = "mouseup";
|
|
30
|
+
const touchEnd = "touchend";
|
|
31
|
+
const touchMove = "touchmove";
|
|
32
|
+
const touchStart = "touchstart";
|
|
33
|
+
function getDirection(absX, absY, deltaX, deltaY) {
|
|
34
|
+
if (absX > absY) {
|
|
35
|
+
if (deltaX > 0) {
|
|
36
|
+
return types_1.RIGHT;
|
|
37
|
+
}
|
|
38
|
+
return types_1.LEFT;
|
|
39
|
+
}
|
|
40
|
+
else if (deltaY > 0) {
|
|
41
|
+
return types_1.DOWN;
|
|
42
|
+
}
|
|
43
|
+
return types_1.UP;
|
|
44
|
+
}
|
|
45
|
+
function rotateXYByAngle(pos, angle) {
|
|
46
|
+
if (angle === 0) {
|
|
47
|
+
return pos;
|
|
48
|
+
}
|
|
49
|
+
const angleInRadians = (Math.PI / 180) * angle;
|
|
50
|
+
const x = pos[0] * Math.cos(angleInRadians) + pos[1] * Math.sin(angleInRadians);
|
|
51
|
+
const y = pos[1] * Math.cos(angleInRadians) - pos[0] * Math.sin(angleInRadians);
|
|
52
|
+
return [x, y];
|
|
53
|
+
}
|
|
54
|
+
function getHandlers(set, handlerProps) {
|
|
55
|
+
const onStart = (event) => {
|
|
56
|
+
const isTouch = "touches" in event;
|
|
57
|
+
// if more than a single touch don't track, for now...
|
|
58
|
+
if (isTouch && event.touches.length > 1) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
set((state, props) => {
|
|
62
|
+
var _a;
|
|
63
|
+
// setup mouse listeners on document to track swipe since swipe can leave container
|
|
64
|
+
if (props.trackMouse && !isTouch) {
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
66
|
+
document.addEventListener(mouseMove, onMove);
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
68
|
+
document.addEventListener(mouseUp, onUp);
|
|
69
|
+
}
|
|
70
|
+
const { clientX, clientY } = isTouch ? event.touches[0] : event;
|
|
71
|
+
const xy = rotateXYByAngle([clientX, clientY], props.rotationAngle);
|
|
72
|
+
(_a = props.onTouchStartOrOnMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, { event });
|
|
73
|
+
return {
|
|
74
|
+
...state,
|
|
75
|
+
...initialState,
|
|
76
|
+
initial: xy.slice(),
|
|
77
|
+
xy,
|
|
78
|
+
start: event.timeStamp || 0,
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
const onMove = (event) => {
|
|
83
|
+
// eslint-disable-next-line complexity
|
|
84
|
+
set((state, props) => {
|
|
85
|
+
var _a, _b;
|
|
86
|
+
const isTouch = "touches" in event;
|
|
87
|
+
// Discount a swipe if additional touches are present after
|
|
88
|
+
// a swipe has started.
|
|
89
|
+
if (isTouch && event.touches.length > 1) {
|
|
90
|
+
return state;
|
|
91
|
+
}
|
|
92
|
+
// if swipe has exceeded duration stop tracking
|
|
93
|
+
if (event.timeStamp - state.start > props.swipeDuration) {
|
|
94
|
+
return state.swiping ? { ...state, swiping: false } : state;
|
|
95
|
+
}
|
|
96
|
+
const { clientX, clientY } = isTouch ? event.touches[0] : event;
|
|
97
|
+
const [x, y] = rotateXYByAngle([clientX, clientY], props.rotationAngle);
|
|
98
|
+
const deltaX = x - state.xy[0];
|
|
99
|
+
const deltaY = y - state.xy[1];
|
|
100
|
+
const absX = Math.abs(deltaX);
|
|
101
|
+
const absY = Math.abs(deltaY);
|
|
102
|
+
const time = (event.timeStamp || 0) - state.start;
|
|
103
|
+
const velocity = Math.sqrt(absX * absX + absY * absY) / (time || 1);
|
|
104
|
+
const vxvy = [deltaX / (time || 1), deltaY / (time || 1)];
|
|
105
|
+
const dir = getDirection(absX, absY, deltaX, deltaY);
|
|
106
|
+
// if swipe is under delta and we have not started to track a swipe: skip update
|
|
107
|
+
const delta = typeof props.delta === "number"
|
|
108
|
+
? props.delta
|
|
109
|
+
: props.delta[dir.toLowerCase()] || defaultProps.delta;
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
111
|
+
// @ts-ignore
|
|
112
|
+
if (absX < delta && absY < delta && !state.swiping) {
|
|
113
|
+
return state;
|
|
114
|
+
}
|
|
115
|
+
const eventData = {
|
|
116
|
+
absX,
|
|
117
|
+
absY,
|
|
118
|
+
deltaX,
|
|
119
|
+
deltaY,
|
|
120
|
+
dir,
|
|
121
|
+
event,
|
|
122
|
+
first: state.first,
|
|
123
|
+
initial: state.initial,
|
|
124
|
+
velocity,
|
|
125
|
+
vxvy,
|
|
126
|
+
};
|
|
127
|
+
// call onSwipeStart if present and is first swipe event
|
|
128
|
+
if (eventData.first) {
|
|
129
|
+
(_a = props.onSwipeStart) === null || _a === void 0 ? void 0 : _a.call(props, eventData);
|
|
130
|
+
}
|
|
131
|
+
// call onSwiping if present
|
|
132
|
+
(_b = props.onSwiping) === null || _b === void 0 ? void 0 : _b.call(props, eventData);
|
|
133
|
+
// track if a swipe is cancelable (handler for swiping or swiped(dir) exists)
|
|
134
|
+
// so we can call preventDefault if needed
|
|
135
|
+
let cancelablePageSwipe = false;
|
|
136
|
+
if (props.onSwiping || props.onSwiped || props[`onSwiped${dir}`]) {
|
|
137
|
+
cancelablePageSwipe = true;
|
|
138
|
+
}
|
|
139
|
+
if (cancelablePageSwipe && props.preventScrollOnSwipe && props.trackTouch && event.cancelable) {
|
|
140
|
+
event.preventDefault();
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
...state,
|
|
144
|
+
// first is now always false
|
|
145
|
+
first: false,
|
|
146
|
+
eventData,
|
|
147
|
+
swiping: true,
|
|
148
|
+
};
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
const onEnd = (event) => {
|
|
152
|
+
set((state, props) => {
|
|
153
|
+
var _a, _b, _c;
|
|
154
|
+
let eventData;
|
|
155
|
+
if (state.swiping && state.eventData) {
|
|
156
|
+
// if swipe is less than duration fire swiped callbacks
|
|
157
|
+
if (event.timeStamp - state.start < props.swipeDuration) {
|
|
158
|
+
eventData = { ...state.eventData, event };
|
|
159
|
+
(_a = props.onSwiped) === null || _a === void 0 ? void 0 : _a.call(props, eventData);
|
|
160
|
+
const onSwipedDir = props[`onSwiped${eventData.dir}`];
|
|
161
|
+
onSwipedDir === null || onSwipedDir === void 0 ? void 0 : onSwipedDir(eventData);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
(_b = props.onTap) === null || _b === void 0 ? void 0 : _b.call(props, { event });
|
|
166
|
+
}
|
|
167
|
+
(_c = props.onTouchEndOrOnMouseUp) === null || _c === void 0 ? void 0 : _c.call(props, { event });
|
|
168
|
+
return { ...state, ...initialState, eventData };
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
const cleanUpMouse = () => {
|
|
172
|
+
// safe to just call removeEventListener
|
|
173
|
+
document.removeEventListener(mouseMove, onMove);
|
|
174
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
175
|
+
document.removeEventListener(mouseUp, onUp);
|
|
176
|
+
};
|
|
177
|
+
const onUp = (e) => {
|
|
178
|
+
cleanUpMouse();
|
|
179
|
+
onEnd(e);
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* The value of passive on touchMove depends on `preventScrollOnSwipe`:
|
|
183
|
+
* - true => { passive: false }
|
|
184
|
+
* - false => { passive: true } // Default
|
|
185
|
+
*
|
|
186
|
+
* NOTE: When preventScrollOnSwipe is true, we attempt to call preventDefault to prevent scroll.
|
|
187
|
+
*
|
|
188
|
+
* props.touchEventOptions can also be set for all touch event listeners,
|
|
189
|
+
* but for `touchmove` specifically when `preventScrollOnSwipe` it will
|
|
190
|
+
* supersede and force passive to false.
|
|
191
|
+
*
|
|
192
|
+
*/
|
|
193
|
+
const attachTouch = (el, props) => {
|
|
194
|
+
// eslint-disable-next-line no-empty-function
|
|
195
|
+
let cleanup = () => { };
|
|
196
|
+
if ((0, is_not_nil_1.isNotNil)(el) && (0, is_not_nil_1.isNotNil)(el.addEventListener)) {
|
|
197
|
+
const baseOptions = {
|
|
198
|
+
...defaultProps.touchEventOptions,
|
|
199
|
+
...props.touchEventOptions,
|
|
200
|
+
};
|
|
201
|
+
// attach touch event listeners and handlers
|
|
202
|
+
const tls = [
|
|
203
|
+
[touchStart, onStart, baseOptions],
|
|
204
|
+
// preventScrollOnSwipe option supersedes touchEventOptions.passive
|
|
205
|
+
[
|
|
206
|
+
touchMove,
|
|
207
|
+
onMove,
|
|
208
|
+
{
|
|
209
|
+
...baseOptions,
|
|
210
|
+
...(props.preventScrollOnSwipe ? { passive: false } : {}),
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
[touchEnd, onEnd, baseOptions],
|
|
214
|
+
];
|
|
215
|
+
tls.forEach(([e, h, o]) => el.addEventListener(e, h, o));
|
|
216
|
+
// return properly scoped cleanup method for removing listeners, options not required
|
|
217
|
+
cleanup = () => tls.forEach(([e, h]) => el.removeEventListener(e, h));
|
|
218
|
+
}
|
|
219
|
+
return cleanup;
|
|
220
|
+
};
|
|
221
|
+
const onRef = (el) => {
|
|
222
|
+
// "inline" ref functions are called twice on render, once with null then again with DOM element
|
|
223
|
+
// ignore null here
|
|
224
|
+
if (el === null) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
set((state, props) => {
|
|
228
|
+
// if the same DOM el as previous just return state
|
|
229
|
+
if (state.el === el) {
|
|
230
|
+
return state;
|
|
231
|
+
}
|
|
232
|
+
const addState = {};
|
|
233
|
+
// if new DOM el clean up old DOM and reset cleanUpTouch
|
|
234
|
+
if (state.el && state.el !== el && state.cleanUpTouch) {
|
|
235
|
+
state.cleanUpTouch();
|
|
236
|
+
addState.cleanUpTouch = void 0;
|
|
237
|
+
}
|
|
238
|
+
// only attach if we want to track touch
|
|
239
|
+
if (props.trackTouch) {
|
|
240
|
+
addState.cleanUpTouch = attachTouch(el, props);
|
|
241
|
+
}
|
|
242
|
+
// store event attached DOM el for comparison, clean up, and re-attachment
|
|
243
|
+
return { ...state, el, ...addState };
|
|
244
|
+
});
|
|
245
|
+
};
|
|
246
|
+
// set ref callback to attach touch event listeners
|
|
247
|
+
const output = {
|
|
248
|
+
ref: onRef,
|
|
249
|
+
};
|
|
250
|
+
// if track mouse attach mouse down listener
|
|
251
|
+
if (handlerProps.trackMouse) {
|
|
252
|
+
output.onMouseDown = onStart;
|
|
253
|
+
}
|
|
254
|
+
return [output, attachTouch];
|
|
255
|
+
}
|
|
256
|
+
function updateTransientState(state, props, previousProps, attachTouch) {
|
|
257
|
+
// if trackTouch is off or there is no el, then remove handlers if necessary and exit
|
|
258
|
+
if (!props.trackTouch || !state.el) {
|
|
259
|
+
if (state.cleanUpTouch) {
|
|
260
|
+
state.cleanUpTouch();
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
...state,
|
|
264
|
+
cleanUpTouch: undefined,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
// trackTouch is on, so if there are no handlers attached, attach them and exit
|
|
268
|
+
if (!state.cleanUpTouch) {
|
|
269
|
+
return {
|
|
270
|
+
...state,
|
|
271
|
+
cleanUpTouch: attachTouch(state.el, props),
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
// trackTouch is on and handlers are already attached, so if preventScrollOnSwipe changes value,
|
|
275
|
+
// remove and reattach handlers (this is required to update the passive option when attaching
|
|
276
|
+
// the handlers)
|
|
277
|
+
if (props.preventScrollOnSwipe !== previousProps.preventScrollOnSwipe ||
|
|
278
|
+
props.touchEventOptions.passive !== previousProps.touchEventOptions.passive) {
|
|
279
|
+
state.cleanUpTouch();
|
|
280
|
+
return {
|
|
281
|
+
...state,
|
|
282
|
+
cleanUpTouch: attachTouch(state.el, props),
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
return state;
|
|
286
|
+
}
|
|
287
|
+
function useSwipeable(options) {
|
|
288
|
+
const { trackMouse } = options;
|
|
289
|
+
const transientState = (0, react_1.useRef)({ ...initialState });
|
|
290
|
+
const transientProps = (0, react_1.useRef)({
|
|
291
|
+
...defaultProps,
|
|
292
|
+
});
|
|
293
|
+
// track previous rendered props
|
|
294
|
+
const previousProps = (0, react_1.useRef)({
|
|
295
|
+
...transientProps.current,
|
|
296
|
+
});
|
|
297
|
+
previousProps.current = { ...transientProps.current };
|
|
298
|
+
// update current render props & defaults
|
|
299
|
+
transientProps.current = {
|
|
300
|
+
...defaultProps,
|
|
301
|
+
...options,
|
|
302
|
+
};
|
|
303
|
+
// Force defaults for config properties
|
|
304
|
+
let defaultKey;
|
|
305
|
+
for (defaultKey in defaultProps) {
|
|
306
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
307
|
+
if (transientProps.current[defaultKey] === void 0) {
|
|
308
|
+
transientProps.current[defaultKey] = defaultProps[defaultKey];
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const [handlers, attachTouch] = (0, react_1.useMemo)(() => getHandlers((stateSetter) => (transientState.current = stateSetter(transientState.current, transientProps.current)), { trackMouse }), [trackMouse]);
|
|
312
|
+
transientState.current = updateTransientState(transientState.current, transientProps.current, previousProps.current, attachTouch);
|
|
313
|
+
return handlers;
|
|
314
|
+
}
|