react-native-gesture-handler 2.4.1 → 2.4.2
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/lib/commonjs/components/DrawerLayout.js +38 -11
- package/lib/commonjs/components/DrawerLayout.js.map +1 -1
- package/lib/commonjs/handlers/ForceTouchGestureHandler.js +2 -1
- package/lib/commonjs/handlers/ForceTouchGestureHandler.js.map +1 -1
- package/lib/commonjs/handlers/createHandler.js +19 -8
- package/lib/commonjs/handlers/createHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestureHandlerCommon.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector.js +83 -63
- package/lib/commonjs/handlers/gestures/GestureDetector.js.map +1 -1
- package/lib/commonjs/handlers/gestures/gesture.js +13 -2
- package/lib/commonjs/handlers/gestures/gesture.js.map +1 -1
- package/lib/commonjs/web/utils.js.map +1 -1
- package/lib/module/components/DrawerLayout.js +38 -11
- package/lib/module/components/DrawerLayout.js.map +1 -1
- package/lib/module/handlers/ForceTouchGestureHandler.js +1 -1
- package/lib/module/handlers/ForceTouchGestureHandler.js.map +1 -1
- package/lib/module/handlers/createHandler.js +20 -8
- package/lib/module/handlers/createHandler.js.map +1 -1
- package/lib/module/handlers/gestureHandlerCommon.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector.js +83 -63
- package/lib/module/handlers/gestures/GestureDetector.js.map +1 -1
- package/lib/module/handlers/gestures/gesture.js +13 -2
- package/lib/module/handlers/gestures/gesture.js.map +1 -1
- package/lib/module/web/utils.js.map +1 -1
- package/lib/typescript/components/DrawerLayout.d.ts +3 -0
- package/lib/typescript/handlers/ForceTouchGestureHandler.d.ts +2 -2
- package/lib/typescript/handlers/gestureHandlerCommon.d.ts +1 -0
- package/lib/typescript/handlers/gestures/GestureDetector.d.ts +2 -1
- package/lib/typescript/handlers/gestures/gesture.d.ts +3 -0
- package/package.json +1 -1
- package/src/components/DrawerLayout.tsx +34 -10
- package/src/handlers/ForceTouchGestureHandler.ts +3 -2
- package/src/handlers/createHandler.ts +25 -11
- package/src/handlers/gestureHandlerCommon.ts +2 -0
- package/src/handlers/gestures/GestureDetector.tsx +107 -81
- package/src/handlers/gestures/gesture.ts +16 -0
- package/src/web/utils.ts +1 -1
@@ -148,6 +148,11 @@ export interface DrawerLayoutProps {
|
|
148
148
|
onDrawerSlide?: (position: number) => void;
|
149
149
|
|
150
150
|
onGestureRef?: (ref: PanGestureHandler) => void;
|
151
|
+
|
152
|
+
// implicit `children` prop has been removed in @types/react^18.0.0
|
153
|
+
children?:
|
154
|
+
| React.ReactNode
|
155
|
+
| ((openValue?: Animated.AnimatedInterpolation) => React.ReactNode);
|
151
156
|
}
|
152
157
|
|
153
158
|
export type DrawerLayoutState = {
|
@@ -155,6 +160,8 @@ export type DrawerLayoutState = {
|
|
155
160
|
touchX: Animated.Value;
|
156
161
|
drawerTranslation: Animated.Value;
|
157
162
|
containerWidth: number;
|
163
|
+
drawerState: DrawerState;
|
164
|
+
drawerOpened: boolean;
|
158
165
|
};
|
159
166
|
|
160
167
|
export type DrawerMovementOption = {
|
@@ -189,6 +196,8 @@ export default class DrawerLayout extends Component<
|
|
189
196
|
touchX,
|
190
197
|
drawerTranslation,
|
191
198
|
containerWidth: 0,
|
199
|
+
drawerState: IDLE,
|
200
|
+
drawerOpened: false,
|
192
201
|
};
|
193
202
|
|
194
203
|
this.updateAnimatedEvent(props, this.state);
|
@@ -349,6 +358,7 @@ export default class DrawerLayout extends Component<
|
|
349
358
|
this.handleRelease({ nativeEvent });
|
350
359
|
} else if (nativeEvent.state === State.ACTIVE) {
|
351
360
|
this.emitStateChanged(DRAGGING, false);
|
361
|
+
this.setState({ drawerState: DRAGGING });
|
352
362
|
if (this.props.keyboardDismissMode === 'on-drag') {
|
353
363
|
Keyboard.dismiss();
|
354
364
|
}
|
@@ -464,6 +474,7 @@ export default class DrawerLayout extends Component<
|
|
464
474
|
const willShow = toValue !== 0;
|
465
475
|
this.updateShowing(willShow);
|
466
476
|
this.emitStateChanged(SETTLING, willShow);
|
477
|
+
this.setState({ drawerState: SETTLING });
|
467
478
|
if (this.props.hideStatusBar) {
|
468
479
|
StatusBar.setHidden(willShow, this.props.statusBarAnimation || 'slide');
|
469
480
|
}
|
@@ -476,6 +487,12 @@ export default class DrawerLayout extends Component<
|
|
476
487
|
}).start(({ finished }) => {
|
477
488
|
if (finished) {
|
478
489
|
this.emitStateChanged(IDLE, willShow);
|
490
|
+
this.setState({ drawerOpened: willShow });
|
491
|
+
if (this.state.drawerState !== DRAGGING) {
|
492
|
+
// it's possilbe that user started drag while the drawer
|
493
|
+
// was settling, don't override state in this case
|
494
|
+
this.setState({ drawerState: IDLE });
|
495
|
+
}
|
479
496
|
if (willShow) {
|
480
497
|
this.props.onDrawerOpen?.();
|
481
498
|
} else {
|
@@ -516,11 +533,14 @@ export default class DrawerLayout extends Component<
|
|
516
533
|
private renderOverlay = () => {
|
517
534
|
/* Overlay styles */
|
518
535
|
invariant(this.openValue, 'should be set');
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
}
|
536
|
+
let overlayOpacity;
|
537
|
+
|
538
|
+
if (this.state.drawerState !== IDLE) {
|
539
|
+
overlayOpacity = this.openValue;
|
540
|
+
} else {
|
541
|
+
overlayOpacity = this.state.drawerOpened ? 1 : 0;
|
542
|
+
}
|
543
|
+
|
524
544
|
const dynamicOverlayStyles = {
|
525
545
|
opacity: overlayOpacity,
|
526
546
|
backgroundColor: this.props.overlayColor,
|
@@ -579,11 +599,15 @@ export default class DrawerLayout extends Component<
|
|
579
599
|
let drawerTranslateX: number | Animated.AnimatedInterpolation = 0;
|
580
600
|
if (drawerSlide) {
|
581
601
|
const closedDrawerOffset = fromLeft ? -drawerWidth! : drawerWidth!;
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
602
|
+
if (this.state.drawerState !== IDLE) {
|
603
|
+
drawerTranslateX = openValue.interpolate({
|
604
|
+
inputRange: [0, 1],
|
605
|
+
outputRange: [closedDrawerOffset, 0],
|
606
|
+
extrapolate: 'clamp',
|
607
|
+
});
|
608
|
+
} else {
|
609
|
+
drawerTranslateX = this.state.drawerOpened ? 0 : closedDrawerOffset;
|
610
|
+
}
|
587
611
|
}
|
588
612
|
const drawerStyles: {
|
589
613
|
transform: { translateX: number | Animated.AnimatedInterpolation }[];
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import React from 'react';
|
1
|
+
import React, { PropsWithChildren } from 'react';
|
2
2
|
import { tagMessage } from '../utils';
|
3
3
|
import PlatformConstants from '../PlatformConstants';
|
4
4
|
import createHandler from './createHandler';
|
@@ -13,7 +13,8 @@ export const forceTouchGestureHandlerProps = [
|
|
13
13
|
'feedbackOnActivation',
|
14
14
|
] as const;
|
15
15
|
|
16
|
-
|
16
|
+
// implicit `children` prop has been removed in @types/react^18.0.0
|
17
|
+
class ForceTouchFallback extends React.Component<PropsWithChildren<unknown>> {
|
17
18
|
static forceTouchAvailable = false;
|
18
19
|
componentDidMount() {
|
19
20
|
console.warn(
|
@@ -148,6 +148,8 @@ type InternalEventHandlers = {
|
|
148
148
|
onGestureHandlerStateChange?: (event: any) => void;
|
149
149
|
};
|
150
150
|
|
151
|
+
const UNRESOLVED_REFS_RETRY_LIMIT = 1;
|
152
|
+
|
151
153
|
// TODO(TS) - make sure that BaseGestureHandlerProps doesn't need other generic parameter to work with custom properties.
|
152
154
|
export default function createHandler<
|
153
155
|
T extends BaseGestureHandlerProps<U>,
|
@@ -198,7 +200,7 @@ export default function createHandler<
|
|
198
200
|
'toggleElementInspector',
|
199
201
|
() => {
|
200
202
|
this.setState((_) => ({ allowTouches }));
|
201
|
-
this.update();
|
203
|
+
this.update(UNRESOLVED_REFS_RETRY_LIMIT);
|
202
204
|
}
|
203
205
|
);
|
204
206
|
}
|
@@ -211,7 +213,7 @@ export default function createHandler<
|
|
211
213
|
// be resolved by then.
|
212
214
|
this.updateEnqueued = setImmediate(() => {
|
213
215
|
this.updateEnqueued = null;
|
214
|
-
this.update();
|
216
|
+
this.update(UNRESOLVED_REFS_RETRY_LIMIT);
|
215
217
|
});
|
216
218
|
}
|
217
219
|
|
@@ -231,7 +233,7 @@ export default function createHandler<
|
|
231
233
|
if (this.viewTag !== viewTag) {
|
232
234
|
this.attachGestureHandler(viewTag as number); // TODO(TS) - check interaction between _viewTag & findNodeHandle
|
233
235
|
}
|
234
|
-
this.update();
|
236
|
+
this.update(UNRESOLVED_REFS_RETRY_LIMIT);
|
235
237
|
}
|
236
238
|
|
237
239
|
componentWillUnmount() {
|
@@ -361,14 +363,26 @@ export default function createHandler<
|
|
361
363
|
scheduleFlushOperations();
|
362
364
|
};
|
363
365
|
|
364
|
-
private update() {
|
365
|
-
const
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
if (
|
371
|
-
this.
|
366
|
+
private update(remainingTries: number) {
|
367
|
+
const props: HandlerProps<U> = this.props;
|
368
|
+
|
369
|
+
// When ref is set via a function i.e. `ref={(r) => refObject.current = r}` instead of
|
370
|
+
// `ref={refObject}` it's possible that it won't be resolved in time. Seems like trying
|
371
|
+
// again is easy enough fix.
|
372
|
+
if (hasUnresolvedRefs(props) && remainingTries > 0) {
|
373
|
+
this.updateEnqueued = setImmediate(() => {
|
374
|
+
this.updateEnqueued = null;
|
375
|
+
this.update(remainingTries - 1);
|
376
|
+
});
|
377
|
+
} else {
|
378
|
+
const newConfig = filterConfig(
|
379
|
+
transformProps ? transformProps(this.props) : this.props,
|
380
|
+
[...allowedProps, ...customNativeProps],
|
381
|
+
config
|
382
|
+
);
|
383
|
+
if (!deepEqual(this.config, newConfig)) {
|
384
|
+
this.updateGestureHandler(newConfig);
|
385
|
+
}
|
372
386
|
}
|
373
387
|
}
|
374
388
|
|
@@ -126,6 +126,8 @@ export type BaseGestureHandlerProps<
|
|
126
126
|
onHandlerStateChange?: (
|
127
127
|
event: HandlerStateChangeEvent<ExtraEventPayloadT>
|
128
128
|
) => void;
|
129
|
+
// implicit `children` prop has been removed in @types/react^18.0.0
|
130
|
+
children?: React.ReactNode;
|
129
131
|
};
|
130
132
|
|
131
133
|
function isConfigParam(param: unknown, name: string) {
|
@@ -268,11 +268,34 @@ function updateHandlers(
|
|
268
268
|
}
|
269
269
|
|
270
270
|
if (preparedGesture.animatedHandlers) {
|
271
|
-
|
271
|
+
const previousHandlersValue =
|
272
|
+
preparedGesture.animatedHandlers.value ?? [];
|
273
|
+
const newHandlersValue = (preparedGesture.config
|
272
274
|
.filter((g) => g.shouldUseReanimated) // ignore gestures that shouldn't run on UI
|
273
275
|
.map((g) => g.handlers) as unknown) as HandlerCallbacks<
|
274
276
|
Record<string, unknown>
|
275
277
|
>[];
|
278
|
+
|
279
|
+
// if amount of gesture configs changes, we need to update the callbacks in shared value
|
280
|
+
let shouldUpdateSharedValue =
|
281
|
+
previousHandlersValue.length !== newHandlersValue.length;
|
282
|
+
|
283
|
+
if (!shouldUpdateSharedValue) {
|
284
|
+
// if the amount is the same, we need to check if any of the configs inside has changed
|
285
|
+
for (let i = 0; i < newHandlersValue.length; i++) {
|
286
|
+
if (
|
287
|
+
// we can use the `gestureId` prop as it's unique for every config instance
|
288
|
+
newHandlersValue[i].gestureId !== previousHandlersValue[i].gestureId
|
289
|
+
) {
|
290
|
+
shouldUpdateSharedValue = true;
|
291
|
+
break;
|
292
|
+
}
|
293
|
+
}
|
294
|
+
}
|
295
|
+
|
296
|
+
if (shouldUpdateSharedValue) {
|
297
|
+
preparedGesture.animatedHandlers.value = newHandlersValue;
|
298
|
+
}
|
276
299
|
}
|
277
300
|
|
278
301
|
scheduleFlushOperations();
|
@@ -299,90 +322,90 @@ function needsToReattach(
|
|
299
322
|
return false;
|
300
323
|
}
|
301
324
|
|
302
|
-
function
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
325
|
+
function isStateChangeEvent(
|
326
|
+
event: GestureUpdateEvent | GestureStateChangeEvent | GestureTouchEvent
|
327
|
+
): event is GestureStateChangeEvent {
|
328
|
+
'worklet';
|
329
|
+
// @ts-ignore Yes, the oldState prop is missing on GestureTouchEvent, that's the point
|
330
|
+
return event.oldState != null;
|
331
|
+
}
|
309
332
|
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
}
|
333
|
+
function isTouchEvent(
|
334
|
+
event: GestureUpdateEvent | GestureStateChangeEvent | GestureTouchEvent
|
335
|
+
): event is GestureTouchEvent {
|
336
|
+
'worklet';
|
337
|
+
return event.eventType != null;
|
338
|
+
}
|
317
339
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
340
|
+
function getHandler(
|
341
|
+
type: CALLBACK_TYPE,
|
342
|
+
gesture: HandlerCallbacks<Record<string, unknown>>
|
343
|
+
) {
|
344
|
+
'worklet';
|
345
|
+
switch (type) {
|
346
|
+
case CALLBACK_TYPE.BEGAN:
|
347
|
+
return gesture.onBegin;
|
348
|
+
case CALLBACK_TYPE.START:
|
349
|
+
return gesture.onStart;
|
350
|
+
case CALLBACK_TYPE.UPDATE:
|
351
|
+
return gesture.onUpdate;
|
352
|
+
case CALLBACK_TYPE.CHANGE:
|
353
|
+
return gesture.onChange;
|
354
|
+
case CALLBACK_TYPE.END:
|
355
|
+
return gesture.onEnd;
|
356
|
+
case CALLBACK_TYPE.FINALIZE:
|
357
|
+
return gesture.onFinalize;
|
358
|
+
case CALLBACK_TYPE.TOUCHES_DOWN:
|
359
|
+
return gesture.onTouchesDown;
|
360
|
+
case CALLBACK_TYPE.TOUCHES_MOVE:
|
361
|
+
return gesture.onTouchesMove;
|
362
|
+
case CALLBACK_TYPE.TOUCHES_UP:
|
363
|
+
return gesture.onTouchesUp;
|
364
|
+
case CALLBACK_TYPE.TOUCHES_CANCELLED:
|
365
|
+
return gesture.onTouchesCancelled;
|
323
366
|
}
|
367
|
+
}
|
324
368
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
return gesture.onChange;
|
339
|
-
case CALLBACK_TYPE.END:
|
340
|
-
return gesture.onEnd;
|
341
|
-
case CALLBACK_TYPE.FINALIZE:
|
342
|
-
return gesture.onFinalize;
|
343
|
-
case CALLBACK_TYPE.TOUCHES_DOWN:
|
344
|
-
return gesture.onTouchesDown;
|
345
|
-
case CALLBACK_TYPE.TOUCHES_MOVE:
|
346
|
-
return gesture.onTouchesMove;
|
347
|
-
case CALLBACK_TYPE.TOUCHES_UP:
|
348
|
-
return gesture.onTouchesUp;
|
349
|
-
case CALLBACK_TYPE.TOUCHES_CANCELLED:
|
350
|
-
return gesture.onTouchesCancelled;
|
351
|
-
}
|
369
|
+
function touchEventTypeToCallbackType(
|
370
|
+
eventType: TouchEventType
|
371
|
+
): CALLBACK_TYPE {
|
372
|
+
'worklet';
|
373
|
+
switch (eventType) {
|
374
|
+
case TouchEventType.TOUCHES_DOWN:
|
375
|
+
return CALLBACK_TYPE.TOUCHES_DOWN;
|
376
|
+
case TouchEventType.TOUCHES_MOVE:
|
377
|
+
return CALLBACK_TYPE.TOUCHES_MOVE;
|
378
|
+
case TouchEventType.TOUCHES_UP:
|
379
|
+
return CALLBACK_TYPE.TOUCHES_UP;
|
380
|
+
case TouchEventType.TOUCHES_CANCELLED:
|
381
|
+
return CALLBACK_TYPE.TOUCHES_CANCELLED;
|
352
382
|
}
|
383
|
+
return CALLBACK_TYPE.UNDEFINED;
|
384
|
+
}
|
353
385
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
return CALLBACK_TYPE.UNDEFINED;
|
386
|
+
function runWorklet(
|
387
|
+
type: CALLBACK_TYPE,
|
388
|
+
gesture: HandlerCallbacks<Record<string, unknown>>,
|
389
|
+
event: GestureStateChangeEvent | GestureUpdateEvent | GestureTouchEvent,
|
390
|
+
...args: any[]
|
391
|
+
) {
|
392
|
+
'worklet';
|
393
|
+
const handler = getHandler(type, gesture);
|
394
|
+
if (gesture.isWorklet[type]) {
|
395
|
+
// @ts-ignore Logic below makes sure the correct event is send to the
|
396
|
+
// correct handler.
|
397
|
+
handler?.(event, ...args);
|
398
|
+
} else if (handler) {
|
399
|
+
console.warn(tagMessage('Animated gesture callback must be a worklet'));
|
369
400
|
}
|
401
|
+
}
|
370
402
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
'worklet';
|
378
|
-
const handler = getHandler(type, gesture);
|
379
|
-
if (gesture.isWorklet[type]) {
|
380
|
-
// @ts-ignore Logic below makes sure the correct event is send to the
|
381
|
-
// correct handler.
|
382
|
-
handler?.(event, ...args);
|
383
|
-
} else if (handler) {
|
384
|
-
console.warn(tagMessage('Animated gesture callback must be a worklet'));
|
385
|
-
}
|
403
|
+
function useAnimatedGesture(
|
404
|
+
preparedGesture: GestureConfigReference,
|
405
|
+
needsRebuild: boolean
|
406
|
+
) {
|
407
|
+
if (!Reanimated) {
|
408
|
+
return;
|
386
409
|
}
|
387
410
|
|
388
411
|
// Hooks are called conditionally, but the condition is whether the
|
@@ -490,10 +513,9 @@ function useAnimatedGesture(
|
|
490
513
|
|
491
514
|
interface GestureDetectorProps {
|
492
515
|
gesture?: ComposedGesture | GestureType;
|
516
|
+
children?: React.ReactNode;
|
493
517
|
}
|
494
|
-
export const GestureDetector:
|
495
|
-
props
|
496
|
-
) => {
|
518
|
+
export const GestureDetector = (props: GestureDetectorProps) => {
|
497
519
|
const gestureConfig = props.gesture;
|
498
520
|
const gesture = gestureConfig?.toGestureArray?.() ?? [];
|
499
521
|
const useReanimatedHook = gesture.some((g) => g.shouldUseReanimated);
|
@@ -605,7 +627,11 @@ export const GestureDetector: React.FunctionComponent<GestureDetectorProps> = (
|
|
605
627
|
}
|
606
628
|
};
|
607
629
|
|
608
|
-
class Wrap extends React.Component<{
|
630
|
+
class Wrap extends React.Component<{
|
631
|
+
onGestureHandlerEvent?: unknown;
|
632
|
+
// implicit `children` prop has been removed in @types/react^18.0.0
|
633
|
+
children?: React.ReactNode;
|
634
|
+
}> {
|
609
635
|
render() {
|
610
636
|
// I don't think that fighting with types over such a simple function is worth it
|
611
637
|
// The only thing it does is add 'collapsable: false' to the child component
|
@@ -53,6 +53,7 @@ type TouchEventHandlerType = (
|
|
53
53
|
) => void;
|
54
54
|
|
55
55
|
export type HandlerCallbacks<EventPayloadT extends Record<string, unknown>> = {
|
56
|
+
gestureId: number;
|
56
57
|
handlerTag: number;
|
57
58
|
onBegin?: (event: GestureStateChangeEvent<EventPayloadT>) => void;
|
58
59
|
onStart?: (event: GestureStateChangeEvent<EventPayloadT>) => void;
|
@@ -115,17 +116,32 @@ export abstract class Gesture {
|
|
115
116
|
abstract prepare(): void;
|
116
117
|
}
|
117
118
|
|
119
|
+
let nextGestureId = 0;
|
118
120
|
export abstract class BaseGesture<
|
119
121
|
EventPayloadT extends Record<string, unknown>
|
120
122
|
> extends Gesture {
|
123
|
+
private gestureId = -1;
|
121
124
|
public handlerTag = -1;
|
122
125
|
public handlerName = '';
|
123
126
|
public config: BaseGestureConfig = {};
|
124
127
|
public handlers: HandlerCallbacks<EventPayloadT> = {
|
128
|
+
gestureId: -1,
|
125
129
|
handlerTag: -1,
|
126
130
|
isWorklet: [],
|
127
131
|
};
|
128
132
|
|
133
|
+
constructor() {
|
134
|
+
super();
|
135
|
+
|
136
|
+
// Used to check whether the gesture config has been updated when wrapping it
|
137
|
+
// with `useMemo`. Since every config will have a unique id, when the dependencies
|
138
|
+
// don't change, the config won't be recreated and the id will stay the same.
|
139
|
+
// If the id is different, it means that the config has changed and the gesture
|
140
|
+
// needs to be updated.
|
141
|
+
this.gestureId = nextGestureId++;
|
142
|
+
this.handlers.gestureId = this.gestureId;
|
143
|
+
}
|
144
|
+
|
129
145
|
private addDependency(
|
130
146
|
key: 'simultaneousWith' | 'requireToFail',
|
131
147
|
gesture: Exclude<GestureRef, number>
|
package/src/web/utils.ts
CHANGED