Skip to content

Commit

Permalink
Ensure the Transition stops once DOM Nodes are hidden (#1500)
Browse files Browse the repository at this point in the history
* ensure that the transitions `stops` once the DOM Node is hidden

* update changelog
  • Loading branch information
RobinMalfait committed May 25, 2022
1 parent df481f3 commit deb4b1b
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Allow to override the `type` on the `Combobox.Input` ([#1476](https://github.com/tailwindlabs/headlessui/pull/1476))
- Ensure the the `<Popover.Panel focus>` closes correctly ([#1477](https://github.com/tailwindlabs/headlessui/pull/1477))
- Only render the `FocusSentinel` if required in the `Tabs` component ([#1493](https://github.com/tailwindlabs/headlessui/pull/1493))
- Ensure the Transition stops once DOM Nodes are hidden ([#1500](https://github.com/tailwindlabs/headlessui/pull/1500))

### Added

Expand Down
Expand Up @@ -218,17 +218,6 @@ let TransitionChild = forwardRefWithAs(function TransitionChild<

let id = useId()

let transitionInFlight = useRef(false)

let nesting = useNesting(() => {
// When all children have been unmounted we can only hide ourselves if and only if we are not
// transitioning ourselves. Otherwise we would unmount before the transitions are finished.
if (!transitionInFlight.current) {
setState(TreeStates.Hidden)
unregister(id)
}
})

useEffect(() => {
if (!id) return
return register(id)
Expand Down Expand Up @@ -280,13 +269,28 @@ let TransitionChild = forwardRefWithAs(function TransitionChild<
return show ? 'enter' : 'leave'
})() as 'enter' | 'leave' | 'idle'

let transitioning = useRef(false)

let nesting = useNesting(() => {
if (transitioning.current) return

// When all children have been unmounted we can only hide ourselves if and only if we are not
// transitioning ourselves. Otherwise we would unmount before the transitions are finished.
setState(TreeStates.Hidden)
unregister(id)
})

useTransition({
container,
classes,
events,
direction: transitionDirection,
onStart: useLatestValue(() => {}),
onStart: useLatestValue(() => {
transitioning.current = true
}),
onStop: useLatestValue((direction) => {
transitioning.current = false

if (direction === 'leave' && !hasChildren(nesting)) {
// When we don't have children anymore we can safely unregister from the parent and hide
// ourselves.
Expand Down
11 changes: 11 additions & 0 deletions packages/@headlessui-react/src/hooks/use-transition.ts
Expand Up @@ -72,6 +72,17 @@ 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()
Expand Down

0 comments on commit deb4b1b

Please sign in to comment.