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";
1414import { AndroidScreenHeader } from "../../components/AndroidScreenHeader";
1515import { SymbolView } from "../../components/AppSymbol";
1616import { 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";
1823import { getMobileThirdPartyLicenses } from "./mobileThirdPartyLicenses";
1924
2025function useMobileThirdPartyLicenses() {
......@@ -65,6 +70,7 @@ export function SettingsOpenSourceLicensesRouteScreen() {
6570 const navigation = useNavigation();
6671 const insets = useSafeAreaInsets();
6772 const [query, setQuery] = useState("");
73 const usesNativeMailSearchToolbar = Platform.OS === "ios" && NATIVE_MAIL_SEARCH_TOOLBAR_SUPPORTED;
6874 const manifest = useMobileThirdPartyLicenses();
6975 const entries = manifest?.entries ?? [];
7076 const filteredEntries = useMemo(
......@@ -109,6 +115,39 @@ export function SettingsOpenSourceLicensesRouteScreen() {
109115
110116 return (
111117 <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}
112151 {Platform.OS === "android" ? (
113152 <>
114153 <NativeStackScreenOptions options={{ headerShown: false }} />
......@@ -117,7 +156,13 @@ export function SettingsOpenSourceLicensesRouteScreen() {
117156 ) : null}
118157 <LegendList
119158 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 }}
121166 contentInsetAdjustmentBehavior="automatic"
122167 data={filteredEntries}
123168 estimatedItemSize={78}
......@@ -132,26 +177,20 @@ export function SettingsOpenSourceLicensesRouteScreen() {
132177 </View>
133178 }
134179 ListHeaderComponent={
135 <View className="gap-4 px-5 pt-4 pb-5">
136 <Text className="text-base leading-normal text-foreground-muted">
137 Notices for dependencies, assets, and optional tools used by T3 Code Mobile.
138 </Text>
139 <TextInput
140 accessibilityLabel="Search open-source licenses"
141 autoCapitalize="none"
142 autoCorrect={false}
143 clearButtonMode="while-editing"
144 onChangeText={setQuery}
145 placeholder="Search packages"
146 returnKeyType="search"
147 value={query}
148 />
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>
180 Platform.OS !== "ios" ? (
181 <View className="px-5 pt-4 pb-5">
182 <TextInput
183 accessibilityLabel="Search open-source licenses"
184 autoCapitalize="none"
185 autoCorrect={false}
186 clearButtonMode="while-editing"
187 onChangeText={setQuery}
188 placeholder="Search packages"
189 returnKeyType="search"
190 value={query}
191 />
192 </View>
193 ) : null
155194 }
156195 renderItem={renderItem}
157196 showsVerticalScrollIndicator={false}