From 9e05bbe8d8b87b07c41259ddac635ea433bee360 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Fri, 5 Feb 2021 18:09:41 +0100 Subject: [PATCH] ensure the active MenuItem is scrolled into view Fixes: #227 --- .../@headlessui-react/src/components/listbox/listbox.tsx | 2 +- packages/@headlessui-react/src/components/menu/menu.tsx | 8 ++++++++ packages/@headlessui-vue/src/components/menu/menu.ts | 7 +++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/@headlessui-react/src/components/listbox/listbox.tsx b/packages/@headlessui-react/src/components/listbox/listbox.tsx index eb1c3a2..4a3ec54 100644 --- a/packages/@headlessui-react/src/components/listbox/listbox.tsx +++ b/packages/@headlessui-react/src/components/listbox/listbox.tsx @@ -537,7 +537,7 @@ function Option< let d = disposables() d.nextFrame(() => document.getElementById(id)?.scrollIntoView?.({ block: 'nearest' })) return d.dispose - }, [active, state.listboxState]) + }, [id, active, state.listboxState]) let handleClick = useCallback( (event: { preventDefault: Function }) => { diff --git a/packages/@headlessui-react/src/components/menu/menu.tsx b/packages/@headlessui-react/src/components/menu/menu.tsx index 68cf69d..5254ad6 100644 --- a/packages/@headlessui-react/src/components/menu/menu.tsx +++ b/packages/@headlessui-react/src/components/menu/menu.tsx @@ -423,6 +423,14 @@ function Item( let id = `headlessui-menu-item-${useId()}` let active = state.activeItemIndex !== null ? state.items[state.activeItemIndex].id === id : false + useIsoMorphicEffect(() => { + if (state.menuState !== MenuStates.Open) return + if (!active) return + let d = disposables() + d.nextFrame(() => document.getElementById(id)?.scrollIntoView?.({ block: 'nearest' })) + return d.dispose + }, [id, active, state.menuState]) + let bag = useRef({ disabled }) useIsoMorphicEffect(() => { diff --git a/packages/@headlessui-vue/src/components/menu/menu.ts b/packages/@headlessui-vue/src/components/menu/menu.ts index 1bc3201..1181e07 100644 --- a/packages/@headlessui-vue/src/components/menu/menu.ts +++ b/packages/@headlessui-vue/src/components/menu/menu.ts @@ -9,6 +9,7 @@ import { nextTick, InjectionKey, Ref, + watchEffect, } from 'vue' import { Features, render } from '../../utils/render' import { useId } from '../../hooks/use-id' @@ -370,6 +371,12 @@ export let MenuItem = defineComponent({ onMounted(() => api.registerItem(id, dataRef)) onUnmounted(() => api.unregisterItem(id)) + watchEffect(() => { + if (api.menuState.value !== MenuStates.Open) return + if (!active.value) return + nextTick(() => document.getElementById(id)?.scrollIntoView?.({ block: 'nearest' })) + }) + function handleClick(event: MouseEvent) { if (disabled) return event.preventDefault() api.closeMenu()