vuewrite 0.0.1 → 0.0.2
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 +16 -9
- package/dist/vuewrite.d.ts +54 -9
- package/dist/vuewrite.js +58 -10
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -11,26 +11,33 @@ You can watch the demo [here](https://vuewrite.easix.ru)
|
|
|
11
11
|
|
|
12
12
|
```vue
|
|
13
13
|
<template>
|
|
14
|
-
<TextEditor
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
<TextEditor
|
|
15
|
+
ref="textEditorRef"
|
|
16
|
+
v-model="modelValue"
|
|
17
|
+
single
|
|
18
|
+
class="text-editor"
|
|
19
|
+
:decorator="decorator"
|
|
20
|
+
@keydown="onKeyDown"
|
|
21
|
+
/>
|
|
20
22
|
</template>
|
|
21
23
|
|
|
22
24
|
<script lang="ts">
|
|
25
|
+
import { TextEditor, TextEditorRef } from 'vuewrite'
|
|
26
|
+
|
|
27
|
+
const textEditorRef = shallowRef<TextEditorRef>()
|
|
28
|
+
const modelValue = ref("")
|
|
23
29
|
|
|
24
30
|
const onKeyDown = (e: KeyboardEvent) => {
|
|
31
|
+
if (!textEditorRef.value) return
|
|
25
32
|
if ((e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey) {
|
|
26
33
|
if (e.code === "KeyB") {
|
|
27
|
-
|
|
34
|
+
textEditorRef.value.toggleStyle("bold")
|
|
28
35
|
}
|
|
29
36
|
if (e.code === "KeyI") {
|
|
30
|
-
|
|
37
|
+
textEditorRef.value.toggleStyle("italic")
|
|
31
38
|
}
|
|
32
39
|
if (e.code === "KeyU") {
|
|
33
|
-
|
|
40
|
+
textEditorRef.value.toggleStyle("underline")
|
|
34
41
|
}
|
|
35
42
|
}
|
|
36
43
|
}
|
package/dist/vuewrite.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ComponentOptionsMixin } from 'vue';
|
|
2
|
+
import { ComputedRef } from 'vue';
|
|
2
3
|
import { DefineComponent } from 'vue';
|
|
3
4
|
import { ExtractPropTypes } from 'vue';
|
|
4
5
|
import { HTMLAttributes } from 'vue';
|
|
@@ -39,24 +40,58 @@ export declare type Style = {
|
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
export declare const TextEditor: __VLS_WithTemplateSlots<DefineComponent<__VLS_TypePropsToRuntimeProps<{
|
|
42
|
-
store: TextEditorStore;
|
|
43
|
-
placeholder?: string | undefined;
|
|
44
43
|
decorator?: Decorator | undefined;
|
|
44
|
+
single?: boolean | undefined;
|
|
45
|
+
modelValue?: string | string[] | undefined;
|
|
46
|
+
styles?: Style[] | Style[][] | undefined;
|
|
45
47
|
}>, {
|
|
46
|
-
|
|
48
|
+
currentStyles: ComputedRef<Map<string, Style>>;
|
|
49
|
+
currentBlock: ComputedRef< {
|
|
50
|
+
id: string;
|
|
51
|
+
text: string;
|
|
52
|
+
type?: string | undefined;
|
|
53
|
+
styles: {
|
|
54
|
+
start: number;
|
|
55
|
+
end: number;
|
|
56
|
+
style: string;
|
|
57
|
+
meta?: any;
|
|
58
|
+
}[];
|
|
59
|
+
} | null>;
|
|
60
|
+
isCollapsed: ComputedRef<boolean>;
|
|
61
|
+
selection: {
|
|
62
|
+
anchor: {
|
|
63
|
+
blockId: string;
|
|
64
|
+
offset: number;
|
|
65
|
+
};
|
|
66
|
+
focus: {
|
|
67
|
+
blockId: string;
|
|
68
|
+
offset: number;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
toggleStyle: (style: string) => void;
|
|
72
|
+
applyStyle: (_style: string, meta?: any) => void;
|
|
73
|
+
removeStyle: (_style: string) => void;
|
|
74
|
+
insertText: (data: string) => void;
|
|
47
75
|
}, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
|
|
48
76
|
keydown: (...args: any[]) => void;
|
|
77
|
+
"update:modelValue": (...args: any[]) => void;
|
|
78
|
+
"update:styles": (...args: any[]) => void;
|
|
49
79
|
}, string, PublicProps, Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
|
|
50
|
-
store: TextEditorStore;
|
|
51
|
-
placeholder?: string | undefined;
|
|
52
80
|
decorator?: Decorator | undefined;
|
|
81
|
+
single?: boolean | undefined;
|
|
82
|
+
modelValue?: string | string[] | undefined;
|
|
83
|
+
styles?: Style[] | Style[][] | undefined;
|
|
53
84
|
}>>> & {
|
|
54
85
|
onKeydown?: ((...args: any[]) => any) | undefined;
|
|
86
|
+
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
87
|
+
"onUpdate:styles"?: ((...args: any[]) => any) | undefined;
|
|
55
88
|
}, {}, {}>, {
|
|
56
89
|
placeholder?(_: {}): any;
|
|
57
90
|
}>;
|
|
58
91
|
|
|
59
|
-
export declare
|
|
92
|
+
export declare type TextEditorRef = Pick<TextEditorStore, "currentStyles" | "currentBlock" | "isCollapsed" | "selection" | "toggleStyle" | "applyStyle" | "removeStyle" | "insertText">;
|
|
93
|
+
|
|
94
|
+
declare class TextEditorStore {
|
|
60
95
|
blocks: {
|
|
61
96
|
id: string;
|
|
62
97
|
text: string;
|
|
@@ -78,9 +113,19 @@ export declare class TextEditorStore {
|
|
|
78
113
|
offset: number;
|
|
79
114
|
};
|
|
80
115
|
};
|
|
81
|
-
|
|
116
|
+
_isCollapsed: ComputedRef<boolean>;
|
|
82
117
|
get isCollapsed(): boolean;
|
|
83
|
-
|
|
118
|
+
_currentBlock: ComputedRef< {
|
|
119
|
+
id: string;
|
|
120
|
+
text: string;
|
|
121
|
+
type?: string | undefined;
|
|
122
|
+
styles: {
|
|
123
|
+
start: number;
|
|
124
|
+
end: number;
|
|
125
|
+
style: string;
|
|
126
|
+
meta?: any;
|
|
127
|
+
}[];
|
|
128
|
+
} | null>;
|
|
84
129
|
get currentBlock(): {
|
|
85
130
|
id: string;
|
|
86
131
|
text: string;
|
|
@@ -105,7 +150,7 @@ export declare class TextEditorStore {
|
|
|
105
150
|
}, number, number];
|
|
106
151
|
private moveStyles;
|
|
107
152
|
deleteSelected(): void;
|
|
108
|
-
|
|
153
|
+
_currentStyles: ComputedRef<Map<string, Style>>;
|
|
109
154
|
get currentStyles(): Map<string, Style>;
|
|
110
155
|
applyStyle(_style: string, meta?: any): void;
|
|
111
156
|
removeStyleAt(block: Block, _start: number, _end: number, _style?: string): void;
|
package/dist/vuewrite.js
CHANGED
|
@@ -158,6 +158,8 @@ class TextEditorStore {
|
|
|
158
158
|
__publicField(this, "_currentStyles", computed(() => {
|
|
159
159
|
const [start, end, startIndex, endIndex] = this.startAndEnd;
|
|
160
160
|
const styles = /* @__PURE__ */ new Map();
|
|
161
|
+
if (startIndex < 0)
|
|
162
|
+
return styles;
|
|
161
163
|
for (let i = startIndex; i <= endIndex; i++) {
|
|
162
164
|
for (let style of this.blocks[i].styles) {
|
|
163
165
|
if (i === startIndex && start.offset < style.start)
|
|
@@ -516,24 +518,64 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
516
518
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
517
519
|
__name: "TextEditor",
|
|
518
520
|
props: {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
521
|
+
decorator: { type: Function },
|
|
522
|
+
single: { type: Boolean },
|
|
523
|
+
modelValue: {},
|
|
524
|
+
styles: {}
|
|
522
525
|
},
|
|
523
|
-
emits: ["keydown"],
|
|
526
|
+
emits: ["keydown", "update:modelValue", "update:styles"],
|
|
524
527
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
525
528
|
const props = __props;
|
|
526
529
|
const emit = __emit;
|
|
527
530
|
const slots = useSlots();
|
|
528
531
|
const textEditorRef = ref();
|
|
529
|
-
const store =
|
|
532
|
+
const store = new TextEditorStore();
|
|
533
|
+
let modelValue = "";
|
|
534
|
+
watch(() => props.modelValue, (newValue) => {
|
|
535
|
+
if (newValue === void 0 || newValue === null || newValue === modelValue)
|
|
536
|
+
return;
|
|
537
|
+
if (!Array.isArray(newValue)) {
|
|
538
|
+
store.blocks[0].text = newValue;
|
|
539
|
+
return;
|
|
540
|
+
} else {
|
|
541
|
+
for (let i = store.blocks.length; i < newValue.length; i++) {
|
|
542
|
+
store.blocks.push({ id: uid(), text: "", styles: [] });
|
|
543
|
+
}
|
|
544
|
+
store.blocks.length = newValue.length;
|
|
545
|
+
for (let i = 0; i < newValue.length; i++) {
|
|
546
|
+
store.blocks[i].text = newValue[i];
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}, { immediate: true });
|
|
550
|
+
let styles;
|
|
551
|
+
watch(() => props.styles, (newStyles) => {
|
|
552
|
+
if (!newStyles || newStyles.length === 0 || newStyles === styles)
|
|
553
|
+
return;
|
|
554
|
+
for (let i = 0; i < store.blocks.length; i++) {
|
|
555
|
+
if (newStyles.length <= i)
|
|
556
|
+
break;
|
|
557
|
+
const style = props.single ? newStyles : newStyles[i];
|
|
558
|
+
store.blocks[i].styles = style;
|
|
559
|
+
}
|
|
560
|
+
}, { immediate: true });
|
|
561
|
+
watch(() => store.blocks, () => {
|
|
562
|
+
if (props.single) {
|
|
563
|
+
modelValue = store.blocks[0].text;
|
|
564
|
+
styles = store.blocks[0].styles;
|
|
565
|
+
} else {
|
|
566
|
+
modelValue = store.blocks.map((item) => item.text);
|
|
567
|
+
styles = store.blocks.map((item) => item.styles);
|
|
568
|
+
}
|
|
569
|
+
emit("update:modelValue", modelValue);
|
|
570
|
+
emit("update:styles", styles);
|
|
571
|
+
}, { deep: true });
|
|
530
572
|
const onKeyDown = (e) => {
|
|
531
573
|
emit("keydown", e);
|
|
532
574
|
if (e.defaultPrevented)
|
|
533
575
|
return;
|
|
534
576
|
if (e.code === "Enter") {
|
|
535
577
|
e.preventDefault();
|
|
536
|
-
if (e.shiftKey) {
|
|
578
|
+
if (e.shiftKey || props.single) {
|
|
537
579
|
store.insertText("\n");
|
|
538
580
|
} else {
|
|
539
581
|
store.addNewLine();
|
|
@@ -600,7 +642,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
600
642
|
};
|
|
601
643
|
watch(() => store.selection, applySelection, { deep: true, flush: "post" });
|
|
602
644
|
__expose({
|
|
603
|
-
store
|
|
645
|
+
currentStyles: store._currentStyles,
|
|
646
|
+
currentBlock: store._currentBlock,
|
|
647
|
+
isCollapsed: store._isCollapsed,
|
|
648
|
+
selection: store.selection,
|
|
649
|
+
toggleStyle: store.toggleStyle.bind(store),
|
|
650
|
+
applyStyle: store.applyStyle.bind(store),
|
|
651
|
+
removeStyle: store.removeStyle.bind(store),
|
|
652
|
+
insertText: store.insertText.bind(store)
|
|
604
653
|
});
|
|
605
654
|
return (_ctx, _cache) => {
|
|
606
655
|
return openBlock(), createElementBlock("div", {
|
|
@@ -616,7 +665,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
616
665
|
key: block.id,
|
|
617
666
|
block,
|
|
618
667
|
slots: unref(slots),
|
|
619
|
-
decorator:
|
|
668
|
+
decorator: props.decorator,
|
|
620
669
|
onPostrender: onPostRender
|
|
621
670
|
}, null, 8, ["block", "slots", "decorator"]);
|
|
622
671
|
}), 128)),
|
|
@@ -626,6 +675,5 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
626
675
|
}
|
|
627
676
|
});
|
|
628
677
|
export {
|
|
629
|
-
_sfc_main as TextEditor
|
|
630
|
-
TextEditorStore
|
|
678
|
+
_sfc_main as TextEditor
|
|
631
679
|
};
|
package/package.json
CHANGED