Open plexus77 opened 2 years ago
So I found a better way to achieve the animation without using the transition component.
<template>
<div class="p-8">
<div class="flex">
<button class="px-2 py-4 mr-4 bg-blue-500 text-white" @click="toggle">
Toggle
</button>
<div>{{ show }}</div>
</div>
<div
v-if="show"
v-motion="'transition'"
:initial="{ opacity: 0, y: -200 }"
:enter="{ opacity: 1, y: 0, transition: { duration: 500 } }"
:leave="{ opacity: 0, y: -200, transition: { duration: 500 } }"
style="width: 200px; height: 200px"
class="m-6 bg-green-900"
>
</div>
</div>
</template>
<script setup>
import { useMotions } from '@vueuse/motion'
definePageMeta({
layout: 'empty'
});
const motions = useMotions()
const show = useState('show', () => false)
const toggle = () => {
if (show.value) {
motions.transition.leave(() => { show.value=false })
} else {
show.value=true
}
}
</script>
I had same problem that motions.transition.leave doesn't work onLeave at transition component.
I create a component "Motionable" as a workaround based on your comment:
Motionable.vue
<template>
<component :is="is" v-if="show || !leaved" v-motion="name">
<slot />
</component>
</template>
<script setup>
import { useMotions } from '@vueuse/motion'
const props = defineProps({
is: { type: [String, Object], default: 'div' },
name: { type: String, required: true },
show: { type: Boolean, default: true },
})
const motions = useMotions()
const leaved = ref(!props.show)
watch(
() => props.show,
async (newShow) => {
const motion = motions[props.name]
if (motion && motion.isAnimating.value) {
motion.stop('leave')
if (newShow) {
motion.apply('enter')
}
}
if (!newShow) {
leaved.value = false
motion.leave(() => {
leaved.value = true
})
}
}
)
</script>
usage
<Motionable
is="div"
name="transition1"
:show="show"
:initial="{
y: 300,
opacity: 0,
}"
:enter="{
y: 0,
opacity: 1,
}"
:leave="{
y: 300,
opacity: 0,
}"
>
hello, world
</Motionable>
yes same problem, nuxt 3
<script setup lang="ts">
import { useMotions } from '@vueuse/motion'
import { Teleport, toRefs } from 'vue'
const props = defineProps({
visible: { type: Boolean, default: false },
})
const emit = defineEmits(['update:visible', 'close'])
const { visible } = toRefs(props)
const leaveTransition = async () => {
const { windowTransition, overlayTransition } = useMotions()
await Promise.all([
overlayTransition.apply('leave'),
windowTransition.apply('leave'),
])
}
const close = async () => {
await leaveTransition()
emit('close')
emit('update:visible', false)
}
</script>
<template>
<Teleport to="#dialog-outlet">
<div v-if="visible" class="fixed z-[99999] h-screen w-screen">
<div
v-motion="'overlayTransition'"
:initial="{
opacity: 0,
}"
:enter="{
opacity: 1,
}"
:leave="{ opacity: 0 }"
class="fixed inset-0 bg-gray-500 bg-opacity-10 backdrop-blur-[3px] transition-opacity"
/>
<div class="fixed inset-0 z-10 overflow-y-auto">
<div
class="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0"
>
<div
v-motion="'windowTransition'"
:initial="{
opacity: 0,
scale: 0,
}"
:enter="{
opacity: 1,
scale: 1,
transition: {
type: 'keyframes',
duration: 50,
},
}"
:leave="{
scale: 0.5,
opacity: 0,
transition: {
duration: 100,
type: 'keyframes',
ease: 'easeInOut',
},
}"
:delay="100"
class="relative w-full transform overflow-hidden rounded-lg bg-white dark:bg-dark-400 px-4 pt-5 pb-4 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-sm sm:p-6"
>
<div>
<div class="text-left">
<h3 id="modal-title" class="text-lg font-medium leading-6">
Change Color Site
</h3>
<slot />
</div>
</div>
<div class="mt-5 sm:mt-6">
<button
type="button"
class="inline-flex w-full justify-center rounded-md border border-transparent bg-red-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 sm:text-sm"
@click="close"
>
Go back to
</button>
</div>
</div>
</div>
</div>
</div>
</Teleport>
</template>
can confirm.. (nuxt 3.13.2)
I am trying to implement a leave transition using the transition element like in your demo so that I can show and hide an element with nice transitions
I'm using Nuxt 3.0.0-rc.10 and @vueuse/motion 2.0.0-beta.22
Here is a simple example below.
If I remove the element then it works as expected with the div animating in when I click show and then disappearing instantly by clicking hide.
I can't see what I am doing wrong here, if there is a bug or perhaps incompatability with the version I am using.