@sanmokeji/smo-editor 0.0.5 → 0.0.7

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,48 +1,206 @@
1
- # smo-editor
1
+ # @sanmokeji/smo-editor
2
2
 
3
- This template should help get you started developing with Vue 3 in Vite.
3
+ 🚀 **SmoEditor** 是一款基于 Vue 3 Tiptap 打造的轻量、高效、开箱即用的富文本编辑器组件。具备完美的 TypeScript 类型支持。
4
4
 
5
- ## Recommended IDE Setup
5
+ ***
6
6
 
7
- [VS Code](https://code.visualstudio.com/) + [Vue (Official)](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
7
+ ## 特性
8
8
 
9
- ## Recommended Browser Setup
9
+ - 🎯 **开箱即用** — 内置完整工具栏,引入即可使用
10
+ - 🪶 **轻量高效** — 基于 Tiptap 3 ProseMirror,按需扩展
11
+ - 💪 **TypeScript 优先** — 完善的类型推导,IDE 智能提示丝滑
12
+ - 🎨 **图片增强** — 支持上传、拖拽、粘贴图片,浮动菜单调整对齐与宽度
13
+ - 🔗 **链接编辑** — 行内链接设置弹窗,自动识别 URL
14
+ - 📐 **文字对齐** — 左对齐 / 居中 / 右对齐
15
+ - 📋 **丰富格式** — 加粗、斜体、删除线、行内代码、代码块、引用、分割线
16
+ - 🔤 **标题层级** — H1 \~ H6 完整支持
17
+ - 📝 **列表** — 有序列表、无序列表
18
+ - ↩️ **撤销重做** — 内置历史记录操作
19
+ - 🔌 **可扩展** — 基于 Tiptap 扩展机制,轻松添加自定义节点和标记
10
20
 
11
- - Chromium-based browsers (Chrome, Edge, Brave, etc.):
12
- - [Vue.js devtools](https://chromewebstore.google.com/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)
13
- - [Turn on Custom Object Formatter in Chrome DevTools](http://bit.ly/object-formatters)
14
- - Firefox:
15
- - [Vue.js devtools](https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/)
16
- - [Turn on Custom Object Formatter in Firefox DevTools](https://fxdx.dev/firefox-devtools-custom-object-formatters/)
21
+ ## 📦 安装
17
22
 
18
- ## Type Support for `.vue` Imports in TS
23
+ ```bash
24
+ # pnpm
25
+ pnpm add @sanmokeji/smo-editor
19
26
 
20
- TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
27
+ # npm
28
+ npm install @sanmokeji/smo-editor
21
29
 
22
- ## Customize configuration
30
+ # yarn
31
+ yarn add @sanmokeji/smo-editor
32
+ ```
23
33
 
24
- See [Vite Configuration Reference](https://vite.dev/config/).
34
+ ### 前置依赖
25
35
 
26
- ## Project Setup
36
+ 确保项目中已安装以下 peer 依赖:
27
37
 
28
- ```sh
29
- pnpm install
38
+ ```bash
39
+ pnpm add vue @tiptap/vue-3
30
40
  ```
31
41
 
32
- ### Compile and Hot-Reload for Development
42
+ ## 🚀 快速开始
33
43
 
34
- ```sh
35
- pnpm dev
44
+ ```vue
45
+ <script setup lang="ts">
46
+ import { ref } from 'vue'
47
+ import { SmoEditor, type SmoEditorOptions } from '@sanmokeji/smo-editor'
48
+ import '@sanmokeji/smo-editor/css'
49
+
50
+ const content = ref('<p>Hello SmoEditor!</p>')
51
+ </script>
52
+
53
+ <template>
54
+ <SmoEditor v-model="content" />
55
+ </template>
36
56
  ```
37
57
 
38
- ### Type-Check, Compile and Minify for Production
58
+ ## 📖 使用指南
39
59
 
40
- ```sh
41
- pnpm build
60
+ ### v-model 双向绑定
61
+
62
+ `SmoEditor` 使用 `v-model` 进行 HTML 内容的双向绑定:
63
+
64
+ ```vue
65
+ <template>
66
+ <SmoEditor v-model="html" />
67
+ </template>
68
+
69
+ <script setup lang="ts">
70
+ import { ref } from 'vue'
71
+ const html = ref('<p>初始内容</p>')
72
+ </script>
73
+ ```
74
+
75
+ ### Props
76
+
77
+ | 属性 | 类型 | 默认值 | 说明 |
78
+ | --------------- | ----------------------------------------------------------------- | ------ | -------------------- |
79
+ | `modelValue` | `string` | `''` | 编辑器 HTML 内容(v-model) |
80
+ | `editable` | `boolean` | `true` | 是否为可编辑状态 |
81
+ | `placeholder` | `string` | `''` | 占位符文本 |
82
+ | `height` | `string \| number` | — | 编辑器容器高度 |
83
+ | `onImageUpload` | `(file: File) => ImageUploadResult \| Promise<ImageUploadResult>` | — | 图片上传回调 |
84
+
85
+ ### 图片上传
86
+
87
+ 传入 `onImageUpload` 回调函数,返回图片 URL 即可。支持工具栏上传、拖拽、粘贴三种方式:
88
+
89
+ ```vue
90
+ <template>
91
+ <SmoEditor v-model="content" :on-image-upload="uploadImage" />
92
+ </template>
93
+
94
+ <script setup lang="ts">
95
+ import type { ImageUploadResult } from '@sanmokeji/smo-editor'
96
+
97
+ const uploadImage = async (file: File): Promise<ImageUploadResult> => {
98
+ const formData = new FormData()
99
+ formData.append('file', file)
100
+
101
+ const res = await fetch('/api/upload', {
102
+ method: 'POST',
103
+ body: formData,
104
+ })
105
+ const { url, alt } = await res.json()
106
+ return { url, alt }
107
+ }
108
+ </script>
109
+ ```
110
+
111
+ 图片上传到编辑器后,选中图片会出现 **浮动菜单(Bubble Menu)**,支持调整:
112
+
113
+ - **对齐**:左对齐 / 居中 / 右对齐
114
+ - **宽度**:自动 / 25% / 50% / 75% / 100%
115
+ - **Alt 文本**:编辑图片替代文字
116
+
117
+ ### 只读模式
118
+
119
+ ```vue
120
+ <template>
121
+ <SmoEditor v-model="content" :editable="false" />
122
+ </template>
123
+ ```
124
+
125
+ ### 占位符
126
+
127
+ ```vue
128
+ <template>
129
+ <SmoEditor v-model="content" placeholder="请输入文章内容..." />
130
+ </template>
42
131
  ```
43
132
 
44
- ### Lint with [ESLint](https://eslint.org/)
133
+ ## 🧩 TypeScript 类型
134
+
135
+ 库提供完整的 TypeScript 类型声明:
136
+
137
+ ```ts
138
+ import { SmoEditor, type SmoEditorOptions, type ImageUploadResult } from '@sanmokeji/smo-editor'
139
+ ```
45
140
 
46
- ```sh
47
- pnpm lint
141
+ `SmoEditorOptions` 和 `ImageUploadResult` 接口定义:
142
+
143
+ ```ts
144
+ export interface ImageUploadResult {
145
+ url: string
146
+ alt?: string
147
+ }
148
+
149
+ export interface SmoEditorOptions {
150
+ content?: string | object
151
+ height?: string | number
152
+ editable?: boolean
153
+ placeholder?: string
154
+ onImageUpload?: (file: File) => ImageUploadResult | Promise<ImageUploadResult>
155
+ }
48
156
  ```
157
+
158
+ ## 🎨 样式导入
159
+
160
+ 编辑器和工具栏的样式已内置,需要手动导入 CSS 文件:
161
+
162
+ ```ts
163
+ // 在你的入口文件或组件中
164
+ import '@sanmokeji/smo-editor/css'
165
+ ```
166
+
167
+ CSS 文件中包含 `.smot-editor-` 前缀的类名,不会污染全局样式。
168
+
169
+ ## ⌨️ 工具栏功能
170
+
171
+ 内置工具栏提供以下功能:
172
+
173
+ | 分组 | 功能 |
174
+ | -- | -------------------------------- |
175
+ | 标题 | H1 / H2 / H3 / H4 / H5 / H6 / 正文 |
176
+ | 内联 | 加粗 / 斜体 / 删除线 / 行内代码 |
177
+ | 块级 | 引用 / 代码块 / 分割线 |
178
+ | 列表 | 有序列表 / 无序列表 |
179
+ | 对齐 | 左对齐 / 居中 / 右对齐 |
180
+ | 媒体 | 图片上传(含浮动编辑菜单) |
181
+ | 链接 | 设置 / 编辑超链接 |
182
+ | 历史 | 撤销 / 重做 |
183
+
184
+ ## 🔧 开发
185
+
186
+ ```bash
187
+ # 安装依赖
188
+ pnpm install
189
+
190
+ # 启动开发服务器
191
+ pnpm dev
192
+
193
+ # 构建生产版本
194
+ pnpm build
195
+
196
+ # 类型检查
197
+ pnpm type-check
198
+ ```
199
+
200
+ ## 📄 License
201
+
202
+ MIT
203
+
204
+ ***
205
+
206
+ Made with ❤️ by SanMoKeJi
@@ -1,2 +1,2 @@
1
- .smo-editor-content-wrapper[data-v-68261a70]{border:1px solid #e2e8f0;border-radius:6px;outline:none;min-height:150px;padding:16px}[data-v-68261a70] .ProseMirror-selectednode{border-radius:4px;outline:2px solid #38bdf8}[data-v-68261a70] .tiptap:focus,[data-v-68261a70] .ProseMirror{outline:none}[data-v-68261a70] .ProseMirror ul{margin:8px 0;padding-left:24px;list-style-type:disc}[data-v-68261a70] .ProseMirror ol{margin:8px 0;padding-left:24px;list-style-type:decimal}[data-v-68261a70] .ProseMirror li p{margin:4px 0}[data-v-68261a70] .ProseMirror blockquote{color:#475569;background-color:#f8fafc;border-left:4px solid #cbd5e1;border-radius:2px;margin:12px 0;padding:8px 16px}[data-v-68261a70] .ProseMirror blockquote p{margin:4px 0}[data-v-68261a70] .ProseMirror pre{color:#38bdf8;background-color:#0f172a;border-radius:6px;margin:16px 0;padding:12px 16px;font-family:Fira Code,Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;overflow-x:auto}[data-v-68261a70] .ProseMirror pre code{color:inherit;background:0 0;padding:0;font-size:13px}[data-v-68261a70] .ProseMirror hr{cursor:pointer;border:none;border-top:2px solid #e2e8f0;margin:24px 0}[data-v-68261a70] .ProseMirror hr.ProseMirror-selectednode{outline:2px solid #38bdf8}[data-v-68261a70] .ProseMirror code{color:#e11d48;background-color:#f1f5f9;border-radius:4px;padding:2px 6px;font-family:monospace;font-size:.85em;font-weight:500}[data-v-68261a70] .ProseMirror .smo-editor-link{color:#2563eb;text-underline-offset:3px;cursor:pointer;font-weight:500;text-decoration:underline}[data-v-68261a70] .ProseMirror .smo-editor-link:hover{color:#1d4ed8}[data-v-68261a70] .tiptap .is-editor-empty:first-child:before{color:#adb5bd;content:attr(data-placeholder);float:left;pointer-events:none;height:0}[data-v-68261a70] .tiptap :first-child{margin-top:0}[data-v-68261a70] .tiptap [data-resize-handle]{z-index:10;background:#00000080;border:1px solid #fffc;border-radius:2px;position:absolute}[data-v-68261a70] .tiptap [data-resize-handle]:hover{background:#000c}[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=top-left],[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=top-right],[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=bottom-left],[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=bottom-right]{width:8px;height:8px}[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=top-left]{cursor:nwse-resize;top:-4px;left:-4px}[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=top-right]{cursor:nesw-resize;top:-4px;right:-4px}[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=bottom-left]{cursor:nesw-resize;bottom:-4px;left:-4px}[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=bottom-right]{cursor:nwse-resize;bottom:-4px;right:-4px}[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=top],[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=bottom]{height:6px;left:8px;right:8px}[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=top]{cursor:ns-resize;top:-3px}[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=bottom]{cursor:ns-resize;bottom:-3px}[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=left],[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=right]{width:6px;top:8px;bottom:8px}[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=left]{cursor:ew-resize;left:-3px}[data-v-68261a70] .tiptap [data-resize-handle][data-resize-handle=right]{cursor:ew-resize;right:-3px}[data-v-68261a70] .tiptap [data-resize-state=true] [data-resize-wrapper]{border-radius:.125rem;outline:1px solid #00000040}.smo-toolbar-group[data-v-0762240b]{align-items:center;gap:2px;padding:0 4px;display:inline-flex;position:relative}.smo-toolbar-group+.smo-toolbar-group[data-v-0762240b]:before{content:"";background-color:#e2e8f0;width:1px;position:absolute;top:6px;bottom:6px;left:-2px}.smo-toolbar-button[data-v-10d293e2]{color:#475569;cursor:pointer;background:0 0;border:none;border-radius:4px;outline:none;justify-content:center;align-items:center;padding:8px;transition:all .2s;display:inline-flex}.smo-toolbar-button[data-v-10d293e2]:hover:not(:disabled){color:#0f172a;background-color:#f1f5f9}.smo-toolbar-button.is-active[data-v-10d293e2]{color:#2563eb;background-color:#e2e8f0;font-weight:700}.smo-toolbar-button[data-v-10d293e2]:disabled{color:#cbd5e1;cursor:not-allowed}.smo-icon[data-v-8230f5dd]{vertical-align:middle;flex-shrink:0;display:inline-block}.smo-custom-select[data-v-0b16f052]{-webkit-user-select:none;user-select:none;display:inline-block;position:relative}.smo-select-trigger[data-v-0b16f052]{color:#475569;cursor:pointer;background-color:#0000;border-radius:4px;justify-content:space-between;align-items:center;min-width:50px;height:28px;padding:0 10px;font-size:13px;transition:all .2s cubic-bezier(.4,0,.2,1);display:flex}.smo-select-trigger[data-v-0b16f052]:hover,.smo-select-trigger.is-active[data-v-0b16f052]{color:#0f172a;background-color:#f1f5f9}.smo-select-value[data-v-0b16f052]{font-weight:500}.smo-select-arrow[data-v-0b16f052]{color:#94a3b8;margin-left:8px;font-size:8px;transition:transform .2s;transform:scale(.8)}.smo-select-arrow.is-rotated[data-v-0b16f052]{transform:scale(.8)rotate(180deg)}.smo-select-dropdown[data-v-0b16f052]{z-index:50;background-color:#fff;border:1px solid #e2e8f0;border-radius:6px;min-width:160px;padding:4px;position:absolute;top:calc(100% + 4px);left:0;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f}.smo-select-option[data-v-0b16f052]{color:#334155;cursor:pointer;border-radius:4px;justify-content:space-between;align-items:center;margin-bottom:2px;padding:6px 10px;font-size:13px;transition:background-color .15s;display:flex}.smo-select-option[data-v-0b16f052]:last-child{margin-bottom:0}.smo-select-option[data-v-0b16f052]:hover{color:#0f172a;background-color:#f8fafc}.smo-select-option.is-selected[data-v-0b16f052]{color:#2563eb;background-color:#eff6ff;font-weight:500}.smo-option-check[data-v-0b16f052]{font-size:11px;font-weight:700}.smo-select-option.opt-h1[data-v-0b16f052]{font-size:18px;font-weight:700}.smo-select-option.opt-h2[data-v-0b16f052]{font-size:16px;font-weight:600}.smo-select-option.opt-h3[data-v-0b16f052]{font-size:14px;font-weight:600}.smo-select-option.opt-h4[data-v-0b16f052]{font-size:13px;font-weight:600}.smo-select-option.opt-h5[data-v-0b16f052]{font-size:12px;font-weight:600}.smo-select-option.opt-h6[data-v-0b16f052]{font-size:11px;font-weight:600}.smo-fade-enter-active[data-v-0b16f052],.smo-fade-leave-active[data-v-0b16f052]{transition:opacity .15s,transform .15s}.smo-fade-enter-from[data-v-0b16f052],.smo-fade-leave-to[data-v-0b16f052]{opacity:0;transform:translateY(-4px)}.smo-link-setter[data-v-77dc2707]{display:inline-block}.smo-link-popover-fixed[data-v-77dc2707]{z-index:9999;background:#fff;border:1px solid #e2e8f0;border-radius:8px;flex-direction:column;gap:10px;width:280px;padding:12px;display:flex;position:fixed;transform:translate(-50%,-100%);box-shadow:0 10px 25px -5px #0f172a26}.smo-popover-field[data-v-77dc2707]{align-items:center;gap:8px;display:flex}.smo-field-label[data-v-77dc2707]{color:#64748b;min-width:36px;font-size:12px}.smo-link-input[data-v-77dc2707]{border:1px solid #cbd5e1;border-radius:4px;outline:none;flex:1;padding:5px 8px;font-size:12px}.smo-link-input[data-v-77dc2707]:focus{border-color:#2563eb}.smo-link-actions[data-v-77dc2707]{justify-content:flex-end;gap:6px;margin-top:4px;display:flex}.smo-popover-btn[data-v-77dc2707]{cursor:pointer;background:#fff;border:1px solid #cbd5e1;border-radius:4px;padding:4px 10px;font-size:12px}.smo-popover-btn.primary[data-v-77dc2707]{color:#fff;background:#2563eb;border-color:#2563eb}.smo-popover-btn.danger[data-v-77dc2707]{color:#fff;background:#ef4444;border-color:#ef4444}.bubble-menu[data-v-3b921f1f]{background-color:#fff;border:1px solid #3d25140d;border-radius:10px;min-width:300px;padding:15px;box-shadow:0 12px 33px #0000000f,0 3.618px 9.949px #0000000a}.bubble-menu .form-item[data-v-3b921f1f]:last-child{margin-bottom:0}.bubble-menu .form-item[data-v-3b921f1f]{color:#475569;align-items:center;margin-bottom:16px;font-size:.8rem;display:flex}.bubble-menu .form-item label[data-v-3b921f1f]{flex-shrink:0;width:4rem}.bubble-menu .form-item input[data-v-3b921f1f]{color:#334155;box-sizing:border-box;border:1px solid #cbd5e1;border-radius:4px;outline:none;flex:1;padding:8px;font-size:12px;transition:border-color .2s}.smo-editor-container{flex-direction:column;width:100%;display:flex}:deep(.smo-editor-content-wrapper){border-top-left-radius:0!important;border-top-right-radius:0!important}
1
+ [data-v-8407b2ea] .ProseMirror-selectednode{border-radius:4px;outline:2px solid #38bdf8}[data-v-8407b2ea] .tiptap:focus,[data-v-8407b2ea] .ProseMirror{outline:none}[data-v-8407b2ea] .ProseMirror ul{margin:8px 0;padding-left:24px;list-style-type:disc}[data-v-8407b2ea] .ProseMirror ol{margin:8px 0;padding-left:24px;list-style-type:decimal}[data-v-8407b2ea] .ProseMirror li p{margin:4px 0}[data-v-8407b2ea] .ProseMirror blockquote{color:#475569;background-color:#f8fafc;border-left:4px solid #cbd5e1;border-radius:2px;margin:12px 0;padding:8px 16px}[data-v-8407b2ea] .ProseMirror blockquote p{margin:4px 0}[data-v-8407b2ea] .ProseMirror pre{color:#38bdf8;background-color:#0f172a;border-radius:6px;margin:16px 0;padding:12px 16px;font-family:Fira Code,Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;overflow-x:auto}[data-v-8407b2ea] .ProseMirror pre code{color:inherit;background:0 0;padding:0;font-size:13px}[data-v-8407b2ea] .ProseMirror hr{cursor:pointer;border:none;border-top:2px solid #e2e8f0;margin:24px 0}[data-v-8407b2ea] .ProseMirror hr.ProseMirror-selectednode{outline:2px solid #38bdf8}[data-v-8407b2ea] .ProseMirror code{color:#e11d48;background-color:#f1f5f9;border-radius:4px;padding:2px 6px;font-family:monospace;font-size:.85em;font-weight:500}[data-v-8407b2ea] .ProseMirror .smo-editor-link{color:#2563eb;text-underline-offset:3px;cursor:pointer;font-weight:500;text-decoration:underline}[data-v-8407b2ea] .ProseMirror .smo-editor-link:hover{color:#1d4ed8}[data-v-8407b2ea] .tiptap .is-editor-empty:first-child:before{color:#adb5bd;content:attr(data-placeholder);float:left;pointer-events:none;height:0}[data-v-8407b2ea] .tiptap :first-child{margin-top:0}[data-v-8407b2ea] .tiptap [data-resize-handle]{z-index:10;background:#00000080;border:1px solid #fffc;border-radius:2px;position:absolute}[data-v-8407b2ea] .tiptap [data-resize-handle]:hover{background:#000c}[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=top-left],[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=top-right],[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=bottom-left],[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=bottom-right]{width:8px;height:8px}[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=top-left]{cursor:nwse-resize;top:-4px;left:-4px}[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=top-right]{cursor:nesw-resize;top:-4px;right:-4px}[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=bottom-left]{cursor:nesw-resize;bottom:-4px;left:-4px}[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=bottom-right]{cursor:nwse-resize;bottom:-4px;right:-4px}[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=top],[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=bottom]{height:6px;left:8px;right:8px}[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=top]{cursor:ns-resize;top:-3px}[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=bottom]{cursor:ns-resize;bottom:-3px}[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=left],[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=right]{width:6px;top:8px;bottom:8px}[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=left]{cursor:ew-resize;left:-3px}[data-v-8407b2ea] .tiptap [data-resize-handle][data-resize-handle=right]{cursor:ew-resize;right:-3px}[data-v-8407b2ea] .tiptap [data-resize-state=true] [data-resize-wrapper]{border-radius:.125rem;outline:1px solid #00000040}.smo-toolbar-group[data-v-0762240b]{align-items:center;gap:2px;padding:0 4px;display:inline-flex;position:relative}.smo-toolbar-group+.smo-toolbar-group[data-v-0762240b]:before{content:"";background-color:#e2e8f0;width:1px;position:absolute;top:6px;bottom:6px;left:-2px}.smo-toolbar-button[data-v-10d293e2]{color:#475569;cursor:pointer;background:0 0;border:none;border-radius:4px;outline:none;justify-content:center;align-items:center;padding:8px;transition:all .2s;display:inline-flex}.smo-toolbar-button[data-v-10d293e2]:hover:not(:disabled){color:#0f172a;background-color:#f1f5f9}.smo-toolbar-button.is-active[data-v-10d293e2]{color:#2563eb;background-color:#e2e8f0;font-weight:700}.smo-toolbar-button[data-v-10d293e2]:disabled{color:#cbd5e1;cursor:not-allowed}.smo-icon[data-v-4de271c4]{vertical-align:middle;flex-shrink:0;display:inline-block}.smo-custom-select[data-v-0b16f052]{-webkit-user-select:none;user-select:none;display:inline-block;position:relative}.smo-select-trigger[data-v-0b16f052]{color:#475569;cursor:pointer;background-color:#0000;border-radius:4px;justify-content:space-between;align-items:center;min-width:50px;height:28px;padding:0 10px;font-size:13px;transition:all .2s cubic-bezier(.4,0,.2,1);display:flex}.smo-select-trigger[data-v-0b16f052]:hover,.smo-select-trigger.is-active[data-v-0b16f052]{color:#0f172a;background-color:#f1f5f9}.smo-select-value[data-v-0b16f052]{font-weight:500}.smo-select-arrow[data-v-0b16f052]{color:#94a3b8;margin-left:8px;font-size:8px;transition:transform .2s;transform:scale(.8)}.smo-select-arrow.is-rotated[data-v-0b16f052]{transform:scale(.8)rotate(180deg)}.smo-select-dropdown[data-v-0b16f052]{z-index:50;background-color:#fff;border:1px solid #e2e8f0;border-radius:6px;min-width:160px;padding:4px;position:absolute;top:calc(100% + 4px);left:0;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f}.smo-select-option[data-v-0b16f052]{color:#334155;cursor:pointer;border-radius:4px;justify-content:space-between;align-items:center;margin-bottom:2px;padding:6px 10px;font-size:13px;transition:background-color .15s;display:flex}.smo-select-option[data-v-0b16f052]:last-child{margin-bottom:0}.smo-select-option[data-v-0b16f052]:hover{color:#0f172a;background-color:#f8fafc}.smo-select-option.is-selected[data-v-0b16f052]{color:#2563eb;background-color:#eff6ff;font-weight:500}.smo-option-check[data-v-0b16f052]{font-size:11px;font-weight:700}.smo-select-option.opt-h1[data-v-0b16f052]{font-size:18px;font-weight:700}.smo-select-option.opt-h2[data-v-0b16f052]{font-size:16px;font-weight:600}.smo-select-option.opt-h3[data-v-0b16f052]{font-size:14px;font-weight:600}.smo-select-option.opt-h4[data-v-0b16f052]{font-size:13px;font-weight:600}.smo-select-option.opt-h5[data-v-0b16f052]{font-size:12px;font-weight:600}.smo-select-option.opt-h6[data-v-0b16f052]{font-size:11px;font-weight:600}.smo-fade-enter-active[data-v-0b16f052],.smo-fade-leave-active[data-v-0b16f052]{transition:opacity .15s,transform .15s}.smo-fade-enter-from[data-v-0b16f052],.smo-fade-leave-to[data-v-0b16f052]{opacity:0;transform:translateY(-4px)}.smo-link-setter[data-v-77dc2707]{display:inline-block}.smo-link-popover-fixed[data-v-77dc2707]{z-index:9999;background:#fff;border:1px solid #e2e8f0;border-radius:8px;flex-direction:column;gap:10px;width:280px;padding:12px;display:flex;position:fixed;transform:translate(-50%,-100%);box-shadow:0 10px 25px -5px #0f172a26}.smo-popover-field[data-v-77dc2707]{align-items:center;gap:8px;display:flex}.smo-field-label[data-v-77dc2707]{color:#64748b;min-width:36px;font-size:12px}.smo-link-input[data-v-77dc2707]{border:1px solid #cbd5e1;border-radius:4px;outline:none;flex:1;padding:5px 8px;font-size:12px}.smo-link-input[data-v-77dc2707]:focus{border-color:#2563eb}.smo-link-actions[data-v-77dc2707]{justify-content:flex-end;gap:6px;margin-top:4px;display:flex}.smo-popover-btn[data-v-77dc2707]{cursor:pointer;background:#fff;border:1px solid #cbd5e1;border-radius:4px;padding:4px 10px;font-size:12px}.smo-popover-btn.primary[data-v-77dc2707]{color:#fff;background:#2563eb;border-color:#2563eb}.smo-popover-btn.danger[data-v-77dc2707]{color:#fff;background:#ef4444;border-color:#ef4444}.bubble-menu[data-v-3b921f1f]{background-color:#fff;border:1px solid #3d25140d;border-radius:10px;min-width:300px;padding:15px;box-shadow:0 12px 33px #0000000f,0 3.618px 9.949px #0000000a}.bubble-menu .form-item[data-v-3b921f1f]:last-child{margin-bottom:0}.bubble-menu .form-item[data-v-3b921f1f]{color:#475569;align-items:center;margin-bottom:16px;font-size:.8rem;display:flex}.bubble-menu .form-item label[data-v-3b921f1f]{flex-shrink:0;width:4rem}.bubble-menu .form-item input[data-v-3b921f1f]{color:#334155;box-sizing:border-box;border:1px solid #cbd5e1;border-radius:4px;outline:none;flex:1;padding:8px;font-size:12px;transition:border-color .2s}.smo-editor-container{border:1px solid #e2e8f0;border-radius:6px}.smo-toolbar{border-bottom:1px solid #e2e8f0;padding:.25rem}.smo-editor-content{outline:none;min-height:10rem;padding:16px}.smo-editor-content img{max-width:100%;transition:width .2s cubic-bezier(.4,0,.2,1);display:block}.smo-editor-content img[data-align=left]{margin-right:auto}.smo-editor-content img[data-align=center]{margin:0 auto}.smo-editor-content img[data-align=right]{margin-left:auto}
2
2
  /*$vite$:1*/
@@ -3,34 +3,40 @@ import { ComponentProvideOptions } from 'vue';
3
3
  import { DefineComponent } from 'vue';
4
4
  import { PublicProps } from 'vue';
5
5
 
6
- declare const __VLS_export: DefineComponent<__VLS_Props, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
6
+ declare const __VLS_export: DefineComponent<SmoEditorProps, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
7
7
  "update:modelValue": (value: string) => any;
8
- }, string, PublicProps, Readonly<__VLS_Props> & Readonly<{
8
+ }, string, PublicProps, Readonly<SmoEditorOptions & {
9
+ modelValue?: string;
10
+ } & {
9
11
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
10
12
  }>, {
11
13
  placeholder: string;
12
14
  editable: boolean;
13
15
  modelValue: string;
14
- }, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
16
+ }, {}, {}, {}, string, ComponentProvideOptions, false, {}>;
15
17
 
16
- declare type __VLS_Props = {
17
- modelValue?: string;
18
- editable?: boolean;
19
- placeholder?: string;
20
- onImageUpload?: (file: File) => Promise<string>;
21
- };
18
+ export declare interface ImageUploadResult {
19
+ url: string;
20
+ alt?: string;
21
+ }
22
22
 
23
23
  export declare const SmoEditor: typeof __VLS_export;
24
24
 
25
25
  export declare interface SmoEditorOptions {
26
26
  /** 编辑器初始内容,可以是 HTML 或 JSON */
27
27
  content?: string | object;
28
+ /** 编辑器容器高度 */
29
+ height?: string | number;
28
30
  /** 是否只读 */
29
31
  editable?: boolean;
30
32
  /** 占位符文字 */
31
33
  placeholder?: string;
32
34
  /** 图片上传处理函数 */
33
- onImageUpload?: (file: File) => Promise<string>;
35
+ onImageUpload?: (file: File) => ImageUploadResult | Promise<ImageUploadResult>;
34
36
  }
35
37
 
38
+ declare type SmoEditorProps = SmoEditorOptions & {
39
+ modelValue?: string;
40
+ };
41
+
36
42
  export { }