mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-25 06:14:59 +00:00
code: tsx,nextjs,frontends (2 files)
This commit is contained in:
37
frontends/nextjs/src/components/nerd-mode-ide/FileTree.tsx
Normal file
37
frontends/nextjs/src/components/nerd-mode-ide/FileTree.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user