@zhaoxiangjun/base44-document 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,59 @@
1
+ import { ReactNode } from 'react';
2
+ export type DocumentPreviewKind = "markdown" | "pdf" | "excel" | "docx" | "text" | "unsupported";
3
+ export type DocumentSource = {
4
+ name: string;
5
+ url?: string;
6
+ file?: File | Blob;
7
+ mimeType?: string;
8
+ extension?: string;
9
+ };
10
+ export type DocumentViewerMessages = {
11
+ title: string;
12
+ loading: string;
13
+ emptyTitle: string;
14
+ emptyDescription: string;
15
+ errorTitle: string;
16
+ unsupportedTitle: string;
17
+ unsupportedDescription: string;
18
+ openExternal: string;
19
+ download: string;
20
+ sheetLabel: string;
21
+ rowsLabel: string;
22
+ columnsLabel: string;
23
+ docFallback: string;
24
+ pdfFallback: string;
25
+ };
26
+ export type DocumentLoadState = {
27
+ kind: DocumentPreviewKind;
28
+ objectUrl?: string;
29
+ html?: string;
30
+ text?: string;
31
+ sheets?: DocumentSheet[];
32
+ error?: string;
33
+ };
34
+ export type DocumentSheet = {
35
+ name: string;
36
+ rows: string[][];
37
+ };
38
+ export type DocumentViewerClassNames = {
39
+ root?: string;
40
+ toolbar?: string;
41
+ content?: string;
42
+ viewport?: string;
43
+ };
44
+ export type DocumentViewerProps = {
45
+ source?: DocumentSource | null;
46
+ className?: string;
47
+ classNames?: DocumentViewerClassNames;
48
+ height?: number | string;
49
+ maxRows?: number;
50
+ messages?: Partial<DocumentViewerMessages>;
51
+ actions?: ReactNode;
52
+ onOpenExternal?: (source: DocumentSource) => void;
53
+ onDownload?: (source: DocumentSource) => void;
54
+ onError?: (error: Error) => void;
55
+ };
56
+ export type DocumentPreviewDialogProps = DocumentViewerProps & {
57
+ open: boolean;
58
+ onOpenChange: (open: boolean) => void;
59
+ };
@@ -0,0 +1,2 @@
1
+ import { ClassValue } from 'clsx';
2
+ export declare function cn(...inputs: ClassValue[]): string;
@@ -0,0 +1,4 @@
1
+ import { DocumentSource } from '../types/document';
2
+ export declare function createDocumentId(file: File): string;
3
+ export declare function openDocumentExternal(source: DocumentSource): void;
4
+ export declare function downloadDocumentSource(source: DocumentSource): void;
@@ -0,0 +1,2 @@
1
+ import { DocumentSource } from '../types/document';
2
+ export declare function getDocumentIcon(source: DocumentSource): import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,4 @@
1
+ import { DocumentPreviewKind, DocumentSource } from '../types/document';
2
+ export declare function getDocumentExtension(source: DocumentSource): string;
3
+ export declare function resolveDocumentKind(source: DocumentSource): DocumentPreviewKind;
4
+ export declare function canOpenDocumentExternally(source: DocumentSource | null | undefined): boolean;
@@ -0,0 +1,7 @@
1
+ import { DocumentSheet } from '../types/document';
2
+ import * as XLSX from "xlsx";
3
+ export declare function getSheetStats(sheet: DocumentSheet): {
4
+ rowCount: number;
5
+ columnCount: number;
6
+ };
7
+ export declare function workbookToSheets(workbook: XLSX.WorkBook, maxRows: number): DocumentSheet[];
@@ -0,0 +1,2 @@
1
+ export declare function resolveSizeValue(value: number | string | undefined): string | undefined;
2
+ export declare function formatFileSize(size: number): string;
@@ -0,0 +1,4 @@
1
+ import { DocumentSource } from '../types/document';
2
+ export declare function readDocumentArrayBuffer(source: DocumentSource): Promise<ArrayBuffer>;
3
+ export declare function readDocumentText(source: DocumentSource): Promise<string>;
4
+ export declare function createDocumentObjectUrl(source: DocumentSource): string | undefined;
@@ -0,0 +1,200 @@
1
+ # Base44 使用说明
2
+
3
+ > 这份文档给 Base44 App、Base44 AI Controls 和开发者使用。
4
+ > Base44 使用 `@zhaoxiangjun/base44-document` 时,只需要优先阅读这一份文档。
5
+
6
+ ## 1. 包信息
7
+
8
+ ```text
9
+ package: @zhaoxiangjun/base44-document
10
+ current: 0.1.0
11
+ ```
12
+
13
+ Base44 App 通过 npm registry 安装,不使用 git 依赖。
14
+
15
+ ```json
16
+ {
17
+ "dependencies": {
18
+ "@zhaoxiangjun/base44-document": "^0.1.0"
19
+ }
20
+ }
21
+ ```
22
+
23
+ 入口文件引入样式:
24
+
25
+ ```tsx
26
+ import "@zhaoxiangjun/base44-ui/styles.css";
27
+ import "@zhaoxiangjun/base44-document/styles.css";
28
+ ```
29
+
30
+ 组件引入:
31
+
32
+ ```tsx
33
+ import { DocumentPreviewDialog, DocumentViewer } from "@zhaoxiangjun/base44-document";
34
+ ```
35
+
36
+ ## 2. 使用边界
37
+
38
+ 这个包只负责浏览器端文档预览 UI,不负责业务请求和 Base44 平台调用。
39
+
40
+ ```text
41
+ 可以做:接收 File、Blob、URL,识别文档类型,渲染预览界面。
42
+ 不可以做:调用 base44.entities、base44.auth、base44.functions.invoke、保存密钥、拼接业务接口。
43
+ ```
44
+
45
+ 业务请求必须留在当前 Base44 App 的 `src/api`、`src/hooks`、`src/lib`、页面容器或 Backend Functions 中。
46
+
47
+ ## 3. 支持格式
48
+
49
+ | 格式 | 支持方式 |
50
+ |------|----------|
51
+ | `.md` / `.markdown` | `marked` 渲染 HTML |
52
+ | `.pdf` | 浏览器 iframe/object URL 预览 |
53
+ | `.xlsx` / `.xls` / `.csv` | `xlsx` 读取并展示 Sheet 表格 |
54
+ | `.docx` | `mammoth` 转 HTML |
55
+ | `.txt` / `.json` / `.xml` / `.log` | 纯文本预览 |
56
+ | `.doc` | 浏览器端不解析,显示外部打开或下载提示 |
57
+
58
+ 说明:
59
+
60
+ ```text
61
+ 这里的 Word 预览支持 DOCX,不支持旧版二进制 DOC 解析。
62
+ DOCX 转 HTML 适合正文预览,不保证完整还原 Word 页眉页脚、批注、复杂版式。
63
+ ```
64
+
65
+ ## 4. DocumentViewer
66
+
67
+ ```tsx
68
+ <DocumentViewer
69
+ source={{
70
+ name: file.name,
71
+ file,
72
+ mimeType: file.type
73
+ }}
74
+ height={560}
75
+ maxRows={100}
76
+ messages={documentMessages}
77
+ onError={handlePreviewError}
78
+ />
79
+ ```
80
+
81
+ 关键 props:
82
+
83
+ ```text
84
+ source?: DocumentSource | null
85
+ height?: number | string
86
+ maxRows?: number
87
+ messages?: Partial<DocumentViewerMessages>
88
+ actions?: ReactNode
89
+ onOpenExternal?: (source: DocumentSource) => void
90
+ onDownload?: (source: DocumentSource) => void
91
+ onError?: (error: Error) => void
92
+ ```
93
+
94
+ `DocumentSource`:
95
+
96
+ ```ts
97
+ type DocumentSource = {
98
+ name: string;
99
+ url?: string;
100
+ file?: File | Blob;
101
+ mimeType?: string;
102
+ extension?: string;
103
+ };
104
+ ```
105
+
106
+ 说明:
107
+
108
+ ```text
109
+ file 优先用于用户本地选择文件、上传前预览和 Blob 预览。
110
+ url 用于已经存在的远程文件,远程文件必须允许浏览器跨域读取。
111
+ PDF 使用 url 或 object URL 交给浏览器渲染。
112
+ Excel 默认最多渲染 100 行,可通过 maxRows 调整。
113
+ ```
114
+
115
+ 本地文件选择示例:
116
+
117
+ ```tsx
118
+ function LocalDocumentPreview() {
119
+ const [source, setSource] = useState<DocumentSource | null>(null);
120
+
121
+ function handleFileChange(event: React.ChangeEvent<HTMLInputElement>) {
122
+ const file = event.target.files?.[0];
123
+ if (!file) return;
124
+
125
+ setSource({
126
+ name: file.name,
127
+ file,
128
+ mimeType: file.type
129
+ });
130
+ }
131
+
132
+ return (
133
+ <>
134
+ <input
135
+ type="file"
136
+ accept=".md,.markdown,.pdf,.csv,.xls,.xlsx,.doc,.docx,.txt,.json,.xml"
137
+ onChange={handleFileChange}
138
+ />
139
+ <DocumentViewer source={source} height={560} />
140
+ </>
141
+ );
142
+ }
143
+ ```
144
+
145
+ ## 5. DocumentPreviewDialog
146
+
147
+ ```tsx
148
+ <DocumentPreviewDialog
149
+ open={open}
150
+ onOpenChange={setOpen}
151
+ source={currentDocument}
152
+ height="min(70vh, 680px)"
153
+ />
154
+ ```
155
+
156
+ 弹窗使用 `@zhaoxiangjun/base44-ui` 的 `DialogFrame`,适合文件列表、任务结果和附件管理中的快速预览。
157
+
158
+ ## 6. 可复用导出
159
+
160
+ 除完整预览组件外,本包也导出内部拆分后的基础能力,便于后续项目按需组合。
161
+
162
+ | 类型 | 导出 |
163
+ |------|------|
164
+ | 子组件 | `DocumentToolbar` / `DocumentContent` / `ExcelPreview` |
165
+ | Hook | `useDocumentPreview` |
166
+ | 常量 | `ACCEPTED_DOCUMENT_TYPES` / `DEFAULT_MAX_ROWS` |
167
+ | 类型识别 | `resolveDocumentKind` / `getDocumentExtension` / `canOpenDocumentExternally` |
168
+ | 文件动作 | `createDocumentId` / `openDocumentExternal` / `downloadDocumentSource` |
169
+ | 格式化 | `formatFileSize` / `resolveSizeValue` |
170
+ | Excel 工具 | `workbookToSheets` / `getSheetStats` |
171
+ | 图标工具 | `getDocumentIcon` |
172
+
173
+ 推荐仍优先使用 `DocumentViewer`;只有需要自定义工具栏、内容区或文件列表时再组合这些基础能力。
174
+
175
+ ## 7. 文案和 i18n
176
+
177
+ 默认文案为英文。Base44 App 应从自己的 i18n / locale 层传入 `messages`。
178
+
179
+ ```tsx
180
+ const documentMessages = {
181
+ title: t("document.preview.title"),
182
+ loading: t("document.preview.loading"),
183
+ emptyTitle: t("document.preview.emptyTitle"),
184
+ emptyDescription: t("document.preview.emptyDescription"),
185
+ errorTitle: t("document.preview.errorTitle"),
186
+ unsupportedTitle: t("document.preview.unsupportedTitle"),
187
+ unsupportedDescription: t("document.preview.unsupportedDescription"),
188
+ openExternal: t("common.open"),
189
+ download: t("common.download")
190
+ };
191
+ ```
192
+
193
+ ## 8. 移动端要求
194
+
195
+ ```text
196
+ 预览容器必须给定稳定高度,例如 height={560} 或 height="70vh"。
197
+ Excel 表格会横向滚动,不应强行压缩列宽到不可读。
198
+ PDF 预览依赖移动浏览器能力,必要时展示打开按钮。
199
+ 弹窗宽度自适应 94vw,内容区滚动在组件内部处理。
200
+ ```
@@ -0,0 +1,64 @@
1
+ # 文档预览功能说明
2
+
3
+ ## 1. 设计目标
4
+
5
+ 本包聚合常见文档预览能力,让 Base44 App 只需要传入 `DocumentSource`,即可获得统一的预览容器和弹窗。
6
+
7
+ ## 2. 数据入口
8
+
9
+ ```ts
10
+ type DocumentSource = {
11
+ name: string;
12
+ url?: string;
13
+ file?: File | Blob;
14
+ mimeType?: string;
15
+ extension?: string;
16
+ };
17
+ ```
18
+
19
+ 优先级:
20
+
21
+ ```text
22
+ mimeType 用于快速判断类型
23
+ extension 用于无 MIME 的业务文件
24
+ name 后缀作为兜底
25
+ file 用于本地 Blob 读取
26
+ url 用于远程文件读取或 PDF 打开
27
+ ```
28
+
29
+ ## 3. 渲染策略
30
+
31
+ ```text
32
+ Markdown:读取 text 后通过 marked 转 HTML
33
+ PDF:file 转 object URL,url 直接 iframe
34
+ Excel/CSV:读取 ArrayBuffer 后通过 xlsx 解析 Sheet
35
+ DOCX:读取 ArrayBuffer 后通过 mammoth 转 HTML
36
+ Text:读取 text 后用 pre 展示
37
+ Unsupported:展示不支持提示和外部打开/下载入口
38
+ ```
39
+
40
+ ## 4. 风险和边界
41
+
42
+ ```text
43
+ 远程 URL 读取受 CORS 限制。
44
+ PDF 渲染依赖浏览器内置 PDF 能力。
45
+ DOCX 转 HTML 不等于完整 Word 排版还原。
46
+ 旧版二进制 DOC 暂不做浏览器端解析。
47
+ XLSX 大文件会消耗浏览器内存,默认限制展示行数。
48
+ 旧版 .doc 不做浏览器端解析。
49
+ ```
50
+
51
+ ## 5. 模块拆分
52
+
53
+ ```text
54
+ DocumentViewer:组合预览状态、工具栏、内容区和事件回调。
55
+ DocumentToolbar:文件名、外部打开、下载和自定义 actions。
56
+ DocumentContent:加载、错误、空状态和不同文档类型渲染。
57
+ ExcelPreview:Sheet 切换、表格渲染和行列统计。
58
+ useDocumentPreview:读取 source 并输出标准 DocumentLoadState。
59
+ utils/excel:Excel workbook 到 DocumentSheet 的转换。
60
+ utils/documentActions:打开、下载、本地文件 id。
61
+ utils/documentIcons:按文档类型选择 lucide 图标。
62
+ utils/format:尺寸和文件大小格式化。
63
+ constants/documentConstants:默认行数和 input accept 类型。
64
+ ```
@@ -0,0 +1,36 @@
1
+ # 本地展示说明
2
+
3
+ 本项目内置 Vite playground,用于验证 `DocumentViewer` 和 `DocumentPreviewDialog`。
4
+
5
+ ## 1. 启动
6
+
7
+ ```bash
8
+ cd react_base44_document
9
+ npm install
10
+ npm run dev
11
+ ```
12
+
13
+ 打开 Vite 输出的本地地址。当前 playground 的第一入口是本地文件选择器。
14
+
15
+ ## 2. 覆盖场景
16
+
17
+ ```text
18
+ 本地 Markdown 文件预览
19
+ 本地 CSV / XLS / XLSX 文件预览
20
+ 本地 PDF 文件预览
21
+ 本地 DOCX 文件预览
22
+ 本地 DOC 不支持提示
23
+ 弹窗预览
24
+ 打开/下载按钮状态
25
+ 移动端窄屏布局
26
+ ```
27
+
28
+ ## 3. 同步要求
29
+
30
+ 组件新增 props、支持格式、样式依赖或使用边界变更时,必须同步更新:
31
+
32
+ ```text
33
+ docs/base44-usage.md
34
+ docs/project-status.md
35
+ README.md
36
+ ```
@@ -0,0 +1,24 @@
1
+ # 2026-06-30 初始化文档预览包
2
+
3
+ ## 内容
4
+
5
+ ```text
6
+ 创建 react_base44_document
7
+ 新增 @zhaoxiangjun/base44-document npm 包配置
8
+ 新增 DocumentViewer / DocumentPreviewDialog
9
+ 新增 useDocumentPreview Hook
10
+ 新增 Markdown、PDF、Excel/CSV、DOCX、文本预览策略
11
+ 新增本地文件选择 playground 和 npm 标准库文档
12
+ ```
13
+
14
+ ## 验证
15
+
16
+ ```text
17
+ npm install:已通过,prepare 自动构建成功。
18
+ npm run typecheck:已通过。
19
+ npm run build:已通过。
20
+ npm pack --dry-run:已通过。
21
+ 本地 playground:http://localhost:5191/ 已启动并通过浏览器检查,支持选择本机文件预览,控制台无 error/warn。
22
+ PDF 预览高度:已修复 DocumentViewer 内容区被 flex-1 压缩的问题。
23
+ 公共复用重构:提取 DocumentToolbar、DocumentContent、ExcelPreview、documentActions、documentIcons、excel、format、documentConstants。
24
+ ```
@@ -0,0 +1,45 @@
1
+ # npm 包维护说明
2
+
3
+ ## 1. 包信息
4
+
5
+ ```text
6
+ package: @zhaoxiangjun/base44-document
7
+ current: 0.1.0
8
+ ```
9
+
10
+ ## 2. 构建验证
11
+
12
+ 发布前必须运行:
13
+
14
+ ```bash
15
+ npm run typecheck
16
+ npm run build
17
+ npm pack --dry-run
18
+ ```
19
+
20
+ ## 3. 版本规则
21
+
22
+ ```text
23
+ 修复内部实现且不改 API:patch
24
+ 新增兼容组件、Hook、props:minor
25
+ 移除或修改公开 API:major
26
+ ```
27
+
28
+ ## 4. 发布
29
+
30
+ 发布前设置 `NPM_TOKEN`:
31
+
32
+ ```bat
33
+ set NPM_TOKEN=your_token
34
+ publish-npm.bat
35
+ ```
36
+
37
+ 脚本会临时创建 `.npmrc`,发布结束后删除,并通过 `npm view` 校验 registry 上的版本。
38
+
39
+ ## 5. 发布后检查
40
+
41
+ ```bash
42
+ npm view @zhaoxiangjun/base44-document@0.1.0 version --registry=https://registry.npmjs.org/
43
+ ```
44
+
45
+ 随后在 Base44 App 或本地展示项目中通过 npm 包名安装验证,不使用本地路径作为发布后验证方式。
@@ -0,0 +1,66 @@
1
+ # react_base44_document 项目状态
2
+
3
+ ## 1. 当前定位
4
+
5
+ `react_base44_document` 是 npm 标准库项目,包名为 `@zhaoxiangjun/base44-document`。
6
+ 它为 Base44 React App 和本地 React 项目提供浏览器端文档预览能力。
7
+
8
+ ## 2. 当前能力
9
+
10
+ ```text
11
+ DocumentViewer:内嵌文档预览容器
12
+ DocumentPreviewDialog:弹窗预览
13
+ useDocumentPreview:文档读取和转换 Hook
14
+ resolveDocumentKind:文档类型识别工具
15
+ Markdown:marked 渲染
16
+ PDF:iframe + object URL 预览
17
+ Excel/CSV:xlsx 读取 Sheet 并展示表格
18
+ DOCX:mammoth 转 HTML
19
+ 文本:pre 预览
20
+ legacy .doc:外部打开/下载提示
21
+ playground:本地文件选择后预览
22
+ ```
23
+
24
+ ## 3. 本轮修改
25
+
26
+ ```text
27
+ 创建 react_base44_document 项目
28
+ 建立 Vite library npm 包结构
29
+ 新增核心组件、Hook、类型和工具函数
30
+ 新增本地文件选择 playground
31
+ 新增 README 与 docs/base44-usage.md、local-display.md、npm-package.md、project-status.md
32
+ 新增 docs/fun 和 docs/logs 记录
33
+ 新增 publish-npm.bat
34
+ 提取 DocumentToolbar、DocumentContent、ExcelPreview 子组件
35
+ 提取 documentActions、documentIcons、format、excel、documentConstants 公共模块
36
+ ```
37
+
38
+ ## 4. 依赖
39
+
40
+ ```text
41
+ react / react-dom:peer dependencies
42
+ @zhaoxiangjun/base44-ui:公共 UI 复用
43
+ lucide-react:图标
44
+ marked:Markdown 渲染
45
+ xlsx:Excel/CSV 读取
46
+ mammoth:DOCX 转 HTML
47
+ clsx / tailwind-merge:className 合并
48
+ ```
49
+
50
+ ## 5. 验证状态
51
+
52
+ ```text
53
+ typecheck:已通过,npm run typecheck
54
+ build:已通过,npm run build
55
+ npm pack --dry-run:已通过,生成 zhaoxiangjun-base44-document-0.1.0.tgz 预检信息
56
+ 本地 playground:已通过,http://localhost:5191/ 可访问,支持从本机选择文件预览,浏览器控制台无 error/warn
57
+ PDF 高度修复:DocumentViewer 内容区按 height 固定占位,避免 iframe 被 flex-1 压缩
58
+ 公共复用重构:已通过,DocumentViewer 仅保留状态组合和事件分发
59
+ ```
60
+
61
+ ## 6. 发布状态
62
+
63
+ ```text
64
+ 当前版本:0.1.0
65
+ 当前状态:本地初始化完成,尚未发布 npm
66
+ ```
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@zhaoxiangjun/base44-document",
3
+ "private": false,
4
+ "version": "0.1.0",
5
+ "type": "module",
6
+ "description": "React document preview components for Base44 apps and local React projects.",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ },
16
+ "./styles.css": "./dist/base44-document.css"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "docs",
21
+ "README.md"
22
+ ],
23
+ "scripts": {
24
+ "dev": "vite --host 0.0.0.0",
25
+ "build": "tsc -p ./tsconfig.build.json && vite build",
26
+ "typecheck": "tsc -p ./tsconfig.json --noEmit",
27
+ "preview": "vite preview --host 0.0.0.0",
28
+ "prepare": "npm run build"
29
+ },
30
+ "peerDependencies": {
31
+ "react": "^18.2.0 || ^19.0.0",
32
+ "react-dom": "^18.2.0 || ^19.0.0"
33
+ },
34
+ "dependencies": {
35
+ "@zhaoxiangjun/base44-ui": "^0.1.5",
36
+ "clsx": "^2.1.1",
37
+ "lucide-react": "^0.468.0",
38
+ "mammoth": "^1.8.0",
39
+ "marked": "^14.1.3",
40
+ "tailwind-merge": "^2.5.5",
41
+ "xlsx": "^0.18.5"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^22.10.2",
45
+ "@types/react": "^18.3.18",
46
+ "@types/react-dom": "^18.3.5",
47
+ "@vitejs/plugin-react": "^4.3.4",
48
+ "autoprefixer": "^10.4.20",
49
+ "postcss": "^8.4.49",
50
+ "tailwindcss": "^3.4.17",
51
+ "typescript": "^5.7.2",
52
+ "vite": "^6.0.5",
53
+ "vite-plugin-dts": "^4.4.0"
54
+ }
55
+ }