From 54ce4b02d524ddbbe37dbe3da5f48b4fdc9bbdce Mon Sep 17 00:00:00 2001 From: Timothy Asir Jeyasingh Date: Mon, 23 Sep 2024 19:10:48 +0530 Subject: [PATCH] Fix the kebab menu close when we click outside the kebab. BZ: https://bugzilla.redhat.com/show_bug.cgi?id=2308314 Jira: https://issues.redhat.com/browse/DFBUGS-351 Signed-off-by: Timothy Asir Jeyasingh --- packages/shared/src/kebab/kebab.tsx | 37 +++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/packages/shared/src/kebab/kebab.tsx b/packages/shared/src/kebab/kebab.tsx index d0adac0d6..3da213c0f 100644 --- a/packages/shared/src/kebab/kebab.tsx +++ b/packages/shared/src/kebab/kebab.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { useEffect } from 'react'; import { getNamespace, getName } from '@odf/shared/selectors'; import { K8sResourceCommon, @@ -21,6 +22,32 @@ import { ModalKeys, defaultModalMap } from '../modals/types'; import { useCustomTranslation } from '../useCustomTranslationHook'; import { referenceForModel } from '../utils'; +const useClickOutside = ( + ref: React.RefObject, + callback: () => void +) => { + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (ref.current && !ref.current.contains(event.target as Node)) { + callback(); + } + }; + + const handleEscapeKey = (event: KeyboardEvent) => { + if (event.key === 'Escape') { + callback(); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + document.addEventListener('keydown', handleEscapeKey); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + document.removeEventListener('keydown', handleEscapeKey); + }; + }, [ref, callback]); +}; + export type CustomKebabItem = { key: string; value: string; @@ -101,19 +128,18 @@ export const Kebab: React.FC & KebabStaticProperties = ({ hideItems, }) => { const { t } = useCustomTranslation(); - const launchModal = useModal(); - const eventRef = React.useRef(undefined); const dropdownToggleRef = React.useRef(); const [toggleDirection, setToggleDirection] = React.useState('down'); const [isOpen, setOpen] = React.useState(false); - const { resourceModel, resource } = extraProps; + // Use the custom hook to detect clicks outside the Kebab menu + useClickOutside(dropdownToggleRef, () => setOpen(false)); + const { resourceModel, resource } = extraProps; const resourceLabel = resourceModel.label; - const navigate = useNavigate(); const [canCreate, createLoading] = useAccessReview({ @@ -237,6 +263,7 @@ export const Kebab: React.FC & KebabStaticProperties = ({ const content = _.has(resource.metadata, 'deletionTimestamp') ? terminatingTooltip || t('Resource is being deleted.') : ''; + return ( & KebabStaticProperties = ({ ref={dropdownToggleRef} aria-label="Dropdown toggle" variant={toggleType === 'Kebab' ? 'plain' : 'default'} - onClick={() => setOpen((o) => !o)} + onClick={() => setOpen(!isOpen)} isExpanded={isOpen} data-test="kebab-button" isDisabled={isDisabled}