58 lines
1.7 KiB
Vue
58 lines
1.7 KiB
Vue
<template>
|
|
<DropdownMenuRoot>
|
|
<DropdownMenuTrigger :disabled="disabled" ><slot /></DropdownMenuTrigger>
|
|
|
|
<DropdownMenuPortal>
|
|
<DropdownMenuContent :align="align" :side="side" class="z-50 outline-none bg-light-20 dark:bg-dark-20 will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade border border-light-35 dark:border-dark-35">
|
|
<DropdownContentRender :options="options" />
|
|
|
|
<DropdownMenuArrow class="fill-light-35 dark:fill-dark-35" />
|
|
</DropdownMenuContent>
|
|
</DropdownMenuPortal>
|
|
</DropdownMenuRoot>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
export interface DropdownItem {
|
|
type: 'item';
|
|
label: string;
|
|
disabled?: boolean;
|
|
select?: () => void;
|
|
icon?: string;
|
|
kbd?: string;
|
|
}
|
|
export interface DropdownCheckbox {
|
|
type: 'checkbox';
|
|
label: string;
|
|
disabled?: boolean;
|
|
checked?: boolean | Ref<boolean>
|
|
select?: (state: boolean) => void;
|
|
kbd?: string;
|
|
}
|
|
export interface DropdownRadioGroup {
|
|
type: 'radio';
|
|
label: string;
|
|
value?: string | Ref<string>
|
|
items: (string | {label: string, value?: string, disabled?: boolean})[];
|
|
change?: (value: string) => void;
|
|
}
|
|
export interface DropdownSubmenu {
|
|
type: 'submenu';
|
|
label: string;
|
|
disabled?: boolean;
|
|
items: DropdownOption[];
|
|
icon?: string;
|
|
}
|
|
export interface DropdownGroup {
|
|
type: 'group';
|
|
label?: string;
|
|
items: DropdownOption[];
|
|
}
|
|
export type DropdownOption = DropdownItem | DropdownCheckbox | DropdownRadioGroup | DropdownSubmenu | DropdownGroup;
|
|
const { options, disabled = false, side, align } = defineProps<{
|
|
options: DropdownOption[]
|
|
disabled?: boolean
|
|
side?: 'top' | 'right' | 'bottom' | 'left'
|
|
align?: 'start' | 'center' | 'end'
|
|
}>();
|
|
</script> |