use IntersectionObserver to show scrolling
Deploy app frontend / app frontend (push) Successful in 1m57s
Deploy db-migrations / db-migrations (push) Successful in 58s
Deploy service message-delivery-method-web-push / service message-delivery-method-web-push (push) Successful in 1m26s
Deploy service tg-bot / service tg-bot (push) Successful in 1m27s

This commit is contained in:
2024-12-19 13:48:20 +02:00
parent 15861a8d59
commit 8d9baf8d7d
6 changed files with 69 additions and 27 deletions
+20 -24
View File
@@ -4,25 +4,26 @@
>
<!-- Shadow Top -->
<div
class="row-start-1 row-span-1 col-start-1 sm:row-start-2 relative w-full h-[1rem] bg-gradient-to-b from-black/30 sm:from-black/10 to-transparent dark:from-white/10 pointer-events-none transition-opacity duration-300"
:class="{ 'opacity-0': !showTopShadow, 'opacity-100': showTopShadow }"
class="transition-opacity opacity-0 row-start-1 row-span-1 col-start-1 sm:row-start-2 relative w-full h-[1rem] bg-gradient-to-b from-black/30 sm:from-black/10 to-transparent dark:from-white/10 pointer-events-none duration-300"
:class="{ 'opacity-100': !isTopOfContentVisible }"
/>
<!-- Content Section -->
<div
class="row-start-1 row-span-3 col-start-1 sm:row-start-2 overflow-hidden overflow-y-auto px-4 overscroll-contain touch-manipulation"
class="row-start-1 row-span-3 col-start-1 sm:row-start-2 overflow-hidden overflow-y-auto px-4 overscroll-contain touch-manipulation scrollbar scrollbar-w-1.5 scrollbar-thumb-gray-500/60 scrollbar-thumb-rounded-full"
ref="contentScrollContainer"
@scroll="handleScroll"
>
<div class="sm:max-w-prose grid grid-cols-1 mx-auto my-5 w-full">
<div ref="isTopOfContentRef" />
<slot name="default" v-bind:scrollToBottom />
<div ref="isBottomOfContentRef" />
</div>
</div>
<!-- Shadow Bottom -->
<div
class="row-start-3 row-span-1 col-start-1 sm:row-start-4 relative w-full h-[1rem] bg-gradient-to-t from-black/10 to-transparent dark:from-white/10 pointer-events-none transition-opacity duration-300"
:class="{ 'opacity-0': !showBottomShadow, 'opacity-100': showBottomShadow }"
class="transition-opacity opacity-0 row-start-3 row-span-1 col-start-1 sm:row-start-4 relative w-full h-[1rem] bg-gradient-to-t from-black/10 to-transparent dark:from-white/10 pointer-events-none duration-300"
:class="{ 'opacity-100': !isBottomOfContentVisible }"
/>
<!-- Footer Section -->
@@ -52,9 +53,6 @@
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { useTemplateRef } from 'vue'
const slots = defineSlots<{
default?: (slotBindings: { scrollToBottom: typeof scrollToBottom }) => void
footer?: () => void
@@ -62,8 +60,18 @@ const slots = defineSlots<{
const contentScrollContainerRef = useTemplateRef('contentScrollContainer')
const showTopShadow = ref(false)
const showBottomShadow = ref(false)
const isTopOfContentRef = useTemplateRef('isTopOfContentRef')
const isTopOfContentVisible = useElementVisibility(isTopOfContentRef, {
threshold: 1,
scrollTarget: contentScrollContainerRef,
})
const isBottomOfContentRef = useTemplateRef('isBottomOfContentRef')
const isBottomOfContentVisible = useElementVisibility(isBottomOfContentRef, {
threshold: 1,
scrollTarget: contentScrollContainerRef,
})
isTopOfContentVisible.value = true
isBottomOfContentVisible.value = true
const scrollToBottom = () => {
if (contentScrollContainerRef.value) {
@@ -71,17 +79,6 @@ const scrollToBottom = () => {
}
}
const handleScroll = () => {
const el = contentScrollContainerRef.value
if (!el) return
const hasScrollTop = el.scrollTop > 0
const hasScrollBottom = el.scrollTop + el.clientHeight < el.scrollHeight
showTopShadow.value = hasScrollTop
showBottomShadow.value = hasScrollBottom
}
// Устанавливаем корректную высоту при загрузке и изменении размера окна
const onresize = () => {
document.documentElement.style.setProperty(
@@ -133,8 +130,7 @@ onMounted(() => {
// visualViewport?.addEventListener('resize', onresize, { passive: true })
contentScrollContainerRef.value!.addEventListener('touchmove', preventScroll, { passive: false })
// Инициализируем отображение теней
handleScroll()
console.log('mounted')
})
onBeforeUnmount(() => {