fix transition enter bug (#1519)

We had an issue where an open Dialog got hidden by css didn't properly
unmount because the Transition never "finished". We fixed this by
checking if the node was hidden by using `getBoundingClientRect`.

Today I learned that just *reading* those values (aka call
`node.getBoundingClientRect()`) it for whatever reason completely stops
the transition. This causes the enter transitions to completely stop
working.

Instead, we move this code so that we only check the existence of the
Node when we try to transition out because this means that the Node is
definitely there, just have to check its bounding rect.
This commit is contained in:
Robin Malfait
2022-05-28 23:28:51 +02:00
committed by GitHub
parent d3ed3f5d26
commit ce12406ec2
2 changed files with 11 additions and 12 deletions
@@ -339,7 +339,8 @@ let TransitionRoot = forwardRefWithAs(function Transition<
>(props: TransitionChildProps<TTag> & { show?: boolean; appear?: boolean }, ref: Ref<HTMLElement>) {
// @ts-expect-error
let { show, appear = false, unmount, ...theirProps } = props as typeof props
let transitionRef = useSyncRefs(ref)
let internalTransitionRef = useRef<HTMLElement | null>(null)
let transitionRef = useSyncRefs(internalTransitionRef, ref)
// The TransitionChild will also call this hook, and we have to make sure that we are ready.
useServerHandoffComplete()
@@ -390,6 +391,15 @@ let TransitionRoot = forwardRefWithAs(function Transition<
setState(TreeStates.Visible)
} else if (!hasChildren(nestingBag)) {
setState(TreeStates.Hidden)
} else {
let node = internalTransitionRef.current
if (!node) return
let rect = node.getBoundingClientRect()
if (rect.x === 0 && rect.y === 0 && rect.width === 0 && rect.height === 0) {
// The node is completely hidden, let's hide it
setState(TreeStates.Hidden)
}
}
}, [show, nestingBag])
@@ -72,17 +72,6 @@ export function useTransition({
if (latestDirection.current === 'idle') return // We don't need to transition
if (!mounted.current) return
dd.add(() => {
if (!node) return
let rect = node.getBoundingClientRect()
if (rect.x === 0 && rect.y === 0 && rect.width === 0 && rect.height === 0) {
// The node is completely hidden
onStop.current(latestDirection.current)
}
})
dd.dispose()
beforeEvent()