@mario9/tiptap-editor 0.2.0 → 1.0.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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @mario9/tiptap-editor
2
2
 
3
- 基于 Tiptap + Vue 3 的富文本编辑器组件。
3
+ 基于 Tiptap + Vue 3 的富文本编辑器组件,支持 Feature Plugin 架构,消费方可按需引入功能模块实现 tree-shaking。
4
4
 
5
5
  ## 安装
6
6
 
@@ -16,17 +16,44 @@ pnpm add vue element-plus katex lowlight @tiptap/core @tiptap/starter-kit @tipta
16
16
 
17
17
  ## 快速开始
18
18
 
19
+ 不传 `features` 时编辑器只有基础输入能力(无工具栏)。通过 `:features` 按需组合功能:
20
+
19
21
  ```vue
20
22
  <script setup lang="ts">
21
23
  import { ref } from 'vue'
22
- import { TiptapEditor } from '@mario9/tiptap-editor'
24
+ import {
25
+ TiptapEditor,
26
+ UndoRedoFeature,
27
+ TextStyleFeature,
28
+ TextAlignFeature,
29
+ ListFeature,
30
+ CodeBlockFeature,
31
+ TableFeature,
32
+ MathFeature,
33
+ ImageFeature,
34
+ SeparatorFeature,
35
+ } from '@mario9/tiptap-editor'
23
36
  import '@mario9/tiptap-editor/tiptap-editor.css'
24
37
 
25
38
  const content = ref('')
26
39
  </script>
27
40
 
28
41
  <template>
29
- <TiptapEditor v-model="content" placeholder="请输入内容..." />
42
+ <TiptapEditor
43
+ v-model="content"
44
+ :features="[
45
+ UndoRedoFeature,
46
+ TextStyleFeature,
47
+ SeparatorFeature,
48
+ TextAlignFeature,
49
+ ListFeature,
50
+ CodeBlockFeature,
51
+ SeparatorFeature,
52
+ TableFeature,
53
+ MathFeature,
54
+ ImageFeature(),
55
+ ]"
56
+ />
30
57
  </template>
31
58
  ```
32
59
 
@@ -36,20 +63,27 @@ const content = ref('')
36
63
  |------|------|--------|------|
37
64
  | `modelValue` | `string` | `''` | 编辑器内容(HTML 格式),支持 `v-model` 双向绑定 |
38
65
  | `placeholder` | `string` | `'请输入内容...'` | 编辑器占位符文本 |
39
- | `upload` | `(file: File) => Promise<string>` | Base64 转换 | 图片上传函数,返回图片 URL |
40
- | `readonly` | `boolean` | `false` | 只读模式:隐藏工具栏,禁止编辑,图片控件仅保留下载,表格控件隐藏,数学公式不可编辑 |
66
+ | `readonly` | `boolean` | `false` | 只读模式:隐藏工具栏,禁止编辑 |
67
+ | `features` | `FeaturePlugin[]` | `[]` | 功能插件列表,决定工具栏内容和注册的扩展 |
41
68
 
42
- ## 自定义图片上传
69
+ ## Feature Plugins
43
70
 
44
- 不传 `upload` 时,图片默认转为 Base64 Data URL。传入自定义函数可将图片上传到服务器:
71
+ | 导出名 | 说明 | 用法 |
72
+ |--------|------|------|
73
+ | `UndoRedoFeature` | 撤销 / 重做 | `UndoRedoFeature` |
74
+ | `TextStyleFeature` | 粗体、斜体、删除线、下划线、链接 | `TextStyleFeature` |
75
+ | `TextAlignFeature` | 文本对齐(左 / 中 / 右 / 两端) | `TextAlignFeature` |
76
+ | `ListFeature` | 有序、无序、任务列表 | `ListFeature` |
77
+ | `CodeBlockFeature` | 代码块(含语法高亮) | `CodeBlockFeature` |
78
+ | `TableFeature` | 表格(含行列增删、移动) | `TableFeature` |
79
+ | `MathFeature` | 数学公式(内联 / 块级,基于 KaTeX) | `MathFeature` |
80
+ | `ImageFeature` | 图片插入(支持自定义上传,默认 Base64) | `ImageFeature(uploadFn?)` |
81
+ | `SeparatorFeature` | 工具栏分隔符 | `SeparatorFeature` |
45
82
 
46
- ```vue
47
- <script setup lang="ts">
48
- import { ref } from 'vue'
49
- import { TiptapEditor, type UploadFn } from '@mario9/tiptap-editor'
50
- import '@mario9/tiptap-editor/tiptap-editor.css'
83
+ `ImageFeature` 是工厂函数,接受可选的 `upload` 参数:
51
84
 
52
- const content = ref('')
85
+ ```typescript
86
+ import { ImageFeature, type UploadFn } from '@mario9/tiptap-editor'
53
87
 
54
88
  const upload: UploadFn = async (file) => {
55
89
  const formData = new FormData()
@@ -58,30 +92,48 @@ const upload: UploadFn = async (file) => {
58
92
  const data = await res.json()
59
93
  return data.url
60
94
  }
61
- </script>
62
95
 
63
- <template>
64
- <TiptapEditor v-model="content" :upload="upload" />
65
- </template>
96
+ // 不传则默认转为 Base64
97
+ ImageFeature()
98
+ // 传入自定义上传函数
99
+ ImageFeature(upload)
100
+ ```
101
+
102
+ ## 自定义 Feature Plugin
103
+
104
+ 实现 `FeaturePlugin` 接口即可创建自定义功能插件:
105
+
106
+ ```typescript
107
+ import type { FeaturePlugin } from '@mario9/tiptap-editor'
108
+ import MyButton from './MyButton.vue'
109
+ import MyExtension from './MyExtension'
110
+
111
+ export const MyFeature: FeaturePlugin = {
112
+ name: 'my-feature',
113
+ install: () => ({
114
+ extensions: [MyExtension],
115
+ }),
116
+ toolbarComponent: MyButton,
117
+ }
66
118
  ```
67
119
 
68
- ## 内置功能
120
+ `install()` 接收 `PluginInstallContext`(含 `readonly` 和 `provide`),返回 `{ extensions, controlComponent? }`。
121
+
122
+ ## 内置功能(始终启用)
123
+
124
+ 以下功能无需通过 `features` 配置,始终注册:
69
125
 
70
- - 撤销 / 重做
71
- - 文本样式:粗体、斜体、删除线、下划线、行内代码
72
126
  - 标题(H1–H6)
73
- - 列表:有序、无序、任务列表
74
- - 文本对齐:左、中、右、两端
75
- - 链接(点击弹出编辑框)
76
- - 图片插入(支持自定义上传函数,默认转为 Base64)
77
- - 表格(含行列增删、移动操作)
78
- - 数学公式(内联 / 块级,基于 KaTeX)
79
- - 代码块(支持语法高亮,见下方说明)
80
- - 气泡菜单(选中文本时快速格式化)
127
+ - 段落、水平线
128
+ - 任务列表(TaskList / TaskItem)
129
+ - 文本对齐扩展(TextAlign)
130
+ - 链接(StarterKit 内置)
131
+ - 气泡菜单(选中文本时浮现)
132
+ - Placeholder
81
133
 
82
134
  ### 代码高亮
83
135
 
84
- 编辑器使用 `lowlight` 提供语法高亮,默认支持以下常见语言:
136
+ `CodeBlockFeature` 使用 `lowlight` 提供语法高亮,默认支持以下常见语言:
85
137
 
86
138
  **Web 开发**: JavaScript, TypeScript, HTML, CSS, SCSS, JSON, XML
87
139
  **后端**: Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift, Kotlin
@@ -89,22 +141,6 @@ const upload: UploadFn = async (file) => {
89
141
  **数据库**: SQL
90
142
  **其他**: Markdown, Diff, Plaintext
91
143
 
92
- 如需支持更多语言,可以自定义 `lowlight` 实例:
93
-
94
- ```typescript
95
- import { createLowlight } from 'lowlight'
96
- import javascript from 'highlight.js/lib/languages/javascript'
97
- import python from 'highlight.js/lib/languages/python'
98
- // 按需导入其他语言...
99
-
100
- const customLowlight = createLowlight()
101
- customLowlight.register('javascript', javascript)
102
- customLowlight.register('python', python)
103
-
104
- // 在编辑器配置中使用自定义实例
105
- // 注意:这需要修改库源码或 fork 后自定义
106
- ```
107
-
108
144
  ## 技术栈
109
145
 
110
146
  - vue 3.5.25
@@ -115,18 +151,25 @@ customLowlight.register('python', python)
115
151
 
116
152
  ```
117
153
  src/
118
- ├── App.vue # 初始化编辑器,渲染工具栏 + 编辑器内容
154
+ ├── TiptapEditor.tsx # 编辑器主组件(feature plugin 驱动)
119
155
  ├── editor.scss # 工具栏和编辑器样式
156
+ ├── features/ # Feature plugin 实现
157
+ │ ├── UndoRedoFeature.ts
158
+ │ ├── TextStyleFeature.ts
159
+ │ ├── TextAlignFeature.ts
160
+ │ ├── ListFeature.ts
161
+ │ ├── CodeBlockFeature.ts
162
+ │ ├── TableFeature.ts
163
+ │ ├── MathFeature.ts # 含对话框状态管理
164
+ │ ├── ImageFeature.ts # 工厂函数,接受 upload 参数
165
+ │ └── SeparatorFeature.tsx
166
+ ├── types/
167
+ │ └── plugin.ts # FeaturePlugin 接口定义
120
168
  ├── components/
121
169
  │ └── IconButton.tsx # 基础按钮,包裹 ElButton 和 ElTooltip
122
- ├── tiptap-ui/ # 工具栏按钮组
123
- ├── UndoRedoButton.tsx # 撤销重做
124
- │ ├── TextStyleButton.tsx # 加粗、斜体、删除线、下划线、链接
125
- ├── TextAlignButton.tsx # 左边对齐、中间对齐、右边对齐、两端对齐
126
- │ ├── ListButton.tsx # 无序列表、有序列表、任务列表
127
- │ ├── CodeBlockButton.tsx # 代码块(含语法高亮)
128
- │ ├── ImageButton.tsx # 图片上传
129
- │ └── BubbleMenuBar.tsx # 气泡菜单(选中文本时浮现)
130
- ├── tiptap-icons/ # SVG 图标组件 (TSX)
131
- └── tiptap-extension/ # Tiptap extensions
170
+ ├── tiptap-ui/ # 工具栏按钮组件(TSX)
171
+ ├── tiptap-icons/ # SVG 图标组件(TSX)
172
+ └── tiptap-extension/ # 自定义 Tiptap 扩展
173
+ ├── ImageWithAlign.ts # 带对齐属性的图片扩展
174
+ └── ImageUpload.tsx # 图片上传节点
132
175
  ```
package/dist/index.d.ts CHANGED
@@ -1,37 +1,32 @@
1
- import { BuiltinToolbarItem } from './types';
2
- import { default as CodeBlockButton } from './tiptap-ui/CodeBlockButton';
1
+ import { CodeBlockFeature } from './features/CodeBlockFeature';
3
2
  import { Component } from 'vue';
4
3
  import { ComponentOptionsMixin } from 'vue';
5
4
  import { ComponentProvideOptions } from 'vue';
6
- import { CustomToolbarItem } from './types';
7
- import { DEFAULT_TOOLBAR_CONFIG } from './types/toolbar';
8
5
  import { DefineComponent } from 'vue';
9
6
  import { ExtractPropTypes } from 'vue';
10
- import { default as ImageButton } from './tiptap-ui/ImageButton';
7
+ import { FeaturePlugin } from './types/plugin';
8
+ import { ImageFeature } from './features/ImageFeature';
11
9
  import { ImageOptions } from '@tiptap/extension-image';
12
10
  import { JSX } from 'vue/jsx-runtime';
13
- import { default as ListButton } from './tiptap-ui/ListButton';
14
- import { default as MathButton } from './tiptap-ui/MathButton';
11
+ import { ListFeature } from './features/ListFeature';
12
+ import { MathFeature } from './features/MathFeature';
13
+ import { MathType } from './types';
15
14
  import { Node as Node_2 } from '@tiptap/core';
15
+ import { PluginInstallContext } from './types/plugin';
16
+ import { PluginInstallResult } from './types/plugin';
16
17
  import { PropType } from 'vue';
17
18
  import { PublicProps } from 'vue';
18
- import { default as TableButton } from './tiptap-ui/TableButton';
19
- import { default as TextAlignButton } from './tiptap-ui/TextAlignButton';
20
- import { default as TextStyleButton } from './tiptap-ui/TextStyleButton';
19
+ import { SeparatorFeature } from './features/SeparatorFeature';
20
+ import { TableFeature } from './features/TableFeature';
21
+ import { TextAlignFeature } from './features/TextAlignFeature';
22
+ import { TextStyleFeature } from './features/TextStyleFeature';
21
23
  import { default as TiptapEditor } from './TiptapEditor';
22
- import { ToolbarConfig } from './types';
23
- import { ToolbarItem } from './types';
24
- import { ToolbarSeparator } from './types';
25
- import { default as UndoRedoButton } from './tiptap-ui/UndoRedoButton';
24
+ import { UndoRedoFeature } from './features/UndoRedoFeature';
26
25
  import { UploadFn } from './types';
27
26
 
28
- export { BuiltinToolbarItem }
27
+ export { CodeBlockFeature }
29
28
 
30
- export { CodeBlockButton }
31
-
32
- export { CustomToolbarItem }
33
-
34
- export { DEFAULT_TOOLBAR_CONFIG }
29
+ export { FeaturePlugin }
35
30
 
36
31
  export declare const IconButton: DefineComponent<ExtractPropTypes< {
37
32
  icon: {
@@ -76,29 +71,31 @@ isActive: boolean;
76
71
  disabled: boolean;
77
72
  }, {}, {}, {}, string, ComponentProvideOptions, true, {}, any>;
78
73
 
79
- export { ImageButton }
74
+ export { ImageFeature }
80
75
 
81
76
  export declare const ImageWithAlign: Node_2<ImageOptions, any>;
82
77
 
83
- export { ListButton }
78
+ export { ListFeature }
84
79
 
85
- export { MathButton }
80
+ export { MathFeature }
86
81
 
87
- export { TableButton }
82
+ export { MathType }
88
83
 
89
- export { TextAlignButton }
84
+ export { PluginInstallContext }
90
85
 
91
- export { TextStyleButton }
86
+ export { PluginInstallResult }
92
87
 
93
- export { TiptapEditor }
88
+ export { SeparatorFeature }
94
89
 
95
- export { ToolbarConfig }
90
+ export { TableFeature }
96
91
 
97
- export { ToolbarItem }
92
+ export { TextAlignFeature }
98
93
 
99
- export { ToolbarSeparator }
94
+ export { TextStyleFeature }
95
+
96
+ export { TiptapEditor }
100
97
 
101
- export { UndoRedoButton }
98
+ export { UndoRedoFeature }
102
99
 
103
100
  export { UploadFn }
104
101