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 { 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 PROMPT_SNIPPETS: readonly PromptSnippet[] = [ { description: 'Audit the current change for regressions, dropped edge cases, and missing tests.', label: 'Code review', text: 'Please review this for bugs, regressions, and missing tests.' }, { description: 'Outline an approach before touching code so the diff stays focused.', label: 'Implementation plan', text: 'Please make a concise implementation plan before changing code.' }, { description: 'Walk through how the selected code works and link to the key files.', label: 'Explain this', text: 'Please explain how this works and point me to the key files.' } ] export function ContextMenu({ state, onInsertText, onOpenUrlDialog, onPasteClipboardImage, onPickFiles, onPickFolders, onPickImages }: ContextMenuProps) { // 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 ( <> Attach Files… Folder… Images… Paste image URL… setSnippetsOpen(true)}> Prompt snippets…
Tip: type @ to reference files inline.
) } function PromptSnippetsDialog({ onInsertText, onOpenChange, open, snippets }: PromptSnippetsDialogProps) { return ( Prompt snippets Pick a starter prompt to drop into the composer.
    {snippets.map(snippet => (
  • ))}
) } 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 PromptSnippet { description: string label: string text: string } interface PromptSnippetsDialogProps { onInsertText: (text: string) => void onOpenChange: (open: boolean) => void open: boolean snippets: readonly PromptSnippet[] }