tailwindlabs / headlessui

Completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS.
https://headlessui.com
MIT License
26.17k stars 1.08k forks source link

ListboxOptions ignores anchor="bottom attribute #3475

Open anzuj opened 2 months ago

anzuj commented 2 months ago

What package within Headless UI are you using? @headlessui/react

What version of that package are you using? v2.1.3

What browser are you using? Chrome

Describe your issue As soon as there isn't enough space on the screen under the ListboxButton for my ListboxOptions, they appear on top of my ListboxButton, disregarding the anchor="bottom" attribute that has been set on it.

image

I've replicated the issue here in a minimum repo: Codesandbox

Is this a bug or do I need to set additional attributes somewhere to force bottom placement regardless of placement in the viewport?

adamwathan commented 2 months ago

Hey! So this is by design at least right now — the anchor prop is for configuring the default position, but we will always move the panel to another position if there is no room for it on screen. At the moment there is no way to force a panel to render off-screen when using the anchor prop, but it's something we could consider if there were enough interest. I think the hardest part would be getting the API right.

anzuj commented 2 months ago

Hey! So this is by design at least right now — the anchor prop is for configuring the default position, but we will always move the panel to another position if there is no room for it on screen. At the moment there is no way to force a panel to render off-screen when using the anchor prop, but it's something we could consider if there were enough interest. I think the hardest part would be getting the API right.

@adamwathan Thanks for a quick reply! I understand why it was designed this way, though it's surprisingly opinionated for headlessUI. The use case that brought me here is having to follow the design guide that mandates "blended together design" dropdowns like this: image.

To execute this using my beloved headlessUI components, I'd need to either

  1. Always force bottom placement for the ListboxOptions
  2. Programmatically detect whether ListboxOptions is currently shown on top or at the bottom and apply dynamic styles

Since option 1 is currently not possible by design, I attempted to achieve option 2. I noticed that data-anchor attribute in a div generated from ListboxOptions seems to reflect the position and is either "top center" or "bottom center". I utilised it to try and have dynamic styles in a repo HERE. Would appreciate a quick glance - is there a better way than what I did there?

Cheers!