@cgboiler/biz-basic 1.0.48 → 1.0.49
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/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/rich-text-editor/RichTextEditor.d.ts +5 -1
- package/es/rich-text-editor/RichTextEditor.js +37 -2
- package/es/rich-text-editor/index.css +1 -1
- package/es/rich-text-editor/index.less +12 -1
- package/es/rich-text-editor/types.d.ts +15 -0
- package/es/rich-text-editor/useExtensions.js +92 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/rich-text-editor/RichTextEditor.d.ts +5 -1
- package/lib/rich-text-editor/RichTextEditor.js +37 -2
- package/lib/rich-text-editor/index.css +1 -1
- package/lib/rich-text-editor/index.less +12 -1
- package/lib/rich-text-editor/types.d.ts +15 -0
- package/lib/rich-text-editor/useExtensions.js +92 -1
- package/package.json +1 -1
package/es/index.d.ts
CHANGED
package/es/index.js
CHANGED
|
@@ -16,7 +16,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
16
16
|
type: BooleanConstructor;
|
|
17
17
|
default: boolean;
|
|
18
18
|
};
|
|
19
|
-
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "mention-input" | "mention-exit" | "update:modelValue" | "mention-clicked" | "hashTag-clicked")[], "blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "mention-input" | "mention-exit" | "update:modelValue" | "mention-clicked" | "hashTag-clicked", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
19
|
+
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "mention-input" | "mention-exit" | "update:modelValue" | "mention-clicked" | "hashTag-clicked" | "customContent-triggered" | "customContent-input" | "customContent-exit" | "customContent-clicked")[], "blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "mention-input" | "mention-exit" | "update:modelValue" | "mention-clicked" | "hashTag-clicked" | "customContent-triggered" | "customContent-input" | "customContent-exit" | "customContent-clicked", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
20
20
|
modelValue: {
|
|
21
21
|
type: StringConstructor;
|
|
22
22
|
default: string;
|
|
@@ -44,6 +44,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
44
44
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
45
45
|
"onMention-clicked"?: ((...args: any[]) => any) | undefined;
|
|
46
46
|
"onHashTag-clicked"?: ((...args: any[]) => any) | undefined;
|
|
47
|
+
"onCustomContent-triggered"?: ((...args: any[]) => any) | undefined;
|
|
48
|
+
"onCustomContent-input"?: ((...args: any[]) => any) | undefined;
|
|
49
|
+
"onCustomContent-exit"?: ((...args: any[]) => any) | undefined;
|
|
50
|
+
"onCustomContent-clicked"?: ((...args: any[]) => any) | undefined;
|
|
47
51
|
}>, {
|
|
48
52
|
modelValue: string;
|
|
49
53
|
placeholder: string;
|
|
@@ -31,7 +31,7 @@ import "./index.css";
|
|
|
31
31
|
var stdin_default = defineComponent({
|
|
32
32
|
name: "RichTextEditor",
|
|
33
33
|
props: richTextEditorProps,
|
|
34
|
-
emits: ["update:modelValue", "mention-triggered", "mention-input", "mention-exit", "mention-clicked", "hashTag-triggered", "hashTag-input", "hashTag-exit", "hashTag-clicked", "blur", "focus"],
|
|
34
|
+
emits: ["update:modelValue", "mention-triggered", "mention-input", "mention-exit", "mention-clicked", "hashTag-triggered", "hashTag-input", "hashTag-exit", "hashTag-clicked", "customContent-triggered", "customContent-input", "customContent-exit", "customContent-clicked", "blur", "focus"],
|
|
35
35
|
setup(props, {
|
|
36
36
|
emit,
|
|
37
37
|
expose
|
|
@@ -99,10 +99,23 @@ var stdin_default = defineComponent({
|
|
|
99
99
|
}
|
|
100
100
|
});
|
|
101
101
|
};
|
|
102
|
+
const insertCustomContent = (data) => {
|
|
103
|
+
editor.value.commands.insertContent({
|
|
104
|
+
type: "customContent",
|
|
105
|
+
attrs: {
|
|
106
|
+
id: data.id || `custom-${Date.now()}`,
|
|
107
|
+
label: data.label,
|
|
108
|
+
obj: data.obj,
|
|
109
|
+
color: data.color,
|
|
110
|
+
hoverColor: data.hoverColor
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
};
|
|
102
114
|
expose({
|
|
103
115
|
getEditor: () => editor.value,
|
|
104
116
|
insertMention,
|
|
105
|
-
insertHashTag
|
|
117
|
+
insertHashTag,
|
|
118
|
+
insertCustomContent
|
|
106
119
|
});
|
|
107
120
|
watch(() => props.modelValue, (newValue) => {
|
|
108
121
|
var _a, _b;
|
|
@@ -185,6 +198,26 @@ var stdin_default = defineComponent({
|
|
|
185
198
|
return;
|
|
186
199
|
}
|
|
187
200
|
};
|
|
201
|
+
const customContentClickHandler = (event) => {
|
|
202
|
+
const target = event.target;
|
|
203
|
+
const tagEl = target.closest(".custom-content") || null;
|
|
204
|
+
if (tagEl) {
|
|
205
|
+
const objStr = tagEl.getAttribute("obj") || "{}";
|
|
206
|
+
const label = tagEl.getAttribute("file-label") || "";
|
|
207
|
+
try {
|
|
208
|
+
const obj = JSON.parse(objStr);
|
|
209
|
+
emit("customContent-clicked", {
|
|
210
|
+
obj,
|
|
211
|
+
label
|
|
212
|
+
});
|
|
213
|
+
} catch (e) {
|
|
214
|
+
console.error("Failed to parse custom content obj:", e);
|
|
215
|
+
}
|
|
216
|
+
event.stopPropagation();
|
|
217
|
+
event.preventDefault();
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
188
221
|
const HISTORY_METADATA_KEY = "rich_text_editor_history_metadata";
|
|
189
222
|
const MAX_HISTORY_ITEMS = 10;
|
|
190
223
|
let saveTimeoutId = null;
|
|
@@ -238,6 +271,7 @@ var stdin_default = defineComponent({
|
|
|
238
271
|
editorElement.addEventListener("click", imageClickHandler);
|
|
239
272
|
editorElement.addEventListener("click", hashTagClickHandler);
|
|
240
273
|
editorElement.addEventListener("click", mentionClickHandler);
|
|
274
|
+
editorElement.addEventListener("click", customContentClickHandler);
|
|
241
275
|
}
|
|
242
276
|
});
|
|
243
277
|
});
|
|
@@ -251,6 +285,7 @@ var stdin_default = defineComponent({
|
|
|
251
285
|
editorElement.removeEventListener("click", imageClickHandler);
|
|
252
286
|
editorElement.removeEventListener("click", hashTagClickHandler);
|
|
253
287
|
editorElement.removeEventListener("click", mentionClickHandler);
|
|
288
|
+
editorElement.removeEventListener("click", customContentClickHandler);
|
|
254
289
|
}
|
|
255
290
|
(_c = editor.value) == null ? void 0 : _c.destroy();
|
|
256
291
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
body .ProseMirror{flex:1;overflow:auto;outline:none;line-height:1.6;font-size:var(--font-base);--white: #fff;--black: #2e2b29;--gray-1: rgba(61, 37, 20, .05);--gray-2: rgba(61, 37, 20, .08);--gray-3: rgba(61, 37, 20, .12);--gray-4: rgba(53, 38, 28, .3);--gray-5: rgba(28, 25, 23, .6);--green: #22c55e;--purple: #6a00f5;--purple-contrast: #5800cc;--purple-light: rgba(88, 5, 255, .05);--yellow-contrast: #facc15;--yellow: rgba(250, 204, 21, .4);--yellow-light: #fffae5;--red: #ff5c33;--red-light: #ffebe5;--shadow: 0px 12px 33px 0px rgba(0, 0, 0, .06), 0px 3.618px 9.949px 0px rgba(0, 0, 0, .04)}body .ProseMirror :first-child{margin-top:0}body .ProseMirror video{width:100%}body .ProseMirror ol{list-style:auto}body .ProseMirror ol ol,body .ProseMirror ul{list-style:disc}body .ProseMirror ol,body .ProseMirror ul{padding-left:1.5em;margin:0 0 12px}body .ProseMirror ol li p,body .ProseMirror ul li p{margin-top:.25em;margin-bottom:.25em}body .ProseMirror li::marker{text-align:start!important}body .ProseMirror h1,body .ProseMirror h2,body .ProseMirror h3,body .ProseMirror h4,body .ProseMirror h5,body .ProseMirror h6{line-height:1.1;margin-top:2.5rem;text-wrap:pretty}body .ProseMirror h1,body .ProseMirror h2{margin-top:1rem;margin-bottom:1rem}body .ProseMirror h1{font-size:1.4rem}body .ProseMirror h2{font-size:1.2rem}body .ProseMirror h3{font-size:1.1rem}body .ProseMirror h4,body .ProseMirror h5,body .ProseMirror h6{font-size:1rem}body .ProseMirror a,body .ProseMirror .editor-link{color:var(--purple);text-decoration:underline;cursor:pointer;transition:color .2s ease}body .ProseMirror a:hover,body .ProseMirror .editor-link:hover{color:var(--purple-contrast);text-decoration:underline}body .ProseMirror code{background-color:#ffe5e8;border-radius:.4rem;color:#c02537;padding:2px 4px}body .ProseMirror pre{border-radius:.5rem;font-family:JetBrainsMono,monospace;margin:1.5rem 0;padding:.75rem 1rem}body .ProseMirror pre code{background:none;color:inherit;font-size:.8rem;padding:0}body .ProseMirror blockquote{border-left:3px solid var(--gray-3);margin:1.5rem 0;padding-left:1rem}body .ProseMirror hr{border:none;border-top:1px solid var(--gray-2);margin:2rem 0}body .ProseMirror p.is-editor-empty:first-child:before{color:var(--gray-4);content:attr(data-placeholder);float:left;height:0;pointer-events:none}body .ProseMirror .is-empty:before{color:var(--gray-4);content:attr(data-placeholder);float:left;height:0;pointer-events:none}body .ProseMirror table{border-collapse:collapse;margin:0;overflow:hidden;table-layout:fixed;width:100%}body .ProseMirror table td,body .ProseMirror table th{border:1px solid var(--gray-3);box-sizing:border-box;min-width:1em;padding:6px 8px;position:relative;vertical-align:top}body .ProseMirror table td>*,body .ProseMirror table th>*{margin-bottom:0}body .ProseMirror table th{background-color:var(--gray-1);font-weight:700;text-align:left}body .ProseMirror table .selectedCell:after{background:var(--gray-2);content:"";left:0;right:0;top:0;bottom:0;pointer-events:none;position:absolute;z-index:2}body .ProseMirror table .column-resize-handle{background-color:var(--purple);bottom:-2px;pointer-events:none;position:absolute;right:-2px;top:0;width:4px}body .ProseMirror .tableWrapper{margin:1.5rem 0;overflow-x:auto}body .ProseMirror.resize-cursor{cursor:ew-resize;cursor:col-resize}body .ProseMirror img{max-width:100%}body .ProseMirror .mention,body .ProseMirror .hash-tag{color:#c02537;padding:0 .3em}.animation-indent--right{animation:indent-right .5s cubic-bezier(.68,-.55,.27,1.55) 1 alternate-reverse}@keyframes indent-right{0%{transform:translate(0)}to{transform:translate(12px)}}
|
|
1
|
+
body .ProseMirror{flex:1;overflow:auto;outline:none;line-height:1.6;font-size:var(--font-base);--white: #fff;--black: #2e2b29;--gray-1: rgba(61, 37, 20, .05);--gray-2: rgba(61, 37, 20, .08);--gray-3: rgba(61, 37, 20, .12);--gray-4: rgba(53, 38, 28, .3);--gray-5: rgba(28, 25, 23, .6);--green: #22c55e;--purple: #6a00f5;--purple-contrast: #5800cc;--purple-light: rgba(88, 5, 255, .05);--yellow-contrast: #facc15;--yellow: rgba(250, 204, 21, .4);--yellow-light: #fffae5;--red: #ff5c33;--red-light: #ffebe5;--shadow: 0px 12px 33px 0px rgba(0, 0, 0, .06), 0px 3.618px 9.949px 0px rgba(0, 0, 0, .04)}body .ProseMirror :first-child{margin-top:0}body .ProseMirror video{width:100%}body .ProseMirror ol{list-style:auto}body .ProseMirror ol ol,body .ProseMirror ul{list-style:disc}body .ProseMirror ol,body .ProseMirror ul{padding-left:1.5em;margin:0 0 12px}body .ProseMirror ol li p,body .ProseMirror ul li p{margin-top:.25em;margin-bottom:.25em}body .ProseMirror li::marker{text-align:start!important}body .ProseMirror h1,body .ProseMirror h2,body .ProseMirror h3,body .ProseMirror h4,body .ProseMirror h5,body .ProseMirror h6{line-height:1.1;margin-top:2.5rem;text-wrap:pretty}body .ProseMirror h1,body .ProseMirror h2{margin-top:1rem;margin-bottom:1rem}body .ProseMirror h1{font-size:1.4rem}body .ProseMirror h2{font-size:1.2rem}body .ProseMirror h3{font-size:1.1rem}body .ProseMirror h4,body .ProseMirror h5,body .ProseMirror h6{font-size:1rem}body .ProseMirror a,body .ProseMirror .editor-link{color:var(--purple);text-decoration:underline;cursor:pointer;transition:color .2s ease}body .ProseMirror a:hover,body .ProseMirror .editor-link:hover{color:var(--purple-contrast);text-decoration:underline}body .ProseMirror code{background-color:#ffe5e8;border-radius:.4rem;color:#c02537;padding:2px 4px}body .ProseMirror pre{border-radius:.5rem;font-family:JetBrainsMono,monospace;margin:1.5rem 0;padding:.75rem 1rem}body .ProseMirror pre code{background:none;color:inherit;font-size:.8rem;padding:0}body .ProseMirror blockquote{border-left:3px solid var(--gray-3);margin:1.5rem 0;padding-left:1rem}body .ProseMirror hr{border:none;border-top:1px solid var(--gray-2);margin:2rem 0}body .ProseMirror p.is-editor-empty:first-child:before{color:var(--gray-4);content:attr(data-placeholder);float:left;height:0;pointer-events:none}body .ProseMirror .is-empty:before{color:var(--gray-4);content:attr(data-placeholder);float:left;height:0;pointer-events:none}body .ProseMirror table{border-collapse:collapse;margin:0;overflow:hidden;table-layout:fixed;width:100%}body .ProseMirror table td,body .ProseMirror table th{border:1px solid var(--gray-3);box-sizing:border-box;min-width:1em;padding:6px 8px;position:relative;vertical-align:top}body .ProseMirror table td>*,body .ProseMirror table th>*{margin-bottom:0}body .ProseMirror table th{background-color:var(--gray-1);font-weight:700;text-align:left}body .ProseMirror table .selectedCell:after{background:var(--gray-2);content:"";left:0;right:0;top:0;bottom:0;pointer-events:none;position:absolute;z-index:2}body .ProseMirror table .column-resize-handle{background-color:var(--purple);bottom:-2px;pointer-events:none;position:absolute;right:-2px;top:0;width:4px}body .ProseMirror .tableWrapper{margin:1.5rem 0;overflow-x:auto}body .ProseMirror.resize-cursor{cursor:ew-resize;cursor:col-resize}body .ProseMirror img{max-width:100%}body .ProseMirror .mention,body .ProseMirror .hash-tag{color:#c02537;padding:0 .3em}body .ProseMirror .custom-content{color:var(--custom-content-color, #000);padding:0 .3em;cursor:pointer;transition:color .2s ease}body .ProseMirror .custom-content:hover{color:var(--custom-content-hover-color, #c02537)}.animation-indent--right{animation:indent-right .5s cubic-bezier(.68,-.55,.27,1.55) 1 alternate-reverse}@keyframes indent-right{0%{transform:translate(0)}to{transform:translate(12px)}}
|
|
@@ -218,11 +218,22 @@ body .ProseMirror {
|
|
|
218
218
|
img {
|
|
219
219
|
max-width: 100%;
|
|
220
220
|
}
|
|
221
|
-
// @人的样式 #话题的样式
|
|
221
|
+
// @人的样式 #话题的样式 自定义内容的样式
|
|
222
222
|
.mention, .hash-tag {
|
|
223
223
|
color: #c02537;
|
|
224
224
|
padding: 0 0.3em;
|
|
225
225
|
}
|
|
226
|
+
|
|
227
|
+
.custom-content {
|
|
228
|
+
color: var(--custom-content-color, #000);
|
|
229
|
+
padding: 0 0.3em;
|
|
230
|
+
cursor: pointer;
|
|
231
|
+
transition: color 0.2s ease;
|
|
232
|
+
|
|
233
|
+
&:hover {
|
|
234
|
+
color: var(--custom-content-hover-color, #c02537);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
226
237
|
}
|
|
227
238
|
|
|
228
239
|
// animation
|
|
@@ -26,6 +26,21 @@ export interface HashTagData {
|
|
|
26
26
|
hashTagId: string;
|
|
27
27
|
name: string;
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* CustomContentData
|
|
31
|
+
* - 功能:自定义内容的数据结构。
|
|
32
|
+
* - 字段说明:
|
|
33
|
+
* - label: string 显示标签(如 )。
|
|
34
|
+
* - obj: 任意JSON对象,内容由用户自定义。
|
|
35
|
+
* - id: 可选及其他扩展字段。
|
|
36
|
+
*/
|
|
37
|
+
export interface CustomContentData {
|
|
38
|
+
label: string;
|
|
39
|
+
obj: Record<string, any>;
|
|
40
|
+
color?: string;
|
|
41
|
+
hoverColor?: string;
|
|
42
|
+
[key: string]: any;
|
|
43
|
+
}
|
|
29
44
|
/**
|
|
30
45
|
* HashTagExitEvent
|
|
31
46
|
* - 功能:在 `hashTag-exit` 事件中传递退出原因与是否为非连续输入。
|
|
@@ -144,6 +144,96 @@ function useExtensions({ props, emit }) {
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
});
|
|
147
|
+
const CustomContent = Mention.extend({
|
|
148
|
+
name: "customContent",
|
|
149
|
+
addAttributes() {
|
|
150
|
+
return {
|
|
151
|
+
id: {
|
|
152
|
+
default: null,
|
|
153
|
+
parseHTML: (element) => element.getAttribute("data-id"),
|
|
154
|
+
renderHTML: (attributes) => {
|
|
155
|
+
if (!attributes.id) {
|
|
156
|
+
return {};
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
"data-id": attributes.id
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
label: {
|
|
164
|
+
default: null,
|
|
165
|
+
parseHTML: (element) => element.getAttribute("file-label"),
|
|
166
|
+
renderHTML: (attributes) => {
|
|
167
|
+
if (!attributes.label) {
|
|
168
|
+
return {};
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
"file-label": attributes.label
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
obj: {
|
|
176
|
+
default: null,
|
|
177
|
+
parseHTML: (element) => {
|
|
178
|
+
const objStr = element.getAttribute("obj");
|
|
179
|
+
return objStr ? JSON.parse(objStr) : null;
|
|
180
|
+
},
|
|
181
|
+
renderHTML: (attributes) => {
|
|
182
|
+
if (!attributes.obj) {
|
|
183
|
+
return {};
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
obj: JSON.stringify(attributes.obj)
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
color: {
|
|
191
|
+
default: null,
|
|
192
|
+
parseHTML: (element) => element.getAttribute("data-color"),
|
|
193
|
+
renderHTML: (attributes) => {
|
|
194
|
+
if (!attributes.color)
|
|
195
|
+
return {};
|
|
196
|
+
return { "data-color": attributes.color };
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
hoverColor: {
|
|
200
|
+
default: null,
|
|
201
|
+
parseHTML: (element) => element.getAttribute("data-hover-color"),
|
|
202
|
+
renderHTML: (attributes) => {
|
|
203
|
+
if (!attributes.hoverColor)
|
|
204
|
+
return {};
|
|
205
|
+
return { "data-hover-color": attributes.hoverColor };
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
},
|
|
210
|
+
renderHTML({ node }) {
|
|
211
|
+
var _a, _b, _c, _d, _e, _f;
|
|
212
|
+
const obj = (_b = (_a = node == null ? void 0 : node.attrs) == null ? void 0 : _a.obj) != null ? _b : {};
|
|
213
|
+
const label = (_d = (_c = node == null ? void 0 : node.attrs) == null ? void 0 : _c.label) != null ? _d : "";
|
|
214
|
+
const color = (_e = node == null ? void 0 : node.attrs) == null ? void 0 : _e.color;
|
|
215
|
+
const hoverColor = (_f = node == null ? void 0 : node.attrs) == null ? void 0 : _f.hoverColor;
|
|
216
|
+
const styleParts = [];
|
|
217
|
+
if (color)
|
|
218
|
+
styleParts.push(`--custom-content-color: ${color}`);
|
|
219
|
+
if (hoverColor)
|
|
220
|
+
styleParts.push(`--custom-content-hover-color: ${hoverColor}`);
|
|
221
|
+
return [
|
|
222
|
+
"span",
|
|
223
|
+
{
|
|
224
|
+
class: "custom-content",
|
|
225
|
+
"data-type": "custom-content",
|
|
226
|
+
obj: JSON.stringify(obj),
|
|
227
|
+
"file-label": label,
|
|
228
|
+
"data-color": color,
|
|
229
|
+
"data-hover-color": hoverColor,
|
|
230
|
+
style: styleParts.length ? styleParts.join(";") : void 0,
|
|
231
|
+
contenteditable: "false"
|
|
232
|
+
},
|
|
233
|
+
label
|
|
234
|
+
];
|
|
235
|
+
}
|
|
236
|
+
});
|
|
147
237
|
const extensions = [
|
|
148
238
|
StarterKit,
|
|
149
239
|
HtmlBlock,
|
|
@@ -291,7 +381,8 @@ function useExtensions({ props, emit }) {
|
|
|
291
381
|
}
|
|
292
382
|
}
|
|
293
383
|
}),
|
|
294
|
-
HashTag
|
|
384
|
+
HashTag,
|
|
385
|
+
CustomContent
|
|
295
386
|
];
|
|
296
387
|
return extensions;
|
|
297
388
|
}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -36,7 +36,7 @@ __export(stdin_exports, {
|
|
|
36
36
|
module.exports = __toCommonJS(stdin_exports);
|
|
37
37
|
var import_rich_text_editor = __toESM(require("./rich-text-editor"));
|
|
38
38
|
__reExport(stdin_exports, require("./rich-text-editor"), module.exports);
|
|
39
|
-
const version = "1.0.
|
|
39
|
+
const version = "1.0.48";
|
|
40
40
|
function install(app) {
|
|
41
41
|
const components = [
|
|
42
42
|
import_rich_text_editor.default
|
|
@@ -16,7 +16,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
16
16
|
type: BooleanConstructor;
|
|
17
17
|
default: boolean;
|
|
18
18
|
};
|
|
19
|
-
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "mention-input" | "mention-exit" | "update:modelValue" | "mention-clicked" | "hashTag-clicked")[], "blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "mention-input" | "mention-exit" | "update:modelValue" | "mention-clicked" | "hashTag-clicked", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
19
|
+
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "mention-input" | "mention-exit" | "update:modelValue" | "mention-clicked" | "hashTag-clicked" | "customContent-triggered" | "customContent-input" | "customContent-exit" | "customContent-clicked")[], "blur" | "focus" | "hashTag-triggered" | "hashTag-input" | "hashTag-exit" | "mention-triggered" | "mention-input" | "mention-exit" | "update:modelValue" | "mention-clicked" | "hashTag-clicked" | "customContent-triggered" | "customContent-input" | "customContent-exit" | "customContent-clicked", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
20
20
|
modelValue: {
|
|
21
21
|
type: StringConstructor;
|
|
22
22
|
default: string;
|
|
@@ -44,6 +44,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
44
44
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
45
45
|
"onMention-clicked"?: ((...args: any[]) => any) | undefined;
|
|
46
46
|
"onHashTag-clicked"?: ((...args: any[]) => any) | undefined;
|
|
47
|
+
"onCustomContent-triggered"?: ((...args: any[]) => any) | undefined;
|
|
48
|
+
"onCustomContent-input"?: ((...args: any[]) => any) | undefined;
|
|
49
|
+
"onCustomContent-exit"?: ((...args: any[]) => any) | undefined;
|
|
50
|
+
"onCustomContent-clicked"?: ((...args: any[]) => any) | undefined;
|
|
47
51
|
}>, {
|
|
48
52
|
modelValue: string;
|
|
49
53
|
placeholder: string;
|
|
@@ -63,7 +63,7 @@ var import_index = require("./index.css");
|
|
|
63
63
|
var stdin_default = (0, import_vue2.defineComponent)({
|
|
64
64
|
name: "RichTextEditor",
|
|
65
65
|
props: import_types.richTextEditorProps,
|
|
66
|
-
emits: ["update:modelValue", "mention-triggered", "mention-input", "mention-exit", "mention-clicked", "hashTag-triggered", "hashTag-input", "hashTag-exit", "hashTag-clicked", "blur", "focus"],
|
|
66
|
+
emits: ["update:modelValue", "mention-triggered", "mention-input", "mention-exit", "mention-clicked", "hashTag-triggered", "hashTag-input", "hashTag-exit", "hashTag-clicked", "customContent-triggered", "customContent-input", "customContent-exit", "customContent-clicked", "blur", "focus"],
|
|
67
67
|
setup(props, {
|
|
68
68
|
emit,
|
|
69
69
|
expose
|
|
@@ -131,10 +131,23 @@ var stdin_default = (0, import_vue2.defineComponent)({
|
|
|
131
131
|
}
|
|
132
132
|
});
|
|
133
133
|
};
|
|
134
|
+
const insertCustomContent = (data) => {
|
|
135
|
+
editor.value.commands.insertContent({
|
|
136
|
+
type: "customContent",
|
|
137
|
+
attrs: {
|
|
138
|
+
id: data.id || `custom-${Date.now()}`,
|
|
139
|
+
label: data.label,
|
|
140
|
+
obj: data.obj,
|
|
141
|
+
color: data.color,
|
|
142
|
+
hoverColor: data.hoverColor
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
};
|
|
134
146
|
expose({
|
|
135
147
|
getEditor: () => editor.value,
|
|
136
148
|
insertMention,
|
|
137
|
-
insertHashTag
|
|
149
|
+
insertHashTag,
|
|
150
|
+
insertCustomContent
|
|
138
151
|
});
|
|
139
152
|
(0, import_vue2.watch)(() => props.modelValue, (newValue) => {
|
|
140
153
|
var _a, _b;
|
|
@@ -217,6 +230,26 @@ var stdin_default = (0, import_vue2.defineComponent)({
|
|
|
217
230
|
return;
|
|
218
231
|
}
|
|
219
232
|
};
|
|
233
|
+
const customContentClickHandler = (event) => {
|
|
234
|
+
const target = event.target;
|
|
235
|
+
const tagEl = target.closest(".custom-content") || null;
|
|
236
|
+
if (tagEl) {
|
|
237
|
+
const objStr = tagEl.getAttribute("obj") || "{}";
|
|
238
|
+
const label = tagEl.getAttribute("file-label") || "";
|
|
239
|
+
try {
|
|
240
|
+
const obj = JSON.parse(objStr);
|
|
241
|
+
emit("customContent-clicked", {
|
|
242
|
+
obj,
|
|
243
|
+
label
|
|
244
|
+
});
|
|
245
|
+
} catch (e) {
|
|
246
|
+
console.error("Failed to parse custom content obj:", e);
|
|
247
|
+
}
|
|
248
|
+
event.stopPropagation();
|
|
249
|
+
event.preventDefault();
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
};
|
|
220
253
|
const HISTORY_METADATA_KEY = "rich_text_editor_history_metadata";
|
|
221
254
|
const MAX_HISTORY_ITEMS = 10;
|
|
222
255
|
let saveTimeoutId = null;
|
|
@@ -270,6 +303,7 @@ var stdin_default = (0, import_vue2.defineComponent)({
|
|
|
270
303
|
editorElement.addEventListener("click", imageClickHandler);
|
|
271
304
|
editorElement.addEventListener("click", hashTagClickHandler);
|
|
272
305
|
editorElement.addEventListener("click", mentionClickHandler);
|
|
306
|
+
editorElement.addEventListener("click", customContentClickHandler);
|
|
273
307
|
}
|
|
274
308
|
});
|
|
275
309
|
});
|
|
@@ -283,6 +317,7 @@ var stdin_default = (0, import_vue2.defineComponent)({
|
|
|
283
317
|
editorElement.removeEventListener("click", imageClickHandler);
|
|
284
318
|
editorElement.removeEventListener("click", hashTagClickHandler);
|
|
285
319
|
editorElement.removeEventListener("click", mentionClickHandler);
|
|
320
|
+
editorElement.removeEventListener("click", customContentClickHandler);
|
|
286
321
|
}
|
|
287
322
|
(_c = editor.value) == null ? void 0 : _c.destroy();
|
|
288
323
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
body .ProseMirror{flex:1;overflow:auto;outline:none;line-height:1.6;font-size:var(--font-base);--white: #fff;--black: #2e2b29;--gray-1: rgba(61, 37, 20, .05);--gray-2: rgba(61, 37, 20, .08);--gray-3: rgba(61, 37, 20, .12);--gray-4: rgba(53, 38, 28, .3);--gray-5: rgba(28, 25, 23, .6);--green: #22c55e;--purple: #6a00f5;--purple-contrast: #5800cc;--purple-light: rgba(88, 5, 255, .05);--yellow-contrast: #facc15;--yellow: rgba(250, 204, 21, .4);--yellow-light: #fffae5;--red: #ff5c33;--red-light: #ffebe5;--shadow: 0px 12px 33px 0px rgba(0, 0, 0, .06), 0px 3.618px 9.949px 0px rgba(0, 0, 0, .04)}body .ProseMirror :first-child{margin-top:0}body .ProseMirror video{width:100%}body .ProseMirror ol{list-style:auto}body .ProseMirror ol ol,body .ProseMirror ul{list-style:disc}body .ProseMirror ol,body .ProseMirror ul{padding-left:1.5em;margin:0 0 12px}body .ProseMirror ol li p,body .ProseMirror ul li p{margin-top:.25em;margin-bottom:.25em}body .ProseMirror li::marker{text-align:start!important}body .ProseMirror h1,body .ProseMirror h2,body .ProseMirror h3,body .ProseMirror h4,body .ProseMirror h5,body .ProseMirror h6{line-height:1.1;margin-top:2.5rem;text-wrap:pretty}body .ProseMirror h1,body .ProseMirror h2{margin-top:1rem;margin-bottom:1rem}body .ProseMirror h1{font-size:1.4rem}body .ProseMirror h2{font-size:1.2rem}body .ProseMirror h3{font-size:1.1rem}body .ProseMirror h4,body .ProseMirror h5,body .ProseMirror h6{font-size:1rem}body .ProseMirror a,body .ProseMirror .editor-link{color:var(--purple);text-decoration:underline;cursor:pointer;transition:color .2s ease}body .ProseMirror a:hover,body .ProseMirror .editor-link:hover{color:var(--purple-contrast);text-decoration:underline}body .ProseMirror code{background-color:#ffe5e8;border-radius:.4rem;color:#c02537;padding:2px 4px}body .ProseMirror pre{border-radius:.5rem;font-family:JetBrainsMono,monospace;margin:1.5rem 0;padding:.75rem 1rem}body .ProseMirror pre code{background:none;color:inherit;font-size:.8rem;padding:0}body .ProseMirror blockquote{border-left:3px solid var(--gray-3);margin:1.5rem 0;padding-left:1rem}body .ProseMirror hr{border:none;border-top:1px solid var(--gray-2);margin:2rem 0}body .ProseMirror p.is-editor-empty:first-child:before{color:var(--gray-4);content:attr(data-placeholder);float:left;height:0;pointer-events:none}body .ProseMirror .is-empty:before{color:var(--gray-4);content:attr(data-placeholder);float:left;height:0;pointer-events:none}body .ProseMirror table{border-collapse:collapse;margin:0;overflow:hidden;table-layout:fixed;width:100%}body .ProseMirror table td,body .ProseMirror table th{border:1px solid var(--gray-3);box-sizing:border-box;min-width:1em;padding:6px 8px;position:relative;vertical-align:top}body .ProseMirror table td>*,body .ProseMirror table th>*{margin-bottom:0}body .ProseMirror table th{background-color:var(--gray-1);font-weight:700;text-align:left}body .ProseMirror table .selectedCell:after{background:var(--gray-2);content:"";left:0;right:0;top:0;bottom:0;pointer-events:none;position:absolute;z-index:2}body .ProseMirror table .column-resize-handle{background-color:var(--purple);bottom:-2px;pointer-events:none;position:absolute;right:-2px;top:0;width:4px}body .ProseMirror .tableWrapper{margin:1.5rem 0;overflow-x:auto}body .ProseMirror.resize-cursor{cursor:ew-resize;cursor:col-resize}body .ProseMirror img{max-width:100%}body .ProseMirror .mention,body .ProseMirror .hash-tag{color:#c02537;padding:0 .3em}.animation-indent--right{animation:indent-right .5s cubic-bezier(.68,-.55,.27,1.55) 1 alternate-reverse}@keyframes indent-right{0%{transform:translate(0)}to{transform:translate(12px)}}
|
|
1
|
+
body .ProseMirror{flex:1;overflow:auto;outline:none;line-height:1.6;font-size:var(--font-base);--white: #fff;--black: #2e2b29;--gray-1: rgba(61, 37, 20, .05);--gray-2: rgba(61, 37, 20, .08);--gray-3: rgba(61, 37, 20, .12);--gray-4: rgba(53, 38, 28, .3);--gray-5: rgba(28, 25, 23, .6);--green: #22c55e;--purple: #6a00f5;--purple-contrast: #5800cc;--purple-light: rgba(88, 5, 255, .05);--yellow-contrast: #facc15;--yellow: rgba(250, 204, 21, .4);--yellow-light: #fffae5;--red: #ff5c33;--red-light: #ffebe5;--shadow: 0px 12px 33px 0px rgba(0, 0, 0, .06), 0px 3.618px 9.949px 0px rgba(0, 0, 0, .04)}body .ProseMirror :first-child{margin-top:0}body .ProseMirror video{width:100%}body .ProseMirror ol{list-style:auto}body .ProseMirror ol ol,body .ProseMirror ul{list-style:disc}body .ProseMirror ol,body .ProseMirror ul{padding-left:1.5em;margin:0 0 12px}body .ProseMirror ol li p,body .ProseMirror ul li p{margin-top:.25em;margin-bottom:.25em}body .ProseMirror li::marker{text-align:start!important}body .ProseMirror h1,body .ProseMirror h2,body .ProseMirror h3,body .ProseMirror h4,body .ProseMirror h5,body .ProseMirror h6{line-height:1.1;margin-top:2.5rem;text-wrap:pretty}body .ProseMirror h1,body .ProseMirror h2{margin-top:1rem;margin-bottom:1rem}body .ProseMirror h1{font-size:1.4rem}body .ProseMirror h2{font-size:1.2rem}body .ProseMirror h3{font-size:1.1rem}body .ProseMirror h4,body .ProseMirror h5,body .ProseMirror h6{font-size:1rem}body .ProseMirror a,body .ProseMirror .editor-link{color:var(--purple);text-decoration:underline;cursor:pointer;transition:color .2s ease}body .ProseMirror a:hover,body .ProseMirror .editor-link:hover{color:var(--purple-contrast);text-decoration:underline}body .ProseMirror code{background-color:#ffe5e8;border-radius:.4rem;color:#c02537;padding:2px 4px}body .ProseMirror pre{border-radius:.5rem;font-family:JetBrainsMono,monospace;margin:1.5rem 0;padding:.75rem 1rem}body .ProseMirror pre code{background:none;color:inherit;font-size:.8rem;padding:0}body .ProseMirror blockquote{border-left:3px solid var(--gray-3);margin:1.5rem 0;padding-left:1rem}body .ProseMirror hr{border:none;border-top:1px solid var(--gray-2);margin:2rem 0}body .ProseMirror p.is-editor-empty:first-child:before{color:var(--gray-4);content:attr(data-placeholder);float:left;height:0;pointer-events:none}body .ProseMirror .is-empty:before{color:var(--gray-4);content:attr(data-placeholder);float:left;height:0;pointer-events:none}body .ProseMirror table{border-collapse:collapse;margin:0;overflow:hidden;table-layout:fixed;width:100%}body .ProseMirror table td,body .ProseMirror table th{border:1px solid var(--gray-3);box-sizing:border-box;min-width:1em;padding:6px 8px;position:relative;vertical-align:top}body .ProseMirror table td>*,body .ProseMirror table th>*{margin-bottom:0}body .ProseMirror table th{background-color:var(--gray-1);font-weight:700;text-align:left}body .ProseMirror table .selectedCell:after{background:var(--gray-2);content:"";left:0;right:0;top:0;bottom:0;pointer-events:none;position:absolute;z-index:2}body .ProseMirror table .column-resize-handle{background-color:var(--purple);bottom:-2px;pointer-events:none;position:absolute;right:-2px;top:0;width:4px}body .ProseMirror .tableWrapper{margin:1.5rem 0;overflow-x:auto}body .ProseMirror.resize-cursor{cursor:ew-resize;cursor:col-resize}body .ProseMirror img{max-width:100%}body .ProseMirror .mention,body .ProseMirror .hash-tag{color:#c02537;padding:0 .3em}body .ProseMirror .custom-content{color:var(--custom-content-color, #000);padding:0 .3em;cursor:pointer;transition:color .2s ease}body .ProseMirror .custom-content:hover{color:var(--custom-content-hover-color, #c02537)}.animation-indent--right{animation:indent-right .5s cubic-bezier(.68,-.55,.27,1.55) 1 alternate-reverse}@keyframes indent-right{0%{transform:translate(0)}to{transform:translate(12px)}}
|
|
@@ -218,11 +218,22 @@ body .ProseMirror {
|
|
|
218
218
|
img {
|
|
219
219
|
max-width: 100%;
|
|
220
220
|
}
|
|
221
|
-
// @人的样式 #话题的样式
|
|
221
|
+
// @人的样式 #话题的样式 自定义内容的样式
|
|
222
222
|
.mention, .hash-tag {
|
|
223
223
|
color: #c02537;
|
|
224
224
|
padding: 0 0.3em;
|
|
225
225
|
}
|
|
226
|
+
|
|
227
|
+
.custom-content {
|
|
228
|
+
color: var(--custom-content-color, #000);
|
|
229
|
+
padding: 0 0.3em;
|
|
230
|
+
cursor: pointer;
|
|
231
|
+
transition: color 0.2s ease;
|
|
232
|
+
|
|
233
|
+
&:hover {
|
|
234
|
+
color: var(--custom-content-hover-color, #c02537);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
226
237
|
}
|
|
227
238
|
|
|
228
239
|
// animation
|
|
@@ -26,6 +26,21 @@ export interface HashTagData {
|
|
|
26
26
|
hashTagId: string;
|
|
27
27
|
name: string;
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* CustomContentData
|
|
31
|
+
* - 功能:自定义内容的数据结构。
|
|
32
|
+
* - 字段说明:
|
|
33
|
+
* - label: string 显示标签(如 )。
|
|
34
|
+
* - obj: 任意JSON对象,内容由用户自定义。
|
|
35
|
+
* - id: 可选及其他扩展字段。
|
|
36
|
+
*/
|
|
37
|
+
export interface CustomContentData {
|
|
38
|
+
label: string;
|
|
39
|
+
obj: Record<string, any>;
|
|
40
|
+
color?: string;
|
|
41
|
+
hoverColor?: string;
|
|
42
|
+
[key: string]: any;
|
|
43
|
+
}
|
|
29
44
|
/**
|
|
30
45
|
* HashTagExitEvent
|
|
31
46
|
* - 功能:在 `hashTag-exit` 事件中传递退出原因与是否为非连续输入。
|
|
@@ -176,6 +176,96 @@ function useExtensions({ props, emit }) {
|
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
});
|
|
179
|
+
const CustomContent = import_extension_mention.default.extend({
|
|
180
|
+
name: "customContent",
|
|
181
|
+
addAttributes() {
|
|
182
|
+
return {
|
|
183
|
+
id: {
|
|
184
|
+
default: null,
|
|
185
|
+
parseHTML: (element) => element.getAttribute("data-id"),
|
|
186
|
+
renderHTML: (attributes) => {
|
|
187
|
+
if (!attributes.id) {
|
|
188
|
+
return {};
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
"data-id": attributes.id
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
label: {
|
|
196
|
+
default: null,
|
|
197
|
+
parseHTML: (element) => element.getAttribute("file-label"),
|
|
198
|
+
renderHTML: (attributes) => {
|
|
199
|
+
if (!attributes.label) {
|
|
200
|
+
return {};
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
"file-label": attributes.label
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
obj: {
|
|
208
|
+
default: null,
|
|
209
|
+
parseHTML: (element) => {
|
|
210
|
+
const objStr = element.getAttribute("obj");
|
|
211
|
+
return objStr ? JSON.parse(objStr) : null;
|
|
212
|
+
},
|
|
213
|
+
renderHTML: (attributes) => {
|
|
214
|
+
if (!attributes.obj) {
|
|
215
|
+
return {};
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
obj: JSON.stringify(attributes.obj)
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
color: {
|
|
223
|
+
default: null,
|
|
224
|
+
parseHTML: (element) => element.getAttribute("data-color"),
|
|
225
|
+
renderHTML: (attributes) => {
|
|
226
|
+
if (!attributes.color)
|
|
227
|
+
return {};
|
|
228
|
+
return { "data-color": attributes.color };
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
hoverColor: {
|
|
232
|
+
default: null,
|
|
233
|
+
parseHTML: (element) => element.getAttribute("data-hover-color"),
|
|
234
|
+
renderHTML: (attributes) => {
|
|
235
|
+
if (!attributes.hoverColor)
|
|
236
|
+
return {};
|
|
237
|
+
return { "data-hover-color": attributes.hoverColor };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
},
|
|
242
|
+
renderHTML({ node }) {
|
|
243
|
+
var _a, _b, _c, _d, _e, _f;
|
|
244
|
+
const obj = (_b = (_a = node == null ? void 0 : node.attrs) == null ? void 0 : _a.obj) != null ? _b : {};
|
|
245
|
+
const label = (_d = (_c = node == null ? void 0 : node.attrs) == null ? void 0 : _c.label) != null ? _d : "";
|
|
246
|
+
const color = (_e = node == null ? void 0 : node.attrs) == null ? void 0 : _e.color;
|
|
247
|
+
const hoverColor = (_f = node == null ? void 0 : node.attrs) == null ? void 0 : _f.hoverColor;
|
|
248
|
+
const styleParts = [];
|
|
249
|
+
if (color)
|
|
250
|
+
styleParts.push(`--custom-content-color: ${color}`);
|
|
251
|
+
if (hoverColor)
|
|
252
|
+
styleParts.push(`--custom-content-hover-color: ${hoverColor}`);
|
|
253
|
+
return [
|
|
254
|
+
"span",
|
|
255
|
+
{
|
|
256
|
+
class: "custom-content",
|
|
257
|
+
"data-type": "custom-content",
|
|
258
|
+
obj: JSON.stringify(obj),
|
|
259
|
+
"file-label": label,
|
|
260
|
+
"data-color": color,
|
|
261
|
+
"data-hover-color": hoverColor,
|
|
262
|
+
style: styleParts.length ? styleParts.join(";") : void 0,
|
|
263
|
+
contenteditable: "false"
|
|
264
|
+
},
|
|
265
|
+
label
|
|
266
|
+
];
|
|
267
|
+
}
|
|
268
|
+
});
|
|
179
269
|
const extensions = [
|
|
180
270
|
import_starter_kit.default,
|
|
181
271
|
import_HtmlBlock.default,
|
|
@@ -323,7 +413,8 @@ function useExtensions({ props, emit }) {
|
|
|
323
413
|
}
|
|
324
414
|
}
|
|
325
415
|
}),
|
|
326
|
-
HashTag
|
|
416
|
+
HashTag,
|
|
417
|
+
CustomContent
|
|
327
418
|
];
|
|
328
419
|
return extensions;
|
|
329
420
|
}
|