From e9158390c1ab712b8c066938fd52de37a3663d34 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Wed, 13 May 2026 17:51:20 +0800 Subject: [PATCH] feat(shortcuts): add search focus shortcut --- src/App.vue | 14 +++++++++- src/components/grid/DataGrid.vue | 16 ++++++++++-- src/components/layout/AppSidebar.vue | 10 ++++++- src/components/layout/ContentArea.vue | 19 +++++++++++++- src/components/objects/ObjectBrowser.vue | 32 +++++++++++++++++++++-- src/components/redis/RedisKeyBrowser.vue | 32 +++++++++++++++++++++-- src/components/sidebar/ConnectionTree.vue | 20 ++++++++++++++ src/lib/keyboardShortcuts.ts | 12 +++++++++ tests/keyboardShortcuts.test.ts | 31 +++++++++++++++++++++- 9 files changed, 176 insertions(+), 10 deletions(-) diff --git a/src/App.vue b/src/App.vue index 3272c71401..670f140feb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -34,7 +34,7 @@ import * as api from "@/lib/api"; import { resolveDefaultDatabase } from "@/lib/defaultDatabase"; import { resolveExecutableSql } from "@/lib/sqlExecutionTarget"; import { isTauriRuntime } from "@/lib/tauriRuntime"; -import { isCloseTabShortcut, isExecuteSqlShortcut } from "@/lib/keyboardShortcuts"; +import { isCloseTabShortcut, isExecuteSqlShortcut, isFocusSearchShortcut } from "@/lib/keyboardShortcuts"; import { isPreviewTab } from "@/lib/tabPresentation"; import { SQL_FILE_UNSUPPORTED_TYPES } from "@/lib/databaseCapabilities"; import { classifyAiSqlExecution } from "@/lib/aiSqlExecutionPolicy"; @@ -80,6 +80,8 @@ const showAiPanel = ref(localStorage.getItem("dbx-ai-panel-open") !== "false"); const { sidebarWidth, aiPanelWidth, historyWidth, startSidebarResize, startAiPanelResize, startHistoryResize } = usePanelResize(); const aiAssistantRef = ref | null>(null); +const appSidebarRef = ref | null>(null); +const contentAreaRef = ref | null>(null); const selectedSql = ref(""); const cursorPos = ref(0); @@ -409,6 +411,14 @@ function onAiRequestAutoExecuteSql(sql: string) { } function handleKeydown(e: KeyboardEvent) { + if (isFocusSearchShortcut(e)) { + const focused = contentAreaRef.value?.focusSearch() || appSidebarRef.value?.focusSearch(); + if (focused) { + e.preventDefault(); + e.stopPropagation(); + } + return; + } if (isCloseTabShortcut(e)) { e.preventDefault(); if (showDriverStore.value) { @@ -574,6 +584,7 @@ onUnmounted(() => { " > { @clear-default-database="clearActiveDefaultDatabase" /> = { "'": "'", '"': '"', "(": ")" }; function onSearchKeydown(e: KeyboardEvent) { @@ -503,7 +513,7 @@ function onSearchKeydown(e: KeyboardEvent) { acceptSuggestion(); return; } - if (e.key === "Escape") { + if (isCancelSearchShortcut(e)) { e.preventDefault(); dismissSuggestions(); return; @@ -519,7 +529,8 @@ function onSearchKeydown(e: KeyboardEvent) { return; } } - if (e.key === "Escape") { + if (isCancelSearchShortcut(e)) { + e.preventDefault(); searchText.value = ""; } } @@ -1742,6 +1753,7 @@ defineExpose({ onToolbarRollback, showDdl, toggleDdl, + focusSearch, }); diff --git a/src/components/layout/AppSidebar.vue b/src/components/layout/AppSidebar.vue index 0cbff9faa8..94e6bbd84f 100644 --- a/src/components/layout/AppSidebar.vue +++ b/src/components/layout/AppSidebar.vue @@ -1,4 +1,5 @@