@react-navigation/elements 3.0.0-alpha.1 → 3.0.0-alpha.11
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/Badge.js +1 -1
- package/lib/module/Badge.js.map +1 -1
- package/lib/module/Button.js +1 -1
- package/lib/module/Button.js.map +1 -1
- package/lib/module/Color.js +95 -0
- package/lib/module/Color.js.map +1 -1
- package/lib/module/Container.js +8 -1
- package/lib/module/Container.js.map +1 -1
- package/lib/module/Header/Header.js +15 -2
- package/lib/module/Header/Header.js.map +1 -1
- package/lib/module/Header/HeaderBackButton.js +27 -13
- package/lib/module/Header/HeaderBackButton.js.map +1 -1
- package/lib/module/Header/HeaderIcon.js +29 -10
- package/lib/module/Header/HeaderIcon.js.map +1 -1
- package/lib/module/Header/HeaderSearchBar.js +28 -21
- package/lib/module/Header/HeaderSearchBar.js.map +1 -1
- package/lib/module/PlatformColor.js +1 -0
- package/lib/module/PlatformColor.js.map +1 -1
- package/lib/module/PlatformColor.native.js +1 -1
- package/lib/module/PlatformColor.native.js.map +1 -1
- package/lib/module/Screen.js +11 -7
- package/lib/module/Screen.js.map +1 -1
- package/lib/module/index.js +1 -7
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/Color.d.ts +4 -3
- package/lib/typescript/src/Color.d.ts.map +1 -1
- package/lib/typescript/src/Container.d.ts +3 -1
- package/lib/typescript/src/Container.d.ts.map +1 -1
- package/lib/typescript/src/Header/Header.d.ts.map +1 -1
- package/lib/typescript/src/Header/HeaderBackButton.d.ts +1 -1
- package/lib/typescript/src/Header/HeaderBackButton.d.ts.map +1 -1
- package/lib/typescript/src/Header/HeaderIcon.d.ts +8 -4
- package/lib/typescript/src/Header/HeaderIcon.d.ts.map +1 -1
- package/lib/typescript/src/Header/HeaderSearchBar.d.ts.map +1 -1
- package/lib/typescript/src/PlatformColor.d.ts +1 -0
- package/lib/typescript/src/PlatformColor.d.ts.map +1 -1
- package/lib/typescript/src/PlatformColor.native.d.ts +1 -1
- package/lib/typescript/src/PlatformColor.native.d.ts.map +1 -1
- package/lib/typescript/src/Screen.d.ts +2 -2
- package/lib/typescript/src/Screen.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +26 -5
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/Badge.tsx +1 -1
- package/src/Button.tsx +1 -3
- package/src/Color.tsx +133 -3
- package/src/Container.tsx +13 -2
- package/src/Header/Header.tsx +17 -1
- package/src/Header/HeaderBackButton.tsx +28 -14
- package/src/Header/HeaderIcon.tsx +49 -9
- package/src/Header/HeaderSearchBar.tsx +27 -18
- package/src/PlatformColor.native.tsx +1 -1
- package/src/PlatformColor.tsx +4 -0
- package/src/Screen.tsx +13 -13
- package/src/index.tsx +1 -16
- package/src/types.tsx +33 -2
- package/lib/module/assets/back-icon.ios.svg +0 -4
- package/lib/module/assets/back-icon@1x.android.png +0 -0
- package/lib/module/assets/back-icon@1x.ios.png +0 -0
- package/lib/module/assets/back-icon@2x.android.png +0 -0
- package/lib/module/assets/back-icon@2x.ios.png +0 -0
- package/lib/module/assets/back-icon@3x.android.png +0 -0
- package/lib/module/assets/back-icon@3x.ios.png +0 -0
- package/lib/module/assets/back-icon@4x.android.png +0 -0
- package/lib/module/assets/back-icon@4x.ios.png +0 -0
- package/lib/module/assets/clear-icon@1x.png +0 -0
- package/lib/module/assets/clear-icon@2x.png +0 -0
- package/lib/module/assets/clear-icon@3x.png +0 -0
- package/lib/module/assets/clear-icon@4x.png +0 -0
- package/lib/module/assets/close-icon@1x.png +0 -0
- package/lib/module/assets/close-icon@2x.png +0 -0
- package/lib/module/assets/close-icon@3x.png +0 -0
- package/lib/module/assets/close-icon@4x.png +0 -0
- package/lib/module/assets/search-icon-legacy@1x.ios.png +0 -0
- package/lib/module/assets/search-icon-legacy@2x.ios.png +0 -0
- package/lib/module/assets/search-icon-legacy@3x.ios.png +0 -0
- package/lib/module/assets/search-icon-legacy@4x.ios.png +0 -0
- package/lib/module/assets/search-icon.ios.svg +0 -4
- package/lib/module/assets/search-icon@1x.android.png +0 -0
- package/lib/module/assets/search-icon@1x.ios.png +0 -0
- package/lib/module/assets/search-icon@2x.android.png +0 -0
- package/lib/module/assets/search-icon@2x.ios.png +0 -0
- package/lib/module/assets/search-icon@3x.android.png +0 -0
- package/lib/module/assets/search-icon@3x.ios.png +0 -0
- package/lib/module/assets/search-icon@4x.android.png +0 -0
- package/lib/module/assets/search-icon@4x.ios.png +0 -0
- package/src/assets/back-icon.ios.svg +0 -4
- package/src/assets/back-icon@1x.android.png +0 -0
- package/src/assets/back-icon@1x.ios.png +0 -0
- package/src/assets/back-icon@2x.android.png +0 -0
- package/src/assets/back-icon@2x.ios.png +0 -0
- package/src/assets/back-icon@3x.android.png +0 -0
- package/src/assets/back-icon@3x.ios.png +0 -0
- package/src/assets/back-icon@4x.android.png +0 -0
- package/src/assets/back-icon@4x.ios.png +0 -0
- package/src/assets/clear-icon@1x.png +0 -0
- package/src/assets/clear-icon@2x.png +0 -0
- package/src/assets/clear-icon@3x.png +0 -0
- package/src/assets/clear-icon@4x.png +0 -0
- package/src/assets/close-icon@1x.png +0 -0
- package/src/assets/close-icon@2x.png +0 -0
- package/src/assets/close-icon@3x.png +0 -0
- package/src/assets/close-icon@4x.png +0 -0
- package/src/assets/search-icon-legacy@1x.ios.png +0 -0
- package/src/assets/search-icon-legacy@2x.ios.png +0 -0
- package/src/assets/search-icon-legacy@3x.ios.png +0 -0
- package/src/assets/search-icon-legacy@4x.ios.png +0 -0
- package/src/assets/search-icon.ios.svg +0 -4
- package/src/assets/search-icon@1x.android.png +0 -0
- package/src/assets/search-icon@1x.ios.png +0 -0
- package/src/assets/search-icon@2x.android.png +0 -0
- package/src/assets/search-icon@2x.ios.png +0 -0
- package/src/assets/search-icon@3x.android.png +0 -0
- package/src/assets/search-icon@3x.ios.png +0 -0
- package/src/assets/search-icon@4x.android.png +0 -0
- package/src/assets/search-icon@4x.ios.png +0 -0
package/src/Color.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// eslint-disable-next-line no-restricted-imports
|
|
2
2
|
import OriginalColor from 'color';
|
|
3
|
-
import type
|
|
3
|
+
import { type ColorValue, Platform } from 'react-native';
|
|
4
|
+
|
|
5
|
+
import { DynamicColorIOS, PlatformColor } from './PlatformColor';
|
|
4
6
|
|
|
5
7
|
type ColorType = {
|
|
6
|
-
isLight(): boolean;
|
|
7
|
-
isDark(): boolean;
|
|
8
8
|
alpha(amount: number): ColorType;
|
|
9
9
|
alpha(): number;
|
|
10
10
|
fade(amount: number): ColorType;
|
|
@@ -19,3 +19,133 @@ export function Color(value: ColorValue): ColorType | undefined {
|
|
|
19
19
|
|
|
20
20
|
return undefined;
|
|
21
21
|
}
|
|
22
|
+
|
|
23
|
+
Color.foreground = (color: ColorValue): ColorValue => {
|
|
24
|
+
const value = color as unknown;
|
|
25
|
+
|
|
26
|
+
if (typeof value === 'object' && value != null) {
|
|
27
|
+
// Special case for Android platform colors
|
|
28
|
+
// Available colors: https://developer.android.com/reference/android/R.color
|
|
29
|
+
if (
|
|
30
|
+
Platform.OS === 'android' &&
|
|
31
|
+
PlatformColor &&
|
|
32
|
+
'resource_paths' in value &&
|
|
33
|
+
Array.isArray(value.resource_paths) &&
|
|
34
|
+
typeof value.resource_paths[0] === 'string'
|
|
35
|
+
) {
|
|
36
|
+
const name = value.resource_paths[0].replace('@android:color/', '');
|
|
37
|
+
|
|
38
|
+
if (name in ANDROID_COLOR_MAP) {
|
|
39
|
+
return PlatformColor(`@android:color/${ANDROID_COLOR_MAP[name]}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Special case for iOS platform colors
|
|
44
|
+
if (
|
|
45
|
+
Platform.OS === 'ios' &&
|
|
46
|
+
PlatformColor &&
|
|
47
|
+
'semantic' in value &&
|
|
48
|
+
Array.isArray(value.semantic) &&
|
|
49
|
+
typeof value.semantic[0] === 'string'
|
|
50
|
+
) {
|
|
51
|
+
const name = value.semantic[0];
|
|
52
|
+
|
|
53
|
+
if (name in IOS_COLOR_MAP) {
|
|
54
|
+
const foreground = IOS_COLOR_MAP[name];
|
|
55
|
+
return foreground === 'white' || foreground === 'black'
|
|
56
|
+
? foreground
|
|
57
|
+
: PlatformColor(foreground);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Special case for iOS dynamic colors
|
|
62
|
+
if (
|
|
63
|
+
Platform.OS === 'ios' &&
|
|
64
|
+
DynamicColorIOS &&
|
|
65
|
+
'dynamic' in value &&
|
|
66
|
+
typeof value.dynamic === 'object' &&
|
|
67
|
+
value.dynamic != null &&
|
|
68
|
+
'light' in value.dynamic &&
|
|
69
|
+
typeof value.dynamic.light === 'string' &&
|
|
70
|
+
'dark' in value.dynamic &&
|
|
71
|
+
typeof value.dynamic.dark === 'string'
|
|
72
|
+
) {
|
|
73
|
+
const lightForeground = Color.foreground(value.dynamic.light);
|
|
74
|
+
const darkForeground = Color.foreground(value.dynamic.dark);
|
|
75
|
+
|
|
76
|
+
if (lightForeground && darkForeground) {
|
|
77
|
+
return DynamicColorIOS({
|
|
78
|
+
light: lightForeground,
|
|
79
|
+
dark: darkForeground,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
} else if (typeof color === 'string' && !color.startsWith('var(')) {
|
|
84
|
+
const processed = OriginalColor(color);
|
|
85
|
+
|
|
86
|
+
if (processed.isLight()) {
|
|
87
|
+
return processed.darken(0.71).string();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return '#fff';
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const ANDROID_COLOR_MAP: Record<string, string> = {
|
|
95
|
+
system_background_dark: 'system_on_background_dark',
|
|
96
|
+
system_background_light: 'system_on_background_light',
|
|
97
|
+
system_error_container_dark: 'system_on_error_container_dark',
|
|
98
|
+
system_error_container_light: 'system_on_error_container_light',
|
|
99
|
+
system_error_dark: 'system_on_error_dark',
|
|
100
|
+
system_error_light: 'system_on_error_light',
|
|
101
|
+
system_primary_container_dark: 'system_on_primary_container_dark',
|
|
102
|
+
system_primary_container_light: 'system_on_primary_container_light',
|
|
103
|
+
system_primary_dark: 'system_on_primary_dark',
|
|
104
|
+
system_primary_fixed: 'system_on_primary_fixed',
|
|
105
|
+
system_primary_light: 'system_on_primary_light',
|
|
106
|
+
system_secondary_container_dark: 'system_on_secondary_container_dark',
|
|
107
|
+
system_secondary_container_light: 'system_on_secondary_container_light',
|
|
108
|
+
system_secondary_dark: 'system_on_secondary_dark',
|
|
109
|
+
system_secondary_fixed: 'system_on_secondary_fixed',
|
|
110
|
+
system_secondary_light: 'system_on_secondary_light',
|
|
111
|
+
system_surface_dark: 'system_on_surface_dark',
|
|
112
|
+
system_surface_disabled: 'system_on_surface_disabled',
|
|
113
|
+
system_surface_light: 'system_on_surface_light',
|
|
114
|
+
system_surface_variant_dark: 'system_on_surface_variant_dark',
|
|
115
|
+
system_surface_variant_light: 'system_on_surface_variant_light',
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const IOS_COLOR_MAP: Record<string, string> = {
|
|
119
|
+
systemBackground: 'label',
|
|
120
|
+
secondarySystemBackground: 'label',
|
|
121
|
+
tertiarySystemBackground: 'label',
|
|
122
|
+
systemGroupedBackground: 'label',
|
|
123
|
+
secondarySystemGroupedBackground: 'label',
|
|
124
|
+
tertiarySystemGroupedBackground: 'label',
|
|
125
|
+
|
|
126
|
+
systemFill: 'label',
|
|
127
|
+
secondarySystemFill: 'label',
|
|
128
|
+
tertiarySystemFill: 'label',
|
|
129
|
+
quaternarySystemFill: 'label',
|
|
130
|
+
|
|
131
|
+
systemRed: 'white',
|
|
132
|
+
systemGreen: 'white',
|
|
133
|
+
systemBlue: 'white',
|
|
134
|
+
systemIndigo: 'white',
|
|
135
|
+
systemPurple: 'white',
|
|
136
|
+
systemBrown: 'white',
|
|
137
|
+
|
|
138
|
+
systemOrange: 'black',
|
|
139
|
+
systemYellow: 'black',
|
|
140
|
+
systemMint: 'black',
|
|
141
|
+
systemTeal: 'black',
|
|
142
|
+
systemCyan: 'black',
|
|
143
|
+
systemPink: 'black',
|
|
144
|
+
|
|
145
|
+
systemGray: 'label',
|
|
146
|
+
systemGray2: 'label',
|
|
147
|
+
systemGray3: 'label',
|
|
148
|
+
systemGray4: 'label',
|
|
149
|
+
systemGray5: 'label',
|
|
150
|
+
systemGray6: 'label',
|
|
151
|
+
};
|
package/src/Container.tsx
CHANGED
|
@@ -2,17 +2,28 @@ import { Platform, View, type ViewStyle } from 'react-native';
|
|
|
2
2
|
|
|
3
3
|
export type Props = {
|
|
4
4
|
inert?: boolean;
|
|
5
|
-
style?:
|
|
5
|
+
style?: ViewStyle &
|
|
6
|
+
Omit<React.CSSProperties, 'backgroundColor'> & {
|
|
7
|
+
backgroundColor?: ViewStyle['backgroundColor'];
|
|
8
|
+
};
|
|
6
9
|
children: React.ReactNode;
|
|
7
10
|
};
|
|
8
11
|
|
|
9
12
|
export function Container({ inert, children, style }: Props) {
|
|
10
13
|
if (Platform.OS === 'web') {
|
|
14
|
+
const { backgroundColor, ...rest } = style ?? {};
|
|
15
|
+
|
|
11
16
|
return (
|
|
12
17
|
<div
|
|
13
18
|
inert={inert}
|
|
14
19
|
aria-hidden={inert}
|
|
15
|
-
style={{
|
|
20
|
+
style={{
|
|
21
|
+
...DEFAULT_STYLE,
|
|
22
|
+
...rest,
|
|
23
|
+
backgroundColor:
|
|
24
|
+
// In practice we only get string on web instead of OpaqueValue
|
|
25
|
+
typeof backgroundColor === 'string' ? backgroundColor : undefined,
|
|
26
|
+
}}
|
|
16
27
|
>
|
|
17
28
|
{children}
|
|
18
29
|
</div>
|
package/src/Header/Header.tsx
CHANGED
|
@@ -458,7 +458,23 @@ export function Header(props: Props) {
|
|
|
458
458
|
headerSearchBarOptions?.onOpen?.();
|
|
459
459
|
}}
|
|
460
460
|
>
|
|
461
|
-
<HeaderIcon
|
|
461
|
+
<HeaderIcon
|
|
462
|
+
icon={Platform.select({
|
|
463
|
+
android: {
|
|
464
|
+
type: 'materialSymbol',
|
|
465
|
+
name: 'search',
|
|
466
|
+
},
|
|
467
|
+
ios: {
|
|
468
|
+
type: 'sfSymbol',
|
|
469
|
+
name: 'magnifyingglass',
|
|
470
|
+
},
|
|
471
|
+
default: {
|
|
472
|
+
type: 'image',
|
|
473
|
+
source: searchIcon,
|
|
474
|
+
},
|
|
475
|
+
})}
|
|
476
|
+
color={iconTintColor}
|
|
477
|
+
/>
|
|
462
478
|
</HeaderButton>
|
|
463
479
|
) : null}
|
|
464
480
|
</HeaderButtonBackground>
|
|
@@ -12,11 +12,12 @@ import {
|
|
|
12
12
|
View,
|
|
13
13
|
} from 'react-native';
|
|
14
14
|
|
|
15
|
-
import
|
|
15
|
+
import backIconImage from '../assets/back-icon.png';
|
|
16
16
|
import { isLiquidGlassSupported } from '../LiquidGlassView';
|
|
17
17
|
import type {
|
|
18
18
|
HeaderBackButtonDisplayMode,
|
|
19
19
|
HeaderBackButtonProps,
|
|
20
|
+
HeaderIcon as HeaderIconType,
|
|
20
21
|
} from '../types';
|
|
21
22
|
import { BUTTON_SIZE, HeaderButton } from './HeaderButton';
|
|
22
23
|
import { HeaderIcon } from './HeaderIcon';
|
|
@@ -24,7 +25,7 @@ import { HeaderIcon } from './HeaderIcon';
|
|
|
24
25
|
export function HeaderBackButton({
|
|
25
26
|
disabled,
|
|
26
27
|
allowFontScaling,
|
|
27
|
-
|
|
28
|
+
icon,
|
|
28
29
|
label,
|
|
29
30
|
labelStyle,
|
|
30
31
|
displayMode = 'minimal',
|
|
@@ -48,17 +49,30 @@ export function HeaderBackButton({
|
|
|
48
49
|
const isMinimal = displayMode === 'minimal' || measuredMinimal;
|
|
49
50
|
|
|
50
51
|
const renderBackImage = () => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<HeaderIcon
|
|
56
|
-
source={backIcon}
|
|
57
|
-
tintColor={tintColor ?? colors.text}
|
|
58
|
-
style={styles.icon}
|
|
59
|
-
/>
|
|
60
|
-
);
|
|
52
|
+
const color = tintColor ?? colors.text;
|
|
53
|
+
|
|
54
|
+
if (typeof icon === 'function') {
|
|
55
|
+
return icon({ tintColor: color });
|
|
61
56
|
}
|
|
57
|
+
|
|
58
|
+
const backIcon =
|
|
59
|
+
icon ??
|
|
60
|
+
Platform.select<HeaderIconType>({
|
|
61
|
+
ios: {
|
|
62
|
+
type: 'sfSymbol',
|
|
63
|
+
name: 'chevron.left',
|
|
64
|
+
},
|
|
65
|
+
android: {
|
|
66
|
+
type: 'materialSymbol',
|
|
67
|
+
name: 'arrow_back',
|
|
68
|
+
},
|
|
69
|
+
default: {
|
|
70
|
+
type: 'image',
|
|
71
|
+
source: backIconImage,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
return <HeaderIcon icon={backIcon} color={color} style={styles.icon} />;
|
|
62
76
|
};
|
|
63
77
|
|
|
64
78
|
const handlePress = () => {
|
|
@@ -231,8 +245,8 @@ function HeaderBackLabel({
|
|
|
231
245
|
// iOS uses a smaller chevron, Android uses a larger arrow
|
|
232
246
|
const ICON_WIDTH = Platform.OS === 'ios' ? 13 : 24;
|
|
233
247
|
const ICON_SPACING_START = isLiquidGlassSupported
|
|
234
|
-
?
|
|
235
|
-
:
|
|
248
|
+
? 15 // Standard distance of chevron from left edge in liquid glass
|
|
249
|
+
: 2; // Otherwise icon is aligned to the start of the button
|
|
236
250
|
|
|
237
251
|
// Standard distance between chevron and label
|
|
238
252
|
const ICON_LABEL_SPACING = 9;
|
|
@@ -1,24 +1,64 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { MaterialSymbol, SFSymbol, useLocale } from '@react-navigation/native';
|
|
2
|
+
import {
|
|
3
|
+
type ColorValue,
|
|
4
|
+
Image,
|
|
5
|
+
type ImageProps,
|
|
6
|
+
Platform,
|
|
7
|
+
StyleSheet,
|
|
8
|
+
} from 'react-native';
|
|
3
9
|
|
|
4
|
-
|
|
5
|
-
|
|
10
|
+
import type { HeaderIcon as HeaderIconType } from '../types';
|
|
11
|
+
|
|
12
|
+
type Props = Omit<ImageProps, 'source'> & {
|
|
13
|
+
icon: HeaderIconType;
|
|
14
|
+
color: ColorValue;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function HeaderIcon({ icon, color, style, ...rest }: Props) {
|
|
6
18
|
const { direction } = useLocale();
|
|
7
19
|
|
|
20
|
+
const iconStyle = [styles.icon, direction === 'rtl' && styles.flip, style];
|
|
21
|
+
|
|
22
|
+
if (icon.type === 'sfSymbol') {
|
|
23
|
+
return (
|
|
24
|
+
<SFSymbol
|
|
25
|
+
name={icon.name}
|
|
26
|
+
color={color}
|
|
27
|
+
size={ICON_SIZE}
|
|
28
|
+
style={iconStyle}
|
|
29
|
+
{...rest}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (icon.type === 'materialSymbol') {
|
|
35
|
+
return (
|
|
36
|
+
<MaterialSymbol
|
|
37
|
+
name={icon.name}
|
|
38
|
+
variant={icon.variant}
|
|
39
|
+
weight={icon.weight}
|
|
40
|
+
color={color}
|
|
41
|
+
size={ICON_SIZE}
|
|
42
|
+
style={iconStyle}
|
|
43
|
+
{...rest}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
8
48
|
return (
|
|
9
49
|
<Image
|
|
10
|
-
source={source}
|
|
50
|
+
source={icon.source}
|
|
11
51
|
resizeMode="contain"
|
|
12
52
|
fadeDuration={0}
|
|
13
|
-
tintColor={
|
|
14
|
-
style={
|
|
53
|
+
tintColor={color}
|
|
54
|
+
style={iconStyle}
|
|
15
55
|
{...rest}
|
|
16
56
|
/>
|
|
17
57
|
);
|
|
18
58
|
}
|
|
19
59
|
|
|
20
|
-
|
|
21
|
-
|
|
60
|
+
const ICON_SIZE = Platform.OS === 'ios' ? 21 : 24;
|
|
61
|
+
const ICON_MARGIN = Platform.OS === 'ios' ? 8 : 3;
|
|
22
62
|
|
|
23
63
|
const styles = StyleSheet.create({
|
|
24
64
|
icon: {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { useNavigation, useTheme } from '@react-navigation/native';
|
|
1
|
+
import { SFSymbol, useNavigation, useTheme } from '@react-navigation/native';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import {
|
|
4
4
|
Animated,
|
|
5
5
|
BackHandler,
|
|
6
6
|
type ColorValue,
|
|
7
|
-
Image,
|
|
8
7
|
type NativeEventSubscription,
|
|
9
8
|
Platform,
|
|
10
9
|
type StyleProp,
|
|
@@ -14,10 +13,7 @@ import {
|
|
|
14
13
|
type ViewStyle,
|
|
15
14
|
} from 'react-native';
|
|
16
15
|
|
|
17
|
-
import clearIcon from '../assets/clear-icon.png';
|
|
18
16
|
import closeIcon from '../assets/close-icon.png';
|
|
19
|
-
import searchIcon from '../assets/search-icon.png';
|
|
20
|
-
import searchIconLegacy from '../assets/search-icon-legacy.png';
|
|
21
17
|
import { Color } from '../Color';
|
|
22
18
|
import {
|
|
23
19
|
AnimatedLiquidGlassContainerView,
|
|
@@ -210,9 +206,10 @@ function HeaderSearchBarInternal(
|
|
|
210
206
|
) : null}
|
|
211
207
|
<HeaderButtonBackground style={styles.searchbarContainer}>
|
|
212
208
|
{Platform.OS === 'ios' ? (
|
|
213
|
-
<
|
|
214
|
-
|
|
215
|
-
|
|
209
|
+
<SFSymbol
|
|
210
|
+
name="magnifyingglass"
|
|
211
|
+
size={SEARCH_ICON_SIZE}
|
|
212
|
+
color={textColor}
|
|
216
213
|
style={[
|
|
217
214
|
styles.inputSearchIconIos,
|
|
218
215
|
!isLiquidGlassSupported && styles.inputSearchIconIosLegacy,
|
|
@@ -263,10 +260,10 @@ function HeaderSearchBarInternal(
|
|
|
263
260
|
!isLiquidGlassSupported && styles.clearButtonIosLegacy,
|
|
264
261
|
]}
|
|
265
262
|
>
|
|
266
|
-
<
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
263
|
+
<SFSymbol
|
|
264
|
+
name="xmark.circle.fill"
|
|
265
|
+
size={CLEAR_ICON_SIZE}
|
|
266
|
+
color={textColor}
|
|
270
267
|
style={styles.clearIconIos}
|
|
271
268
|
/>
|
|
272
269
|
</PlatformPressable>
|
|
@@ -278,7 +275,19 @@ function HeaderSearchBarInternal(
|
|
|
278
275
|
onPress={onClear}
|
|
279
276
|
style={[styles.closeButton, { opacity: clearVisibleAnim }]}
|
|
280
277
|
>
|
|
281
|
-
<HeaderIcon
|
|
278
|
+
<HeaderIcon
|
|
279
|
+
icon={Platform.select({
|
|
280
|
+
android: {
|
|
281
|
+
type: 'materialSymbol',
|
|
282
|
+
name: 'close',
|
|
283
|
+
},
|
|
284
|
+
default: {
|
|
285
|
+
type: 'image',
|
|
286
|
+
source: closeIcon,
|
|
287
|
+
},
|
|
288
|
+
})}
|
|
289
|
+
color={textColor}
|
|
290
|
+
/>
|
|
282
291
|
</HeaderButton>
|
|
283
292
|
) : null}
|
|
284
293
|
{Platform.OS === 'ios' ? (
|
|
@@ -288,7 +297,7 @@ function HeaderSearchBarInternal(
|
|
|
288
297
|
accessibilityLabel={cancelButtonText}
|
|
289
298
|
onPress={cancelSearch}
|
|
290
299
|
>
|
|
291
|
-
<
|
|
300
|
+
<SFSymbol name="xmark" color={textColor} />
|
|
292
301
|
</HeaderButton>
|
|
293
302
|
</HeaderButtonBackground>
|
|
294
303
|
) : (
|
|
@@ -332,14 +341,14 @@ const styles = StyleSheet.create({
|
|
|
332
341
|
},
|
|
333
342
|
inputSearchIconIos: {
|
|
334
343
|
position: 'absolute',
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
344
|
+
top: '50%',
|
|
345
|
+
left: BUTTON_SPACING + SEARCHBAR_ICON_SPACING / 2,
|
|
346
|
+
marginTop: -SEARCH_ICON_SIZE / 2,
|
|
338
347
|
height: SEARCH_ICON_SIZE,
|
|
339
348
|
width: SEARCH_ICON_SIZE,
|
|
340
349
|
},
|
|
341
350
|
inputSearchIconIosLegacy: {
|
|
342
|
-
top:
|
|
351
|
+
top: SEARCHBAR_ICON_SPACING,
|
|
343
352
|
},
|
|
344
353
|
backButton: {
|
|
345
354
|
alignSelf: 'center',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { PlatformColor } from 'react-native';
|
|
1
|
+
export { DynamicColorIOS, PlatformColor } from 'react-native';
|
package/src/PlatformColor.tsx
CHANGED
package/src/Screen.tsx
CHANGED
|
@@ -6,18 +6,13 @@ 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
|
|
|
18
12
|
import { getDefaultHeaderHeight } from './Header/getDefaultHeaderHeight';
|
|
19
13
|
import { HeaderHeightContext } from './Header/HeaderHeightContext';
|
|
20
14
|
import { HeaderShownContext } from './Header/HeaderShownContext';
|
|
15
|
+
import { Container } from './internal';
|
|
21
16
|
import { useFrameSize } from './useFrameSize';
|
|
22
17
|
|
|
23
18
|
type Props = {
|
|
@@ -29,7 +24,7 @@ type Props = {
|
|
|
29
24
|
headerShown?: boolean;
|
|
30
25
|
headerStatusBarHeight?: number;
|
|
31
26
|
headerTransparent?: boolean;
|
|
32
|
-
style?:
|
|
27
|
+
style?: React.ComponentProps<typeof Container>['style'];
|
|
33
28
|
children: React.ReactNode;
|
|
34
29
|
};
|
|
35
30
|
|
|
@@ -72,12 +67,17 @@ export function Screen(props: Props) {
|
|
|
72
67
|
}, [route.name]);
|
|
73
68
|
|
|
74
69
|
return (
|
|
75
|
-
<
|
|
76
|
-
|
|
77
|
-
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
|
|
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}>
|
|
@@ -105,7 +105,7 @@ export function Screen(props: Props) {
|
|
|
105
105
|
</HeaderHeightContext.Provider>
|
|
106
106
|
</HeaderShownContext.Provider>
|
|
107
107
|
</View>
|
|
108
|
-
</
|
|
108
|
+
</Container>
|
|
109
109
|
);
|
|
110
110
|
}
|
|
111
111
|
|
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';
|
|
@@ -22,14 +16,5 @@ export { getLabel } from './Label/getLabel';
|
|
|
22
16
|
export { Label } from './Label/Label';
|
|
23
17
|
export { PlatformPressable } from './PlatformPressable';
|
|
24
18
|
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
19
|
export * from './types';
|
|
20
|
+
export { useFrameSize } from './useFrameSize';
|
package/src/types.tsx
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
MaterialSymbolProps,
|
|
3
|
+
SFSymbolProps,
|
|
4
|
+
} from '@react-navigation/native';
|
|
5
|
+
import * as React from 'react';
|
|
1
6
|
import type {
|
|
2
7
|
Animated,
|
|
3
8
|
ColorValue,
|
|
9
|
+
ImageSourcePropType,
|
|
4
10
|
LayoutChangeEvent,
|
|
5
11
|
StyleProp,
|
|
6
12
|
TextInputProps,
|
|
@@ -325,11 +331,36 @@ export type HeaderButtonProps = {
|
|
|
325
331
|
children: React.ReactNode;
|
|
326
332
|
};
|
|
327
333
|
|
|
334
|
+
export type HeaderIcon =
|
|
335
|
+
| {
|
|
336
|
+
type: 'image';
|
|
337
|
+
source: ImageSourcePropType;
|
|
338
|
+
}
|
|
339
|
+
| {
|
|
340
|
+
type: 'sfSymbol';
|
|
341
|
+
name: SFSymbolProps['name'];
|
|
342
|
+
}
|
|
343
|
+
| ({
|
|
344
|
+
type: 'materialSymbol';
|
|
345
|
+
} & Pick<MaterialSymbolProps, 'name' | 'variant' | 'weight'>);
|
|
346
|
+
|
|
328
347
|
export type HeaderBackButtonProps = Omit<HeaderButtonProps, 'children'> & {
|
|
329
348
|
/**
|
|
330
|
-
*
|
|
349
|
+
* Icon to display for the back button.
|
|
350
|
+
*
|
|
351
|
+
* Supported types:
|
|
352
|
+
* - image: custom image source
|
|
353
|
+
* - sfSymbol: SF Symbol icon (iOS only)
|
|
354
|
+
* - materialSymbol: material symbol icon (Android only)
|
|
355
|
+
* - React Node: function that returns a React Element
|
|
356
|
+
*
|
|
357
|
+
* Defaults to back icon image for the platform
|
|
358
|
+
* - A chevron on iOS
|
|
359
|
+
* - An arrow on Android
|
|
331
360
|
*/
|
|
332
|
-
|
|
361
|
+
icon?:
|
|
362
|
+
| HeaderIcon
|
|
363
|
+
| ((props: { tintColor: ColorValue | undefined }) => React.ReactNode);
|
|
333
364
|
/**
|
|
334
365
|
* Label text for the button. Usually the title of the previous screen.
|
|
335
366
|
* By default, this is only shown on iOS.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|