mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-10 15:55:53 +08:00
feat: Advanced file editor and file tree improvements (#444)
# Features - File drag and drop upload: Support uploading files and folders via drag and drop - Binary file handling: Detect binary files and display a friendly message instead of trying to edit them - Folder download: Download folders as ZIP files (using JSZip library) - Context menu integration: Full right-click context menu for file operations (rename, delete, copy path, download, new file/folder)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import type { MouseEvent, MutableRefObject } from 'react';
|
||||
import type { CodeEditorFile } from '../types/types';
|
||||
import CodeEditor from './CodeEditor';
|
||||
@@ -17,6 +17,11 @@ type EditorSidebarProps = {
|
||||
fillSpace?: boolean;
|
||||
};
|
||||
|
||||
// Minimum width for the left content (file tree, chat, etc.)
|
||||
const MIN_LEFT_CONTENT_WIDTH = 200;
|
||||
// Minimum width for the editor sidebar
|
||||
const MIN_EDITOR_WIDTH = 280;
|
||||
|
||||
export default function EditorSidebar({
|
||||
editingFile,
|
||||
isMobile,
|
||||
@@ -31,6 +36,49 @@ export default function EditorSidebar({
|
||||
fillSpace,
|
||||
}: EditorSidebarProps) {
|
||||
const [poppedOut, setPoppedOut] = useState(false);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [effectiveWidth, setEffectiveWidth] = useState(editorWidth);
|
||||
|
||||
// Adjust editor width when container size changes to ensure buttons are always visible
|
||||
useEffect(() => {
|
||||
if (!editingFile || isMobile || poppedOut) return;
|
||||
|
||||
const updateWidth = () => {
|
||||
if (!containerRef.current) return;
|
||||
const parentElement = containerRef.current.parentElement;
|
||||
if (!parentElement) return;
|
||||
|
||||
const containerWidth = parentElement.clientWidth;
|
||||
|
||||
// Calculate maximum allowed editor width
|
||||
const maxEditorWidth = containerWidth - MIN_LEFT_CONTENT_WIDTH;
|
||||
|
||||
if (maxEditorWidth < MIN_EDITOR_WIDTH) {
|
||||
// Not enough space - pop out the editor so user can still see everything
|
||||
setPoppedOut(true);
|
||||
} else if (editorWidth > maxEditorWidth) {
|
||||
// Editor is too wide - constrain it to ensure left content has space
|
||||
setEffectiveWidth(maxEditorWidth);
|
||||
} else {
|
||||
setEffectiveWidth(editorWidth);
|
||||
}
|
||||
};
|
||||
|
||||
updateWidth();
|
||||
window.addEventListener('resize', updateWidth);
|
||||
|
||||
// Also use ResizeObserver for more accurate detection
|
||||
const resizeObserver = new ResizeObserver(updateWidth);
|
||||
const parentEl = containerRef.current?.parentElement;
|
||||
if (parentEl) {
|
||||
resizeObserver.observe(parentEl);
|
||||
}
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', updateWidth);
|
||||
resizeObserver.disconnect();
|
||||
};
|
||||
}, [editingFile, isMobile, poppedOut, editorWidth]);
|
||||
|
||||
if (!editingFile) {
|
||||
return null;
|
||||
@@ -54,7 +102,7 @@ export default function EditorSidebar({
|
||||
const useFlexLayout = editorExpanded || (fillSpace && !hasManualWidth);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div ref={containerRef} className={`flex h-full flex-shrink-0 min-w-0 ${editorExpanded ? 'flex-1' : ''}`}>
|
||||
{!editorExpanded && (
|
||||
<div
|
||||
ref={resizeHandleRef}
|
||||
@@ -67,8 +115,8 @@ export default function EditorSidebar({
|
||||
)}
|
||||
|
||||
<div
|
||||
className={`flex-shrink-0 border-l border-gray-200 dark:border-gray-700 h-full overflow-hidden ${useFlexLayout ? 'flex-1' : ''}`}
|
||||
style={useFlexLayout ? undefined : { width: `${editorWidth}px` }}
|
||||
className={`border-l border-gray-200 dark:border-gray-700 h-full overflow-hidden ${useFlexLayout ? 'flex-1 min-w-0' : `flex-shrink-0 min-w-[${MIN_EDITOR_WIDTH}px]`}`}
|
||||
style={useFlexLayout ? undefined : { width: `${effectiveWidth}px`, minWidth: `${MIN_EDITOR_WIDTH}px` }}
|
||||
>
|
||||
<CodeEditor
|
||||
file={editingFile}
|
||||
@@ -80,6 +128,6 @@ export default function EditorSidebar({
|
||||
onPopOut={() => setPoppedOut(true)}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user