refactor(chat): migrate session keyboard shortcuts to @tanstack/react-hotkey

This commit is contained in:
ibelick
2026-02-15 10:50:16 +01:00
parent 02285796cb
commit ea44827903
3 changed files with 57 additions and 30 deletions
+1
View File
@@ -18,6 +18,7 @@
"@shikijs/langs": "^3.21.0",
"@shikijs/themes": "^3.21.0",
"@tailwindcss/vite": "^4.1.18",
"@tanstack/react-hotkeys": "^0.1.0",
"@tanstack/react-query": "^5.84.1",
"@tanstack/react-router": "^1.132.0",
"@tanstack/react-router-devtools": "^1.132.0",
@@ -1,4 +1,4 @@
import { useEffect } from 'react'
import { useHotkey } from '@tanstack/react-hotkeys'
type SessionShortcutOptions = {
onNewSession: () => void
@@ -9,37 +9,32 @@ function useSessionShortcuts({
onNewSession,
onSearchSessions,
}: SessionShortcutOptions) {
useEffect(() => {
function handleKeyDown(event: KeyboardEvent) {
if (event.defaultPrevented) return
if (event.altKey) return
if (!(event.metaKey || event.ctrlKey)) return
const target = event.target as HTMLElement | null
if (!target) return
const tag = target.tagName.toLowerCase()
if (
tag === 'input' ||
tag === 'textarea' ||
tag === 'select' ||
target.isContentEditable
) {
return
}
useHotkey(
'Mod+K',
function handleSearchHotkey(event) {
if (event.altKey || isEditableTarget(event.target)) return
event.preventDefault()
onSearchSessions()
},
{ preventDefault: true },
)
if (event.key.toLowerCase() === 'k' && !event.shiftKey) {
event.preventDefault()
onSearchSessions()
}
useHotkey(
'Mod+Shift+O',
function handleNewSessionHotkey(event) {
if (event.altKey || isEditableTarget(event.target)) return
event.preventDefault()
onNewSession()
},
{ preventDefault: true },
)
}
if (event.key.toLowerCase() === 'o' && event.shiftKey) {
event.preventDefault()
onNewSession()
}
}
window.addEventListener('keydown', handleKeyDown)
return () => window.removeEventListener('keydown', handleKeyDown)
}, [onNewSession, onSearchSessions])
function isEditableTarget(target: EventTarget | null): boolean {
if (!(target instanceof HTMLElement)) return false
const tag = target.tagName.toLowerCase()
if (tag === 'input' || tag === 'textarea' || tag === 'select') return true
return target.isContentEditable
}
export { useSessionShortcuts }
+31
View File
@@ -60,9 +60,18 @@ importers:
'@hugeicons/react':
specifier: ^1.1.4
version: 1.1.4(react@19.2.4)
'@shikijs/langs':
specifier: ^3.21.0
version: 3.22.0
'@shikijs/themes':
specifier: ^3.21.0
version: 3.22.0
'@tailwindcss/vite':
specifier: ^4.1.18
version: 4.1.18(vite@7.3.1(@types/node@22.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))
'@tanstack/react-hotkeys':
specifier: ^0.1.0
version: 0.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@tanstack/react-query':
specifier: ^5.84.1
version: 5.90.20(react@19.2.4)
@@ -1332,9 +1341,20 @@ packages:
resolution: {integrity: sha512-xyIfof8eHBuub1CkBnbKNKQXeRZC4dClhmzePHVOEel4G7lk/dW+TQ16da7CFdeNLv6u6Owf5VoBQxoo6DFTSA==}
engines: {node: '>=12'}
'@tanstack/hotkeys@0.1.0':
resolution: {integrity: sha512-2ypLO3C2vKxMbCjiOfA3RzDaUIUYsQtyLc+Qwl6oKzQvWxReGlQN7DOQZSeKyX9D395d3E65e2v7Fm14BzUGew==}
engines: {node: '>=18'}
'@tanstack/query-core@5.90.20':
resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==}
'@tanstack/react-hotkeys@0.1.0':
resolution: {integrity: sha512-Hteo+hdPKdR2G7uAwTmScu1JUHM/f03lVihxVfR/A3XMyVJmbzi4SJieRk/kLgYKeXFRGIUx/xSI3mHeVc6DbQ==}
engines: {node: '>=18'}
peerDependencies:
react: '>=16.8'
react-dom: '>=16.8'
'@tanstack/react-query@5.90.20':
resolution: {integrity: sha512-vXBxa+qeyveVO7OA0jX1z+DeyCA4JKnThKv411jd5SORpBKgkcVnYKCiBgECvADvniBX7tobwBmg01qq9JmMJw==}
peerDependencies:
@@ -4528,8 +4548,19 @@ snapshots:
'@tanstack/history@1.154.14': {}
'@tanstack/hotkeys@0.1.0':
dependencies:
'@tanstack/store': 0.8.0
'@tanstack/query-core@5.90.20': {}
'@tanstack/react-hotkeys@0.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies:
'@tanstack/hotkeys': 0.1.0
'@tanstack/react-store': 0.8.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
'@tanstack/react-query@5.90.20(react@19.2.4)':
dependencies:
'@tanstack/query-core': 5.90.20