forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1<script setup lang="ts">
2const viewport = useWindowSize()
3const scroll = useWindowScroll()
4const container = useTemplateRef<HTMLDivElement>('container')
5const content = useTemplateRef<HTMLDivElement>('content')
6const bounds = useElementBounding(content)
7
8const active = computed(() => {
9 return bounds.height.value > viewport.height.value
10})
11
12const direction = computed((previous = 'up'): string => {
13 if (!active.value) return 'up'
14 return scroll.directions.bottom ? 'down' : scroll.directions.top ? 'up' : previous
15})
16
17const offset = computed(() => {
18 if (!active.value) return 0
19 if (!container.value) return 0
20 if (!content.value) return 0
21
22 return direction.value === 'down'
23 ? content.value.offsetTop
24 : container.value.offsetHeight - content.value.offsetTop - content.value.offsetHeight
25})
26
27const style = computed(() => {
28 return direction.value === 'down'
29 ? { paddingBlockStart: `${offset.value}px` }
30 : { paddingBlockEnd: `${offset.value}px` }
31})
32</script>
33
34<template>
35 <div
36 ref="container"
37 class="group relative data-[active=true]:flex"
38 :data-direction="direction"
39 :data-active="active"
40 :style="style"
41 >
42 <div
43 ref="content"
44 class="sticky w-full group-data-[direction=up]:(self-start top-30 xl:top-14) group-data-[direction=down]:(self-end bottom-8)"
45 >
46 <slot />
47 </div>
48 </div>
49</template>