Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Jojo_44's avatar

Headless UI Open ListboxOptions programmatically

Hi,

I use the latest Headless UI Listbox Version and I try to open/close the ListboxOptions programmatically. I looked into the listbox.ts source code and I still can't figure it out. Only once you click on the ListboxButton it opens/closes but I want to replace the ListboxButton with my own component and toggle the options. Is this possible somehow?

<template>
  <Listbox v-model="selectedPerson">
    <ListboxButton>{{ selectedPerson.name }}</ListboxButton>
   // something like <div @click="open/close options"></div>
    <ListboxOptions>
      <ListboxOption
        v-for="person in people"
        :key="person"
        :value="person"
        :disabled="person.unavailable"
      >
        {{ person.name }}
      </ListboxOption>
    </ListboxOptions>
  </Listbox>
</template>

Thank you and best regards, Jules

0 likes
4 replies
drehimself's avatar

You can add the static prop on the ListboxOptions and that will ignore the internal open state of Headless UI. You can then add your own state to toggle the visibility of the Listbox.

<div v-show="myOpen">
  <ListboxOptions static>
</div>
const myOpen = ref(true)

At this point, you can programmatically do what you want with the myOpen state, here's a standard button:

<button @click="myOpen = !myOpen">My own button</button>

https://headlessui.dev/vue/listbox#showing-hiding-the-listbox

1 like
Jojo_44's avatar

Hi drehimself,

thank you for your response.

This opens/closes the ListboxOptions if you click on the button. But since it is not using the Listbox open state you loose the functionality of closing when you select an option or click outside the Listbox. Ofc I could implement this functionality myself but this defeats the purpose of using the Listbox component. I wonder why they didn't expose the openListbox/closeListbox functions.

Best regards, Jules

drehimself's avatar

Ah, right.

It may be worth it to post your use case (and an example) on the Discussions tab of their GitHub repo. It could possibly be added in the future for this component (and maybe other similar components).

renky's avatar

Maybe it is a bit late, but since I just faced the same issue and there is still no official solution, I came to the following workaround (using Vue Composition API):

<script setup>
...
const listBoxButton = ref()
....
</script>
<template>
...
<ListboxButton ref="listBoxButton">
...
</template>

and finally for open close, i just do:

function open() {
    listBoxButton.value.$el.dispatchEvent(new Event('click'))
}

Please or to participate in this conversation.