@react-navigation/elements 2.0.0-alpha.0 → 2.0.0-alpha.10

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 (162) hide show
  1. package/lib/commonjs/Background.js +2 -2
  2. package/lib/commonjs/Background.js.map +1 -1
  3. package/lib/commonjs/Button.js +100 -0
  4. package/lib/commonjs/Button.js.map +1 -0
  5. package/lib/commonjs/Header/Header.js +21 -17
  6. package/lib/commonjs/Header/Header.js.map +1 -1
  7. package/lib/commonjs/Header/HeaderBackButton.js +22 -40
  8. package/lib/commonjs/Header/HeaderBackButton.js.map +1 -1
  9. package/lib/commonjs/Header/HeaderBackContext.js +1 -2
  10. package/lib/commonjs/Header/HeaderBackContext.js.map +1 -1
  11. package/lib/commonjs/Header/HeaderBackground.js +2 -2
  12. package/lib/commonjs/Header/HeaderBackground.js.map +1 -1
  13. package/lib/commonjs/Header/HeaderButton.js +60 -0
  14. package/lib/commonjs/Header/HeaderButton.js.map +1 -0
  15. package/lib/commonjs/Header/HeaderHeightContext.js +1 -2
  16. package/lib/commonjs/Header/HeaderHeightContext.js.map +1 -1
  17. package/lib/commonjs/Header/HeaderShownContext.js +1 -2
  18. package/lib/commonjs/Header/HeaderShownContext.js.map +1 -1
  19. package/lib/commonjs/Header/HeaderTitle.js +2 -2
  20. package/lib/commonjs/Header/HeaderTitle.js.map +1 -1
  21. package/lib/commonjs/Header/getDefaultHeaderHeight.js +5 -3
  22. package/lib/commonjs/Header/getDefaultHeaderHeight.js.map +1 -1
  23. package/lib/commonjs/Header/getHeaderTitle.js.map +1 -1
  24. package/lib/commonjs/Header/useHeaderHeight.js +2 -2
  25. package/lib/commonjs/Header/useHeaderHeight.js.map +1 -1
  26. package/lib/commonjs/Label/Label.js +33 -0
  27. package/lib/commonjs/Label/Label.js.map +1 -0
  28. package/lib/commonjs/Label/getLabel.js +10 -0
  29. package/lib/commonjs/Label/getLabel.js.map +1 -0
  30. package/lib/commonjs/MaskedView.android.js.map +1 -1
  31. package/lib/commonjs/MaskedView.ios.js.map +1 -1
  32. package/lib/commonjs/MaskedView.js.map +1 -1
  33. package/lib/commonjs/MaskedViewNative.js +3 -2
  34. package/lib/commonjs/MaskedViewNative.js.map +1 -1
  35. package/lib/commonjs/MissingIcon.js +2 -2
  36. package/lib/commonjs/MissingIcon.js.map +1 -1
  37. package/lib/commonjs/PlatformPressable.js +27 -4
  38. package/lib/commonjs/PlatformPressable.js.map +1 -1
  39. package/lib/commonjs/ResourceSavingView.js +2 -2
  40. package/lib/commonjs/ResourceSavingView.js.map +1 -1
  41. package/lib/commonjs/SafeAreaProviderCompat.js +2 -2
  42. package/lib/commonjs/SafeAreaProviderCompat.js.map +1 -1
  43. package/lib/commonjs/Screen.js +6 -2
  44. package/lib/commonjs/Screen.js.map +1 -1
  45. package/lib/commonjs/Text.js +28 -0
  46. package/lib/commonjs/Text.js.map +1 -0
  47. package/lib/commonjs/getDefaultSidebarWidth.js +26 -0
  48. package/lib/commonjs/getDefaultSidebarWidth.js.map +1 -0
  49. package/lib/commonjs/getNamedContext.js +2 -2
  50. package/lib/commonjs/getNamedContext.js.map +1 -1
  51. package/lib/commonjs/index.js +50 -3
  52. package/lib/commonjs/index.js.map +1 -1
  53. package/lib/commonjs/types.js.map +1 -1
  54. package/lib/module/Background.js.map +1 -1
  55. package/lib/module/Button.js +91 -0
  56. package/lib/module/Button.js.map +1 -0
  57. package/lib/module/Header/Header.js +19 -15
  58. package/lib/module/Header/Header.js.map +1 -1
  59. package/lib/module/Header/HeaderBackButton.js +20 -38
  60. package/lib/module/Header/HeaderBackButton.js.map +1 -1
  61. package/lib/module/Header/HeaderBackContext.js.map +1 -1
  62. package/lib/module/Header/HeaderBackground.js.map +1 -1
  63. package/lib/module/Header/HeaderButton.js +52 -0
  64. package/lib/module/Header/HeaderButton.js.map +1 -0
  65. package/lib/module/Header/HeaderHeightContext.js.map +1 -1
  66. package/lib/module/Header/HeaderShownContext.js.map +1 -1
  67. package/lib/module/Header/HeaderTitle.js.map +1 -1
  68. package/lib/module/Header/getDefaultHeaderHeight.js +6 -4
  69. package/lib/module/Header/getDefaultHeaderHeight.js.map +1 -1
  70. package/lib/module/Header/getHeaderTitle.js.map +1 -1
  71. package/lib/module/Header/useHeaderHeight.js.map +1 -1
  72. package/lib/module/Label/Label.js +25 -0
  73. package/lib/module/Label/Label.js.map +1 -0
  74. package/lib/module/Label/getLabel.js +4 -0
  75. package/lib/module/Label/getLabel.js.map +1 -0
  76. package/lib/module/MaskedView.android.js.map +1 -1
  77. package/lib/module/MaskedView.ios.js.map +1 -1
  78. package/lib/module/MaskedView.js.map +1 -1
  79. package/lib/module/MaskedViewNative.js +1 -0
  80. package/lib/module/MaskedViewNative.js.map +1 -1
  81. package/lib/module/MissingIcon.js.map +1 -1
  82. package/lib/module/PlatformPressable.js +25 -2
  83. package/lib/module/PlatformPressable.js.map +1 -1
  84. package/lib/module/ResourceSavingView.js.map +1 -1
  85. package/lib/module/SafeAreaProviderCompat.js.map +1 -1
  86. package/lib/module/Screen.js +4 -0
  87. package/lib/module/Screen.js.map +1 -1
  88. package/lib/module/Text.js +20 -0
  89. package/lib/module/Text.js.map +1 -0
  90. package/lib/module/getDefaultSidebarWidth.js +19 -0
  91. package/lib/module/getDefaultSidebarWidth.js.map +1 -0
  92. package/lib/module/getNamedContext.js.map +1 -1
  93. package/lib/module/index.js +6 -0
  94. package/lib/module/index.js.map +1 -1
  95. package/lib/module/types.js.map +1 -1
  96. package/lib/typescript/src/Background.d.ts +2 -2
  97. package/lib/typescript/src/Background.d.ts.map +1 -1
  98. package/lib/typescript/src/Button.d.ts +12 -0
  99. package/lib/typescript/src/Button.d.ts.map +1 -0
  100. package/lib/typescript/src/Header/Header.d.ts +2 -1
  101. package/lib/typescript/src/Header/Header.d.ts.map +1 -1
  102. package/lib/typescript/src/Header/HeaderBackButton.d.ts +2 -1
  103. package/lib/typescript/src/Header/HeaderBackButton.d.ts.map +1 -1
  104. package/lib/typescript/src/Header/HeaderBackContext.d.ts +2 -1
  105. package/lib/typescript/src/Header/HeaderBackContext.d.ts.map +1 -1
  106. package/lib/typescript/src/Header/HeaderBackground.d.ts +2 -2
  107. package/lib/typescript/src/Header/HeaderBackground.d.ts.map +1 -1
  108. package/lib/typescript/src/Header/HeaderButton.d.ts +4 -0
  109. package/lib/typescript/src/Header/HeaderButton.d.ts.map +1 -0
  110. package/lib/typescript/src/Header/HeaderTitle.d.ts +3 -2
  111. package/lib/typescript/src/Header/HeaderTitle.d.ts.map +1 -1
  112. package/lib/typescript/src/Header/getDefaultHeaderHeight.d.ts +1 -1
  113. package/lib/typescript/src/Header/getDefaultHeaderHeight.d.ts.map +1 -1
  114. package/lib/typescript/src/Label/Label.d.ts +10 -0
  115. package/lib/typescript/src/Label/Label.d.ts.map +1 -0
  116. package/lib/typescript/src/Label/getLabel.d.ts +5 -0
  117. package/lib/typescript/src/Label/getLabel.d.ts.map +1 -0
  118. package/lib/typescript/src/MaskedViewNative.d.ts +1 -1
  119. package/lib/typescript/src/MaskedViewNative.d.ts.map +1 -1
  120. package/lib/typescript/src/MissingIcon.d.ts +3 -2
  121. package/lib/typescript/src/MissingIcon.d.ts.map +1 -1
  122. package/lib/typescript/src/PlatformPressable.d.ts +3 -2
  123. package/lib/typescript/src/PlatformPressable.d.ts.map +1 -1
  124. package/lib/typescript/src/ResourceSavingView.d.ts +2 -2
  125. package/lib/typescript/src/ResourceSavingView.d.ts.map +1 -1
  126. package/lib/typescript/src/SafeAreaProviderCompat.d.ts +2 -2
  127. package/lib/typescript/src/SafeAreaProviderCompat.d.ts.map +1 -1
  128. package/lib/typescript/src/Screen.d.ts +3 -3
  129. package/lib/typescript/src/Screen.d.ts.map +1 -1
  130. package/lib/typescript/src/Text.d.ts +4 -0
  131. package/lib/typescript/src/Text.d.ts.map +1 -0
  132. package/lib/typescript/src/getDefaultSidebarWidth.d.ts +5 -0
  133. package/lib/typescript/src/getDefaultSidebarWidth.d.ts.map +1 -0
  134. package/lib/typescript/src/getNamedContext.d.ts.map +1 -1
  135. package/lib/typescript/src/index.d.ts +6 -0
  136. package/lib/typescript/src/index.d.ts.map +1 -1
  137. package/lib/typescript/src/types.d.ts +26 -22
  138. package/lib/typescript/src/types.d.ts.map +1 -1
  139. package/package.json +17 -15
  140. package/src/Background.tsx +6 -1
  141. package/src/Button.tsx +99 -0
  142. package/src/Header/Header.tsx +79 -72
  143. package/src/Header/HeaderBackButton.tsx +17 -29
  144. package/src/Header/HeaderBackContext.tsx +3 -4
  145. package/src/Header/HeaderBackground.tsx +3 -3
  146. package/src/Header/HeaderButton.tsx +54 -0
  147. package/src/Header/HeaderTitle.tsx +3 -3
  148. package/src/Header/getDefaultHeaderHeight.tsx +8 -4
  149. package/src/Header/getHeaderTitle.tsx +2 -2
  150. package/src/Label/Label.tsx +32 -0
  151. package/src/Label/getLabel.tsx +10 -0
  152. package/src/MaskedViewNative.tsx +1 -0
  153. package/src/MissingIcon.tsx +1 -1
  154. package/src/PlatformPressable.tsx +34 -6
  155. package/src/ResourceSavingView.tsx +7 -1
  156. package/src/SafeAreaProviderCompat.tsx +2 -2
  157. package/src/Screen.tsx +13 -4
  158. package/src/Text.tsx +14 -0
  159. package/src/getDefaultSidebarWidth.tsx +22 -0
  160. package/src/getNamedContext.tsx +1 -0
  161. package/src/index.tsx +6 -0
  162. package/src/types.tsx +27 -23
@@ -3,15 +3,15 @@ import * as React from 'react';
3
3
  import {
4
4
  Animated,
5
5
  Image,
6
- LayoutChangeEvent,
6
+ type LayoutChangeEvent,
7
7
  Platform,
8
8
  StyleSheet,
9
9
  View,
10
10
  } from 'react-native';
11
11
 
12
12
  import { MaskedView } from '../MaskedView';
13
- import { PlatformPressable } from '../PlatformPressable';
14
13
  import type { HeaderBackButtonProps } from '../types';
14
+ import { HeaderButton } from './HeaderButton';
15
15
 
16
16
  export function HeaderBackButton({
17
17
  disabled,
@@ -31,6 +31,7 @@ export function HeaderBackButton({
31
31
  accessibilityLabel = label && label !== 'Back' ? `${label}, back` : 'Go back',
32
32
  testID,
33
33
  style,
34
+ href,
34
35
  }: HeaderBackButtonProps) {
35
36
  const { colors, fonts } = useTheme();
36
37
  const { direction } = useLocale();
@@ -79,6 +80,7 @@ export function HeaderBackButton({
79
80
  Boolean(labelVisible) && styles.iconWithLabel,
80
81
  Boolean(tintColor) && { tintColor },
81
82
  ]}
83
+ resizeMode="contain"
82
84
  source={require('../assets/back-icon.png')}
83
85
  fadeDuration={0}
84
86
  />
@@ -136,6 +138,7 @@ export function HeaderBackButton({
136
138
  <View style={styles.iconMaskContainer}>
137
139
  <Image
138
140
  source={require('../assets/back-icon-mask.png')}
141
+ resizeMode="contain"
139
142
  style={[styles.iconMask, direction === 'rtl' && styles.flip]}
140
143
  />
141
144
  <View style={styles.iconMaskFillerRect} />
@@ -147,43 +150,34 @@ export function HeaderBackButton({
147
150
  );
148
151
  };
149
152
 
150
- const handlePress = () => onPress && requestAnimationFrame(onPress);
153
+ const handlePress = () => {
154
+ if (onPress) {
155
+ requestAnimationFrame(() => onPress());
156
+ }
157
+ };
151
158
 
152
159
  return (
153
- <PlatformPressable
160
+ <HeaderButton
154
161
  disabled={disabled}
155
- accessible
156
- accessibilityRole="button"
162
+ href={href}
157
163
  accessibilityLabel={accessibilityLabel}
158
164
  testID={testID}
159
- onPress={disabled ? undefined : handlePress}
165
+ onPress={handlePress}
160
166
  pressColor={pressColor}
161
167
  pressOpacity={pressOpacity}
162
- android_ripple={androidRipple}
163
- style={[styles.container, disabled && styles.disabled, style]}
164
- hitSlop={Platform.select({
165
- ios: undefined,
166
- default: { top: 16, right: 16, bottom: 16, left: 16 },
167
- })}
168
+ style={[styles.container, style]}
168
169
  >
169
170
  <React.Fragment>
170
171
  {renderBackImage()}
171
172
  {renderLabel()}
172
173
  </React.Fragment>
173
- </PlatformPressable>
174
+ </HeaderButton>
174
175
  );
175
176
  }
176
177
 
177
- const androidRipple = {
178
- borderless: true,
179
- foreground: Platform.OS === 'android' && Platform.Version >= 23,
180
- radius: 20,
181
- };
182
-
183
178
  const styles = StyleSheet.create({
184
179
  container: {
185
- alignItems: 'center',
186
- flexDirection: 'row',
180
+ paddingHorizontal: 0,
187
181
  minWidth: StyleSheet.hairlineWidth, // Avoid collapsing when title is long
188
182
  ...Platform.select({
189
183
  ios: null,
@@ -193,9 +187,6 @@ const styles = StyleSheet.create({
193
187
  },
194
188
  }),
195
189
  },
196
- disabled: {
197
- opacity: 0.5,
198
- },
199
190
  label: {
200
191
  fontSize: 17,
201
192
  // Title and back label are a bit different width due to title being bold
@@ -215,13 +206,11 @@ const styles = StyleSheet.create({
215
206
  marginLeft: 8,
216
207
  marginRight: 22,
217
208
  marginVertical: 12,
218
- resizeMode: 'contain',
219
209
  },
220
210
  default: {
221
211
  height: 24,
222
212
  width: 24,
223
213
  margin: 3,
224
- resizeMode: 'contain',
225
214
  },
226
215
  }),
227
216
  iconWithLabel:
@@ -245,9 +234,8 @@ const styles = StyleSheet.create({
245
234
  marginLeft: -14.5,
246
235
  marginVertical: 12,
247
236
  alignSelf: 'center',
248
- resizeMode: 'contain',
249
237
  },
250
238
  flip: {
251
- transform: [{ scaleX: -1 }],
239
+ transform: 'scaleX(-1)',
252
240
  },
253
241
  });
@@ -1,6 +1,5 @@
1
1
  import { getNamedContext } from '../getNamedContext';
2
2
 
3
- export const HeaderBackContext = getNamedContext<{ title: string } | undefined>(
4
- 'HeaderBackContext',
5
- undefined
6
- );
3
+ export const HeaderBackContext = getNamedContext<
4
+ { title: string | undefined; href: string | undefined } | undefined
5
+ >('HeaderBackContext', undefined);
@@ -3,10 +3,10 @@ import * as React from 'react';
3
3
  import {
4
4
  Animated,
5
5
  Platform,
6
- StyleProp,
6
+ type StyleProp,
7
7
  StyleSheet,
8
- ViewProps,
9
- ViewStyle,
8
+ type ViewProps,
9
+ type ViewStyle,
10
10
  } from 'react-native';
11
11
 
12
12
  type Props = Omit<ViewProps, 'style'> & {
@@ -0,0 +1,54 @@
1
+ import * as React from 'react';
2
+ import { Platform, StyleSheet } from 'react-native';
3
+
4
+ import { PlatformPressable } from '../PlatformPressable';
5
+ import type { HeaderButtonProps } from '../types';
6
+
7
+ export function HeaderButton({
8
+ disabled,
9
+ onPress,
10
+ pressColor,
11
+ pressOpacity,
12
+ accessibilityLabel,
13
+ testID,
14
+ style,
15
+ href,
16
+ children,
17
+ }: HeaderButtonProps) {
18
+ return (
19
+ <PlatformPressable
20
+ disabled={disabled}
21
+ href={href}
22
+ accessibilityLabel={accessibilityLabel}
23
+ testID={testID}
24
+ onPress={onPress}
25
+ pressColor={pressColor}
26
+ pressOpacity={pressOpacity}
27
+ android_ripple={androidRipple}
28
+ style={[styles.container, disabled && styles.disabled, style]}
29
+ hitSlop={Platform.select({
30
+ ios: undefined,
31
+ default: { top: 16, right: 16, bottom: 16, left: 16 },
32
+ })}
33
+ >
34
+ {children}
35
+ </PlatformPressable>
36
+ );
37
+ }
38
+
39
+ const androidRipple = {
40
+ borderless: true,
41
+ foreground: Platform.OS === 'android' && Platform.Version >= 23,
42
+ radius: 20,
43
+ };
44
+
45
+ const styles = StyleSheet.create({
46
+ container: {
47
+ flexDirection: 'row',
48
+ alignItems: 'center',
49
+ paddingHorizontal: 8,
50
+ },
51
+ disabled: {
52
+ opacity: 0.5,
53
+ },
54
+ });
@@ -3,10 +3,10 @@ import * as React from 'react';
3
3
  import {
4
4
  Animated,
5
5
  Platform,
6
- StyleProp,
6
+ type StyleProp,
7
7
  StyleSheet,
8
- TextProps,
9
- TextStyle,
8
+ type TextProps,
9
+ type TextStyle,
10
10
  } from 'react-native';
11
11
 
12
12
  type Props = Omit<TextProps, 'style'> & {
@@ -1,14 +1,20 @@
1
- import { Platform } from 'react-native';
1
+ import { PixelRatio, Platform } from 'react-native';
2
2
 
3
3
  import type { Layout } from '../types';
4
4
 
5
5
  export function getDefaultHeaderHeight(
6
6
  layout: Layout,
7
7
  modalPresentation: boolean,
8
- statusBarHeight: number
8
+ topInset: number
9
9
  ): number {
10
10
  let headerHeight;
11
11
 
12
+ // On models with Dynamic Island the status bar height is smaller than the safe area top inset.
13
+ const hasDynamicIsland = Platform.OS === 'ios' && topInset > 50;
14
+ const statusBarHeight = hasDynamicIsland
15
+ ? topInset - (5 + 1 / PixelRatio.get())
16
+ : topInset;
17
+
12
18
  const isLandscape = layout.width > layout.height;
13
19
 
14
20
  if (Platform.OS === 'ios') {
@@ -29,8 +35,6 @@ export function getDefaultHeaderHeight(
29
35
  }
30
36
  }
31
37
  }
32
- } else if (Platform.OS === 'android') {
33
- headerHeight = 56;
34
38
  } else {
35
39
  headerHeight = 64;
36
40
  }
@@ -7,6 +7,6 @@ export function getHeaderTitle(
7
7
  return typeof options.headerTitle === 'string'
8
8
  ? options.headerTitle
9
9
  : options.title !== undefined
10
- ? options.title
11
- : fallback;
10
+ ? options.title
11
+ : fallback;
12
12
  }
@@ -0,0 +1,32 @@
1
+ import * as React from 'react';
2
+ import {
3
+ type StyleProp,
4
+ StyleSheet,
5
+ type TextProps,
6
+ type TextStyle,
7
+ } from 'react-native';
8
+
9
+ import { Text } from '../Text';
10
+
11
+ type Props = Omit<TextProps, 'style'> & {
12
+ tintColor?: string;
13
+ children?: string;
14
+ style?: StyleProp<TextStyle>;
15
+ };
16
+
17
+ export function Label({ tintColor, style, ...rest }: Props) {
18
+ return (
19
+ <Text
20
+ numberOfLines={1}
21
+ {...rest}
22
+ style={[styles.label, tintColor != null && { color: tintColor }, style]}
23
+ />
24
+ );
25
+ }
26
+
27
+ const styles = StyleSheet.create({
28
+ label: {
29
+ textAlign: 'center',
30
+ backgroundColor: 'transparent',
31
+ },
32
+ });
@@ -0,0 +1,10 @@
1
+ export function getLabel(
2
+ options: { label?: string; title?: string },
3
+ fallback: string
4
+ ): string {
5
+ return options.label !== undefined
6
+ ? options.label
7
+ : options.title !== undefined
8
+ ? options.title
9
+ : fallback;
10
+ }
@@ -16,6 +16,7 @@ let RNCMaskedView: MaskedViewType | undefined;
16
16
  try {
17
17
  // Add try/catch to support usage even if it's not installed, since it's optional.
18
18
  // Newer versions of Metro will handle it properly.
19
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
19
20
  RNCMaskedView = require('@react-native-masked-view/masked-view').default;
20
21
  } catch (e) {
21
22
  // Ignore
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { StyleProp, StyleSheet, Text, TextStyle } from 'react-native';
2
+ import { type StyleProp, StyleSheet, Text, type TextStyle } from 'react-native';
3
3
 
4
4
  type Props = {
5
5
  color?: string;
@@ -3,18 +3,19 @@ import * as React from 'react';
3
3
  import {
4
4
  Animated,
5
5
  Easing,
6
- GestureResponderEvent,
6
+ type GestureResponderEvent,
7
7
  Platform,
8
8
  Pressable,
9
- PressableProps,
10
- StyleProp,
11
- ViewStyle,
9
+ type PressableProps,
10
+ type StyleProp,
11
+ type ViewStyle,
12
12
  } from 'react-native';
13
13
 
14
14
  export type Props = Omit<PressableProps, 'style'> & {
15
15
  pressColor?: string;
16
16
  pressOpacity?: number;
17
17
  style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
18
+ href?: string;
18
19
  children: React.ReactNode;
19
20
  };
20
21
 
@@ -28,6 +29,8 @@ const ANDROID_SUPPORTS_RIPPLE =
28
29
  * PlatformPressable provides an abstraction on top of Pressable to handle platform differences.
29
30
  */
30
31
  export function PlatformPressable({
32
+ disabled,
33
+ onPress,
31
34
  onPressIn,
32
35
  onPressOut,
33
36
  android_ripple,
@@ -52,6 +55,26 @@ export function PlatformPressable({
52
55
  }).start();
53
56
  };
54
57
 
58
+ const handlePress = (e: GestureResponderEvent) => {
59
+ // @ts-expect-error: these properties exist on web, but not in React Native
60
+ const hasModifierKey = e.metaKey || e.altKey || e.ctrlKey || e.shiftKey; // ignore clicks with modifier keys
61
+ // @ts-expect-error: these properties exist on web, but not in React Native
62
+ const isLeftClick = e.button == null || e.button === 0; // only handle left clicks
63
+ const isSelfTarget = [undefined, null, '', 'self'].includes(
64
+ // @ts-expect-error: these properties exist on web, but not in React Native
65
+ e.currentTarget?.target
66
+ ); // let browser handle "target=_blank" etc.
67
+
68
+ if (Platform.OS === 'web' && rest.href != null) {
69
+ if (!hasModifierKey && isLeftClick && isSelfTarget) {
70
+ e.preventDefault();
71
+ onPress?.(e);
72
+ }
73
+ } else {
74
+ onPress?.(e);
75
+ }
76
+ };
77
+
55
78
  const handlePressIn = (e: GestureResponderEvent) => {
56
79
  animateTo(pressOpacity, 0);
57
80
  onPressIn?.(e);
@@ -64,6 +87,11 @@ export function PlatformPressable({
64
87
 
65
88
  return (
66
89
  <AnimatedPressable
90
+ accessible
91
+ accessibilityRole={
92
+ Platform.OS === 'web' && rest.href != null ? 'link' : 'button'
93
+ }
94
+ onPress={disabled ? undefined : handlePress}
67
95
  onPressIn={handlePressIn}
68
96
  onPressOut={handlePressOut}
69
97
  android_ripple={
@@ -73,8 +101,8 @@ export function PlatformPressable({
73
101
  pressColor !== undefined
74
102
  ? pressColor
75
103
  : dark
76
- ? 'rgba(255, 255, 255, .32)'
77
- : 'rgba(0, 0, 0, .32)',
104
+ ? 'rgba(255, 255, 255, .32)'
105
+ : 'rgba(0, 0, 0, .32)',
78
106
  ...android_ripple,
79
107
  }
80
108
  : undefined
@@ -1,5 +1,11 @@
1
1
  import * as React from 'react';
2
- import { Platform, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
2
+ import {
3
+ Platform,
4
+ type StyleProp,
5
+ StyleSheet,
6
+ View,
7
+ type ViewStyle,
8
+ } from 'react-native';
3
9
 
4
10
  type Props = {
5
11
  visible: boolean;
@@ -2,10 +2,10 @@ import * as React from 'react';
2
2
  import {
3
3
  Dimensions,
4
4
  Platform,
5
- StyleProp,
5
+ type StyleProp,
6
6
  StyleSheet,
7
7
  View,
8
- ViewStyle,
8
+ type ViewStyle,
9
9
  } from 'react-native';
10
10
  import {
11
11
  initialWindowMetrics,
package/src/Screen.tsx CHANGED
@@ -1,12 +1,18 @@
1
1
  import {
2
2
  NavigationContext,
3
- NavigationProp,
3
+ type NavigationProp,
4
4
  NavigationRouteContext,
5
- ParamListBase,
6
- RouteProp,
5
+ type ParamListBase,
6
+ type RouteProp,
7
7
  } from '@react-navigation/native';
8
8
  import * as React from 'react';
9
- import { Animated, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
9
+ import {
10
+ Animated,
11
+ type StyleProp,
12
+ StyleSheet,
13
+ View,
14
+ type ViewStyle,
15
+ } from 'react-native';
10
16
  import {
11
17
  useSafeAreaFrame,
12
18
  useSafeAreaInsets,
@@ -59,6 +65,9 @@ export function Screen(props: Props) {
59
65
  accessibilityElementsHidden={!focused}
60
66
  importantForAccessibility={focused ? 'auto' : 'no-hide-descendants'}
61
67
  style={[styles.container, style]}
68
+ // On Fabric we need to disable collapsing for the background to ensure
69
+ // that we won't render unnecessary views due to the view flattening.
70
+ collapsable={false}
62
71
  >
63
72
  <View style={styles.content}>
64
73
  <HeaderShownContext.Provider
package/src/Text.tsx ADDED
@@ -0,0 +1,14 @@
1
+ import { useTheme } from '@react-navigation/native';
2
+ import * as React from 'react';
3
+ import { Text as NativeText, type TextProps } from 'react-native';
4
+
5
+ export function Text({ style, ...rest }: TextProps) {
6
+ const { colors, fonts } = useTheme();
7
+
8
+ return (
9
+ <NativeText
10
+ {...rest}
11
+ style={[{ color: colors.text }, fonts.regular, style]}
12
+ />
13
+ );
14
+ }
@@ -0,0 +1,22 @@
1
+ import { Platform } from 'react-native';
2
+
3
+ export const getDefaultSidebarWidth = ({
4
+ height,
5
+ width,
6
+ }: {
7
+ height: number;
8
+ width: number;
9
+ }) => {
10
+ /*
11
+ * Default sidebar width is screen width - header height
12
+ * with a max width of 280 on mobile and 320 on tablet
13
+ * https://material.io/components/navigation-drawer
14
+ */
15
+ const smallerAxisSize = Math.min(height, width);
16
+ const isLandscape = width > height;
17
+ const isTablet = smallerAxisSize >= 600;
18
+ const appBarHeight = Platform.OS === 'ios' ? (isLandscape ? 32 : 44) : 56;
19
+ const maxWidth = isTablet ? 320 : 280;
20
+
21
+ return Math.min(smallerAxisSize - appBarHeight, maxWidth);
22
+ };
@@ -3,6 +3,7 @@ import * as React from 'react';
3
3
  const contexts = '__react_navigation__elements_contexts';
4
4
 
5
5
  declare global {
6
+ // eslint-disable-next-line no-var
6
7
  var __react_navigation__elements_contexts: Map<string, React.Context<any>>;
7
8
  }
8
9
 
package/src/index.tsx CHANGED
@@ -1,19 +1,25 @@
1
1
  export { Background } from './Background';
2
+ export { Button } from './Button';
3
+ export { getDefaultSidebarWidth } from './getDefaultSidebarWidth';
2
4
  export { getDefaultHeaderHeight } from './Header/getDefaultHeaderHeight';
3
5
  export { getHeaderTitle } from './Header/getHeaderTitle';
4
6
  export { Header } from './Header/Header';
5
7
  export { HeaderBackButton } from './Header/HeaderBackButton';
6
8
  export { HeaderBackContext } from './Header/HeaderBackContext';
7
9
  export { HeaderBackground } from './Header/HeaderBackground';
10
+ export { HeaderButton } from './Header/HeaderButton';
8
11
  export { HeaderHeightContext } from './Header/HeaderHeightContext';
9
12
  export { HeaderShownContext } from './Header/HeaderShownContext';
10
13
  export { HeaderTitle } from './Header/HeaderTitle';
11
14
  export { useHeaderHeight } from './Header/useHeaderHeight';
15
+ export { getLabel } from './Label/getLabel';
16
+ export { Label } from './Label/Label';
12
17
  export { MissingIcon } from './MissingIcon';
13
18
  export { PlatformPressable } from './PlatformPressable';
14
19
  export { ResourceSavingView } from './ResourceSavingView';
15
20
  export { SafeAreaProviderCompat } from './SafeAreaProviderCompat';
16
21
  export { Screen } from './Screen';
22
+ export { Text } from './Text';
17
23
 
18
24
  export const Assets = [
19
25
  // eslint-disable-next-line import/no-commonjs
package/src/types.tsx CHANGED
@@ -148,6 +148,26 @@ export type HeaderTitleProps = {
148
148
  };
149
149
 
150
150
  export type HeaderButtonProps = {
151
+ /**
152
+ * Callback to call when the button is pressed.
153
+ */
154
+ onPress?: () => void;
155
+ /**
156
+ * The `href` to use for the anchor tag on web
157
+ */
158
+ href?: string;
159
+ /**
160
+ * Whether the button is disabled.
161
+ */
162
+ disabled?: boolean;
163
+ /**
164
+ * Accessibility label for the button for screen readers.
165
+ */
166
+ accessibilityLabel?: string;
167
+ /**
168
+ * ID to locate this button in tests.
169
+ */
170
+ testID?: string;
151
171
  /**
152
172
  * Tint color for the header button.
153
173
  */
@@ -161,20 +181,16 @@ export type HeaderButtonProps = {
161
181
  */
162
182
  pressOpacity?: number;
163
183
  /**
164
- * Whether it's possible to navigate back in stack.
165
- */
166
- canGoBack?: boolean;
167
- };
168
-
169
- export type HeaderBackButtonProps = HeaderButtonProps & {
170
- /**
171
- * Whether the button is disabled.
184
+ * Style object for the button.
172
185
  */
173
- disabled?: boolean;
186
+ style?: StyleProp<ViewStyle>;
174
187
  /**
175
- * Callback to call when the button is pressed.
188
+ * Content to render for the button. Usually the icon.
176
189
  */
177
- onPress?: () => void;
190
+ children: React.ReactNode;
191
+ };
192
+
193
+ export type HeaderBackButtonProps = Omit<HeaderButtonProps, 'children'> & {
178
194
  /**
179
195
  * Function which returns a React Element to display custom image in header's back button.
180
196
  */
@@ -213,16 +229,4 @@ export type HeaderBackButtonProps = HeaderButtonProps & {
213
229
  * Layout of the title element in the header.
214
230
  */
215
231
  titleLayout?: Layout;
216
- /**
217
- * Accessibility label for the button for screen readers.
218
- */
219
- accessibilityLabel?: string;
220
- /**
221
- * ID to locate this button in tests.
222
- */
223
- testID?: string;
224
- /**
225
- * Style object for the button.
226
- */
227
- style?: StyleProp<ViewStyle>;
228
232
  };