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
Using a custom Portal component #38
Comments
Hi @ragulka, can you provide a minimal reproducible question example (like github repo, codesandbox, stackblitz...) for me to debug 😅? I will refer to your suggestion and try to find a solution. |
Hi @ragulka, I think this can be broken down into two parts. First, regarding the change of Teleport to use the Second, if you want to use <template>
<Popover v-slot="{ close }">
<Float
placement="bottom-start"
:offset="15"
:shift="6"
:flip="10"
arrow
enter="transition duration-200 ease-out"
enter-from="opacity-0 -translate-y-1"
enter-to="opacity-100 translate-y-0"
leave="transition duration-150 ease-in"
leave-from="opacity-100 translate-y-0"
leave-to="opacity-0 -translate-y-1"
>
<PopoverButton class="px-3 py-1.5 flex justify-center items-center bg-rose-50 hover:bg-rose-100 text-rose-500 rounded">
Open
</PopoverButton>
<PopoverPanel class="w-[240px] bg-white border border-gray-200 rounded-md shadow-lg focus:outline-none">
<FloatArrow class="absolute bg-white w-5 h-5 rotate-45 border border-gray-200" />
<div class="relative p-3 bg-white rounded-md">
<label class="inline-block mb-1">Combobox</label>
<Combobox v-model="selected">
<Float
as="div"
class="relative"
placement="bottom-start"
:offset="4"
leave="transition ease-in duration-100"
leave-from="opacity-100"
leave-to="opacity-0"
floating-as="template"
@hide="query = ''"
>
<div class="relative w-full text-left bg-white border border-gray-200 rounded-lg shadow-md cursor-default focus:outline-none sm:text-sm overflow-hidden">
<ComboboxInput
class="w-full border-none py-2 pl-3 pr-10 text-sm leading-5 text-gray-900 focus:outline-none focus:ring-0"
:display-value="person => person?.name"
@change="query = $event.target.value"
/>
<ComboboxButton class="absolute inset-y-0 right-0 flex items-center pr-2">
<HeroiconsChevronUpDown20Solid class="w-5 h-5 text-gray-400" aria-hidden="true" />
</ComboboxButton>
</div>
<ComboboxOptions class="absolute w-full py-1 overflow-auto text-base bg-white rounded-md shadow-lg max-h-60 ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
<div
v-if="filteredPeople.length === 0 && query !== ''"
class="relative py-2 px-4 text-gray-700 cursor-default select-none"
>
Nothing found.
</div>
<ComboboxOption
v-for="person in filteredPeople"
v-slot="{ selected, active }"
:key="person.id"
:value="person"
as="template"
>
<li
class="relative py-2 pl-10 pr-4 cursor-default select-none"
:class="active ? 'text-white bg-rose-600' : 'text-gray-900'"
>
<span class="block truncate" :class="selected ? 'font-medium' : 'font-normal'">
{{ person.name }}
</span>
<span
v-if="selected"
class="absolute inset-y-0 left-0 flex items-center pl-3"
:class="active ? 'text-white' : 'text-rose-600'"
>
<HeroiconsCheck20Solid class="w-5 h-5" aria-hidden="true" />
</span>
</li>
</ComboboxOption>
</ComboboxOptions>
</Float>
</Combobox>
<div class="mt-4 flex justify-end">
<button type="button" class="px-4 py-1 bg-rose-500 text-white text-sm rounded" @click="close">
Submit
</button>
</div>
</div>
</PopoverPanel>
</Float>
</Popover>
</template>
<script setup>
import { computed, ref } from 'vue'
import { Combobox, ComboboxButton, ComboboxInput, ComboboxOption, ComboboxOptions, Popover, PopoverButton, PopoverPanel } from '@headlessui/vue'
import { Float, FloatArrow } from '@headlessui-float/vue'
import HeroiconsCheck20Solid from '~icons/heroicons/check-20-solid'
import HeroiconsChevronUpDown20Solid from '~icons/heroicons/chevron-up-down-20-solid'
const people = [
{ id: 1, name: 'Wade Cooper' },
{ id: 2, name: 'Arlene Mccoy' },
{ id: 3, name: 'Devon Webb' },
{ id: 4, name: 'Tom Cook' },
{ id: 5, name: 'Tanya Fox' },
{ id: 6, name: 'Hellen Schmidt' },
]
const selected = ref(people[0])
const query = ref('')
const filteredPeople = computed(() =>
query.value === ''
? people
: people.filter(person =>
person.name
.toLowerCase()
.replace(/\s+/g, '')
.includes(query.value.toLowerCase().replace(/\s+/g, ''))
)
)
</script> If you have other questions, open a new issue and attach your sample code or minimally reproducible GitHub project. Online demo is provided here to test |
Use Version
Use version when question appear:
Describe the question
I'm trying to render a HeadlessUI Combobox inside a Popover. For this, I need to teleport the combobox options to the body, so that the dropdown options can overflow the popover, and the popover won't show scrollbars.
However, there's an issue - when clicking any of the combobox options, the popover is immediately closed. I believe it is because of the click outside handler, which now sees the options as being rendered outside of the popover. I saw a mention in HeadlessUI repo that using the
Portal
from@headlessui/vue
instead of the regularTeleport
component should help with this. Unfortunately, I don't see that it's possible to customize the portal component forFloat
. Would you consider supporting something like that? Or perhaps there's another solution to the issue?Screenshots
If applicable, add screenshots to help explain your problem.
The text was updated successfully, but these errors were encountered: