diff --git a/frontend/src/components/SimulationList.tsx b/frontend/src/components/SimulationList.tsx index a158a23..2028e9d 100644 --- a/frontend/src/components/SimulationList.tsx +++ b/frontend/src/components/SimulationList.tsx @@ -1,4 +1,4 @@ -import { useRef, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { ChevronDown, Plus } from 'lucide-react'; import { extractApiError } from '@/api/client'; @@ -26,9 +26,27 @@ function NewSimulationDropdown({ engagementId }: { engagementId: number }): JSX. const { push } = useToast(); const [open, setOpen] = useState(false); const [showPicker, setShowPicker] = useState(false); - const btnRef = useRef(null); + const ref = useRef(null); const createMutation = useCreateSimulation(engagementId); + useEffect(() => { + if (!open) return; + const onPointerDown = (e: PointerEvent) => { + if (ref.current && !ref.current.contains(e.target as Node)) { + setOpen(false); + } + }; + const onKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Escape') setOpen(false); + }; + document.addEventListener('pointerdown', onPointerDown); + document.addEventListener('keydown', onKeyDown); + return () => { + document.removeEventListener('pointerdown', onPointerDown); + document.removeEventListener('keydown', onKeyDown); + }; + }, [open]); + const handleBlank = () => { setOpen(false); navigate(`/engagements/${engagementId}/simulations/new`); @@ -51,7 +69,7 @@ function NewSimulationDropdown({ engagementId }: { engagementId: number }): JSX. }; return ( -
+