From d61aa77b520a1663c5e9201097775674776683d9 Mon Sep 17 00:00:00 2001 From: Lily Delalande <119957291+lily-de@users.noreply.github.com> Date: Tue, 1 Apr 2025 21:10:10 -0400 Subject: [PATCH] ui: settings v2 click anywhere to exit models bottom bar (#1997) --- .../models/bottom_bar/ModelsBottomBar.tsx | 87 ++++++++++++------- 1 file changed, 55 insertions(+), 32 deletions(-) diff --git a/ui/desktop/src/components/settings_v2/models/bottom_bar/ModelsBottomBar.tsx b/ui/desktop/src/components/settings_v2/models/bottom_bar/ModelsBottomBar.tsx index 3391ff7d..4e9c7941 100644 --- a/ui/desktop/src/components/settings_v2/models/bottom_bar/ModelsBottomBar.tsx +++ b/ui/desktop/src/components/settings_v2/models/bottom_bar/ModelsBottomBar.tsx @@ -1,6 +1,6 @@ import { ChevronDown, ChevronUp } from '../../../icons'; import { Sliders } from 'lucide-react'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useRef } from 'react'; import { useConfig } from '../../../ConfigContext'; import { getCurrentModelAndProviderForDisplay } from '../index'; import { AddModelModal } from '../subcomponents/AddModelModal'; @@ -16,6 +16,7 @@ export default function ModelsBottomBar({ dropdownRef, setView }: ModelsBottomBa const [provider, setProvider] = useState(null); const [model, setModel] = useState(''); const [isAddModelModalOpen, setIsAddModelModalOpen] = useState(false); + const menuRef = useRef(null); useEffect(() => { (async () => { @@ -28,42 +29,64 @@ export default function ModelsBottomBar({ dropdownRef, setView }: ModelsBottomBa })(); }, [read, getProviders]); + // Add click outside handler + useEffect(() => { + function handleClickOutside(event: MouseEvent) { + if (menuRef.current && !menuRef.current.contains(event.target as Node)) { + setIsModelMenuOpen(false); + } + } + + // Add the event listener when the menu is open + if (isModelMenuOpen) { + document.addEventListener('mousedown', handleClickOutside); + } + + // Clean up the event listener + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, [isModelMenuOpen]); + return (
-
setIsModelMenuOpen(!isModelMenuOpen)} - > - {model} - {isModelMenuOpen ? ( - - ) : ( - +
+
setIsModelMenuOpen(!isModelMenuOpen)} + > + {model} + {isModelMenuOpen ? ( + + ) : ( + + )} +
+ + {/* Dropdown Menu */} + {isModelMenuOpen && ( +
+
+
Current:
+
+ {model} -- {provider} +
+
{ + setIsModelMenuOpen(false); + setIsAddModelModalOpen(true); + }} + > + Change Model + +
+
+
)}
- {/* Dropdown Menu */} - {isModelMenuOpen && ( -
-
-
Current:
-
- {model} -- {provider} -
-
{ - setIsModelMenuOpen(false); - setIsAddModelModalOpen(true); - }} - > - Change Model - -
-
-
- )} {isAddModelModalOpen ? ( setIsAddModelModalOpen(false)} /> ) : null}