From 9d520258e5e533c08f19a727b08210b5cd13d223 Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Fri, 3 Apr 2026 20:11:21 +0100 Subject: [PATCH 1/5] chore: refactor header shortcuts Just a simplification since these are getting lengthy and repetitive already. --- app/components/Package/Header.vue | 72 +++++++++---------------------- 1 file changed, 20 insertions(+), 52 deletions(-) diff --git a/app/components/Package/Header.vue b/app/components/Package/Header.vue index 7cf6b4c8bc..ebc187e3ef 100644 --- a/app/components/Package/Header.vue +++ b/app/components/Package/Header.vue @@ -72,7 +72,6 @@ function hasProvenance(version: PackumentVersion | null): boolean { return !!(version.dist as { attestations?: unknown }).attestations } -const router = useRouter() // Docs URL: use our generated API docs const docsLink = computed(() => { if (!props.resolvedVersion) return null @@ -122,57 +121,26 @@ const diffLink = computed((): RouteLocationRaw | null => { const keyboardShortcuts = useKeyboardShortcuts() -onKeyStroke( - e => keyboardShortcuts.value && isKeyWithoutModifiers(e, '.') && !isEditableElement(e.target), - e => { - if (codeLink.value === null) return - e.preventDefault() - - navigateTo(codeLink.value) - }, - { dedupe: true }, -) - -onKeyStroke( - e => keyboardShortcuts.value && isKeyWithoutModifiers(e, 'm') && !isEditableElement(e.target), - e => { - if (mainLink.value === null) return - e.preventDefault() - - navigateTo(mainLink.value) - }, - { dedupe: true }, -) - -onKeyStroke( - e => keyboardShortcuts.value && isKeyWithoutModifiers(e, 'd') && !isEditableElement(e.target), - e => { - if (!docsLink.value) return - e.preventDefault() - navigateTo(docsLink.value) - }, - { dedupe: true }, -) - -onKeyStroke( - e => keyboardShortcuts.value && isKeyWithoutModifiers(e, 'c') && !isEditableElement(e.target), - e => { - if (!props.pkg) return - e.preventDefault() - router.push({ name: 'compare', query: { packages: props.pkg.name } }) - }, - { dedupe: true }, -) - -onKeyStroke( - e => keyboardShortcuts.value && isKeyWithoutModifiers(e, 'f') && !isEditableElement(e.target), - e => { - if (diffLink.value === null) return - e.preventDefault() - navigateTo(diffLink.value) - }, - { dedupe: true }, -) +const shortcuts: [string, () => RouteLocationRaw | null | false | undefined][] = [ + ['.', () => codeLink.value], + ['m', () => mainLink.value], + ['d', () => docsLink.value], + ['c', () => props.pkg && { name: 'compare' as const, query: { packages: props.pkg.name } }], + ['f', () => diffLink.value], +] + +for (const [key, getTarget] of shortcuts) { + onKeyStroke( + e => keyboardShortcuts.value && isKeyWithoutModifiers(e, key) && !isEditableElement(e.target), + e => { + const target = getTarget() + if (!target) return + e.preventDefault() + navigateTo(target) + }, + { dedupe: true }, + ) +} const fundingUrl = computed(() => { let funding = props.displayVersion?.funding From dc6195e1567e97718ad2aef201465ff39ead780d Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Fri, 3 Apr 2026 22:53:33 +0100 Subject: [PATCH 2/5] feat: try extract shortcuts --- app/app.vue | 2 ++ app/components/AppHeader.vue | 22 +++------------ app/components/Package/Header.vue | 31 +++++--------------- app/composables/useShortcuts.ts | 47 +++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 42 deletions(-) create mode 100644 app/composables/useShortcuts.ts diff --git a/app/app.vue b/app/app.vue index 5916e3e328..26c409c88f 100644 --- a/app/app.vue +++ b/app/app.vue @@ -50,6 +50,8 @@ if (import.meta.server) { const keyboardShortcuts = useKeyboardShortcuts() const { settings } = useSettings() +initKeyShortcuts() + onKeyDown( '/', e => { diff --git a/app/components/AppHeader.vue b/app/components/AppHeader.vue index 1ccfc31d40..3c9b520aff 100644 --- a/app/components/AppHeader.vue +++ b/app/components/AppHeader.vue @@ -1,10 +1,8 @@