From a2fbb86aa34fbd699fc9857e902569830e99cca6 Mon Sep 17 00:00:00 2001 From: jellydeck <91427591+jellydeck@users.noreply.github.com> Date: Sat, 31 Jan 2026 12:12:11 +0530 Subject: [PATCH 1/4] performant transition approach with data attribute Co-Authored-By: Nathan Knowler --- app/app.vue | 22 +++++++++++++++++----- app/assets/main.css | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/app/app.vue b/app/app.vue index 2e9d67ea24..3a171e86b1 100644 --- a/app/app.vue +++ b/app/app.vue @@ -10,6 +10,7 @@ const { locale, locales } = useI18n() initPreferencesOnPrehydrate() const isHomepage = computed(() => route.name === 'index') +const showKbdHints = ref(false) const localeMap = locales.value.reduce( (acc, l) => { @@ -21,8 +22,9 @@ const localeMap = locales.value.reduce( useHead({ htmlAttrs: { - lang: () => locale.value, - dir: () => localeMap[locale.value] ?? 'ltr', + 'lang': () => locale.value, + 'dir': () => localeMap[locale.value] ?? 'ltr', + 'data-kbd-hints': () => showKbdHints.value, }, titleTemplate: titleChunk => { return titleChunk ? titleChunk : 'npmx - Better npm Package Browser' @@ -40,9 +42,7 @@ function handleGlobalKeydown(e: KeyboardEvent) { const isEditableTarget = target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable - if (isEditableTarget) { - return - } + if (isEditableTarget) return if (e.key === '/') { e.preventDefault() @@ -59,10 +59,22 @@ function handleGlobalKeydown(e: KeyboardEvent) { router.push('/search') } + + if (e.key === '?') { + e.preventDefault() + showKbdHints.value = true + } +} + +function handleGlobalKeyup(e: KeyboardEvent) { + if (e.key === '?') { + showKbdHints.value = false + } } if (import.meta.client) { useEventListener(document, 'keydown', handleGlobalKeydown) + useEventListener(document, 'keyup', handleGlobalKeyup) } diff --git a/app/assets/main.css b/app/assets/main.css index 651f8ae587..40232fcbe6 100644 --- a/app/assets/main.css +++ b/app/assets/main.css @@ -553,6 +553,26 @@ input[type='search']::-webkit-search-results-decoration { animation: none; } +/* Keyboard shortcut highlight on "?" key press */ +kbd { + position: relative; +} + +kbd::before { + content: ''; + position: absolute; + inset: 0; + border-radius: inherit; + box-shadow: 0 0 4px 2px var(--accent); + opacity: 0; + transition: opacity 200ms ease-out; + pointer-events: none; +} + +html[data-kbd-hints='true'] kbd::before { + opacity: 1; +} + /* Customize the view transition animations for specific elements */ ::view-transition-old(search-box), ::view-transition-new(search-box), From fc8350d2389450643d83c2e70ddde9802f9dbd29 Mon Sep 17 00:00:00 2001 From: jellydeck <91427591+jellydeck@users.noreply.github.com> Date: Sat, 31 Jan 2026 13:55:55 +0530 Subject: [PATCH 2/4] updated comment --- app/app.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/app.vue b/app/app.vue index 3a171e86b1..e580b859f5 100644 --- a/app/app.vue +++ b/app/app.vue @@ -35,7 +35,9 @@ if (import.meta.server) { setJsonLd(createWebSiteSchema()) } -// Global keyboard shortcut: "/" focuses search or navigates to search page +// Global keyboard shortcut: +// "/" focuses search or navigates to search page +// "?" highlights keyboard shorcuts function handleGlobalKeydown(e: KeyboardEvent) { const target = e.target as HTMLElement From 9492de58828192c2afb85569b2079da178e0a5a3 Mon Sep 17 00:00:00 2001 From: jellydeck <91427591+jellydeck@users.noreply.github.com> Date: Sat, 31 Jan 2026 15:41:54 +0530 Subject: [PATCH 3/4] hide data-attribute on key release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Jens Rømer Hesselbjerg <26376491+jhroemer@users.noreply.github.com> --- app/app.vue | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/app.vue b/app/app.vue index e580b859f5..3b5a98b103 100644 --- a/app/app.vue +++ b/app/app.vue @@ -69,9 +69,7 @@ function handleGlobalKeydown(e: KeyboardEvent) { } function handleGlobalKeyup(e: KeyboardEvent) { - if (e.key === '?') { - showKbdHints.value = false - } + showKbdHints.value = false } if (import.meta.client) { From ca9f7af789e62b59f17eaf84a0b3b8e2875a6d0f Mon Sep 17 00:00:00 2001 From: Jaydip Sanghani <91427591+jellydeck@users.noreply.github.com> Date: Sat, 31 Jan 2026 17:23:30 +0530 Subject: [PATCH 4/4] use shallowRef Co-authored-by: Robin --- app/app.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/app.vue b/app/app.vue index 3b5a98b103..56cde20c6d 100644 --- a/app/app.vue +++ b/app/app.vue @@ -10,7 +10,7 @@ const { locale, locales } = useI18n() initPreferencesOnPrehydrate() const isHomepage = computed(() => route.name === 'index') -const showKbdHints = ref(false) +const showKbdHints = shallowRef(false) const localeMap = locales.value.reduce( (acc, l) => {