Only restore focus to the Menu.Button if necessary when activating a Menu.Option (#1782)
* only restore focus to the Menu Button if necessary This will check whether the focus got moved to somewhere else or not once we activate an item via click or pressing `enter`. Pressing escape will still move focus to the Menu Button. * update changelog
This commit is contained in:
@@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Ensure `Disclosure.Panel` is properly linked ([#1747](https://github.com/tailwindlabs/headlessui/pull/1747))
|
||||
- Only select the active option when using "singular" mode when pressing `<tab>` in the `Combobox` component ([#1750](https://github.com/tailwindlabs/headlessui/pull/1750))
|
||||
- Improve the types of the `Combobox` component ([#1761](https://github.com/tailwindlabs/headlessui/pull/1761))
|
||||
- Only restore focus to the `Menu.Button` if necessary when activating a `Menu.Option` ([#1782](https://github.com/tailwindlabs/headlessui/pull/1782))
|
||||
|
||||
## Changed
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
sortByDomNode,
|
||||
Focus as FocusManagementFocus,
|
||||
focusFrom,
|
||||
restoreFocusIfNecessary,
|
||||
} from '../../utils/focus-management'
|
||||
import { useOutsideClick } from '../../hooks/use-outside-click'
|
||||
import { useTreeWalker } from '../../hooks/use-tree-walker'
|
||||
@@ -463,7 +464,7 @@ let Items = forwardRefWithAs(function Items<TTag extends ElementType = typeof DE
|
||||
let { dataRef } = state.items[state.activeItemIndex]
|
||||
dataRef.current?.domRef.current?.click()
|
||||
}
|
||||
disposables().nextFrame(() => state.buttonRef.current?.focus({ preventScroll: true }))
|
||||
restoreFocusIfNecessary(state.buttonRef.current)
|
||||
break
|
||||
|
||||
case Keys.ArrowDown:
|
||||
@@ -615,7 +616,7 @@ let Item = forwardRefWithAs(function Item<TTag extends ElementType = typeof DEFA
|
||||
let handleClick = useEvent((event: MouseEvent) => {
|
||||
if (disabled) return event.preventDefault()
|
||||
dispatch({ type: ActionTypes.CloseMenu })
|
||||
disposables().nextFrame(() => state.buttonRef.current?.focus({ preventScroll: true }))
|
||||
restoreFocusIfNecessary(state.buttonRef.current)
|
||||
})
|
||||
|
||||
let handleFocus = useEvent(() => {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { disposables } from './disposables'
|
||||
import { match } from './match'
|
||||
import { getOwnerDocument } from './owner'
|
||||
|
||||
@@ -99,6 +100,18 @@ export function isFocusableElement(
|
||||
})
|
||||
}
|
||||
|
||||
export function restoreFocusIfNecessary(element: HTMLElement | null) {
|
||||
let ownerDocument = getOwnerDocument(element)
|
||||
disposables().nextFrame(() => {
|
||||
if (
|
||||
ownerDocument &&
|
||||
!isFocusableElement(ownerDocument.activeElement as HTMLElement, FocusableMode.Strict)
|
||||
) {
|
||||
focusElement(element)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function focusElement(element: HTMLElement | null) {
|
||||
element?.focus({ preventScroll: true })
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Make form components uncontrollable ([#1683](https://github.com/tailwindlabs/headlessui/pull/1683))
|
||||
- Improve `Combobox` re-opening keyboard issue on mobile ([#1732](https://github.com/tailwindlabs/headlessui/pull/1732))
|
||||
- Only select the active option when using "singular" mode when pressing `<tab>` in the `Combobox` component ([#1750](https://github.com/tailwindlabs/headlessui/pull/1750))
|
||||
- Only restore focus to the `MenuButton` if necessary when activating a `MenuOption` ([#1782](https://github.com/tailwindlabs/headlessui/pull/1782))
|
||||
|
||||
## [1.6.7] - 2022-07-12
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
sortByDomNode,
|
||||
Focus as FocusManagementFocus,
|
||||
focusFrom,
|
||||
restoreFocusIfNecessary,
|
||||
} from '../../utils/focus-management'
|
||||
import { useOutsideClick } from '../../hooks/use-outside-click'
|
||||
|
||||
@@ -384,7 +385,7 @@ export let MenuItems = defineComponent({
|
||||
dom(_activeItem.dataRef.domRef)?.click()
|
||||
}
|
||||
api.closeMenu()
|
||||
nextTick(() => dom(api.buttonRef)?.focus({ preventScroll: true }))
|
||||
restoreFocusIfNecessary(dom(api.buttonRef))
|
||||
break
|
||||
|
||||
case Keys.ArrowDown:
|
||||
@@ -531,7 +532,7 @@ export let MenuItem = defineComponent({
|
||||
function handleClick(event: MouseEvent) {
|
||||
if (props.disabled) return event.preventDefault()
|
||||
api.closeMenu()
|
||||
nextTick(() => dom(api.buttonRef)?.focus({ preventScroll: true }))
|
||||
restoreFocusIfNecessary(dom(api.buttonRef))
|
||||
}
|
||||
|
||||
function handleFocus() {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { nextTick } from 'vue'
|
||||
import { match } from './match'
|
||||
import { getOwnerDocument } from './owner'
|
||||
|
||||
@@ -92,6 +93,18 @@ export function isFocusableElement(
|
||||
})
|
||||
}
|
||||
|
||||
export function restoreFocusIfNecessary(element: HTMLElement | null) {
|
||||
let ownerDocument = getOwnerDocument(element)
|
||||
nextTick(() => {
|
||||
if (
|
||||
ownerDocument &&
|
||||
!isFocusableElement(ownerDocument.activeElement as HTMLElement, FocusableMode.Strict)
|
||||
) {
|
||||
focusElement(element)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function focusElement(element: HTMLElement | null) {
|
||||
element?.focus({ preventScroll: true })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user