Skip to content

Commit 6d811f6

Browse files
committed
feat: merge package mobile top action into bottom bar
1 parent 8eab73f commit 6d811f6

File tree

3 files changed

+34
-13
lines changed

3 files changed

+34
-13
lines changed

app/components/ScrollToTop.client.vue

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,26 @@ const route = useRoute()
33
44
// Pages where scroll-to-top should NOT be shown
55
const excludedRoutes = new Set(['index', 'code'])
6+
const isPackagePage = computed(() => route.path.includes('/package/'))
67
7-
const isActive = computed(() => !excludedRoutes.has(route.name as string))
8+
const isActive = computed(() => !excludedRoutes.has(route.name as string) && !isPackagePage.value)
89
910
const SCROLL_TO_TOP_DURATION = 500
1011
1112
const isMounted = useMounted()
12-
const isTouchDeviceClient = shallowRef(false)
13-
const scrollThreshold = 300
13+
const { scrollToTop, isTouchDeviceClient } = useScrollToTop({ duration: SCROLL_TO_TOP_DURATION })
14+
1415
const { y: scrollTop } = useScroll(window)
1516
const isVisible = computed(() => {
1617
if (supportsScrollStateQueries.value) return false
17-
return scrollTop.value > scrollThreshold
18+
return scrollTop.value > SCROLL_TO_TOP_THRESHOLD
1819
})
1920
const { isSupported: supportsScrollStateQueries } = useCssSupports(
2021
'container-type',
2122
'scroll-state',
2223
{ ssrValue: false },
2324
)
2425
const shouldShowButton = computed(() => isActive.value && isTouchDeviceClient.value)
25-
26-
const { scrollToTop } = useScrollToTop({ duration: SCROLL_TO_TOP_DURATION })
27-
28-
onMounted(() => {
29-
isTouchDeviceClient.value = isTouchDevice()
30-
})
3126
</script>
3227

3328
<template>

app/composables/useScrollToTop.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ interface UseScrollToTopOptions {
88
// Easing function for the scroll animation
99
const easeOutQuad = (t: number) => t * (2 - t)
1010

11+
export const SCROLL_TO_TOP_THRESHOLD = 300
12+
1113
/**
1214
* Scroll to the top of the page with a smooth animation.
1315
* @param options - Configuration options for the scroll animation.
@@ -86,8 +88,14 @@ export function useScrollToTop(options: UseScrollToTopOptions) {
8688

8789
tryOnScopeDispose(cancel)
8890

91+
const isTouchDeviceClient = shallowRef(false)
92+
onMounted(() => {
93+
isTouchDeviceClient.value = isTouchDevice()
94+
})
95+
8996
return {
9097
scrollToTop,
9198
cancel,
99+
isTouchDeviceClient,
92100
}
93101
}

app/pages/package/[[org]]/[name].vue

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,13 @@ const { copied: copiedVersion, copy: copyVersion } = useClipboard({
250250
copiedDuring: 2000,
251251
})
252252
253+
const { scrollToTop, isTouchDeviceClient } = useScrollToTop({ duration: 500 })
254+
255+
const { y: scrollY } = useScroll(window)
256+
const showScrollToTop = computed(
257+
() => isTouchDeviceClient.value && scrollY.value > SCROLL_TO_TOP_THRESHOLD,
258+
)
259+
253260
// Fetch dependency analysis (lazy, client-side)
254261
// This is the same composable used by PackageVulnerabilityTree and PackageDeprecatedTree
255262
const { data: vulnTree, status: vulnTreeStatus } = useDependencyAnalysis(
@@ -785,26 +792,37 @@ const showSkeleton = shallowRef(false)
785792
:to="docsLink"
786793
aria-keyshortcuts="d"
787794
classicon="i-lucide:file-text"
795+
:title="$t('package.links.docs')"
788796
>
789-
{{ $t('package.links.docs') }}
797+
<span class="max-sm:sr-only">{{ $t('package.links.docs') }}</span>
790798
</LinkBase>
791799
<LinkBase
792800
v-if="codeLink"
793801
variant="button-secondary"
794802
:to="codeLink"
795803
aria-keyshortcuts="."
796804
classicon="i-lucide:code"
805+
:title="$t('package.links.code')"
797806
>
798-
{{ $t('package.links.code') }}
807+
<span class="max-sm:sr-only">{{ $t('package.links.code') }}</span>
799808
</LinkBase>
800809
<LinkBase
801810
variant="button-secondary"
802811
:to="{ name: 'compare', query: { packages: pkg.name } }"
803812
aria-keyshortcuts="c"
804813
classicon="i-lucide:git-compare"
814+
:title="$t('package.links.compare')"
805815
>
806-
{{ $t('package.links.compare') }}
816+
<span class="max-sm:sr-only">{{ $t('package.links.compare') }}</span>
807817
</LinkBase>
818+
<ButtonBase
819+
v-if="showScrollToTop"
820+
variant="secondary"
821+
:title="$t('common.scroll_to_top')"
822+
:aria-label="$t('common.scroll_to_top')"
823+
@click="() => scrollToTop()"
824+
classicon="i-lucide:arrow-up"
825+
/>
808826
</ButtonGroup>
809827

810828
<!-- Package metrics -->

0 commit comments

Comments
 (0)