Comments (18)
I've recreate my module from scratch and now it works well, thanks everyone for your help !
from radix-vue.
Related issue with Transition and Teleport (Portal)
no
from radix-vue.
Here is minimal repro :
https://stackblitz.com/edit/nuxt-starter-chghww
from radix-vue.
Okay, so there are a few things to consider to make it work:
- Upgrade to
[email protected]
because v1.6.1 had broken transitions (#801) - When using the
Transition
on theComboboxContent
, you don't actually needforceMount
. It should work just fine. - In the minimal repro, the animation classes are wrong. It should be
.fade-enter-from
but it just says.fade-enter
so enter animation doesn't work.
I got it working by updating Radix Vue to v1.6.2 and the file looking like this:
<template>
<div>
<ComboboxRoot v-model="selected">
<ComboboxAnchor>
<ComboboxTrigger>
<span v-if="selected.length === 0">{{ placeholder }}</span>
<span v-else>{{ selected }}</span>
<Icon name="radix-icons:caret-sort" />
</ComboboxTrigger>
</ComboboxAnchor>
<div>
<ComboboxPortal>
<Transition name="fade">
<ComboboxContent position="popper">
<ComboboxViewport class="flex flex-col">
<div>
<Icon name="radix-icons:magnifying-glass" />
<ComboboxInput
:placeholder="placeholder ? placeholder : 'Search...'"
/>
</div>
<ComboboxGroup>
<ComboboxItem
v-for="(option, item) of options"
:key="item"
:value="option"
>
<span>{{ option }}</span>
<ComboboxItemIndicator>
<Icon name="radix-icons:check" />
</ComboboxItemIndicator>
</ComboboxItem>
</ComboboxGroup>
<ComboboxEmpty />
</ComboboxViewport>
</ComboboxContent>
</Transition>
</ComboboxPortal>
</div>
</ComboboxRoot>
</div>
</template>
<script setup lang="ts">
const selected = ref("");
const placeholder = ref("Placeholder...");
const options = ref(["Nuxt", "Vue", "Svelte", "Tauri"]);
</script>
<style>
div[data-radix-popper-content-wrapper] {
top: 4px !important;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
</style>
Also, it might be irrelevant for this particular issue, but when you want to use the Radix Vue module for Nuxt, it should be:
- modules: ["radix-vue"]
+ modules: ["radix-vue/nuxt"]
from radix-vue.
That's very strange I will try to recreate a nuxt module project an retry to see if it works
from radix-vue.
Kinda related issue with Transition and Teleport (Portal) 😅
from radix-vue.
Hi @nethriis! Can you please try wrapping the Transition
on the ComboboxContent
instead of the ComboboxPortal
?
Usually the transition must be applied to the HTML element that will be animated, but in this case the ComboboxPortal
is a Teleport
so it doesn't render an actual HTML element.
I have done it like this and it does seem to be working.
from radix-vue.
@ChrisGV04 Thanks for your response I tried it and I receive the same error :
[Vue warn]: Component inside <Transition> renders non-element root node that cannot be animated.
at <PrimitiveSlot ref=Ref< undefined > class="border border-gray-300 rounded-md bg-white shadow-md w-[--radix-combobox-trigger-width] z-10" >
at <CollectionSlot class="border border-gray-300 rounded-md bg-white shadow-md w-[--radix-combobox-trigger-width] z-10" >
at <ComboboxContentImpl position="popper" onEscapeKeyDown=fn onPointerDownOutside=fn ... >
at <Presence present=true class="border border-gray-300 rounded-md bg-white shadow-md w-[--radix-combobox-trigger-width] z-10" >
at <ComboboxContent position="popper" class="border border-gray-300 rounded-md bg-white shadow-md w-[--radix-combobox-trigger-width] z-10" >
at <BaseTransition appear=false persisted=false mode=undefined ... >
at <Transition name="fade" >
at <Teleport disabled=false forceMount=true to=undefined >
at <ComboboxPortal forceMount="" >
at <Primitive ref=fn<s> style=
Object { pointerEvents: "auto" }
as=undefined ... >
at <PopperRoot class="w-[200px]" >
at <ComboboxRoot modelValue="" onUpdate:modelValue=fn class="w-[200px]" >
at <Combobox modelValue="" onUpdate:modelValue=fn options=
Array(4) [ "Nuxt", "Vue", "Svelte", "Tauri" ]
... >
at <App key=3 >
at <NuxtRoot>
But only when the Combobox popper shows
from radix-vue.
I see. Let me give it a try on a fresh demo
from radix-vue.
@ChrisGV04 It's weird now I have updated to 1.6.2, I have an hydration mismatch error :
[Vue warn]: Hydration node mismatch:
- rendered on server:
<div class="w-[inherit]"> <empty string>
- expected on client: Symbol("v-fgt")
at <PrimitiveSlot class="w-[inherit]" >
at <Primitive ref=fn<s> as=undefined as-child=true ... >
at <PopperAnchor as-child="" class="w-[inherit]" >
at <ComboboxAnchor class="w-[inherit]" >
at <Primitive ref=fn<s> style=
Object { pointerEvents: undefined }
as=undefined ... >
at <PopperRoot class="w-[200px]" >
at <ComboboxRoot modelValue="" onUpdate:modelValue=fn class="w-[200px]" >
at <Combobox modelValue="" onUpdate:modelValue=fn options=
Array(4) [ "Nuxt", "Vue", "Svelte", "Tauri" ]
... >
at <App key=3 >
at <NuxtRoot>
from radix-vue.
I wasn't able to reproduce the hydration mismatch on the minimal repro with the corrections applied. Did you try the 3 suggestions to get it working?
Also, you must remove forceMount
from the ComboboxPortal
.
from radix-vue.
Yes I've done all 3 suggestions, it works on the stackblitz but not in my code. Idk why.
from radix-vue.
Oh I see. Do you mind sharing the file that doesn't work?
And even with the hydration mismatch, does the animation work?
from radix-vue.
No the animation doesn't work and the popper not appear anymore.
Here is the file :
<script setup lang="ts">
import {
ComboboxAnchor,
ComboboxContent,
ComboboxEmpty,
ComboboxGroup,
ComboboxInput,
ComboboxItem,
ComboboxItemIndicator,
ComboboxPortal,
ComboboxViewport,
ComboboxTrigger,
ComboboxRoot
} from 'radix-vue'
const selected = defineModel<string>({
required: true
})
defineProps<{
id?: string
options: string[]
placeholder?: string
emptyText?: string
}>()
</script>
<template>
<ComboboxRoot v-model="selected">
<ComboboxAnchor class="w-[inherit]">
<ComboboxTrigger
class="inline-flex items-center justify-between whitespace-nowrap transition-colors border border-gray-300 rounded-md hover:bg-gray-100 w-full px-2.5 py-1.5"
>
<span v-if="selected.length === 0">{{ placeholder }}</span>
<span v-else>{{ selected }}</span>
<Icon name="radix-icons:caret-sort" class="w-4 h-4 text-gray-500" />
</ComboboxTrigger>
</ComboboxAnchor>
<div>
<ComboboxPortal>
<Transition name="fade">
<ComboboxContent
position="popper"
class="border border-gray-300 rounded-md bg-white shadow-md w-[--radix-combobox-trigger-width] z-10"
>
<ComboboxViewport class="flex flex-col">
<div class="flex items-center space-x-1.5 border-b border-b-gray-200 px-2.5 w-full">
<Icon
name="radix-icons:magnifying-glass"
class="min-w-4 min-h-4 text-gray-500"
/>
<ComboboxInput
:placeholder="placeholder ? placeholder : 'Search...'"
class="py-1.5 w-full focus:outline-none bg-transparent placeholder:text-gray-500"
/>
</div>
<ComboboxGroup class="p-1">
<ComboboxItem
v-for="(option, item) of options"
:key="item"
:value="option"
class="flex items-center justify-between rounded-md px-2 py-1 data-[highlighted]:bg-gray-100 transition-colors cursor-pointer"
>
<span>{{ option }}</span>
<ComboboxItemIndicator class="flex items-center">
<Icon name="radix-icons:check" class="w-4 h-4" />
</ComboboxItemIndicator>
</ComboboxItem>
</ComboboxGroup>
<ComboboxEmpty class="p-3">
{{ emptyText ? emptyText : 'No option' }}
</ComboboxEmpty>
</ComboboxViewport>
</ComboboxContent>
</Transition>
</ComboboxPortal>
</div>
</ComboboxRoot>
</template>
<style>
div[data-radix-popper-content-wrapper] {
top: 4px !important;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to /* .fade-leave-active in <2.1.8 */ {
opacity: 0;
}
</style>
from radix-vue.
I cannot replicate the hydration mismatch with your file either. Maybe the issue is on the way you used the component, not from Radix Vue.
Do you mind sharing the file where you used this component that's giving you the hydration mismatch? Maybe one of the props is causing the mismatch
from radix-vue.
Here is the file where the component is called:
<script setup lang="ts">
const darkMode = ref(false)
const selectedCombobox = ref('')
const optionsCombobox = ref(['Nuxt', 'Vue', 'Svelte', 'Tauri'])
const accept = ref(false)
const selectedRadio = ref('')
const optionsRadio = ref(['Default', 'Comfortable', 'Compact'])
</script>
<template>
<div class="p-2 space-y-2">
Nuxt module playground!
<div class="flex items-center space-x-2">
<label for="airplane">Dark mode</label>
<Switch
id="airplane"
offIcon="radix-icons:sun"
onIcon="radix-icons:moon"
v-model="darkMode"
/>
</div>
<Avatar src="https://avatars.githubusercontent.com/u/72009265?v=4" fallback="DA" />
<Combobox
v-model="selectedCombobox"
:options="optionsCombobox"
placeholder="Select framework..."
emptyText="No framework found."
class="w-[200px]"
/>
<label class="flex flex-row gap-2 items-center">
<Checkbox v-model="accept" />
<span class="select-none">Accept terms and conditions.</span>
</label>
<RadioGroup v-model="selectedRadio" :options="optionsRadio" />
</div>
</template>
from radix-vue.
For your information I develop this in the context of nuxt module idk if this context affect the behavior of radix-vue element.
You said that the error is not due to radix but my code. BUT it worked before the 1.6.2
from radix-vue.
That's very strange...
I also have my own Nuxt module using Radix Vue and the combobox doesn't give me hydration mismatches and animations work great. I do get hydration mismatches for the DropdownMenu
, but that is normal as of today (See why here: #577)
I added your component to my module and used it in another SSR app and it worked without issues. Even the animations are working.
from radix-vue.
Related Issues (20)
- [Bug]: flakey test on FocusScope.test HOT 2
- [Bug]: Extending ToastRootEmits with enabled declaration throws "A type annotation is necessary (2742)" HOT 1
- [Feature]: Extend Calendar with DateTime option HOT 4
- [Bug]: NumberField increment/decrement not taking into account user input number
- [Feature]: Remove NumberFieldLabel HOT 1
- [Feature]: Calendar step per week
- [Feature]: Dialog overlay click event HOT 2
- [Bug]: Pagination hides a single page behind an ellipsis
- [Feature]: Checkbox for multiple choice selections HOT 4
- [Bug]: Listbox not present in namespaced imports
- [Bug]: `Accordion` / `Collapsible` components default open on SSR HOT 5
- [Bug]: Datefield model value not updated when changing AM/PM by typing lowercase "a" or "p"
- [Bug]: `as-child` type issues with 1.8.2 HOT 2
- [Feature]: DatePickerField exposes modalValue to make DatePickerInput optional
- [Feature]: Expose `selectedValue` / highlighted item in ComboboxRoot HOT 1
- [Feature]: Expose more options to configure underlying `floating-ui` for advanced popper positioning HOT 4
- [Bug]: Error when pressing an already selected toggle group again HOT 2
- [Bug]: "Hover Card" component is missing is-hovering check HOT 4
- [Bug]: ESLint config doesn't have the Vue plugin enabled HOT 1
- [Feature]: Integrate Renovate/Dependabot HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from radix-vue.