use PrimeVue carousel in place of custom one

This commit is contained in:
lightling 2025-01-29 18:29:48 -05:00
parent a89afae23c
commit 04463b3083
Signed by: lightling
GPG key ID: F1F29650D537C773
5 changed files with 140 additions and 56 deletions

View file

@ -11,6 +11,7 @@
"devDependencies": {
"@goldenwere/mackenzii-types": "*",
"@goldenwere/mackenzii-embeds": "*",
"@primevue/themes": "4.2.5",
"@types/dompurify": "3.2.0",
"@types/js-yaml": "4.0.9",
"@types/node": "22.12.0",
@ -24,6 +25,7 @@
"marked-highlight": "2.2.1",
"normalize.css": "8.0.1",
"pinia": "2.3.1",
"primevue": "4.2.5",
"pug": "3.0.3",
"rfdc": "1.4.1",
"sass": "1.83.4",

View file

@ -4,6 +4,7 @@ const hljs = import('highlight.js')
import type { HLJSApi } from 'highlight.js'
const marked = import('marked')
import { markedHighlight } from 'marked-highlight'
import PrimeVue from 'primevue/config'
import type { RoutedWindow, SiteGlobals } from '@goldenwere/mackenzii-types'
@ -43,7 +44,9 @@ export const createApp = ViteSSG(
window.router = router
}
app.use(createPinia())
app
.use(createPinia())
.use(PrimeVue, { theme: 'none' })
initializeRouteStore(routes, globals as unknown as SiteGlobals)
},
)

View file

@ -0,0 +1,35 @@
.p-carousel
display: flex
flex-direction: column
.p-carousel-content-container
display: flex
flex-direction: column
overflow: auto
.p-carousel-content
display: flex
flex-direction: row
gap: var(--p-carousel-content-gap)
.p-carousel-prev-button, .p-carousel-next-button
align-self: center
flex-shrink: 0
.p-carousel-viewport
width: 100%
overflow: hidden
.p-carousel-item-list
display: flex
flex-direction: row
.p-carousel-indicator-list
display: flex
flex-direction: row
justify-content: center
flex-wrap: wrap
padding: 1rem
gap: 1rem
margin: 0
list-style: none

View file

@ -1,5 +1,10 @@
<script setup lang="ts">
import { computed, onMounted, ref, watchEffect } from 'vue'
import {
computed,
onMounted,
ref,
} from 'vue'
import PrimeVueCarousel from 'primevue/carousel'
import { marked } from 'marked'
import type {
GalleryEntry,
@ -42,35 +47,15 @@ const fields = computed(() => {
return toReturn
})
const variants = computed(() => (resolved.value as GalleryEntryWithVariants).variants)
const variantsCount = computed(() => Object.keys((resolved.value as GalleryEntryWithVariants).variants).length)
const currentSelection = defineModel('currentSelection', { type: Number, default: 0 })
const currentUrl = computed(() => (resolved.value as GalleryEntryWithVariants).variants[currentSelection.value].url)
const currentAlt = computed(() => (resolved.value as GalleryEntryWithVariants).variants[currentSelection.value].alternativeText)
const currentCaption = computed(() => (resolved.value as GalleryEntryWithVariants).variants[currentSelection.value].caption)
const carousel = ref(null! as HTMLElement)
const onVariantSelected = (event: Event, id: number) => {
currentSelection.value = id
}
const onButtonClicked = (event: Event | null, direction: number, override?: number) => {
let val = Number(carousel.value.dataset.index!)
if (!!override) {
val = override
} else {
val += direction
}
if (val >= variantsCount.value) {
val = 0
} else if (val < 0) {
val = variantsCount.value - 1
}
const offset = (carousel.value.children[0] as HTMLImageElement).offsetWidth
carousel.value.style.transform = `translateX(-${offset * val}px)`
carousel.value.dataset.index = `${val}`
}
onMounted(async () => {
let config = await fetchAndParseConfig<ListWithEntries<GalleryEntry>>(routeConfig.config)
resolved.value = await fetchConfigByIdFromList(config, currentRoute.query.id as string)
@ -97,27 +82,21 @@ onMounted(async () => {
:title='currentCaption || currentAlt || description'
:alt='currentAlt || currentCaption || description'
)
.view-carousel
button.left(
@click='onButtonClicked($event, -1)'
)
span &lt;
.carousel(
ref='carousel'
data-index=0
PrimeVueCarousel(
:value='variants'
:numVisible='5'
:numScroll='5'
)
template(
#item='slotProps'
)
img(
v-for='(variant, id) in variants'
:class='{ active: id === currentSelection }'
:alt='variant.alternativeText || variant.caption || description'
:src='variant.thumbnailUrl || variant.url'
:title='variant.caption || id'
@click='onVariantSelected($event, id)'
:class='{ active: slotProps.index === currentSelection }'
:alt='slotProps.data.alternativeText || slotProps.data.caption || description'
:src='slotProps.data.thumbnailUrl || slotProps.data.url'
:title='slotProps.data.caption || slotProps.index'
@click='onVariantSelected($event, slotProps.index)'
)
button.right(
@click='onButtonClicked($event, 1)'
)
span &gt;
.view-content
p.title(
v-html='title'
@ -134,20 +113,6 @@ onMounted(async () => {
)
</template>
<style scoped lang="sass">
.view-carousel
position: relative
button
bottom: 0
position: absolute
top: 0
z-index: 1
&.left
left: 0
&.right
right: 0
.carousel
display: flex
img
cursor: pointer
<style lang="sass">
@import 'src/styles/components/carousel.sass'
</style>