Skip to content
Open
Show file tree
Hide file tree
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
5 changes: 4 additions & 1 deletion app/components/pages/home/FeaturedTags.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,13 @@
if (isExternalHref(path)) return path
return localePath(path)
}

const featuredTagsRef = ref<HTMLElement | null>(null)
useHorizontalScroll(featuredTagsRef)
</script>

<template>
<ol class="scrollbar-hide grid grid-flow-col gap-4 overflow-x-auto">
<ol ref="featuredTagsRef" class="scrollbar-hide grid grid-flow-col gap-4 overflow-x-auto">
<template
v-for="(tag, index) in preselectedTags"
:key="tag.name"
Expand Down
5 changes: 4 additions & 1 deletion app/components/pages/posts/navigation/search/SearchMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@
throw new Error(`Unknown filter type: ${type}`)
}
}

const scrollContainerRef = ref<HTMLElement | null>(null)
useHorizontalScroll(scrollContainerRef)
</script>

<template>
Expand Down Expand Up @@ -347,7 +350,7 @@
</HeadlessCombobox>

<!-- Filters -->
<section class="-mx-5 mt-8 scrollbar-hide flex gap-4 overflow-x-auto py-1 pr-3 before:w-1 after:w-1">
<section ref="scrollContainerRef" class="-mx-5 mt-8 scrollbar-hide flex gap-4 overflow-x-auto py-1 pr-3 before:w-1 after:w-1">
<!-- -->

<!-- Tag Collections Toggler -->
Expand Down
44 changes: 44 additions & 0 deletions app/composables/useHorizontalScroll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useEventListener } from '@vueuse/core'

export function useHorizontalScroll(elRef: Ref<HTMLElement | null>) {
let isDown = false
let startX = 0
let scrollLeft = 0

useEventListener(elRef, 'mousedown', (e: MouseEvent) => {
if (!elRef.value) return
isDown = true
elRef.value.classList.add('cursor-grabbing')
elRef.value.classList.remove('cursor-grab')
startX = e.pageX - elRef.value.offsetLeft
scrollLeft = elRef.value.scrollLeft
})

useEventListener(elRef, 'mouseleave', () => {
if (!elRef.value) return
isDown = false
elRef.value.classList.remove('cursor-grabbing')
elRef.value.classList.add('cursor-grab')
})

useEventListener(elRef, 'mouseup', () => {
if (!elRef.value) return
isDown = false
elRef.value.classList.remove('cursor-grabbing')
elRef.value.classList.add('cursor-grab')
})

useEventListener(elRef, 'mousemove', (e: MouseEvent) => {
if (!isDown || !elRef.value) return
e.preventDefault()
const x = e.pageX - elRef.value.offsetLeft
const walk = (x - startX) * 2 // Scroll-fast
elRef.value.scrollLeft = scrollLeft - walk
})

onMounted(() => {
if (elRef.value) {
elRef.value.classList.add('cursor-grab')
}
})
}