diff --git a/.gitignore b/.gitignore index 94ddae49b..ad703815a 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ console-extensions.md .idea/ scripts/ca.crt scripts/console-client-secret -*.json-* \ No newline at end of file +*.json-* +.codegpt \ No newline at end of file diff --git a/src/utils/components/ActionsDropdown/ActionsDropdown.tsx b/src/utils/components/ActionsDropdown/ActionsDropdown.tsx index ca71cb252..30d500294 100644 --- a/src/utils/components/ActionsDropdown/ActionsDropdown.tsx +++ b/src/utils/components/ActionsDropdown/ActionsDropdown.tsx @@ -2,6 +2,7 @@ import React, { FC, memo, ReactNode, useRef, useState } from 'react'; import DropdownToggle from '@kubevirt-utils/components/toggles/DropdownToggle'; import KebabToggle from '@kubevirt-utils/components/toggles/KebabToggle'; +import { useClickOutside } from '@kubevirt-utils/hooks/useClickOutside/useClickOutside'; import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation'; import { Menu, MenuContent, MenuList, Popper, Tooltip } from '@patternfly/react-core'; @@ -34,6 +35,8 @@ const ActionsDropdown: FC = ({ const toggleRef = useRef(null); const containerRef = useRef(null); + useClickOutside([menuRef, toggleRef], () => setIsOpen(false)); + const onToggle = () => { setIsOpen((prevIsOpen) => { if (onLazyClick && !prevIsOpen) onLazyClick(); @@ -52,18 +55,6 @@ const ActionsDropdown: FC = ({ variant, }); - const menu = ( - - - - {actions?.map((action) => ( - - ))} - - - - ); - if (isDisabled) return (
@@ -77,10 +68,20 @@ const ActionsDropdown: FC = ({
{Toggle(toggleRef)} + + + {actions?.map((action) => ( + + ))} + + + + } appendTo={containerRef.current} isVisible={isOpen} placement="bottom-end" - popper={menu} triggerRef={toggleRef} />
diff --git a/src/utils/components/AddBootableVolumeModal/components/VolumeMetadata/components/InstanceTypeDrilldownSelect/components/ComposableDrilldownSelect/ComposableDrilldownSelect.tsx b/src/utils/components/AddBootableVolumeModal/components/VolumeMetadata/components/InstanceTypeDrilldownSelect/components/ComposableDrilldownSelect/ComposableDrilldownSelect.tsx index e61e20bc7..f6292d6d3 100644 --- a/src/utils/components/AddBootableVolumeModal/components/VolumeMetadata/components/InstanceTypeDrilldownSelect/components/ComposableDrilldownSelect/ComposableDrilldownSelect.tsx +++ b/src/utils/components/AddBootableVolumeModal/components/VolumeMetadata/components/InstanceTypeDrilldownSelect/components/ComposableDrilldownSelect/ComposableDrilldownSelect.tsx @@ -37,7 +37,8 @@ const ComposableDrilldownSelect: FC = ({ const [menuDrilledIn, setMenuDrilledIn] = useState([]); const [drilldownPath, setDrilldownPath] = useState([]); const [menuHeights, setMenuHeights] = useState({}); - const ref = useRef(null); + const menuRef = useRef(null); + const toggleRef = useRef(null); const onToggleClick = (ev?: React.MouseEvent) => { ev?.stopPropagation(); // Stop handleClickOutside from handling @@ -73,7 +74,7 @@ const ComposableDrilldownSelect: FC = ({ } }; - useClickOutside(ref, onToggleClick); + useClickOutside([menuRef], onToggleClick); return ( = ({ onDrillIn={drillIn} onDrillOut={drillOut} onGetMenuHeight={setHeight} - ref={ref} + ref={menuRef} > {children} @@ -96,7 +97,7 @@ const ComposableDrilldownSelect: FC = ({ } trigger={ - + {toggleLabel} } diff --git a/src/utils/hooks/useClickOutside/useClickOutside.ts b/src/utils/hooks/useClickOutside/useClickOutside.ts index 7f4590363..e7c326fc1 100644 --- a/src/utils/hooks/useClickOutside/useClickOutside.ts +++ b/src/utils/hooks/useClickOutside/useClickOutside.ts @@ -1,24 +1,24 @@ -import { RefObject, useEffect } from 'react'; +import { MutableRefObject, useEffect } from 'react'; import { CLICK, ESCAPE, KEYDOWN, TAB } from './constants'; -export const useClickOutside = ( - ref: RefObject, +export const useClickOutside = ( + refs: MutableRefObject[], onClickOutside: () => void, ) => { useEffect(() => { const handleClickOutside = (event: MouseEvent) => { - if (ref?.current && !ref?.current.contains(event.target as Node)) { + if (refs?.every((ref) => ref?.current && !ref?.current.contains(event.target as Node))) { onClickOutside(); } }; - const handleMenuKeys = (event) => { - if (ref?.current) { - if (event?.key === ESCAPE) { - onClickOutside(); - } - if (!ref?.current?.contains(event?.target) && event?.key === TAB) { + const handleMenuKeys = (event: KeyboardEvent) => { + if (event?.key === ESCAPE) { + onClickOutside(); + } else if (event.key === TAB) { + // Check if the focus is outside all provided refs + if (refs.every((ref) => ref.current && !ref.current.contains(event.target as Node))) { onClickOutside(); } } @@ -31,5 +31,5 @@ export const useClickOutside = ( window?.removeEventListener(KEYDOWN, handleMenuKeys); document.removeEventListener(CLICK, handleClickOutside); }; - }, [ref, onClickOutside]); + }, [refs, onClickOutside]); }; diff --git a/src/views/catalog/CreateFromInstanceTypes/components/SelectInstanceTypeSection/hooks/useInstanceTypeCardMenuSection.ts b/src/views/catalog/CreateFromInstanceTypes/components/SelectInstanceTypeSection/hooks/useInstanceTypeCardMenuSection.ts index 8515a1e9f..c5dc641b8 100644 --- a/src/views/catalog/CreateFromInstanceTypes/components/SelectInstanceTypeSection/hooks/useInstanceTypeCardMenuSection.ts +++ b/src/views/catalog/CreateFromInstanceTypes/components/SelectInstanceTypeSection/hooks/useInstanceTypeCardMenuSection.ts @@ -32,7 +32,7 @@ const useInstanceTypeCardMenuSection = (): UseInstanceTypeCardMenuSectionValues }); }; - useClickOutside(menuRef, onMenuToggle); + useClickOutside([menuRef], onMenuToggle); return { activeMenu, menuRef, onMenuSelect, onMenuToggle }; };