Skip to content

Commit deb4b1b

Browse files
authored
Ensure the Transition stops once DOM Nodes are hidden (#1500)
* ensure that the transitions `stops` once the DOM Node is hidden * update changelog
1 parent df481f3 commit deb4b1b

File tree

3 files changed

+28
-12
lines changed

3 files changed

+28
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- Allow to override the `type` on the `Combobox.Input` ([#1476](https://github.com/tailwindlabs/headlessui/pull/1476))
1717
- Ensure the the `<Popover.Panel focus>` closes correctly ([#1477](https://github.com/tailwindlabs/headlessui/pull/1477))
1818
- Only render the `FocusSentinel` if required in the `Tabs` component ([#1493](https://github.com/tailwindlabs/headlessui/pull/1493))
19+
- Ensure the Transition stops once DOM Nodes are hidden ([#1500](https://github.com/tailwindlabs/headlessui/pull/1500))
1920

2021
### Added
2122

packages/@headlessui-react/src/components/transitions/transition.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -218,17 +218,6 @@ let TransitionChild = forwardRefWithAs(function TransitionChild<
218218

219219
let id = useId()
220220

221-
let transitionInFlight = useRef(false)
222-
223-
let nesting = useNesting(() => {
224-
// When all children have been unmounted we can only hide ourselves if and only if we are not
225-
// transitioning ourselves. Otherwise we would unmount before the transitions are finished.
226-
if (!transitionInFlight.current) {
227-
setState(TreeStates.Hidden)
228-
unregister(id)
229-
}
230-
})
231-
232221
useEffect(() => {
233222
if (!id) return
234223
return register(id)
@@ -280,13 +269,28 @@ let TransitionChild = forwardRefWithAs(function TransitionChild<
280269
return show ? 'enter' : 'leave'
281270
})() as 'enter' | 'leave' | 'idle'
282271

272+
let transitioning = useRef(false)
273+
274+
let nesting = useNesting(() => {
275+
if (transitioning.current) return
276+
277+
// When all children have been unmounted we can only hide ourselves if and only if we are not
278+
// transitioning ourselves. Otherwise we would unmount before the transitions are finished.
279+
setState(TreeStates.Hidden)
280+
unregister(id)
281+
})
282+
283283
useTransition({
284284
container,
285285
classes,
286286
events,
287287
direction: transitionDirection,
288-
onStart: useLatestValue(() => {}),
288+
onStart: useLatestValue(() => {
289+
transitioning.current = true
290+
}),
289291
onStop: useLatestValue((direction) => {
292+
transitioning.current = false
293+
290294
if (direction === 'leave' && !hasChildren(nesting)) {
291295
// When we don't have children anymore we can safely unregister from the parent and hide
292296
// ourselves.

packages/@headlessui-react/src/hooks/use-transition.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ export function useTransition({
7272
if (latestDirection.current === 'idle') return // We don't need to transition
7373
if (!mounted.current) return
7474

75+
dd.add(() => {
76+
if (!node) return
77+
78+
let rect = node.getBoundingClientRect()
79+
80+
if (rect.x === 0 && rect.y === 0 && rect.width === 0 && rect.height === 0) {
81+
// The node is completely hidden
82+
onStop.current(latestDirection.current)
83+
}
84+
})
85+
7586
dd.dispose()
7687

7788
beforeEvent()

0 commit comments

Comments
 (0)