@@ -181,7 +181,7 @@ export function Listbox<
|
||||
|
||||
if (!optionsRef.current?.contains(target)) dispatch({ type: ActionTypes.CloseListbox })
|
||||
if (active !== document.body && active?.contains(target)) return // Keep focus on newly clicked/focused element
|
||||
if (!event.defaultPrevented) buttonRef.current?.focus()
|
||||
if (!event.defaultPrevented) buttonRef.current?.focus({ preventScroll: true })
|
||||
}
|
||||
|
||||
window.addEventListener('click', handler)
|
||||
@@ -237,7 +237,7 @@ const Button = forwardRefWithAs(function Button<
|
||||
event.preventDefault()
|
||||
dispatch({ type: ActionTypes.OpenListbox })
|
||||
d.nextFrame(() => {
|
||||
state.optionsRef.current?.focus()
|
||||
state.optionsRef.current?.focus({ preventScroll: true })
|
||||
if (!state.propsRef.current.value)
|
||||
dispatch({ type: ActionTypes.GoToOption, focus: Focus.First })
|
||||
})
|
||||
@@ -247,7 +247,7 @@ const Button = forwardRefWithAs(function Button<
|
||||
event.preventDefault()
|
||||
dispatch({ type: ActionTypes.OpenListbox })
|
||||
d.nextFrame(() => {
|
||||
state.optionsRef.current?.focus()
|
||||
state.optionsRef.current?.focus({ preventScroll: true })
|
||||
if (!state.propsRef.current.value)
|
||||
dispatch({ type: ActionTypes.GoToOption, focus: Focus.Last })
|
||||
})
|
||||
@@ -262,11 +262,11 @@ const Button = forwardRefWithAs(function Button<
|
||||
if (props.disabled) return
|
||||
if (state.listboxState === ListboxStates.Open) {
|
||||
dispatch({ type: ActionTypes.CloseListbox })
|
||||
d.nextFrame(() => state.buttonRef.current?.focus())
|
||||
d.nextFrame(() => state.buttonRef.current?.focus({ preventScroll: true }))
|
||||
} else {
|
||||
event.preventDefault()
|
||||
dispatch({ type: ActionTypes.OpenListbox })
|
||||
d.nextFrame(() => state.optionsRef.current?.focus())
|
||||
d.nextFrame(() => state.optionsRef.current?.focus({ preventScroll: true }))
|
||||
}
|
||||
},
|
||||
[dispatch, d, state, props.disabled]
|
||||
@@ -309,9 +309,10 @@ function Label<TTag extends React.ElementType = typeof DEFAULT_LABEL_TAG>(
|
||||
const [state] = useListboxContext([Listbox.name, Label.name].join('.'))
|
||||
const id = `headlessui-listbox-label-${useId()}`
|
||||
|
||||
const handlePointerUp = React.useCallback(() => state.buttonRef.current?.focus(), [
|
||||
state.buttonRef,
|
||||
])
|
||||
const handlePointerUp = React.useCallback(
|
||||
() => state.buttonRef.current?.focus({ preventScroll: true }),
|
||||
[state.buttonRef]
|
||||
)
|
||||
|
||||
const propsBag = React.useMemo<OptionsRenderPropArg>(
|
||||
() => ({ open: state.listboxState === ListboxStates.Open }),
|
||||
@@ -370,7 +371,7 @@ const Options = forwardRefWithAs(function Options<
|
||||
const { dataRef } = state.options[state.activeOptionIndex]
|
||||
state.propsRef.current.onChange(dataRef.current.value)
|
||||
}
|
||||
disposables().nextFrame(() => state.buttonRef.current?.focus())
|
||||
disposables().nextFrame(() => state.buttonRef.current?.focus({ preventScroll: true }))
|
||||
break
|
||||
|
||||
case Keys.ArrowDown:
|
||||
@@ -394,7 +395,7 @@ const Options = forwardRefWithAs(function Options<
|
||||
case Keys.Escape:
|
||||
event.preventDefault()
|
||||
dispatch({ type: ActionTypes.CloseListbox })
|
||||
return d.nextFrame(() => state.buttonRef.current?.focus())
|
||||
return d.nextFrame(() => state.buttonRef.current?.focus({ preventScroll: true }))
|
||||
|
||||
case Keys.Tab:
|
||||
return event.preventDefault()
|
||||
@@ -516,7 +517,7 @@ function Option<
|
||||
if (disabled) return event.preventDefault()
|
||||
select()
|
||||
dispatch({ type: ActionTypes.CloseListbox })
|
||||
disposables().nextFrame(() => state.buttonRef.current?.focus())
|
||||
disposables().nextFrame(() => state.buttonRef.current?.focus({ preventScroll: true }))
|
||||
},
|
||||
[dispatch, state.buttonRef, disabled, select]
|
||||
)
|
||||
|
||||
@@ -157,7 +157,7 @@ export function Menu<TTag extends React.ElementType = typeof DEFAULT_MENU_TAG>(
|
||||
|
||||
if (!itemsRef.current?.contains(target)) dispatch({ type: ActionTypes.CloseMenu })
|
||||
if (active !== document.body && active?.contains(target)) return // Keep focus on newly clicked/focused element
|
||||
if (!event.defaultPrevented) buttonRef.current?.focus()
|
||||
if (!event.defaultPrevented) buttonRef.current?.focus({ preventScroll: true })
|
||||
}
|
||||
|
||||
window.addEventListener('click', handler)
|
||||
@@ -209,7 +209,7 @@ const Button = forwardRefWithAs(function Button<
|
||||
event.preventDefault()
|
||||
dispatch({ type: ActionTypes.OpenMenu })
|
||||
d.nextFrame(() => {
|
||||
state.itemsRef.current?.focus()
|
||||
state.itemsRef.current?.focus({ preventScroll: true })
|
||||
dispatch({ type: ActionTypes.GoToItem, focus: Focus.First })
|
||||
})
|
||||
break
|
||||
@@ -218,7 +218,7 @@ const Button = forwardRefWithAs(function Button<
|
||||
event.preventDefault()
|
||||
dispatch({ type: ActionTypes.OpenMenu })
|
||||
d.nextFrame(() => {
|
||||
state.itemsRef.current?.focus()
|
||||
state.itemsRef.current?.focus({ preventScroll: true })
|
||||
dispatch({ type: ActionTypes.GoToItem, focus: Focus.Last })
|
||||
})
|
||||
break
|
||||
@@ -232,11 +232,11 @@ const Button = forwardRefWithAs(function Button<
|
||||
if (props.disabled) return
|
||||
if (state.menuState === MenuStates.Open) {
|
||||
dispatch({ type: ActionTypes.CloseMenu })
|
||||
d.nextFrame(() => state.buttonRef.current?.focus())
|
||||
d.nextFrame(() => state.buttonRef.current?.focus({ preventScroll: true }))
|
||||
} else {
|
||||
event.preventDefault()
|
||||
dispatch({ type: ActionTypes.OpenMenu })
|
||||
d.nextFrame(() => state.itemsRef.current?.focus())
|
||||
d.nextFrame(() => state.itemsRef.current?.focus({ preventScroll: true }))
|
||||
}
|
||||
},
|
||||
[dispatch, d, state, props.disabled]
|
||||
@@ -306,7 +306,7 @@ const Items = forwardRefWithAs(function Items<
|
||||
const { id } = state.items[state.activeItemIndex]
|
||||
document.getElementById(id)?.click()
|
||||
}
|
||||
disposables().nextFrame(() => state.buttonRef.current?.focus())
|
||||
disposables().nextFrame(() => state.buttonRef.current?.focus({ preventScroll: true }))
|
||||
break
|
||||
|
||||
case Keys.ArrowDown:
|
||||
@@ -330,7 +330,7 @@ const Items = forwardRefWithAs(function Items<
|
||||
case Keys.Escape:
|
||||
event.preventDefault()
|
||||
dispatch({ type: ActionTypes.CloseMenu })
|
||||
disposables().nextFrame(() => state.buttonRef.current?.focus())
|
||||
disposables().nextFrame(() => state.buttonRef.current?.focus({ preventScroll: true }))
|
||||
break
|
||||
|
||||
case Keys.Tab:
|
||||
@@ -415,7 +415,7 @@ function Item<TTag extends React.ElementType = typeof DEFAULT_ITEM_TAG>(
|
||||
(event: { preventDefault: Function }) => {
|
||||
if (disabled) return event.preventDefault()
|
||||
dispatch({ type: ActionTypes.CloseMenu })
|
||||
disposables().nextFrame(() => state.buttonRef.current?.focus())
|
||||
disposables().nextFrame(() => state.buttonRef.current?.focus({ preventScroll: true }))
|
||||
if (onClick) return onClick(event)
|
||||
},
|
||||
[dispatch, state.buttonRef, disabled, onClick]
|
||||
|
||||
@@ -134,7 +134,7 @@ function Label<TTag extends React.ElementType = typeof DEFAULT_LABEL_TAG>(
|
||||
const handlePointerUp = React.useCallback(() => {
|
||||
if (!state.switch) return
|
||||
state.switch.click()
|
||||
state.switch.focus()
|
||||
state.switch.focus({ preventScroll: true })
|
||||
}, [state.switch])
|
||||
|
||||
const propsWeControl = { ref: state.setLabel, id, onPointerUp: handlePointerUp }
|
||||
|
||||
@@ -167,7 +167,7 @@ export const Listbox = defineComponent({
|
||||
|
||||
if (!optionsRef.value?.contains(target)) api.closeListbox()
|
||||
if (active !== document.body && active?.contains(target)) return // Keep focus on newly clicked/focused element
|
||||
if (!event.defaultPrevented) buttonRef.value?.focus()
|
||||
if (!event.defaultPrevented) buttonRef.value?.focus({ preventScroll: true })
|
||||
}
|
||||
|
||||
window.addEventListener('click', handler)
|
||||
@@ -210,7 +210,7 @@ export const ListboxLabel = defineComponent({
|
||||
id,
|
||||
el: api.labelRef,
|
||||
handlePointerUp() {
|
||||
api.buttonRef.value?.focus()
|
||||
api.buttonRef.value?.focus({ preventScroll: true })
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -263,7 +263,7 @@ export const ListboxButton = defineComponent({
|
||||
event.preventDefault()
|
||||
api.openListbox()
|
||||
nextTick(() => {
|
||||
api.optionsRef.value?.focus()
|
||||
api.optionsRef.value?.focus({ preventScroll: true })
|
||||
if (!api.value.value) api.goToOption(Focus.First)
|
||||
})
|
||||
break
|
||||
@@ -272,7 +272,7 @@ export const ListboxButton = defineComponent({
|
||||
event.preventDefault()
|
||||
api.openListbox()
|
||||
nextTick(() => {
|
||||
api.optionsRef.value?.focus()
|
||||
api.optionsRef.value?.focus({ preventScroll: true })
|
||||
if (!api.value.value) api.goToOption(Focus.Last)
|
||||
})
|
||||
break
|
||||
@@ -283,11 +283,11 @@ export const ListboxButton = defineComponent({
|
||||
if (props.disabled) return
|
||||
if (api.listboxState.value === ListboxStates.Open) {
|
||||
api.closeListbox()
|
||||
nextTick(() => api.buttonRef.value?.focus())
|
||||
nextTick(() => api.buttonRef.value?.focus({ preventScroll: true }))
|
||||
} else {
|
||||
event.preventDefault()
|
||||
api.openListbox()
|
||||
nextFrame(() => api.optionsRef.value?.focus())
|
||||
nextFrame(() => api.optionsRef.value?.focus({ preventScroll: true }))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ export const ListboxOptions = defineComponent({
|
||||
api.select(dataRef.value)
|
||||
}
|
||||
api.closeListbox()
|
||||
nextTick(() => api.buttonRef.value?.focus())
|
||||
nextTick(() => api.buttonRef.value?.focus({ preventScroll: true }))
|
||||
break
|
||||
|
||||
case Keys.ArrowDown:
|
||||
@@ -380,7 +380,7 @@ export const ListboxOptions = defineComponent({
|
||||
case Keys.Escape:
|
||||
event.preventDefault()
|
||||
api.closeListbox()
|
||||
nextTick(() => api.buttonRef.value?.focus())
|
||||
nextTick(() => api.buttonRef.value?.focus({ preventScroll: true }))
|
||||
break
|
||||
|
||||
case Keys.Tab:
|
||||
@@ -456,7 +456,7 @@ export const ListboxOption = defineComponent({
|
||||
if (disabled) return event.preventDefault()
|
||||
api.select(value)
|
||||
api.closeListbox()
|
||||
nextTick(() => api.buttonRef.value?.focus())
|
||||
nextTick(() => api.buttonRef.value?.focus({ preventScroll: true }))
|
||||
}
|
||||
|
||||
function handleFocus() {
|
||||
|
||||
@@ -144,7 +144,7 @@ export const Menu = defineComponent({
|
||||
|
||||
if (!itemsRef.value?.contains(target)) api.closeMenu()
|
||||
if (active !== document.body && active?.contains(target)) return // Keep focus on newly clicked/focused element
|
||||
if (!event.defaultPrevented) buttonRef.value?.focus()
|
||||
if (!event.defaultPrevented) buttonRef.value?.focus({ preventScroll: true })
|
||||
}
|
||||
|
||||
window.addEventListener('click', handler)
|
||||
@@ -202,7 +202,7 @@ export const MenuButton = defineComponent({
|
||||
event.preventDefault()
|
||||
api.openMenu()
|
||||
nextTick(() => {
|
||||
api.itemsRef.value?.focus()
|
||||
api.itemsRef.value?.focus({ preventScroll: true })
|
||||
api.goToItem(Focus.First)
|
||||
})
|
||||
break
|
||||
@@ -211,7 +211,7 @@ export const MenuButton = defineComponent({
|
||||
event.preventDefault()
|
||||
api.openMenu()
|
||||
nextTick(() => {
|
||||
api.itemsRef.value?.focus()
|
||||
api.itemsRef.value?.focus({ preventScroll: true })
|
||||
api.goToItem(Focus.Last)
|
||||
})
|
||||
break
|
||||
@@ -222,11 +222,11 @@ export const MenuButton = defineComponent({
|
||||
if (props.disabled) return
|
||||
if (api.menuState.value === MenuStates.Open) {
|
||||
api.closeMenu()
|
||||
nextTick(() => api.buttonRef.value?.focus())
|
||||
nextTick(() => api.buttonRef.value?.focus({ preventScroll: true }))
|
||||
} else {
|
||||
event.preventDefault()
|
||||
api.openMenu()
|
||||
nextFrame(() => api.itemsRef.value?.focus())
|
||||
nextFrame(() => api.itemsRef.value?.focus({ preventScroll: true }))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ export const MenuItems = defineComponent({
|
||||
document.getElementById(id)?.click()
|
||||
}
|
||||
api.closeMenu()
|
||||
nextTick(() => api.buttonRef.value?.focus())
|
||||
nextTick(() => api.buttonRef.value?.focus({ preventScroll: true }))
|
||||
break
|
||||
|
||||
case Keys.ArrowDown:
|
||||
@@ -321,7 +321,7 @@ export const MenuItems = defineComponent({
|
||||
case Keys.Escape:
|
||||
event.preventDefault()
|
||||
api.closeMenu()
|
||||
nextTick(() => api.buttonRef.value?.focus())
|
||||
nextTick(() => api.buttonRef.value?.focus({ preventScroll: true }))
|
||||
break
|
||||
|
||||
case Keys.Tab:
|
||||
@@ -373,7 +373,7 @@ export const MenuItem = defineComponent({
|
||||
function handleClick(event: MouseEvent) {
|
||||
if (disabled) return event.preventDefault()
|
||||
api.closeMenu()
|
||||
nextTick(() => api.buttonRef.value?.focus())
|
||||
nextTick(() => api.buttonRef.value?.focus({ preventScroll: true }))
|
||||
}
|
||||
|
||||
function handleFocus() {
|
||||
|
||||
@@ -136,7 +136,7 @@ export const SwitchLabel = defineComponent({
|
||||
el: api.labelRef,
|
||||
handlePointerUp() {
|
||||
api.switchRef.value?.click()
|
||||
api.switchRef.value?.focus()
|
||||
api.switchRef.value?.focus({ preventScroll: true })
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user