+
{node.description}
)}
{hasChildren && expanded && (
-
+
{node.children!.map((child) => (
);
-}
+});
+
+NodeItem.displayName = 'NodeItem';
export function FileTree({ nodes, children, descriptions }: FileTreeProps): React.ReactElement {
- const [selectedNode, setSelectedNode] = useState(null);
const [selectedPath, setSelectedPath] = useState(null);
const treeData = useMemo(() => {
@@ -187,14 +290,13 @@ export function FileTree({ nodes, children, descriptions }: FileTreeProps): Reac
return [];
}, [nodes, children, descriptions]);
- const handleSelect = (node: FileNode, path: string) => {
- setSelectedNode(node);
+ const handleSelect = useCallback((path: string) => {
setSelectedPath(path);
- };
+ }, []);
return (
-
-
+
+
{treeData.map((node) => (
Date: Mon, 15 Dec 2025 13:33:44 +0800
Subject: [PATCH 3/3] =?UTF-8?q?refactor(FileTree):=20=E4=BC=98=E5=8C=96?=
=?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=8F=90=E9=AB=98=E5=8F=AF=E7=BB=B4=E6=8A=A4?=
=?UTF-8?q?=E6=80=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/FileTree/index.tsx | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/src/components/FileTree/index.tsx b/src/components/FileTree/index.tsx
index 8e059436f..2d7071c39 100644
--- a/src/components/FileTree/index.tsx
+++ b/src/components/FileTree/index.tsx
@@ -26,6 +26,9 @@ interface FileTreeProps {
descriptions?: Record;
}
+const MAX_INLINE_COMMENT_LENGTH = 30;
+const ROOT_PATH = 'root';
+
const TEXT_EXTENSIONS = new Set([
".json", ".yml", ".yaml", ".md", ".txt",
".properties", ".xml", ".html", ".css",
@@ -103,7 +106,7 @@ function parseTreeString(content: string): FileNode[] {
}
let description: React.ReactNode | undefined = undefined;
- if (comment.length > 30) {
+ if (comment.length > MAX_INLINE_COMMENT_LENGTH) {
description = comment;
}
@@ -143,8 +146,7 @@ function injectDescriptions(nodes: FileNode[], descriptions: Record void) => {
if (typeof document !== 'undefined' && 'startViewTransition' in document) {
- // @ts-ignore
- document.startViewTransition(() => {
+ (document as any).startViewTransition(() => {
flushSync(callback);
});
} else {
@@ -152,6 +154,13 @@ const startViewTransition = (callback: () => void) => {
}
};
+const getIconColorClass = (hasChildren: boolean, isExplicitFolder: boolean | undefined, iconType: any) => {
+ if (hasChildren || isExplicitFolder || iconType === FolderOutlined || iconType === FolderOpenOutlined) {
+ return "text-[var(--ifm-color-primary)]";
+ }
+ return "text-[var(--ifm-color-emphasis-700)]";
+};
+
const NodeItem = React.memo(({
node,
path,
@@ -204,6 +213,7 @@ const NodeItem = React.memo(({
}
const isSelected = selectedPath === currentPath;
+ const iconColorClass = getIconColorClass(hasChildren, isExplicitFolder, (Icon as React.ReactElement)?.type);
return (
-
@@ -227,7 +237,7 @@ const NodeItem = React.memo(({
{Icon}
@@ -301,7 +311,7 @@ export function FileTree({ nodes, children, descriptions }: FileTreeProps): Reac