@@ -113,7 +113,6 @@ private struct LiquidTabs26View: View {
113113 @StateObject private var store = LiquidTabsStore . shared
114114 let navController : UINavigationController
115115
116- @State private var searchText : String = " "
117116 @FocusState private var isSearchFocused : Bool
118117
119118 @State private var hackShowKeyboard : Bool = false
@@ -135,6 +134,13 @@ private struct LiquidTabs26View: View {
135134 )
136135 }
137136
137+ private var searchTextBinding : Binding < String > {
138+ Binding (
139+ get: { store. searchText } ,
140+ set: { store. searchText = $0 }
141+ )
142+ }
143+
138144 private func handleRetap( on selection: LiquidTabsTabSelection ) {
139145 print ( " User re-tapped tab: \( selection) " )
140146 navController. popToRootViewController ( animated: true )
@@ -219,10 +225,13 @@ private struct LiquidTabs26View: View {
219225 . ignoresSafeArea ( )
220226 }
221227 }
222- . searchable ( text: $searchText )
228+ . searchable ( text: searchTextBinding )
223229 . searchFocused ( $isSearchFocused)
224230 . searchToolbarBehavior ( . minimize)
225- . onChange ( of: searchText) { query in
231+ . onChange ( of: store. searchText) { query in
232+ if query. isEmpty {
233+ store. searchResults = [ ]
234+ }
226235 LiquidTabsPlugin . shared? . notifySearchChanged ( query: query)
227236 }
228237 . background ( Color . logseqBackground)
@@ -295,35 +304,47 @@ private struct LiquidTabs26View: View {
295304// Search host for 26+
296305// Only responsible for cancel behaviour and tab switching.
297306// It does NOT own the focus anymore.
307+ @available ( iOS 26 . 0 , * )
308+ private enum SearchRoute : Hashable {
309+ case result( String )
310+ }
311+
298312@available ( iOS 26 . 0 , * )
299313private struct SearchTabHost26 : View {
300314 let navController : UINavigationController
301315 var selectedTab : Binding < LiquidTabsTabSelection >
302316 let firstTabId : String ?
303- let store : LiquidTabsStore
317+ @ ObservedObject var store : LiquidTabsStore
304318
305319 @Environment ( \. isSearching) private var isSearching
306320 @State private var wasSearching : Bool = false
307321
308322 var body : some View {
309323 NavigationStack {
310- NativeNavHost ( navController: navController)
311- . ignoresSafeArea ( )
312- . onChange ( of: isSearching) { searching in
313- if searching {
314- wasSearching = true
315- } else if wasSearching,
316- case . search = selectedTab. wrappedValue,
317- let firstId = firstTabId {
318-
319- // User tapped Cancel: switch back to first normal tab.
320- wasSearching = false
321- selectedTab. wrappedValue = . content( 0 )
322- store. selectedId = firstId
323- }
324- }
324+ ZStack {
325+ Color . logseqBackground
326+ . ignoresSafeArea ( )
327+
328+ SearchResultsContent (
329+ navController: navController,
330+ store: store
331+ )
332+ }
325333 }
334+ . onChange ( of: isSearching) { searching in
335+ if searching {
336+ wasSearching = true
337+ } else if wasSearching,
338+ case . search = selectedTab. wrappedValue,
339+ let firstId = firstTabId {
340+
341+ wasSearching = false
342+ selectedTab. wrappedValue = . content( 0 )
343+ store. selectedId = firstId
344+ }
345+ }
326346 }
347+
327348}
328349
329350// MARK: - iOS 16–25 implementation
@@ -333,9 +354,15 @@ private struct LiquidTabs16View: View {
333354 @StateObject private var store = LiquidTabsStore . shared
334355 let navController : UINavigationController
335356
336- @State private var searchText : String = " "
337357 @State private var hackShowKeyboard : Bool = false
338358
359+ private var searchTextBinding : Binding < String > {
360+ Binding (
361+ get: { store. searchText } ,
362+ set: { store. searchText = $0 }
363+ )
364+ }
365+
339366 var body : some View {
340367 ZStack {
341368 Color . logseqBackground. ignoresSafeArea ( )
@@ -380,7 +407,8 @@ private struct LiquidTabs16View: View {
380407 // --- 🔍 SEARCH TAB (iOS 16–25) ---
381408 SearchTab16Host (
382409 navController: navController,
383- searchText: $searchText
410+ searchText: searchTextBinding,
411+ store: store
384412 )
385413 . ignoresSafeArea ( )
386414 . tabItem {
@@ -425,13 +453,18 @@ private struct LiquidTabs16View: View {
425453private struct SearchTab16Host : View {
426454 let navController : UINavigationController
427455 @Binding var searchText : String
456+ @ObservedObject var store : LiquidTabsStore
428457
429458 var body : some View {
430459 NavigationStack {
431460 ZStack {
432- // Main content (fills whole screen)
433- NativeNavHost ( navController: navController)
434- . ignoresSafeArea ( )
461+ Color . logseqBackground
462+ . ignoresSafeArea ( )
463+
464+ SearchResultsContent (
465+ navController: navController,
466+ store: store
467+ )
435468
436469 // Bottom search bar
437470 VStack {
@@ -462,10 +495,36 @@ private struct SearchTab16Host: View {
462495 . padding ( . bottom, 12 )
463496 }
464497 }
465- . navigationBarHidden ( true )
466498 }
467499 . onChange ( of: searchText) { query in
468500 LiquidTabsPlugin . shared? . notifySearchChanged ( query: query)
469501 }
470502 }
471503}
504+
505+ private struct SearchResultsContent : View {
506+ let navController : UINavigationController
507+ @ObservedObject var store : LiquidTabsStore
508+
509+ var body : some View {
510+ List ( store. searchResults) { result in
511+ NavigationLink ( value: result) {
512+ Text ( result. title)
513+ . foregroundColor ( . primary)
514+ . padding ( . vertical, 8 )
515+ . contentShape ( Rectangle ( ) ) // improves tap area
516+ }
517+ . listRowBackground ( Color . clear)
518+ }
519+ . scrollContentBackground ( . hidden)
520+ . scrollDismissesKeyboard ( . immediately)
521+ . navigationTitle ( " Search " )
522+ . navigationDestination ( for: NativeSearchResult . self) { result in
523+ NativeNavHost ( navController: navController)
524+ . ignoresSafeArea ( )
525+ . onAppear {
526+ LiquidTabsPlugin . shared? . openResult ( id: result. id)
527+ }
528+ }
529+ }
530+ }
0 commit comments