From 167e64534f4bdbc1cae8185a11c68d44597b49de Mon Sep 17 00:00:00 2001 From: corpi Date: Tue, 17 Mar 2026 21:11:28 +0900 Subject: [PATCH] refactor(space): refine thought orb interaction --- src/widgets/space-focus-hud/ui/ThoughtOrb.tsx | 70 +++++++++++++------ 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/src/widgets/space-focus-hud/ui/ThoughtOrb.tsx b/src/widgets/space-focus-hud/ui/ThoughtOrb.tsx index b20ed2a..17bfd4a 100644 --- a/src/widgets/space-focus-hud/ui/ThoughtOrb.tsx +++ b/src/widgets/space-focus-hud/ui/ThoughtOrb.tsx @@ -13,6 +13,7 @@ export const ThoughtOrb = ({ isFocusMode, onCaptureThought }: ThoughtOrbProps) = const [draft, setDraft] = useState(''); const [isAbsorbing, setIsAbsorbing] = useState(false); const inputRef = useRef(null); + const containerRef = useRef(null); useEffect(() => { if (isOpen && inputRef.current) { @@ -26,12 +27,24 @@ export const ThoughtOrb = ({ isFocusMode, onCaptureThought }: ThoughtOrbProps) = const handleEscape = (e: KeyboardEvent) => { if (e.key === 'Escape') { setIsOpen(false); - setDraft(''); + // Slightly delay clearing text to allow fade out animation + setTimeout(() => setDraft(''), 300); + } + }; + + const handleOutsideClick = (e: MouseEvent) => { + if (containerRef.current && !containerRef.current.contains(e.target as Node)) { + setIsOpen(false); + setTimeout(() => setDraft(''), 300); } }; window.addEventListener('keydown', handleEscape); - return () => window.removeEventListener('keydown', handleEscape); + document.addEventListener('mousedown', handleOutsideClick); + return () => { + window.removeEventListener('keydown', handleEscape); + document.removeEventListener('mousedown', handleOutsideClick); + }; }, [isOpen]); if (!isFocusMode) return null; @@ -56,40 +69,41 @@ export const ThoughtOrb = ({ isFocusMode, onCaptureThought }: ThoughtOrbProps) = }; return ( -
+
{/* The Magnetic Orb */} {/* Tooltip */}
@@ -101,23 +115,33 @@ export const ThoughtOrb = ({ isFocusMode, onCaptureThought }: ThoughtOrbProps) = {/* Input Field */}
-
- {/* Premium Smoked Glass Container */} -
+ + {/* Ethereal Volumetric Glass Container */} +
setDraft(e.target.value)} disabled={isAbsorbing} - placeholder="Dump a distracting thought..." - className="relative z-10 w-full bg-transparent px-6 py-5 text-[15px] font-medium text-white outline-none placeholder:text-white/40 drop-shadow-sm disabled:opacity-50" + placeholder="What's distracting you?" + className={cn( + "relative z-10 w-full bg-transparent px-8 py-4 text-[15px] font-light tracking-wide text-white outline-none placeholder:text-white/30 drop-shadow-sm disabled:opacity-50 transition-opacity duration-500", + isOpen ? "opacity-100" : "opacity-0" + )} />