UNPKG

@ant-design/x

Version:

Craft AI-driven interfaces effortlessly

108 lines (105 loc) 3.61 kB
import { FileOutlined, FolderOutlined } from '@ant-design/icons'; import { Tree } from 'antd'; import clsx from 'clsx'; import React, { useCallback } from 'react'; import { useXProviderContext } from "../x-provider"; // File tree node type const { DirectoryTree: AntDirectoryTree } = Tree; const DirectoryTree = ({ treeData, selectedKeys, expandedKeys, onSelect, onExpand, showLine = false, defaultExpandAll = true, className, classNames, directoryIcons, styles, style, directoryTitle, prefixCls: customizePrefixCls }) => { // ============================ Tree Config ============================ const isFolder = node => { return !!node.children && node.children.length > 0; }; const getIcon = useCallback(node => { // If directoryIcons is false or null, do not display icons if (directoryIcons === false || directoryIcons === null) { return null; } if (isFolder(node)) { const icon = directoryIcons?.directory; if (typeof icon === 'function') { return icon(); } return icon || /*#__PURE__*/React.createElement(FolderOutlined, null); } // Return corresponding icon based on file extension const filePath = node.path.toLowerCase(); const extension = filePath.split('.').pop(); if (extension) { // Check if custom icon configuration exists const icon = directoryIcons?.[extension]; if (icon) { return typeof icon === 'function' ? icon() : icon; } } return /*#__PURE__*/React.createElement(FileOutlined, null); }, [directoryIcons]); const buildPathSegments = useCallback((node, parentSegments = []) => { if (node.path === '/' && parentSegments.length === 0) { return ['/']; } return [...parentSegments, node.path].filter(segment => segment !== ''); }, []); const convertToTreeData = useCallback((nodes, parentSegments = []) => { return nodes.map(node => { const pathSegments = buildPathSegments(node, parentSegments); const fullPath = pathSegments.join('/').replace(/^\/+/, ''); return { ...node, key: fullPath, path: fullPath, pathSegments, title: node.title, icon: getIcon(node), isLeaf: !isFolder(node), children: node.children ? convertToTreeData(node.children, pathSegments) : undefined }; }); }, [buildPathSegments, getIcon]); const treeDataConverted = convertToTreeData(treeData); const titleNode = directoryTitle === false || directoryTitle === null ? null : typeof directoryTitle === 'function' ? directoryTitle() : directoryTitle; // ============================ Prefix ============================ const { getPrefixCls } = useXProviderContext(); const prefixCls = getPrefixCls('folder', customizePrefixCls); return /*#__PURE__*/React.createElement(React.Fragment, null, titleNode ? /*#__PURE__*/React.createElement("div", { style: { ...styles?.directoryTitle, ...style }, className: clsx(`${prefixCls}-directory-tree-title`, className, classNames?.directoryTitle) }, titleNode) : null, /*#__PURE__*/React.createElement(AntDirectoryTree, { treeData: treeDataConverted, selectedKeys: selectedKeys, expandedKeys: expandedKeys, onSelect: onSelect, onExpand: onExpand, multiple: false, blockNode: true, classNames: { itemTitle: `${prefixCls}-directory-tree-item-title` }, showLine: showLine, defaultExpandAll: defaultExpandAll, className: clsx(`${prefixCls}-directory-tree-content`) })); }; export default DirectoryTree;