@ant-design/x
Version:
Craft AI-driven interfaces effortlessly
159 lines (155 loc) • 5.48 kB
JavaScript
import { Empty, Flex, Spin } from 'antd';
import { clsx } from 'clsx';
import React from 'react';
import { PrismLight as SyntaxHighlighter } from 'react-syntax-highlighter';
import { oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';
import useXComponentConfig from "../_util/hooks/use-x-component-config";
import ActionsCopy from "../actions/ActionsCopy";
import { useLocale } from "../locale";
import enUS from "../locale/en_US";
import { useXProviderContext } from "../x-provider";
import useStyle from "./style";
const customOneLight = {
...oneLight,
'pre[class*="language-"]': {
...oneLight['pre[class*="language-"]'],
margin: 0,
background: 'transparent',
padding: 0,
borderRadius: 0
}
};
const FileView = props => {
const {
prefixCls: customizePrefixCls,
classNames,
styles,
style,
selectedFile,
fileContent = '',
loading = false,
previewTitle,
getFileNode,
emptyRender,
previewRender
} = props;
const [contextLocale] = useLocale('Folder', enUS.Folder);
// ============================ Prefix ============================
const {
getPrefixCls
} = useXProviderContext();
const prefixCls = getPrefixCls('folder', customizePrefixCls);
const contextConfig = useXComponentConfig('folder');
const previewCls = `${prefixCls}-preview`;
const [hashId, cssVarCls] = useStyle(prefixCls);
// ============================ Helpers ============================
const getFileExtension = (path = '') => {
const parts = path.split('.');
return parts[parts.length - 1] || '';
};
const getLanguageFromExtension = ext => {
return ext.toLowerCase() || 'txt';
};
// ============================ Render ============================
const renderContent = () => {
if (loading) {
return /*#__PURE__*/React.createElement("div", {
className: clsx(`${previewCls}-loading-container`, classNames?.previewRender)
}, /*#__PURE__*/React.createElement(Spin, null));
}
if (!selectedFile || selectedFile.length === 0) {
// If emptyRender is false or null, do not display empty state
if (emptyRender === false || emptyRender === null) {
return null;
}
const emptyNode = typeof emptyRender === 'function' ? emptyRender() : emptyRender || /*#__PURE__*/React.createElement(Empty, {
image: Empty.PRESENTED_IMAGE_SIMPLE,
description: contextLocale.selectFile
});
return /*#__PURE__*/React.createElement("div", {
className: clsx(`${previewCls}-empty-container`, classNames?.previewRender)
}, emptyNode);
}
const fileNode = getFileNode?.(selectedFile);
const title = fileNode?.title || selectedFile[selectedFile.length - 1];
const path = selectedFile;
// Get file extension from filename
const fileName = selectedFile[selectedFile.length - 1];
const extension = getFileExtension(fileName);
const language = getLanguageFromExtension(extension);
// Handle custom content title
let headerNode;
if (previewTitle === false || previewTitle === null) {
// If previewTitle is false or null, do not display title
headerNode = null;
} else if (previewTitle) {
headerNode = typeof previewTitle === 'function' ? previewTitle({
title,
path,
content: fileContent
}) : previewTitle;
} else {
headerNode = /*#__PURE__*/React.createElement(Flex, {
justify: "space-between",
align: "center",
className: `${previewCls}-title`
}, /*#__PURE__*/React.createElement("span", {
className: `${previewCls}-filename`
}, title), /*#__PURE__*/React.createElement(ActionsCopy, {
text: fileContent,
className: `${previewCls}-copy`
}));
}
// Handle custom preview content
let contentNode;
const originContentNode = /*#__PURE__*/React.createElement(SyntaxHighlighter, {
language: language,
wrapLines: true,
style: customOneLight,
codeTagProps: {
style: {
background: 'transparent'
}
}
}, fileContent.replace(/\n$/, ''));
if (previewRender) {
if (typeof previewRender === 'function') {
contentNode = previewRender({
content: fileContent,
path: selectedFile,
title: fileNode?.title,
language
}, {
originNode: originContentNode
});
} else {
contentNode = previewRender;
}
} else {
contentNode = /*#__PURE__*/React.createElement(SyntaxHighlighter, {
language: language,
wrapLines: true,
style: customOneLight,
codeTagProps: {
style: {
background: 'transparent'
}
}
}, fileContent.replace(/\n$/, ''));
}
return /*#__PURE__*/React.createElement(React.Fragment, null, headerNode && /*#__PURE__*/React.createElement("div", {
className: clsx(`${previewCls}-title-wrapper`, classNames?.previewTitle)
}, headerNode), /*#__PURE__*/React.createElement("div", {
className: clsx(`${previewCls}-content`, classNames?.previewRender)
}, contentNode));
};
return /*#__PURE__*/React.createElement("div", {
className: clsx(`${prefixCls}-preview`, classNames?.filePreview, hashId, cssVarCls),
style: {
...contextConfig.styles?.filePreview,
...styles?.filePreview,
...style
}
}, renderContent());
};
export default FileView;