@rathkit/rte-vue 0.0.0 → 0.1.0-alpha.3
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 +31 -4
- package/dist/composables.d.ts +9 -0
- package/dist/composables.js +25 -0
- package/dist/editor.d.ts +3 -0
- package/dist/editor.js +35 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/package.json +65 -3
package/README.md
CHANGED
|
@@ -1,11 +1,38 @@
|
|
|
1
1
|
# @rathkit/rte-vue
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **Alpha** (0.1.0-alpha.0). Not for production: the APIs will change between releases. Published to the `next` tag only.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The editor for Vue: a component and composables over the headless layer. A ref changes only when the value it holds does.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
6
8
|
|
|
7
9
|
```sh
|
|
8
|
-
npm install @rathkit/rte-vue@next
|
|
10
|
+
npm install @rathkit/rte-vue@next @rathkit/rte-core@next @rathkit/rte-headless@next
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This package has no dependencies of its own. It works with `@rathkit/rte-core`, `@rathkit/rte-headless`, `vue` (peer dependencies, all optional so that npm installs nothing you did not ask for), so install the ones you use alongside it; `vue` comes from your own project.
|
|
14
|
+
|
|
15
|
+
## Example
|
|
16
|
+
|
|
17
|
+
```vue
|
|
18
|
+
<script setup>
|
|
19
|
+
import { shallowRef } from "vue";
|
|
20
|
+
import { RteEditor, useCommand } from "@rathkit/rte-vue";
|
|
21
|
+
|
|
22
|
+
const editor = shallowRef();
|
|
23
|
+
const bold = useCommand(editor, "format.bold");
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<template>
|
|
27
|
+
<button :aria-pressed="bold.active" @click="editor?.commands.run('format.bold')">Bold</button>
|
|
28
|
+
<RteEditor label="Body" default-value="<p>Hello</p>" @ready="(e) => (editor = e)" @change="(html) => console.log(html)" />
|
|
29
|
+
</template>
|
|
9
30
|
```
|
|
10
31
|
|
|
11
|
-
|
|
32
|
+
## More
|
|
33
|
+
|
|
34
|
+
Documentation: <https://rathkit.com>. Source and issues: <https://github.com/rathkit/rte>. What is checked: [SUPPORT.md](https://github.com/rathkit/rte/blob/main/docs/SUPPORT.md). Changes: [CHANGELOG.md](https://github.com/rathkit/rte/blob/main/CHANGELOG.md). How a release is verified: [VERIFY.md](https://github.com/rathkit/rte/blob/main/docs/VERIFY.md).
|
|
35
|
+
|
|
36
|
+
## License
|
|
37
|
+
|
|
38
|
+
[Apache-2.0](LICENSE)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type MaybeRef, type Ref } from "vue";
|
|
2
|
+
import { type ExternalStore, type HeadlessEditor } from "@rathkit/rte-headless";
|
|
3
|
+
import type { CommandState, EditorSnapshot } from "@rathkit/rte-core";
|
|
4
|
+
/** Follows a store with a ref. The editor may be given as a ref that fills in later; the ref follows whichever editor is current. */
|
|
5
|
+
export declare function useStore<T, E extends HeadlessEditor | undefined>(editor: MaybeRef<E>, make: (editor: HeadlessEditor) => ExternalStore<T>, empty: T): Readonly<Ref<T>>;
|
|
6
|
+
/** One command's state: whether it can run, whether it is on, its value. Off and disabled until the editor exists. */
|
|
7
|
+
export declare function useCommand(editor: MaybeRef<HeadlessEditor | undefined>, name: string): Readonly<Ref<CommandState>>;
|
|
8
|
+
/** One value worked out from the editor state. The ref changes, and anything reading it re-runs, only when that value changes. */
|
|
9
|
+
export declare function useSelector<T>(editor: MaybeRef<HeadlessEditor | undefined>, selector: (snapshot: EditorSnapshot) => T, equals?: (a: T, b: T) => boolean): Readonly<Ref<T | undefined>>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { onScopeDispose, shallowRef, unref, watch } from "vue";
|
|
2
|
+
import { commandStore, selectStore } from "@rathkit/rte-headless";
|
|
3
|
+
const idle = Object.freeze({ enabled: false, active: false, value: undefined });
|
|
4
|
+
export function useStore(editor, make, empty) {
|
|
5
|
+
const state = shallowRef(empty);
|
|
6
|
+
let unsubscribe = () => undefined;
|
|
7
|
+
const stop = watch(() => unref(editor), (current) => {
|
|
8
|
+
unsubscribe();
|
|
9
|
+
if (!current) {
|
|
10
|
+
state.value = empty;
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const store = make(current);
|
|
14
|
+
state.value = store.getSnapshot();
|
|
15
|
+
unsubscribe = store.subscribe(() => { state.value = store.getSnapshot(); });
|
|
16
|
+
}, { immediate: true });
|
|
17
|
+
onScopeDispose(() => { stop(); unsubscribe(); });
|
|
18
|
+
return state;
|
|
19
|
+
}
|
|
20
|
+
export function useCommand(editor, name) {
|
|
21
|
+
return useStore(editor, (e) => commandStore(e, name), idle);
|
|
22
|
+
}
|
|
23
|
+
export function useSelector(editor, selector, equals) {
|
|
24
|
+
return useStore(editor, (e) => selectStore(e, selector, equals), undefined);
|
|
25
|
+
}
|
package/dist/editor.d.ts
ADDED
package/dist/editor.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { defineComponent, h, onBeforeUnmount, onMounted, shallowRef, watch } from "vue";
|
|
2
|
+
import { createEditor } from "@rathkit/rte-core/standard";
|
|
3
|
+
export const RteEditor = defineComponent({
|
|
4
|
+
name: "RteEditor",
|
|
5
|
+
props: {
|
|
6
|
+
defaultValue: { type: String, default: "" },
|
|
7
|
+
readOnly: { type: Boolean, default: false },
|
|
8
|
+
label: { type: String, required: true },
|
|
9
|
+
options: { type: Object, default: () => ({}) },
|
|
10
|
+
},
|
|
11
|
+
emits: ["change", "ready"],
|
|
12
|
+
setup(props, { emit, expose }) {
|
|
13
|
+
const element = shallowRef(null);
|
|
14
|
+
const editor = shallowRef(undefined);
|
|
15
|
+
let stop = () => undefined;
|
|
16
|
+
onMounted(() => {
|
|
17
|
+
const made = createEditor({ ...props.options, element: element.value, html: props.defaultValue, readOnly: props.readOnly });
|
|
18
|
+
let last = made.getHtml();
|
|
19
|
+
const off = made.subscribe(() => {
|
|
20
|
+
const html = made.getHtml();
|
|
21
|
+
if (html === last)
|
|
22
|
+
return;
|
|
23
|
+
last = html;
|
|
24
|
+
emit("change", html);
|
|
25
|
+
});
|
|
26
|
+
stop = () => { off(); made.destroy(); };
|
|
27
|
+
editor.value = made;
|
|
28
|
+
emit("ready", made);
|
|
29
|
+
});
|
|
30
|
+
onBeforeUnmount(() => { stop(); editor.value = undefined; });
|
|
31
|
+
watch(() => props.readOnly, (readOnly) => editor.value?.setReadOnly(readOnly));
|
|
32
|
+
expose({ editor });
|
|
33
|
+
return () => h("div", { ref: element, "aria-label": props.label, "data-rk-surface": "" });
|
|
34
|
+
},
|
|
35
|
+
});
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rathkit/rte-vue",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.0-alpha.3",
|
|
4
|
+
"description": "The editor for Vue: a component and composables over the headless layer, with no editor or accessibility logic of its own.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"rich-text",
|
|
7
|
+
"editor",
|
|
8
|
+
"wysiwyg",
|
|
9
|
+
"contenteditable",
|
|
10
|
+
"zero-dependencies",
|
|
11
|
+
"typescript",
|
|
12
|
+
"vue",
|
|
13
|
+
"composables"
|
|
14
|
+
],
|
|
5
15
|
"license": "Apache-2.0",
|
|
6
16
|
"homepage": "https://rathkit.com",
|
|
7
17
|
"repository": {
|
|
@@ -12,7 +22,59 @@
|
|
|
12
22
|
"bugs": {
|
|
13
23
|
"url": "https://github.com/rathkit/rte/issues"
|
|
14
24
|
},
|
|
25
|
+
"type": "module",
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=22.14.0"
|
|
29
|
+
},
|
|
15
30
|
"publishConfig": {
|
|
16
|
-
"access": "public"
|
|
31
|
+
"access": "public",
|
|
32
|
+
"provenance": true,
|
|
33
|
+
"tag": "next"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"NOTICE",
|
|
38
|
+
"!dist/**/*.map"
|
|
39
|
+
],
|
|
40
|
+
"exports": {
|
|
41
|
+
".": {
|
|
42
|
+
"types": "./dist/index.d.ts",
|
|
43
|
+
"default": "./dist/index.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"@rathkit/rte-core": ">=0.1.0-alpha.3 <0.2.0",
|
|
48
|
+
"@rathkit/rte-headless": ">=0.1.0-alpha.3 <0.2.0",
|
|
49
|
+
"vue": ">=3.4"
|
|
50
|
+
},
|
|
51
|
+
"peerDependenciesMeta": {
|
|
52
|
+
"@rathkit/rte-core": {
|
|
53
|
+
"optional": true
|
|
54
|
+
},
|
|
55
|
+
"@rathkit/rte-headless": {
|
|
56
|
+
"optional": true
|
|
57
|
+
},
|
|
58
|
+
"vue": {
|
|
59
|
+
"optional": true
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@rathkit/rte-core": "workspace:*",
|
|
64
|
+
"@rathkit/rte-headless": "workspace:*"
|
|
65
|
+
},
|
|
66
|
+
"scripts": {
|
|
67
|
+
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && tsc -p tsconfig.build.js.json",
|
|
68
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
69
|
+
"test": "node --import ./test/register.mjs --test \"src/**/*.test.ts\""
|
|
70
|
+
},
|
|
71
|
+
"rathkit": {
|
|
72
|
+
"budgets": [
|
|
73
|
+
{
|
|
74
|
+
"name": "vue",
|
|
75
|
+
"entry": "dist/index.js",
|
|
76
|
+
"gzipKB": 2
|
|
77
|
+
}
|
|
78
|
+
]
|
|
17
79
|
}
|
|
18
80
|
}
|