vuewrite 0.0.20 → 0.0.21
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/.vscode/extensions.json +3 -3
- package/README.md +67 -67
- package/dist/vuewrite.d.ts +16 -2
- package/dist/vuewrite.js +58 -30
- package/package.json +39 -39
package/.vscode/extensions.json
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
{
|
|
2
|
-
"recommendations": ["Vue.volar"]
|
|
3
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"recommendations": ["Vue.volar"]
|
|
3
|
+
}
|
package/README.md
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
# VueWrite
|
|
2
|
-
|
|
3
|
-
VueWrite is another text editor that takes full advantage of Vue3's features.
|
|
4
|
-
It contains no pre-made styles and blocks as its main goal is complete customization and extension
|
|
5
|
-
|
|
6
|
-
## Demo
|
|
7
|
-
|
|
8
|
-
You can watch the demo [here](https://vuewrite.easix.ru)
|
|
9
|
-
|
|
10
|
-
## Quickstart
|
|
11
|
-
|
|
12
|
-
```vue
|
|
13
|
-
<template>
|
|
14
|
-
<TextEditor
|
|
15
|
-
ref="textEditorRef"
|
|
16
|
-
v-model="modelValue"
|
|
17
|
-
single
|
|
18
|
-
class="text-editor"
|
|
19
|
-
:decorator="decorator"
|
|
20
|
-
@keydown="onKeyDown"
|
|
21
|
-
/>
|
|
22
|
-
</template>
|
|
23
|
-
|
|
24
|
-
<script lang="ts">
|
|
25
|
-
import { TextEditor, TextEditorRef } from 'vuewrite'
|
|
26
|
-
|
|
27
|
-
const textEditorRef = shallowRef<TextEditorRef>()
|
|
28
|
-
const modelValue = shallowRef("")
|
|
29
|
-
|
|
30
|
-
const onKeyDown = (e: KeyboardEvent) => {
|
|
31
|
-
if (!textEditorRef.value) return
|
|
32
|
-
if ((e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey) {
|
|
33
|
-
if (e.code === "KeyB") {
|
|
34
|
-
textEditorRef.value.toggleStyle("bold")
|
|
35
|
-
}
|
|
36
|
-
if (e.code === "KeyI") {
|
|
37
|
-
textEditorRef.value.toggleStyle("italic")
|
|
38
|
-
}
|
|
39
|
-
if (e.code === "KeyU") {
|
|
40
|
-
textEditorRef.value.toggleStyle("underline")
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const decorator = (style: Style) => {
|
|
46
|
-
if (style.style === 'bold' || style.style === "underline" || style.style === "italic") {
|
|
47
|
-
return { class: style.style }
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
</script>
|
|
52
|
-
|
|
53
|
-
<style lang="css">
|
|
54
|
-
.text-editor {
|
|
55
|
-
white-space: pre-wrap;
|
|
56
|
-
}
|
|
57
|
-
.text-editor .bold {
|
|
58
|
-
font-weight: 700
|
|
59
|
-
}
|
|
60
|
-
.text-editor .italic {
|
|
61
|
-
font-style: italic
|
|
62
|
-
}
|
|
63
|
-
.text-editor .underline {
|
|
64
|
-
text-decoration: underline
|
|
65
|
-
}
|
|
66
|
-
</style>
|
|
67
|
-
|
|
1
|
+
# VueWrite
|
|
2
|
+
|
|
3
|
+
VueWrite is another text editor that takes full advantage of Vue3's features.
|
|
4
|
+
It contains no pre-made styles and blocks as its main goal is complete customization and extension
|
|
5
|
+
|
|
6
|
+
## Demo
|
|
7
|
+
|
|
8
|
+
You can watch the demo [here](https://vuewrite.easix.ru)
|
|
9
|
+
|
|
10
|
+
## Quickstart
|
|
11
|
+
|
|
12
|
+
```vue
|
|
13
|
+
<template>
|
|
14
|
+
<TextEditor
|
|
15
|
+
ref="textEditorRef"
|
|
16
|
+
v-model="modelValue"
|
|
17
|
+
single
|
|
18
|
+
class="text-editor"
|
|
19
|
+
:decorator="decorator"
|
|
20
|
+
@keydown="onKeyDown"
|
|
21
|
+
/>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script lang="ts">
|
|
25
|
+
import { TextEditor, TextEditorRef } from 'vuewrite'
|
|
26
|
+
|
|
27
|
+
const textEditorRef = shallowRef<TextEditorRef>()
|
|
28
|
+
const modelValue = shallowRef("")
|
|
29
|
+
|
|
30
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
31
|
+
if (!textEditorRef.value) return
|
|
32
|
+
if ((e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey) {
|
|
33
|
+
if (e.code === "KeyB") {
|
|
34
|
+
textEditorRef.value.toggleStyle("bold")
|
|
35
|
+
}
|
|
36
|
+
if (e.code === "KeyI") {
|
|
37
|
+
textEditorRef.value.toggleStyle("italic")
|
|
38
|
+
}
|
|
39
|
+
if (e.code === "KeyU") {
|
|
40
|
+
textEditorRef.value.toggleStyle("underline")
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const decorator = (style: Style) => {
|
|
46
|
+
if (style.style === 'bold' || style.style === "underline" || style.style === "italic") {
|
|
47
|
+
return { class: style.style }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<style lang="css">
|
|
54
|
+
.text-editor {
|
|
55
|
+
white-space: pre-wrap;
|
|
56
|
+
}
|
|
57
|
+
.text-editor .bold {
|
|
58
|
+
font-weight: 700
|
|
59
|
+
}
|
|
60
|
+
.text-editor .italic {
|
|
61
|
+
font-style: italic
|
|
62
|
+
}
|
|
63
|
+
.text-editor .underline {
|
|
64
|
+
text-decoration: underline
|
|
65
|
+
}
|
|
66
|
+
</style>
|
|
67
|
+
|
|
68
68
|
```
|
package/dist/vuewrite.d.ts
CHANGED
|
@@ -40,11 +40,16 @@ export declare type Decorator = (style: Style) => HTMLAttributes & {
|
|
|
40
40
|
} | undefined;
|
|
41
41
|
|
|
42
42
|
declare type HistoryAction = {
|
|
43
|
-
type:
|
|
43
|
+
type: string;
|
|
44
44
|
blocks: Block[];
|
|
45
|
+
fullUpdate: boolean;
|
|
45
46
|
selection: TextEditorSelection;
|
|
46
47
|
};
|
|
47
48
|
|
|
49
|
+
declare type Modifier = (block: Block) => HTMLAttributes & {
|
|
50
|
+
tag?: string;
|
|
51
|
+
} | undefined;
|
|
52
|
+
|
|
48
53
|
export declare type Style = {
|
|
49
54
|
start: number;
|
|
50
55
|
end: number;
|
|
@@ -54,6 +59,7 @@ export declare type Style = {
|
|
|
54
59
|
|
|
55
60
|
export declare const TextEditor: __VLS_WithTemplateSlots<DefineComponent<__VLS_TypePropsToRuntimeProps<{
|
|
56
61
|
decorator?: Decorator | undefined;
|
|
62
|
+
modifier?: Modifier | undefined;
|
|
57
63
|
single?: boolean | undefined;
|
|
58
64
|
modelValue?: string | {
|
|
59
65
|
text: string;
|
|
@@ -99,7 +105,7 @@ insertBlock: (blockData: Partial<Block>) => void;
|
|
|
99
105
|
addNewLine: () => void;
|
|
100
106
|
removeNewLine: () => void;
|
|
101
107
|
selectAll: () => void;
|
|
102
|
-
pushHistory: (type:
|
|
108
|
+
pushHistory: (type: string) => void;
|
|
103
109
|
getClientRects: (selection: TextEditorSelection) => DOMRectList;
|
|
104
110
|
}, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
|
|
105
111
|
keydown: (...args: any[]) => void;
|
|
@@ -107,6 +113,7 @@ keydown: (...args: any[]) => void;
|
|
|
107
113
|
"update:styles": (...args: any[]) => void;
|
|
108
114
|
}, string, PublicProps, Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
|
|
109
115
|
decorator?: Decorator | undefined;
|
|
116
|
+
modifier?: Modifier | undefined;
|
|
110
117
|
single?: boolean | undefined;
|
|
111
118
|
modelValue?: string | {
|
|
112
119
|
text: string;
|
|
@@ -129,8 +136,12 @@ onKeydown?: ((...args: any[]) => any) | undefined;
|
|
|
129
136
|
declare class TextEditorHistory {
|
|
130
137
|
actions: HistoryAction[];
|
|
131
138
|
currentCursor: number;
|
|
139
|
+
private blocksIds;
|
|
140
|
+
private cachedBlocksJson;
|
|
132
141
|
private store;
|
|
133
142
|
constructor(store: TextEditorStore);
|
|
143
|
+
private cacheBlockIds;
|
|
144
|
+
private blockIdsChanged;
|
|
134
145
|
tickStarted: boolean;
|
|
135
146
|
push(type: HistoryAction["type"]): void;
|
|
136
147
|
private applyAction;
|
|
@@ -242,6 +253,7 @@ declare class TextEditorStore {
|
|
|
242
253
|
export declare const TextEditorView: DefineComponent<Readonly<{
|
|
243
254
|
styles?: any;
|
|
244
255
|
decorator?: any;
|
|
256
|
+
modifier?: any;
|
|
245
257
|
parser?: any;
|
|
246
258
|
modelValue?: any;
|
|
247
259
|
}>, () => VNode<RendererNode, RendererElement, {
|
|
@@ -249,11 +261,13 @@ modelValue?: any;
|
|
|
249
261
|
}>, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<ExtractPropTypes<Readonly<{
|
|
250
262
|
styles?: any;
|
|
251
263
|
decorator?: any;
|
|
264
|
+
modifier?: any;
|
|
252
265
|
parser?: any;
|
|
253
266
|
modelValue?: any;
|
|
254
267
|
}>>>, {
|
|
255
268
|
readonly styles?: any;
|
|
256
269
|
readonly decorator?: any;
|
|
270
|
+
readonly modifier?: any;
|
|
257
271
|
readonly parser?: any;
|
|
258
272
|
readonly modelValue?: any;
|
|
259
273
|
}, {}>;
|
package/dist/vuewrite.js
CHANGED
|
@@ -4,7 +4,7 @@ var __publicField = (obj, key, value) => {
|
|
|
4
4
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
return value;
|
|
6
6
|
};
|
|
7
|
-
import { getCurrentScope, onScopeDispose, unref, watch,
|
|
7
|
+
import { getCurrentScope, onScopeDispose, unref, watch, reactive, computed, ref, defineComponent, getCurrentInstance, h, nextTick, useSlots, isProxy, toRaw, onMounted, openBlock, createElementBlock, Fragment, renderList, createBlock, renderSlot, createCommentVNode } from "vue";
|
|
8
8
|
function tryOnScopeDispose(fn) {
|
|
9
9
|
if (getCurrentScope()) {
|
|
10
10
|
onScopeDispose(fn);
|
|
@@ -144,50 +144,57 @@ class TextEditorHistory {
|
|
|
144
144
|
constructor(store) {
|
|
145
145
|
__publicField(this, "actions", []);
|
|
146
146
|
__publicField(this, "currentCursor", 0);
|
|
147
|
+
__publicField(this, "blocksIds", "");
|
|
148
|
+
__publicField(this, "cachedBlocksJson", "");
|
|
147
149
|
__publicField(this, "store");
|
|
148
150
|
__publicField(this, "tickStarted", false);
|
|
149
151
|
this.store = store;
|
|
150
152
|
window.showHistory = () => console.log(this.actions);
|
|
151
153
|
}
|
|
154
|
+
cacheBlockIds() {
|
|
155
|
+
this.blocksIds = this.store.blocks.map((item) => item.id).join(",");
|
|
156
|
+
}
|
|
157
|
+
blockIdsChanged() {
|
|
158
|
+
return this.blocksIds !== this.store.blocks.map((item) => item.id).join(",");
|
|
159
|
+
}
|
|
152
160
|
push(type) {
|
|
153
161
|
var _a;
|
|
154
162
|
if (this.currentCursor + 1 < this.actions.length) {
|
|
155
163
|
this.actions.length = this.currentCursor + 1;
|
|
156
164
|
}
|
|
157
|
-
const lastAction = this.actions.length > 0
|
|
165
|
+
const lastAction = this.actions.length > 0 ? this.actions[this.actions.length - 1] : null;
|
|
158
166
|
const selection = JSON.parse(JSON.stringify(this.store.selection));
|
|
159
|
-
|
|
167
|
+
const fullUpdate = type === "setText" || type === "addNewLine" || this.blockIdsChanged();
|
|
168
|
+
const blocksJson = JSON.stringify(this.store.blocks);
|
|
169
|
+
if (!fullUpdate && this.store.currentBlock) {
|
|
160
170
|
const currentBlock = JSON.parse(JSON.stringify(this.store.currentBlock));
|
|
161
|
-
if (lastAction && lastAction.type === type && ((_a = lastAction.blocks[0]) == null ? void 0 : _a.id) === currentBlock.id) {
|
|
171
|
+
if (lastAction && lastAction.type === type && ((_a = lastAction.blocks[0]) == null ? void 0 : _a.id) === currentBlock.id && (lastAction.type === "insertText" || lastAction.type === "deleteContentBackward" || lastAction.type === "deleteContentForward")) {
|
|
162
172
|
lastAction.blocks = [currentBlock];
|
|
163
173
|
lastAction.selection = selection;
|
|
164
174
|
} else {
|
|
165
|
-
this.actions.push({ type, blocks: [currentBlock], selection });
|
|
166
|
-
}
|
|
167
|
-
} else if (type === "setText") {
|
|
168
|
-
const blocks = JSON.parse(JSON.stringify(this.store.blocks));
|
|
169
|
-
if (this.tickStarted && lastAction) {
|
|
170
|
-
lastAction.blocks = blocks;
|
|
171
|
-
lastAction.selection = selection;
|
|
172
|
-
} else {
|
|
173
|
-
this.actions.push({ type: "setText", blocks, selection });
|
|
175
|
+
this.actions.push({ type, blocks: [currentBlock], selection, fullUpdate });
|
|
174
176
|
}
|
|
177
|
+
} else {
|
|
178
|
+
this.actions.push({ type, blocks: JSON.parse(blocksJson), selection, fullUpdate });
|
|
175
179
|
}
|
|
176
180
|
this.currentCursor = this.actions.length - 1;
|
|
177
|
-
if (
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
181
|
+
if (fullUpdate) {
|
|
182
|
+
if (lastAction && !lastAction.fullUpdate) {
|
|
183
|
+
lastAction.fullUpdate = true;
|
|
184
|
+
lastAction.blocks = JSON.parse(this.cachedBlocksJson);
|
|
185
|
+
}
|
|
186
|
+
this.cacheBlockIds();
|
|
182
187
|
}
|
|
188
|
+
this.cachedBlocksJson = blocksJson;
|
|
183
189
|
}
|
|
184
190
|
applyAction(action) {
|
|
185
|
-
if (action.
|
|
191
|
+
if (action.fullUpdate) {
|
|
186
192
|
for (let i = 0; i < action.blocks.length; i++) {
|
|
187
193
|
if (i >= this.store.blocks.length) {
|
|
188
194
|
this.store.blocks.push({ ...action.blocks[i] });
|
|
189
195
|
} else {
|
|
190
196
|
Object.assign(this.store.blocks[i], action.blocks[i]);
|
|
197
|
+
this.store.blocks[i].type = action.blocks[i].type;
|
|
191
198
|
}
|
|
192
199
|
}
|
|
193
200
|
if (this.store.blocks.length > action.blocks.length) {
|
|
@@ -198,10 +205,13 @@ class TextEditorHistory {
|
|
|
198
205
|
const block = this.store.blocks.find((block2) => block2.id === _block.id);
|
|
199
206
|
if (block) {
|
|
200
207
|
block.text = _block.text;
|
|
208
|
+
block.styles = _block.styles;
|
|
209
|
+
block.type = _block.type;
|
|
201
210
|
}
|
|
202
211
|
}
|
|
203
212
|
}
|
|
204
213
|
Object.assign(this.store.selection, action.selection);
|
|
214
|
+
this.cacheBlockIds();
|
|
205
215
|
}
|
|
206
216
|
undo() {
|
|
207
217
|
if (this.currentCursor === 0)
|
|
@@ -301,7 +311,6 @@ class TextEditorStore {
|
|
|
301
311
|
this.concatBlocks(this.blocks[blockIndex - 1], this.blocks[blockIndex]);
|
|
302
312
|
this.blocks.splice(blockIndex, 1);
|
|
303
313
|
}
|
|
304
|
-
this.history.push("setText");
|
|
305
314
|
}
|
|
306
315
|
onInput(_e) {
|
|
307
316
|
const ev = _e;
|
|
@@ -327,6 +336,7 @@ class TextEditorStore {
|
|
|
327
336
|
block.text = block.text.slice(0, offset) + block.text.slice(this.selection.focus.offset);
|
|
328
337
|
this.moveOffset(offset);
|
|
329
338
|
}
|
|
339
|
+
this.history.push("deleteContentBackward");
|
|
330
340
|
}
|
|
331
341
|
if (ev.inputType === "deleteContentForward") {
|
|
332
342
|
const blockIndex = this.blocks.findIndex((item) => item.id === this.selection.anchor.blockId);
|
|
@@ -334,12 +344,13 @@ class TextEditorStore {
|
|
|
334
344
|
const nextBlock = this.blocks[blockIndex + 1];
|
|
335
345
|
if (nextBlock) {
|
|
336
346
|
this.blocks.splice(blockIndex + 1, 1);
|
|
337
|
-
this.concatBlocks(this.blocks[blockIndex
|
|
347
|
+
this.concatBlocks(this.blocks[blockIndex], nextBlock);
|
|
338
348
|
}
|
|
339
349
|
} else {
|
|
340
350
|
block.text = block.text.slice(0, this.selection.focus.offset) + block.text.slice(this.selection.focus.offset + 1);
|
|
341
351
|
this.moveStyles(block, this.selection.focus.offset + 1, 1);
|
|
342
352
|
}
|
|
353
|
+
this.history.push("deleteContentForward");
|
|
343
354
|
}
|
|
344
355
|
}
|
|
345
356
|
if (ev.inputType === "insertText") {
|
|
@@ -352,6 +363,7 @@ class TextEditorStore {
|
|
|
352
363
|
const index2 = this.blocks.findIndex((item) => item.id === this.selection.anchor.blockId);
|
|
353
364
|
const block2 = { id: uid(), text: "", styles: [] };
|
|
354
365
|
this.blocks.splice(index2, 0, block2);
|
|
366
|
+
this.history.push("addNewLine");
|
|
355
367
|
return;
|
|
356
368
|
}
|
|
357
369
|
this.deleteSelected();
|
|
@@ -364,7 +376,7 @@ class TextEditorStore {
|
|
|
364
376
|
this.blocks.splice(index + 1, 0, block);
|
|
365
377
|
this.selection.anchor = { blockId: block.id, offset: 0 };
|
|
366
378
|
this.selection.focus = { blockId: block.id, offset: 0 };
|
|
367
|
-
this.history.push("
|
|
379
|
+
this.history.push("addNewLine");
|
|
368
380
|
}
|
|
369
381
|
addNewLineAfter() {
|
|
370
382
|
const index = this.blocks.findIndex((item) => item.id === this.selection.anchor.blockId);
|
|
@@ -448,6 +460,8 @@ class TextEditorStore {
|
|
|
448
460
|
return this._currentStyles.value;
|
|
449
461
|
}
|
|
450
462
|
applyStyle(_style, meta) {
|
|
463
|
+
if (this.isCollapsed)
|
|
464
|
+
return;
|
|
451
465
|
const [start, end, startIndex, endIndex] = this.startAndEnd;
|
|
452
466
|
for (let i = startIndex; i <= endIndex; i++) {
|
|
453
467
|
const block = this.blocks[i];
|
|
@@ -481,6 +495,7 @@ class TextEditorStore {
|
|
|
481
495
|
block.styles.sort((a, b) => a.start - b.start);
|
|
482
496
|
}
|
|
483
497
|
}
|
|
498
|
+
this.history.push("applyStyle");
|
|
484
499
|
}
|
|
485
500
|
removeStyleAt(block, _start, _end, _style) {
|
|
486
501
|
const removeAll = typeof _style !== "string";
|
|
@@ -511,6 +526,7 @@ class TextEditorStore {
|
|
|
511
526
|
const _end = i === endIndex ? end.offset : block.text.length;
|
|
512
527
|
this.removeStyleAt(block, _start, _end, _style);
|
|
513
528
|
}
|
|
529
|
+
this.history.push("applyStyle");
|
|
514
530
|
}
|
|
515
531
|
removeAllStyles() {
|
|
516
532
|
const [start, end, startIndex, endIndex] = this.startAndEnd;
|
|
@@ -541,7 +557,7 @@ class TextEditorStore {
|
|
|
541
557
|
let uidCounter = 0;
|
|
542
558
|
const uid = () => (uidCounter++).toString();
|
|
543
559
|
const _sfc_main$2 = defineComponent({
|
|
544
|
-
props: ["block", "slots", "static", "decorator", "parser"],
|
|
560
|
+
props: ["block", "slots", "static", "decorator", "modifier", "parser"],
|
|
545
561
|
emits: ["postrender"],
|
|
546
562
|
setup(props, { emit }) {
|
|
547
563
|
const slot = computed(() => {
|
|
@@ -549,9 +565,6 @@ const _sfc_main$2 = defineComponent({
|
|
|
549
565
|
return props.slots["default"] ?? null;
|
|
550
566
|
return props.slots[props.block.type] ?? null;
|
|
551
567
|
});
|
|
552
|
-
const blockProps = {
|
|
553
|
-
"data-vw-block-id": props.block.id
|
|
554
|
-
};
|
|
555
568
|
const instance = getCurrentInstance();
|
|
556
569
|
const getRef = () => {
|
|
557
570
|
if (!instance)
|
|
@@ -675,18 +688,30 @@ const _sfc_main$2 = defineComponent({
|
|
|
675
688
|
elementTag = tag;
|
|
676
689
|
}
|
|
677
690
|
}
|
|
678
|
-
if (Object.keys(attrs).length === 0)
|
|
691
|
+
if (Object.keys(attrs).length === 0 && elementTag === "span")
|
|
679
692
|
return text;
|
|
680
693
|
return h(elementTag, attrs, text);
|
|
681
694
|
};
|
|
682
695
|
return () => {
|
|
696
|
+
let elementTag = "div";
|
|
697
|
+
const blockProps = {
|
|
698
|
+
"data-vw-block-id": props.block.id
|
|
699
|
+
};
|
|
700
|
+
const additionalProps = props.modifier && props.modifier(props.block);
|
|
701
|
+
if (additionalProps) {
|
|
702
|
+
if (additionalProps.tag) {
|
|
703
|
+
elementTag = additionalProps.tag;
|
|
704
|
+
delete additionalProps.tag;
|
|
705
|
+
}
|
|
706
|
+
Object.assign(blockProps, additionalProps);
|
|
707
|
+
}
|
|
683
708
|
if (slot.value) {
|
|
684
709
|
const component = slot.value({ content, props: blockProps, block: props.block });
|
|
685
710
|
if (Array.isArray(component) && component.length === 1)
|
|
686
711
|
return component[0];
|
|
687
712
|
return component;
|
|
688
713
|
}
|
|
689
|
-
return h(
|
|
714
|
+
return h(elementTag, blockProps, content());
|
|
690
715
|
};
|
|
691
716
|
}
|
|
692
717
|
});
|
|
@@ -800,6 +825,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
800
825
|
__name: "TextEditor",
|
|
801
826
|
props: {
|
|
802
827
|
decorator: { type: Function },
|
|
828
|
+
modifier: { type: Function },
|
|
803
829
|
single: { type: Boolean },
|
|
804
830
|
modelValue: {},
|
|
805
831
|
parser: { type: Function },
|
|
@@ -1011,10 +1037,11 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
1011
1037
|
key: block.id,
|
|
1012
1038
|
block,
|
|
1013
1039
|
slots: unref(slots),
|
|
1040
|
+
modifier: props.modifier,
|
|
1014
1041
|
decorator: props.decorator,
|
|
1015
1042
|
parser: props.parser,
|
|
1016
1043
|
onPostrender: onPostRender
|
|
1017
|
-
}, null, 8, ["block", "slots", "decorator", "parser"]);
|
|
1044
|
+
}, null, 8, ["block", "slots", "modifier", "decorator", "parser"]);
|
|
1018
1045
|
}), 128)),
|
|
1019
1046
|
unref(store).blocks.length === 1 && unref(store).blocks[0].text === "" && !unref(store).blocks[0].type ? renderSlot(_ctx.$slots, "placeholder", { key: 0 }) : createCommentVNode("", true)
|
|
1020
1047
|
], 544);
|
|
@@ -1022,7 +1049,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
1022
1049
|
}
|
|
1023
1050
|
});
|
|
1024
1051
|
const _sfc_main = defineComponent({
|
|
1025
|
-
props: ["modelValue", "decorator", "parser", "styles"],
|
|
1052
|
+
props: ["modelValue", "decorator", "parser", "styles", "modifier"],
|
|
1026
1053
|
setup(props, { slots }) {
|
|
1027
1054
|
const blocks = computed(() => {
|
|
1028
1055
|
if (Array.isArray(props.modelValue)) {
|
|
@@ -1035,6 +1062,7 @@ const _sfc_main = defineComponent({
|
|
|
1035
1062
|
block,
|
|
1036
1063
|
slots,
|
|
1037
1064
|
decorator: props.decorator,
|
|
1065
|
+
modifier: props.modifier,
|
|
1038
1066
|
parser: props.parser,
|
|
1039
1067
|
static: true
|
|
1040
1068
|
})));
|
package/package.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "vuewrite",
|
|
3
|
-
"description": "Rich Text Editor based on Vue3 reactivity",
|
|
4
|
-
"private": false,
|
|
5
|
-
"version": "0.0.
|
|
6
|
-
"type": "module",
|
|
7
|
-
"license": "MIT",
|
|
8
|
-
"author": "den59k",
|
|
9
|
-
"repository": {
|
|
10
|
-
"type": "git",
|
|
11
|
-
"url": "https://github.com/den59k/vuewrite.git"
|
|
12
|
-
},
|
|
13
|
-
"main": "dist/vuewrite.js",
|
|
14
|
-
"types": "dist/vuewrite.d.ts",
|
|
15
|
-
"scripts": {
|
|
16
|
-
"dev": "vite",
|
|
17
|
-
"build": "vue-tsc && vite build",
|
|
18
|
-
"build:app": "vue-tsc && vite build -c vite-app.config.ts",
|
|
19
|
-
"preview": "vite preview"
|
|
20
|
-
},
|
|
21
|
-
"dependencies": {
|
|
22
|
-
"vue": "^3",
|
|
23
|
-
"vuewrite": "^0.0.19"
|
|
24
|
-
},
|
|
25
|
-
"devDependencies": {
|
|
26
|
-
"@vitejs/plugin-vue": "^5.0.4",
|
|
27
|
-
"@vueuse/core": "^10.10.0",
|
|
28
|
-
"color2k": "^2.0.3",
|
|
29
|
-
"sass": "^1.77.2",
|
|
30
|
-
"typescript": "^5.2.2",
|
|
31
|
-
"vite": "^5.2.0",
|
|
32
|
-
"vite-plugin-dts": "^3.9.1",
|
|
33
|
-
"vue-tsc": "^2.0.6",
|
|
34
|
-
"vuesix": "^1.0.12"
|
|
35
|
-
},
|
|
36
|
-
"files": [
|
|
37
|
-
"dist"
|
|
38
|
-
]
|
|
39
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "vuewrite",
|
|
3
|
+
"description": "Rich Text Editor based on Vue3 reactivity",
|
|
4
|
+
"private": false,
|
|
5
|
+
"version": "0.0.21",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "den59k",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/den59k/vuewrite.git"
|
|
12
|
+
},
|
|
13
|
+
"main": "dist/vuewrite.js",
|
|
14
|
+
"types": "dist/vuewrite.d.ts",
|
|
15
|
+
"scripts": {
|
|
16
|
+
"dev": "vite",
|
|
17
|
+
"build": "vue-tsc && vite build",
|
|
18
|
+
"build:app": "vue-tsc && vite build -c vite-app.config.ts",
|
|
19
|
+
"preview": "vite preview"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"vue": "^3",
|
|
23
|
+
"vuewrite": "^0.0.19"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@vitejs/plugin-vue": "^5.0.4",
|
|
27
|
+
"@vueuse/core": "^10.10.0",
|
|
28
|
+
"color2k": "^2.0.3",
|
|
29
|
+
"sass": "^1.77.2",
|
|
30
|
+
"typescript": "^5.2.2",
|
|
31
|
+
"vite": "^5.2.0",
|
|
32
|
+
"vite-plugin-dts": "^3.9.1",
|
|
33
|
+
"vue-tsc": "^2.0.6",
|
|
34
|
+
"vuesix": "^1.0.12"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist"
|
|
38
|
+
]
|
|
39
|
+
}
|