Skip to content

Commit 1073680

Browse files
committed
use new useOnDisappear hook in components with the anchor prop
1 parent cef19c5 commit 1073680

File tree

4 files changed

+15
-18
lines changed

4 files changed

+15
-18
lines changed

packages/@headlessui-react/src/components/dialog/dialog.tsx

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { useEventListener } from '../../hooks/use-event-listener'
2424
import { useId } from '../../hooks/use-id'
2525
import { useInert } from '../../hooks/use-inert'
2626
import { useIsTouchDevice } from '../../hooks/use-is-touch-device'
27+
import { useOnDisappear } from '../../hooks/use-on-disappear'
2728
import { useOutsideClick } from '../../hooks/use-outside-click'
2829
import { useOwnerDocument } from '../../hooks/use-owner'
2930
import { useRootContainers } from '../../hooks/use-root-containers'
@@ -338,24 +339,8 @@ function DialogFn<TTag extends ElementType = typeof DEFAULT_DIALOG_TAG>(
338339
})()
339340
useScrollLock(ownerDocument, scrollLockEnabled, resolveRootContainers)
340341

341-
// Trigger close when the FocusTrap gets hidden
342-
useEffect(() => {
343-
if (dialogState !== DialogStates.Open) return
344-
if (!internalDialogRef.current) return
345-
346-
let observer = new ResizeObserver((entries) => {
347-
for (let entry of entries) {
348-
let rect = entry.target.getBoundingClientRect()
349-
if (rect.x === 0 && rect.y === 0 && rect.width === 0 && rect.height === 0) {
350-
close()
351-
}
352-
}
353-
})
354-
355-
observer.observe(internalDialogRef.current)
356-
357-
return () => observer.disconnect()
358-
}, [dialogState, internalDialogRef, close])
342+
// Ensure we close the dialog as soon as the dialog itself becomes hidden
343+
useOnDisappear(internalDialogRef, close, dialogState === DialogStates.Open)
359344

360345
let [describedby, DescriptionProvider] = useDescriptions()
361346

packages/@headlessui-react/src/components/listbox/listbox.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { useEvent } from '../../hooks/use-event'
3131
import { useId } from '../../hooks/use-id'
3232
import { useIsoMorphicEffect } from '../../hooks/use-iso-morphic-effect'
3333
import { useLatestValue } from '../../hooks/use-latest-value'
34+
import { useOnDisappear } from '../../hooks/use-on-disappear'
3435
import { useOutsideClick } from '../../hooks/use-outside-click'
3536
import { useResolveButtonType } from '../../hooks/use-resolve-button-type'
3637
import { useSyncRefs } from '../../hooks/use-sync-refs'
@@ -898,6 +899,9 @@ function OptionsFn<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(
898899
return data.listboxState === ListboxStates.Open
899900
})()
900901

902+
// Ensure we close the listbox as soon as the button becomes hidden
903+
useOnDisappear(data.buttonRef, actions.closeListbox, visible)
904+
901905
let initialOption = useRef<number | null>(null)
902906

903907
useEffect(() => {

packages/@headlessui-react/src/components/menu/menu.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/menubutton/
44
import { useFocusRing } from '@react-aria/focus'
55
import { useHover } from '@react-aria/interactions'
6+
import { useOnDisappear } from 'hooks/use-on-disappear'
67
import React, {
78
Fragment,
89
createContext,
@@ -611,6 +612,9 @@ function ItemsFn<TTag extends ElementType = typeof DEFAULT_ITEMS_TAG>(
611612
return state.menuState === MenuStates.Open
612613
})()
613614

615+
// Ensure we close the menu as soon as the button becomes hidden
616+
useOnDisappear(state.buttonRef, () => dispatch({ type: ActionTypes.CloseMenu }), visible)
617+
614618
// We keep track whether the button moved or not, we only check this when the menu state becomes
615619
// closed. If the button moved, then we want to cancel pending transitions to prevent that the
616620
// attached `MenuItems` is still transitioning while the button moved away.

packages/@headlessui-react/src/components/popover/popover.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { useEventListener } from '../../hooks/use-event-listener'
2929
import { useId } from '../../hooks/use-id'
3030
import { useIsoMorphicEffect } from '../../hooks/use-iso-morphic-effect'
3131
import { useLatestValue } from '../../hooks/use-latest-value'
32+
import { useOnDisappear } from '../../hooks/use-on-disappear'
3233
import { useOutsideClick } from '../../hooks/use-outside-click'
3334
import { useOwnerDocument } from '../../hooks/use-owner'
3435
import { useResolveButtonType } from '../../hooks/use-resolve-button-type'
@@ -854,6 +855,9 @@ function PanelFn<TTag extends ElementType = typeof DEFAULT_PANEL_TAG>(
854855
return state.popoverState === PopoverStates.Open
855856
})()
856857

858+
// Ensure we close the popover as soon as the button becomes hidden
859+
useOnDisappear(state.button, () => dispatch({ type: ActionTypes.ClosePopover }), visible)
860+
857861
let handleKeyDown = useEvent((event: ReactKeyboardEvent<HTMLButtonElement>) => {
858862
switch (event.key) {
859863
case Keys.Escape:

0 commit comments

Comments
 (0)