react-native-screens 3.8.0 → 3.10.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.
Files changed (79) hide show
  1. package/README.md +61 -3
  2. package/android/build.gradle +0 -2
  3. package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +71 -0
  4. package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +7 -0
  5. package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +29 -0
  6. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -1
  7. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +7 -41
  8. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +55 -40
  9. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +19 -1
  10. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +30 -5
  11. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +77 -12
  12. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +13 -4
  13. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +8 -0
  14. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +7 -1
  15. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +1 -0
  16. package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +90 -0
  17. package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +150 -0
  18. package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +40 -0
  19. package/ios/RNSScreen.m +35 -0
  20. package/ios/RNSScreenStack.m +24 -6
  21. package/ios/RNSScreenStackHeaderConfig.m +41 -0
  22. package/lib/commonjs/index.js +24 -1
  23. package/lib/commonjs/index.js.map +1 -1
  24. package/lib/commonjs/index.native.js +101 -11
  25. package/lib/commonjs/index.native.js.map +1 -1
  26. package/lib/commonjs/native-stack/utils/useBackPressSubscription.js +67 -0
  27. package/lib/commonjs/native-stack/utils/useBackPressSubscription.js.map +1 -0
  28. package/lib/commonjs/native-stack/views/HeaderConfig.js +46 -4
  29. package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -1
  30. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +60 -0
  31. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
  32. package/lib/commonjs/reanimated/ReanimatedScreen.js +7 -79
  33. package/lib/commonjs/reanimated/ReanimatedScreen.js.map +1 -1
  34. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js +61 -0
  35. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js.map +1 -0
  36. package/lib/commonjs/reanimated/index.js +2 -2
  37. package/lib/commonjs/reanimated/index.js.map +1 -1
  38. package/lib/commonjs/utils.js +20 -0
  39. package/lib/commonjs/utils.js.map +1 -0
  40. package/lib/module/index.js +5 -0
  41. package/lib/module/index.js.map +1 -1
  42. package/lib/module/index.native.js +97 -13
  43. package/lib/module/index.native.js.map +1 -1
  44. package/lib/module/native-stack/utils/useBackPressSubscription.js +50 -0
  45. package/lib/module/native-stack/utils/useBackPressSubscription.js.map +1 -0
  46. package/lib/module/native-stack/views/HeaderConfig.js +46 -5
  47. package/lib/module/native-stack/views/HeaderConfig.js.map +1 -1
  48. package/lib/module/reanimated/ReanimatedNativeStackScreen.js +40 -0
  49. package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
  50. package/lib/module/reanimated/ReanimatedScreen.js +6 -73
  51. package/lib/module/reanimated/ReanimatedScreen.js.map +1 -1
  52. package/lib/module/reanimated/ReanimatedScreenProvider.js +49 -0
  53. package/lib/module/reanimated/ReanimatedScreenProvider.js.map +1 -0
  54. package/lib/module/reanimated/index.js +1 -1
  55. package/lib/module/reanimated/index.js.map +1 -1
  56. package/lib/module/utils.js +8 -0
  57. package/lib/module/utils.js.map +1 -0
  58. package/lib/typescript/index.d.ts +2 -0
  59. package/lib/typescript/native-stack/types.d.ts +0 -2
  60. package/lib/typescript/native-stack/utils/useBackPressSubscription.d.ts +16 -0
  61. package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +5 -0
  62. package/lib/typescript/reanimated/ReanimatedScreen.d.ts +5 -2
  63. package/lib/typescript/reanimated/ReanimatedScreenProvider.d.ts +2 -0
  64. package/lib/typescript/reanimated/index.d.ts +1 -1
  65. package/lib/typescript/types.d.ts +46 -1
  66. package/lib/typescript/utils.d.ts +2 -0
  67. package/native-stack/README.md +35 -7
  68. package/package.json +5 -2
  69. package/src/index.native.tsx +134 -38
  70. package/src/index.tsx +10 -0
  71. package/src/native-stack/types.tsx +0 -2
  72. package/src/native-stack/utils/useBackPressSubscription.tsx +66 -0
  73. package/src/native-stack/views/HeaderConfig.tsx +46 -3
  74. package/src/reanimated/ReanimatedNativeStackScreen.tsx +61 -0
  75. package/src/reanimated/ReanimatedScreen.tsx +6 -84
  76. package/src/reanimated/ReanimatedScreenProvider.tsx +42 -0
  77. package/src/reanimated/index.tsx +1 -1
  78. package/src/types.tsx +46 -1
  79. package/src/utils.ts +12 -0
@@ -0,0 +1,61 @@
1
+ import React from 'react';
2
+ import { Platform } from 'react-native';
3
+ import {
4
+ Screen,
5
+ ScreenProps,
6
+ TransitionProgressEventType,
7
+ } from 'react-native-screens';
8
+
9
+ // @ts-ignore file to be used only if `react-native-reanimated` available in the project
10
+ import Animated, { useEvent, useSharedValue } from 'react-native-reanimated';
11
+ import ReanimatedTransitionProgressContext from './ReanimatedTransitionProgressContext';
12
+
13
+ const AnimatedScreen = Animated.createAnimatedComponent(
14
+ (Screen as unknown) as React.ComponentClass
15
+ );
16
+
17
+ const ReanimatedNativeStackScreen = React.forwardRef<
18
+ typeof AnimatedScreen,
19
+ ScreenProps
20
+ >((props, ref) => {
21
+ const { children, ...rest } = props;
22
+
23
+ const progress = useSharedValue(0);
24
+ const closing = useSharedValue(0);
25
+ const goingForward = useSharedValue(0);
26
+
27
+ return (
28
+ <AnimatedScreen
29
+ // @ts-ignore some problems with ref and onTransitionProgressReanimated being "fake" prop for parsing of `useEvent` return value
30
+ ref={ref}
31
+ onTransitionProgressReanimated={useEvent(
32
+ (event: TransitionProgressEventType) => {
33
+ 'worklet';
34
+ progress.value = event.progress;
35
+ closing.value = event.closing;
36
+ goingForward.value = event.goingForward;
37
+ },
38
+ [
39
+ // This should not be necessary, but is not properly managed by `react-native-reanimated`
40
+ // @ts-ignore wrong type
41
+ Platform.OS === 'android'
42
+ ? 'onTransitionProgress'
43
+ : 'topTransitionProgress',
44
+ ]
45
+ )}
46
+ {...rest}>
47
+ <ReanimatedTransitionProgressContext.Provider
48
+ value={{
49
+ progress: progress,
50
+ closing: closing,
51
+ goingForward: goingForward,
52
+ }}>
53
+ {children}
54
+ </ReanimatedTransitionProgressContext.Provider>
55
+ </AnimatedScreen>
56
+ );
57
+ });
58
+
59
+ ReanimatedNativeStackScreen.displayName = 'ReanimatedNativeStackScreen';
60
+
61
+ export default ReanimatedNativeStackScreen;
@@ -1,103 +1,25 @@
1
- import React, { PropsWithChildren } from 'react';
2
- import { Platform, View } from 'react-native';
3
- import {
4
- Screen,
5
- ScreenProps,
6
- ScreenContext,
7
- TransitionProgressEventType,
8
- } from 'react-native-screens';
1
+ import React from 'react';
2
+ import { Screen, ScreenProps } from 'react-native-screens';
9
3
 
10
4
  // @ts-ignore file to be used only if `react-native-reanimated` available in the project
11
- import Animated, { useEvent, useSharedValue } from 'react-native-reanimated';
12
- import ReanimatedTransitionProgressContext from './ReanimatedTransitionProgressContext';
5
+ import Animated from 'react-native-reanimated';
13
6
 
14
7
  const AnimatedScreen = Animated.createAnimatedComponent(
15
8
  (Screen as unknown) as React.ComponentClass
16
9
  );
17
10
 
18
- class ReanimatedScreenWrapper extends React.Component<ScreenProps> {
19
- private ref: React.ElementRef<typeof View> | null = null;
20
-
21
- setNativeProps(props: ScreenProps): void {
22
- this.ref?.setNativeProps(props);
23
- }
24
-
25
- setRef = (ref: React.ElementRef<typeof View> | null): void => {
26
- this.ref = ref;
27
- this.props.onComponentRef?.(ref);
28
- };
29
-
30
- render() {
31
- return (
32
- <ReanimatedScreen
33
- {...this.props}
34
- // @ts-ignore some problems with ref
35
- ref={this.setRef}
36
- />
37
- );
38
- }
39
- }
40
-
41
11
  const ReanimatedScreen = React.forwardRef<typeof AnimatedScreen, ScreenProps>(
42
12
  (props, ref) => {
43
- const { children, ...rest } = props;
44
-
45
- const progress = useSharedValue(0);
46
- const closing = useSharedValue(0);
47
- const goingForward = useSharedValue(0);
48
-
49
13
  return (
50
14
  <AnimatedScreen
51
15
  // @ts-ignore some problems with ref and onTransitionProgressReanimated being "fake" prop for parsing of `useEvent` return value
52
16
  ref={ref}
53
- // ReanimatedScreen.tsx should only be used by Screens of native-stack, but it always better to check
54
- onTransitionProgressReanimated={
55
- !props.isNativeStack
56
- ? undefined
57
- : useEvent(
58
- (event: TransitionProgressEventType) => {
59
- 'worklet';
60
- progress.value = event.progress;
61
- closing.value = event.closing;
62
- goingForward.value = event.goingForward;
63
- },
64
- [
65
- // This should not be necessary, but is not properly managed by `react-native-reanimated`
66
- // @ts-ignore wrong type
67
- Platform.OS === 'android'
68
- ? 'onTransitionProgress'
69
- : 'topTransitionProgress',
70
- ]
71
- )
72
- }
73
- {...rest}>
74
- {!props.isNativeStack ? ( // see comment of this prop in types.tsx for information why it is needed
75
- children
76
- ) : (
77
- <ReanimatedTransitionProgressContext.Provider
78
- value={{
79
- progress: progress,
80
- closing: closing,
81
- goingForward: goingForward,
82
- }}>
83
- {children}
84
- </ReanimatedTransitionProgressContext.Provider>
85
- )}
86
- </AnimatedScreen>
17
+ {...props}
18
+ />
87
19
  );
88
20
  }
89
21
  );
90
22
 
91
- // used to silence error "Component definition is missing display name"
92
23
  ReanimatedScreen.displayName = 'ReanimatedScreen';
93
24
 
94
- export default function ReanimatedScreenProvider(
95
- props: PropsWithChildren<unknown>
96
- ) {
97
- return (
98
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
- <ScreenContext.Provider value={ReanimatedScreenWrapper as any}>
100
- {props.children}
101
- </ScreenContext.Provider>
102
- );
103
- }
25
+ export default ReanimatedScreen;
@@ -0,0 +1,42 @@
1
+ import React, { PropsWithChildren } from 'react';
2
+ import { View } from 'react-native';
3
+ import { ScreenProps, ScreenContext } from 'react-native-screens';
4
+ import ReanimatedNativeStackScreen from './ReanimatedNativeStackScreen';
5
+ import AnimatedScreen from './ReanimatedScreen';
6
+
7
+ class ReanimatedScreenWrapper extends React.Component<ScreenProps> {
8
+ private ref: React.ElementRef<typeof View> | null = null;
9
+
10
+ setNativeProps(props: ScreenProps): void {
11
+ this.ref?.setNativeProps(props);
12
+ }
13
+
14
+ setRef = (ref: React.ElementRef<typeof View> | null): void => {
15
+ this.ref = ref;
16
+ this.props.onComponentRef?.(ref);
17
+ };
18
+
19
+ render() {
20
+ const ReanimatedScreen = this.props.isNativeStack
21
+ ? ReanimatedNativeStackScreen
22
+ : AnimatedScreen;
23
+ return (
24
+ <ReanimatedScreen
25
+ {...this.props}
26
+ // @ts-ignore some problems with ref
27
+ ref={this.setRef}
28
+ />
29
+ );
30
+ }
31
+ }
32
+
33
+ export default function ReanimatedScreenProvider(
34
+ props: PropsWithChildren<unknown>
35
+ ) {
36
+ return (
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ <ScreenContext.Provider value={ReanimatedScreenWrapper as any}>
39
+ {props.children}
40
+ </ScreenContext.Provider>
41
+ );
42
+ }
@@ -1,2 +1,2 @@
1
- export { default as ReanimatedScreenProvider } from './ReanimatedScreen';
1
+ export { default as ReanimatedScreenProvider } from './ReanimatedScreenProvider';
2
2
  export { default as useReanimatedTransitionProgress } from './useReanimatedTransitionProgress';
package/src/types.tsx CHANGED
@@ -331,6 +331,14 @@ export interface ScreenStackHeaderConfigProps extends ViewProps {
331
331
  * Boolean that allows for disabling drop shadow under navigation header when the edge of any scrollable content reaches the matching edge of the navigation bar.
332
332
  */
333
333
  largeTitleHideShadow?: boolean;
334
+ /**
335
+ * Callback which is executed when screen header is attached
336
+ */
337
+ onAttached?: () => void;
338
+ /**
339
+ * Callback which is executed when screen header is detached
340
+ */
341
+ onDetached?: () => void;
334
342
  /**
335
343
  * String that can be displayed in the header as a fallback for `headerTitle`.
336
344
  */
@@ -371,24 +379,47 @@ export interface SearchBarProps {
371
379
  * The auto-capitalization behavior
372
380
  */
373
381
  autoCapitalize?: 'none' | 'words' | 'sentences' | 'characters';
382
+ /**
383
+ * Automatically focuses search bar on mount
384
+ *
385
+ * @platform android
386
+ */
387
+ autoFocus?: boolean;
374
388
  /**
375
389
  * The search field background color
376
390
  */
377
391
  barTintColor?: string;
378
392
  /**
379
393
  * The text to be used instead of default `Cancel` button text
394
+ *
395
+ * @platform ios
380
396
  */
381
397
  cancelButtonText?: string;
382
-
398
+ /**
399
+ * Specifies whether the back button should close search bar's text input or not.
400
+ *
401
+ * @platform android
402
+ */
403
+ disableBackButtonOverride?: boolean;
383
404
  /**
384
405
  * Indicates whether to hide the navigation bar
406
+ *
407
+ * @platform ios
385
408
  */
386
409
  hideNavigationBar?: boolean;
387
410
  /**
388
411
  * Indicates whether to hide the search bar when scrolling
412
+ *
413
+ * @platform ios
389
414
  */
390
415
  hideWhenScrolling?: boolean;
391
416
 
417
+ /**
418
+ * Sets type of the input. Defaults to `text`.
419
+ *
420
+ * @platform android
421
+ */
422
+ inputType?: 'text' | 'phone' | 'number' | 'email';
392
423
  /**
393
424
  * Indicates whether to to obscure the underlying content
394
425
  */
@@ -399,6 +430,8 @@ export interface SearchBarProps {
399
430
  onBlur?: (e: NativeSyntheticEvent<TargetedEvent>) => void;
400
431
  /**
401
432
  * A callback that gets called when the cancel button is pressed
433
+ *
434
+ * @platform ios
402
435
  */
403
436
  onCancelButtonPress?: (e: NativeSyntheticEvent<TargetedEvent>) => void;
404
437
 
@@ -410,7 +443,19 @@ export interface SearchBarProps {
410
443
  /**
411
444
  * A callback that gets called when search bar has received focus
412
445
  */
446
+ onClose?: () => void;
447
+ /**
448
+ * A callback that gets called when search bar is opened
449
+ *
450
+ * @platform android
451
+ */
413
452
  onFocus?: (e: NativeSyntheticEvent<TargetedEvent>) => void;
453
+ /**
454
+ * A callback that gets called when search bar is closed
455
+ *
456
+ * @platform android
457
+ */
458
+ onOpen?: () => void;
414
459
  /**
415
460
  * A callback that gets called when the search button is pressed. It receives the current text value of the search bar.
416
461
  */
package/src/utils.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { BackHandler, Platform } from 'react-native';
2
+
3
+ export const isSearchBarAvailableForCurrentPlatform = [
4
+ 'ios',
5
+ 'android',
6
+ ].includes(Platform.OS);
7
+
8
+ export function executeNativeBackPress() {
9
+ // This function invokes the native back press event
10
+ BackHandler.exitApp();
11
+ return true;
12
+ }