Skip to content
Closed
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
43 changes: 43 additions & 0 deletions app/components/ScrollToTop.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<script setup lang="ts">
// Track scroll position
const showButton = ref(false)

// Show button after scrolling down 300px
function handleScroll() {
showButton.value = window.scrollY > 300
}

// Scroll to top smoothly
function scrollToTop() {
window.scrollTo({ top: 0, behavior: 'smooth' })
}

// Add/remove scroll listener
onMounted(() => {
window.addEventListener('scroll', handleScroll, { passive: true })
})

onUnmounted(() => {
window.removeEventListener('scroll', handleScroll)
})
</script>

<template>
<Transition
enter-active-class="transition-all duration-200"
enter-from-class="opacity-0 translate-y-2"
enter-to-class="opacity-100 translate-y-0"
leave-active-class="transition-all duration-200"
leave-from-class="opacity-100 translate-y-0"
leave-to-class="opacity-0 translate-y-2"
>
<button
v-if="showButton"
class="md:hidden fixed bottom-4 right-4 z-40 w-12 h-12 bg-bg-elevated border border-border rounded-full shadow-lg flex items-center justify-center text-fg-muted hover:text-fg transition-colors active:scale-98"
aria-label="Scroll to top"
@click="scrollToTop"
>
<span class="i-carbon-arrow-up w-5 h-5" />
</button>
</Transition>
</template>
3 changes: 3 additions & 0 deletions app/pages/[...package].vue
Original file line number Diff line number Diff line change
Expand Up @@ -759,5 +759,8 @@ defineOgImageComponent('Package', {
</p>
<NuxtLink to="/" class="btn"> Go back home </NuxtLink>
</div>

<!-- Scroll to top button (mobile only) -->
<ScrollToTop />
</main>
</template>