diff --git a/docs/zh-CN/components/pdf-viewer.md b/docs/zh-CN/components/pdf-viewer.md deleted file mode 100644 index d5baa5ad0..000000000 --- a/docs/zh-CN/components/pdf-viewer.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: PDF Viewer -description: -type: 0 -group: ⚙ 组件 -menuName: PDFViewer 渲染 -icon: -order: 24 ---- - -## 基本用法 - -```schema: scope="body" -{ - "type": "pdf-viewer", - "id": "pdf-viewer", - "src": "/examples/static/simple.pdf" -} -``` - -## 配合文件上传实现预览功能 - -配置和 `input-file` 相同的 `name` 即可 - -```schema: scope="body" -{ - "type": "form", - "title": "", - "wrapWithPanel": false, - "body": [ - { - "type": "input-file", - "name": "file", - "label": "File", - "asBlob": true, - "accept": ".pdf" - }, - { - "type": "pdf-viewer", - "id": "pdf-viewer", - "name": "file" - } - ] -} -``` - -## 属性表 - -| 属性名 | 类型 | 默认值 | 说明 | -| ---------- | ------ | ------ | ---------- | -| src | Api | | 文档地址 | -| width | number | 500 | 宽度 | -| height | number | - | 高度 | -| background | string | #fff | PDF 背景色 | diff --git a/examples/components/Components.tsx b/examples/components/Components.tsx index c6853b0a9..4bbc1b029 100644 --- a/examples/components/Components.tsx +++ b/examples/components/Components.tsx @@ -987,13 +987,6 @@ export const components = [ import('../../docs/zh-CN/components/office-viewer.md').then(wrapDoc) ) }, - { - label: 'PDFViewer 渲染', - path: '/zh-CN/components/pdf-viewer', - component: React.lazy(() => - import('../../docs/zh-CN/components/pdf-viewer.md').then(wrapDoc) - ) - }, { label: 'Progress 进度条', path: '/zh-CN/components/progress', diff --git a/examples/components/Example.jsx b/examples/components/Example.jsx index 3efa54bcc..fa19ec4c4 100644 --- a/examples/components/Example.jsx +++ b/examples/components/Example.jsx @@ -130,7 +130,6 @@ import Tab3Schema from './Tabs/Tab3'; import Loading from './Loading'; import CodeSchema from './Code'; import OfficeViewer from './OfficeViewer'; -import PdfViewer from './PdfViewer'; import InputTableEvent from './EventAction/cmpt-event-action/InputTableEvent'; import WizardPage from './WizardPage'; @@ -913,13 +912,6 @@ export const examples = [ component: makeSchemaRenderer(OfficeViewer) }, - { - label: 'Pdf 预览', - icon: 'fa fa-file-pdf', - path: '/examples/pdf-viewer', - component: makeSchemaRenderer(PdfViewer) - }, - { label: '多 loading', icon: 'fa fa-spinner', diff --git a/examples/components/PdfViewer.jsx b/examples/components/PdfViewer.jsx deleted file mode 100644 index 6c9db2e3a..000000000 --- a/examples/components/PdfViewer.jsx +++ /dev/null @@ -1,23 +0,0 @@ -export default { - type: 'page', - body: { - type: 'form', - id: 'form', - debug: true, - wrapWithPanel: false, - body: [ - { - type: 'input-file', - name: 'file', - label: '选择 PDF 文件预览效果(不会上传到服务器)', - asBlob: true, - accept: '.pdf' - }, - { - type: 'pdf-viewer', - id: 'pdf-viewer', - name: 'file' - } - ] - } -}; diff --git a/examples/static/simple.pdf b/examples/static/simple.pdf deleted file mode 100644 index a64ea050b..000000000 Binary files a/examples/static/simple.pdf and /dev/null differ diff --git a/fis-conf.js b/fis-conf.js index 1080ccf2d..361abb1be 100644 --- a/fis-conf.js +++ b/fis-conf.js @@ -241,7 +241,7 @@ fis.match('/examples/mod.js', { isMod: false }); -fis.match('{markdown-it,moment-timezone,pdfjs-dist}/**', { +fis.match('{markdown-it,moment-timezone}/**', { preprocessor: fis.plugin('js-require-file') }); @@ -503,7 +503,6 @@ if (fis.project.currentMedia() === 'publish-sdk') { '!amis-ui/lib/components/RichText.js', '!amis-ui/lib/components/Tinymce.js', '!amis-ui/lib/components/ColorPicker.js', - '!amis-ui/lib/components/PdfViewer.js', '!react-color/**', '!material-colors/**', '!reactcss/**', @@ -563,11 +562,6 @@ if (fis.project.currentMedia() === 'publish-sdk') { 'tinycolor2/**' ], - 'pdf-viewer.js': [ - 'amis-ui/lib/components/PdfViewer.js', - 'pdfjs-dist/build/pdf.worker.min.js' - ], - 'cropperjs.js': ['cropperjs/**', 'react-cropper/**'], 'barcode.js': ['src/components/BarCode.tsx', 'jsbarcode/**'], @@ -590,7 +584,6 @@ if (fis.project.currentMedia() === 'publish-sdk') { '!mpegts.js/**', '!hls.js/**', '!froala-editor/**', - '!pdfjs-dist/**', '!amis-ui/lib/components/RichText.js', '!zrender/**', diff --git a/packages/amis-ui/package.json b/packages/amis-ui/package.json index 6c945423e..2e3f36747 100644 --- a/packages/amis-ui/package.json +++ b/packages/amis-ui/package.json @@ -65,7 +65,6 @@ "react-intersection-observer": "9.5.2", "react-json-view": "1.21.3", "react-overlays": "5.1.1", - "react-pdf": "^7.7.1", "react-textarea-autosize": "8.3.3", "react-transition-group": "4.4.2", "react-visibility-sensor": "5.1.1", @@ -144,4 +143,4 @@ ] }, "gitHead": "37d23b4a8eb1c663bc38e8dd9040889ea1526ec4" -} +} \ No newline at end of file diff --git a/packages/amis-ui/rollup.config.js b/packages/amis-ui/rollup.config.js index ae15fb0ac..527df261a 100644 --- a/packages/amis-ui/rollup.config.js +++ b/packages/amis-ui/rollup.config.js @@ -49,8 +49,7 @@ const input = [ './src/components/Markdown.tsx', './src/components/Tinymce.tsx', './src/components/RichText.tsx', - './src/components/CityDB.ts', - './src/components/PdfViewer.tsx' + './src/components/CityDB.ts' ]; /** 获取子包编译后的入口路径,需要使用相对路径 */ diff --git a/packages/amis-ui/scss/components/_pdf_viewer.scss b/packages/amis-ui/scss/components/_pdf_viewer.scss deleted file mode 100644 index e8abd90c7..000000000 --- a/packages/amis-ui/scss/components/_pdf_viewer.scss +++ /dev/null @@ -1,45 +0,0 @@ -.#{$ns}PdfViewer { - position: relative; - height: 100%; - min-height: 500px; - display: flex; - justify-content: center; - padding: 50px 0; - &-Content { - width: max-content; - max-width: 100%; - &.is-loaded { - box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 4px 0px; - } - } - - &-Loading { - text-align: center; - } - - &-Tool { - position: absolute; - z-index: 10; - padding: 5px 15px; - bottom: 60px; - background-color: #444444; - border-radius: 10px; - color: #fff; - text-align: center; - user-select: none; - .gap { - margin: 0 4px; - } - .icon { - cursor: pointer; - width: 20px; - margin: 0 10px; - &:hover { - color: var(--colors-brand-5); - } - } - .page-input { - width: 40px; - } - } -} diff --git a/packages/amis-ui/scss/themes/_common.scss b/packages/amis-ui/scss/themes/_common.scss index 0ffc1bf4b..df33798ec 100644 --- a/packages/amis-ui/scss/themes/_common.scss +++ b/packages/amis-ui/scss/themes/_common.scss @@ -142,6 +142,5 @@ @import '../components/debug'; @import '../components/menu'; @import '../components/overflow-tpl'; -@import '../components/pdf_viewer'; @import '../components/print'; diff --git a/packages/amis-ui/src/components/PdfViewer.tsx b/packages/amis-ui/src/components/PdfViewer.tsx deleted file mode 100644 index 2706f2fb2..000000000 --- a/packages/amis-ui/src/components/PdfViewer.tsx +++ /dev/null @@ -1,143 +0,0 @@ -/** - * @file PdfViewer.tsx PDF 预览 - * - * @created: 2024/02/26 - */ - -import React from 'react'; -import {themeable, ThemeProps} from 'amis-core'; -import {Document, Page, pdfjs} from 'react-pdf'; - -import {Icon} from './icons'; -import Input from './Input'; -import Spinner from './Spinner'; -// @ts-ignore -import pdfJSWorkerURL from 'pdfjs-dist/build/pdf.worker.min'; -pdfjs.GlobalWorkerOptions.workerSrc = pdfJSWorkerURL; - -export interface PdfViewerProps extends ThemeProps { - file?: ArrayBuffer; - width?: number; - height?: number; - background?: string; -} - -const PdfViewer: React.FC = props => { - const {classnames: cx, className, width = 500} = props; - const [file, setFile] = React.useState(props.file); - const [loaded, setLoaded] = React.useState(false); - const [page, setPage] = React.useState(1); - const [scale, setScale] = React.useState(1); - const [total, setTotal] = React.useState(1); - const inputRef = React.useRef(); - - React.useEffect(() => { - if (props.file instanceof ArrayBuffer && props.file.byteLength > 0) { - setFile(props.file); - } else { - setFile(undefined); - } - }, [props.file]); - - function handleLoadSuccess({numPages}: {numPages: number}) { - setLoaded(true); - setTotal(numPages); - } - - function handleChangePage(idx: number) { - const newPage = page + idx; - if (newPage <= 0 || newPage > total) { - return; - } - setPage(newPage); - } - - function handlePageBlur(event: React.ChangeEvent) { - const newPage = +event.target.value; - if (isNaN(newPage) || newPage <= 0 || newPage > total) { - if (inputRef.current) { - inputRef.current.value = page + ''; - } - return; - } - setPage(newPage); - } - - function handleChangeScale(t: number) { - setScale(scale * t); - } - - if (!file) { - return null; - } - - function renderLoading() { - return ( -
- -
- ); - } - - function renderTool() { - return ( -
- handleChangePage(-1)} - /> - - / - {total} - handleChangePage(1)} - /> - handleChangeScale(1.2)} - /> - handleChangeScale(0.8)} - /> -
- ); - } - - return ( -
-
- - No PDF data
} - scale={scale} - renderTextLayer={false} - renderAnnotationLayer={false} - /> - -
- {loaded ? renderTool() : null} - - ); -}; - -export default themeable(PdfViewer); diff --git a/packages/amis-ui/src/components/TimelineItem.tsx b/packages/amis-ui/src/components/TimelineItem.tsx index ae116843c..8262e1fe0 100644 --- a/packages/amis-ui/src/components/TimelineItem.tsx +++ b/packages/amis-ui/src/components/TimelineItem.tsx @@ -3,7 +3,7 @@ import {localeable, LocaleProps} from 'amis-core'; import {themeable, ThemeProps} from 'amis-core'; import {Icon} from './icons'; -import type {IconCheckedSchema} from '../index'; +import type {IconCheckedSchema} from 'amis-ui'; export interface TimelineItemProps { /** diff --git a/packages/amis/package.json b/packages/amis/package.json index 67501f898..0b6269fc1 100644 --- a/packages/amis/package.json +++ b/packages/amis/package.json @@ -244,4 +244,4 @@ "react-dom": ">=16.8.6" }, "gitHead": "37d23b4a8eb1c663bc38e8dd9040889ea1526ec4" -} +} \ No newline at end of file diff --git a/packages/amis/src/Schema.ts b/packages/amis/src/Schema.ts index 89fabe370..5f813bc7d 100644 --- a/packages/amis/src/Schema.ts +++ b/packages/amis/src/Schema.ts @@ -253,7 +253,6 @@ export type SchemaType = | 'input-formula' | 'diff-editor' | 'office-viewer' - | 'pdf-viewer' // editor 系列 | 'editor' diff --git a/packages/amis/src/index.tsx b/packages/amis/src/index.tsx index 906ac577e..4b8d4900d 100644 --- a/packages/amis/src/index.tsx +++ b/packages/amis/src/index.tsx @@ -153,7 +153,6 @@ import './renderers/Password'; import './renderers/DateRange'; import './renderers/MultilineText'; import './renderers/OfficeViewer'; -import './renderers/PdfViewer'; import './renderers/AMIS'; import './compat'; diff --git a/packages/amis/src/renderers/PdfViewer.tsx b/packages/amis/src/renderers/PdfViewer.tsx deleted file mode 100644 index 1cff74c47..000000000 --- a/packages/amis/src/renderers/PdfViewer.tsx +++ /dev/null @@ -1,189 +0,0 @@ -/** - * @file PdfViewer.tsx PDF 预览 - * - * @created: 2024/02/26 - */ - -import React from 'react'; -import { - autobind, - getVariable, - isApiOutdated, - IScopedContext, - Renderer, - RendererProps, - resolveVariableAndFilter, - ScopedContext -} from 'amis-core'; -import {BaseSchema} from '../Schema'; - -export const PdfView = React.lazy( - () => import('amis-ui/lib/components/PdfViewer') -); - -export interface PdfViewerSchema extends BaseSchema { - type: 'pdf-viewer'; - /** - * 文件地址 - */ - src?: string; - /** - * 文件取值,一般配合表单使用 - */ - name?: string; - width?: number; - height?: number; - background?: string; -} - -export interface PdfViewerProps extends RendererProps {} - -interface PdfViewerState { - loading: boolean; -} - -export default class PdfViewer extends React.Component< - PdfViewerProps, - PdfViewerState -> { - file?: ArrayBuffer; - reader?: FileReader; - fetchCancel?: Function; - constructor(props: PdfViewerProps) { - super(props); - this.state = { - loading: false - }; - } - - componentDidMount() { - this.renderPdf(); - } - - componentDidUpdate(prevProps: PdfViewerProps) { - const props = this.props; - - if (isApiOutdated(prevProps.src, props.src, prevProps.data, props.data)) { - this.abortLoad(); - this.fetchPdf(); - } - - if (getVariable(props.data, props.name)) { - if ( - getVariable(prevProps.data, prevProps.name) !== - getVariable(props.data, props.name) - ) { - this.abortLoad(); - this.renderPdf(); - } - } - } - - @autobind - abortLoad() { - if (this.fetchCancel) { - this.fetchCancel('load canceled'); - this.fetchCancel = undefined; - } - if (this.reader) { - this.reader.abort(); - this.reader = undefined; - } - } - - @autobind - async renderPdf() { - const {src, name, data} = this.props; - // src 优先级高于 name - if (src) { - if (!this.file) { - await this.fetchPdf(); - } - } else if (getVariable(data, name)) { - await this.renderFormFile(); - } - } - - @autobind - async fetchPdf() { - const {env, src, data, translate: __} = this.props; - const finalSrc = src - ? resolveVariableAndFilter(src, data, '| raw') - : undefined; - - if (!finalSrc) { - console.warn('file src is empty'); - return; - } - - this.setState({ - loading: true - }); - - try { - const res = await env.fetcher(finalSrc, data, { - responseType: 'arraybuffer', - cancelExecutor: (executor: Function) => (this.fetchCancel = executor) - }); - this.file = res.data; - this.forceUpdate(); - } catch (error) { - console.error(error); - } finally { - this.setState({ - loading: false - }); - } - } - - @autobind - async renderFormFile() { - const {name, data} = this.props; - const file = getVariable(data, name); - if (file instanceof File) { - const reader = new FileReader(); - reader.onload = _e => { - const data = reader.result as ArrayBuffer; - this.file = data; - this.forceUpdate(); - }; - reader.readAsArrayBuffer(file); - this.reader = reader; - } - } - - render() { - const {className, classnames: cx, width, height, background} = this.props; - - return ( - - ); - } -} - -@Renderer({ - type: 'pdf-viewer' -}) -export class PdfViewerRenderer extends PdfViewer { - static contextType = ScopedContext; - - constructor(props: PdfViewerProps, context: IScopedContext) { - super(props); - - const scoped = context; - scoped.registerComponent(this); - } - - componentWillUnmount() { - super.componentWillUnmount?.(); - const scoped = this.context as IScopedContext; - scoped.unRegisterComponent(this); - } -}