From 9eac048d4c34e29608d6381f91630e73aa901ffb Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Sat, 30 May 2026 14:04:21 +0700 Subject: [PATCH] fix(hig): initial focus and Escape dismissal for activation, token, and review sheets (#1490) --- CHANGELOG.md | 1 + TablePro/Views/Components/SQLReviewSheet.swift | 1 + TablePro/Views/Settings/LicenseActivationSheet.swift | 3 +++ TablePro/Views/Settings/Sections/MCPTokenRevealSheet.swift | 3 +++ 4 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a74cc19e..26b4d4fd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- The license activation sheet focuses the key field on open, the SQL review sheet closes with Escape even while the editor has focus, and the integration token sheet focuses its Done button. (#1490) - Escape now dismisses search-based sheets and popovers (database switcher, quick switcher, column and connection pickers). Pressing Escape clears the search text first; a second Escape closes the sheet. (#1490) - Running `EXPLAIN` or `EXPLAIN ANALYZE` typed in the editor now opens the plan viewer instead of squashing the plan into one truncated grid cell. (#1480) - Filtering the data grid keeps you on the keyboard. Applying or clearing a filter returns focus to the grid so you can keep moving through cells, Return applies the filter, and Escape closes the filter panel and returns to the grid. (#1490) diff --git a/TablePro/Views/Components/SQLReviewSheet.swift b/TablePro/Views/Components/SQLReviewSheet.swift index 62aaa2cc3..4e1bc09e0 100644 --- a/TablePro/Views/Components/SQLReviewSheet.swift +++ b/TablePro/Views/Components/SQLReviewSheet.swift @@ -55,6 +55,7 @@ struct SQLReviewSheet: View { } .frame(width: 560, height: 460) .background(Color(nsColor: .windowBackgroundColor)) + .onExitCommand { dismiss() } .task { await prepare() } } diff --git a/TablePro/Views/Settings/LicenseActivationSheet.swift b/TablePro/Views/Settings/LicenseActivationSheet.swift index 4cf7f5557..25be56923 100644 --- a/TablePro/Views/Settings/LicenseActivationSheet.swift +++ b/TablePro/Views/Settings/LicenseActivationSheet.swift @@ -13,6 +13,7 @@ struct LicenseActivationSheet: View { @State private var licenseKeyInput = "" @State private var isActivating = false @State private var errorMessage: String? + @FocusState private var keyFocused: Bool var body: some View { VStack(spacing: 0) { @@ -40,6 +41,7 @@ struct LicenseActivationSheet: View { .textFieldStyle(.roundedBorder) .disableAutocorrection(true) .multilineTextAlignment(.center) + .focused($keyFocused) .onSubmit { Task { await activate() } } if let errorMessage { @@ -79,6 +81,7 @@ struct LicenseActivationSheet: View { .padding(.bottom, 24) } .frame(width: 400) + .defaultFocus($keyFocused, true) } private func activate() async { diff --git a/TablePro/Views/Settings/Sections/MCPTokenRevealSheet.swift b/TablePro/Views/Settings/Sections/MCPTokenRevealSheet.swift index 3d640cfa0..430bd7501 100644 --- a/TablePro/Views/Settings/Sections/MCPTokenRevealSheet.swift +++ b/TablePro/Views/Settings/Sections/MCPTokenRevealSheet.swift @@ -11,6 +11,7 @@ struct MCPTokenRevealSheet: View { @State private var isTokenRevealed = false @State private var tokenCopied = false @State private var selectedClient: IntegrationClient = .claudeCode + @FocusState private var doneFocused: Bool var body: some View { VStack(spacing: 0) { @@ -29,10 +30,12 @@ struct MCPTokenRevealSheet: View { Spacer() Button(String(localized: "Done")) { dismiss() } .keyboardShortcut(.defaultAction) + .focused($doneFocused) } .padding() } .frame(minWidth: 540, minHeight: 520) + .defaultFocus($doneFocused, true) } private var warningBanner: some View {