Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 40 additions & 6 deletions app/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const { locale, locales } = useI18n()
initPreferencesOnPrehydrate()

const isHomepage = computed(() => route.name === 'index')
const showKbdHints = shallowRef(false)

const localeMap = locales.value.reduce(
(acc, l) => {
Expand All @@ -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'
Expand All @@ -33,16 +35,16 @@ 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 all keyboard shortcut elements
function handleGlobalKeydown(e: KeyboardEvent) {
const target = e.target as HTMLElement

const isEditableTarget =
target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable

if (isEditableTarget) {
return
}
if (isEditableTarget) return

if (e.key === '/') {
e.preventDefault()
Expand All @@ -59,10 +61,20 @@ function handleGlobalKeydown(e: KeyboardEvent) {

router.push('/search')
}

if (e.key === '?') {
e.preventDefault()
showKbdHints.value = true
}
}

function handleGlobalKeyup() {
showKbdHints.value = false
}

if (import.meta.client) {
useEventListener(document, 'keydown', handleGlobalKeydown)
useEventListener(document, 'keyup', handleGlobalKeyup)
}
</script>

Expand All @@ -82,3 +94,25 @@ if (import.meta.client) {
<ScrollToTop />
</div>
</template>

<style>
/* 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;
}
</style>
Loading