@oix1987/yjd 2.1.1 → 2.2.0
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 +92 -5
- package/core.js +1 -0
- package/dist/core.esm.js +1 -1
- package/dist/core.esm.js.map +1 -1
- package/dist/rich-editor.esm.js +1 -1
- package/dist/rich-editor.esm.js.map +1 -1
- package/dist/rich-editor.min.js +1 -1
- package/dist/rich-editor.min.js.map +1 -1
- package/index.d.ts +98 -6
- package/index.js +6 -94
- package/lib/core/editor.js +173 -1
- package/lib/modules/ai.js +494 -0
- package/lib/modules/toolbar.js +14 -2
- package/lib/styles.css +86 -0
- package/lib/styles.css.js +1 -1
- package/lib/styles.min.css +1 -1
- package/lib/ui/icons.js +2 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -27,12 +27,17 @@ Every preset is built from the same `/core` entry — pick a profile, tree-shake
|
|
|
27
27
|
| Preset | Includes | Size |
|
|
28
28
|
|---|---|---|
|
|
29
29
|
| Minimal | bold · italic · underline · link | **~16 KB** |
|
|
30
|
-
|
|
|
30
|
+
| Comment box | bold · italic · link · list · image · mention + `fromTextarea` | **~26 KB** |
|
|
31
31
|
| Basic | + strike · headings · lists · align | **~25 KB** |
|
|
32
32
|
| Standard | + colour · image · table · find · code view | **~38 KB** |
|
|
33
|
-
|
|
|
33
|
+
| + AI assistant | any preset + `ai` module (BYO model, no SDK bundled) | **+~2 KB** |
|
|
34
|
+
| Full (all-in-one) | everything, CSS inlined | **~66 KB** |
|
|
34
35
|
|
|
35
|
-
>
|
|
36
|
+
> All figures are measured gzip. Tree-shake from the `/core` entry to land near the
|
|
37
|
+
> top of the table; the all-in-one default (`import yjd from '@oix1987/yjd'`) is the
|
|
38
|
+
> ~66 KB row because it registers every format/module and inlines the CSS. For
|
|
39
|
+
> comparison, Quill 2 is ~60 KB. The standalone stylesheet is ~10 KB gzip — link it
|
|
40
|
+
> once (and skip `StylesLoader`) to keep it out of the JS.
|
|
36
41
|
|
|
37
42
|
## Install
|
|
38
43
|
|
|
@@ -93,6 +98,30 @@ new Editor('#editor', {
|
|
|
93
98
|
<link rel="stylesheet" href="@oix1987/yjd/lib/styles.min.css">
|
|
94
99
|
```
|
|
95
100
|
|
|
101
|
+
### Lightweight comment box (~26 KB)
|
|
102
|
+
|
|
103
|
+
`Editor.fromTextarea`, `renderStatic` and the Markdown/JSON helpers all live in
|
|
104
|
+
`/core`, so a comment box pulls only the formats/modules you register — not the
|
|
105
|
+
whole editor. Link the stylesheet (don't import `StylesLoader`) to keep CSS out
|
|
106
|
+
of the JS.
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
import { Editor, registry, Bold, Italic, Link, List, Image, Mention, Toolbar, History }
|
|
110
|
+
from '@oix1987/yjd/core';
|
|
111
|
+
|
|
112
|
+
[['formats/bold', Bold], ['formats/italic', Italic], ['formats/link', Link],
|
|
113
|
+
['formats/list', List], ['formats/image', Image],
|
|
114
|
+
['modules/mention', Mention], ['modules/toolbar', Toolbar], ['modules/history', History]]
|
|
115
|
+
.forEach(([k, v]) => registry.register(k, v));
|
|
116
|
+
|
|
117
|
+
const ed = Editor.fromTextarea('#comment', {
|
|
118
|
+
format: 'markdown',
|
|
119
|
+
toolbar1: [{ group: 'insert', items: ['bold', 'italic', 'link', 'list', 'image', 'emoji'] }],
|
|
120
|
+
mention: { source: (q) => fetchUsers(q) },
|
|
121
|
+
submit: { onEnter: (html) => post(html) },
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
96
125
|
## Options
|
|
97
126
|
|
|
98
127
|
| Option | Type | Description |
|
|
@@ -111,7 +140,7 @@ new Editor('#editor', {
|
|
|
111
140
|
|
|
112
141
|
**Formats** — `bold` · `italic` · `underline` · `strike` · `subscript` · `superscript` · `color` · `background` · `link` · `heading` · `font-family` · `text-size` · `line-height` · `capitalization` · `text-align` · `list` · `indent-increase` · `indent-decrease` · `image` · `video` · `table` · `emoji` · `tag`
|
|
113
142
|
|
|
114
|
-
**Modules** — `toolbar` · `history` · `slash-menu` · `mention` · `block-toolbar` (bubble bar) · `table-toolbar` · `find-replace` · `code-view` · `resize-handles`
|
|
143
|
+
**Modules** — `toolbar` · `history` · `slash-menu` · `mention` · `ai` (BYO-model assistant) · `block-toolbar` (bubble bar) · `table-toolbar` · `find-replace` · `code-view` · `resize-handles`
|
|
115
144
|
|
|
116
145
|
## Methods
|
|
117
146
|
|
|
@@ -201,6 +230,63 @@ Inserts a token that serializes with its id:
|
|
|
201
230
|
If a `source` item has no `avatar_url`, pass `icon` (inline SVG) for special entries
|
|
202
231
|
like “@all”. Menus are portaled to `<body>` but inherit the editor's `--rte-*` theme.
|
|
203
232
|
|
|
233
|
+
### AI assistant (bring your own model)
|
|
234
|
+
|
|
235
|
+
Turn yjd into a "write-with-AI" surface **without bundling any model**. Like
|
|
236
|
+
`mention.source`, you supply a `complete` hook that calls whatever LLM you like
|
|
237
|
+
(Claude, your own endpoint, anything). The module is **inert until you do**, and
|
|
238
|
+
**tree-shakes to 0** when unused — so the AI code never reaches users who don't
|
|
239
|
+
opt in.
|
|
240
|
+
|
|
241
|
+
```js
|
|
242
|
+
new yjd('#editor', {
|
|
243
|
+
ai: {
|
|
244
|
+
// REQUIRED. Resolve to the generated text. Stream by calling onToken with
|
|
245
|
+
// each chunk; if you only stream, return undefined and chunks are joined.
|
|
246
|
+
complete: async ({ action, prompt, text, signal }, onToken) => {
|
|
247
|
+
const res = await fetch('/api/ai', {
|
|
248
|
+
method: 'POST', signal,
|
|
249
|
+
body: JSON.stringify({ action, prompt, text }),
|
|
250
|
+
});
|
|
251
|
+
return (await res.json()).text;
|
|
252
|
+
},
|
|
253
|
+
autocomplete: true, // optional: inline ghost-text, Tab to accept
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**What the user gets:**
|
|
259
|
+
|
|
260
|
+
- **Selection toolbar** — select text and a floating bar offers *Improve · Fix
|
|
261
|
+
spelling & grammar · Shorten · Lengthen · Simplify · Summarize* plus a free-form
|
|
262
|
+
**Ask AI…** box. The result is previewed with **Accept / Retry / Discard** — the
|
|
263
|
+
user always stays in control (nothing overwrites their text until they accept).
|
|
264
|
+
- **Ghost-text autocomplete** (opt-in) — a greyed inline suggestion as they type;
|
|
265
|
+
**Tab** accepts, any other key dismisses. Debounced and request-cancelling, so it
|
|
266
|
+
never blocks typing.
|
|
267
|
+
|
|
268
|
+
Customise the actions, or drive it programmatically:
|
|
269
|
+
|
|
270
|
+
```js
|
|
271
|
+
ai: { complete, actions: [{ id: 'tr', label: 'Translate → FR', prompt: 'Translate to French.' }] }
|
|
272
|
+
|
|
273
|
+
editor.ai.run('Make this sound friendlier'); // run on the current selection
|
|
274
|
+
editor.on('ai:accept', ({ result }) => {}); // ai:start · ai:done · ai:error · ai:accept · ai:discard
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Building your own agent UI? The same primitives are public:
|
|
278
|
+
|
|
279
|
+
```js
|
|
280
|
+
editor.getSelection(); // { text, html, isEmpty, range }
|
|
281
|
+
editor.replaceSelection(text, { asText: true }); // sanitized, undo-aware
|
|
282
|
+
const s = editor.streamInto(); // token-by-token sink
|
|
283
|
+
s.append('Hel'); s.append('lo'); s.commit(); // or s.cancel() to undo the stream
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Nothing the module renders ever lives in the editable DOM, so `getContent()` /
|
|
287
|
+
`getJSON()` / `onChange` stay clean. Menus portal to `<body>` but inherit the
|
|
288
|
+
editor's `--rte-*` theme.
|
|
289
|
+
|
|
204
290
|
### Toolbar presets
|
|
205
291
|
|
|
206
292
|
```js
|
|
@@ -237,7 +323,8 @@ renderStatic(post.body_html, document.querySelector('#post'));
|
|
|
237
323
|
|
|
238
324
|
- **Events** (via `editor.on(name, cb)` / `editor.off(name, cb)`): `change`,
|
|
239
325
|
`image:upload` · `image:uploaded` · `image:error`, `file:upload` · `file:uploaded`
|
|
240
|
-
· `file:error`, `mention:select`, `
|
|
326
|
+
· `file:error`, `mention:select`, `ai:start` · `ai:done` · `ai:accept` · `ai:discard`
|
|
327
|
+
· `ai:error`, `content:overflow` (when `maxContentSize` exceeded).
|
|
241
328
|
- `editor.editor` is the public contentEditable element (attach your own listeners).
|
|
242
329
|
- **Markdown dialect** — GFM-ish: headings `#`–`######`, `**bold**`, `*italic*`,
|
|
243
330
|
`~~strike~~`, `` `code` ``, fenced ``` ``` ```, `>` quotes, `-`/`1.` lists,
|
package/core.js
CHANGED
|
@@ -62,6 +62,7 @@ export { default as CodeView } from './lib/modules/code-view.js';
|
|
|
62
62
|
export { default as FindReplace } from './lib/modules/find-replace.js';
|
|
63
63
|
export { default as SlashMenu } from './lib/modules/slash-menu.js';
|
|
64
64
|
export { default as Mention } from './lib/modules/mention.js';
|
|
65
|
+
export { default as Ai } from './lib/modules/ai.js';
|
|
65
66
|
export { default as ResizeHandles } from './lib/modules/resize-handles.js';
|
|
66
67
|
|
|
67
68
|
// UI
|