vite-plugin-entry-shaking-debugger
Version:
Debugger for vite-plugin-entry-shaking
54 lines (46 loc) • 1.71 kB
text/typescript
import type { Ref } from 'vue';
import { ref, toRef, watch, watchEffect } from 'vue';
import { isComponentInstance } from '#utils';
import type { ButtonInstance } from '@components/Button/Button.types';
import { useMenu } from '@composables/useMenu';
import type { DropdownMenuProps } from './DropdownMenu.types';
const NAVIGATION_KEYS = ['ArrowUp', 'ArrowDown', 'PageUp', 'PageDown', 'Home', 'End'];
export function useDropdownMenu(
props: DropdownMenuProps,
emit: any,
items: Ref<(ButtonInstance | HTMLButtonElement | null)[]>,
) {
const isOpen = toRef(props, 'isOpen');
const isTransitioning = toRef(props, 'isTransitioning');
const menuItems = ref<(HTMLButtonElement | null)[]>([]);
const menu = useMenu('y', menuItems);
let originActiveItem = document.activeElement;
const handleKeydown = (event: KeyboardEvent) => {
if (!NAVIGATION_KEYS.includes(event.key)) return;
if (event.key === 'Escape') return emit('close');
menu.handleKeydown(event);
};
watchEffect(() => {
menuItems.value = items.value.map((item) =>
isComponentInstance(item) ? item!.reference : item,
);
});
// Autofocus first menu item when opening the dropdown.
watch(isOpen, (isPopoverOpen) => {
if (isPopoverOpen) {
originActiveItem = document.activeElement;
menuItems.value[0]?.classList.add('active');
menu.setFirstItem();
} else {
(originActiveItem as HTMLElement).focus();
}
});
// CSS Transitions prevent focus.
watch(isTransitioning, (isPopoverTransitioning) => {
if (!isPopoverTransitioning) {
menuItems.value[0]?.classList.remove('active');
menu.focusActiveItem();
}
});
return { handleKeydown };
}