-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transition does not call afterLeave
when using nested Transition.Child
#1866
Comments
Hey! Thank you for your bug report! I see what you are saying, but what is your use case for using I mean, if you buy a car and take out the engine, it won't work as expected either right 😅 |
Ah yeah sorry the In the actual code I have in a production app there is a Dialog component which is using the Radix UI dialog primitive together with the Headless UI Transition component to animate its presence. The problem there is that I think it is a race condition of some sorts because I'm not able to reproduce the problem in CodeSandbox but in the app I'm working on it happens 100% of the time. Note the comments in the Actual codeimport { Transition } from '@headlessui/react'
import {
Root as DialogRoot,
DialogPortal,
DialogOverlay,
DialogContent,
} from '@radix-ui/react-dialog'
import { Fragment } from 'react'
// … more imports and not so important code
interface DialogProps {
appear?: boolean
isOpen: boolean
hasVariableHeight?: boolean
hasTransparentOverlay?: boolean
children: React.ReactNode
close(): void
onUnmount?(): void
}
export function Dialog({
appear,
isOpen,
hasVariableHeight,
hasTransparentOverlay,
children,
close,
onUnmount,
}: DialogProps) {
return (
<DialogRoot open={isOpen} onOpenChange={(isOpen) => !isOpen && close()}>
<DialogPortal forceMount>
<Transition
as={Fragment}
appear={appear}
show={isOpen}
{...(!hasTransparentOverlay && {
enter: 'transition-colors ease-out duration-300',
enterFrom: 'bg-transparent',
enterTo: 'bg-black/25',
leave: 'transition-colors ease-in duration-150',
leaveFrom: 'bg-black/25',
leaveTo: 'bg-transparent',
})}
>
<DialogOverlay className="fixed inset-0 overflow-y-scroll" forceMount>
<VerticalPositionContainer hasVariableHeight={hasVariableHeight}>
<Transition.Child
as={Fragment}
enterFrom="opacity-0 scale-95"
// Putting transition properties in here because large render trees like the command line cause race conditions in which animations from classes put in `enter` won't work.
enterTo="transition ease-out duration-150 opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
// To counter transition class staying in Transition component when entered
entered="transition-none"
// Calling onUnmount here instead of parent <Transition /> because of https://github.com/tailwindlabs/headlessui/issues/1866
afterLeave={onUnmount}
>
<DialogContent asChild forceMount>
<KeyboardShortcutProvider
// !pointer-events-auto: Prevent Radix UI disabling pointer events when there are modal elements open inside. We render an overlay on top while those modal elements are open, but we want to enable pointer events during the exit animation of modal elements.
className="outline-none focus-visible:ring !pointer-events-auto"
>
{/* Necessary because KeyboardShortcutProvider stops propagation which makes Radix UI's internal escape handler not work anymore */}
<UseEscapeStack callback={close} />
{children}
</KeyboardShortcutProvider>
</DialogContent>
</Transition.Child>
</VerticalPositionContainer>
</DialogOverlay>
</Transition>
</DialogPortal>
</DialogRoot>
)
} |
Hmmm yeah if you could figure out a minimal reproduction that would be awesome. That said, our components communicate with each other so the I can see a potential issue where in this code: <DialogRoot open={isOpen} onOpenChange={(isOpen) => !isOpen && close()}> The One thing we do showcase in our docs is that the |
The I'll try to put the Transition on the outside and report back. |
Hey! Going to close this one for now. If you can reproduce the issue with the I hope you figured it out for your use case 💪 |
What package within Headless UI are you using?
@headlessui/react
What version of that package are you using?
v1.7.2
What browser are you using?
Chrome
Reproduction URL
https://codesandbox.io/s/headlessui-transition-bug-afterleave-3k435m?file=/src/App.tsx:666-1441
console.log('unmount')
inafterLeave
callback never gets called.Describe your issue
When using a nested Transition.Child within a Transition component, the
afterLeave
callback from the Transition component doesn't get called when the exit transition ends.Related: #1364
The text was updated successfully, but these errors were encountered: