@oix1987/yjd 2.0.0 → 2.1.1
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 +140 -6
- package/core.js +5 -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 +163 -0
- package/index.js +113 -1
- package/lib/core/editor.js +313 -14
- package/lib/formats/image.js +16 -22
- package/lib/modules/mention.js +228 -0
- package/lib/modules/slash-menu.js +6 -4
- package/lib/modules/toolbar.js +28 -0
- package/lib/serialize.js +248 -0
- package/lib/static.js +28 -0
- package/lib/styles.css +182 -0
- package/lib/styles.css.js +1 -1
- package/lib/styles.min.css +1 -1
- package/lib/ui/icons.js +1 -0
- package/package.json +1 -1
- package/umd-entry.js +6 -5
package/README.md
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
🔗 **[yjd.io](https://yjd.io)** · [Live playground](https://yjd.io/demos/) · [Docs](https://yjd.io/site/docs.html)
|
|
6
6
|
|
|
7
7
|
```js
|
|
8
|
-
import
|
|
9
|
-
new
|
|
8
|
+
import yjd from '@oix1987/yjd';
|
|
9
|
+
new yjd('#editor', { placeholder: 'Start writing…' });
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
---
|
|
@@ -45,7 +45,7 @@ Or via CDN (all-in-one UMD):
|
|
|
45
45
|
```html
|
|
46
46
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@oix1987/yjd/lib/styles.min.css">
|
|
47
47
|
<script src="https://cdn.jsdelivr.net/npm/@oix1987/yjd"></script>
|
|
48
|
-
<script> new
|
|
48
|
+
<script> new yjd('#editor'); </script>
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
## Quick start (all-in-one)
|
|
@@ -53,14 +53,21 @@ Or via CDN (all-in-one UMD):
|
|
|
53
53
|
The default build registers everything and injects its CSS:
|
|
54
54
|
|
|
55
55
|
```js
|
|
56
|
-
import
|
|
56
|
+
import yjd from '@oix1987/yjd'; // `RichEditor` is kept as an alias
|
|
57
57
|
|
|
58
|
-
const editor = new
|
|
58
|
+
const editor = new yjd('#editor', {
|
|
59
59
|
placeholder: 'Start writing…',
|
|
60
60
|
onChange: (html) => console.log(html),
|
|
61
61
|
});
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
Via `<script>` (UMD) the global is `yjd` (and `window.RichEditor` still works):
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<script src="https://unpkg.com/@oix1987/yjd"></script>
|
|
68
|
+
<script>const editor = new yjd('#editor');</script>
|
|
69
|
+
```
|
|
70
|
+
|
|
64
71
|
## Tree-shakeable core
|
|
65
72
|
|
|
66
73
|
For the smallest bundle, import from `@oix1987/yjd/core` (side-effect-free) and register only what you need. Link the stylesheet once.
|
|
@@ -104,12 +111,139 @@ new Editor('#editor', {
|
|
|
104
111
|
|
|
105
112
|
**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`
|
|
106
113
|
|
|
107
|
-
**Modules** — `toolbar` · `history` · `slash-menu` · `block-toolbar` (bubble bar) · `table-toolbar` · `find-replace` · `code-view` · `resize-handles`
|
|
114
|
+
**Modules** — `toolbar` · `history` · `slash-menu` · `mention` · `block-toolbar` (bubble bar) · `table-toolbar` · `find-replace` · `code-view` · `resize-handles`
|
|
108
115
|
|
|
109
116
|
## Methods
|
|
110
117
|
|
|
111
118
|
`getHTML()` · `getText()` · `insertHTML(html)` · `insertText(t)` · `clear()` · `isEmpty()` · `focus()` · `setReadOnly(bool)` · `undo()` · `redo()`
|
|
112
119
|
|
|
120
|
+
## Integration API
|
|
121
|
+
|
|
122
|
+
Drop yjd into an existing app — upload images to your storage, tag people, store
|
|
123
|
+
content in whatever format you already use, and progressively enhance `<textarea>`s.
|
|
124
|
+
|
|
125
|
+
### Export / import (HTML · JSON · Markdown)
|
|
126
|
+
|
|
127
|
+
```js
|
|
128
|
+
editor.getHTML(); editor.setHTML(html);
|
|
129
|
+
editor.getJSON(); editor.setJSON(json); // { type: 'doc', content: [...] }
|
|
130
|
+
editor.getMarkdown(); editor.setMarkdown(md); // mention ids survive round-trips
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Also exported standalone: `htmlToMarkdown`, `markdownToHtml`, `domToJson`, `jsonToHtml`.
|
|
134
|
+
|
|
135
|
+
### Image upload hook
|
|
136
|
+
|
|
137
|
+
Provide `image.upload` to send files to your server/CDN instead of inlining base64.
|
|
138
|
+
Applies to every insert path — toolbar, paste, and drag-drop. A placeholder shows
|
|
139
|
+
while uploading; the `src` is swapped on success, or the image is removed on failure.
|
|
140
|
+
|
|
141
|
+
```js
|
|
142
|
+
new yjd('#editor', {
|
|
143
|
+
image: {
|
|
144
|
+
upload: async (file) => (await api.upload(file)).url, // return the URL
|
|
145
|
+
accept: 'image/png,image/jpeg,image/webp',
|
|
146
|
+
maxSize: 8 * 1024 * 1024,
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
// events: editor.on('image:upload'|'image:uploaded'|'image:error', cb)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Omit `upload` to keep the base64 fallback.
|
|
153
|
+
|
|
154
|
+
### File attachments
|
|
155
|
+
|
|
156
|
+
Like `image`, but for any file. Uploads via `file.upload` and inserts a **file chip**
|
|
157
|
+
(icon + name + size) that serializes to a Markdown link `[name (size)](url)`. Works
|
|
158
|
+
from the toolbar (`file` button), paste, and drag-drop.
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
new yjd('#editor', {
|
|
162
|
+
toolbar1: [{ group: 'insert', items: ['image', 'file'] }], // add the paperclip
|
|
163
|
+
file: {
|
|
164
|
+
upload: async (f) => ({ url: (await api.upload(f)).url, name: f.name }),
|
|
165
|
+
accept: '.pdf,.zip,.docx',
|
|
166
|
+
maxSize: 25 * 1024 * 1024,
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
// events: editor.on('file:upload' | 'file:uploaded' | 'file:error', cb)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Enter-to-submit (comment boxes)
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
new yjd('#comment', {
|
|
176
|
+
submit: {
|
|
177
|
+
onEnter: (html, editor) => post(html), // Enter sends; Shift+Enter = newline
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
When a mention/slash/emoji popup is open, Enter is left for the popup (it picks the
|
|
183
|
+
item, doesn't submit). Check it yourself with `editor.isMenuOpen()`.
|
|
184
|
+
|
|
185
|
+
### @mention / #task
|
|
186
|
+
|
|
187
|
+
```js
|
|
188
|
+
new yjd('#editor', {
|
|
189
|
+
mention: {
|
|
190
|
+
trigger: '@',
|
|
191
|
+
source: async (q) => fetchUsers(q), // [{ id, name, avatar_url }]
|
|
192
|
+
renderItem: (u) => `<img src="${u.avatar_url}"> ${u.name}`,
|
|
193
|
+
triggers: [{ char: '#', source: (q) => fetchTasks(q) }], // optional extra
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
editor.on('mention:select', (item) => { /* … */ });
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Inserts a token that serializes with its id:
|
|
200
|
+
`<span class="mention" data-id="u_123">@Ann</span>` → Markdown `@[Ann](u_123)`.
|
|
201
|
+
If a `source` item has no `avatar_url`, pass `icon` (inline SVG) for special entries
|
|
202
|
+
like “@all”. Menus are portaled to `<body>` but inherit the editor's `--rte-*` theme.
|
|
203
|
+
|
|
204
|
+
### Toolbar presets
|
|
205
|
+
|
|
206
|
+
```js
|
|
207
|
+
toolbar: 'full' // the default set
|
|
208
|
+
toolbar: 'compact' // bold/italic/underline · link · list · image · emoji
|
|
209
|
+
toolbar: { exclude: ['table','video','color'] } // defaults minus these
|
|
210
|
+
toolbar1: [{ group, items: [...] }] // or full custom groups
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### fromTextarea (two-way + controller)
|
|
214
|
+
|
|
215
|
+
Enhance an existing form field. Binding is **two-way**: editor edits update
|
|
216
|
+
`textarea.value` (firing native `input`/`change`), and `textarea.value = …` from app
|
|
217
|
+
code updates the editor. The returned editor carries a controller.
|
|
218
|
+
|
|
219
|
+
```js
|
|
220
|
+
const ed = yjd.fromTextarea('#body', { format: 'markdown' }); // or 'html'
|
|
221
|
+
ed.setValue(md); // load content
|
|
222
|
+
ed.getValue(); // current content (per format)
|
|
223
|
+
ed.destroy(); // remove editor, restore textarea + last value
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### renderStatic
|
|
227
|
+
|
|
228
|
+
Render stored HTML into a read-only view that matches the editor exactly (sanitized,
|
|
229
|
+
tagged `.yjd-content`) — no editor instance needed. Load the stylesheet on the page.
|
|
230
|
+
|
|
231
|
+
```js
|
|
232
|
+
import { renderStatic } from '@oix1987/yjd';
|
|
233
|
+
renderStatic(post.body_html, document.querySelector('#post'));
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Events & API notes
|
|
237
|
+
|
|
238
|
+
- **Events** (via `editor.on(name, cb)` / `editor.off(name, cb)`): `change`,
|
|
239
|
+
`image:upload` · `image:uploaded` · `image:error`, `file:upload` · `file:uploaded`
|
|
240
|
+
· `file:error`, `mention:select`, `content:overflow` (when `maxContentSize` exceeded).
|
|
241
|
+
- `editor.editor` is the public contentEditable element (attach your own listeners).
|
|
242
|
+
- **Markdown dialect** — GFM-ish: headings `#`–`######`, `**bold**`, `*italic*`,
|
|
243
|
+
`~~strike~~`, `` `code` ``, fenced ``` ``` ```, `>` quotes, `-`/`1.` lists,
|
|
244
|
+
pipe tables, `` images, `[text](url)` links, mentions `@[Name](id)` /
|
|
245
|
+
`#[Name](id)`, file chips `[name (size)](url)`.
|
|
246
|
+
|
|
113
247
|
## Styling
|
|
114
248
|
|
|
115
249
|
Theme via CSS custom properties:
|
package/core.js
CHANGED
|
@@ -61,6 +61,7 @@ export { default as TableToolbar } from './lib/modules/table-toolbar.js';
|
|
|
61
61
|
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
|
+
export { default as Mention } from './lib/modules/mention.js';
|
|
64
65
|
export { default as ResizeHandles } from './lib/modules/resize-handles.js';
|
|
65
66
|
|
|
66
67
|
// UI
|
|
@@ -75,3 +76,7 @@ export { default as ImagePopup } from './lib/ui/image-popup.js';
|
|
|
75
76
|
export { default as VideoPopup } from './lib/ui/video-popup.js';
|
|
76
77
|
export { default as TagPopup } from './lib/ui/tag-popup.js';
|
|
77
78
|
export { default as createCustomButton } from './lib/ui/select-button.js';
|
|
79
|
+
|
|
80
|
+
// Static rendering + serialization helpers
|
|
81
|
+
export { renderStatic } from './lib/static.js';
|
|
82
|
+
export { htmlToMarkdown, markdownToHtml, domToJson, jsonToHtml } from './lib/serialize.js';
|