@overlap/rte 0.1.9 → 0.1.10

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.
Files changed (2) hide show
  1. package/README.md +409 -181
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @overlap/rte
2
2
 
3
- A lightweight, extensible Rich Text Editor for React.
3
+ A lightweight, extensible Rich Text Editor for React -- zero extra dependencies beyond React itself.
4
4
 
5
5
  ## Installation
6
6
 
@@ -10,266 +10,494 @@ npm install @overlap/rte
10
10
 
11
11
  ## Features
12
12
 
13
- - **Lightweight**: Minimal dependencies (React only)
14
- - **Extensible**: Simple plugin system
15
- - **Contenteditable-based**: Uses native browser functionality
16
- - **Undo/Redo**: Full history support
17
- - **JSON data model**: Structured export/import
18
- - **TypeScript**: Fully typed
19
- - **Vite & Deno compatible**: ESM module support
20
-
21
- ## Basic Usage
13
+ - **Lightweight** -- only peer-depends on React, no heavy framework
14
+ - **Plugin system** -- compose exactly the toolbar you need
15
+ - **Settings object** -- configure features with a single object instead of assembling plugins manually
16
+ - **Contenteditable-based** -- uses native browser editing for performance
17
+ - **Full formatting** -- bold, italic, underline, strikethrough, subscript, superscript, inline code
18
+ - **Block formats** -- headings (h1-h6), bullet lists, numbered lists, checkbox lists, blockquote, code block
19
+ - **Tables** -- insert, row/column operations, context menu
20
+ - **Images** -- upload via callback, URL insert, drag & drop, paste
21
+ - **Links** -- floating editor, advanced attributes, custom fields
22
+ - **Colors** -- text color and background color pickers
23
+ - **Font sizes** -- configurable size dropdown
24
+ - **Alignment** -- left, center, right, justify
25
+ - **Indent / Outdent** -- nested list support via Tab / Shift+Tab
26
+ - **Undo / Redo** -- full history management
27
+ - **HTML import/export** -- `htmlToContent()` and `contentToHTML()`
28
+ - **Theming** -- CSS variables + theme prop for brand colors
29
+ - **Lexical compatible** -- correctly parses and renders HTML generated by Lexical editors
30
+ - **TypeScript** -- fully typed, ships `.d.ts`
31
+
32
+ ## Quick Start
22
33
 
23
34
  ```tsx
24
- import React, { useState } from "react";
25
35
  import { Editor, EditorContent } from "@overlap/rte";
26
- import "@overlap/rte/dist/styles.css"; // CSS importieren
36
+ import "@overlap/rte/dist/styles.css";
27
37
 
28
38
  function App() {
29
- const [content, setContent] = useState<EditorContent | undefined>();
39
+ const [content, setContent] = useState<EditorContent>();
30
40
 
31
41
  return (
32
42
  <Editor
33
43
  initialContent={content}
34
- onChange={(newContent) => {
35
- setContent(newContent);
36
- console.log("Content:", newContent);
37
- }}
38
- placeholder="Text eingeben..."
44
+ onChange={setContent}
45
+ placeholder="Enter text..."
39
46
  />
40
47
  );
41
48
  }
42
49
  ```
43
50
 
44
- **Note:** The CSS must be imported separately. Import it with `import '@overlap/rte/dist/styles.css'`.
51
+ > **Note:** Always import the CSS: `import '@overlap/rte/dist/styles.css'`
45
52
 
46
- ## With Custom Plugins
53
+ ---
47
54
 
48
- ```tsx
49
- import React from "react";
50
- import { Editor, Plugin, EditorAPI, ButtonProps } from "@overlap/rte";
55
+ ## Settings-Based Configuration
51
56
 
52
- // Create custom plugin
53
- const customPlugin: Plugin = {
54
- name: "custom",
55
- type: "inline",
56
- command: "bold", // or custom logic
57
- renderButton: (props: ButtonProps) => (
58
- <button
59
- onClick={props.onClick}
60
- className={`toolbar-button ${props.isActive ? "active" : ""}`}
61
- >
62
- {/* Or use SVG icons */}
63
- </button>
64
- ),
65
- execute: (editor: EditorAPI) => {
66
- editor.executeCommand("bold");
57
+ Instead of assembling plugins manually, pass a **settings object** to control which features are enabled. This is the recommended approach for most use cases.
58
+
59
+ ```tsx
60
+ import { Editor, EditorSettings, buildPluginsFromSettings } from "@overlap/rte";
61
+ import "@overlap/rte/dist/styles.css";
62
+
63
+ const settings: EditorSettings = {
64
+ format: {
65
+ bold: true,
66
+ italic: true,
67
+ underline: true,
68
+ strikethrough: true,
69
+ code: false,
70
+ subscript: true,
71
+ superscript: true,
72
+ bulletList: true,
73
+ numberedList: true,
74
+ quote: true,
75
+ codeBlock: false,
76
+ check: true,
77
+ typography: ["h1", "h2", "h3"],
78
+ colors: ["#000", "#ff0000", "#00aa00", "#0000ff"],
79
+ fontSize: true,
80
+ alignment: ["left", "center", "right", "justify", "indent", "outdent"],
81
+ },
82
+ link: {
83
+ external: true,
84
+ internal: true,
67
85
  },
68
- isActive: (editor: EditorAPI) => {
69
- return document.queryCommandState("bold");
86
+ table: {
87
+ enabled: true,
88
+ },
89
+ image: {
90
+ enabled: true,
70
91
  },
71
92
  };
72
93
 
73
94
  function App() {
74
- return (
75
- <Editor
76
- plugins={[customPlugin]}
77
- onChange={(content) => console.log(content)}
78
- />
79
- );
95
+ // Option A: Let the Editor build plugins from settings automatically
96
+ return <Editor settings={settings} onImageUpload={handleUpload} />;
97
+
98
+ // Option B: Build plugins yourself for more control
99
+ const plugins = buildPluginsFromSettings(settings, {
100
+ onImageUpload: handleUpload,
101
+ linkCustomFields: [
102
+ {
103
+ key: "urlExtra",
104
+ label: "Anchor / Params",
105
+ placeholder: "?param=value or #anchor",
106
+ dataAttribute: "data-url-extra",
107
+ appendToHref: true,
108
+ },
109
+ ],
110
+ });
111
+ return <Editor plugins={plugins} />;
112
+ }
113
+ ```
114
+
115
+ ### EditorSettings Interface
116
+
117
+ ```typescript
118
+ interface EditorSettings {
119
+ format?: {
120
+ bold?: boolean;
121
+ italic?: boolean;
122
+ underline?: boolean;
123
+ strikethrough?: boolean;
124
+ code?: boolean; // inline code
125
+ subscript?: boolean;
126
+ superscript?: boolean;
127
+ bulletList?: boolean;
128
+ numberedList?: boolean;
129
+ quote?: boolean;
130
+ codeBlock?: boolean;
131
+ check?: boolean; // checkbox lists
132
+ typography?: string[]; // e.g. ["h1", "h2", "h3"]
133
+ colors?: string[]; // e.g. ["#000", "#ff0000"]
134
+ fontSize?: boolean;
135
+ alignment?: string[]; // e.g. ["left", "center", "right", "justify", "indent", "outdent"]
136
+ };
137
+ link?: {
138
+ external?: boolean;
139
+ internal?: boolean;
140
+ };
141
+ table?: {
142
+ enabled?: boolean;
143
+ };
144
+ image?: {
145
+ enabled?: boolean;
146
+ };
80
147
  }
81
148
  ```
82
149
 
83
- ## With Optional Plugins
150
+ By default, **everything is enabled** (`defaultEditorSettings`). Disable features by setting them to `false` or removing values from arrays.
151
+
152
+ ---
153
+
154
+ ## Manual Plugin Composition
155
+
156
+ For full control, assemble plugins yourself:
84
157
 
85
158
  ```tsx
86
- import React from "react";
87
- import { Editor, defaultPlugins, linkPlugin } from "@overlap/rte";
159
+ import {
160
+ Editor,
161
+ boldPlugin,
162
+ italicPlugin,
163
+ underlinePlugin,
164
+ strikethroughPlugin,
165
+ subscriptPlugin,
166
+ superscriptPlugin,
167
+ codeInlinePlugin,
168
+ undoPlugin,
169
+ redoPlugin,
170
+ clearFormattingPlugin,
171
+ indentListItemPlugin,
172
+ outdentListItemPlugin,
173
+ createBlockFormatPlugin,
174
+ createTextColorPlugin,
175
+ createBackgroundColorPlugin,
176
+ createFontSizePlugin,
177
+ createAlignmentPlugin,
178
+ createAdvancedLinkPlugin,
179
+ createImagePlugin,
180
+ tablePlugin,
181
+ } from "@overlap/rte";
182
+
183
+ const plugins = [
184
+ undoPlugin,
185
+ redoPlugin,
186
+ createBlockFormatPlugin(["h1", "h2", "h3"], {
187
+ bulletList: true,
188
+ numberedList: true,
189
+ quote: true,
190
+ check: true,
191
+ codeBlock: false,
192
+ }),
193
+ boldPlugin,
194
+ italicPlugin,
195
+ underlinePlugin,
196
+ strikethroughPlugin,
197
+ createAdvancedLinkPlugin({ enableTarget: true }),
198
+ createTextColorPlugin(["#000", "#ff0000", "#00aa00", "#0000ff"]),
199
+ createBackgroundColorPlugin(["#ffff00", "#00ff00", "#ff00ff"]),
200
+ createFontSizePlugin([12, 14, 16, 18, 20, 24, 28, 32]),
201
+ createAlignmentPlugin(["left", "center", "right", "justify"]),
202
+ tablePlugin,
203
+ createImagePlugin(handleUpload),
204
+ subscriptPlugin,
205
+ superscriptPlugin,
206
+ codeInlinePlugin,
207
+ clearFormattingPlugin,
208
+ indentListItemPlugin,
209
+ outdentListItemPlugin,
210
+ ];
88
211
 
89
212
  function App() {
90
- const allPlugins = [...defaultPlugins, linkPlugin];
91
-
92
- return (
93
- <Editor
94
- plugins={allPlugins}
95
- onChange={(content) => console.log(content)}
96
- />
97
- );
213
+ return <Editor plugins={plugins} onChange={console.log} />;
98
214
  }
99
215
  ```
100
216
 
101
- **Note:** The `defaultPlugins` already include block formatting (headings, lists, blockquote) in a single dropdown. You can customize which headings are available using the `headings` prop:
217
+ ---
218
+
219
+ ## Advanced Link Plugin
220
+
221
+ The link plugin supports a floating editor with advanced attributes and extensible custom fields:
102
222
 
103
223
  ```tsx
104
- <Editor
105
- headings={["h1", "h2", "h3", "h4"]} // Customize available headings
106
- plugins={allPlugins}
107
- onChange={(content) => console.log(content)}
108
- />
224
+ import { createAdvancedLinkPlugin, LinkCustomField } from "@overlap/rte";
225
+
226
+ const linkPlugin = createAdvancedLinkPlugin({
227
+ enableTarget: true, // show "Open in new tab" checkbox
228
+ customFields: [
229
+ {
230
+ key: "urlExtra",
231
+ label: "Anchor / Params",
232
+ placeholder: "?param=value or #anchor",
233
+ dataAttribute: "data-url-extra",
234
+ appendToHref: true,
235
+ },
236
+ {
237
+ key: "pageRef",
238
+ label: "Page Reference",
239
+ placeholder: "Select a page...",
240
+ dataAttribute: "data-page-ref",
241
+ disablesUrl: true,
242
+ },
243
+ ],
244
+ });
109
245
  ```
110
246
 
111
- ## API
247
+ ### LinkCustomField
112
248
 
113
- ### Editor Props
249
+ | Property | Type | Description |
250
+ | --- | --- | --- |
251
+ | `key` | `string` | Unique identifier |
252
+ | `label` | `string` | Input label text |
253
+ | `placeholder` | `string?` | Input placeholder |
254
+ | `dataAttribute` | `string` | HTML data attribute stored on the `<a>` tag |
255
+ | `appendToHref` | `boolean?` | If true, value is appended to the `href` |
256
+ | `disablesUrl` | `boolean?` | If true, hides the URL field when this field has a value |
114
257
 
115
- | Prop | Type | Description |
116
- | ------------------ | ----------------------------------- | ------------------------------------------------------ |
117
- | `initialContent` | `EditorContent?` | Initial editor content |
118
- | `onChange` | `(content: EditorContent) => void?` | Callback on changes |
119
- | `plugins` | `Plugin[]?` | Array of plugins (default: defaultPlugins) |
120
- | `headings` | `string[]?` | Available heading levels (default: ["h1", "h2", "h3"]) |
121
- | `placeholder` | `string?` | Placeholder text |
122
- | `className` | `string?` | CSS class for container |
123
- | `toolbarClassName` | `string?` | CSS class for toolbar |
124
- | `editorClassName` | `string?` | CSS class for editor |
125
- | `onImageUpload` | `(file: File) => Promise<string>?` | Callback for image uploads |
258
+ ---
126
259
 
127
- ### EditorContent
260
+ ## Image Upload
128
261
 
129
- ```typescript
130
- interface EditorContent {
131
- blocks: EditorNode[];
262
+ ```tsx
263
+ import { Editor, createImagePlugin } from "@overlap/rte";
264
+
265
+ async function handleUpload(file: File): Promise<string> {
266
+ const formData = new FormData();
267
+ formData.append("file", file);
268
+ const res = await fetch("/api/upload", { method: "POST", body: formData });
269
+ const { url } = await res.json();
270
+ return url;
132
271
  }
133
272
 
134
- interface EditorNode {
135
- type: string;
136
- children?: EditorNode[];
137
- text?: string;
138
- attributes?: Record<string, string>;
139
- }
273
+ // Via settings:
274
+ <Editor settings={{ image: { enabled: true } }} onImageUpload={handleUpload} />
275
+
276
+ // Via plugin:
277
+ <Editor plugins={[...otherPlugins, createImagePlugin(handleUpload)]} />
140
278
  ```
141
279
 
142
- ### EditorAPI
280
+ Images can be inserted by:
281
+ - Clicking the toolbar button (file picker or URL input)
282
+ - Pasting an image from the clipboard
283
+ - Dragging and dropping an image file
143
284
 
144
- The EditorAPI is passed to plugins and provides the following methods:
285
+ ---
145
286
 
146
- - `executeCommand(command: string, value?: string): boolean` - Executes a command
147
- - `getSelection(): Selection | null` - Returns the current selection
148
- - `getContent(): EditorContent` - Returns the current content
149
- - `setContent(content: EditorContent): void` - Sets the content
150
- - `insertBlock(type: string, attributes?: Record<string, string>): void` - Inserts a block
151
- - `insertInline(type: string, attributes?: Record<string, string>): void` - Inserts an inline element
152
- - `undo(): void` - Undoes the last action
153
- - `redo(): void` - Redoes the last action
154
- - `canUndo(): boolean` - Checks if undo is possible
155
- - `canRedo(): boolean` - Checks if redo is possible
156
- - `indentListItem(): void` - Indents a list item (creates sub-list)
157
- - `outdentListItem(): void` - Outdents a list item
287
+ ## Tables
158
288
 
159
- ### Plugin Interface
289
+ ```tsx
290
+ import { Editor, tablePlugin } from "@overlap/rte";
160
291
 
161
- ```typescript
162
- interface Plugin {
163
- name: string;
164
- type: "inline" | "block" | "command";
165
- command?: string;
166
- renderButton?: (props: ButtonProps) => React.ReactElement;
167
- execute?: (editor: EditorAPI) => void;
168
- isActive?: (editor: EditorAPI) => boolean;
169
- canExecute?: (editor: EditorAPI) => boolean;
170
- }
292
+ // Via settings:
293
+ <Editor settings={{ table: { enabled: true } }} />
294
+
295
+ // Via plugin:
296
+ <Editor plugins={[...otherPlugins, tablePlugin]} />
171
297
  ```
172
298
 
173
- ## Default Plugins
299
+ Right-click a table cell to access the context menu with row/column operations.
174
300
 
175
- The `defaultPlugins` include:
301
+ ---
176
302
 
177
- - **Bold, Italic, Underline** - Text formatting
178
- - **Undo/Redo** - History management
179
- - **Block Format Dropdown** - Headings (h1-h3 by default), Lists (ul, ol), Blockquote
180
- - **Clear Formatting** - Remove all formatting
181
- - **Indent/Outdent** - List indentation (Tab/Shift+Tab)
303
+ ## Theming
182
304
 
183
- ## Optional Plugins
305
+ ### CSS Variables
184
306
 
185
- - `linkPlugin` - Insert and edit links
186
- - `createFontSizePlugin` - Font size selector
187
- - `createColorPlugin` - Text color picker
188
- - `createBackgroundColorPlugin` - Background color picker
189
- - `createImagePlugin` - Image upload
190
- - `createHeadingsPlugin` - Custom heading levels (if not using default block format)
307
+ Override CSS variables on `.rte-container` or a parent element:
191
308
 
192
- ## Creating Plugins
309
+ ```css
310
+ .my-editor {
311
+ --rte-primary-color: #339192;
312
+ --rte-primary-light: rgba(51, 145, 146, 0.15);
313
+ --rte-border-color: #e0e0e0;
314
+ --rte-toolbar-bg: #fafafa;
315
+ --rte-content-bg: #ffffff;
316
+ --rte-button-hover-bg: rgba(51, 145, 146, 0.08);
317
+ --rte-border-radius: 8px;
318
+ }
319
+ ```
193
320
 
194
- ### Example: Simple Inline Plugin
321
+ ### Theme Prop
195
322
 
196
- ```typescript
197
- import { Plugin, EditorAPI, ButtonProps } from "@overlap/rte";
198
- import { createInlinePlugin } from "@overlap/rte";
199
-
200
- const myPlugin = createInlinePlugin(
201
- "myPlugin",
202
- "bold", // Command
203
- "mdi:format-bold", // Icon name (rendered internally as SVG)
204
- "My Plugin" // Label
205
- );
323
+ ```tsx
324
+ <Editor
325
+ theme={{
326
+ primaryColor: "#339192",
327
+ borderColor: "#e0e0e0",
328
+ borderRadius: 8,
329
+ toolbarBg: "#fafafa",
330
+ contentBg: "#ffffff",
331
+ buttonHoverBg: "rgba(51, 145, 146, 0.08)",
332
+ }}
333
+ />
334
+ ```
335
+
336
+ ### CSS Class Overrides
337
+
338
+ ```css
339
+ .rte-container { /* outer wrapper */ }
340
+ .rte-toolbar { /* toolbar row */ }
341
+ .rte-toolbar-button { /* individual toolbar button */ }
342
+ .rte-toolbar-button-active { /* active state */ }
343
+ .rte-editor { /* contenteditable area */ }
206
344
  ```
207
345
 
208
- **Note:** Icons are rendered internally as SVG. You can also use your own SVG icons in your plugins.
346
+ ---
347
+
348
+ ## HTML Import / Export
349
+
350
+ ```tsx
351
+ import { htmlToContent, contentToHTML, EditorAPI } from "@overlap/rte";
352
+
353
+ // Import HTML into the editor
354
+ const content = htmlToContent("<p>Hello <strong>world</strong></p>");
355
+ <Editor initialContent={content} />
209
356
 
210
- ### Example: Complex Plugin
357
+ // Export HTML from the editor
358
+ function MyEditor() {
359
+ const apiRef = useRef<EditorAPI>(null);
360
+
361
+ return (
362
+ <Editor
363
+ onEditorAPIReady={(api) => { apiRef.current = api; }}
364
+ onChange={() => {
365
+ const html = apiRef.current?.exportHtml();
366
+ console.log(html);
367
+ }}
368
+ />
369
+ );
370
+ }
371
+ ```
372
+
373
+ ---
374
+
375
+ ## Editor Props
376
+
377
+ | Prop | Type | Description |
378
+ | --- | --- | --- |
379
+ | `initialContent` | `EditorContent?` | Initial editor content (JSON) |
380
+ | `onChange` | `(content: EditorContent) => void` | Called on every content change |
381
+ | `plugins` | `Plugin[]?` | Manual plugin array (overrides settings) |
382
+ | `settings` | `EditorSettings?` | Settings object to auto-build plugins |
383
+ | `settingsOptions` | `BuildPluginsOptions?` | Extra options when using settings (e.g. `onImageUpload`, `linkCustomFields`) |
384
+ | `placeholder` | `string?` | Placeholder text (default: `"Enter text..."`) |
385
+ | `className` | `string?` | CSS class for the outer container |
386
+ | `toolbarClassName` | `string?` | CSS class for the toolbar |
387
+ | `editorClassName` | `string?` | CSS class for the editor area |
388
+ | `headings` | `string[]?` | Heading levels when using default plugins |
389
+ | `fontSizes` | `number[]?` | Font sizes when using default plugins |
390
+ | `colors` | `string[]?` | Color palette when using default plugins |
391
+ | `onImageUpload` | `(file: File) => Promise<string>` | Image upload callback |
392
+ | `onEditorAPIReady` | `(api: EditorAPI) => void` | Callback when editor API is ready |
393
+ | `theme` | `object?` | Theme overrides (see Theming section) |
394
+
395
+ ---
396
+
397
+ ## EditorAPI
398
+
399
+ Available via `onEditorAPIReady` callback or passed to plugin functions:
400
+
401
+ | Method | Description |
402
+ | --- | --- |
403
+ | `executeCommand(cmd, value?)` | Execute a `document.execCommand` |
404
+ | `getSelection()` | Get the current `Selection` |
405
+ | `getContent()` | Get content as `EditorContent` JSON |
406
+ | `setContent(content)` | Set content from `EditorContent` JSON |
407
+ | `exportHtml()` | Export current content as HTML string |
408
+ | `importHtml(html)` | Import HTML string into the editor |
409
+ | `insertBlock(type, attrs?)` | Insert a block element |
410
+ | `insertInline(type, attrs?)` | Insert an inline element |
411
+ | `undo()` / `redo()` | History navigation |
412
+ | `canUndo()` / `canRedo()` | Check history state |
413
+ | `indentListItem()` | Indent the current list item |
414
+ | `outdentListItem()` | Outdent the current list item |
415
+ | `clearFormatting()` | Remove all formatting from selection |
416
+ | `clearTextColor()` | Remove text color |
417
+ | `clearBackgroundColor()` | Remove background color |
418
+ | `clearFontSize()` | Remove font size |
419
+ | `clearLinks()` | Remove links (keep text) |
420
+
421
+ ---
422
+
423
+ ## Creating Custom Plugins
211
424
 
212
425
  ```typescript
213
- const customPlugin: Plugin = {
214
- name: "custom",
215
- type: "block",
426
+ import { Plugin, EditorAPI, ButtonProps } from "@overlap/rte";
427
+
428
+ const highlightPlugin: Plugin = {
429
+ name: "highlight",
430
+ type: "inline",
216
431
  renderButton: (props: ButtonProps) => (
217
- <button onClick={props.onClick}>
218
- {/* Use SVG icons or emojis */}
219
- <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
220
- <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
221
- </svg>
432
+ <button
433
+ onClick={props.onClick}
434
+ className={`rte-toolbar-button ${props.isActive ? "rte-toolbar-button-active" : ""}`}
435
+ title="Highlight"
436
+ >
437
+ H
222
438
  </button>
223
439
  ),
224
440
  execute: (editor: EditorAPI) => {
225
- editor.insertBlock("div", { class: "custom-block" });
441
+ editor.executeCommand("backColor", "#ffff00");
226
442
  },
227
- isActive: (editor: EditorAPI) => {
228
- // Check if plugin is active
229
- return false;
230
- },
231
- canExecute: (editor: EditorAPI) => {
232
- // Check if plugin can be executed
233
- return true;
443
+ isActive: () => {
444
+ const sel = document.getSelection();
445
+ if (!sel || sel.rangeCount === 0) return false;
446
+ const el = sel.getRangeAt(0).commonAncestorContainer;
447
+ const parent = el.nodeType === Node.TEXT_NODE ? el.parentElement : el as HTMLElement;
448
+ return parent?.closest("[style*='background-color: rgb(255, 255, 0)']") !== null;
234
449
  },
450
+ canExecute: () => true,
235
451
  };
236
452
  ```
237
453
 
238
- ## Styling
454
+ ---
239
455
 
240
- The editor comes with minimal CSS. You can override the styles:
456
+ ## Exports Overview
241
457
 
242
- ```css
243
- .rte-container {
244
- /* Container styles */
245
- }
246
-
247
- .rte-toolbar {
248
- /* Toolbar styles */
249
- }
250
-
251
- .rte-toolbar-button {
252
- /* Button styles */
253
- }
254
-
255
- .rte-editor {
256
- /* Editor styles */
257
- }
458
+ ```typescript
459
+ // Components
460
+ export { Editor, Toolbar, Dropdown };
461
+
462
+ // Settings
463
+ export { EditorSettings, defaultEditorSettings, buildPluginsFromSettings, BuildPluginsOptions };
464
+
465
+ // Individual plugins
466
+ export { boldPlugin, italicPlugin, underlinePlugin, strikethroughPlugin };
467
+ export { subscriptPlugin, superscriptPlugin, codeInlinePlugin };
468
+ export { undoPlugin, redoPlugin, clearFormattingPlugin };
469
+ export { indentListItemPlugin, outdentListItemPlugin };
470
+ export { defaultPlugins };
471
+
472
+ // Plugin factories
473
+ export { createBlockFormatPlugin, BlockFormatOptions };
474
+ export { createTextColorPlugin, createBackgroundColorPlugin };
475
+ export { createFontSizePlugin };
476
+ export { createAlignmentPlugin };
477
+ export { createAdvancedLinkPlugin, LinkCustomField };
478
+ export { createImagePlugin };
479
+ export { tablePlugin };
480
+
481
+ // Utilities
482
+ export { htmlToContent, contentToHTML, contentToDOM, domToContent, createEmptyContent };
483
+ export { HistoryManager };
484
+
485
+ // Types
486
+ export { Plugin, EditorAPI, EditorContent, EditorNode, EditorProps, ButtonProps };
258
487
  ```
259
488
 
489
+ ---
490
+
260
491
  ## Development
261
492
 
262
493
  ```bash
263
- # Install dependencies
264
- npm install
265
-
266
- # Build
267
- npm run build
494
+ npm install # install dependencies
495
+ npm run build # production build
496
+ npm run dev # watch mode
268
497
 
269
- # Development with watch
270
- npm run dev
498
+ cd example && npm run dev # run the showcase app
271
499
  ```
272
500
 
273
- ## Lizenz
501
+ ## License
274
502
 
275
503
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@overlap/rte",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "A lightweight, extensible Rich Text Editor for React",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",