Giter Club home page Giter Club logo

Comments (18)

nethriis avatar nethriis commented on September 23, 2024 3

I've recreate my module from scratch and now it works well, thanks everyone for your help !

from radix-vue.

nethriis avatar nethriis commented on September 23, 2024 1

Related issue with Transition and Teleport (Portal)

radix-vue/shadcn-vue#440

no

from radix-vue.

nethriis avatar nethriis commented on September 23, 2024 1

Here is minimal repro :
https://stackblitz.com/edit/nuxt-starter-chghww

from radix-vue.

ChrisGV04 avatar ChrisGV04 commented on September 23, 2024 1

Okay, so there are a few things to consider to make it work:

  1. Upgrade to [email protected] because v1.6.1 had broken transitions (#801)
  2. When using the Transition on the ComboboxContent, you don't actually need forceMount. It should work just fine.
  3. 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.

nethriis avatar nethriis commented on September 23, 2024 1

That's very strange I will try to recreate a nuxt module project an retry to see if it works

from radix-vue.

sadeghbarati avatar sadeghbarati commented on September 23, 2024

Kinda related issue with Transition and Teleport (Portal) 😅

radix-vue/shadcn-vue#440

from radix-vue.

ChrisGV04 avatar ChrisGV04 commented on September 23, 2024

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.

nethriis avatar nethriis commented on September 23, 2024

@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.

ChrisGV04 avatar ChrisGV04 commented on September 23, 2024

I see. Let me give it a try on a fresh demo

from radix-vue.

nethriis avatar nethriis commented on September 23, 2024

@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.

ChrisGV04 avatar ChrisGV04 commented on September 23, 2024

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.

nethriis avatar nethriis commented on September 23, 2024

Yes I've done all 3 suggestions, it works on the stackblitz but not in my code. Idk why.

from radix-vue.

ChrisGV04 avatar ChrisGV04 commented on September 23, 2024

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.

nethriis avatar nethriis commented on September 23, 2024

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.

ChrisGV04 avatar ChrisGV04 commented on September 23, 2024

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.

nethriis avatar nethriis commented on September 23, 2024

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.

nethriis avatar nethriis commented on September 23, 2024

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.

ChrisGV04 avatar ChrisGV04 commented on September 23, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.