authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-09-15 20:15:01-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-15 20:15:01-07:00
logf8500f11271622ed82df7f6c1d7f73eddb4f43e6
tree414ce271400f839430115c2c0dda5abdb58103f2
parenteed974c122e192de45b54b7dac7ca1a51448c08f
signature Signed by PGP key B5690EEEBB952194

fix(mobile): use native toolbar search for licenses (#12011)


1 files changed, 61 insertions(+), 22 deletions(-)

apps/mobile/src/features/settings/SettingsOpenSourceLicensesRouteScreen.tsx+61-22
...@@ -14,7 +14,12 @@ import { useSafeAreaInsets } from "react-native-safe-area-context";...@@ -14,7 +14,12 @@ import { useSafeAreaInsets } from "react-native-safe-area-context";
14import { AndroidScreenHeader } from "../../components/AndroidScreenHeader";14import { AndroidScreenHeader } from "../../components/AndroidScreenHeader";
15import { SymbolView } from "../../components/AppSymbol";15import { SymbolView } from "../../components/AppSymbol";
16import { AppText as Text, AppTextInput as TextInput } from "../../components/AppText";16import { AppText as Text, AppTextInput as TextInput } from "../../components/AppText";
17import { NativeStackScreenOptions } from "../../native/StackHeader";17import { NativeHeaderToolbar, NativeStackScreenOptions } from "../../native/StackHeader";
18import {
19 createNativeMailSearchToolbarItem,
20 NATIVE_MAIL_SEARCH_TOOLBAR_CONTENT_INSET,
21 NATIVE_MAIL_SEARCH_TOOLBAR_SUPPORTED,
22} from "../layout/native-mail-search-toolbar";
18import { getMobileThirdPartyLicenses } from "./mobileThirdPartyLicenses";23import { getMobileThirdPartyLicenses } from "./mobileThirdPartyLicenses";
1924
20function useMobileThirdPartyLicenses() {25function useMobileThirdPartyLicenses() {
...@@ -65,6 +70,7 @@ export function SettingsOpenSourceLicensesRouteScreen() {...@@ -65,6 +70,7 @@ export function SettingsOpenSourceLicensesRouteScreen() {
65 const navigation = useNavigation();70 const navigation = useNavigation();
66 const insets = useSafeAreaInsets();71 const insets = useSafeAreaInsets();
67 const [query, setQuery] = useState("");72 const [query, setQuery] = useState("");
73 const usesNativeMailSearchToolbar = Platform.OS === "ios" && NATIVE_MAIL_SEARCH_TOOLBAR_SUPPORTED;
68 const manifest = useMobileThirdPartyLicenses();74 const manifest = useMobileThirdPartyLicenses();
69 const entries = manifest?.entries ?? [];75 const entries = manifest?.entries ?? [];
70 const filteredEntries = useMemo(76 const filteredEntries = useMemo(
...@@ -109,6 +115,39 @@ export function SettingsOpenSourceLicensesRouteScreen() {...@@ -109,6 +115,39 @@ export function SettingsOpenSourceLicensesRouteScreen() {
109115
110 return (116 return (
111 <View collapsable={false} className="flex-1 bg-sheet">117 <View collapsable={false} className="flex-1 bg-sheet">
118 {Platform.OS === "ios" ? (
119 <NativeStackScreenOptions
120 options={{
121 unstable_headerToolbarItems: usesNativeMailSearchToolbar
122 ? () => [
123 createNativeMailSearchToolbarItem({
124 onSearchTextChange: setQuery,
125 placeholder: "Search packages",
126 searchTextChangeId: "open-source-licenses-search-text",
127 showsSearchDismissButton: true,
128 }),
129 ]
130 : undefined,
131 headerSearchBarOptions: usesNativeMailSearchToolbar
132 ? undefined
133 : {
134 allowToolbarIntegration: true,
135 autoCapitalize: "none",
136 hideNavigationBar: false,
137 hideWhenScrolling: false,
138 obscureBackground: false,
139 onCancelButtonPress: () => setQuery(""),
140 onChangeText: (event) => setQuery(event.nativeEvent.text),
141 placeholder: "Search packages",
142 },
143 }}
144 />
145 ) : null}
146 {Platform.OS === "ios" && !usesNativeMailSearchToolbar ? (
147 <NativeHeaderToolbar placement="bottom">
148 <NativeHeaderToolbar.SearchBarSlot />
149 </NativeHeaderToolbar>
150 ) : null}
112 {Platform.OS === "android" ? (151 {Platform.OS === "android" ? (
113 <>152 <>
114 <NativeStackScreenOptions options={{ headerShown: false }} />153 <NativeStackScreenOptions options={{ headerShown: false }} />
...@@ -117,7 +156,13 @@ export function SettingsOpenSourceLicensesRouteScreen() {...@@ -117,7 +156,13 @@ export function SettingsOpenSourceLicensesRouteScreen() {
117 ) : null}156 ) : null}
118 <LegendList157 <LegendList
119 className="flex-1"158 className="flex-1"
120 contentContainerStyle={{ paddingBottom: Math.max(insets.bottom, 18) + 18 }}159 contentContainerStyle={{
160 paddingBottom: usesNativeMailSearchToolbar
161 ? NATIVE_MAIL_SEARCH_TOOLBAR_CONTENT_INSET + 18
162 : Platform.OS === "ios"
163 ? 18
164 : Math.max(insets.bottom, 18) + 18,
165 }}
121 contentInsetAdjustmentBehavior="automatic"166 contentInsetAdjustmentBehavior="automatic"
122 data={filteredEntries}167 data={filteredEntries}
123 estimatedItemSize={78}168 estimatedItemSize={78}
...@@ -132,26 +177,20 @@ export function SettingsOpenSourceLicensesRouteScreen() {...@@ -132,26 +177,20 @@ export function SettingsOpenSourceLicensesRouteScreen() {
132 </View>177 </View>
133 }178 }
134 ListHeaderComponent={179 ListHeaderComponent={
135 <View className="gap-4 px-5 pt-4 pb-5">180 Platform.OS !== "ios" ? (
136 <Text className="text-base leading-normal text-foreground-muted">181 <View className="px-5 pt-4 pb-5">
137 Notices for dependencies, assets, and optional tools used by T3 Code Mobile.182 <TextInput
138 </Text>183 accessibilityLabel="Search open-source licenses"
139 <TextInput184 autoCapitalize="none"
140 accessibilityLabel="Search open-source licenses"185 autoCorrect={false}
141 autoCapitalize="none"186 clearButtonMode="while-editing"
142 autoCorrect={false}187 onChangeText={setQuery}
143 clearButtonMode="while-editing"188 placeholder="Search packages"
144 onChangeText={setQuery}189 returnKeyType="search"
145 placeholder="Search packages"190 value={query}
146 returnKeyType="search"191 />
147 value={query}192 </View>
148 />193 ) : null
149 <Text className="tabular-nums text-sm text-foreground-muted">
150 {filteredEntries.length === entries.length
151 ? `${String(entries.length)} notices`
152 : `${String(filteredEntries.length)} of ${String(entries.length)} notices`}
153 </Text>
154 </View>
155 }194 }
156 renderItem={renderItem}195 renderItem={renderItem}
157 showsVerticalScrollIndicator={false}196 showsVerticalScrollIndicator={false}