Skip to content

Commit e81158f

Browse files
committed
fix: pin the sidebar only when necessary
1 parent bd6265b commit e81158f

File tree

1 file changed

+53
-4
lines changed

1 file changed

+53
-4
lines changed

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

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,57 @@ onMounted(() => {
5252
checkHeaderPosition()
5353
})
5454
55+
const windowSize = useWindowSize()
56+
const sidebar = useTemplateRef<HTMLDivElement>('sidebar')
57+
const sidebarContainer = useTemplateRef<HTMLDivElement>('container')
58+
const sidebarBounds = useElementBounding(sidebar)
59+
const scrollState = useWindowScroll()
60+
const scrollDirection = shallowRef<'up' | 'down'>('down')
61+
const sidebarOffset = shallowRef([0, 0])
62+
63+
const sidebarOverflow = computed(() => {
64+
return sidebarBounds.height.value > windowSize.height.value - 120
65+
})
66+
67+
const sidebarStyles = computed(() => {
68+
if (!sidebarOverflow.value) {
69+
return {
70+
alignSelf: 'flex-start',
71+
top: '80px',
72+
}
73+
}
74+
75+
if (scrollDirection.value === 'down') {
76+
return {
77+
alignSelf: 'flex-end',
78+
marginBlockStart: `${sidebarOffset.value[0]}px`,
79+
bottom: '40px',
80+
}
81+
}
82+
83+
if (scrollDirection.value === 'up') {
84+
return {
85+
alignSelf: 'flex-start',
86+
marginBlockEnd: `${sidebarOffset.value[1]}px`,
87+
top: '80px',
88+
}
89+
}
90+
})
91+
92+
watch(scrollState.directions, ({ bottom, top }) => {
93+
if (bottom) scrollDirection.value = 'down'
94+
if (top) scrollDirection.value = 'up'
95+
})
96+
97+
function checkSidebarPosition() {
98+
sidebarOffset.value = [
99+
sidebar.value!.offsetTop,
100+
sidebarContainer.value!.offsetHeight - sidebar.value!.offsetTop - sidebar.value!.offsetHeight,
101+
]
102+
}
103+
104+
useEventListener('scroll', checkSidebarPosition, { passive: true })
105+
55106
const { packageName, requestedVersion, orgName } = usePackageRoute()
56107
const selectedPM = useSelectedPackageManager()
57108
const activePmId = computed(() => selectedPM.value ?? 'npm')
@@ -1187,11 +1238,9 @@ onKeyStroke(
11871238
</div>
11881239
</section>
11891240
</section>
1190-
<div class="area-sidebar">
1241+
<div ref="container" class="area-sidebar relative flex">
11911242
<!-- Sidebar -->
1192-
<div
1193-
class="sidebar-scroll sticky top-34 space-y-6 sm:space-y-8 min-w-0 overflow-y-auto pe-2.5 lg:(max-h-[calc(100dvh-8.5rem)] overscroll-contain) xl:(top-22 pt-2 max-h-[calc(100dvh-6rem)])"
1194-
>
1243+
<div ref="sidebar" class="sticky w-full xl:(pt-2)" :style="sidebarStyles">
11951244
<!-- Team access controls (for scoped packages when connected) -->
11961245
<ClientOnly>
11971246
<PackageAccessControls :package-name="pkg.name" />

0 commit comments

Comments
 (0)