Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Nuxt3] Combobox.Positioner incorrect position of content #2195

Closed
1 of 3 tasks
bogdan0083 opened this issue Feb 16, 2024 · 6 comments
Closed
1 of 3 tasks

[Nuxt3] Combobox.Positioner incorrect position of content #2195

bogdan0083 opened this issue Feb 16, 2024 · 6 comments

Comments

@bogdan0083
Copy link

bogdan0083 commented Feb 16, 2024

Description

Hey guys! Thank you for creating such a beautiful library ❤️

I created nuxt3 project and installed @ark-ui/vue library. Tried to use Combobox. It works, but position of content is calculated incorrectly. I expect it to be UNDER input field. Instead, it shows at the top left corner:

Снимок экрана 2024-02-16 в 19 54 48

Link to Reproduction (or Detailed Explanation)

https://stackblitz.com/edit/nuxt-starter-fzamjd?file=components%2FComboboxArk.vue

Steps to Reproduce

  1. Create empty Nuxt 3 project (in my case it's 3.10.1 version)
  2. Install @ark-ui/vue
  3. Create Combobox component (I use UnoCSS for styling, but no styles added for Combobox.Positioner or Combobox.Content:
<script setup>
import { ref } from 'vue';
import { Combobox } from '@ark-ui/vue';

const advancedItems = ref([
  { label: 'React', value: 'react' },
  { label: 'Solid', value: 'solid' },
  { label: 'Vue', value: 'vue' },
  { label: 'Svelte', value: 'svelte', disabled: true },
]);

const inputValue = ref('');

const onInputValueChange = (details) => {
  console.log(details);
  inputValue.value = details.value;
};

const onValueChange = (details) => {
  console.log(details);
  inputValue.value = '';
};
</script>

<template>
  <Combobox.Root
    :items="advancedItems"
    multiple
    v-slot="api"
    :onInputValueChange="onInputValueChange"
    :onValueChange="onValueChange"
  >
    <Combobox.Label>Framework</Combobox.Label>
    <Combobox.Control
      class="flex items-center flex-wrap relative pr-12 gap-x-3"
    >
      <div
        v-for="selectedItem in api.value"
        :key="selectedItem"
        class="inline-flex grow-0 shrink-0"
      >
        {{ selectedItem }}
      </div>
      <div class="min-w-10 w-[fit-content] inline-flex grow shrink">
        <Combobox.Input
          :value="inputValue"
          class="text-gray-500 bg-transparent b-none w-full block"
        />
      </div>
      <Combobox.Trigger class="absolute w-12 top-0 right-0"
        >Open</Combobox.Trigger
      >
    </Combobox.Control>
    <Teleport to="body">
      <Combobox.Positioner>
        <Combobox.Content>
          <Combobox.ItemGroup id="framework">
            <Combobox.ItemGroupLabel htmlFor="framework"
              >Frameworks</Combobox.ItemGroupLabel
            >
            <Combobox.Item
              v-for="item in advancedItems"
              :key="item.value"
              :item="item"
            >
              <Combobox.ItemText>{{ item.label }}</Combobox.ItemText>
              <Combobox.ItemIndicator>✓</Combobox.ItemIndicator>
            </Combobox.Item>
          </Combobox.ItemGroup>
        </Combobox.Content>
      </Combobox.Positioner>
    </Teleport>
  </Combobox.Root>
</template>
  1. Use your newly created component inside app.vue:
<template>
  <div class="flex flex-col w-300px">
    <h2>Combobox Ark example</h2>
    <Combobox />
  </div>
</template>

<script setup>

useHead({
  bodyAttrs: {
    class: 'text-gray-100 bg-gray-960 l:(text-gray-900 bg-white-100)',
  },
});
</script>
  1. run npm run dev and see the result. Content has wrong position on open (it's in the top left corner. I expect it to be under input)

Ark UI Version

@ark-ui/vue: 0.11.0

Framework

  • React
  • Solid
  • Vue

Browser

Firefox

Additional Information

No response

@bogdan0083
Copy link
Author

Here's the same example with Vue 3 and Vite, without SSR. You can see that the position of content is correct.

@Omikorin
Copy link
Collaborator

Thank you for opening this issue. I think it's similar to the problem with Portal in React with SSR

@jeferson-sb
Copy link

jeferson-sb commented Feb 18, 2024

@bogdan0083 I've also stumble upon this issue some weeks ago, it seems even though Nuxt has SSR support for Teleport sometimes it adds the div above <div id="__nuxt"> during hydration. I had to wrap the teleport inside of <ClientOnly> as they describe in the docs.

There is, though, an implement coming up that maybe will fix this 🤔
nuxt/nuxt#25041
nuxt/nuxt#25043

@bogdan0083
Copy link
Author

bogdan0083 commented Feb 19, 2024

@bogdan0083 I've also stumble upon this issue some weeks ago, it seems even though Nuxt has SSR support for Teleport sometimes it adds the div above <div id="__nuxt"> during hydration. I had to wrap the teleport inside of as they describe in the docs.

There is, though, an implement coming up that maybe will fix this 🤔 nuxt/nuxt#25041 nuxt/nuxt#25043

Hmm, I've just tried your solution with <ClientOnly> wrapper of Teleport and it still doesn't work 🤔 . Tried it on my bug reproduction example (It doesn't have ClientOnly wrapper now).

But I guess nuxt is definitely to blame here, that's for sure.

@manniL
Copy link

manniL commented Feb 19, 2024

But I guess nuxt is definitely to blame here, that's for sure.

Mostly Vue SSR behavior - we'd love to mimic the client-side Vue behavior but it'd lead to hydration errors. Nevertheless, with the linked PR it should work fine and follow the best practices 👍

@cschroeter
Copy link
Member

@manniL @bogdan0083 @jeferson-sb

This should be fixed in 1.0.0-2 I've added an example in Nuxt here https://stackblitz.com/github/chakra-ui/ark/tree/main/templates/vue/nuxt?file=components%2Fcombobox.vue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants