{(canRename || canCreateFile || canCreateFolder || canDelete || canReveal) && (
setContextMenuPath(open ? node.path : null)}
>
setContextMenuPath(null)}>
{canRename && (
{ e.stopPropagation(); onOpenDialog('rename', node); }}>
Rename
)}
{
e.stopPropagation();
void copyTextToClipboard(node.path).then((result) => {
if (result.ok) {
toast.success('Path copied');
return;
}
toast.error('Copy failed');
});
}}>
Copy Path
{canReveal && (
{ e.stopPropagation(); onRevealPath(node.path); }}>
Reveal in Finder
)}
{isDir && (canCreateFile || canCreateFolder) && (
<>
{canCreateFile && (
{ e.stopPropagation(); onOpenDialog('createFile', node); }}>
New File
)}
{canCreateFolder && (
{ e.stopPropagation(); onOpenDialog('createFolder', node); }}>
New Folder
)}
>
)}
{canDelete && (
<>
{ e.stopPropagation(); onOpenDialog('delete', node); }}
className="text-destructive focus:text-destructive"
>
Delete
>
)}
)}
);
};
// --- Main component ---
export const SidebarFilesTree: React.FC = () => {
const { files, runtime } = useRuntimeAPIs();
const currentDirectory = useEffectiveDirectory() ?? '';
const root = normalizePath(currentDirectory.trim());
const showHidden = useDirectoryShowHidden();
const showGitignored = useFilesViewShowGitignored();
const searchFiles = useFileSearchStore((state) => state.searchFiles);
const openContextFile = useUIStore((state) => state.openContextFile);
const gitStatus = useGitStatus(currentDirectory);
const [searchQuery, setSearchQuery] = React.useState('');
const debouncedSearchQuery = useDebouncedValue(searchQuery, 200);
const searchInputRef = React.useRef