Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,56 @@ render(<BaseExample />);

```

- JsonPreview
- JSON文件预览
- _ReactFile(@kne/current-lib_react-file)[import * as _ReactFile from "@kne/react-file"],(@kne/current-lib_react-file/dist/index.css),remoteLoader(@kne/remote-loader)

```jsx
const { JsonPreview } = _ReactFile;
const { createWithRemoteLoader, getPublicPath } = remoteLoader;

const BaseExample = createWithRemoteLoader({
modules: ['components-core:Global@PureGlobal', 'components-core:InfoPage']
})(({ remoteModules }) => {
const [PureGlobal, InfoPage] = remoteModules;
return (
<PureGlobal preset={{
ajax: async api => {
return { data: { code: 0, data: api.loader() } };
},
apis: {
file: {
staticUrl: getPublicPath('react-file') || window.PUBLIC_URL
}
}
}}>
<InfoPage>
<InfoPage.Part title="JSON文件预览 - 默认黑色主题">
<JsonPreview
url="https://jsonplaceholder.typicode.com/users"
/>
</InfoPage.Part>
<InfoPage.Part title="JSON文件预览 - 白色主题">
<JsonPreview
url="https://jsonplaceholder.typicode.com/users"
theme="light"
/>
</InfoPage.Part>
<InfoPage.Part title="JSON文件预览 - 从第2级开始收起">
<JsonPreview
url="https://jsonplaceholder.typicode.com/users"
collapsedFrom={2}
/>
</InfoPage.Part>
</InfoPage>
</PureGlobal>
);
});

render(<BaseExample />);

```


### API

Expand Down Expand Up @@ -562,6 +612,33 @@ ZIP压缩包文件预览组件,支持查看压缩包内部的文件列表和
- `.tar` - TAR归档文件
- `.gz` - Gzip压缩文件

### JsonPreview

JSON文件预览组件,使用 @kne/json-view 提供友好的 JSON 数据展示。

#### 属性

| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| url | string | - | JSON文件的URL地址 |
| className | string | - | 自定义容器类名 |
| maxWidth | string/number | - | 容器最大宽度 |
| theme | 'light' \| 'dark' | 'dark' | 主题模式 |
| collapsedFrom | number | - | 从第几级开始收起,默认全部展开 |
| searchable | boolean | true | 是否开启搜索功能 |
| collapsable | boolean | true | 是否显示展开/收起全部按钮 |
| indentWidth | number | 20 | 缩进宽度(像素) |
| showLineNumbers | boolean | true | 是否显示行号 |

#### 功能特性

- 语法高亮:不同数据类型使用不同颜色
- 层级控制:支持展开/收起,可指定从第几级开始收起
- 搜索功能:基于 Fuse.js 的模糊搜索,关键字高亮
- 双主题支持:白色和黑色两种主题
- 复制功能:一键复制格式化的 JSON 数据
- 行号显示:左侧显示行号

### FilePreview

文件预览组件,支持多种文件格式的预览。
Expand Down
27 changes: 27 additions & 0 deletions doc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,33 @@ ZIP压缩包文件预览组件,支持查看压缩包内部的文件列表和
- `.tar` - TAR归档文件
- `.gz` - Gzip压缩文件

### JsonPreview

JSON文件预览组件,使用 @kne/json-view 提供友好的 JSON 数据展示。

#### 属性

| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| url | string | - | JSON文件的URL地址 |
| className | string | - | 自定义容器类名 |
| maxWidth | string/number | - | 容器最大宽度 |
| theme | 'light' \| 'dark' | 'dark' | 主题模式 |
| collapsedFrom | number | - | 从第几级开始收起,默认全部展开 |
| searchable | boolean | true | 是否开启搜索功能 |
| collapsable | boolean | true | 是否显示展开/收起全部按钮 |
| indentWidth | number | 20 | 缩进宽度(像素) |
| showLineNumbers | boolean | true | 是否显示行号 |

#### 功能特性

- 语法高亮:不同数据类型使用不同颜色
- 层级控制:支持展开/收起,可指定从第几级开始收起
- 搜索功能:基于 Fuse.js 的模糊搜索,关键字高亮
- 双主题支持:白色和黑色两种主题
- 复制功能:一键复制格式化的 JSON 数据
- 行号显示:左侧显示行号

### FilePreview

文件预览组件,支持多种文件格式的预览。
Expand Down
19 changes: 19 additions & 0 deletions doc/example.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,25 @@
"packageName": "@kne/remote-loader"
}
]
},
{
"title": "JsonPreview",
"description": "JSON文件预览",
"code": "./json-preview.js",
"scope": [
{
"name": "_ReactFile",
"packageName": "@kne/current-lib_react-file",
"importStatement": "import * as _ReactFile from \"@kne/react-file\""
},
{
"packageName": "@kne/current-lib_react-file/dist/index.css"
},
{
"name": "remoteLoader",
"packageName": "@kne/remote-loader"
}
]
}
]
}
42 changes: 42 additions & 0 deletions doc/json-preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const { JsonPreview } = _ReactFile;
const { createWithRemoteLoader, getPublicPath } = remoteLoader;

const BaseExample = createWithRemoteLoader({
modules: ['components-core:Global@PureGlobal', 'components-core:InfoPage']
})(({ remoteModules }) => {
const [PureGlobal, InfoPage] = remoteModules;
return (
<PureGlobal preset={{
ajax: async api => {
return { data: { code: 0, data: api.loader() } };
},
apis: {
file: {
staticUrl: getPublicPath('react-file') || window.PUBLIC_URL
}
}
}}>
<InfoPage>
<InfoPage.Part title="JSON文件预览 - 默认黑色主题">
<JsonPreview
url="https://jsonplaceholder.typicode.com/users"
/>
</InfoPage.Part>
<InfoPage.Part title="JSON文件预览 - 白色主题">
<JsonPreview
url="https://jsonplaceholder.typicode.com/users"
theme="light"
/>
</InfoPage.Part>
<InfoPage.Part title="JSON文件预览 - 从第2级开始收起">
<JsonPreview
url="https://jsonplaceholder.typicode.com/users"
collapsedFrom={2}
/>
</InfoPage.Part>
</InfoPage>
</PureGlobal>
);
});

render(<BaseExample />);
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kne/react-file",
"version": "0.1.35",
"version": "0.1.36",
"description": "提供了文件上传,文件预览,文件批量管理等功能",
"syntax": {
"esmodules": true
Expand Down Expand Up @@ -92,6 +92,7 @@
"@kne/create-deferred": "^0.1.0",
"@kne/global-context": "^1.3.2",
"@kne/iframe-resizer": "^0.1.3",
"@kne/json-view": "^0.1.1",
"@kne/markdown-components-render": "^0.1.10",
"@kne/react-fetch": "^1.5.5",
"@kne/react-file-type": "^1.0.9",
Expand Down
66 changes: 66 additions & 0 deletions src/components/FilePreview/JsonPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { useState, useEffect } from 'react';
import { getAjax } from '@kne/react-fetch';
import JsonView from '@kne/json-view';
import style from './style.module.scss';
import { Spin } from 'antd';
import classnames from 'classnames';
import { createWithIntlProvider, useIntl } from '@kne/react-intl';
import zhCn from '../../locale/zh-CN';
import '@kne/json-view/dist/index.css';

const JsonPreview = createWithIntlProvider(
'zh-CN',
zhCn,
'react-file'
)(({ url, className, maxWidth, theme = 'dark', collapsedFrom, searchable = true, collapsable = true, indentWidth = 20, showLineNumbers = true }) => {
const { formatMessage } = useIntl();
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);

useEffect(() => {
const ajax = getAjax();
ajax({ url, method: 'GET' }).then(
({ data: responseData }) => {
try {
// 如果返回的是字符串,尝试解析为 JSON
const jsonData = typeof responseData === 'string' ? JSON.parse(responseData) : responseData;
setData(jsonData);
setLoading(false);
} catch (e) {
console.error('JSON parse error:', e);
setError(true);
setLoading(false);
}
},
() => {
setLoading(false);
setError(true);
}
);
}, [url]);

return (
<div
className={classnames(className, style['container'])}
style={{
maxWidth
}}
>
{loading ? (
<div className={style['loading']}>
<Spin />
</div>
) : null}
<div className={style['text-outer']}>
{error ? (
<div className={style['error']}>{formatMessage({ id: 'fileLoadedError' })}</div>
) : (
<JsonView data={data} theme={theme} collapsedFrom={collapsedFrom} searchable={searchable} collapsable={collapsable} indentWidth={indentWidth} showLineNumbers={showLineNumbers} />
)}
</div>
</div>
);
});

export default JsonPreview;
1 change: 1 addition & 0 deletions src/components/FilePreview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export { default as AudioPreview } from './AudioPreview';
export { default as VideoPreview } from './VideoPreview';
export { default as MarkdownPreview } from './MarkdownPreview';
export { default as ZipPreview } from './ZipPreview';
export { default as JsonPreview } from './JsonPreview';
export { default as typeFormat, typeComponentMapping } from './typeFormat';
7 changes: 6 additions & 1 deletion src/components/FilePreview/typeFormat.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import AudioPreview from './AudioPreview';
import VideoPreview from './VideoPreview';
import MarkdownPreview from './MarkdownPreview';
import ZipPreview from './ZipPreview';
import JsonPreview from './JsonPreview';

const typeFormat = url => {
if (typeof url !== 'string') {
Expand All @@ -24,7 +25,7 @@ const typeFormat = url => {
if (/.pdf$/.test(_path)) {
return 'pdf';
}
if (/.(png|jpg|jpeg)$/.test(_path)) {
if (/.(png|jpg|jpeg|gif|bmp|webp|svg)$/.test(_path)) {
return 'image';
}
if (/.(html|htm)$/.test(_path)) {
Expand All @@ -42,6 +43,9 @@ const typeFormat = url => {
if (/.(zip|rar|7z|tar|gz)$/.test(_path)) {
return 'zip';
}
if (/.json$/.test(_path)) {
return 'json';
}
return 'unknown';
};

Expand All @@ -57,6 +61,7 @@ export const typeComponentMapping = {
audio: AudioPreview,
video: VideoPreview,
zip: ZipPreview,
json: JsonPreview,
unknown: UnknownPreview
};

Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export { default } from './components/File';
export { default as Download, useDownload, download, downloadBlobFile } from './components/Download';
export { default as FilePreview, ZipPreview, HtmlPreview, PdfPreview, TextPreview, MarkdownPreview, ImagePreview, UnknownPreview, OfficePreview, OSSFilePreview, AudioPreview, VideoPreview } from './components/FilePreview';
export { default as FilePreview, ZipPreview, JsonPreview, HtmlPreview, PdfPreview, TextPreview, MarkdownPreview, ImagePreview, UnknownPreview, OfficePreview, OSSFilePreview, AudioPreview, VideoPreview } from './components/FilePreview';
export { default as FileButton, useFileModalProps, useFileModal, FileModal } from './components/FileButton';
export { default as Image } from './components/Image';
export { default as PrintButton } from './components/PrintButton';
Expand Down
Loading