11<template >
22 <div class =" relative" v-if =" threeDotsDropdownItems?.length || customActions?.length || (bulkActions?.some((action: AdminForthBulkActionCommon) => action.showInThreeDotsDropdown))" >
33 <button
4+ ref =" buttonTriggerRef"
45 @click =" toggleDropdownVisibility"
56 class =" flex items-center py-2 px-2 text-sm font-medium text-lightThreeDotsMenuIconDots focus:outline-none bg-lightThreeDotsMenuIconBackground rounded border border-lightThreeDotsMenuIconBackgroundBorder hover:bg-lightThreeDotsMenuIconBackgroundHover hover:text-lightThreeDotsMenuIconDotsHover focus:z-10 focus:ring-4 focus:ring-lightThreeDotsMenuIconFocus dark:focus:ring-darkThreeDotsMenuIconFocus dark:bg-darkThreeDotsMenuIconBackground dark:text-darkThreeDotsMenuIconDots dark:border-darkThreeDotsMenuIconBackgroundBorder dark:hover:text-darkThreeDotsMenuIconDotsHover dark:hover:bg-darkThreeDotsMenuIconBackgroundHover rounded-default"
67 >
1213 <!-- Dropdown menu -->
1314 <div
1415 v-if =" showDropdown"
16+ ref =" dropdownRef"
1517 class =" absolute z-30 right-0 mt-3 bg-lightThreeDotsMenuBodyBackground divide-y divide-gray-100 rounded-lg shadow w-44 dark:bg-darkThreeDotsMenuBodyBackground dark:divide-gray-600" >
1618 <ul class =" py-2 text-sm text-lightThreeDotsMenuBodyText dark:text-darkThreeDotsMenuBodyText" aria-labelledby =" dropdownMenuIconButton" >
1719 <li v-for =" (item, i) in threeDotsDropdownItems" :key =" `dropdown-item-${i}`" >
@@ -82,7 +84,7 @@ import adminforth from '@/adminforth';
8284import { callAdminForthApi } from ' @/utils' ;
8385import { useRoute , useRouter } from ' vue-router' ;
8486import CallActionWrapper from ' @/components/CallActionWrapper.vue'
85- import { ref , type ComponentPublicInstance } from ' vue' ;
87+ import { ref , type ComponentPublicInstance , onMounted , onUnmounted } from ' vue' ;
8688import type { AdminForthBulkActionCommon , AdminForthComponentDeclarationFull } from ' @/types/Common' ;
8789import type { AdminForthActionInput } from ' @/types/Back' ;
8890
@@ -92,6 +94,8 @@ const coreStore = useCoreStore();
9294const router = useRouter ();
9395const threeDotsDropdownItemsRefs = ref <Array <ComponentPublicInstance | null >>([]);
9496const showDropdown = ref (false );
97+ const dropdownRef = ref <HTMLElement | null >(null );
98+ const buttonTriggerRef = ref <HTMLElement | null >(null );
9599
96100const props = defineProps ({
97101 threeDotsDropdownItems: Array < AdminForthComponentDeclarationFull > ,
@@ -182,4 +186,21 @@ async function injectedComponentClick(index: number) {
182186function toggleDropdownVisibility() {
183187 showDropdown .value = ! showDropdown .value ;
184188}
189+
190+ function handleClickOutside(e : MouseEvent ) {
191+ if (! dropdownRef .value ) return
192+
193+ if (! dropdownRef .value .contains (e .target as Node ) && ! buttonTriggerRef .value ?.contains (e .target as Node )) {
194+ showDropdown .value = false ;
195+ }
196+ }
197+
198+ onMounted (() => {
199+ document .addEventListener (' mousedown' , handleClickOutside )
200+ })
201+
202+ onUnmounted (() => {
203+ document .removeEventListener (' mousedown' , handleClickOutside )
204+ })
205+
185206 </script >
0 commit comments