index/components/animations/AClientOnly.vue

98 lines
2.0 KiB
Vue

<script setup lang="ts">
import { useQuasar } from 'quasar'
import type { PropType } from 'vue'
type ModeOptions = 'in-out' | 'out-in' | 'default' | undefined
type RenderOptions =
| 'never'
| 'always'
| 'xs'
| 'sm'
| 'sm-down'
| 'sm-up'
| 'md'
| 'md-down'
| 'md-up'
| 'lg'
| 'lg-down'
| 'lg-up'
| 'xl'
| undefined
const quasar = useQuasar()
const props = defineProps({
fallback: {
type: String,
default: '',
},
render: {
type: String as PropType<RenderOptions>,
default: 'always',
},
appear: {
type: Boolean,
default: false,
},
mode: {
type: String as PropType<ModeOptions>,
default: 'out-in',
},
enter: {
type: String,
default: 'animate__fadeIn',
},
leave: {
type: String,
default: 'animate__fadeOut',
},
})
const render = computed(() => {
switch (props.render) {
case 'never':
return false
case 'always':
return true
case 'xs':
return quasar.screen.xs
case 'sm':
return quasar.screen.sm
case 'sm-down':
return quasar.screen.xs || quasar.screen.sm
case 'sm-up':
return !quasar.screen.xs
case 'md':
return quasar.screen.md
case 'md-down':
return !quasar.screen.lg && !quasar.screen.xl
case 'md-up':
return !quasar.screen.xs && !quasar.screen.sm
case 'lg':
return quasar.screen.lg
case 'lg-down':
return !quasar.screen.xl
case 'lg-up':
return quasar.screen.lg || quasar.screen.xl
case 'xl':
return quasar.screen.xl
default:
return false
}
})
</script>
<template>
<ClientOnly>
<template #fallback>{{ props.fallback }}</template>
<Transition
:appear="props.appear"
:mode="props.mode"
:enter-active-class="`animate__animated ${props.enter}`"
:leave-active-class="`animate__animated ${props.leave}`"
>
<slot v-if="(quasar.screen.width || quasar.screen.height) && render" />
</Transition>
</ClientOnly>
</template>