--button-width incorrect when parent is rendered with an animation
What package within Headless UI are you using?
For example: @headlessui/react
What version of that package are you using?
For example: v2.2.0
What browser are you using?
Chrome
Reproduction URL
https://codesandbox.io/p/devbox/stupefied-rosalind-cfyp2k
Describe your issue You can see in the repro URL I'm animating a Dialog that contains a Listbox, and the ListboxOptions don't take up the full width of the ListboxButton.
If an animation involving scale is used to show the content, --button-width is calculated before the animation finishes so it will be incorrect. The implementation of useElementSize uses a ResizeObserver, but that doesn't call the callback when its size changes via animation. It looks like the ResizeObserver's entry.borderBoxSize has the correct values, so maybe that would be an acceptable solution?
I have the same issue as well, I have a form rendered in a dialog
Same issue, does anyone have a solution?
Has anyone had a solution for this?
Probably a bad solution, but you can access the state when the menu opens and recalculate it manually. Probably can make it more efficient by also tracking if the width was updated.
Very simplified version (keep rest of your props, including anchor, etc):
Combobox:
const comboboxInputRef = useRef<HTMLInputElement>(null);
const comboboxOptionsRef = useRef<HTMLDivElement>(null);
const setInputWidth = () => {
if (comboboxInputRef.current && comboboxOptionsRef.current) {
const inputWidth = comboboxInputRef.current.getBoundingClientRect().width;
comboboxOptionsRef.current.style.setProperty('--input-width', `${inputWidth}px`);
}
}
...
<Headless.Combobox {...props}>
{({ open }) => {
if (open) {
setInputWidth();
}
...
// set ref to ComboboxInput
<Headless.ComboboxInput ref={comboboxInputRef}
...
// set ref to ComboboxOptions
<Headless.ComboboxOptions ref={comboboxOptionsRef} className="w-[var(--input-width)]"
Select:
const listboxOptionsRef = useRef<HTMLDivElement>(null);
const listboxButtonRef = useRef<HTMLButtonElement>(null);
const setButtonWidth = () => {
if (listboxButtonRef.current && listboxOptionsRef.current) {
const buttonWidth = listboxButtonRef.current.getBoundingClientRect().width;
listboxOptionsRef.current.style.setProperty('--button-width', `${buttonWidth}px`);
}
}
...
<Headless.Listbox {...props}>
{({ open }) => {
if (open) {
setButtonWidth();
}
...
// Set ref to ListboxButton
<Headless.ListboxButton ref={listboxButtonRef}
...
// Set ref to ListboxOptions
<Headless.ListboxOptions ref={listboxOptionsRef} className="w-[var(--button-width)]"
cc: @abolajibisiriyu @BratislavZdravkovic @fusionfitdevs
This should be fixed by #3786, and will be available in the next release.
You can already try it using:
npm install @headlessui/react@insiders.