`data-enter` is not removed when performing exit transition before enter ends (`v2.1.0` transition API regression)
What package within Headless UI are you using?
@headlessui/react
What version of that package are you using?
v2.1.0
What browser are you using?
Chrome
Describe your issue
The title is clear enough. Simply open the reproduction and quickly double-click the button. There is supposed to be NO exit transition, however, there is due to the data-enter is still there during the exit transition.
I didn't check whether the same thing happens to exit -> enter quick switch. I think it worths to check that as well while fixing this.
I tried it in version 2.1 and the original API is still usable, like the one below,
I don't know why they need to be deleted from the document, use data - * instead
<TransitionChild
enter="ease-out duration-[5000ms]"
enterFrom="opacity-0 translate-y-8"
enterTo="opacity-100 translate-y-0"
leave="ease-in duration-[5000ms]"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-8"
>
From my perspective the new API is easier to use, but everyone has their own feelings. But issues need to be fixed for any new APIs for sure.
@xsjcTony I think your className was written incorrectly. Please try using my writing method below
<PopoverPanel
transition
// className="mt-4 ease-out data-[enter]:duration-500 data-[closed]:opacity-0 data-[closed]:translate-y-6"
className={clsx([
// Base styles
'mt-4 ease-out',
// Shared closed styles
'data-[closed]:opacity-0',
// Entering styles
'data-[enter]:duration-500 data-[enter]:data-[closed]:translate-y-6',
// Leaving styles
'data-[leave]:duration-300 data-[leave]:data-[closed]:translate-y-6',
])}
>
https://headlessui.com/react/transition#different-enter-leave-transitions
Besides, I still feel that the original API is easier to understand
@RobinMalfait I would like to ask if the original API will continue to be useful in future versions
<TransitionChild
enter="ease-out duration-[5000ms]"
enterFrom="opacity-0 translate-y-8"
enterTo="opacity-100 translate-y-0"
leave="ease-in duration-[5000ms]"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-8"
>
@xsjcTony I think your className was written incorrectly. Please try using my writing method below
<PopoverPanel transition // className="mt-4 ease-out data-[enter]:duration-500 data-[closed]:opacity-0 data-[closed]:translate-y-6" className={clsx([ // Base styles 'mt-4 ease-out', // Shared closed styles 'data-[closed]:opacity-0', // Entering styles 'data-[enter]:duration-500 data-[enter]:data-[closed]:translate-y-6', // Leaving styles 'data-[leave]:duration-300 data-[leave]:data-[closed]:translate-y-6', ])} >https://headlessui.com/react/transition#different-enter-leave-transitions
It's the same @LeiYao123 (I changed enter to [5s] so it's more obvious). It's something wrong in JS, that data-enter is not removed when quickly switched, nothing to do with those classnames. Potentially data-leave is also not removed while quick switched from exit to enter.
https://stackblitz.com/edit/vitejs-vite-or4hkb?file=src%2FApp.tsx
Besides, I don't want any leaving styles, and the same data-[closed] is absolutely redundant for translate-y-6
Still an issue in v2.1.6 👀
@RobinMalfait I've updated all dependencies to the latest in the reproduction, in case you need it. Thanks.
Hey!
@LeiYao123 the original API will stay, if we ever remove it then it will be part of a bigger v3 or v4 release. But chances are that it just keeps working 👍
@xsjcTony I understand the problem, but in this case what's happening is that when you quickly click on the button we don't go from enter to leave. Instead, we "cancel" the enter transition and therefore are still in the enter stage if that makes sense.
To solve this, you can use the data-closed state, and only set a duration if you are entering and not closing. If you are on Tailwind CSS v4, then the snippet looks like this:
import {Popover, PopoverButton, PopoverPanel} from '@headlessui/react';
function App() {
return (
<div>
<Popover>
<PopoverButton>Trigger</PopoverButton>
<PopoverPanel
transition
className="mt-4 ease-out data-enter:not-data-closed:duration-500 data-closed:opacity-0 data-closed:translate-y-6"
>
123
</PopoverPanel>
</Popover>
</div>
);
}
export default App;
This is essentially saying that if you enter and you are not closing (cancelled), then set a duration of 500ms: data-enter:not-data-closed:duration-500
Hope this helps!
Alright. Thanks for the response. Though it's a bit anti-intuitive, but I'll take it.