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

tailwindcss-react-aria-components breaks :active selector #5970

Open imericxu opened 4 months ago

imericxu commented 4 months ago

Provide a general summary of the issue here

When the extension tailwindcss-react-aria-components is installed, having both :hover and :active selectors styling the same property doesn't work as expected.

🤔 Expected Behavior?

:active styles should override base and :hover styles.

😯 Current Behavior

If both :hover and :active have different values for background-color, the element will have the :hover background color when the state is actually :active.

💁 Possible Solution

No response

🔦 Context

The tailwindcss-react-aria-components plugin helps to simplify the development process with autocompletion and shorter Tailwind selectors, but breaks existing code that uses the :active selector with :hover.

🖥️ Steps to Reproduce

I couldn't figure out how to use tailwind-react-aria-components in CodeSandBox for free, but here's simple steps and code to reproduce:

  1. npx create-next-app@latest with default options
  2. npm i react-aria-components tailwindcss-react-aria-components
  3. Add tailwindcss-react-aria-components to tailwind.config.ts plugins
  4. Replace src/app/page.tsx with following code (I know <Button> exists, this is just an example):
    export default function Home() {
     return (
       <main className="m-4 flex justify-center">
         <button
           type="button"
           className="bg-blue-500 text-white/95 text-xl leading-6 py-2 px-4 hover:bg-blue-600 active:bg-blue-700"
         >
           Press me
         </button>
       </main>
     );
    }
  5. Notice that the background color does not change on press
  6. Comment out/remove tailwindcss-react-aria-components plugin
  7. The background color will now change on press

Version

react-aria@3.21.1 & react-aria-components@1.1.1 & tailwindcss-react-aria-components@1.1.1

What browsers are you seeing the problem on?

Chrome, Safari

If other, please specify.

No response

What operating system are you using?

macOS

🧢 Your Company/Team

No response

🕷 Tracking Issue

No response

reidbarber commented 4 months ago

I think it's preferable to use the pressed: variant from the plugin in place of tailwind's default active: variant. You'll get more consistent behavior across input modalities, and this should also fix your issue due to how they're ordered in the plugin. I think the behavior you're seeing is expected, since :active and [data-hovered] have the same specificity, it comes down to which comes last in the stylesheet, which would be [data-hovered] since it comes from the plugin.

imericxu commented 4 months ago

I understand the benefits that pressed offers, however, the issue is that the plugin is disrupting the expected behavior, i.e., adding the plugin shouldn’t change existing behavior. In this case, the native hover state is being used because <button> doesn’t have a programmatic isHovered state. It seems like the native :hover selector’s precedence is modified by the plugin, so it only makes sense that the :active selector’s precedence is modified accordingly, even though the selector is discouraged, to maintain consistent behavior.

The specific use case where I want to keep using the :active state is with links because the link components and press removes the native drag and drop ability.

reidbarber commented 4 months ago

The only potential solution I can think of is specifying a custom variant order in the plugin.

k-miyata commented 4 months ago

Prefixing all React Aria Components modifiers can resolve this issue.