mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-06 16:04:23 +00:00
Migrate FileTree
This commit is contained in:
@@ -1,65 +1,102 @@
|
||||
import React from 'react';
|
||||
import React, { useRef, useState, useLayoutEffect } from 'react';
|
||||
import { Tree } from 'react-arborist';
|
||||
import { Group, Text } from '@mantine/core';
|
||||
import { IconFile, IconFolder, IconFolderOpen } from '@tabler/icons-react';
|
||||
import { isImageFile } from '../utils/fileHelpers';
|
||||
import { Tooltip } from '@mantine/core';
|
||||
import useResizeObserver from '@react-hook/resize-observer';
|
||||
|
||||
const FileIcon = ({ isFolder, isOpen }) => {
|
||||
if (isFolder) {
|
||||
return isOpen ? (
|
||||
<IconFolderOpen size={16} color="var(--mantine-color-yellow-filled)" />
|
||||
) : (
|
||||
<IconFolder size={16} color="var(--mantine-color-yellow-filled)" />
|
||||
);
|
||||
const useSize = (target) => {
|
||||
const [size, setSize] = useState();
|
||||
|
||||
useLayoutEffect(() => {
|
||||
setSize(target.current.getBoundingClientRect());
|
||||
}, [target]);
|
||||
|
||||
useResizeObserver(target, (entry) => setSize(entry.contentRect));
|
||||
return size;
|
||||
};
|
||||
|
||||
const FileIcon = ({ node }) => {
|
||||
if (node.isLeaf) {
|
||||
return <IconFile size={16} />;
|
||||
}
|
||||
return <IconFile size={16} />;
|
||||
return node.isOpen ? (
|
||||
<IconFolderOpen size={16} color="var(--mantine-color-yellow-filled)" />
|
||||
) : (
|
||||
<IconFolder size={16} color="var(--mantine-color-yellow-filled)" />
|
||||
);
|
||||
};
|
||||
|
||||
const Node = ({ node, style, dragHandle }) => {
|
||||
const isFolder = Array.isArray(node.data.children);
|
||||
|
||||
return (
|
||||
<Group
|
||||
ref={dragHandle}
|
||||
style={style}
|
||||
pl={node.level * 20}
|
||||
py={4}
|
||||
onClick={() => node.toggle()}
|
||||
sx={(theme) => ({
|
||||
cursor: 'pointer',
|
||||
'&:hover': {
|
||||
backgroundColor:
|
||||
theme.colorScheme === 'dark'
|
||||
? theme.colors.dark[6]
|
||||
: theme.colors.gray[0],
|
||||
},
|
||||
})}
|
||||
>
|
||||
<FileIcon isFolder={isFolder} isOpen={node.isOpen} />
|
||||
<Text size="sm">{node.data.name}</Text>
|
||||
</Group>
|
||||
<Tooltip label={node.data.name} openDelay={500}>
|
||||
<div
|
||||
ref={dragHandle}
|
||||
style={{
|
||||
...style,
|
||||
paddingLeft: `${node.level * 20}px`,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
cursor: 'pointer',
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
onClick={() => {
|
||||
if (node.isInternal) {
|
||||
node.toggle();
|
||||
} else {
|
||||
node.tree.props.onNodeClick(node);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<FileIcon node={node} />
|
||||
<span
|
||||
style={{
|
||||
marginLeft: '8px',
|
||||
fontSize: '14px',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
{node.data.name}
|
||||
</span>
|
||||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const FileTree = ({ files, handleFileSelect }) => {
|
||||
const handleNodeClick = (node) => {
|
||||
if (!node.isInternal) {
|
||||
handleFileSelect(node.data.path);
|
||||
}
|
||||
};
|
||||
const target = useRef(null);
|
||||
const size = useSize(target);
|
||||
|
||||
return (
|
||||
<Tree
|
||||
data={files}
|
||||
openByDefault={false}
|
||||
width="100%"
|
||||
height={400} // Adjust this value as needed
|
||||
indent={24}
|
||||
rowHeight={28}
|
||||
onActivate={handleNodeClick}
|
||||
<div
|
||||
ref={target}
|
||||
style={{ height: 'calc(100vh - 140px)', marginTop: '20px' }}
|
||||
>
|
||||
{Node}
|
||||
</Tree>
|
||||
{size && (
|
||||
<Tree
|
||||
data={files}
|
||||
openByDefault={false}
|
||||
width={size.width}
|
||||
height={size.height}
|
||||
indent={24}
|
||||
rowHeight={28}
|
||||
onActivate={(node) => {
|
||||
if (!node.isInternal) {
|
||||
handleFileSelect(node.data.path);
|
||||
}
|
||||
}}
|
||||
onNodeClick={(node) => {
|
||||
if (!node.isInternal) {
|
||||
handleFileSelect(node.data.path);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{Node}
|
||||
</Tree>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user