129 lines
3.2 KiB
Vue
129 lines
3.2 KiB
Vue
<template>
|
|
<div ref="target" class="product">
|
|
<ProductImages v-if="isMobile" />
|
|
|
|
<div v-if="isMobile" class="product-info">
|
|
<div class="product-info__title">
|
|
<ProductPrice :price="currentVariant?.options[0]?.price || 0" />
|
|
|
|
<div>
|
|
фотомодель
|
|
</div>
|
|
</div>
|
|
|
|
<h1>
|
|
{{ productsData?.name }}
|
|
</h1>
|
|
|
|
<div class="mt20">
|
|
<UButton
|
|
icon="lucide:shopping-cart"
|
|
class="justify-content-center w-100 d-flex"
|
|
label="Добавить"
|
|
size="xl"
|
|
@click="open = !open"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<UDrawer
|
|
v-if="isMobile"
|
|
v-model:open="open"
|
|
class="product__drawer"
|
|
fixed
|
|
:ui="{
|
|
content: 'fixed bg-default ring ring-default flex focus:outline-none overflow-hidden',
|
|
container: 'w-full flex flex-col gap-4 p-4 overflow-hidden',
|
|
body: 'flex-1 overflow-y-auto',
|
|
}"
|
|
>
|
|
<template #content>
|
|
<div ref="targetDrawer" style="overflow-y: auto;">
|
|
<ProductDescription />
|
|
</div>
|
|
</template>
|
|
</UDrawer>
|
|
|
|
<ProductImages v-if="!isMobile" />
|
|
<ProductDescription v-if="!isMobile" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { UseSwipeDirection } from '@vueuse/core'
|
|
import { useMediaQuery, useScroll, useSwipe } from '@vueuse/core'
|
|
import { computed, shallowRef } from 'vue'
|
|
import ProductPrice from '~/components/ProductPrice.vue'
|
|
import { useCurrentProduct, useProduct } from '~/composables'
|
|
|
|
const { productsData } = useProduct()
|
|
const { currentVariant } = useCurrentProduct()
|
|
const isMobile = useMediaQuery('(max-width: 1280px)')
|
|
const open = ref(false)
|
|
const target = shallowRef<HTMLElement | null>(null)
|
|
const targetHeight = computed(() => target.value?.offsetHeight)
|
|
const targetDrawer = shallowRef<HTMLElement | null>(null)
|
|
const targetDrawerHeight = computed(() => targetDrawer.value?.offsetHeight)
|
|
const { y } = useScroll(targetDrawer)
|
|
|
|
const { lengthY } = useSwipe(
|
|
target,
|
|
{
|
|
passive: false,
|
|
onSwipeEnd(e: TouchEvent, direction: UseSwipeDirection) {
|
|
console.log('target.value', target.value)
|
|
if (lengthY.value > 50 && targetHeight.value && (Math.abs(lengthY.value) / targetHeight.value) >= 0.25) {
|
|
open.value = true
|
|
}
|
|
},
|
|
},
|
|
)
|
|
|
|
const { lengthY: drawerLengthY } = useSwipe(
|
|
targetDrawer,
|
|
{
|
|
passive: false,
|
|
onSwipeEnd(e: TouchEvent, direction: UseSwipeDirection) {
|
|
console.log('targetDrawer.value', targetDrawer.value)
|
|
if (drawerLengthY.value < 0 && y.value === 0 && targetDrawerHeight.value && (Math.abs(drawerLengthY.value) / targetDrawerHeight.value) >= 0.2) {
|
|
open.value = false
|
|
}
|
|
},
|
|
},
|
|
)
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
@use '~/assets/scss/utils' as *;
|
|
|
|
.product {
|
|
position: relative;
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: row;
|
|
|
|
@media (max-width: 768px) {
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
}
|
|
|
|
.product-info {
|
|
padding-inline: 15px;
|
|
position: absolute;
|
|
bottom: 40px;
|
|
z-index: 10;
|
|
width: 100vw;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
gap: 10px;
|
|
|
|
&__title {
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: space-between;
|
|
}
|
|
}
|
|
</style>
|