'use client'; import { useState, useRef, useEffect } from 'react'; import { cn } from '@/shared/lib/cn'; interface ThoughtOrbProps { isFocusMode: boolean; onCaptureThought: (note: string) => void; } export const ThoughtOrb = ({ isFocusMode, onCaptureThought }: ThoughtOrbProps) => { const [isOpen, setIsOpen] = useState(false); const [draft, setDraft] = useState(''); const [isAbsorbing, setIsAbsorbing] = useState(false); const inputRef = useRef(null); useEffect(() => { if (isOpen && inputRef.current) { inputRef.current.focus(); } }, [isOpen]); useEffect(() => { if (!isOpen) return; const handleEscape = (e: KeyboardEvent) => { if (e.key === 'Escape') { setIsOpen(false); setDraft(''); } }; window.addEventListener('keydown', handleEscape); return () => window.removeEventListener('keydown', handleEscape); }, [isOpen]); if (!isFocusMode) return null; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const trimmed = draft.trim(); if (!trimmed) { setIsOpen(false); return; } setIsAbsorbing(true); onCaptureThought(trimmed); // Provide a satisfying "sucking" animation delay before closing setTimeout(() => { setIsOpen(false); setDraft(''); setIsAbsorbing(false); }, 600); }; return (
{/* The Orb */} {/* Tooltip */}
Brain Dump
{/* Input Field */}
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/30 disabled:opacity-50" />
); };