refactor(editor): Migrate TemplatesInfoCarousel.vue to composition API (#10919)

This commit is contained in:
Ricardo Espinoza 2024-09-23 07:52:40 -04:00 committed by GitHub
parent 39310c01fb
commit 6e0d9d2fd5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 89 additions and 97 deletions

View file

@ -1,114 +1,106 @@
<script lang="ts">
import { defineComponent } from 'vue';
import type { PropType } from 'vue';
<script setup lang="ts">
import { nextTick, onBeforeMount, onMounted, ref, watch } from 'vue';
import type { ITemplatesCollection } from '@/Interface';
import Card from '@/components/CollectionWorkflowCard.vue';
import TemplatesInfoCard from '@/components/TemplatesInfoCard.vue';
import { VueAgile } from 'vue-agile';
import type { VueAgile } from 'vue-agile';
type SliderRef = InstanceType<typeof VueAgile>;
export default defineComponent({
name: 'TemplatesInfoCarousel',
components: {
Card,
TemplatesInfoCard,
agile: VueAgile,
const props = withDefaults(
defineProps<{
collections: ITemplatesCollection[];
loading?: boolean;
showItemCount?: boolean;
showNavigation?: boolean;
cardsWidth?: string;
}>(),
{
showItemCount: true,
showNavigation: true,
cardsWidth: '240px',
loading: false,
},
props: {
collections: {
type: Array as PropType<ITemplatesCollection[]>,
required: true,
},
loading: {
type: Boolean,
},
showItemCount: {
type: Boolean,
default: true,
},
showNavigation: {
type: Boolean,
default: true,
},
cardsWidth: {
type: String,
default: '240px',
},
},
data() {
return {
carouselScrollPosition: 0,
cardWidth: parseInt(this.cardsWidth, 10),
sliderWidth: 0,
scrollEnd: false,
listElement: null as null | Element,
};
},
watch: {
collections() {
setTimeout(() => {
this.updateCarouselScroll();
}, 0);
},
loading() {
setTimeout(() => {
this.updateCarouselScroll();
}, 0);
},
},
async mounted() {
await this.$nextTick();
const sliderRef = this.$refs.slider as SliderRef | undefined;
if (!sliderRef) {
return;
}
);
this.listElement = sliderRef.$el.querySelector('.agile__list');
if (this.listElement) {
this.listElement.addEventListener('scroll', this.updateCarouselScroll);
}
},
beforeUnmount() {
const sliderRef = this.$refs.slider as SliderRef | undefined;
if (sliderRef) {
sliderRef.destroy();
}
const emit = defineEmits<{
openCollection: [payload: { event: MouseEvent; id: number }];
}>();
window.removeEventListener('scroll', this.updateCarouselScroll);
},
methods: {
updateCarouselScroll() {
if (this.listElement) {
this.carouselScrollPosition = Number(this.listElement.scrollLeft.toFixed());
const carouselScrollPosition = ref(0);
const cardWidth = ref(parseInt(props.cardsWidth, 10));
const scrollEnd = ref(false);
const listElement = ref<null | Element>(null);
const sliderRef = ref<null | SliderRef>(null);
const width = this.listElement.clientWidth;
const scrollWidth = this.listElement.scrollWidth;
const scrollLeft = this.carouselScrollPosition;
this.scrollEnd = scrollWidth - width <= scrollLeft + 7;
}
},
onCardClick(event: MouseEvent, id: number) {
this.$emit('openCollection', { event, id });
},
scrollLeft() {
if (this.listElement) {
this.listElement.scrollBy({ left: -(this.cardWidth * 2), top: 0, behavior: 'smooth' });
}
},
scrollRight() {
if (this.listElement) {
this.listElement.scrollBy({ left: this.cardWidth * 2, top: 0, behavior: 'smooth' });
}
},
const updateCarouselScroll = () => {
if (listElement.value) {
carouselScrollPosition.value = Number(listElement.value.scrollLeft.toFixed());
const width = listElement.value.clientWidth;
const scrollWidth = listElement.value.scrollWidth;
const scrollLeft = carouselScrollPosition.value;
scrollEnd.value = scrollWidth - width <= scrollLeft + 7;
}
};
const onCardClick = (event: MouseEvent, id: number) => {
emit('openCollection', { event, id });
};
const scrollLeft = () => {
if (listElement.value) {
listElement.value.scrollBy({ left: -(cardWidth.value * 2), top: 0, behavior: 'smooth' });
}
};
const scrollRight = () => {
if (listElement.value) {
listElement.value.scrollBy({ left: cardWidth.value * 2, top: 0, behavior: 'smooth' });
}
};
watch(
() => props.collections,
() => {
setTimeout(() => {
updateCarouselScroll();
}, 0);
},
);
watch(
() => props.loading,
() => {
setTimeout(() => {
updateCarouselScroll();
}, 0);
},
);
onMounted(async () => {
await nextTick();
if (!sliderRef.value) {
return;
}
listElement.value = sliderRef.value.$el.querySelector('.agile__list');
if (listElement.value) {
listElement.value.addEventListener('scroll', updateCarouselScroll);
}
});
onBeforeMount(() => {
if (sliderRef.value) {
sliderRef.value.destroy();
}
window.addEventListener('scroll', updateCarouselScroll);
});
</script>
<template>
<div v-show="loading || collections.length" :class="$style.container">
<agile
ref="slider"
ref="sliderRef"
:dots="false"
:nav-buttons="false"
:infinite="false"

View file

@ -160,13 +160,13 @@ export default defineComponent({
this.areCategoriesPrepopulated = true;
}
},
onOpenCollection({ event, id }: { event: MouseEvent; id: string }) {
onOpenCollection({ event, id }: { event: MouseEvent; id: number }) {
this.navigateTo(event, VIEWS.COLLECTION, id);
},
onOpenTemplate({ event, id }: { event: MouseEvent; id: string }) {
onOpenTemplate({ event, id }: { event: MouseEvent; id: number }) {
this.navigateTo(event, VIEWS.TEMPLATE, id);
},
navigateTo(e: MouseEvent, page: string, id: string) {
navigateTo(e: MouseEvent, page: string, id: number) {
if (e.metaKey || e.ctrlKey) {
const route = this.$router.resolve({ name: page, params: { id } });
window.open(route.href, '_blank');