@react-navigation/elements 3.0.0-alpha.5 → 3.0.0-alpha.50

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 (213) hide show
  1. package/lib/module/ActivityView.js +90 -0
  2. package/lib/module/ActivityView.js.map +1 -0
  3. package/lib/module/ActivityView.native.js +67 -0
  4. package/lib/module/ActivityView.native.js.map +1 -0
  5. package/lib/module/Badge.js +6 -7
  6. package/lib/module/Badge.js.map +1 -1
  7. package/lib/module/BlurEffectBackground.js +3 -3
  8. package/lib/module/BlurEffectBackground.js.map +1 -1
  9. package/lib/module/Button.js +99 -14
  10. package/lib/module/Button.js.map +1 -1
  11. package/lib/module/Color.js +565 -4
  12. package/lib/module/Color.js.map +1 -1
  13. package/lib/module/Container.js +12 -1
  14. package/lib/module/Container.js.map +1 -1
  15. package/lib/module/Header/Header.js +30 -18
  16. package/lib/module/Header/Header.js.map +1 -1
  17. package/lib/module/Header/HeaderBackButton.js +27 -13
  18. package/lib/module/Header/HeaderBackButton.js.map +1 -1
  19. package/lib/module/Header/HeaderButton.js +4 -5
  20. package/lib/module/Header/HeaderButton.js.map +1 -1
  21. package/lib/module/Header/HeaderButtonBackground.js +1 -2
  22. package/lib/module/Header/HeaderButtonBackground.js.map +1 -1
  23. package/lib/module/Header/HeaderIcon.js +14 -17
  24. package/lib/module/Header/HeaderIcon.js.map +1 -1
  25. package/lib/module/Header/HeaderSearchBar.js +36 -26
  26. package/lib/module/Header/HeaderSearchBar.js.map +1 -1
  27. package/lib/module/Header/getHeaderTitle.js.map +1 -1
  28. package/lib/module/Header/useHeaderHeight.js +1 -1
  29. package/lib/module/Header/useHeaderHeight.js.map +1 -1
  30. package/lib/module/Label/getLabel.js.map +1 -1
  31. package/lib/module/LiquidGlassView.ios.js +1 -2
  32. package/lib/module/LiquidGlassView.ios.js.map +1 -1
  33. package/lib/module/LiquidGlassView.js +0 -4
  34. package/lib/module/LiquidGlassView.js.map +1 -1
  35. package/lib/module/PlatformColor.js +1 -0
  36. package/lib/module/PlatformColor.js.map +1 -1
  37. package/lib/module/PlatformColor.native.js +1 -1
  38. package/lib/module/PlatformColor.native.js.map +1 -1
  39. package/lib/module/PlatformIcon.js +46 -0
  40. package/lib/module/PlatformIcon.js.map +1 -0
  41. package/lib/module/PlatformPressable.js +64 -21
  42. package/lib/module/PlatformPressable.js.map +1 -1
  43. package/lib/module/SafeAreaProviderCompat.js +1 -1
  44. package/lib/module/SafeAreaProviderCompat.js.map +1 -1
  45. package/lib/module/Screen.js +31 -18
  46. package/lib/module/Screen.js.map +1 -1
  47. package/lib/module/index.js +2 -7
  48. package/lib/module/index.js.map +1 -1
  49. package/lib/module/internal.js +1 -1
  50. package/lib/module/internal.js.map +1 -1
  51. package/lib/module/useFrameSize.js +6 -2
  52. package/lib/module/useFrameSize.js.map +1 -1
  53. package/lib/typescript/src/ActivityView.d.ts +31 -0
  54. package/lib/typescript/src/ActivityView.d.ts.map +1 -0
  55. package/lib/typescript/src/ActivityView.native.d.ts +3 -0
  56. package/lib/typescript/src/ActivityView.native.d.ts.map +1 -0
  57. package/lib/typescript/src/Badge.d.ts +7 -6
  58. package/lib/typescript/src/Badge.d.ts.map +1 -1
  59. package/lib/typescript/src/BlurEffectBackground.d.ts +2 -2
  60. package/lib/typescript/src/BlurEffectBackground.d.ts.map +1 -1
  61. package/lib/typescript/src/Button.d.ts +54 -6
  62. package/lib/typescript/src/Button.d.ts.map +1 -1
  63. package/lib/typescript/src/Color.d.ts +4 -4
  64. package/lib/typescript/src/Color.d.ts.map +1 -1
  65. package/lib/typescript/src/Container.d.ts +8 -4
  66. package/lib/typescript/src/Container.d.ts.map +1 -1
  67. package/lib/typescript/src/Header/Header.d.ts +5 -4
  68. package/lib/typescript/src/Header/Header.d.ts.map +1 -1
  69. package/lib/typescript/src/Header/HeaderBackButton.d.ts +3 -2
  70. package/lib/typescript/src/Header/HeaderBackButton.d.ts.map +1 -1
  71. package/lib/typescript/src/Header/HeaderBackground.d.ts +5 -5
  72. package/lib/typescript/src/Header/HeaderBackground.d.ts.map +1 -1
  73. package/lib/typescript/src/Header/HeaderButton.d.ts +7 -2
  74. package/lib/typescript/src/Header/HeaderButton.d.ts.map +1 -1
  75. package/lib/typescript/src/Header/HeaderButtonBackground.d.ts +1 -1
  76. package/lib/typescript/src/Header/HeaderButtonBackground.d.ts.map +1 -1
  77. package/lib/typescript/src/Header/HeaderIcon.d.ts +10 -4
  78. package/lib/typescript/src/Header/HeaderIcon.d.ts.map +1 -1
  79. package/lib/typescript/src/Header/HeaderSearchBar.d.ts +10 -7
  80. package/lib/typescript/src/Header/HeaderSearchBar.d.ts.map +1 -1
  81. package/lib/typescript/src/Header/HeaderTitle.d.ts +4 -4
  82. package/lib/typescript/src/Header/HeaderTitle.d.ts.map +1 -1
  83. package/lib/typescript/src/Header/getHeaderTitle.d.ts +2 -2
  84. package/lib/typescript/src/Header/getHeaderTitle.d.ts.map +1 -1
  85. package/lib/typescript/src/Label/Label.d.ts +1 -1
  86. package/lib/typescript/src/Label/Label.d.ts.map +1 -1
  87. package/lib/typescript/src/Label/getLabel.d.ts +2 -2
  88. package/lib/typescript/src/Label/getLabel.d.ts.map +1 -1
  89. package/lib/typescript/src/LiquidGlassView.d.ts +7 -5
  90. package/lib/typescript/src/LiquidGlassView.d.ts.map +1 -1
  91. package/lib/typescript/src/LiquidGlassView.ios.d.ts +4 -2
  92. package/lib/typescript/src/LiquidGlassView.ios.d.ts.map +1 -1
  93. package/lib/typescript/src/MissingIcon.d.ts +3 -3
  94. package/lib/typescript/src/MissingIcon.d.ts.map +1 -1
  95. package/lib/typescript/src/PlatformColor.d.ts +1 -0
  96. package/lib/typescript/src/PlatformColor.d.ts.map +1 -1
  97. package/lib/typescript/src/PlatformColor.native.d.ts +1 -1
  98. package/lib/typescript/src/PlatformColor.native.d.ts.map +1 -1
  99. package/lib/typescript/src/PlatformIcon.d.ts +11 -0
  100. package/lib/typescript/src/PlatformIcon.d.ts.map +1 -0
  101. package/lib/typescript/src/PlatformPressable.d.ts +12 -15
  102. package/lib/typescript/src/PlatformPressable.d.ts.map +1 -1
  103. package/lib/typescript/src/SafeAreaProviderCompat.d.ts +1 -1
  104. package/lib/typescript/src/SafeAreaProviderCompat.d.ts.map +1 -1
  105. package/lib/typescript/src/Screen.d.ts +7 -7
  106. package/lib/typescript/src/Screen.d.ts.map +1 -1
  107. package/lib/typescript/src/Text.d.ts +1 -1
  108. package/lib/typescript/src/Text.d.ts.map +1 -1
  109. package/lib/typescript/src/index.d.ts +21 -21
  110. package/lib/typescript/src/index.d.ts.map +1 -1
  111. package/lib/typescript/src/internal.d.ts +6 -6
  112. package/lib/typescript/src/internal.d.ts.map +1 -1
  113. package/lib/typescript/src/types.d.ts +120 -70
  114. package/lib/typescript/src/types.d.ts.map +1 -1
  115. package/lib/typescript/src/useFrameSize.d.ts +2 -2
  116. package/lib/typescript/src/useFrameSize.d.ts.map +1 -1
  117. package/package.json +27 -22
  118. package/src/ActivityView.native.tsx +90 -0
  119. package/src/ActivityView.tsx +129 -0
  120. package/src/Badge.tsx +11 -10
  121. package/src/BlurEffectBackground.tsx +3 -3
  122. package/src/Button.tsx +177 -28
  123. package/src/Color.tsx +755 -8
  124. package/src/Container.tsx +21 -4
  125. package/src/Header/Header.tsx +47 -27
  126. package/src/Header/HeaderBackButton.tsx +34 -20
  127. package/src/Header/HeaderBackground.tsx +3 -3
  128. package/src/Header/HeaderButton.tsx +16 -18
  129. package/src/Header/HeaderButtonBackground.tsx +1 -4
  130. package/src/Header/HeaderIcon.tsx +26 -13
  131. package/src/Header/HeaderSearchBar.tsx +58 -49
  132. package/src/Header/HeaderTitle.tsx +3 -3
  133. package/src/Header/getHeaderTitle.tsx +4 -1
  134. package/src/Header/useHeaderHeight.tsx +1 -1
  135. package/src/Label/getLabel.tsx +1 -1
  136. package/src/LiquidGlassView.ios.tsx +14 -9
  137. package/src/LiquidGlassView.tsx +15 -11
  138. package/src/MissingIcon.tsx +2 -2
  139. package/src/PlatformColor.native.tsx +1 -1
  140. package/src/PlatformColor.tsx +4 -0
  141. package/src/PlatformIcon.tsx +70 -0
  142. package/src/PlatformPressable.tsx +108 -48
  143. package/src/SafeAreaProviderCompat.tsx +1 -1
  144. package/src/Screen.tsx +41 -28
  145. package/src/index.tsx +2 -16
  146. package/src/internal.tsx +1 -1
  147. package/src/types.tsx +153 -76
  148. package/src/useFrameSize.tsx +11 -4
  149. package/lib/module/Lazy.js +0 -42
  150. package/lib/module/Lazy.js.map +0 -1
  151. package/lib/module/assets/back-icon.ios.svg +0 -4
  152. package/lib/module/assets/back-icon@1x.android.png +0 -0
  153. package/lib/module/assets/back-icon@1x.ios.png +0 -0
  154. package/lib/module/assets/back-icon@2x.android.png +0 -0
  155. package/lib/module/assets/back-icon@2x.ios.png +0 -0
  156. package/lib/module/assets/back-icon@3x.android.png +0 -0
  157. package/lib/module/assets/back-icon@3x.ios.png +0 -0
  158. package/lib/module/assets/back-icon@4x.android.png +0 -0
  159. package/lib/module/assets/back-icon@4x.ios.png +0 -0
  160. package/lib/module/assets/clear-icon@1x.png +0 -0
  161. package/lib/module/assets/clear-icon@2x.png +0 -0
  162. package/lib/module/assets/clear-icon@3x.png +0 -0
  163. package/lib/module/assets/clear-icon@4x.png +0 -0
  164. package/lib/module/assets/close-icon@1x.png +0 -0
  165. package/lib/module/assets/close-icon@2x.png +0 -0
  166. package/lib/module/assets/close-icon@3x.png +0 -0
  167. package/lib/module/assets/close-icon@4x.png +0 -0
  168. package/lib/module/assets/search-icon-legacy@1x.ios.png +0 -0
  169. package/lib/module/assets/search-icon-legacy@2x.ios.png +0 -0
  170. package/lib/module/assets/search-icon-legacy@3x.ios.png +0 -0
  171. package/lib/module/assets/search-icon-legacy@4x.ios.png +0 -0
  172. package/lib/module/assets/search-icon.ios.svg +0 -4
  173. package/lib/module/assets/search-icon@1x.android.png +0 -0
  174. package/lib/module/assets/search-icon@1x.ios.png +0 -0
  175. package/lib/module/assets/search-icon@2x.android.png +0 -0
  176. package/lib/module/assets/search-icon@2x.ios.png +0 -0
  177. package/lib/module/assets/search-icon@3x.android.png +0 -0
  178. package/lib/module/assets/search-icon@3x.ios.png +0 -0
  179. package/lib/module/assets/search-icon@4x.android.png +0 -0
  180. package/lib/module/assets/search-icon@4x.ios.png +0 -0
  181. package/lib/typescript/src/Lazy.d.ts +0 -31
  182. package/lib/typescript/src/Lazy.d.ts.map +0 -1
  183. package/src/Lazy.tsx +0 -59
  184. package/src/assets/back-icon.ios.svg +0 -4
  185. package/src/assets/back-icon@1x.android.png +0 -0
  186. package/src/assets/back-icon@1x.ios.png +0 -0
  187. package/src/assets/back-icon@2x.android.png +0 -0
  188. package/src/assets/back-icon@2x.ios.png +0 -0
  189. package/src/assets/back-icon@3x.android.png +0 -0
  190. package/src/assets/back-icon@3x.ios.png +0 -0
  191. package/src/assets/back-icon@4x.android.png +0 -0
  192. package/src/assets/back-icon@4x.ios.png +0 -0
  193. package/src/assets/clear-icon@1x.png +0 -0
  194. package/src/assets/clear-icon@2x.png +0 -0
  195. package/src/assets/clear-icon@3x.png +0 -0
  196. package/src/assets/clear-icon@4x.png +0 -0
  197. package/src/assets/close-icon@1x.png +0 -0
  198. package/src/assets/close-icon@2x.png +0 -0
  199. package/src/assets/close-icon@3x.png +0 -0
  200. package/src/assets/close-icon@4x.png +0 -0
  201. package/src/assets/search-icon-legacy@1x.ios.png +0 -0
  202. package/src/assets/search-icon-legacy@2x.ios.png +0 -0
  203. package/src/assets/search-icon-legacy@3x.ios.png +0 -0
  204. package/src/assets/search-icon-legacy@4x.ios.png +0 -0
  205. package/src/assets/search-icon.ios.svg +0 -4
  206. package/src/assets/search-icon@1x.android.png +0 -0
  207. package/src/assets/search-icon@1x.ios.png +0 -0
  208. package/src/assets/search-icon@2x.android.png +0 -0
  209. package/src/assets/search-icon@2x.ios.png +0 -0
  210. package/src/assets/search-icon@3x.android.png +0 -0
  211. package/src/assets/search-icon@3x.ios.png +0 -0
  212. package/src/assets/search-icon@4x.android.png +0 -0
  213. package/src/assets/search-icon@4x.ios.png +0 -0
@@ -1,14 +1,20 @@
1
+ import type {
2
+ LiquidGlassContainerViewProps,
3
+ LiquidGlassViewProps,
4
+ } from '@callstack/liquid-glass';
1
5
  import { Animated, View } from 'react-native';
2
6
 
3
- type CallstackLiquidGlass = typeof import('@callstack/liquid-glass');
7
+ type AnimatedLiquidGlassViewProps =
8
+ Animated.AnimatedProps<LiquidGlassViewProps>;
9
+
10
+ type AnimatedLiquidGlassContainerViewProps =
11
+ Animated.AnimatedProps<LiquidGlassContainerViewProps>;
4
12
 
5
13
  let isLiquidGlassSupported: boolean,
6
- LiquidGlassView: CallstackLiquidGlass['LiquidGlassView'],
7
- LiquidGlassContainerView: CallstackLiquidGlass['LiquidGlassContainerView'],
8
- AnimatedLiquidGlassView: Animated.AnimatedComponent<typeof LiquidGlassView>,
9
- AnimatedLiquidGlassContainerView: Animated.AnimatedComponent<
10
- typeof LiquidGlassContainerView
11
- >;
14
+ LiquidGlassView: React.ComponentType<LiquidGlassViewProps>,
15
+ LiquidGlassContainerView: React.ComponentType<LiquidGlassContainerViewProps>,
16
+ AnimatedLiquidGlassView: React.ComponentType<AnimatedLiquidGlassViewProps>,
17
+ AnimatedLiquidGlassContainerView: React.ComponentType<AnimatedLiquidGlassContainerViewProps>;
12
18
 
13
19
  try {
14
20
  // Add try/catch to support usage even if it's not installed, since it's optional.
@@ -24,9 +30,8 @@ try {
24
30
  } catch (e) {
25
31
  isLiquidGlassSupported = false;
26
32
  LiquidGlassView = View;
27
- // @ts-expect-error: this is fine
33
+ LiquidGlassContainerView = View;
28
34
  AnimatedLiquidGlassView = Animated.View;
29
- // @ts-expect-error: this is fine
30
35
  AnimatedLiquidGlassContainerView = Animated.View;
31
36
  }
32
37
 
@@ -1,20 +1,24 @@
1
+ import type {
2
+ LiquidGlassContainerViewProps,
3
+ LiquidGlassViewProps,
4
+ } from '@callstack/liquid-glass';
1
5
  import { Animated, View } from 'react-native';
2
6
 
3
- type CallstackLiquidGlass = typeof import('@callstack/liquid-glass');
7
+ type AnimatedLiquidGlassViewProps =
8
+ Animated.AnimatedProps<LiquidGlassViewProps>;
4
9
 
5
- export const LiquidGlassView: CallstackLiquidGlass['LiquidGlassView'] = View;
10
+ type AnimatedLiquidGlassContainerViewProps =
11
+ Animated.AnimatedProps<LiquidGlassContainerViewProps>;
6
12
 
7
- export const LiquidGlassContainerView: CallstackLiquidGlass['LiquidGlassContainerView'] =
13
+ export const LiquidGlassView: React.ComponentType<LiquidGlassViewProps> = View;
14
+
15
+ export const LiquidGlassContainerView: React.ComponentType<LiquidGlassContainerViewProps> =
8
16
  View;
9
17
 
10
- // @ts-expect-error: this is fine
11
- export const AnimatedLiquidGlassView: Animated.AnimatedComponent<
12
- typeof LiquidGlassView
13
- > = Animated.View;
18
+ export const AnimatedLiquidGlassView: React.ComponentType<AnimatedLiquidGlassViewProps> =
19
+ Animated.View;
14
20
 
15
- // @ts-expect-error: this is fine
16
- export const AnimatedLiquidGlassContainerView: Animated.AnimatedComponent<
17
- typeof LiquidGlassContainerView
18
- > = Animated.View;
21
+ export const AnimatedLiquidGlassContainerView: React.ComponentType<AnimatedLiquidGlassContainerViewProps> =
22
+ Animated.View;
19
23
 
20
24
  export const isLiquidGlassSupported = false;
@@ -8,8 +8,8 @@ import {
8
8
  import { Text } from './Text';
9
9
 
10
10
  type Props = {
11
- color?: ColorValue;
12
- size?: number;
11
+ color: ColorValue;
12
+ size: number;
13
13
  style?: StyleProp<TextStyle>;
14
14
  };
15
15
 
@@ -1 +1 @@
1
- export { PlatformColor } from 'react-native';
1
+ export { DynamicColorIOS, PlatformColor } from 'react-native';
@@ -6,3 +6,7 @@
6
6
  export const PlatformColor:
7
7
  | typeof import('react-native').PlatformColor
8
8
  | undefined = undefined;
9
+
10
+ export const DynamicColorIOS:
11
+ | typeof import('react-native').DynamicColorIOS
12
+ | undefined = undefined;
@@ -0,0 +1,70 @@
1
+ import { MaterialSymbol, SFSymbol } from '@react-navigation/native';
2
+ import {
3
+ type ColorValue,
4
+ Image,
5
+ type ImageStyle,
6
+ type StyleProp,
7
+ StyleSheet,
8
+ type ViewStyle,
9
+ } from 'react-native';
10
+
11
+ import type { Icon } from './types';
12
+
13
+ export type PlatformIconStyle = ImageStyle & ViewStyle;
14
+
15
+ export type PlatformIconProps = {
16
+ icon: Icon;
17
+ size: number;
18
+ color?: ColorValue | undefined;
19
+ style?: StyleProp<PlatformIconStyle> | undefined;
20
+ };
21
+
22
+ export function PlatformIcon({
23
+ icon,
24
+ color,
25
+ size,
26
+ style,
27
+ ...rest
28
+ }: PlatformIconProps) {
29
+ switch (icon.type) {
30
+ case 'sfSymbol':
31
+ return (
32
+ <SFSymbol
33
+ name={icon.name}
34
+ color={color}
35
+ size={size}
36
+ style={StyleSheet.flatten(style)}
37
+ {...rest}
38
+ />
39
+ );
40
+ case 'materialSymbol':
41
+ return (
42
+ <MaterialSymbol
43
+ name={icon.name}
44
+ variant={icon.variant}
45
+ weight={icon.weight}
46
+ size={size}
47
+ color={color}
48
+ style={StyleSheet.flatten(style)}
49
+ {...rest}
50
+ />
51
+ );
52
+ case 'image':
53
+ return (
54
+ <Image
55
+ source={icon.source}
56
+ resizeMode="contain"
57
+ fadeDuration={0}
58
+ tintColor={icon.tinted === false ? undefined : color}
59
+ style={[
60
+ {
61
+ width: size,
62
+ height: size,
63
+ },
64
+ style,
65
+ ]}
66
+ {...rest}
67
+ />
68
+ );
69
+ }
70
+ }
@@ -1,4 +1,4 @@
1
- import { useTheme } from '@react-navigation/native';
1
+ import { IsFocusedContext, useTheme } from '@react-navigation/native';
2
2
  import * as React from 'react';
3
3
  import {
4
4
  Animated,
@@ -19,15 +19,20 @@ type HoverEffectProps = {
19
19
  };
20
20
 
21
21
  export type Props = Omit<PressableProps, 'style' | 'onPress'> & {
22
- href?: string;
23
- pressColor?: ColorValue;
24
- pressOpacity?: number;
25
- hoverEffect?: HoverEffectProps;
26
- style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
27
- onPress?: (
28
- e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
29
- ) => void;
22
+ href?: string | undefined;
23
+ pressColor?: ColorValue | undefined;
24
+ pressOpacity?: number | undefined;
25
+ hoverEffect?: HoverEffectProps | undefined;
26
+ style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>> | undefined;
27
+ onPress?:
28
+ | ((
29
+ e:
30
+ | React.MouseEvent<HTMLAnchorElement, MouseEvent>
31
+ | GestureResponderEvent
32
+ ) => void)
33
+ | undefined;
30
34
  children: React.ReactNode;
35
+ ref?: React.Ref<React.ComponentRef<typeof AnimatedPressable>> | undefined;
31
36
  };
32
37
 
33
38
  const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
@@ -41,25 +46,25 @@ const useNativeDriver = Platform.OS !== 'web';
41
46
  /**
42
47
  * PlatformPressable provides an abstraction on top of Pressable to handle platform differences.
43
48
  */
44
- function PlatformPressableInternal(
45
- {
46
- disabled,
47
- onPress,
48
- onPressIn,
49
- onPressOut,
50
- android_ripple,
51
- pressColor,
52
- pressOpacity = 0.3,
53
- hoverEffect,
54
- style,
55
- children,
56
- ...rest
57
- }: Props,
58
- ref: React.Ref<React.ComponentRef<typeof AnimatedPressable>>
59
- ) {
49
+ export function PlatformPressable({
50
+ disabled,
51
+ onPress,
52
+ onPressIn,
53
+ onPressOut,
54
+ android_ripple,
55
+ pressColor,
56
+ pressOpacity = 0.3,
57
+ hoverEffect,
58
+ style,
59
+ children,
60
+ ref,
61
+ ...rest
62
+ }: Props) {
60
63
  const { dark } = useTheme();
61
64
  const [opacity] = React.useState(() => new Animated.Value(1));
62
65
 
66
+ const interactive = !disabled && !rest['aria-disabled'];
67
+
63
68
  const animateTo = (toValue: number, duration: number) => {
64
69
  if (ANDROID_SUPPORTS_RIPPLE) {
65
70
  return;
@@ -76,7 +81,7 @@ function PlatformPressableInternal(
76
81
  const handlePress = (
77
82
  e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
78
83
  ) => {
79
- if (Platform.OS === 'web' && rest.href !== null) {
84
+ if (Platform.OS === 'web' && rest.href != null) {
80
85
  // ignore clicks with modifier keys
81
86
  const hasModifierKey =
82
87
  ('metaKey' in e && e.metaKey) ||
@@ -91,7 +96,7 @@ function PlatformPressableInternal(
91
96
  // let browser handle "target=_blank" etc.
92
97
  const isSelfTarget =
93
98
  e.currentTarget && 'target' in e.currentTarget
94
- ? [undefined, null, '', 'self'].includes(e.currentTarget.target)
99
+ ? [undefined, null, '', '_self'].includes(e.currentTarget.target)
95
100
  : true;
96
101
 
97
102
  if (!hasModifierKey && isLeftClick && isSelfTarget) {
@@ -115,16 +120,75 @@ function PlatformPressableInternal(
115
120
  onPressOut?.(e);
116
121
  };
117
122
 
123
+ const elementRef = React.useRef<HTMLElement | null>(null);
124
+
125
+ const handleRef = React.useCallback(
126
+ (node: React.ComponentRef<typeof AnimatedPressable> | null) => {
127
+ elementRef.current =
128
+ Platform.OS === 'web' &&
129
+ typeof HTMLElement !== 'undefined' &&
130
+ node instanceof HTMLElement
131
+ ? node
132
+ : null;
133
+
134
+ if (typeof ref === 'function') {
135
+ return ref(node);
136
+ } else if (ref != null) {
137
+ ref.current = node;
138
+ }
139
+ },
140
+ [ref]
141
+ );
142
+
143
+ // React Native Web doesn't correctly handle ref cleanup functions
144
+ // So we use a `useEffect` for the listeners instead of the ref callback
145
+ React.useEffect(() => {
146
+ const element = elementRef.current;
147
+
148
+ if (rest.href == null || element == null || interactive) {
149
+ return;
150
+ }
151
+
152
+ // On web, a non-interactive button prevents our onPress from being called
153
+ // But the link is still clickable, and will perform a full page navigation
154
+ // So we manually prevent the default behavior of the link in that case
155
+ // The `href` is still set so regular link semantics are preserved
156
+ const preventNavigation = (event: Event) => {
157
+ event.preventDefault();
158
+ event.stopPropagation();
159
+ };
160
+
161
+ element.addEventListener('click', preventNavigation, true);
162
+ element.addEventListener('auxclick', preventNavigation, true);
163
+
164
+ return () => {
165
+ element.removeEventListener('click', preventNavigation, true);
166
+ element.removeEventListener('auxclick', preventNavigation, true);
167
+ };
168
+ }, [interactive, rest.href]);
169
+
170
+ let focusable: boolean | undefined;
171
+
172
+ if (disabled) {
173
+ focusable = false;
174
+ } else if (Platform.isTV) {
175
+ // On `react-native-tvos`, the focus engine doesn't respect `aria-hidden` on screens
176
+ // So we hide them from TV focus engine for unfocused screens
177
+ focusable = React.use(IsFocusedContext);
178
+ }
179
+
118
180
  return (
119
181
  <AnimatedPressable
120
- ref={ref}
182
+ ref={handleRef}
121
183
  accessible
184
+ disabled={disabled}
185
+ focusable={focusable}
122
186
  role={Platform.OS === 'web' && rest.href != null ? 'link' : 'button'}
123
- onPress={disabled ? undefined : handlePress}
124
- onPressIn={disabled ? undefined : handlePressIn}
125
- onPressOut={disabled ? undefined : handlePressOut}
187
+ onPress={interactive ? handlePress : undefined}
188
+ onPressIn={interactive ? handlePressIn : undefined}
189
+ onPressOut={interactive ? handlePressOut : undefined}
126
190
  android_ripple={
127
- ANDROID_SUPPORTS_RIPPLE && !disabled
191
+ ANDROID_SUPPORTS_RIPPLE && interactive
128
192
  ? {
129
193
  color:
130
194
  pressColor !== undefined
@@ -139,27 +203,23 @@ function PlatformPressableInternal(
139
203
  style={[
140
204
  {
141
205
  cursor:
142
- (Platform.OS === 'web' || Platform.OS === 'ios') && !disabled
206
+ (Platform.OS === 'web' || Platform.OS === 'ios') && interactive
143
207
  ? // Pointer cursor on web
144
208
  // Hover effect on iPad and visionOS
145
209
  'pointer'
146
210
  : 'auto',
147
- opacity: !ANDROID_SUPPORTS_RIPPLE && !disabled ? opacity : 1,
211
+ opacity: !ANDROID_SUPPORTS_RIPPLE && interactive ? opacity : 1,
148
212
  },
149
213
  style,
150
214
  ]}
151
215
  {...rest}
152
216
  >
153
- {!disabled ? <HoverEffect {...hoverEffect} /> : null}
217
+ {interactive ? <HoverEffect {...hoverEffect} /> : null}
154
218
  {children}
155
219
  </AnimatedPressable>
156
220
  );
157
221
  }
158
222
 
159
- export const PlatformPressable = React.forwardRef(PlatformPressableInternal);
160
-
161
- PlatformPressable.displayName = 'PlatformPressable';
162
-
163
223
  const css = String.raw;
164
224
 
165
225
  const CLASS_NAME = `__react-navigation_elements_Pressable_hover`;
@@ -196,20 +256,20 @@ const HoverEffect = ({
196
256
  return null;
197
257
  }
198
258
 
259
+ const style: React.CSSProperties & {
260
+ [key: `--${string}`]: string | number;
261
+ } = {
262
+ '--overlay-color': color,
263
+ '--overlay-hover-opacity': hoverOpacity,
264
+ '--overlay-active-opacity': activeOpacity,
265
+ };
266
+
199
267
  return (
200
268
  <>
201
269
  <style href={CLASS_NAME} precedence="elements">
202
270
  {CSS_TEXT}
203
271
  </style>
204
- <div
205
- className={CLASS_NAME}
206
- style={{
207
- // @ts-expect-error: CSS variables are not typed
208
- '--overlay-color': color,
209
- '--overlay-hover-opacity': hoverOpacity,
210
- '--overlay-active-opacity': activeOpacity,
211
- }}
212
- />
272
+ <div className={CLASS_NAME} style={style} />
213
273
  </>
214
274
  );
215
275
  };
@@ -34,7 +34,7 @@ const initialMetrics =
34
34
  : initialWindowMetrics;
35
35
 
36
36
  export function SafeAreaProviderCompat({ children, style }: Props) {
37
- const insets = React.useContext(SafeAreaInsetsContext);
37
+ const insets = React.use(SafeAreaInsetsContext);
38
38
 
39
39
  return (
40
40
  <FrameSizeProvider
package/src/Screen.tsx CHANGED
@@ -6,15 +6,10 @@ import {
6
6
  useTheme,
7
7
  } from '@react-navigation/native';
8
8
  import * as React from 'react';
9
- import {
10
- Animated,
11
- type StyleProp,
12
- StyleSheet,
13
- View,
14
- type ViewStyle,
15
- } from 'react-native';
9
+ import { StyleSheet, View } from 'react-native';
16
10
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
17
11
 
12
+ import { Container, type Props as ContainerProps } from './Container';
18
13
  import { getDefaultHeaderHeight } from './Header/getDefaultHeaderHeight';
19
14
  import { HeaderHeightContext } from './Header/HeaderHeightContext';
20
15
  import { HeaderShownContext } from './Header/HeaderShownContext';
@@ -22,14 +17,14 @@ import { useFrameSize } from './useFrameSize';
22
17
 
23
18
  type Props = {
24
19
  focused: boolean;
25
- modal?: boolean;
20
+ modal?: boolean | undefined;
26
21
  navigation: NavigationProp<ParamListBase>;
27
22
  route: RouteProp<ParamListBase>;
28
23
  header: React.ReactNode;
29
- headerShown?: boolean;
30
- headerStatusBarHeight?: number;
31
- headerTransparent?: boolean;
32
- style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
24
+ headerShown?: boolean | undefined;
25
+ headerStatusBarHeight?: number | undefined;
26
+ headerTransparent?: boolean | undefined;
27
+ style?: ContainerProps['style'] | undefined;
33
28
  children: React.ReactNode;
34
29
  };
35
30
 
@@ -37,8 +32,8 @@ export function Screen(props: Props) {
37
32
  const insets = useSafeAreaInsets();
38
33
  const { colors } = useTheme();
39
34
 
40
- const isParentHeaderShown = React.useContext(HeaderShownContext);
41
- const parentHeaderHeight = React.useContext(HeaderHeightContext);
35
+ const isParentHeaderShown = React.use(HeaderShownContext);
36
+ const parentHeaderHeight = React.use(HeaderHeightContext);
42
37
 
43
38
  const {
44
39
  focused,
@@ -61,7 +56,7 @@ export function Screen(props: Props) {
61
56
  })
62
57
  );
63
58
 
64
- const headerRef = React.useRef<View>(null);
59
+ const headerRef = React.useRef<React.ComponentRef<typeof View>>(null);
65
60
 
66
61
  const [headerHeight, setHeaderHeight] = React.useState(defaultHeaderHeight);
67
62
 
@@ -72,25 +67,43 @@ export function Screen(props: Props) {
72
67
  }, [route.name]);
73
68
 
74
69
  return (
75
- <Animated.View
76
- aria-hidden={!focused}
77
- style={[styles.container, { backgroundColor: colors.background }, style]}
70
+ <Container
71
+ inert={!focused}
72
+ style={{
73
+ ...styles.container,
74
+ backgroundColor: colors.background,
75
+ ...style,
76
+ }}
78
77
  // On Fabric we need to disable collapsing for the background to ensure
79
78
  // that we won't render unnecessary views due to the view flattening.
80
- collapsable={false}
79
+ // Container sets `collapsable` to `false` internally
80
+ // This comment is left to make sure refactors don't remove it by mistake
81
81
  >
82
82
  {headerShown ? (
83
83
  <NavigationProvider navigation={navigation} route={route}>
84
84
  <View
85
- ref={headerRef}
86
- onLayout={(e) => {
87
- const { height } = e.nativeEvent.layout;
88
-
89
- setHeaderHeight(height);
90
- }}
91
- style={[styles.header, headerTransparent ? styles.absolute : null]}
85
+ style={[
86
+ styles.header,
87
+ headerTransparent
88
+ ? [
89
+ styles.absolute,
90
+ // Specify an explicit min height for Android screen readers
91
+ { minHeight: headerHeight },
92
+ ]
93
+ : null,
94
+ ]}
92
95
  >
93
- {header}
96
+ <View
97
+ ref={headerRef}
98
+ onLayout={(e) => {
99
+ const { height } = e.nativeEvent.layout;
100
+
101
+ setHeaderHeight(height);
102
+ }}
103
+ style={{ pointerEvents: 'box-none' }}
104
+ >
105
+ {header}
106
+ </View>
94
107
  </View>
95
108
  </NavigationProvider>
96
109
  ) : null}
@@ -105,7 +118,7 @@ export function Screen(props: Props) {
105
118
  </HeaderHeightContext.Provider>
106
119
  </HeaderShownContext.Provider>
107
120
  </View>
108
- </Animated.View>
121
+ </Container>
109
122
  );
110
123
  }
111
124
 
package/src/index.tsx CHANGED
@@ -1,9 +1,3 @@
1
- import backIcon from './assets/back-icon.png';
2
- import clearIcon from './assets/clear-icon.png';
3
- import closeIcon from './assets/close-icon.png';
4
- import searchIcon from './assets/search-icon.png';
5
- import searchIconLegacy from './assets/search-icon-legacy.png';
6
-
7
1
  export { Badge } from './Badge';
8
2
  export { Button } from './Button';
9
3
  export { getDefaultSidebarWidth } from './getDefaultSidebarWidth';
@@ -20,16 +14,8 @@ export { HeaderTitle } from './Header/HeaderTitle';
20
14
  export { useHeaderHeight } from './Header/useHeaderHeight';
21
15
  export { getLabel } from './Label/getLabel';
22
16
  export { Label } from './Label/Label';
17
+ export { PlatformIcon } from './PlatformIcon';
23
18
  export { PlatformPressable } from './PlatformPressable';
24
19
  export { Text } from './Text';
25
- export { useFrameSize } from './useFrameSize';
26
-
27
- export const Assets = [
28
- backIcon,
29
- searchIcon,
30
- searchIconLegacy,
31
- closeIcon,
32
- clearIcon,
33
- ];
34
-
35
20
  export * from './types';
21
+ export { useFrameSize } from './useFrameSize';
package/src/internal.tsx CHANGED
@@ -1,6 +1,6 @@
1
+ export { ActivityView } from './ActivityView';
1
2
  export { Color } from './Color';
2
3
  export { Container, type Props as ContainerProps } from './Container';
3
- export { Lazy } from './Lazy';
4
4
  export { isLiquidGlassSupported } from './LiquidGlassView';
5
5
  export { MissingIcon } from './MissingIcon';
6
6
  export { SafeAreaProviderCompat } from './SafeAreaProviderCompat';