diff --git a/packages/ui/src/components/views/FilesView.tsx b/packages/ui/src/components/views/FilesView.tsx index 8e8aa187..e4b5b8ab 100644 --- a/packages/ui/src/components/views/FilesView.tsx +++ b/packages/ui/src/components/views/FilesView.tsx @@ -28,6 +28,7 @@ import { RiCodeSSlashLine, RiNodeTree, RiDownloadLine, + RiMenuFold2Line, } from '@remixicon/react'; import { toast } from '@/components/ui'; import { copyTextToClipboard } from '@/lib/clipboard'; @@ -2316,7 +2317,7 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { variant="ghost" size="sm" onClick={() => void saveDraft()} - className="h-6 px-1 gap-1 text-muted-foreground opacity-80 hover:opacity-100" + className="h-6 gap-1 px-1 text-muted-foreground opacity-80 hover:bg-transparent hover:opacity-100 focus-visible:bg-transparent active:bg-transparent" title={`Save now (${getModifierLabel()}+S) - auto-saves after 1.5s`} aria-label={`Save (${getModifierLabel()}+S)`} > @@ -2330,7 +2331,7 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { + )} @@ -2420,7 +2430,7 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { variant="ghost" size="sm" onClick={() => saveJsonViewMode(jsonViewMode === 'tree' ? 'text' : 'tree')} - className="h-6 w-6 p-0 text-muted-foreground opacity-65 hover:opacity-100" + className="h-6 w-6 p-0 text-muted-foreground opacity-65 hover:bg-transparent hover:opacity-100 focus-visible:bg-transparent active:bg-transparent" title={jsonViewMode === 'tree' ? 'Switch to Text View' : 'Switch to Tree View'} > {jsonViewMode === 'tree' ? ( @@ -2449,7 +2459,7 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { toast.error('Copy failed'); } }} - className="h-6 w-6 p-0" + className="h-6 w-6 p-0 hover:bg-transparent focus-visible:bg-transparent active:bg-transparent" title="Copy file contents" aria-label="Copy file contents" > @@ -2479,7 +2489,7 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { toast.error('Copy failed'); } }} - className="h-6 w-6 p-0" + className="h-6 w-6 p-0 hover:bg-transparent focus-visible:bg-transparent active:bg-transparent" title={`Copy file path (${displaySelectedPath})`} aria-label={`Copy file path (${displaySelectedPath})`} > @@ -2499,7 +2509,7 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { const fn = files.downloadFile; if (fn) void fn(selectedFile.path); }} - className="h-6 w-6 p-0" + className="h-6 w-6 p-0 hover:bg-transparent focus-visible:bg-transparent active:bg-transparent" title="Save file" aria-label="Save file" > @@ -2512,7 +2522,7 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { variant="ghost" size="sm" onClick={() => setIsFullscreen(false)} - className="h-6 w-6 p-0" + className="h-6 w-6 p-0 hover:bg-transparent focus-visible:bg-transparent active:bg-transparent" title="Exit fullscreen" aria-label="Exit fullscreen" > @@ -2523,7 +2533,7 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { variant="ghost" size="sm" onClick={() => setIsFullscreen(!isFullscreen)} - className="h-6 w-6 p-0" + className="h-6 w-6 p-0 hover:bg-transparent focus-visible:bg-transparent active:bg-transparent" title={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'} aria-label={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'} > @@ -2809,11 +2819,6 @@ export const FilesView: React.FC = ({ mode = 'full' }) => { data-keyboard-avoid="none" style={isMobile ? { height: 'calc(100% - var(--oc-keyboard-inset, 0px))' } : undefined} > -
void; view: EditorView | null; + variant?: 'overlay' | 'inline'; }; type CursorSnapshot = { @@ -51,7 +53,7 @@ const moveSelectionToLine = (view: EditorView, lineNumber: number, preferredChar }); }; -export function GoToLineDialog({ open, onOpenChange, view }: GoToLineDialogProps) { +export function GoToLineDialog({ open, onOpenChange, view, variant = 'overlay' }: GoToLineDialogProps) { const [inputValue, setInputValue] = React.useState(''); const initialCursorRef = React.useRef(null); const committedRef = React.useRef(false); @@ -159,7 +161,7 @@ export function GoToLineDialog({ open, onOpenChange, view }: GoToLineDialogProps document.removeEventListener('pointerdown', handlePointerDown, true); document.removeEventListener('keydown', handleKeyDown, true); }; - }, [handleOpenChange, open]); + }, [handleOpenChange, open, variant]); const helperText = React.useMemo(() => { if (!view) { @@ -174,6 +176,46 @@ export function GoToLineDialog({ open, onOpenChange, view }: GoToLineDialogProps return `Go to line ${lineNumber}`; }, [lineNumber, view]); + if (variant === 'inline') { + if (!open) { + return null; + } + + return ( +
+ setInputValue(event.target.value)} + onKeyDown={(event) => { + if (event.key === 'Enter') { + event.preventDefault(); + handleSubmit(); + } + }} + placeholder="Line" + className="h-6 w-20 rounded-md border-border/70 bg-transparent px-2 typography-meta" + /> + +
+ ); + } + return (