Files
hereconnect/apps/frontend/src/layouts/LayoutWithTabs.vue
T

118 lines
3.6 KiB
Vue
Raw Normal View History

2024-12-06 21:20:27 +02:00
<template>
2024-12-07 22:37:32 +02:00
<div
class="grid h-full sm:grid-rows-[auto_1fr_auto] grid-rows-[1fr_auto_auto] overflow-hidden touch-none"
>
2024-12-08 11:06:31 +02:00
<!-- Content Section -->
2024-12-07 01:33:10 +02:00
<div
2024-12-07 23:18:32 +02:00
class="flex overflow-hidden overflow-y-auto pb-safe-or-4 sm:pt-safe px-4 overscroll-contain touch-manipulation"
2024-12-07 01:33:10 +02:00
ref="contentScrollContainer"
>
<div class="sm:max-w-prose grid grid-cols-1 mx-auto my-5 w-full">
<slot name="default" v-bind:scrollToBottom />
2024-12-06 22:34:49 +02:00
</div>
2024-12-06 21:20:27 +02:00
</div>
2024-12-08 11:06:31 +02:00
<!-- Footer Section -->
2024-12-06 21:20:27 +02:00
<slot name="footer">
<footer
v-if="!slots.footer"
2024-12-08 11:06:31 +02:00
class="bg-gray-100 dark:bg-gray-800 text-center py-1.5 border-t dark:border-gray-700 text-xs sm:text-base text-gray-700 dark:text-gray-300 sm:order-last sm:pb-safe-or-1.5"
2024-12-06 21:20:27 +02:00
>
<span class="text-nowrap">Сделайте НаСвязи удобнее.</span>
<span> </span>
<span class="text-nowrap">
Будем рады
2024-12-08 13:34:21 +02:00
<RouterLink
to="/donate"
2024-12-08 11:06:31 +02:00
class="underline underline-offset-2 text-primary-600 dark:text-primary-400"
>
вашей поддержке
2024-12-08 13:34:21 +02:00
</RouterLink>
2024-12-06 21:20:27 +02:00
</span>
</footer>
</slot>
2024-12-08 11:06:31 +02:00
<!-- TabBar -->
2024-12-06 21:20:27 +02:00
<TabBar />
</div>
</template>
<script setup lang="ts">
2024-12-07 01:33:10 +02:00
import { useTemplateRef } from 'vue'
2024-12-06 21:20:27 +02:00
const slots = defineSlots<{
2024-12-07 01:33:10 +02:00
default?: (slotBindings: { scrollToBottom: typeof scrollToBottom }) => void
2024-12-06 21:20:27 +02:00
footer?: () => void
}>()
2024-12-07 01:33:10 +02:00
const contentScrollContainerRef = useTemplateRef('contentScrollContainer')
const scrollToBottom = () => {
if (contentScrollContainerRef.value) {
contentScrollContainerRef.value.scrollTop = contentScrollContainerRef.value.scrollHeight
}
}
2024-12-07 22:37:32 +02:00
// Устанавливаем корректную высоту при загрузке и изменении размера окна
const onresize = () => {
document.documentElement.style.setProperty(
'--visual-viewport-offset-top',
`${visualViewport!.offsetTop!}px`,
)
document.documentElement.style.setProperty(
'--visual-viewport-height',
`${visualViewport!.height}px`,
)
if (document.activeElement) {
if ('scrollIntoViewIfNeeded' in document.activeElement) {
;(document.activeElement.scrollIntoViewIfNeeded as (options?: ScrollIntoViewOptions) => void)(
{
block: 'center',
},
)
} else {
document.activeElement.scrollIntoView({ block: 'center' })
}
}
}
2024-12-07 23:18:32 +02:00
function preventScroll(e: TouchEvent) {
if (
contentScrollContainerRef.value &&
contentScrollContainerRef.value.scrollHeight <= contentScrollContainerRef.value.clientHeight
) {
e.preventDefault()
}
}
2024-12-07 22:37:32 +02:00
2024-12-06 22:34:49 +02:00
const layoutPageHead = useHead({
2024-12-07 22:37:32 +02:00
htmlAttrs: { class: 'overflow-hidden overscroll-none touch-none fix-layout-scrolling' },
bodyAttrs: { class: 'overflow-hidden overscroll-none touch-none' },
2024-12-06 22:34:49 +02:00
})
2024-12-07 23:18:32 +02:00
onMounted(() => {
visualViewport?.addEventListener('resize', onresize, { passive: true })
contentScrollContainerRef.value!.addEventListener('touchmove', preventScroll, { passive: false })
})
2024-12-07 22:37:32 +02:00
onBeforeUnmount(() => {
layoutPageHead?.dispose()
2024-12-07 23:18:32 +02:00
visualViewport?.removeEventListener('resize', onresize)
2024-12-07 22:37:32 +02:00
document.documentElement.style.removeProperty('--visual-viewport-offset-top')
document.documentElement.style.removeProperty('--visual-viewport-height')
2024-12-07 23:18:32 +02:00
contentScrollContainerRef.value!.removeEventListener('touchmove', preventScroll)
2024-12-07 22:37:32 +02:00
})
2024-12-06 22:34:49 +02:00
</script>
2024-12-07 22:37:32 +02:00
<style scoped>
::v-global(html.fix-layout-scrolling) {
--visual-viewport-height: 100dvh;
--visual-viewport-offset-top: 0px;
position: fixed;
width: 100dvw;
height: var(--visual-viewport-height);
top: var(--visual-viewport-offset-top);
bottom: 0;
}
</style>