Refactor ViewportResponsiveWrapper to use defineComponent and simplify slot rendering logic.

This commit is contained in:
Jeppe Bundgaard
2026-03-18 13:10:49 +01:00
parent e53b751f81
commit dc130229b5
@@ -1,34 +1,29 @@
<script setup>
<script>
/**
* This element is used to create responsive displays.
* When a display does not have a slot, it should be empty.
*/
import { defineComponent } from 'vue'
import { useMediaQuery } from '@vueuse/core'
const getMatch = (q) => {
const getMatch = (query) => {
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return false
return window.matchMedia(q).matches
return window.matchMedia(query).matches
}
const isMobile = useMediaQuery('(max-width: 768px)', getMatch('(max-width: 768px)'))
const isTablet = useMediaQuery('(min-width: 769px) and (max-width: 1024px)', getMatch('(min-width: 769px) and (max-width: 1024px)'))
const isDesktop = useMediaQuery('(min-width: 1025px)', getMatch('(min-width: 1025px)'))
export default defineComponent({
name: 'ViewportResponsiveWrapper',
setup(_, { slots }) {
const isMobile = useMediaQuery('(max-width: 768px)', getMatch('(max-width: 768px)'))
const isTablet = useMediaQuery('(min-width: 769px) and (max-width: 1024px)', getMatch('(min-width: 769px) and (max-width: 1024px)'))
const isDesktop = useMediaQuery('(min-width: 1025px)', getMatch('(min-width: 1025px)'))
return () => {
if (isMobile.value && slots.mobile) return slots.mobile()
if (isTablet.value && slots.tablet) return slots.tablet()
if (isDesktop.value && slots.desktop) return slots.desktop()
return slots.default ? slots.default() : []
}
},
})
</script>
<template>
<template v-if="isMobile && $slots.mobile">
<slot name="mobile" v-if="$slots.mobile" />
</template>
<template v-else-if="isTablet && $slots.tablet">
<slot name="tablet" v-if="$slots.tablet" />
</template>
<template v-else-if="isDesktop && $slots.desktop">
<slot name="desktop" v-if="$slots.desktop" />
</template>
<template v-else>
<slot name="default" v-if="$slots.default" />
</template>
</template>
<style scoped>
</style>