Skip to content

Commit 4e12df6

Browse files
committed
refactor: replace custom sidebar search field with native .searchable()
1 parent a4a40ee commit 4e12df6

5 files changed

Lines changed: 22 additions & 61 deletions

File tree

TablePro.xcodeproj/project.pbxproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@
2424
5A867000D00000000 /* RedisDriver.tableplugin in Copy Plug-Ins */ = {isa = PBXBuildFile; fileRef = 5A867000100000000 /* RedisDriver.tableplugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
2525
5A868000A00000000 /* TableProPluginKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A860000100000000 /* TableProPluginKit.framework */; };
2626
5A868000D00000000 /* PostgreSQLDriver.tableplugin in Copy Plug-Ins */ = {isa = PBXBuildFile; fileRef = 5A868000100000000 /* PostgreSQLDriver.tableplugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
27-
5ACE00012F4F000000000004 /* CodeEditSourceEditor in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000002 /* CodeEditSourceEditor */; };
28-
5ACE00012F4F000000000005 /* CodeEditLanguages in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000003 /* CodeEditLanguages */; };
29-
5ACE00012F4F000000000006 /* CodeEditTextView in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000007 /* CodeEditTextView */; };
30-
5ACE00012F4F00000000000A /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000009 /* Sparkle */; };
31-
5ACE00012F4F00000000000D /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F00000000000C /* MarkdownUI */; };
32-
5AEE5B362F5C9B7B00FA84D7 /* OracleNIO in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F00000000000F /* OracleNIO */; };
3327
5A86A000A00000000 /* TableProPluginKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A860000100000000 /* TableProPluginKit.framework */; };
3428
5A86A000D00000000 /* CSVExport.tableplugin in Copy Plug-Ins */ = {isa = PBXBuildFile; fileRef = 5A86A000100000000 /* CSVExport.tableplugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
3529
5A86B000A00000000 /* TableProPluginKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A860000100000000 /* TableProPluginKit.framework */; };
@@ -40,6 +34,12 @@
4034
5A86D000D00000000 /* XLSXExport.tableplugin in Copy Plug-Ins */ = {isa = PBXBuildFile; fileRef = 5A86D000100000000 /* XLSXExport.tableplugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
4135
5A86E000A00000000 /* TableProPluginKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A860000100000000 /* TableProPluginKit.framework */; };
4236
5A86E000D00000000 /* MQLExport.tableplugin in Copy Plug-Ins */ = {isa = PBXBuildFile; fileRef = 5A86E000100000000 /* MQLExport.tableplugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
37+
5ACE00012F4F000000000004 /* CodeEditSourceEditor in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000002 /* CodeEditSourceEditor */; };
38+
5ACE00012F4F000000000005 /* CodeEditLanguages in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000003 /* CodeEditLanguages */; };
39+
5ACE00012F4F000000000006 /* CodeEditTextView in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000007 /* CodeEditTextView */; };
40+
5ACE00012F4F00000000000A /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000009 /* Sparkle */; };
41+
5ACE00012F4F00000000000D /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F00000000000C /* MarkdownUI */; };
42+
5AEE5B362F5C9B7B00FA84D7 /* OracleNIO in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F00000000000F /* OracleNIO */; };
4343
/* End PBXBuildFile section */
4444

4545
/* Begin PBXContainerItemProxy section */

TablePro.xcodeproj/xcshareddata/xcschemes/TablePro.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
33
LastUpgradeVersion = "2640"
4-
version = "1.7">
4+
version = "1.8">
55
<BuildAction
66
parallelizeBuildables = "YES"
77
buildImplicitDependencies = "YES"

TablePro/ContentView.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,11 @@ struct ContentView: View {
232232
schemaProvider: SchemaProviderRegistry.shared.provider(for: currentSession.connection.id)
233233
)
234234
}
235+
.searchable(
236+
text: sidebarSearchTextBinding(for: currentSession.connection.id),
237+
placement: .sidebar,
238+
prompt: "Filter"
239+
)
235240
.navigationSplitViewColumnWidth(min: 200, ideal: 250, max: 600)
236241
} detail: {
237242
// MARK: - Detail (Main workspace with optional right sidebar)
@@ -332,6 +337,14 @@ struct ContentView: View {
332337
)
333338
}
334339

340+
private func sidebarSearchTextBinding(for connectionId: UUID) -> Binding<String> {
341+
let state = SharedSidebarState.forConnection(connectionId)
342+
return Binding(
343+
get: { state.searchText },
344+
set: { state.searchText = $0 }
345+
)
346+
}
347+
335348
private var sessionTableOperationOptionsBinding: Binding<[String: TableOperationOptions]> {
336349
createSessionBinding(
337350
get: { $0.tableOperationOptions },

TablePro/Resources/Localizable.xcstrings

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,6 +1810,7 @@
18101810
}
18111811
},
18121812
"Clear table filter" : {
1813+
"extractionState" : "stale",
18131814
"localizations" : {
18141815
"vi" : {
18151816
"stringUnit" : {

TablePro/Views/Sidebar/SidebarView.swift

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ import SwiftUI
1212
/// Sidebar view displaying list of database tables
1313
struct SidebarView: View {
1414
@State private var viewModel: SidebarViewModel
15-
/// Local search text for responsive typing; synced to/from shared state
16-
@State private var localSearchText: String = ""
17-
/// Debounce task for writing local search text to the shared state
18-
@State private var searchSyncTask: Task<Void, Never>?
1915

2016
// Keep @Binding on the view for SwiftUI change tracking.
2117
// The ViewModel stores the same bindings for write access.
@@ -56,7 +52,6 @@ struct SidebarView: View {
5652
) {
5753
_tables = tables
5854
self.sidebarState = sidebarState
59-
_localSearchText = State(initialValue: sidebarState.searchText)
6055
_pendingTruncates = pendingTruncates
6156
_pendingDeletes = pendingDeletes
6257
let selectedBinding = Binding(
@@ -84,28 +79,11 @@ struct SidebarView: View {
8479

8580
var body: some View {
8681
VStack(alignment: .leading, spacing: 0) {
87-
if !tables.isEmpty {
88-
searchField
89-
}
9082
content
9183
}
9284
.frame(minWidth: 280)
93-
.onChange(of: localSearchText) { _, newValue in
94-
viewModel.debouncedSearchText = newValue
95-
searchSyncTask?.cancel()
96-
searchSyncTask = Task { @MainActor in
97-
try? await Task.sleep(nanoseconds: 150_000_000)
98-
guard !Task.isCancelled else { return }
99-
if sidebarState.searchText != newValue {
100-
sidebarState.searchText = newValue
101-
}
102-
}
103-
}
10485
.onChange(of: sidebarState.searchText) { _, newValue in
105-
if localSearchText != newValue {
106-
localSearchText = newValue
107-
viewModel.debouncedSearchText = newValue
108-
}
86+
viewModel.debouncedSearchText = newValue
10987
}
11088
.onChange(of: tables) { _, newTables in
11189
let hasSession = DatabaseManager.shared.activeSessions[connectionId] != nil
@@ -135,37 +113,6 @@ struct SidebarView: View {
135113
}
136114
}
137115

138-
// MARK: - Search Field
139-
140-
private var searchField: some View {
141-
HStack(spacing: 6) {
142-
Image(systemName: "magnifyingglass")
143-
.foregroundStyle(.secondary)
144-
.font(.system(size: DesignConstants.FontSize.medium))
145-
146-
TextField("Filter", text: $localSearchText)
147-
.textFieldStyle(.plain)
148-
.font(.system(size: DesignConstants.FontSize.body))
149-
150-
if !localSearchText.isEmpty {
151-
Button(action: { localSearchText = "" }) {
152-
Image(systemName: "xmark.circle.fill")
153-
.foregroundStyle(.secondary)
154-
.font(.system(size: DesignConstants.FontSize.medium))
155-
}
156-
.buttonStyle(.plain)
157-
.accessibilityLabel(String(localized: "Clear table filter"))
158-
}
159-
}
160-
.padding(.horizontal, 8)
161-
.padding(.vertical, DesignConstants.Spacing.xxs)
162-
.background(Color(nsColor: .quaternaryLabelColor))
163-
.cornerRadius(6)
164-
.padding(.horizontal, 10)
165-
.padding(.top, 8)
166-
.padding(.bottom, 4)
167-
}
168-
169116
// MARK: - Content States
170117

171118
@ViewBuilder

0 commit comments

Comments
 (0)