@oix1987/yjd 2.1.2 → 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 +63 -4
- 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 +89 -0
- package/index.js +3 -0
- package/lib/core/editor.js +95 -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
|
@@ -30,11 +30,12 @@ Every preset is built from the same `/core` entry — pick a profile, tree-shake
|
|
|
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
|
|
36
37
|
> top of the table; the all-in-one default (`import yjd from '@oix1987/yjd'`) is the
|
|
37
|
-
> ~
|
|
38
|
+
> ~66 KB row because it registers every format/module and inlines the CSS. For
|
|
38
39
|
> comparison, Quill 2 is ~60 KB. The standalone stylesheet is ~10 KB gzip — link it
|
|
39
40
|
> once (and skip `StylesLoader`) to keep it out of the JS.
|
|
40
41
|
|
|
@@ -139,7 +140,7 @@ const ed = Editor.fromTextarea('#comment', {
|
|
|
139
140
|
|
|
140
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`
|
|
141
142
|
|
|
142
|
-
**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`
|
|
143
144
|
|
|
144
145
|
## Methods
|
|
145
146
|
|
|
@@ -229,6 +230,63 @@ Inserts a token that serializes with its id:
|
|
|
229
230
|
If a `source` item has no `avatar_url`, pass `icon` (inline SVG) for special entries
|
|
230
231
|
like “@all”. Menus are portaled to `<body>` but inherit the editor's `--rte-*` theme.
|
|
231
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
|
+
|
|
232
290
|
### Toolbar presets
|
|
233
291
|
|
|
234
292
|
```js
|
|
@@ -265,7 +323,8 @@ renderStatic(post.body_html, document.querySelector('#post'));
|
|
|
265
323
|
|
|
266
324
|
- **Events** (via `editor.on(name, cb)` / `editor.off(name, cb)`): `change`,
|
|
267
325
|
`image:upload` · `image:uploaded` · `image:error`, `file:upload` · `file:uploaded`
|
|
268
|
-
· `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).
|
|
269
328
|
- `editor.editor` is the public contentEditable element (attach your own listeners).
|
|
270
329
|
- **Markdown dialect** — GFM-ish: headings `#`–`######`, `**bold**`, `*italic*`,
|
|
271
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
|