adobe / react-spectrum

A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.
https://react-spectrum.adobe.com
Apache License 2.0
12.21k stars 1.07k forks source link

[React Aria Components] `--trigger-width` incorrect if ComboxBox inside Modal #5331

Open elilabes opened 8 months ago

elilabes commented 8 months ago

Provide a general summary of the issue here

When you place a ComboxBox inside of a Modal using Popover, the variable for --trigger-width is incorrectly set.

πŸ€” Expected Behavior?

The --trigger-width should always update to be the width of the trigger.

😯 Current Behavior

From my testing, it seems that it measures when the modal is triggered (and the input is one size). Then the modal finishes rendering contents and they are a different size. However, for some reason the resize observer is not fired.

If I breakpoint at the time this code is run, it is correctly identifying the inputs and their widths (although they are shorter). If I then let it play through, and check the widths of the inputs, they are larger. However, it has not triggered the resize. https://github.com/adobe/react-spectrum/blob/403ec27bf8f5af6e19529b78782526f680c171ca/packages/react-aria-components/src/ComboBox.tsx#L153-L166C6

πŸ’ Possible Solution

Not sure why the resize event isn't being fired.

I have seen some libraries accept a list of dependencies that should trigger recalculation. E.g. a prop that takes an array of references, and if any resize then it recalculates. That doesn't seem like it should be necessary though.

Update After finding that it is because of the scale animation, maybe the ComboBox/Select could detect when inside a Modal/Dialog and update the width when the animation is finished (e.g. data-entering).

Alternatively, the simplest option could just be to measure when it is triggered, so it is always up to date based on the current interaction.

πŸ”¦ Context

I am building a form in a Modal that needs to use a ComoBox

πŸ–₯️ Steps to Reproduce

https://codesandbox.io/s/react-typescript-forked-2ly428?file=/src/App.tsx

Apologies the styles are a bit yuck, I copied them from the docs.

Version

1.0.0-beta.2

What browsers are you seeing the problem on?

Chrome

If other, please specify.

I also tried the nightly build and same issue

What operating system are you using?

MacOS

🧒 Your Company/Team

No response

πŸ•· Tracking Issue

No response

elilabes commented 8 months ago

Literally as I posted this I had an idea. It is caused by the CSS animation that is used in the demo.

The modal starts out scaled down and grows when opened. That would make sense as to why the resize observer doesn't get called (as the width / height are not getting changed I guess).

For my use case I'll change my animation to work around this, but should probably still work.

elilabes commented 8 months ago

Worth noting that the popover position can also be wrong if there is an animation

khairulhaaziq commented 6 months ago

Having the same issue. it appears the width is calculated on the first render(e.g.) if animation is scale-95 to scale-100, the trigger-width is calculated with scale 95.

This is my workaround currently, ofcourse you can do more advanced with mutationObserver, but this is fine for me

style={{width: inputRef.current ? `${inputRef.current.getBoundingClientRect().width}px` : undefined}}
sookmax commented 2 months ago

After finding that it is because of the scale animation

If anyone uses tailwindcss for styling, you might be able to work around this by specifying a fixed width on the popover element and adding animations to the child of Popover using group-data-[entering] and group-data-[exiting].

The tricky part of this workaround is that you also need to specify a 'null' animation with the same duration to the popover itself to ensure data-entering and data-exiting states work properly.

My example is with a Menu, but I thought It might be useful to share here anyway: https://stackblitz.com/edit/vitejs-vite-sf3fvk?file=src%2FApp.tsx (it loads a little slow)

https://github.com/adobe/react-spectrum/assets/71210554/b5ec7f14-a4ff-4e7d-889f-c4b5f065196d