code: tsx,nextjs,frontends (2 files)

This commit is contained in:
2025-12-26 00:31:23 +00:00
parent e920d3d967
commit 2bebf64069
2 changed files with 116 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
import type { FileNode } from '@/lib/nerd-mode-ide'
import { FileTreeNode } from './FileTreeNode'
interface FileTreeProps {
nodes: FileNode[]
selectedFileId: string | null
activeFolderId: string | null
onToggleFolder: (nodeId: string) => void
onSelectFile: (nodeId: string) => void
onSelectFolder: (nodeId: string) => void
}
export function FileTree({
nodes,
selectedFileId,
activeFolderId,
onToggleFolder,
onSelectFile,
onSelectFolder,
}: FileTreeProps) {
return (
<div>
{nodes.map((node) => (
<FileTreeNode
key={node.id}
node={node}
level={0}
selectedFileId={selectedFileId}
activeFolderId={activeFolderId}
onToggleFolder={onToggleFolder}
onSelectFile={onSelectFile}
onSelectFolder={onSelectFolder}
/>
))}
</div>
)
}

View File

@@ -0,0 +1,79 @@
import ChevronRightIcon from '@mui/icons-material/ChevronRight'
import DescriptionOutlinedIcon from '@mui/icons-material/DescriptionOutlined'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import FolderOutlinedIcon from '@mui/icons-material/FolderOutlined'
import FolderOpenOutlinedIcon from '@mui/icons-material/FolderOpenOutlined'
import type { FileNode } from '@/lib/nerd-mode-ide'
interface FileTreeNodeProps {
node: FileNode
level: number
selectedFileId: string | null
activeFolderId: string | null
onToggleFolder: (nodeId: string) => void
onSelectFile: (nodeId: string) => void
onSelectFolder: (nodeId: string) => void
}
export function FileTreeNode({
node,
level,
selectedFileId,
activeFolderId,
onToggleFolder,
onSelectFile,
onSelectFolder,
}: FileTreeNodeProps) {
const isSelected = node.type === 'file'
? selectedFileId === node.id
: activeFolderId === node.id
const paddingLeft = `${level * 16}px`
return (
<div>
<div
className={`flex items-center gap-2 px-2 py-1 cursor-pointer hover:bg-accent rounded text-sm ${
isSelected ? 'bg-accent' : ''
}`}
style={{ paddingLeft }}
onClick={() => {
if (node.type === 'folder') {
onToggleFolder(node.id)
onSelectFolder(node.id)
} else {
onSelectFile(node.id)
}
}}
>
{node.type === 'folder' ? (
<>
{node.expanded ? <ExpandMoreIcon fontSize="inherit" /> : <ChevronRightIcon fontSize="inherit" />}
{node.expanded ? <FolderOpenOutlinedIcon fontSize="small" /> : <FolderOutlinedIcon fontSize="small" />}
</>
) : (
<>
<div style={{ width: '14px' }} />
<DescriptionOutlinedIcon fontSize="small" />
</>
)}
<span>{node.name}</span>
</div>
{node.type === 'folder' && node.expanded && node.children && node.children.length > 0 && (
<div>
{node.children.map((child) => (
<FileTreeNode
key={child.id}
node={child}
level={level + 1}
selectedFileId={selectedFileId}
activeFolderId={activeFolderId}
onToggleFolder={onToggleFolder}
onSelectFile={onSelectFile}
onSelectFolder={onSelectFolder}
/>
))}
</div>
)}
</div>
)
}