Skip to content

Commit

Permalink
add explicit enabled value to the useOutsideClick hook
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinMalfait committed Jun 3, 2022
1 parent eb439cb commit 7acaf08
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 75 deletions.
12 changes: 6 additions & 6 deletions packages/@headlessui-react/src/components/combobox/combobox.tsx
Expand Up @@ -34,7 +34,7 @@ import { forwardRefWithAs, render, compact, PropsForFeatures, Features } from '.
import { isDisabledReactIssue7711 } from '../../utils/bugs'
import { match } from '../../utils/match'
import { objectToFormEntries } from '../../utils/form'
import { sortByDomNode } from '../../utils/focus-management'
import { FocusableMode, isFocusableElement, sortByDomNode } from '../../utils/focus-management'

import { Hidden, Features as HiddenFeatures } from '../../internal/hidden'
import { useOpenClosed, State, OpenClosedProvider } from '../../internal/open-closed'
Expand Down Expand Up @@ -415,11 +415,11 @@ let ComboboxRoot = forwardRefWithAs(function Combobox<
}, [data])

// Handle outside click
useOutsideClick([data.buttonRef, data.inputRef, data.optionsRef], () => {
if (data.comboboxState !== ComboboxState.Open) return

dispatch({ type: ActionTypes.CloseCombobox })
})
useOutsideClick(
[data.buttonRef, data.inputRef, data.optionsRef],
() => dispatch({ type: ActionTypes.CloseCombobox }),
data.comboboxState === ComboboxState.Open
)

let slot = useMemo<ComboboxRenderPropArg<TType>>(
() => ({
Expand Down
9 changes: 2 additions & 7 deletions packages/@headlessui-react/src/components/dialog/dialog.tsx
Expand Up @@ -212,13 +212,8 @@ let DialogRoot = forwardRefWithAs(function Dialog<
state.panelRef.current ?? internalDialogRef.current,
] as HTMLElement[]
},
() => {
if (dialogState !== DialogStates.Open) return
if (hasNestedDialogs) return

close()
},
enabled
close,
enabled && !hasNestedDialogs
)

// Handle `Escape` to close
Expand Down
20 changes: 11 additions & 9 deletions packages/@headlessui-react/src/components/listbox/listbox.tsx
Expand Up @@ -396,16 +396,18 @@ let ListboxRoot = forwardRefWithAs(function Listbox<
)

// Handle outside click
useOutsideClick([buttonRef, optionsRef], (event, target) => {
if (listboxState !== ListboxStates.Open) return

dispatch({ type: ActionTypes.CloseListbox })
useOutsideClick(
[buttonRef, optionsRef],
(event, target) => {
dispatch({ type: ActionTypes.CloseListbox })

if (!isFocusableElement(target, FocusableMode.Loose)) {
event.preventDefault()
buttonRef.current?.focus()
}
})
if (!isFocusableElement(target, FocusableMode.Loose)) {
event.preventDefault()
buttonRef.current?.focus()
}
},
listboxState === ListboxStates.Open
)

let slot = useMemo<ListboxRenderPropArg>(
() => ({ open: listboxState === ListboxStates.Open, disabled }),
Expand Down
20 changes: 11 additions & 9 deletions packages/@headlessui-react/src/components/menu/menu.tsx
Expand Up @@ -239,16 +239,18 @@ let MenuRoot = forwardRefWithAs(function Menu<TTag extends ElementType = typeof
let menuRef = useSyncRefs(ref)

// Handle outside click
useOutsideClick([buttonRef, itemsRef], (event, target) => {
if (menuState !== MenuStates.Open) return

dispatch({ type: ActionTypes.CloseMenu })
useOutsideClick(
[buttonRef, itemsRef],
(event, target) => {
dispatch({ type: ActionTypes.CloseMenu })

if (!isFocusableElement(target, FocusableMode.Loose)) {
event.preventDefault()
buttonRef.current?.focus()
}
})
if (!isFocusableElement(target, FocusableMode.Loose)) {
event.preventDefault()
buttonRef.current?.focus()
}
},
menuState === MenuStates.Open
)

let slot = useMemo<MenuRenderPropArg>(
() => ({ open: menuState === MenuStates.Open }),
Expand Down
20 changes: 11 additions & 9 deletions packages/@headlessui-react/src/components/popover/popover.tsx
Expand Up @@ -258,16 +258,18 @@ let PopoverRoot = forwardRefWithAs(function Popover<
)

// Handle outside click
useOutsideClick([button, panel], (event, target) => {
if (popoverState !== PopoverStates.Open) return

dispatch({ type: ActionTypes.ClosePopover })
useOutsideClick(
[button, panel],
(event, target) => {
dispatch({ type: ActionTypes.ClosePopover })

if (!isFocusableElement(target, FocusableMode.Loose)) {
event.preventDefault()
button?.focus()
}
})
if (!isFocusableElement(target, FocusableMode.Loose)) {
event.preventDefault()
button?.focus()
}
},
popoverState === PopoverStates.Open
)

let close = useEvent((focusableElement?: HTMLElement | MutableRefObject<HTMLElement | null>) => {
dispatch({ type: ActionTypes.ClosePopover })
Expand Down
9 changes: 5 additions & 4 deletions packages/@headlessui-vue/src/components/combobox/combobox.ts
Expand Up @@ -396,10 +396,11 @@ export let Combobox = defineComponent({
}

// Handle outside click
useOutsideClick([inputRef, buttonRef, optionsRef], () => {
if (comboboxState.value !== ComboboxStates.Open) return
api.closeCombobox()
})
useOutsideClick(
[inputRef, buttonRef, optionsRef],
() => api.closeCombobox(),
computed(() => comboboxState.value === ComboboxStates.Open)
)

watch([api.value, api.inputRef], () => api.syncInputValue(), {
immediate: true,
Expand Down
6 changes: 2 additions & 4 deletions packages/@headlessui-vue/src/components/dialog/dialog.ts
Expand Up @@ -191,12 +191,10 @@ export let Dialog = defineComponent({
},

(_event, target) => {
if (dialogState.value !== DialogStates.Open) return
if (hasNestedDialogs.value) return

api.close()
nextTick(() => target?.focus())
}
},
computed(() => dialogState.value === DialogStates.Open && !hasNestedDialogs.value)
)

// Handle `Escape` to close
Expand Down
20 changes: 11 additions & 9 deletions packages/@headlessui-vue/src/components/listbox/listbox.ts
Expand Up @@ -298,16 +298,18 @@ export let Listbox = defineComponent({
}

// Handle outside click
useOutsideClick([buttonRef, optionsRef], (event, target) => {
if (listboxState.value !== ListboxStates.Open) return

api.closeListbox()
useOutsideClick(
[buttonRef, optionsRef],
(event, target) => {
api.closeListbox()

if (!isFocusableElement(target, FocusableMode.Loose)) {
event.preventDefault()
dom(buttonRef)?.focus()
}
})
if (!isFocusableElement(target, FocusableMode.Loose)) {
event.preventDefault()
dom(buttonRef)?.focus()
}
},
computed(() => listboxState.value === ListboxStates.Open)
)

// @ts-expect-error Types of property 'dataRef' are incompatible.
provide(ListboxContext, api)
Expand Down
20 changes: 11 additions & 9 deletions packages/@headlessui-vue/src/components/menu/menu.ts
Expand Up @@ -201,16 +201,18 @@ export let Menu = defineComponent({
}

// Handle outside click
useOutsideClick([buttonRef, itemsRef], (event, target) => {
if (menuState.value !== MenuStates.Open) return

api.closeMenu()
useOutsideClick(
[buttonRef, itemsRef],
(event, target) => {
api.closeMenu()

if (!isFocusableElement(target, FocusableMode.Loose)) {
event.preventDefault()
dom(buttonRef)?.focus()
}
})
if (!isFocusableElement(target, FocusableMode.Loose)) {
event.preventDefault()
dom(buttonRef)?.focus()
}
},
computed(() => menuState.value === MenuStates.Open)
)

// @ts-expect-error Types of property 'dataRef' are incompatible.
provide(MenuContext, api)
Expand Down
20 changes: 11 additions & 9 deletions packages/@headlessui-vue/src/components/popover/popover.ts
Expand Up @@ -211,16 +211,18 @@ export let Popover = defineComponent({
)

// Handle outside click
useOutsideClick([button, panel], (event, target) => {
if (popoverState.value !== PopoverStates.Open) return

api.closePopover()
useOutsideClick(
[button, panel],
(event, target) => {
api.closePopover()

if (!isFocusableElement(target, FocusableMode.Loose)) {
event.preventDefault()
dom(button)?.focus()
}
})
if (!isFocusableElement(target, FocusableMode.Loose)) {
event.preventDefault()
dom(button)?.focus()
}
},
computed(() => popoverState.value === PopoverStates.Open)
)

return () => {
let slot = { open: popoverState.value === PopoverStates.Open, close: api.close }
Expand Down

0 comments on commit 7acaf08

Please sign in to comment.