Make sticky card functional
This commit is contained in:
@@ -1,10 +1,27 @@
|
||||
<script lang="ts" setup>
|
||||
|
||||
// import
|
||||
|
||||
import useGetProduct from "~/composables/api/product/useGetProduct";
|
||||
import type { ProductVariantProvideType } from "~/pages/product/[id].vue";
|
||||
|
||||
// types
|
||||
|
||||
type Props = {
|
||||
showChatButton: boolean;
|
||||
};
|
||||
|
||||
// props
|
||||
|
||||
defineProps<Props>();
|
||||
|
||||
// emits
|
||||
|
||||
const emit = defineEmits(["update:showChatButton"]);
|
||||
|
||||
// provide / inject
|
||||
|
||||
const { selectedVariant } = inject("productVariant") as ProductVariantProvideType;
|
||||
|
||||
// state
|
||||
|
||||
const route = useRoute();
|
||||
@@ -12,12 +29,32 @@ const id = route.params.id as string | undefined;
|
||||
|
||||
const { data: product } = useGetProduct(id);
|
||||
|
||||
const { selectedVariant } = inject("productVariant") as ProductVariantProvideType;
|
||||
const videoSectionEl = useTemplateRef<HTMLDivElement>("videoSectionEl");
|
||||
|
||||
const { bottom: videoSectionBottomBounding, height: videoSectionHeightBounding } = useElementBounding(videoSectionEl);
|
||||
const isVideoSectionVisible = useElementVisibility(videoSectionEl, {
|
||||
rootMargin: "0px 0px -20% 0px",
|
||||
});
|
||||
|
||||
// computed
|
||||
|
||||
const isVideoSectionHittingBottom = computed(() => {
|
||||
return videoSectionBottomBounding.value < videoSectionHeightBounding.value - 100;
|
||||
});
|
||||
|
||||
// watch
|
||||
|
||||
watch([isVideoSectionVisible, isVideoSectionHittingBottom], ([isVideoSectionVisible, isVideoSectionHittingBottom]) => {
|
||||
emit("update:showChatButton", !(isVideoSectionVisible && !isVideoSectionHittingBottom));
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section v-if="selectedVariant?.video" class="h-[110svh] w-full relative bg-black mt-[5rem]">
|
||||
<section
|
||||
v-if="selectedVariant?.video"
|
||||
ref="videoSectionEl"
|
||||
class="h-[110svh] w-full relative bg-black mt-[5rem]"
|
||||
>
|
||||
<video
|
||||
:src="selectedVariant.video"
|
||||
class="object-cover absolute size-full"
|
||||
@@ -28,14 +65,22 @@ const { selectedVariant } = inject("productVariant") as ProductVariantProvideTyp
|
||||
loop
|
||||
/>
|
||||
<div class="size-full absolute inset-0 bg-black/20" />
|
||||
<div class="absolute max-sm:flex items-center justify-center max-sm:px-5 sm:right-10 bottom-10 w-full">
|
||||
<StickyCard
|
||||
:color="selectedVariant.color!"
|
||||
:price="selectedVariant.price"
|
||||
:picture="selectedVariant.images[0].image"
|
||||
:title="product!.name"
|
||||
class="max-sm:!w-full"
|
||||
/>
|
||||
</div>
|
||||
<Transition
|
||||
name="fade"
|
||||
:duration="150"
|
||||
>
|
||||
<div
|
||||
v-if="isVideoSectionVisible && !isVideoSectionHittingBottom"
|
||||
class="fixed max-sm:flex max-sm:w-full items-center justify-center max-sm:px-5 sm:right-10 bottom-10 h-fit w-fit"
|
||||
>
|
||||
<StickyCard
|
||||
:color="selectedVariant.color!"
|
||||
:price="selectedVariant.price"
|
||||
:picture="selectedVariant.images[0].image"
|
||||
:title="product!.name"
|
||||
class="max-sm:!w-full"
|
||||
/>
|
||||
</div>
|
||||
</Transition>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user