react-native-drawer-layout 5.0.0-alpha.2 → 5.0.0-alpha.20
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/module/utils/getDrawerWidth.js +1 -1
- package/lib/module/utils/getDrawerWidth.js.map +1 -1
- package/lib/module/utils/useDrawerProgress.js +1 -1
- package/lib/module/utils/useDrawerProgress.js.map +1 -1
- package/lib/module/views/Drawer.js +9 -5
- package/lib/module/views/Drawer.js.map +1 -1
- package/lib/module/views/Drawer.native.js +162 -57
- package/lib/module/views/Drawer.native.js.map +1 -1
- package/lib/module/views/GestureHandler.js +4 -14
- package/lib/module/views/GestureHandler.js.map +1 -1
- package/lib/module/views/GestureHandlerNative.js +1 -1
- package/lib/module/views/GestureHandlerNative.js.map +1 -1
- package/lib/typescript/src/index.d.ts +3 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +4 -4
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/utils/DrawerGestureContext.d.ts +2 -1
- package/lib/typescript/src/utils/DrawerGestureContext.d.ts.map +1 -1
- package/lib/typescript/src/utils/getDrawerWidth.d.ts.map +1 -1
- package/lib/typescript/src/views/Drawer.d.ts +3 -2
- package/lib/typescript/src/views/Drawer.d.ts.map +1 -1
- package/lib/typescript/src/views/Drawer.native.d.ts +3 -2
- package/lib/typescript/src/views/Drawer.native.d.ts.map +1 -1
- package/lib/typescript/src/views/GestureHandler.android.d.ts +1 -1
- package/lib/typescript/src/views/GestureHandler.android.d.ts.map +1 -1
- package/lib/typescript/src/views/GestureHandler.d.ts +5 -13
- package/lib/typescript/src/views/GestureHandler.d.ts.map +1 -1
- package/lib/typescript/src/views/GestureHandler.ios.d.ts +1 -1
- package/lib/typescript/src/views/GestureHandler.ios.d.ts.map +1 -1
- package/lib/typescript/src/views/GestureHandlerNative.d.ts +2 -2
- package/lib/typescript/src/views/GestureHandlerNative.d.ts.map +1 -1
- package/lib/typescript/src/views/Overlay.d.ts +2 -2
- package/lib/typescript/src/views/Overlay.d.ts.map +1 -1
- package/lib/typescript/src/views/Overlay.native.d.ts +2 -2
- package/lib/typescript/src/views/Overlay.native.d.ts.map +1 -1
- package/package.json +17 -15
- package/src/types.tsx +6 -4
- package/src/utils/getDrawerWidth.tsx +5 -3
- package/src/utils/useDrawerProgress.tsx +1 -1
- package/src/views/Drawer.native.tsx +208 -59
- package/src/views/Drawer.tsx +14 -6
- package/src/views/GestureHandler.tsx +13 -15
- package/src/views/GestureHandlerNative.tsx +5 -3
|
@@ -8,16 +8,20 @@ import {
|
|
|
8
8
|
StatusBar,
|
|
9
9
|
StyleSheet,
|
|
10
10
|
View,
|
|
11
|
+
type ViewProps,
|
|
11
12
|
} from 'react-native';
|
|
12
13
|
import Animated, {
|
|
14
|
+
cancelAnimation,
|
|
13
15
|
interpolate,
|
|
14
16
|
ReduceMotion,
|
|
15
|
-
|
|
17
|
+
useAnimatedProps,
|
|
16
18
|
useAnimatedStyle,
|
|
17
19
|
useDerivedValue,
|
|
18
20
|
useSharedValue,
|
|
21
|
+
withDelay,
|
|
19
22
|
withSpring,
|
|
20
23
|
} from 'react-native-reanimated';
|
|
24
|
+
import { scheduleOnRN } from 'react-native-worklets';
|
|
21
25
|
import useLatestCallback from 'use-latest-callback';
|
|
22
26
|
|
|
23
27
|
import type { DrawerProps } from '../types';
|
|
@@ -25,10 +29,10 @@ import { DrawerGestureContext } from '../utils/DrawerGestureContext';
|
|
|
25
29
|
import { DrawerProgressContext } from '../utils/DrawerProgressContext';
|
|
26
30
|
import { getDrawerWidthNative } from '../utils/getDrawerWidth';
|
|
27
31
|
import {
|
|
28
|
-
Gesture,
|
|
29
32
|
GestureDetector,
|
|
30
33
|
GestureHandlerRootView,
|
|
31
|
-
|
|
34
|
+
type PanGestureConfig,
|
|
35
|
+
usePanGesture,
|
|
32
36
|
} from './GestureHandler';
|
|
33
37
|
import { Overlay } from './Overlay';
|
|
34
38
|
|
|
@@ -36,6 +40,18 @@ const SWIPE_EDGE_WIDTH = 32;
|
|
|
36
40
|
const SWIPE_MIN_OFFSET = 5;
|
|
37
41
|
const SWIPE_MIN_DISTANCE = 60;
|
|
38
42
|
const SWIPE_MIN_VELOCITY = 500;
|
|
43
|
+
const PEEK_DELAY = 160;
|
|
44
|
+
const PEEK_EDGE_WIDTH = 20;
|
|
45
|
+
const PEEK_DISTANCE = 20;
|
|
46
|
+
const PROGRESS_EPSILON = 0.05;
|
|
47
|
+
|
|
48
|
+
const SPRING_CONFIG = {
|
|
49
|
+
stiffness: 500,
|
|
50
|
+
damping: 40,
|
|
51
|
+
mass: 1,
|
|
52
|
+
overshootClamping: true,
|
|
53
|
+
reduceMotion: ReduceMotion.Never,
|
|
54
|
+
};
|
|
39
55
|
|
|
40
56
|
const minmax = (value: number, start: number, end: number) => {
|
|
41
57
|
'worklet';
|
|
@@ -104,7 +120,7 @@ export function Drawer({
|
|
|
104
120
|
[hideStatusBarOnOpen, statusBarAnimation]
|
|
105
121
|
);
|
|
106
122
|
|
|
107
|
-
React.
|
|
123
|
+
React.useLayoutEffect(() => {
|
|
108
124
|
hideStatusBar(isOpen);
|
|
109
125
|
|
|
110
126
|
return () => hideStatusBar(false);
|
|
@@ -147,13 +163,17 @@ export function Drawer({
|
|
|
147
163
|
getDrawerTranslationX(open, initialWidth)
|
|
148
164
|
);
|
|
149
165
|
|
|
150
|
-
const contentRef = React.useRef<View
|
|
166
|
+
const contentRef = React.useRef<React.ComponentRef<typeof View>>(null);
|
|
167
|
+
|
|
168
|
+
const updateLayout = useLatestCallback((width: number) => {
|
|
169
|
+
layoutWidth.set(width);
|
|
170
|
+
translationX.set(getDrawerTranslationX(open, width));
|
|
171
|
+
});
|
|
151
172
|
|
|
152
173
|
React.useLayoutEffect(() => {
|
|
153
174
|
const measureLayout = () => {
|
|
154
175
|
contentRef.current?.measure((_x, _y, width) => {
|
|
155
|
-
|
|
156
|
-
translationX.set(getDrawerTranslationX(open, width));
|
|
176
|
+
updateLayout(width);
|
|
157
177
|
});
|
|
158
178
|
};
|
|
159
179
|
|
|
@@ -163,6 +183,7 @@ export function Drawer({
|
|
|
163
183
|
// Measure the layout again on screen rotation
|
|
164
184
|
let handle: number | undefined;
|
|
165
185
|
|
|
186
|
+
// eslint-disable-next-line @eslint-react/web-api/no-leaked-event-listener
|
|
166
187
|
const subscription = Dimensions.addEventListener('change', () => {
|
|
167
188
|
// The measurement is not accurate without the delay
|
|
168
189
|
handle = requestAnimationFrame(() => {
|
|
@@ -183,15 +204,26 @@ export function Drawer({
|
|
|
183
204
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
184
205
|
}, []);
|
|
185
206
|
|
|
186
|
-
const onLayout = (
|
|
187
|
-
|
|
188
|
-
|
|
207
|
+
const onLayout = React.useCallback(
|
|
208
|
+
(event: LayoutChangeEvent) => {
|
|
209
|
+
updateLayout(event.nativeEvent.layout.width);
|
|
210
|
+
},
|
|
211
|
+
[updateLayout]
|
|
212
|
+
);
|
|
189
213
|
|
|
190
214
|
const touchStartX = useSharedValue(0);
|
|
191
215
|
const touchX = useSharedValue(0);
|
|
192
|
-
const
|
|
216
|
+
const isGestureActive = useSharedValue(false);
|
|
217
|
+
const isPeeking = useSharedValue(false);
|
|
218
|
+
|
|
219
|
+
const onOpenLatest = useLatestCallback(onOpen);
|
|
220
|
+
const onCloseLatest = useLatestCallback(onClose);
|
|
193
221
|
|
|
194
222
|
const onAnimationStart = useLatestCallback((open: boolean) => {
|
|
223
|
+
if (drawerType !== 'permanent') {
|
|
224
|
+
hideKeyboard();
|
|
225
|
+
}
|
|
226
|
+
|
|
195
227
|
onTransitionStart?.(!open);
|
|
196
228
|
});
|
|
197
229
|
|
|
@@ -213,6 +245,7 @@ export function Drawer({
|
|
|
213
245
|
|
|
214
246
|
touchStartX.set(0);
|
|
215
247
|
touchX.set(0);
|
|
248
|
+
isPeeking.set(false);
|
|
216
249
|
|
|
217
250
|
const containerWidth = layoutWidth.get();
|
|
218
251
|
const toValue = getDrawerTranslationX(open, containerWidth);
|
|
@@ -226,87 +259,159 @@ export function Drawer({
|
|
|
226
259
|
}
|
|
227
260
|
|
|
228
261
|
if (velocity === undefined) {
|
|
229
|
-
|
|
262
|
+
scheduleOnRN(onAnimationStart, open);
|
|
230
263
|
}
|
|
231
264
|
|
|
265
|
+
// Ignore velocity that opposes the spring direction.
|
|
266
|
+
// Otherwise overshootClamping makes the spring snap instantly.
|
|
267
|
+
const isSameDirection =
|
|
268
|
+
velocity !== undefined &&
|
|
269
|
+
((toValue > translationX.get() && velocity > 0) ||
|
|
270
|
+
(toValue < translationX.get() && velocity < 0));
|
|
271
|
+
|
|
272
|
+
const effectiveVelocity = isSameDirection ? velocity : 0;
|
|
273
|
+
|
|
232
274
|
animatingTo.set(open ? 'open' : 'close');
|
|
233
275
|
translationX.set(
|
|
234
276
|
withSpring(
|
|
235
277
|
toValue,
|
|
236
278
|
{
|
|
237
|
-
velocity,
|
|
238
|
-
stiffness:
|
|
239
|
-
damping:
|
|
240
|
-
mass:
|
|
279
|
+
velocity: effectiveVelocity,
|
|
280
|
+
stiffness: 500,
|
|
281
|
+
damping: 40,
|
|
282
|
+
mass: 1,
|
|
241
283
|
overshootClamping: true,
|
|
242
284
|
reduceMotion: ReduceMotion.Never,
|
|
243
285
|
},
|
|
244
286
|
(finished) => {
|
|
245
287
|
animatingTo.set(null);
|
|
246
|
-
|
|
288
|
+
scheduleOnRN(onAnimationEnd, open, finished);
|
|
247
289
|
}
|
|
248
290
|
)
|
|
249
291
|
);
|
|
250
292
|
|
|
251
293
|
if (open) {
|
|
252
|
-
|
|
294
|
+
scheduleOnRN(onOpenLatest);
|
|
253
295
|
} else {
|
|
254
|
-
|
|
296
|
+
scheduleOnRN(onCloseLatest);
|
|
255
297
|
}
|
|
256
298
|
},
|
|
257
299
|
[
|
|
258
300
|
touchStartX,
|
|
259
301
|
touchX,
|
|
302
|
+
isPeeking,
|
|
260
303
|
layoutWidth,
|
|
261
304
|
getDrawerTranslationX,
|
|
262
305
|
translationX,
|
|
263
306
|
animatingTo,
|
|
264
307
|
onAnimationStart,
|
|
265
308
|
onAnimationEnd,
|
|
266
|
-
|
|
267
|
-
|
|
309
|
+
onOpenLatest,
|
|
310
|
+
onCloseLatest,
|
|
268
311
|
]
|
|
269
312
|
);
|
|
270
313
|
|
|
271
|
-
React.
|
|
314
|
+
React.useLayoutEffect(() => {
|
|
272
315
|
toggleDrawer(open);
|
|
273
316
|
}, [animatingTo, open, toggleDrawer]);
|
|
274
317
|
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
let panGesture = Gesture?.Pan()
|
|
279
|
-
.onBegin((event) => {
|
|
318
|
+
const panGestureConfig = React.useMemo(() => {
|
|
319
|
+
const config: PanGestureConfig = {
|
|
320
|
+
onBegin: (event) => {
|
|
280
321
|
'worklet';
|
|
281
322
|
|
|
282
|
-
startX.set(translationX.get());
|
|
283
|
-
gestureState.set(event.state);
|
|
284
323
|
touchStartX.set(event.x);
|
|
285
|
-
|
|
286
|
-
|
|
324
|
+
|
|
325
|
+
if (open) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const distanceFromEdge =
|
|
330
|
+
drawerPosition === 'left' ? event.x : layoutWidth.get() - event.x;
|
|
331
|
+
|
|
332
|
+
if (distanceFromEdge > PEEK_EDGE_WIDTH) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const closedTranslation = getDrawerTranslationX(
|
|
337
|
+
false,
|
|
338
|
+
layoutWidth.get()
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
// Don't start the peek if the drawer isn't fully closed
|
|
342
|
+
if (translationX.get() !== closedTranslation) {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const peekDistance = Math.min(
|
|
347
|
+
PEEK_DISTANCE,
|
|
348
|
+
Math.abs(closedTranslation)
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
if (peekDistance <= 0) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const peekTranslation =
|
|
356
|
+
closedTranslation +
|
|
357
|
+
peekDistance * (drawerPosition === 'left' ? 1 : -1);
|
|
358
|
+
|
|
359
|
+
isPeeking.set(true);
|
|
360
|
+
translationX.set(
|
|
361
|
+
withDelay(PEEK_DELAY, withSpring(peekTranslation, SPRING_CONFIG))
|
|
362
|
+
);
|
|
363
|
+
},
|
|
364
|
+
onActivate: (event) => {
|
|
287
365
|
'worklet';
|
|
288
366
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
367
|
+
const wasPeeking = isPeeking.get();
|
|
368
|
+
|
|
369
|
+
if (wasPeeking) {
|
|
370
|
+
// If a peek is pending or the drawer is peeking,
|
|
371
|
+
// cancel the peek animation
|
|
372
|
+
cancelAnimation(translationX);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const currentTranslation = translationX.get();
|
|
376
|
+
const closedTranslation = getDrawerTranslationX(
|
|
377
|
+
false,
|
|
378
|
+
layoutWidth.get()
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
// Start the gesture from the pan's initial translation
|
|
382
|
+
// We avoid this if the drawer has already moved for the peek,
|
|
383
|
+
// otherwise there can be a jump to the pan's initial translation
|
|
384
|
+
if (!wasPeeking || currentTranslation === closedTranslation) {
|
|
385
|
+
translationX.set(currentTranslation + event.translationX);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
isPeeking.set(false);
|
|
389
|
+
isGestureActive.set(true);
|
|
390
|
+
|
|
391
|
+
scheduleOnRN(onGestureBegin);
|
|
392
|
+
},
|
|
393
|
+
onUpdate: (event) => {
|
|
292
394
|
'worklet';
|
|
293
395
|
|
|
396
|
+
isGestureActive.set(true);
|
|
294
397
|
touchX.set(event.x);
|
|
295
|
-
translationX.set(
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
.onEnd((event, success) => {
|
|
398
|
+
translationX.set(translationX.get() + event.changeX);
|
|
399
|
+
},
|
|
400
|
+
onDeactivate: (event) => {
|
|
299
401
|
'worklet';
|
|
300
402
|
|
|
301
|
-
|
|
403
|
+
isGestureActive.set(false);
|
|
302
404
|
|
|
303
|
-
if (
|
|
304
|
-
|
|
405
|
+
if (event.canceled) {
|
|
406
|
+
toggleDrawer(open, event.velocityX);
|
|
407
|
+
scheduleOnRN(onGestureAbort);
|
|
408
|
+
|
|
409
|
+
return;
|
|
305
410
|
}
|
|
306
411
|
|
|
307
412
|
const nextOpen =
|
|
308
413
|
(Math.abs(event.translationX) > SWIPE_MIN_OFFSET &&
|
|
309
|
-
Math.abs(event.
|
|
414
|
+
Math.abs(event.velocityX) > swipeMinVelocity) ||
|
|
310
415
|
Math.abs(event.translationX) > swipeMinDistance
|
|
311
416
|
? drawerPosition === 'left'
|
|
312
417
|
? // If swiped to right, open the drawer, otherwise close it
|
|
@@ -318,29 +423,42 @@ export function Drawer({
|
|
|
318
423
|
: open;
|
|
319
424
|
|
|
320
425
|
toggleDrawer(nextOpen, event.velocityX);
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
426
|
+
scheduleOnRN(onGestureFinish);
|
|
427
|
+
},
|
|
428
|
+
onFinalize: () => {
|
|
429
|
+
'worklet';
|
|
430
|
+
|
|
431
|
+
if (isPeeking.get()) {
|
|
432
|
+
isPeeking.set(false);
|
|
433
|
+
|
|
434
|
+
translationX.set(
|
|
435
|
+
withSpring(
|
|
436
|
+
getDrawerTranslationX(false, layoutWidth.get()),
|
|
437
|
+
SPRING_CONFIG
|
|
438
|
+
)
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
activeOffsetX: [-SWIPE_MIN_OFFSET, SWIPE_MIN_OFFSET],
|
|
443
|
+
failOffsetY: [-SWIPE_MIN_OFFSET, SWIPE_MIN_OFFSET],
|
|
444
|
+
hitSlop,
|
|
445
|
+
enabled: drawerType !== 'permanent' && swipeEnabled,
|
|
446
|
+
};
|
|
331
447
|
|
|
332
|
-
return
|
|
448
|
+
return configureGestureHandler?.(config) ?? config;
|
|
333
449
|
}, [
|
|
334
450
|
configureGestureHandler,
|
|
335
451
|
drawerPosition,
|
|
336
452
|
drawerType,
|
|
337
|
-
|
|
453
|
+
getDrawerTranslationX,
|
|
338
454
|
hitSlop,
|
|
455
|
+
isGestureActive,
|
|
456
|
+
isPeeking,
|
|
457
|
+
layoutWidth,
|
|
339
458
|
onGestureBegin,
|
|
340
459
|
onGestureAbort,
|
|
341
460
|
onGestureFinish,
|
|
342
461
|
open,
|
|
343
|
-
startX,
|
|
344
462
|
swipeEnabled,
|
|
345
463
|
swipeMinDistance,
|
|
346
464
|
swipeMinVelocity,
|
|
@@ -350,6 +468,8 @@ export function Drawer({
|
|
|
350
468
|
translationX,
|
|
351
469
|
]);
|
|
352
470
|
|
|
471
|
+
const pan = usePanGesture(panGestureConfig);
|
|
472
|
+
|
|
353
473
|
const translateX = useDerivedValue(() => {
|
|
354
474
|
const drawerWidth = getDrawerWidthNative({
|
|
355
475
|
containerWidth: layoutWidth.get(),
|
|
@@ -382,7 +502,7 @@ export function Drawer({
|
|
|
382
502
|
//
|
|
383
503
|
// This is used only when drawerType is "front"
|
|
384
504
|
const touchDistance =
|
|
385
|
-
drawerType === 'front' &&
|
|
505
|
+
drawerType === 'front' && isGestureActive.get()
|
|
386
506
|
? minmax(
|
|
387
507
|
drawerPosition === 'left'
|
|
388
508
|
? touchStartX.get() - drawerWidth
|
|
@@ -494,6 +614,34 @@ export function Drawer({
|
|
|
494
614
|
);
|
|
495
615
|
});
|
|
496
616
|
|
|
617
|
+
const contentAnimatedProps = useAnimatedProps<ViewProps>(() => {
|
|
618
|
+
const hidden =
|
|
619
|
+
drawerType !== 'permanent' && progress.value >= 1 - PROGRESS_EPSILON;
|
|
620
|
+
|
|
621
|
+
if (Platform.OS === 'android') {
|
|
622
|
+
const importantForAccessibility: ViewProps['importantForAccessibility'] =
|
|
623
|
+
hidden ? 'no-hide-descendants' : 'auto';
|
|
624
|
+
|
|
625
|
+
return { importantForAccessibility };
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
return { accessibilityElementsHidden: hidden };
|
|
629
|
+
}, [drawerType, progress]);
|
|
630
|
+
|
|
631
|
+
const drawerContentAnimatedProps = useAnimatedProps<ViewProps>(() => {
|
|
632
|
+
const hidden =
|
|
633
|
+
drawerType !== 'permanent' && progress.value < 1 - PROGRESS_EPSILON;
|
|
634
|
+
|
|
635
|
+
if (Platform.OS === 'android') {
|
|
636
|
+
const importantForAccessibility: ViewProps['importantForAccessibility'] =
|
|
637
|
+
hidden ? 'no-hide-descendants' : 'auto';
|
|
638
|
+
|
|
639
|
+
return { importantForAccessibility };
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
return { accessibilityElementsHidden: hidden };
|
|
643
|
+
}, [drawerType, progress]);
|
|
644
|
+
|
|
497
645
|
return (
|
|
498
646
|
<GestureHandlerRootView style={[styles.container, style]}>
|
|
499
647
|
<DrawerProgressContext.Provider value={progress}>
|
|
@@ -519,12 +667,12 @@ export function Drawer({
|
|
|
519
667
|
onLayout={onLayout}
|
|
520
668
|
style={[styles.content, contentAnimatedStyle]}
|
|
521
669
|
>
|
|
522
|
-
<View
|
|
523
|
-
|
|
670
|
+
<Animated.View
|
|
671
|
+
animatedProps={contentAnimatedProps}
|
|
524
672
|
style={styles.content}
|
|
525
673
|
>
|
|
526
674
|
{children}
|
|
527
|
-
</View>
|
|
675
|
+
</Animated.View>
|
|
528
676
|
{drawerType !== 'permanent' ? (
|
|
529
677
|
<Overlay
|
|
530
678
|
open={open}
|
|
@@ -536,6 +684,7 @@ export function Drawer({
|
|
|
536
684
|
) : null}
|
|
537
685
|
</Animated.View>
|
|
538
686
|
<Animated.View
|
|
687
|
+
animatedProps={drawerContentAnimatedProps}
|
|
539
688
|
removeClippedSubviews={Platform.OS !== 'ios'}
|
|
540
689
|
style={[
|
|
541
690
|
styles.drawer,
|
package/src/views/Drawer.tsx
CHANGED
|
@@ -34,18 +34,26 @@ export function Drawer({
|
|
|
34
34
|
progress.set(open ? 1 : 0);
|
|
35
35
|
}, [open, progress]);
|
|
36
36
|
|
|
37
|
-
const drawerRef = React.useRef<View
|
|
37
|
+
const drawerRef = React.useRef<React.ComponentRef<typeof View>>(null);
|
|
38
38
|
|
|
39
|
-
const onTransitionStartLatest = useLatestCallback(() => {
|
|
40
|
-
|
|
39
|
+
const onTransitionStartLatest = useLatestCallback((e: TransitionEvent) => {
|
|
40
|
+
if (e.target === e.currentTarget && e.propertyName === 'transform') {
|
|
41
|
+
onTransitionStart?.(open === false);
|
|
42
|
+
}
|
|
41
43
|
});
|
|
42
44
|
|
|
43
|
-
const onTransitionEndLatest = useLatestCallback(() => {
|
|
44
|
-
|
|
45
|
+
const onTransitionEndLatest = useLatestCallback((e: TransitionEvent) => {
|
|
46
|
+
if (e.target === e.currentTarget && e.propertyName === 'transform') {
|
|
47
|
+
onTransitionEnd?.(open === false);
|
|
48
|
+
}
|
|
45
49
|
});
|
|
46
50
|
|
|
47
51
|
React.useEffect(() => {
|
|
48
|
-
const element =
|
|
52
|
+
const element =
|
|
53
|
+
typeof HTMLElement !== 'undefined' &&
|
|
54
|
+
drawerRef.current instanceof HTMLElement
|
|
55
|
+
? drawerRef.current
|
|
56
|
+
: null;
|
|
49
57
|
|
|
50
58
|
element?.addEventListener('transitionstart', onTransitionStartLatest);
|
|
51
59
|
element?.addEventListener('transitionend', onTransitionEndLatest);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
PanGesture,
|
|
5
|
+
PanGestureConfig,
|
|
6
|
+
} from 'react-native-gesture-handler';
|
|
4
7
|
|
|
5
|
-
// FIXME: Inline this type instead of getting it from react-native-gesture-handler
|
|
6
|
-
// Otherwise, we get a type error:
|
|
7
|
-
// Exported variable 'GestureDetector' has or is using name 'GestureDetectorProps' from external module ".." but cannot be named.
|
|
8
8
|
type GestureDetectorProps = {
|
|
9
|
-
gesture:
|
|
9
|
+
gesture: PanGesture | undefined;
|
|
10
10
|
userSelect?: 'none' | 'auto' | 'text';
|
|
11
11
|
children: React.ReactNode;
|
|
12
12
|
};
|
|
@@ -21,15 +21,13 @@ export const GestureDetector = ({
|
|
|
21
21
|
|
|
22
22
|
export const GestureHandlerRootView = View;
|
|
23
23
|
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
| undefined = undefined;
|
|
24
|
+
export function usePanGesture(config: PanGestureConfig) {
|
|
25
|
+
React.useDebugValue(config);
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
UNDETERMINED = 0,
|
|
30
|
-
FAILED = 1,
|
|
31
|
-
BEGAN = 2,
|
|
32
|
-
CANCELLED = 3,
|
|
33
|
-
ACTIVE = 4,
|
|
34
|
-
END = 5,
|
|
27
|
+
return undefined;
|
|
35
28
|
}
|
|
29
|
+
|
|
30
|
+
export type {
|
|
31
|
+
PanGesture,
|
|
32
|
+
PanGestureConfig,
|
|
33
|
+
} from 'react-native-gesture-handler';
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type {
|
|
2
|
+
PanGesture,
|
|
3
|
+
PanGestureConfig,
|
|
4
|
+
} from 'react-native-gesture-handler';
|
|
2
5
|
export {
|
|
3
|
-
Gesture,
|
|
4
6
|
GestureDetector,
|
|
5
7
|
GestureHandlerRootView,
|
|
6
|
-
|
|
8
|
+
usePanGesture,
|
|
7
9
|
} from 'react-native-gesture-handler';
|