import { useState } from 'react' import { Button } from '@/components/ui/button' import { Codicon } from '@/components/ui/codicon' import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/components/ui/dropdown-menu' import { Kbd } from '@/components/ui/kbd' import { useI18n } from '@/i18n' import { Clipboard, FileText, FolderOpen, type IconComponent, ImageIcon, Link, MessageSquareText } from '@/lib/icons' import { cn } from '@/lib/utils' import { GHOST_ICON_BTN } from './controls' import type { ChatBarState } from './types' const SNIPPET_KEYS = ['codeReview', 'implementationPlan', 'explainThis'] export function ContextMenu({ state, onInsertText, onOpenUrlDialog, onPasteClipboardImage, onPickFiles, onPickFolders, onPickImages }: ContextMenuProps) { const { t } = useI18n() const c = t.composer // Prompt snippets used to be a Radix submenu. That submenu didn't open // reliably when the parent menu was positioned at the bottom of the // window (composer "+" anchor), so we promoted it to a real Dialog — // easier to grow with search / descriptions, and no positioning math. const [snippetsOpen, setSnippetsOpen] = useState(false) return ( <> {c.attachLabel} {c.files} {c.folder} {c.images} {c.pasteImage} {c.url} setSnippetsOpen(true)}> {c.promptSnippets}
{c.tipPre} @ {c.tipPost}
) } function PromptSnippetsDialog({ onInsertText, onOpenChange, open }: PromptSnippetsDialogProps) { const { t } = useI18n() const c = t.composer return ( {c.snippetsTitle} {c.snippetsDesc}
    {SNIPPET_KEYS.map(key => { const snippet = c.snippets[key] return (
  • ) })}
) } export function ContextMenuItem({ children, disabled, icon: Icon, onSelect }: ContextMenuItemProps) { return ( {children} ) } interface ContextMenuItemProps { children: string disabled?: boolean icon: IconComponent onSelect?: () => void } interface ContextMenuProps { onInsertText: (text: string) => void onOpenUrlDialog: () => void onPasteClipboardImage?: () => void onPickFiles?: () => void onPickFolders?: () => void onPickImages?: () => void state: ChatBarState } interface PromptSnippetsDialogProps { onInsertText: (text: string) => void onOpenChange: (open: boolean) => void open: boolean }