feat(primitives): add menu, dropdown-menu, context-menu, and menubar primitives
Implements WAI-ARIA APG-compliant headless menu primitive families: - menu: base primitive with MenuRoot, MenuContent, MenuItem, MenuCheckboxItem, MenuRadioGroup/Item, MenuSub, and helpers - dropdown-menu: DropdownMenuRoot with trigger anchoring - context-menu: ContextMenuRoot with right-click virtual anchor - menubar: MenubarRoot with keyboard navigation between menus Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
<script lang="ts">
|
||||
import type { Direction } from '../config-provider';
|
||||
|
||||
export interface MenuRootProps {
|
||||
open?: boolean;
|
||||
dir?: Direction;
|
||||
modal?: boolean;
|
||||
}
|
||||
export interface MenuRootEmits {
|
||||
'update:open': [value: boolean];
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { shallowRef, toRef } from 'vue';
|
||||
|
||||
import { useConfig } from '../config-provider';
|
||||
import { PopperRoot } from '../popper';
|
||||
import { provideMenuContext, provideMenuRootContext } from './context';
|
||||
import { useIsUsingKeyboard } from './useIsUsingKeyboard';
|
||||
|
||||
const {
|
||||
open = false,
|
||||
dir: dirProp,
|
||||
modal = true,
|
||||
} = defineProps<MenuRootProps>();
|
||||
|
||||
const emit = defineEmits<MenuRootEmits>();
|
||||
|
||||
defineSlots<{ default?: () => unknown }>();
|
||||
|
||||
const config = useConfig();
|
||||
const dirRef = toRef(() => dirProp ?? config.dir.value);
|
||||
const isUsingKeyboardRef = useIsUsingKeyboard();
|
||||
const content = shallowRef<HTMLElement | null>(null);
|
||||
const openRef = toRef(() => open);
|
||||
|
||||
provideMenuContext({
|
||||
open: openRef,
|
||||
onOpenChange: v => emit('update:open', v),
|
||||
content,
|
||||
onContentChange: (el) => { content.value = el; },
|
||||
});
|
||||
|
||||
provideMenuRootContext({
|
||||
onClose: () => emit('update:open', false),
|
||||
dir: dirRef,
|
||||
isUsingKeyboardRef,
|
||||
modal: toRef(() => modal),
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PopperRoot>
|
||||
<slot />
|
||||
</PopperRoot>
|
||||
</template>
|
||||
Reference in New Issue
Block a user