oneuxi-editor 1.0.0 → 1.0.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 +521 -0
- package/package.json +7 -3
package/README.md
ADDED
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
# oneuxi-editor
|
|
2
|
+
|
|
3
|
+
A production-ready rich text editor for React applications, built on the Lexical engine. Designed for SaaS products, internal tools, and content platforms that need a dependable editor without the weight of legacy alternatives.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/oneuxi-editor)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://t.me/thedebuglab)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Why oneuxi-editor
|
|
12
|
+
|
|
13
|
+
Most rich text solutions either carry significant legacy weight or are overly opinionated about their design system. `oneuxi-editor` is built to be dropped into any React project with a single import, minimal configuration, and a clean public API. It is SSR-safe, fully tree-shakeable, and ships without any bundled peer dependencies beyond Lexical itself.
|
|
14
|
+
|
|
15
|
+
It works independently of the `oneuxi` UI component library. If you use `oneuxi` elsewhere, they share a consistent design language. If you do not, `oneuxi-editor` stands entirely on its own.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Table of Contents
|
|
20
|
+
|
|
21
|
+
- [Installation](#installation)
|
|
22
|
+
- [Basic Usage](#basic-usage)
|
|
23
|
+
- [Controlled and Uncontrolled Modes](#controlled-and-uncontrolled-modes)
|
|
24
|
+
- [Output Formats](#output-formats)
|
|
25
|
+
- [Toolbar Configuration](#toolbar-configuration)
|
|
26
|
+
- [Themes](#themes)
|
|
27
|
+
- [Editor Height](#editor-height)
|
|
28
|
+
- [Bubble Toolbar](#bubble-toolbar)
|
|
29
|
+
- [HTML Source Mode](#html-source-mode)
|
|
30
|
+
- [Images and File Uploads](#images-and-file-uploads)
|
|
31
|
+
- [Tables](#tables)
|
|
32
|
+
- [Code Blocks](#code-blocks)
|
|
33
|
+
- [Mentions](#mentions)
|
|
34
|
+
- [Slash Commands](#slash-commands)
|
|
35
|
+
- [Paste Cleanup](#paste-cleanup)
|
|
36
|
+
- [Security and Sanitization](#security-and-sanitization)
|
|
37
|
+
- [SSR and Next.js](#ssr-and-nextjs)
|
|
38
|
+
- [Imperative API](#imperative-api)
|
|
39
|
+
- [Props Reference](#props-reference)
|
|
40
|
+
- [Accessibility](#accessibility)
|
|
41
|
+
- [Browser Support](#browser-support)
|
|
42
|
+
- [Bundle Size](#bundle-size)
|
|
43
|
+
- [AI Features — Coming Soon](#ai-features--coming-soon)
|
|
44
|
+
- [Community & Support](#community--support)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install oneuxi-editor
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Import the stylesheet once at your application root:
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import "oneuxi-editor/styles.css"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Basic Usage
|
|
63
|
+
|
|
64
|
+
The simplest form of the editor requires no configuration. It renders with a default toolbar and outputs HTML on every change.
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { Editor } from "oneuxi-editor"
|
|
68
|
+
import "oneuxi-editor/styles.css"
|
|
69
|
+
|
|
70
|
+
export default function App() {
|
|
71
|
+
return (
|
|
72
|
+
<Editor
|
|
73
|
+
placeholder="Start writing..."
|
|
74
|
+
onChange={(html) => console.log(html)}
|
|
75
|
+
/>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Controlled and Uncontrolled Modes
|
|
83
|
+
|
|
84
|
+
**Controlled** — pass `value` and `onChange` to keep the content in sync with your state. Useful for forms, autosave, and live preview panels.
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { useState } from "react"
|
|
88
|
+
import { Editor } from "oneuxi-editor"
|
|
89
|
+
|
|
90
|
+
export default function ControlledEditor() {
|
|
91
|
+
const [html, setHtml] = useState("<p>Initial content</p>")
|
|
92
|
+
|
|
93
|
+
return <Editor value={html} onChange={setHtml} />
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Uncontrolled** — pass `defaultValue` to set initial content without managing state. Useful for simple forms where you only need the final value on submit.
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { useRef } from "react"
|
|
101
|
+
import { Editor } from "oneuxi-editor"
|
|
102
|
+
import type { EditorRef } from "oneuxi-editor"
|
|
103
|
+
|
|
104
|
+
export default function UncontrolledForm() {
|
|
105
|
+
const editorRef = useRef<EditorRef>(null)
|
|
106
|
+
|
|
107
|
+
const handleSubmit = () => {
|
|
108
|
+
const html = editorRef.current?.getHTML()
|
|
109
|
+
console.log(html)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<>
|
|
114
|
+
<Editor ref={editorRef} defaultValue="<p>Draft</p>" />
|
|
115
|
+
<button onClick={handleSubmit}>Submit</button>
|
|
116
|
+
</>
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Output Formats
|
|
124
|
+
|
|
125
|
+
The editor supports three output formats, controlled by the `output` prop.
|
|
126
|
+
|
|
127
|
+
**HTML** (default) — returns sanitized HTML as a string.
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
<Editor output="html" onChange={(html) => console.log(html)} />
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**JSON** — returns the Lexical editor state as a JSON string. Useful for round-trip serialization.
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
<Editor
|
|
137
|
+
output="json"
|
|
138
|
+
onChange={(json) => {
|
|
139
|
+
const state = JSON.parse(json)
|
|
140
|
+
console.log(state)
|
|
141
|
+
}}
|
|
142
|
+
/>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Text** — returns plain text with all markup stripped.
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
<Editor output="text" onChange={(text) => console.log(text)} />
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Toolbar Configuration
|
|
154
|
+
|
|
155
|
+
Pass an array of toolbar item names to control which controls are shown and in what order. Use `"|"` as a separator.
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
<Editor
|
|
159
|
+
toolbar={[
|
|
160
|
+
"undo", "redo", "|",
|
|
161
|
+
"heading", "|",
|
|
162
|
+
"bold", "italic", "underline", "strike", "|",
|
|
163
|
+
"align", "|",
|
|
164
|
+
"bulletList", "orderedList", "checkList", "|",
|
|
165
|
+
"link", "image", "table", "codeBlock", "blockquote", "hr", "|",
|
|
166
|
+
"sourceMode", "findReplace", "fullscreen"
|
|
167
|
+
]}
|
|
168
|
+
/>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Available items: `undo`, `redo`, `heading`, `bold`, `italic`, `underline`, `strike`, `code`, `subscript`, `superscript`, `clearFormatting`, `align`, `bulletList`, `orderedList`, `checkList`, `indent`, `outdent`, `link`, `image`, `table`, `codeBlock`, `blockquote`, `hr`, `sourceMode`, `findReplace`, `fullscreen`.
|
|
172
|
+
|
|
173
|
+
To render without any toolbar (headless mode):
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
<Editor toolbar={false} bubbleToolbar={false} />
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
You can also insert custom React components directly into the toolbar array:
|
|
180
|
+
|
|
181
|
+
```tsx
|
|
182
|
+
import { WordCountDisplay } from "./WordCountDisplay"
|
|
183
|
+
|
|
184
|
+
<Editor toolbar={["bold", "italic", WordCountDisplay]} />
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Themes
|
|
190
|
+
|
|
191
|
+
Three built-in theme modes are available. The editor respects your OS preference when set to `"system"`.
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
<Editor theme="light" />
|
|
195
|
+
<Editor theme="dark" />
|
|
196
|
+
<Editor theme="system" /> {/* follows OS dark mode setting */}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
For brand-specific styling, pass a theme object with any combination of CSS custom property overrides:
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
<Editor
|
|
203
|
+
theme={{
|
|
204
|
+
mode: "dark",
|
|
205
|
+
primary: "#7c3aed",
|
|
206
|
+
background: "#0f172a",
|
|
207
|
+
surface: "#1e293b",
|
|
208
|
+
border: "#334155",
|
|
209
|
+
radius: "12px",
|
|
210
|
+
fontFamily: "'Inter', sans-serif",
|
|
211
|
+
fontSize: "15px"
|
|
212
|
+
}}
|
|
213
|
+
/>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
All theme values map to scoped CSS custom properties (`--oue-*`) applied inline on the editor container. This means multiple editors on the same page can have different themes without conflicting.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Editor Height
|
|
221
|
+
|
|
222
|
+
By default, the editor grows with its content. To constrain the height and enable scrolling within the content area, pass a `height` prop. The toolbar remains pinned at the top while the content area scrolls independently.
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
{/* Fixed pixel height */}
|
|
226
|
+
<Editor height={400} />
|
|
227
|
+
|
|
228
|
+
{/* CSS string value */}
|
|
229
|
+
<Editor height="50vh" />
|
|
230
|
+
|
|
231
|
+
{/* Minimum height with auto-grow */}
|
|
232
|
+
<Editor minHeight={200} />
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Both `height` and `minHeight` accept numbers (interpreted as pixels) or any valid CSS length string.
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Bubble Toolbar
|
|
240
|
+
|
|
241
|
+
A contextual toolbar that appears above selected text. Configure the items it shows:
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
<Editor bubbleToolbar={["bold", "italic", "underline", "strike", "link"]} />
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Disable it entirely:
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
<Editor bubbleToolbar={false} />
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## HTML Source Mode
|
|
256
|
+
|
|
257
|
+
Toggle between the visual editor and raw HTML source:
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
<Editor sourceMode />
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
The `sourceMode` toolbar button can also be included in the toolbar config to let users switch at runtime. Changes in either view stay in sync.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Images and File Uploads
|
|
268
|
+
|
|
269
|
+
Images can be inserted via URL or through a custom upload handler. The upload handler receives a `File` object and must return a Promise resolving to `{ src, alt?, width?, height? }`.
|
|
270
|
+
|
|
271
|
+
```tsx
|
|
272
|
+
import { Editor, ImageExtension } from "oneuxi-editor"
|
|
273
|
+
|
|
274
|
+
const imageExtension = ImageExtension.configure({
|
|
275
|
+
upload: async (file: File) => {
|
|
276
|
+
const form = new FormData()
|
|
277
|
+
form.append("file", file)
|
|
278
|
+
const res = await fetch("/api/upload", { method: "POST", body: form })
|
|
279
|
+
const data = await res.json()
|
|
280
|
+
return { src: data.url, alt: file.name }
|
|
281
|
+
},
|
|
282
|
+
maxSize: 5 * 1024 * 1024,
|
|
283
|
+
allowedTypes: ["image/jpeg", "image/png", "image/webp", "image/gif"]
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
<Editor extensions={[imageExtension]} />
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Tables
|
|
292
|
+
|
|
293
|
+
Insert and edit HTML tables. Cells support all standard formatting (bold, links, lists).
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
import { Editor } from "oneuxi-editor"
|
|
297
|
+
|
|
298
|
+
{/* Tables are included in the default editor — use the toolbar button */}
|
|
299
|
+
<Editor toolbar={["table"]} />
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Code Blocks
|
|
305
|
+
|
|
306
|
+
Syntax-highlighted code blocks are included out of the box. Use the `codeBlock` toolbar item to insert one, or type a fenced code block in source mode.
|
|
307
|
+
|
|
308
|
+
```tsx
|
|
309
|
+
<Editor toolbar={["codeBlock"]} />
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Mentions
|
|
315
|
+
|
|
316
|
+
Trigger user mentions with `@`. Provide a search function that returns a list of users.
|
|
317
|
+
|
|
318
|
+
```tsx
|
|
319
|
+
import { Editor, MentionExtension } from "oneuxi-editor"
|
|
320
|
+
|
|
321
|
+
const mentionExt = MentionExtension.configure({
|
|
322
|
+
trigger: "@",
|
|
323
|
+
search: async (query: string) => {
|
|
324
|
+
const res = await fetch(`/api/users?q=${query}`)
|
|
325
|
+
return res.json() // [{ id, name, username, avatar? }]
|
|
326
|
+
}
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
<Editor extensions={[mentionExt]} />
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Slash Commands
|
|
335
|
+
|
|
336
|
+
Type `/` to open a command menu. Register custom commands or use the built-in set.
|
|
337
|
+
|
|
338
|
+
```tsx
|
|
339
|
+
import { Editor, SlashCommandExtension } from "oneuxi-editor"
|
|
340
|
+
|
|
341
|
+
<Editor extensions={[SlashCommandExtension]} />
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Paste Cleanup
|
|
347
|
+
|
|
348
|
+
Pasting from external office suites or rich document sources is handled automatically. The editor strips proprietary markup (`MsoNormal`, `mso-*`, inline styled wrapper spans) while preserving the semantic structure: headings, lists, bold, italic, links, and tables come through intact.
|
|
349
|
+
|
|
350
|
+
No configuration is required. Paste cleanup runs silently on every paste event.
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## Security and Sanitization
|
|
355
|
+
|
|
356
|
+
All HTML imported or pasted into the editor is sanitized by DOMPurify before parsing. The following are blocked unconditionally:
|
|
357
|
+
|
|
358
|
+
- `<script>` tags and inline event handlers (`onerror`, `onload`, etc.)
|
|
359
|
+
- `javascript:` URLs in `<a href>` attributes
|
|
360
|
+
- `<iframe>`, `<object>`, `<embed>`, and similar embeds
|
|
361
|
+
|
|
362
|
+
You can extend or restrict the allowed tag set via the `html` prop:
|
|
363
|
+
|
|
364
|
+
```tsx
|
|
365
|
+
<Editor
|
|
366
|
+
html={{
|
|
367
|
+
allowedTags: ["p", "strong", "em", "a", "ul", "ol", "li", "h1", "h2", "h3"],
|
|
368
|
+
allowedAttributes: {
|
|
369
|
+
"a": ["href", "target", "rel"]
|
|
370
|
+
}
|
|
371
|
+
}}
|
|
372
|
+
/>
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## SSR and Next.js
|
|
378
|
+
|
|
379
|
+
The editor is SSR-safe. It does not access `window`, `document`, or the DOM at module import time. System theme detection uses `useSyncExternalStore` with a stable server snapshot to prevent hydration mismatches in Next.js App Router and Pages Router.
|
|
380
|
+
|
|
381
|
+
No dynamic import wrappers or `ssr: false` configuration is needed.
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## Imperative API
|
|
386
|
+
|
|
387
|
+
Use a `ref` to call editor methods programmatically from outside the component.
|
|
388
|
+
|
|
389
|
+
```tsx
|
|
390
|
+
import { useRef } from "react"
|
|
391
|
+
import { Editor } from "oneuxi-editor"
|
|
392
|
+
import type { EditorRef } from "oneuxi-editor"
|
|
393
|
+
|
|
394
|
+
function MyPage() {
|
|
395
|
+
const editorRef = useRef<EditorRef>(null)
|
|
396
|
+
|
|
397
|
+
return (
|
|
398
|
+
<>
|
|
399
|
+
<Editor ref={editorRef} />
|
|
400
|
+
<button onClick={() => editorRef.current?.clear()}>Clear</button>
|
|
401
|
+
<button onClick={() => console.log(editorRef.current?.getHTML())}>
|
|
402
|
+
Get HTML
|
|
403
|
+
</button>
|
|
404
|
+
</>
|
|
405
|
+
)
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Available methods:
|
|
410
|
+
|
|
411
|
+
| Method | Description |
|
|
412
|
+
|--------|-------------|
|
|
413
|
+
| `focus()` | Focus the editor |
|
|
414
|
+
| `blur()` | Remove focus from the editor |
|
|
415
|
+
| `clear()` | Clear all content |
|
|
416
|
+
| `getHTML()` | Return current content as HTML string |
|
|
417
|
+
| `setHTML(html)` | Replace content with the provided HTML |
|
|
418
|
+
| `getText()` | Return plain text content |
|
|
419
|
+
| `getJSON()` | Return Lexical editor state as a JSON object |
|
|
420
|
+
| `setJSON(json)` | Replace content from a Lexical state object |
|
|
421
|
+
| `isEmpty()` | Return true if the editor has no content |
|
|
422
|
+
| `isDirty()` | Return true if content has changed since last clean mark |
|
|
423
|
+
| `markClean()` | Reset the dirty state |
|
|
424
|
+
| `undo()` | Undo the last change |
|
|
425
|
+
| `redo()` | Redo the last undone change |
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
## Props Reference
|
|
430
|
+
|
|
431
|
+
| Prop | Type | Default | Description |
|
|
432
|
+
|------|------|---------|-------------|
|
|
433
|
+
| `value` | `string` | — | Controlled HTML content |
|
|
434
|
+
| `defaultValue` | `string` | — | Initial uncontrolled content |
|
|
435
|
+
| `output` | `"html" \| "json" \| "text"` | `"html"` | Format of onChange output |
|
|
436
|
+
| `placeholder` | `string` | `"Start writing..."` | Placeholder text |
|
|
437
|
+
| `readOnly` | `boolean` | `false` | Disable all editing |
|
|
438
|
+
| `disabled` | `boolean` | `false` | Disable and apply disabled styling |
|
|
439
|
+
| `theme` | `"light" \| "dark" \| "system" \| ThemeObject` | `"system"` | Editor color theme |
|
|
440
|
+
| `height` | `string \| number` | — | Fixed editor height; enables scrolling |
|
|
441
|
+
| `minHeight` | `string \| number` | — | Minimum editor height |
|
|
442
|
+
| `toolbar` | `ToolbarItem[] \| false` | default set | Toolbar items or false to hide |
|
|
443
|
+
| `bubbleToolbar` | `ToolbarItem[] \| false` | default set | Bubble toolbar items |
|
|
444
|
+
| `sourceMode` | `boolean` | `false` | Start in HTML source mode |
|
|
445
|
+
| `fullscreen` | `boolean` | `false` | Start in fullscreen mode |
|
|
446
|
+
| `characterCount` | `boolean` | `false` | Show character count in footer |
|
|
447
|
+
| `wordCount` | `boolean` | `false` | Show word count in footer |
|
|
448
|
+
| `maxLength` | `number` | — | Maximum character limit |
|
|
449
|
+
| `extensions` | `EditorExtension[]` | — | Custom or built-in extensions |
|
|
450
|
+
| `preset` | `"basic" \| "full"` | — | Load a predefined extension set |
|
|
451
|
+
| `html` | `HTMLPolicy` | — | DOMPurify allow-list configuration |
|
|
452
|
+
| `autosave` | `AutosaveConfig` | — | Autosave callback and debounce delay |
|
|
453
|
+
| `icons` | `CustomIconMap` | — | Override default toolbar icons |
|
|
454
|
+
| `onChange` | `(output: string) => void` | — | Fires on every content change |
|
|
455
|
+
| `onUpdate` | `(update: EditorUpdate) => void` | — | Full update object with html, text, json |
|
|
456
|
+
| `onError` | `(error: Error) => void` | — | Lexical runtime error handler |
|
|
457
|
+
| `onDirtyChange` | `(isDirty: boolean) => void` | — | Fires when dirty state changes |
|
|
458
|
+
| `onCharacterCountChange` | `(count: number) => void` | — | Fires on character count change |
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## Accessibility
|
|
463
|
+
|
|
464
|
+
The toolbar renders with `role="toolbar"` and `aria-label` attributes on every control. Interactive elements have unique, descriptive `aria-label` values for screen reader compatibility. Keyboard navigation within the editor follows standard `contenteditable` conventions.
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
## Browser Support
|
|
469
|
+
|
|
470
|
+
The editor targets the last two stable releases of:
|
|
471
|
+
|
|
472
|
+
- Chrome and Edge
|
|
473
|
+
- Firefox
|
|
474
|
+
- Safari
|
|
475
|
+
- Mobile Chrome and Safari
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## Bundle Size
|
|
480
|
+
|
|
481
|
+
The editor ships as separate ESM and CJS builds with full source maps. Lexical itself is a peer dependency and is not included in these figures.
|
|
482
|
+
|
|
483
|
+
| Output | Raw | Gzipped |
|
|
484
|
+
|--------|-----|---------|
|
|
485
|
+
| ESM (`index.mjs`) | 75.9 KB | 15.2 KB |
|
|
486
|
+
| CJS (`index.js`) | 85.0 KB | 15.8 KB |
|
|
487
|
+
| CSS (`styles.css`) | 10.0 KB | 2.4 KB |
|
|
488
|
+
|
|
489
|
+
Extensions that are not imported are not included in your production bundle.
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
## AI Features — Coming Soon
|
|
494
|
+
|
|
495
|
+
The next phase of `oneuxi-editor` introduces a set of AI-assisted writing capabilities designed to integrate directly into the editing experience. These features will work with any OpenAI-compatible API endpoint and will require no changes to your existing editor integration.
|
|
496
|
+
|
|
497
|
+
Planned capabilities include:
|
|
498
|
+
|
|
499
|
+
**Inline completions** — The editor will offer sentence and paragraph completions as you type, accepting them with a single key.
|
|
500
|
+
|
|
501
|
+
**Selection-based actions** — Selecting text will expose actions to rephrase, expand, summarize, simplify, or change tone, inline without opening a separate panel.
|
|
502
|
+
|
|
503
|
+
**Content generation** — A prompt bar for generating drafts, outlines, and structured content from a short description.
|
|
504
|
+
|
|
505
|
+
**Grammar and clarity suggestions** — Passive, non-intrusive suggestions that highlight improvements without interrupting the writing flow.
|
|
506
|
+
|
|
507
|
+
**Custom AI commands** — Register your own AI actions tied to your backend, using the same extension API as other oneuxi-editor features.
|
|
508
|
+
|
|
509
|
+
The AI module will be optional and tree-shakeable. It will not add to your bundle size unless explicitly imported.
|
|
510
|
+
|
|
511
|
+
---
|
|
512
|
+
|
|
513
|
+
## Community & Support
|
|
514
|
+
|
|
515
|
+
Join our Telegram channel for updates, discussions, and support: [https://t.me/thedebuglab](https://t.me/thedebuglab)
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## License
|
|
520
|
+
|
|
521
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oneuxi-editor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A production-ready, lightweight, modular rich text and HTML editor for React applications built on Lexical",
|
|
5
5
|
"author": "thedebuglab",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
"./styles.css": "./dist/styles.css"
|
|
40
40
|
},
|
|
41
41
|
"files": [
|
|
42
|
-
"dist"
|
|
42
|
+
"dist",
|
|
43
|
+
"README.md"
|
|
43
44
|
],
|
|
44
45
|
"scripts": {
|
|
45
46
|
"build": "tsup",
|
|
@@ -49,7 +50,10 @@
|
|
|
49
50
|
"test:watch": "vitest",
|
|
50
51
|
"test:e2e": "playwright test",
|
|
51
52
|
"prepublishOnly": "npm run build && npm run typecheck && npm run test",
|
|
52
|
-
"release": "npm publish --access public"
|
|
53
|
+
"release": "npm publish --access public",
|
|
54
|
+
"release:patch": "npm version patch && npm publish --access public",
|
|
55
|
+
"release:minor": "npm version minor && npm publish --access public",
|
|
56
|
+
"release:major": "npm version major && npm publish --access public"
|
|
53
57
|
},
|
|
54
58
|
"peerDependencies": {
|
|
55
59
|
"react": "^18.0.0 || ^19.0.0",
|