react-native-drawer-layout 3.0.0 → 3.2.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.
Files changed (79) hide show
  1. package/README.md +3 -3
  2. package/lib/commonjs/index.js +8 -9
  3. package/lib/commonjs/index.js.map +1 -1
  4. package/lib/commonjs/utils/DrawerGestureContext.js +3 -3
  5. package/lib/commonjs/utils/DrawerGestureContext.js.map +1 -1
  6. package/lib/commonjs/utils/DrawerProgressContext.js +3 -3
  7. package/lib/commonjs/utils/DrawerProgressContext.js.map +1 -1
  8. package/lib/commonjs/utils/useDrawerProgress.js +3 -4
  9. package/lib/commonjs/utils/useDrawerProgress.js.map +1 -1
  10. package/lib/commonjs/views/Drawer.js +2 -2
  11. package/lib/commonjs/views/Drawer.js.map +1 -1
  12. package/lib/commonjs/views/GestureHandler.android.js.map +1 -1
  13. package/lib/commonjs/views/GestureHandler.ios.js.map +1 -1
  14. package/lib/commonjs/views/GestureHandler.js.map +1 -1
  15. package/lib/commonjs/views/GestureHandlerNative.js +2 -3
  16. package/lib/commonjs/views/GestureHandlerNative.js.map +1 -1
  17. package/lib/commonjs/views/legacy/Drawer.js +235 -201
  18. package/lib/commonjs/views/legacy/Drawer.js.map +1 -1
  19. package/lib/commonjs/views/legacy/Overlay.js +6 -4
  20. package/lib/commonjs/views/legacy/Overlay.js.map +1 -1
  21. package/lib/commonjs/views/modern/Drawer.js +34 -12
  22. package/lib/commonjs/views/modern/Drawer.js.map +1 -1
  23. package/lib/commonjs/views/modern/Overlay.js +6 -4
  24. package/lib/commonjs/views/modern/Overlay.js.map +1 -1
  25. package/lib/module/index.js +4 -4
  26. package/lib/module/index.js.map +1 -1
  27. package/lib/module/utils/DrawerGestureContext.js +1 -1
  28. package/lib/module/utils/DrawerGestureContext.js.map +1 -1
  29. package/lib/module/utils/DrawerProgressContext.js +1 -1
  30. package/lib/module/utils/DrawerProgressContext.js.map +1 -1
  31. package/lib/module/utils/useDrawerProgress.js +2 -2
  32. package/lib/module/utils/useDrawerProgress.js.map +1 -1
  33. package/lib/module/views/Drawer.js +2 -2
  34. package/lib/module/views/Drawer.js.map +1 -1
  35. package/lib/module/views/GestureHandler.android.js.map +1 -1
  36. package/lib/module/views/GestureHandler.ios.js.map +1 -1
  37. package/lib/module/views/GestureHandler.js.map +1 -1
  38. package/lib/module/views/GestureHandlerNative.js +1 -1
  39. package/lib/module/views/GestureHandlerNative.js.map +1 -1
  40. package/lib/module/views/legacy/Drawer.js +232 -198
  41. package/lib/module/views/legacy/Drawer.js.map +1 -1
  42. package/lib/module/views/legacy/Overlay.js +5 -3
  43. package/lib/module/views/legacy/Overlay.js.map +1 -1
  44. package/lib/module/views/modern/Drawer.js +32 -10
  45. package/lib/module/views/modern/Drawer.js.map +1 -1
  46. package/lib/module/views/modern/Overlay.js +5 -3
  47. package/lib/module/views/modern/Overlay.js.map +1 -1
  48. package/lib/typescript/src/index.d.ts +4 -4
  49. package/lib/typescript/src/index.d.ts.map +1 -1
  50. package/lib/typescript/src/types.d.ts +25 -0
  51. package/lib/typescript/src/types.d.ts.map +1 -1
  52. package/lib/typescript/src/utils/DrawerGestureContext.d.ts +1 -2
  53. package/lib/typescript/src/utils/DrawerGestureContext.d.ts.map +1 -1
  54. package/lib/typescript/src/utils/DrawerProgressContext.d.ts +1 -2
  55. package/lib/typescript/src/utils/DrawerProgressContext.d.ts.map +1 -1
  56. package/lib/typescript/src/utils/useDrawerProgress.d.ts +1 -1
  57. package/lib/typescript/src/utils/useDrawerProgress.d.ts.map +1 -1
  58. package/lib/typescript/src/views/Drawer.d.ts +1 -1
  59. package/lib/typescript/src/views/Drawer.d.ts.map +1 -1
  60. package/lib/typescript/src/views/legacy/Drawer.d.ts +1 -1
  61. package/lib/typescript/src/views/legacy/Drawer.d.ts.map +1 -1
  62. package/lib/typescript/src/views/legacy/Overlay.d.ts +2 -2
  63. package/lib/typescript/src/views/legacy/Overlay.d.ts.map +1 -1
  64. package/lib/typescript/src/views/modern/Drawer.d.ts +1 -1
  65. package/lib/typescript/src/views/modern/Drawer.d.ts.map +1 -1
  66. package/lib/typescript/src/views/modern/Overlay.d.ts +2 -2
  67. package/lib/typescript/src/views/modern/Overlay.d.ts.map +1 -1
  68. package/package.json +7 -3
  69. package/src/index.tsx +4 -4
  70. package/src/types.tsx +31 -0
  71. package/src/utils/DrawerGestureContext.tsx +2 -1
  72. package/src/utils/DrawerProgressContext.tsx +1 -1
  73. package/src/utils/useDrawerProgress.tsx +2 -2
  74. package/src/views/Drawer.tsx +4 -4
  75. package/src/views/GestureHandlerNative.tsx +1 -1
  76. package/src/views/legacy/Drawer.tsx +26 -4
  77. package/src/views/legacy/Overlay.tsx +15 -5
  78. package/src/views/modern/Drawer.tsx +57 -17
  79. package/src/views/modern/Overlay.tsx +15 -5
@@ -18,9 +18,9 @@ import {
18
18
  SWIPE_MIN_VELOCITY,
19
19
  } from '../../constants';
20
20
  import type { DrawerProps } from '../../types';
21
- import DrawerProgressContext from '../../utils/DrawerProgressContext';
21
+ import { DrawerProgressContext } from '../../utils/DrawerProgressContext';
22
22
  import { GestureState, PanGestureHandler } from '../GestureHandler';
23
- import Overlay from './Overlay';
23
+ import { Overlay } from './Overlay';
24
24
 
25
25
  const {
26
26
  Clock,
@@ -76,7 +76,7 @@ type Props = DrawerProps & {
76
76
  layout: { width: number };
77
77
  };
78
78
 
79
- export default class Drawer extends React.Component<Props> {
79
+ export class Drawer extends React.Component<Props> {
80
80
  componentDidUpdate(prevProps: Props) {
81
81
  const {
82
82
  open,
@@ -284,6 +284,14 @@ export default class Drawer extends React.Component<Props> {
284
284
  set(this.manuallyTriggerSpring, FALSE),
285
285
  ]),
286
286
  spring(this.clock, state, { ...SPRING_CONFIG, toValue }),
287
+ onChange(
288
+ state.finished,
289
+ cond(
290
+ state.finished,
291
+ call([this.isOpen], (open) => this.props.onTransitionEnd?.(!open)),
292
+ call([this.isOpen], (open) => this.props.onTransitionStart?.(!open))
293
+ )
294
+ ),
287
295
  cond(state.finished, [
288
296
  // Reset gesture and velocity from previous gesture
289
297
  set(this.touchX, 0),
@@ -370,6 +378,18 @@ export default class Drawer extends React.Component<Props> {
370
378
  call([], this.handleStartInteraction)
371
379
  )
372
380
  ),
381
+ onChange(
382
+ this.gestureState,
383
+ cond(eq(this.gestureState, GestureState.END), [
384
+ call([], () => this.props.onGestureEnd?.()),
385
+ ])
386
+ ),
387
+ onChange(
388
+ this.gestureState,
389
+ cond(eq(this.gestureState, GestureState.CANCELLED), [
390
+ call([], () => this.props.onGestureCancel?.()),
391
+ ])
392
+ ),
373
393
  cond(
374
394
  eq(this.gestureState, GestureState.ACTIVE),
375
395
  [
@@ -378,6 +398,7 @@ export default class Drawer extends React.Component<Props> {
378
398
  set(this.isSwiping, TRUE),
379
399
  // Also update the drag offset to the last position
380
400
  set(this.offsetX, this.position),
401
+ call([], () => this.props.onGestureStart?.()),
381
402
  ]),
382
403
  // Update position with previous offset + gesture distance
383
404
  set(
@@ -502,6 +523,7 @@ export default class Drawer extends React.Component<Props> {
502
523
  renderDrawerContent,
503
524
  children,
504
525
  gestureHandlerProps,
526
+ overlayAccessibilityLabel,
505
527
  } = this.props;
506
528
 
507
529
  const isOpen = drawerType === 'permanent' ? true : open;
@@ -592,6 +614,7 @@ export default class Drawer extends React.Component<Props> {
592
614
  <Overlay
593
615
  progress={progress}
594
616
  onPress={() => this.toggleDrawer(false)}
617
+ accessibilityLabel={overlayAccessibilityLabel}
595
618
  style={overlayStyle as any}
596
619
  accessibilityElementsHidden={!isOpen}
597
620
  importantForAccessibility={
@@ -619,7 +642,6 @@ export default class Drawer extends React.Component<Props> {
619
642
  />
620
643
  )}
621
644
  <Animated.View
622
- accessibilityViewIsModal={isOpen && drawerType !== 'permanent'}
623
645
  removeClippedSubviews={Platform.OS !== 'ios'}
624
646
  onLayout={this.handleDrawerLayout}
625
647
  style={[
@@ -18,10 +18,17 @@ const PROGRESS_EPSILON = 0.05;
18
18
  type Props = React.ComponentProps<typeof Animated.View> & {
19
19
  progress: Animated.Node<number>;
20
20
  onPress: () => void;
21
+ accessibilityLabel?: string;
21
22
  };
22
23
 
23
- const Overlay = React.forwardRef(function Overlay(
24
- { progress, onPress, style, ...props }: Props,
24
+ export const Overlay = React.forwardRef(function Overlay(
25
+ {
26
+ progress,
27
+ onPress,
28
+ style,
29
+ accessibilityLabel = 'Close drawer',
30
+ ...props
31
+ }: Props,
25
32
  ref: React.Ref<Animated.View>
26
33
  ) {
27
34
  const animatedStyle = {
@@ -48,7 +55,12 @@ const Overlay = React.forwardRef(function Overlay(
48
55
  ref={ref}
49
56
  style={[styles.overlay, overlayStyle, animatedStyle, style]}
50
57
  >
51
- <Pressable onPress={onPress} style={styles.pressable} />
58
+ <Pressable
59
+ onPress={onPress}
60
+ style={styles.pressable}
61
+ accessibilityRole="button"
62
+ accessibilityLabel={accessibilityLabel}
63
+ />
52
64
  </Animated.View>
53
65
  );
54
66
  });
@@ -71,5 +83,3 @@ const styles = StyleSheet.create({
71
83
  flex: 1,
72
84
  },
73
85
  });
74
-
75
- export default Overlay;
@@ -17,6 +17,7 @@ import Animated, {
17
17
  useSharedValue,
18
18
  withSpring,
19
19
  } from 'react-native-reanimated';
20
+ import useLatestCallback from 'use-latest-callback';
20
21
 
21
22
  import {
22
23
  DEFAULT_DRAWER_WIDTH,
@@ -25,13 +26,13 @@ import {
25
26
  SWIPE_MIN_VELOCITY,
26
27
  } from '../../constants';
27
28
  import type { DrawerProps } from '../../types';
28
- import DrawerProgressContext from '../../utils/DrawerProgressContext';
29
+ import { DrawerProgressContext } from '../../utils/DrawerProgressContext';
29
30
  import {
30
31
  GestureState,
31
32
  PanGestureHandler,
32
33
  PanGestureHandlerGestureEvent,
33
34
  } from '../GestureHandler';
34
- import Overlay from './Overlay';
35
+ import { Overlay } from './Overlay';
35
36
 
36
37
  const minmax = (value: number, start: number, end: number) => {
37
38
  'worklet';
@@ -43,7 +44,7 @@ type Props = DrawerProps & {
43
44
  layout: { width: number };
44
45
  };
45
46
 
46
- export default function Drawer({
47
+ export function Drawer({
47
48
  layout,
48
49
  drawerPosition,
49
50
  drawerStyle,
@@ -53,8 +54,14 @@ export default function Drawer({
53
54
  keyboardDismissMode,
54
55
  onClose,
55
56
  onOpen,
57
+ onGestureStart,
58
+ onGestureCancel,
59
+ onGestureEnd,
60
+ onTransitionStart,
61
+ onTransitionEnd,
56
62
  open,
57
63
  overlayStyle,
64
+ overlayAccessibilityLabel,
58
65
  statusBarAnimation,
59
66
  swipeEnabled,
60
67
  swipeEdgeWidth,
@@ -131,13 +138,15 @@ export default function Drawer({
131
138
  }
132
139
  };
133
140
 
134
- const onGestureStart = () => {
141
+ const onGestureBegin = () => {
142
+ onGestureStart?.();
135
143
  startInteraction();
136
144
  hideKeyboard();
137
145
  hideStatusBar(true);
138
146
  };
139
147
 
140
148
  const onGestureFinish = () => {
149
+ onGestureEnd?.();
141
150
  endInteraction();
142
151
  };
143
152
 
@@ -154,23 +163,42 @@ export default function Drawer({
154
163
  const translationX = useSharedValue(getDrawerTranslationX(open));
155
164
  const gestureState = useSharedValue<GestureState>(GestureState.UNDETERMINED);
156
165
 
166
+ const handleAnimationStart = useLatestCallback((open: boolean) => {
167
+ onTransitionStart?.(!open);
168
+ });
169
+
170
+ const handleAnimationEnd = useLatestCallback(
171
+ (open: boolean, finished?: boolean) => {
172
+ if (!finished) return;
173
+ onTransitionEnd?.(!open);
174
+ }
175
+ );
176
+
157
177
  const toggleDrawer = React.useCallback(
158
178
  (open: boolean, velocity?: number) => {
159
179
  'worklet';
160
180
 
161
181
  const translateX = getDrawerTranslationX(open);
162
182
 
183
+ if (velocity === undefined) {
184
+ runOnJS(handleAnimationStart)(open);
185
+ }
186
+
163
187
  touchStartX.value = 0;
164
188
  touchX.value = 0;
165
- translationX.value = withSpring(translateX, {
166
- velocity,
167
- stiffness: 1000,
168
- damping: 500,
169
- mass: 3,
170
- overshootClamping: true,
171
- restDisplacementThreshold: 0.01,
172
- restSpeedThreshold: 0.01,
173
- });
189
+ translationX.value = withSpring(
190
+ translateX,
191
+ {
192
+ velocity,
193
+ stiffness: 1000,
194
+ damping: 500,
195
+ mass: 3,
196
+ overshootClamping: true,
197
+ restDisplacementThreshold: 0.01,
198
+ restSpeedThreshold: 0.01,
199
+ },
200
+ (finished) => runOnJS(handleAnimationEnd)(open, finished)
201
+ );
174
202
 
175
203
  if (open) {
176
204
  runOnJS(onOpen)();
@@ -178,7 +206,16 @@ export default function Drawer({
178
206
  runOnJS(onClose)();
179
207
  }
180
208
  },
181
- [getDrawerTranslationX, onClose, onOpen, touchStartX, touchX, translationX]
209
+ [
210
+ getDrawerTranslationX,
211
+ handleAnimationEnd,
212
+ handleAnimationStart,
213
+ onClose,
214
+ onOpen,
215
+ touchStartX,
216
+ touchX,
217
+ translationX,
218
+ ]
182
219
  );
183
220
 
184
221
  React.useEffect(() => toggleDrawer(open), [open, toggleDrawer]);
@@ -193,17 +230,20 @@ export default function Drawer({
193
230
  gestureState.value = event.state;
194
231
  touchStartX.value = event.x;
195
232
  },
233
+ onCancel: () => {
234
+ runOnJS(() => onGestureCancel?.())();
235
+ },
196
236
  onActive: (event, ctx) => {
197
237
  touchX.value = event.x;
198
238
  translationX.value = ctx.startX + event.translationX;
199
239
  gestureState.value = event.state;
200
240
 
201
241
  // onStart will _always_ be called, even when the activation
202
- // criteria isn't met yet. This makes sure onGestureStart is only
242
+ // criteria isn't met yet. This makes sure onGestureBegin is only
203
243
  // called when the criteria is really met.
204
244
  if (!ctx.hasCalledOnStart) {
205
245
  ctx.hasCalledOnStart = true;
206
- runOnJS(onGestureStart)();
246
+ runOnJS(onGestureBegin)();
207
247
  }
208
248
  },
209
249
  onEnd: (event) => {
@@ -366,11 +406,11 @@ export default function Drawer({
366
406
  progress={progress}
367
407
  onPress={() => toggleDrawer(false)}
368
408
  style={overlayStyle}
409
+ accessibilityLabel={overlayAccessibilityLabel}
369
410
  />
370
411
  ) : null}
371
412
  </Animated.View>
372
413
  <Animated.View
373
- accessibilityViewIsModal={isOpen && drawerType !== 'permanent'}
374
414
  removeClippedSubviews={Platform.OS !== 'ios'}
375
415
  style={[
376
416
  styles.container,
@@ -10,10 +10,17 @@ const PROGRESS_EPSILON = 0.05;
10
10
  type Props = React.ComponentProps<typeof Animated.View> & {
11
11
  progress: Animated.SharedValue<number>;
12
12
  onPress: () => void;
13
+ accessibilityLabel?: string;
13
14
  };
14
15
 
15
- const Overlay = React.forwardRef(function Overlay(
16
- { progress, onPress, style, ...props }: Props,
16
+ export const Overlay = React.forwardRef(function Overlay(
17
+ {
18
+ progress,
19
+ onPress,
20
+ style,
21
+ accessibilityLabel = 'Close drawer',
22
+ ...props
23
+ }: Props,
17
24
  ref: React.Ref<Animated.View>
18
25
  ) {
19
26
  const animatedStyle = useAnimatedStyle(() => {
@@ -42,7 +49,12 @@ const Overlay = React.forwardRef(function Overlay(
42
49
  style={[styles.overlay, overlayStyle, animatedStyle, style]}
43
50
  animatedProps={animatedProps}
44
51
  >
45
- <Pressable onPress={onPress} style={styles.pressable} />
52
+ <Pressable
53
+ onPress={onPress}
54
+ style={styles.pressable}
55
+ accessibilityRole="button"
56
+ accessibilityLabel={accessibilityLabel}
57
+ />
46
58
  </Animated.View>
47
59
  );
48
60
  });
@@ -66,5 +78,3 @@ const styles = StyleSheet.create({
66
78
  pointerEvents: 'auto',
67
79
  },
68
80
  });
69
-
70
- export default Overlay;