kc-plate-editor 0.5.4 → 0.5.6
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.
- package/README.md +572 -4
- package/dist/components/editor/plate-editor.d.ts +8 -2
- package/dist/{index-D-kymQAz.js → index-BDYrl3fS.js} +293 -293
- package/dist/{index-ClCxNd_m.js → index-BFrlP6Yp.js} +1 -1
- package/dist/{index-C4RdEaLJ.mjs → index-D8ZvqcZ1.mjs} +21264 -21155
- package/dist/{index-BX9WxJZL.mjs → index-KasM0pgW.mjs} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +78 -74
- package/dist/lib/config-provider.d.ts +66 -9
- package/dist/lib/http.d.ts +32 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,34 @@
|
|
|
8
8
|
|
|
9
9
|
| 版本 | 状态 | 说明 |
|
|
10
10
|
|------|------|------|
|
|
11
|
-
| v0.5.
|
|
11
|
+
| v0.5.6 | ✅ 最新版本 | 增强上传配置灵活性 |
|
|
12
|
+
| v0.5.5 | ✅ 稳定版本 | 快捷键保存、本地存储、目录跳转优化 |
|
|
13
|
+
| v0.5.4 | ✅ 稳定版本 | 滚动和布局优化 |
|
|
14
|
+
| v0.5.0 | ✅ 已发布私服 | 基础稳定版本 |
|
|
15
|
+
|
|
16
|
+
### v0.5.6 更新内容
|
|
17
|
+
|
|
18
|
+
- **增强上传配置** - 新增 `UploadConfig` 详细配置接口
|
|
19
|
+
- **增强 AI 配置** - 新增 `AIConfig` 详细配置接口
|
|
20
|
+
- **自定义上传函数** - 支持 `customUpload` 完全自定义上传逻辑
|
|
21
|
+
- **自定义 AI 函数** - 支持 `customCopilot` 和 `customCommand` 自定义 AI 逻辑
|
|
22
|
+
- **文件验证** - 支持 `maxSize` 和 `acceptTypes` 文件验证
|
|
23
|
+
- **额外表单数据** - 支持 `extraData` 添加额外表单字段
|
|
24
|
+
- **灵活响应解析** - 支持多种服务端响应格式
|
|
25
|
+
- **配置辅助函数** - 新增 `getUploadConfig`、`getAiConfig` 等辅助函数
|
|
26
|
+
|
|
27
|
+
### v0.5.5 更新内容
|
|
28
|
+
|
|
29
|
+
- **快捷键保存** - 支持 `Ctrl+S` / `Cmd+S` 快捷键保存
|
|
30
|
+
- **本地存储** - 新增 `saveToLocalStorage()` 和 `clearLocalStorage()` 方法
|
|
31
|
+
- **目录跳转优化** - 修复目录点击跳转不准确的问题
|
|
32
|
+
- **onSave 回调** - 新增 `onSave` 属性用于处理快捷键保存事件
|
|
33
|
+
|
|
34
|
+
### v0.5.4 更新内容
|
|
35
|
+
|
|
36
|
+
- 修复编辑器容器双滚动条问题
|
|
37
|
+
- 优化 `EditorContainer` 的 `demo` 变体高度设置
|
|
38
|
+
- 修复工具栏吸顶在嵌套滚动容器中失效的问题
|
|
12
39
|
|
|
13
40
|
### v0.5.0 更新内容
|
|
14
41
|
|
|
@@ -25,6 +52,7 @@
|
|
|
25
52
|
- [特性](#特性)
|
|
26
53
|
- [安装](#安装)
|
|
27
54
|
- [快速开始](#快速开始)
|
|
55
|
+
- [集成注意事项](#集成注意事项) ⭐ **重要**
|
|
28
56
|
- [工具栏配置](#工具栏配置)
|
|
29
57
|
- [内容操作](#内容操作)
|
|
30
58
|
- [导出功能](#导出功能)
|
|
@@ -171,6 +199,437 @@ function App() {
|
|
|
171
199
|
}
|
|
172
200
|
```
|
|
173
201
|
|
|
202
|
+
### 6. 高级上传配置 (v0.5.6+)
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
import { ConfigProvider, PlateEditor, type UploadConfig } from 'kc-plate-editor';
|
|
206
|
+
|
|
207
|
+
// 详细的上传配置
|
|
208
|
+
const uploadConfig: UploadConfig = {
|
|
209
|
+
url: '/api/upload', // 上传地址
|
|
210
|
+
fieldName: 'file', // 文件字段名
|
|
211
|
+
maxSize: 10 * 1024 * 1024, // 最大 10MB
|
|
212
|
+
acceptTypes: ['image/*', 'video/*', 'application/pdf'],
|
|
213
|
+
headers: {
|
|
214
|
+
'X-Upload-Token': 'your-token',
|
|
215
|
+
},
|
|
216
|
+
extraData: {
|
|
217
|
+
category: 'document',
|
|
218
|
+
source: 'editor',
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
function App() {
|
|
223
|
+
return (
|
|
224
|
+
<ConfigProvider
|
|
225
|
+
config={{
|
|
226
|
+
baseURL: 'https://api.example.com', // API 基础地址
|
|
227
|
+
upload: uploadConfig,
|
|
228
|
+
locale: 'zh-CN',
|
|
229
|
+
}}
|
|
230
|
+
>
|
|
231
|
+
<PlateEditor />
|
|
232
|
+
</ConfigProvider>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### 7. 自定义上传函数
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
import { ConfigProvider, PlateEditor, type UploadResult } from 'kc-plate-editor';
|
|
241
|
+
|
|
242
|
+
// 完全自定义上传逻辑
|
|
243
|
+
async function customUpload(
|
|
244
|
+
file: File,
|
|
245
|
+
onProgress?: (progress: number) => void
|
|
246
|
+
): Promise<UploadResult> {
|
|
247
|
+
const formData = new FormData();
|
|
248
|
+
formData.append('file', file);
|
|
249
|
+
|
|
250
|
+
// 使用你自己的上传逻辑
|
|
251
|
+
const response = await fetch('/api/my-upload', {
|
|
252
|
+
method: 'POST',
|
|
253
|
+
body: formData,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const result = await response.json();
|
|
257
|
+
|
|
258
|
+
return {
|
|
259
|
+
url: result.fileUrl,
|
|
260
|
+
name: file.name,
|
|
261
|
+
size: file.size,
|
|
262
|
+
type: file.type,
|
|
263
|
+
key: result.fileId,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function App() {
|
|
268
|
+
return (
|
|
269
|
+
<ConfigProvider
|
|
270
|
+
config={{
|
|
271
|
+
upload: {
|
|
272
|
+
customUpload, // 使用自定义上传函数
|
|
273
|
+
},
|
|
274
|
+
locale: 'zh-CN',
|
|
275
|
+
}}
|
|
276
|
+
>
|
|
277
|
+
<PlateEditor />
|
|
278
|
+
</ConfigProvider>
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### 8. AI 配置 (v0.5.6+)
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
import { ConfigProvider, PlateEditor, type AIConfig } from 'kc-plate-editor';
|
|
287
|
+
|
|
288
|
+
// 详细的 AI 配置
|
|
289
|
+
const aiConfig: AIConfig = {
|
|
290
|
+
copilotUrl: '/api/ai/copilot', // Copilot 自动补全 API
|
|
291
|
+
commandUrl: '/api/ai/command', // AI 命令/对话 API
|
|
292
|
+
apiKey: 'your-api-key', // API 密钥
|
|
293
|
+
model: 'gpt-4', // 模型名称
|
|
294
|
+
headers: {
|
|
295
|
+
'X-Custom-Header': 'value',
|
|
296
|
+
},
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
function App() {
|
|
300
|
+
return (
|
|
301
|
+
<ConfigProvider
|
|
302
|
+
config={{
|
|
303
|
+
baseURL: 'https://api.example.com',
|
|
304
|
+
ai: aiConfig,
|
|
305
|
+
locale: 'zh-CN',
|
|
306
|
+
}}
|
|
307
|
+
>
|
|
308
|
+
<PlateEditor />
|
|
309
|
+
</ConfigProvider>
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## 集成注意事项
|
|
317
|
+
|
|
318
|
+
> ⚠️ **重要**: 在将 kc-plate-editor 集成到现有项目时,请仔细阅读以下注意事项,避免常见问题。
|
|
319
|
+
|
|
320
|
+
### 1. 全局样式冲突
|
|
321
|
+
|
|
322
|
+
**问题**: 项目中的全局 CSS 可能会影响编辑器的显示效果。
|
|
323
|
+
|
|
324
|
+
**常见冲突**:
|
|
325
|
+
|
|
326
|
+
```css
|
|
327
|
+
/* ❌ 这些全局样式会破坏编辑器的列表显示 */
|
|
328
|
+
ul, ol {
|
|
329
|
+
list-style: none;
|
|
330
|
+
padding: 0;
|
|
331
|
+
margin: 0;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/* ❌ 这会影响编辑器内的链接样式 */
|
|
335
|
+
a {
|
|
336
|
+
text-decoration: none;
|
|
337
|
+
color: inherit;
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**解决方案**:
|
|
342
|
+
|
|
343
|
+
```css
|
|
344
|
+
/* ✅ 方案1: 使用更具体的选择器,排除编辑器区域 */
|
|
345
|
+
ul:not([data-slate-node]), ol:not([data-slate-node]) {
|
|
346
|
+
list-style: none;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/* ✅ 方案2: 在编辑器容器内重置样式 */
|
|
350
|
+
[data-plate-editor-container] ul,
|
|
351
|
+
[data-plate-editor-container] ol {
|
|
352
|
+
list-style: revert;
|
|
353
|
+
padding: revert;
|
|
354
|
+
margin: revert;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/* ✅ 方案3: 直接注释掉全局样式(推荐) */
|
|
358
|
+
/* ul, ol { list-style: none; } */
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### 2. 容器高度和滚动
|
|
362
|
+
|
|
363
|
+
**问题**: 编辑器需要明确的高度才能正确滚动。
|
|
364
|
+
|
|
365
|
+
```tsx
|
|
366
|
+
// ❌ 错误:没有设置高度,编辑器会无限增长
|
|
367
|
+
<div>
|
|
368
|
+
<PlateEditor />
|
|
369
|
+
</div>
|
|
370
|
+
|
|
371
|
+
// ✅ 正确:设置固定高度或使用 flex 布局
|
|
372
|
+
<div style={{ height: 500 }}>
|
|
373
|
+
<PlateEditor />
|
|
374
|
+
</div>
|
|
375
|
+
|
|
376
|
+
// ✅ 正确:使用 flex 布局填充可用空间
|
|
377
|
+
<div style={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
|
|
378
|
+
<header>...</header>
|
|
379
|
+
<div style={{ flex: 1, overflow: 'hidden' }}>
|
|
380
|
+
<PlateEditor />
|
|
381
|
+
</div>
|
|
382
|
+
</div>
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**Ant Design Card 中使用**:
|
|
386
|
+
|
|
387
|
+
```tsx
|
|
388
|
+
// ✅ 推荐配置:设置 body 的高度和 overflow
|
|
389
|
+
<Card
|
|
390
|
+
style={{ minHeight: 500 }}
|
|
391
|
+
styles={{
|
|
392
|
+
body: {
|
|
393
|
+
padding: 0,
|
|
394
|
+
height: 500,
|
|
395
|
+
display: 'flex',
|
|
396
|
+
flexDirection: 'column',
|
|
397
|
+
overflow: 'hidden' // 防止双滚动条
|
|
398
|
+
}
|
|
399
|
+
}}
|
|
400
|
+
>
|
|
401
|
+
<PlateEditor />
|
|
402
|
+
</Card>
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### 3. 工具栏吸顶
|
|
406
|
+
|
|
407
|
+
**问题**: 工具栏吸顶需要正确的滚动容器。
|
|
408
|
+
|
|
409
|
+
```tsx
|
|
410
|
+
// ❌ 错误:外层容器有 overflow: auto,会创建新的滚动上下文
|
|
411
|
+
<div style={{ overflow: 'auto', height: 500 }}>
|
|
412
|
+
<PlateEditor toolbarSticky={true} />
|
|
413
|
+
</div>
|
|
414
|
+
|
|
415
|
+
// ✅ 正确:外层容器使用 overflow: hidden
|
|
416
|
+
<div style={{ overflow: 'hidden', height: 500 }}>
|
|
417
|
+
<PlateEditor toolbarSticky={true} />
|
|
418
|
+
</div>
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
**独立工具栏场景**:
|
|
422
|
+
|
|
423
|
+
```tsx
|
|
424
|
+
// 使用 StandaloneToolbar 时,需要自己管理滚动容器
|
|
425
|
+
import { StandaloneToolbar, PlateEditor } from 'kc-plate-editor';
|
|
426
|
+
|
|
427
|
+
// 滚动容器
|
|
428
|
+
<div className="scroll-container" style={{ overflow: 'auto', height: 500 }}>
|
|
429
|
+
{/* 工具栏使用 CSS sticky */}
|
|
430
|
+
<div style={{ position: 'sticky', top: 0, zIndex: 50 }}>
|
|
431
|
+
<StandaloneToolbar config={config} editor={editor} sticky={false} />
|
|
432
|
+
</div>
|
|
433
|
+
|
|
434
|
+
<PlateEditor showToolbar={false} />
|
|
435
|
+
</div>
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### 4. 快捷键保存
|
|
439
|
+
|
|
440
|
+
**v0.5.5 新增**: 支持 `Ctrl+S` / `Cmd+S` 快捷键保存。
|
|
441
|
+
|
|
442
|
+
```tsx
|
|
443
|
+
<PlateEditor
|
|
444
|
+
// 方式1: 使用 onSave 回调处理保存逻辑
|
|
445
|
+
onSave={(content) => {
|
|
446
|
+
console.log('快捷键保存:', content);
|
|
447
|
+
// 调用 API 保存到服务器
|
|
448
|
+
saveToServer(content);
|
|
449
|
+
}}
|
|
450
|
+
|
|
451
|
+
// 方式2: 启用自动保存到 localStorage
|
|
452
|
+
autoSave={true}
|
|
453
|
+
autoSaveKey="my-editor-content"
|
|
454
|
+
autoSaveInterval={5000} // 5秒自动保存一次
|
|
455
|
+
/>
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**清理本地存储**:
|
|
459
|
+
|
|
460
|
+
```tsx
|
|
461
|
+
// 发布或退出时清理临时数据
|
|
462
|
+
const handlePublish = async () => {
|
|
463
|
+
await publishDocument();
|
|
464
|
+
editorRef.current?.clearLocalStorage();
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
const handleExit = () => {
|
|
468
|
+
editorRef.current?.clearLocalStorage();
|
|
469
|
+
navigate('/');
|
|
470
|
+
};
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
### 5. 目录跳转
|
|
474
|
+
|
|
475
|
+
**问题**: 目录点击跳转不到正确位置。
|
|
476
|
+
|
|
477
|
+
**原因**: 编辑器使用了嵌套滚动容器,`scrollIntoView` 可能无法正确工作。
|
|
478
|
+
|
|
479
|
+
**v0.5.5 已修复**: 目录跳转现在会自动查找正确的滚动容器。
|
|
480
|
+
|
|
481
|
+
```tsx
|
|
482
|
+
// 如果仍有问题,确保编辑器容器结构正确
|
|
483
|
+
<div style={{ height: 500, overflow: 'hidden' }}>
|
|
484
|
+
<PlateEditor
|
|
485
|
+
showToc={true}
|
|
486
|
+
tocPosition="right"
|
|
487
|
+
tocWidth={240}
|
|
488
|
+
/>
|
|
489
|
+
</div>
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### 6. 表单集成
|
|
493
|
+
|
|
494
|
+
**在 Ant Design Form 中使用**:
|
|
495
|
+
|
|
496
|
+
```tsx
|
|
497
|
+
import { Form, Input, Button } from 'antd';
|
|
498
|
+
import { PlateEditor, ConfigProvider, EditorErrorBoundary } from 'kc-plate-editor';
|
|
499
|
+
|
|
500
|
+
function ArticleForm() {
|
|
501
|
+
const editorRef = useRef<PlateEditorRef>(null);
|
|
502
|
+
|
|
503
|
+
const handleSubmit = async () => {
|
|
504
|
+
const content = editorRef.current?.getContent();
|
|
505
|
+
const markdown = editorRef.current?.getMarkdown();
|
|
506
|
+
const html = await editorRef.current?.getHtml();
|
|
507
|
+
|
|
508
|
+
// 提交到服务器
|
|
509
|
+
await submitArticle({ content, markdown, html });
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
return (
|
|
513
|
+
<Form onFinish={handleSubmit}>
|
|
514
|
+
<Form.Item label="标题" name="title">
|
|
515
|
+
<Input />
|
|
516
|
+
</Form.Item>
|
|
517
|
+
|
|
518
|
+
<Form.Item label="内容">
|
|
519
|
+
{/* 添加边框样式 */}
|
|
520
|
+
<div style={{ border: '1px solid #d9d9d9', borderRadius: 8, overflow: 'hidden' }}>
|
|
521
|
+
<ConfigProvider config={{ locale: 'zh-CN' }}>
|
|
522
|
+
<EditorErrorBoundary>
|
|
523
|
+
<PlateEditor
|
|
524
|
+
ref={editorRef}
|
|
525
|
+
toolbarConfig={BASIC_TOOLBAR}
|
|
526
|
+
toolbarSticky={false} // 表单中不需要吸顶
|
|
527
|
+
showSettings={false}
|
|
528
|
+
/>
|
|
529
|
+
</EditorErrorBoundary>
|
|
530
|
+
</ConfigProvider>
|
|
531
|
+
</div>
|
|
532
|
+
</Form.Item>
|
|
533
|
+
|
|
534
|
+
<Button type="primary" htmlType="submit">提交</Button>
|
|
535
|
+
</Form>
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### 7. 全屏编辑模式
|
|
541
|
+
|
|
542
|
+
**实现全屏沉浸式编辑**:
|
|
543
|
+
|
|
544
|
+
```tsx
|
|
545
|
+
function FullScreenEditor() {
|
|
546
|
+
return (
|
|
547
|
+
<div style={{
|
|
548
|
+
height: '100vh',
|
|
549
|
+
display: 'flex',
|
|
550
|
+
flexDirection: 'column',
|
|
551
|
+
background: '#fff',
|
|
552
|
+
}}>
|
|
553
|
+
{/* 顶部导航栏 */}
|
|
554
|
+
<div style={{
|
|
555
|
+
padding: '8px 16px',
|
|
556
|
+
borderBottom: '1px solid #e8e8e8',
|
|
557
|
+
flexShrink: 0,
|
|
558
|
+
}}>
|
|
559
|
+
<span>文档标题</span>
|
|
560
|
+
<Button onClick={handleSave}>保存</Button>
|
|
561
|
+
</div>
|
|
562
|
+
|
|
563
|
+
{/* 编辑器区域 - flex: 1 填充剩余空间 */}
|
|
564
|
+
<div style={{ flex: 1, overflow: 'hidden' }}>
|
|
565
|
+
<PlateEditor
|
|
566
|
+
toolbarConfig={FULL_TOOLBAR}
|
|
567
|
+
toolbarSticky={true}
|
|
568
|
+
toolbarAlign="center"
|
|
569
|
+
contentMaxWidth={900}
|
|
570
|
+
showToc={true}
|
|
571
|
+
tocPosition="right"
|
|
572
|
+
autoFocus
|
|
573
|
+
/>
|
|
574
|
+
</div>
|
|
575
|
+
</div>
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
### 8. 错误边界
|
|
581
|
+
|
|
582
|
+
**始终使用 EditorErrorBoundary 包裹编辑器**:
|
|
583
|
+
|
|
584
|
+
```tsx
|
|
585
|
+
import { EditorErrorBoundary, PlateEditor } from 'kc-plate-editor';
|
|
586
|
+
|
|
587
|
+
// ✅ 推荐:使用错误边界防止编辑器崩溃影响整个页面
|
|
588
|
+
<EditorErrorBoundary>
|
|
589
|
+
<PlateEditor />
|
|
590
|
+
</EditorErrorBoundary>
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### 9. 性能优化
|
|
594
|
+
|
|
595
|
+
**避免不必要的重渲染**:
|
|
596
|
+
|
|
597
|
+
```tsx
|
|
598
|
+
// ❌ 错误:每次渲染都创建新的配置对象
|
|
599
|
+
<PlateEditor
|
|
600
|
+
toolbarConfig={{ ...FULL_TOOLBAR, history: false }}
|
|
601
|
+
/>
|
|
602
|
+
|
|
603
|
+
// ✅ 正确:使用 useMemo 缓存配置
|
|
604
|
+
const toolbarConfig = useMemo(() => ({
|
|
605
|
+
...FULL_TOOLBAR,
|
|
606
|
+
history: false,
|
|
607
|
+
}), []);
|
|
608
|
+
|
|
609
|
+
<PlateEditor toolbarConfig={toolbarConfig} />
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
**预设切换时重新挂载编辑器**:
|
|
613
|
+
|
|
614
|
+
```tsx
|
|
615
|
+
// 使用 key 强制重新挂载,确保工具栏配置正确应用
|
|
616
|
+
<PlateEditor
|
|
617
|
+
key={`editor-${activePreset}`}
|
|
618
|
+
toolbarConfig={getToolbarConfig()}
|
|
619
|
+
/>
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
### 10. 常见问题排查
|
|
623
|
+
|
|
624
|
+
| 问题 | 可能原因 | 解决方案 |
|
|
625
|
+
|------|----------|----------|
|
|
626
|
+
| 列表没有项目符号 | 全局 CSS 重置了 list-style | 移除或修改全局样式 |
|
|
627
|
+
| 双滚动条 | 容器和编辑器都有 overflow | 外层使用 `overflow: hidden` |
|
|
628
|
+
| 工具栏不吸顶 | 滚动容器不正确 | 检查父容器的 overflow 设置 |
|
|
629
|
+
| 目录跳转失效 | 嵌套滚动容器 | 升级到 v0.5.5 |
|
|
630
|
+
| 快捷键无效 | 焦点不在编辑器 | 确保编辑器已聚焦 |
|
|
631
|
+
| 内容丢失 | 未保存就离开 | 使用 autoSave 或 onSave |
|
|
632
|
+
|
|
174
633
|
---
|
|
175
634
|
|
|
176
635
|
## 工具栏配置
|
|
@@ -345,49 +804,158 @@ const outline = editorRef.current?.getOutline();
|
|
|
345
804
|
|
|
346
805
|
### PlateEditorRef 方法
|
|
347
806
|
|
|
807
|
+
#### 内容管理
|
|
808
|
+
|
|
348
809
|
| 方法 | 说明 | 返回值 |
|
|
349
810
|
|------|------|--------|
|
|
350
811
|
| `getContent()` | 获取编辑器内容 | `Value` |
|
|
351
812
|
| `setContent(value)` | 设置编辑器内容 | `void` |
|
|
352
813
|
| `resetContent()` | 重置为初始内容 | `void` |
|
|
814
|
+
| `getText()` | 获取纯文本内容 | `string` |
|
|
815
|
+
| `isEmpty()` | 检查编辑器是否为空 | `boolean` |
|
|
816
|
+
|
|
817
|
+
#### Markdown/HTML 转换
|
|
818
|
+
|
|
819
|
+
| 方法 | 说明 | 返回值 |
|
|
820
|
+
|------|------|--------|
|
|
353
821
|
| `getMarkdown()` | 获取 Markdown | `string` |
|
|
354
822
|
| `setMarkdown(md)` | 设置 Markdown | `void` |
|
|
355
823
|
| `insertMarkdown(md)` | 插入 Markdown | `void` |
|
|
356
824
|
| `getHtml()` | 获取 HTML | `Promise<string>` |
|
|
357
825
|
| `setHtml(html)` | 设置 HTML | `void` |
|
|
826
|
+
|
|
827
|
+
#### 查找替换
|
|
828
|
+
|
|
829
|
+
| 方法 | 说明 | 返回值 |
|
|
830
|
+
|------|------|--------|
|
|
358
831
|
| `find(text, options)` | 查找文本 | `MatchPosition[]` |
|
|
359
832
|
| `replace(search, replace, options)` | 替换文本 | `number` |
|
|
833
|
+
|
|
834
|
+
#### 文档分析
|
|
835
|
+
|
|
836
|
+
| 方法 | 说明 | 返回值 |
|
|
837
|
+
|------|------|--------|
|
|
360
838
|
| `getWordCount()` | 获取字数统计 | `WordCountResult` |
|
|
361
839
|
| `getOutline()` | 获取文档大纲 | `OutlineItem[]` |
|
|
840
|
+
|
|
841
|
+
#### 导出功能
|
|
842
|
+
|
|
843
|
+
| 方法 | 说明 | 返回值 |
|
|
844
|
+
|------|------|--------|
|
|
362
845
|
| `exportAsHtml(filename)` | 导出 HTML | `Promise<void>` |
|
|
363
846
|
| `exportAsMarkdown(filename)` | 导出 Markdown | `Promise<void>` |
|
|
364
847
|
| `exportAsPdf(filename)` | 导出 PDF | `Promise<void>` |
|
|
365
848
|
| `exportAsImage(filename)` | 导出图片 | `Promise<void>` |
|
|
849
|
+
|
|
850
|
+
#### 插入操作
|
|
851
|
+
|
|
852
|
+
| 方法 | 说明 | 返回值 |
|
|
853
|
+
|------|------|--------|
|
|
366
854
|
| `insertText(text)` | 插入文本 | `void` |
|
|
367
855
|
| `insertLink(url, text)` | 插入链接 | `void` |
|
|
368
856
|
| `insertImage(url)` | 插入图片 | `void` |
|
|
857
|
+
|
|
858
|
+
#### 格式控制
|
|
859
|
+
|
|
860
|
+
| 方法 | 说明 | 返回值 |
|
|
861
|
+
|------|------|--------|
|
|
369
862
|
| `toggleMark(mark)` | 切换格式 | `void` |
|
|
370
863
|
| `undo()` | 撤销 | `void` |
|
|
371
864
|
| `redo()` | 重做 | `void` |
|
|
865
|
+
|
|
866
|
+
#### 编辑器控制
|
|
867
|
+
|
|
868
|
+
| 方法 | 说明 | 返回值 |
|
|
869
|
+
|------|------|--------|
|
|
372
870
|
| `focus()` | 聚焦编辑器 | `void` |
|
|
373
871
|
| `blur()` | 失焦编辑器 | `void` |
|
|
374
872
|
| `getEditor()` | 获取底层编辑器实例 | `TPlateEditor` |
|
|
375
873
|
|
|
874
|
+
#### 修改状态
|
|
875
|
+
|
|
876
|
+
| 方法 | 说明 | 返回值 |
|
|
877
|
+
|------|------|--------|
|
|
878
|
+
| `isModified()` | 检查内容是否已修改 | `boolean` |
|
|
879
|
+
| `resetModifiedState()` | 重置修改状态 | `void` |
|
|
880
|
+
|
|
881
|
+
#### 工具栏/目录控制
|
|
882
|
+
|
|
883
|
+
| 方法 | 说明 | 返回值 |
|
|
884
|
+
|------|------|--------|
|
|
885
|
+
| `setToolbarVisible(visible)` | 设置工具栏可见性 | `void` |
|
|
886
|
+
| `setTocVisible(visible)` | 设置目录可见性 | `void` |
|
|
887
|
+
|
|
888
|
+
#### 本地存储 (v0.5.5+)
|
|
889
|
+
|
|
890
|
+
| 方法 | 说明 | 返回值 |
|
|
891
|
+
|------|------|--------|
|
|
892
|
+
| `saveToLocalStorage()` | 手动保存到 localStorage | `void` |
|
|
893
|
+
| `clearLocalStorage()` | 清理 localStorage 临时数据 | `void` |
|
|
894
|
+
|
|
895
|
+
#### 自动保存
|
|
896
|
+
|
|
897
|
+
| 方法 | 说明 | 返回值 |
|
|
898
|
+
|------|------|--------|
|
|
899
|
+
| `getAutoSaveState()` | 获取自动保存状态 | `AutoSaveState` |
|
|
900
|
+
| `saveNow()` | 立即触发保存 | `void` |
|
|
901
|
+
| `restoreAutoSave()` | 恢复自动保存的内容 | `Value \| null` |
|
|
902
|
+
| `clearAutoSave()` | 清除自动保存数据 | `void` |
|
|
903
|
+
|
|
376
904
|
### PlateEditorProps
|
|
377
905
|
|
|
906
|
+
#### 基础属性
|
|
907
|
+
|
|
378
908
|
| 属性 | 类型 | 默认值 | 说明 |
|
|
379
909
|
|------|------|--------|------|
|
|
380
910
|
| `value` | `Value` | - | 编辑器内容 |
|
|
381
911
|
| `onChange` | `(value: Value) => void` | - | 内容变化回调 |
|
|
382
912
|
| `mode` | `'edit' \| 'view' \| 'suggestion'` | `'edit'` | 编辑器模式 |
|
|
913
|
+
| `disabled` | `boolean` | `false` | 是否禁用 |
|
|
914
|
+
| `readOnly` | `boolean` | `false` | 是否只读 |
|
|
915
|
+
| `autoFocus` | `boolean` | `false` | 是否自动聚焦 |
|
|
916
|
+
| `className` | `string` | - | 自定义类名 |
|
|
917
|
+
|
|
918
|
+
#### 工具栏属性
|
|
919
|
+
|
|
920
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
921
|
+
|------|------|--------|------|
|
|
383
922
|
| `toolbarConfig` | `ToolbarConfig` | `FULL_TOOLBAR` | 工具栏配置 |
|
|
384
923
|
| `showToolbar` | `boolean` | `true` | 是否显示工具栏 |
|
|
924
|
+
| `toolbarSticky` | `boolean` | `true` | 工具栏是否吸顶 |
|
|
385
925
|
| `toolbarAlign` | `'left' \| 'center' \| 'right'` | `'left'` | 工具栏对齐 |
|
|
386
926
|
| `toolbarFullWidth` | `boolean` | `false` | 工具栏是否全宽 |
|
|
927
|
+
| `toolbarClassName` | `string` | - | 工具栏类名 |
|
|
928
|
+
| `toolbarStyle` | `CSSProperties` | - | 工具栏样式 |
|
|
929
|
+
| `customToolbarButtons` | `CustomToolbarButtons` | - | 自定义工具栏按钮 |
|
|
930
|
+
|
|
931
|
+
#### 目录属性
|
|
932
|
+
|
|
933
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
934
|
+
|------|------|--------|------|
|
|
387
935
|
| `showToc` | `boolean` | `false` | 是否显示目录 |
|
|
388
|
-
| `tocPosition` | `'left' \| 'right'` | `'left'` | 目录位置 |
|
|
389
|
-
| `
|
|
390
|
-
| `
|
|
936
|
+
| `tocPosition` | `'left' \| 'right' \| 'top' \| 'custom'` | `'left'` | 目录位置 |
|
|
937
|
+
| `tocWidth` | `string \| number` | `'320px'` | 目录宽度 |
|
|
938
|
+
| `tocClassName` | `string` | - | 目录类名 |
|
|
939
|
+
| `tocStyle` | `CSSProperties` | - | 目录样式 |
|
|
940
|
+
| `renderToc` | `(toc: ReactNode) => ReactNode` | - | 自定义目录渲染 |
|
|
941
|
+
|
|
942
|
+
#### 保存属性 (v0.5.5+)
|
|
943
|
+
|
|
944
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
945
|
+
|------|------|--------|------|
|
|
946
|
+
| `onSave` | `(content: Value) => void` | - | 快捷键保存回调 |
|
|
947
|
+
| `autoSave` | `boolean` | `false` | 是否启用自动保存 |
|
|
948
|
+
| `autoSaveKey` | `string` | - | localStorage 存储键名 |
|
|
949
|
+
| `autoSaveInterval` | `number` | `30000` | 自动保存间隔(毫秒) |
|
|
950
|
+
| `onAutoSave` | `(content: Value) => void` | - | 自动保存回调 |
|
|
951
|
+
|
|
952
|
+
#### 其他属性
|
|
953
|
+
|
|
954
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
955
|
+
|------|------|--------|------|
|
|
956
|
+
| `showSettings` | `boolean` | `true` | 是否显示设置按钮 |
|
|
957
|
+
| `contentMaxWidth` | `string \| number` | - | 内容区域最大宽度 |
|
|
958
|
+
| `onModifiedChange` | `(isModified: boolean) => void` | - | 修改状态变化回调 |
|
|
391
959
|
|
|
392
960
|
---
|
|
393
961
|
|
|
@@ -88,6 +88,8 @@ export interface PlateEditorProps {
|
|
|
88
88
|
autoSaveInterval?: number;
|
|
89
89
|
/** 自动保存回调 */
|
|
90
90
|
onAutoSave?: (content: Value) => void;
|
|
91
|
+
/** 保存回调(用于快捷键保存 Ctrl+S / Cmd+S) */
|
|
92
|
+
onSave?: (content: Value) => void;
|
|
91
93
|
}
|
|
92
94
|
/**
|
|
93
95
|
* PlateEditor 组件引用接口
|
|
@@ -150,8 +152,12 @@ export interface PlateEditorRef {
|
|
|
150
152
|
exportAsMarkdown: (filename?: string) => Promise<void>;
|
|
151
153
|
/** 导出为 PDF 文件 */
|
|
152
154
|
exportAsPdf: (filename?: string) => Promise<void>;
|
|
153
|
-
/**
|
|
154
|
-
exportAsImage: (filename
|
|
155
|
+
/** 导出为图片 */
|
|
156
|
+
exportAsImage: (filename: string) => Promise<void>;
|
|
157
|
+
/** 清理本地存储的临时内容 */
|
|
158
|
+
clearLocalStorage: () => void;
|
|
159
|
+
/** 手动保存到本地存储 */
|
|
160
|
+
saveToLocalStorage: () => void;
|
|
155
161
|
/** 查找文本 */
|
|
156
162
|
find: (searchText: string, options?: FindOptions) => MatchPosition[];
|
|
157
163
|
/** 替换文本 */
|