Open iyume opened 5 months ago
@iyume That happens because the of the v-if
, which causes the component to be unmounted. if you use a v-show
instead the text will fade as well . If you want the component to unmount after the transition you can do something like this.
<script setup lang="ts">
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/shadcn/components/ui/select";
import { ref } from 'vue';
const isMounted = ref(false);
const fold = ref(false);
const selected = ref();
</script>
<template>
<button @click="fold = !fold">Action</button>
<Transition enter-from-class="opacity-0" enter-active-class="transition-opacity duration-1000"
enter-to-class="opacity-100" leave-from-class="opacity-100" leave-active-class="transition-opacity duration-1000"
leave-to-class="opacity-0" @enter="isMounted = true" @leave="isMounted = false">
<div v-show="!fold" v-if='!isMounted'>
<Select v-model="selected">
<SelectTrigger class="w-[180px]">
<SelectValue placeholder="Select a fruit" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
<SelectItem value="apple"> Apple </SelectItem>
<SelectItem value="banana"> Banana </SelectItem>
<SelectItem value="blueberry"> Blueberry </SelectItem>
<SelectItem value="grapes"> Grapes </SelectItem>
<SelectItem value="pineapple"> Pineapple </SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
</Transition>
</template>
@stripedpurple I tried your code snippet, but it looks strange.
Promise.then(异步)
queueFlush @ chunk-SV7XBIS2.js?v=84e1f9c6:1775
queueJob @ chunk-SV7XBIS2.js?v=84e1f9c6:1769
(匿名) @ chunk-SV7XBIS2.js?v=84e1f9c6:7580
resetScheduling @ chunk-SV7XBIS2.js?v=84e1f9c6:513
triggerEffects @ chunk-SV7XBIS2.js?v=84e1f9c6:557
triggerRefValue @ chunk-SV7XBIS2.js?v=84e1f9c6:1317
set value @ chunk-SV7XBIS2.js?v=84e1f9c6:1362
set @ chunk-SV7XBIS2.js?v=84e1f9c6:1380
_createElementVNode.onClick._cache.<computed>._cache.<computed> @ app.vue:21
callWithErrorHandling @ chunk-SV7XBIS2.js?v=84e1f9c6:1660
callWithAsyncErrorHandling @ chunk-SV7XBIS2.js?v=84e1f9c6:1667
invoker @ chunk-SV7XBIS2.js?v=84e1f9c6:10287
Uncaught (in promise) Maximum recursive updates exceeded in component <BaseTransition>. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.
@iyume ,perhaps this issus is caused by radix-vue,I tried to combine your code with the code for the Select component in the radix-vue official doc,but I made a lot of simplifications,then encountered the same problem as you. here is my code:
<script setup lang="ts">
import { ref } from 'vue'
import {
SelectContent,
SelectItem,
SelectItemText,
SelectRoot,
SelectTrigger,
SelectValue,
} from 'radix-vue'
const selected = ref()
const fold = ref(false)
</script>
<template>
<button @click="fold = !fold">Action</button>
<Transition>
<div v-if="!fold">
<SelectRoot v-model="selected">
<SelectTrigger>
<SelectValue placeholder="Select a fruit..." />
</SelectTrigger>
<SelectContent>
<SelectItem value="Apple">
<SelectItemText> Apple </SelectItemText>
</SelectItem>
</SelectContent>
</SelectRoot>
</div>
</Transition>
</template>
<style>
.v-enter-active,
.v-leave-active {
transition: opacity 1s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
</style>
https://github.com/radix-vue/shadcn-vue/assets/55320213/ee703a8a-fd85-4d30-b809-008cde71468b
Thanks to your solutions! Yes, it can only work with v-show
. I'm curious about why Transition
cannot "snapshot" the Select
's DOM. 🤔
Thanks to your solutions! Yes, it can only work with
v-show
. I'm curious about whyTransition
cannot "snapshot" theSelect
's DOM. 🤔
“I’m not sure either, but I guess it might be due to the way the source code is written in radix-vue? This is part of the code for SelectItemText.vue
:
<template>
<Primitive :id="itemContext.textId" :ref="forwardRef" v-bind="{ ...props, ...$attrs }">
<slot />
</Primitive>
<!-- Portal the select item text into the trigger value node -->
<Teleport
v-if="itemContext.isSelected.value && rootContext.valueElement.value && !rootContext.valueElementHasChildren.value" :to="rootContext.valueElement.value"
>
<slot />
</Teleport>
</template>
and i've written a piece of code here to mimic it:
<script setup lang="ts">
import { ref } from 'vue'
const isDisplay = ref(true)
const root = ref(null)
</script>
<template>
<div>
<button @click="isDisplay = !isDisplay">Show</button>
<Transition>
<div ref="root" v-if="isDisplay">
<p>hello</p>
</div>
</Transition>
<Teleport v-if="root" :to="root"> if </Teleport>
</div>
</template>
<style>
.v-enter-active,
.v-leave-active {
transition: opacity 2s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
</style>
here is the running effect:
https://github.com/radix-vue/shadcn-vue/assets/55320213/43a96006-7609-4328-bc5a-0292c0c51343
”
you can also replace <div ref="root" v-if="isDisplay">
to <div ref="root" v-show="isDisplay">
and then get such an effect:
https://github.com/radix-vue/shadcn-vue/assets/55320213/fe8f6917-8454-45f4-a87a-12db5b25bcc3
Thanks to your work! I point out the related issues here: https://github.com/vuejs/core/issues/5836 https://github.com/vuejs/core/pull/6548
Reproduction
Describe the bug
Select is not compatible with opacity transition component. The text disappear (not transparent) on entering opacity transition.
System Info
Contributes