From 6e34f7f900abbbf6c5379a2b4bce7c5408ecba4a Mon Sep 17 00:00:00 2001 From: Rkoester47 Date: Mon, 13 Apr 2026 20:41:35 -0400 Subject: [PATCH 1/4] added keyboard shortcuts --- src/app/App.tsx | 28 ++++++++++++++ src/shared/hooks/useKeyboardShortcuts.ts | 47 ++++++++++++++++++++++++ tsconfig.app.json | 1 + 3 files changed, 76 insertions(+) create mode 100644 src/shared/hooks/useKeyboardShortcuts.ts diff --git a/src/app/App.tsx b/src/app/App.tsx index c41d9de..29c597f 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -8,6 +8,7 @@ import { CreateEventModal } from '@/app/components/CreateEventModal' import { ExitOverlay } from '@/shared/components/ExitOverlay' import { useHorizontalWheelScroll } from '@/shared/hooks/useHorizontalWheelScroll' import { usePageTransition } from '@/shared/hooks/usePageTransition' +import { useKeyboardShortcuts } from '@/shared/hooks/useKeyboardShortcuts' import { HomeSection } from './sections/HomeSection' import { ProfileSection } from './sections/ProfileSection' @@ -54,6 +55,33 @@ export default function AppMain() { } } }, []) + + useKeyboardShortcuts({ + switchHome: () => { + const section = document.getElementById('home') + if (section) scrollSectionIntoView(section) + }, + + switchEvents: () => { + const section = document.getElementById('events') + if (section) scrollSectionIntoView(section) + }, + + switchOrgs: () => { + const section = document.getElementById('orgs') + if (section) scrollSectionIntoView(section) + }, + + switchProfile: () => { + const section = document.getElementById('profile') + if (section) scrollSectionIntoView(section) + }, + + openSearch: () => { + setSearchSessionKey((k) => k + 1) + setIsSearchOpen(true) + }, +}) const scrollSectionIntoView = (section: HTMLElement) => { const scroller = scrollerRef.current diff --git a/src/shared/hooks/useKeyboardShortcuts.ts b/src/shared/hooks/useKeyboardShortcuts.ts new file mode 100644 index 0000000..e0a358e --- /dev/null +++ b/src/shared/hooks/useKeyboardShortcuts.ts @@ -0,0 +1,47 @@ +import { useEffect } from 'react' + +type ShortcutHandlers = { + switchHome: () => void + switchEvents: () => void + switchOrgs: () => void + switchProfile: () => void + openSearch: () => void +} + +function isTypingInInput(target: EventTarget | null) { + if (!(target instanceof HTMLElement)) return false + + const tag = target.tagName.toLowerCase() + + return ( + tag === 'input' || + tag === 'textarea' || + target.isContentEditable + ) +} + +export function useKeyboardShortcuts(handlers: ShortcutHandlers) { + useEffect(() => { + const onKeyDown = (event: KeyboardEvent) => { + if (isTypingInInput(event.target)) return + + if (event.key === '/') { + event.preventDefault() + handlers.openSearch() + return + } + + // Naviigation shortcuts + if (event.key === 'h') handlers.switchHome() + if (event.key === 'e') handlers.switchEvents() + if (event.key === 'o') handlers.switchOrgs() + if (event.key === 'p') handlers.switchProfile() + } + + window.addEventListener('keydown', onKeyDown) + + return () => { + window.removeEventListener('keydown', onKeyDown) + } + }, [handlers]) +} diff --git a/tsconfig.app.json b/tsconfig.app.json index f0b1ae5..a37b076 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -24,6 +24,7 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true, "baseUrl": ".", + "ignoreDeprecations": "6.0", "paths": { "@/*": ["src/*"] } From f944c3d64931e81387e445c5f5b60ae64be6b8a8 Mon Sep 17 00:00:00 2001 From: Rkoester47 Date: Tue, 14 Apr 2026 21:43:25 -0400 Subject: [PATCH 2/4] Added shortcut documentation on hover --- src/app/components/AppTopNav.tsx | 2 +- src/shared/components/TopNav.tsx | 1 + src/shared/data/content.ts | 9 +++++---- src/shared/hooks/useKeyboardShortcuts.ts | 8 ++------ 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/app/components/AppTopNav.tsx b/src/app/components/AppTopNav.tsx index b93e0ae..f95978d 100644 --- a/src/app/components/AppTopNav.tsx +++ b/src/app/components/AppTopNav.tsx @@ -33,7 +33,7 @@ export function AppTopNav({ onOpenSearch }: AppTopNavProps) { className={styles.searchButton} onClick={onOpenSearch} aria-label="Open search" - title="Search" + title="Search (CTRL+k)" >