@flogeez/angular-tiptap-editor 0.3.3 → 0.3.5
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 +459 -459
- package/fesm2022/flogeez-angular-tiptap-editor.mjs +364 -384
- package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
- package/index.d.ts +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,459 +1,459 @@
|
|
|
1
|
-
# Angular Tiptap Editor
|
|
2
|
-
|
|
3
|
-
A modern, customizable rich-text editor for Angular applications, built with Tiptap and featuring complete internationalization support.
|
|
4
|
-
|
|
5
|
-
[](https://stackblitz.com/edit/angular-tiptap-editor)
|
|
6
|
-
|
|
7
|
-
## 🚀 Features
|
|
8
|
-
|
|
9
|
-
- **Modern Angular**: Built with Angular 18+ with Signals and modern patterns
|
|
10
|
-
- **Rich Text Editing**: Powered by Tiptap v3.3.0 with extensive formatting options
|
|
11
|
-
- **Table Support**: Full table management with bubble menus and cell selection
|
|
12
|
-
- **Slash Commands**: Intuitive slash commands for quick content insertion
|
|
13
|
-
- **Internationalization**: Full i18n support (English & French) with auto-detection
|
|
14
|
-
- **Customizable**: Highly configurable toolbar, bubble menus, and slash commands
|
|
15
|
-
- **Image Support**: Advanced image handling with resizing, compression, and bubble menus
|
|
16
|
-
- **Height Control**: Configurable editor height with scrolling
|
|
17
|
-
- **Word/Character Count**: Real-time word and character counting with proper pluralization
|
|
18
|
-
- **Office Paste**: Clean pasting from Microsoft Office applications
|
|
19
|
-
- **TypeScript**: Full TypeScript support with strict typing
|
|
20
|
-
- **Accessibility**: Built with accessibility best practices
|
|
21
|
-
- **Service Architecture**: Clean service-based architecture with `EditorCommandsService`
|
|
22
|
-
|
|
23
|
-
## 📦 Installation
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
npm install @flogeez/angular-tiptap-editor
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### CSS Styles
|
|
30
|
-
|
|
31
|
-
Add the required CSS to your `angular.json` file in the `styles` array:
|
|
32
|
-
|
|
33
|
-
```json
|
|
34
|
-
{
|
|
35
|
-
"styles": [
|
|
36
|
-
...
|
|
37
|
-
"node_modules/@fontsource/material-symbols-outlined/index.css",
|
|
38
|
-
"node_modules/@flogeez/angular-tiptap-editor/src/lib/styles/index.css",
|
|
39
|
-
...
|
|
40
|
-
]
|
|
41
|
-
}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## 🎯 Quick Start
|
|
45
|
-
|
|
46
|
-
### 1. Basic Usage
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
import { Component } from "@angular/core";
|
|
50
|
-
import { AngularTiptapEditorComponent } from "@flogeez/angular-tiptap-editor";
|
|
51
|
-
|
|
52
|
-
@Component({
|
|
53
|
-
selector: "app-example",
|
|
54
|
-
standalone: true,
|
|
55
|
-
imports: [AngularTiptapEditorComponent],
|
|
56
|
-
template: `
|
|
57
|
-
<angular-tiptap-editor
|
|
58
|
-
[content]="content"
|
|
59
|
-
(contentChange)="onContentChange($event)"
|
|
60
|
-
/>
|
|
61
|
-
`,
|
|
62
|
-
})
|
|
63
|
-
export class ExampleComponent {
|
|
64
|
-
content = "<p>Hello <strong>World</strong>!</p>";
|
|
65
|
-
|
|
66
|
-
onContentChange(newContent: string) {
|
|
67
|
-
this.content = newContent;
|
|
68
|
-
console.log("Content updated:", newContent);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### 2. With Custom Configuration
|
|
74
|
-
|
|
75
|
-
```typescript
|
|
76
|
-
import { Component } from "@angular/core";
|
|
77
|
-
import {
|
|
78
|
-
AngularTiptapEditorComponent,
|
|
79
|
-
DEFAULT_TOOLBAR_CONFIG,
|
|
80
|
-
DEFAULT_BUBBLE_MENU_CONFIG,
|
|
81
|
-
} from "@flogeez/angular-tiptap-editor";
|
|
82
|
-
|
|
83
|
-
@Component({
|
|
84
|
-
selector: "app-advanced",
|
|
85
|
-
standalone: true,
|
|
86
|
-
imports: [AngularTiptapEditorComponent],
|
|
87
|
-
template: `
|
|
88
|
-
<angular-tiptap-editor
|
|
89
|
-
[content]="content"
|
|
90
|
-
[toolbar]="toolbarConfig"
|
|
91
|
-
[bubbleMenu]="bubbleMenuConfig"
|
|
92
|
-
[slashCommands]="slashCommandsConfig"
|
|
93
|
-
[locale]="'en'"
|
|
94
|
-
[height]="400"
|
|
95
|
-
[showCharacterCount]="true"
|
|
96
|
-
[showWordCount]="true"
|
|
97
|
-
(contentChange)="onContentChange($event)"
|
|
98
|
-
/>
|
|
99
|
-
`,
|
|
100
|
-
})
|
|
101
|
-
export class AdvancedComponent {
|
|
102
|
-
content = "<h1>Welcome!</h1><p>Start editing...</p>";
|
|
103
|
-
|
|
104
|
-
// Use default configurations as base
|
|
105
|
-
toolbarConfig = {
|
|
106
|
-
...DEFAULT_TOOLBAR_CONFIG,
|
|
107
|
-
clear: true, // Add clear button
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
bubbleMenuConfig = {
|
|
111
|
-
...DEFAULT_BUBBLE_MENU_CONFIG,
|
|
112
|
-
table: true, // Enable table bubble menu
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
slashCommandsConfig = {
|
|
116
|
-
commands: [], // Will be populated by the library
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
onContentChange(newContent: string) {
|
|
120
|
-
this.content = newContent;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### 3. With Form Integration
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
import { Component } from "@angular/core";
|
|
129
|
-
import { FormControl, ReactiveFormsModule } from "@angular/forms";
|
|
130
|
-
import { AngularTiptapEditorComponent } from "@flogeez/angular-tiptap-editor";
|
|
131
|
-
|
|
132
|
-
@Component({
|
|
133
|
-
selector: "app-form",
|
|
134
|
-
standalone: true,
|
|
135
|
-
imports: [AngularTiptapEditorComponent, ReactiveFormsModule],
|
|
136
|
-
template: `
|
|
137
|
-
<form>
|
|
138
|
-
<angular-tiptap-editor
|
|
139
|
-
[formControl]="contentControl"
|
|
140
|
-
placeholder="Enter your content here..."
|
|
141
|
-
[showCharacterCount]="true"
|
|
142
|
-
[showWordCount]="true"
|
|
143
|
-
/>
|
|
144
|
-
<button type="submit">Submit</button>
|
|
145
|
-
</form>
|
|
146
|
-
`,
|
|
147
|
-
})
|
|
148
|
-
export class FormComponent {
|
|
149
|
-
contentControl = new FormControl("<p>Initial content</p>");
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### 4. Using EditorCommandsService
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
import { Component, inject } from "@angular/core";
|
|
157
|
-
import { EditorCommandsService } from "@flogeez/angular-tiptap-editor";
|
|
158
|
-
|
|
159
|
-
@Component({
|
|
160
|
-
selector: "app-commands",
|
|
161
|
-
standalone: true,
|
|
162
|
-
template: `
|
|
163
|
-
<div>
|
|
164
|
-
<button (click)="clearContent()">Clear Content</button>
|
|
165
|
-
<button (click)="focusEditor()">Focus Editor</button>
|
|
166
|
-
<button (click)="setContent()">Set Content</button>
|
|
167
|
-
</div>
|
|
168
|
-
`,
|
|
169
|
-
})
|
|
170
|
-
export class CommandsComponent {
|
|
171
|
-
private editorCommandsService = inject(EditorCommandsService);
|
|
172
|
-
private editor: Editor | null = null;
|
|
173
|
-
|
|
174
|
-
onEditorCreated(editor: Editor) {
|
|
175
|
-
this.editor = editor;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
clearContent() {
|
|
179
|
-
if (this.editor) {
|
|
180
|
-
this.editorCommandsService.clearContent(this.editor);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
focusEditor() {
|
|
185
|
-
if (this.editor) {
|
|
186
|
-
this.editorCommandsService.focus(this.editor);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
setContent() {
|
|
191
|
-
if (this.editor) {
|
|
192
|
-
this.editorCommandsService.setContent(
|
|
193
|
-
this.editor,
|
|
194
|
-
"<h1>New Content</h1>"
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
## ✨ Key Features
|
|
202
|
-
|
|
203
|
-
### 📊 Table Management
|
|
204
|
-
|
|
205
|
-
Full table support with intuitive bubble menus:
|
|
206
|
-
|
|
207
|
-
- **Table Creation**: Insert tables via slash commands (`/table`)
|
|
208
|
-
- **Cell Selection**: Click and drag to select multiple cells
|
|
209
|
-
- **Bubble Menus**: Context-aware menus for table operations
|
|
210
|
-
- **Row/Column Management**: Add, remove, and merge cells
|
|
211
|
-
- **Styling**: Custom table styling with proper borders
|
|
212
|
-
|
|
213
|
-
### ⚡ Slash Commands
|
|
214
|
-
|
|
215
|
-
Quick content insertion with slash commands:
|
|
216
|
-
|
|
217
|
-
- **Headings**: `/h1`, `/h2`, `/h3`
|
|
218
|
-
- **Lists**: `/bullet`, `/numbered`
|
|
219
|
-
- **Blocks**: `/quote`, `/code`, `/line`
|
|
220
|
-
- **Media**: `/image`, `/table`
|
|
221
|
-
- **Fully Internationalized**: All commands translated
|
|
222
|
-
|
|
223
|
-
### 🖼️ Advanced Image Handling
|
|
224
|
-
|
|
225
|
-
Professional image management:
|
|
226
|
-
|
|
227
|
-
- **Drag & Drop**: Drag images directly into the editor
|
|
228
|
-
- **File Selection**: Click to select images from device
|
|
229
|
-
- **Auto-Compression**: Images automatically compressed (max 1920x1080)
|
|
230
|
-
- **Resizable**: Images can be resized with handles
|
|
231
|
-
- **Bubble Menu**: Context menu for image operations
|
|
232
|
-
|
|
233
|
-
### 📝 Word & Character Counting
|
|
234
|
-
|
|
235
|
-
Real-time content statistics:
|
|
236
|
-
|
|
237
|
-
- **Live Updates**: Counters update as you type
|
|
238
|
-
- **Proper Pluralization**: "1 word" vs "2 words"
|
|
239
|
-
- **Separate Counts**: Independent word and character counts
|
|
240
|
-
- **Configurable**: Show/hide individual counters
|
|
241
|
-
|
|
242
|
-
## 🎨 Demo
|
|
243
|
-
|
|
244
|
-
### 🌐 Live Demo
|
|
245
|
-
|
|
246
|
-
Try the interactive demo online: **[https://flogeez.github.io/angular-tiptap-editor/](https://flogeez.github.io/angular-tiptap-editor/)**
|
|
247
|
-
|
|
248
|
-
### 🖥️ Run Locally
|
|
249
|
-
|
|
250
|
-
```bash
|
|
251
|
-
git clone https://github.com/FloGeez/angular-tiptap-editor.git
|
|
252
|
-
cd angular-tiptap-editor
|
|
253
|
-
npm install
|
|
254
|
-
npm start
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
Open [http://localhost:4200](http://localhost:4200) to view the demo.
|
|
258
|
-
|
|
259
|
-
## 📖 Documentation
|
|
260
|
-
|
|
261
|
-
### API Reference
|
|
262
|
-
|
|
263
|
-
#### Inputs
|
|
264
|
-
|
|
265
|
-
| Input | Type | Default | Description |
|
|
266
|
-
| -------------------- | --------------------- | ------------------- | ---------------------------- |
|
|
267
|
-
| `content` | `string` | `""` | Initial HTML content |
|
|
268
|
-
| `placeholder` | `string` | `"Start typing..."` | Placeholder text |
|
|
269
|
-
| `locale` | `'en' \| 'fr'` | Auto-detect | Editor language |
|
|
270
|
-
| `editable` | `boolean` | `true` | Whether editor is editable |
|
|
271
|
-
| `height` | `number` | `undefined` | Fixed height in pixels |
|
|
272
|
-
| `maxHeight` | `number` | `undefined` | Maximum height in pixels |
|
|
273
|
-
| `minHeight` | `number` | `200` | Minimum height in pixels |
|
|
274
|
-
| `showToolbar` | `boolean` | `true` | Show toolbar |
|
|
275
|
-
| `showBubbleMenu` | `boolean` | `true` | Show bubble menu |
|
|
276
|
-
| `showCharacterCount` | `boolean` | `true` | Show character counter |
|
|
277
|
-
| `showWordCount` | `boolean` | `true` | Show word counter |
|
|
278
|
-
| `toolbar` | `ToolbarConfig` | All enabled | Toolbar configuration |
|
|
279
|
-
| `bubbleMenu` | `BubbleMenuConfig` | All enabled | Bubble menu configuration |
|
|
280
|
-
| `slashCommands` | `SlashCommandsConfig` | All enabled | Slash commands configuration |
|
|
281
|
-
|
|
282
|
-
#### Outputs
|
|
283
|
-
|
|
284
|
-
| Output | Type | Description |
|
|
285
|
-
| --------------- | ----------------- | ------------------------------- |
|
|
286
|
-
| `contentChange` | `string` | Emitted when content changes |
|
|
287
|
-
| `editorCreated` | `Editor` | Emitted when editor is created |
|
|
288
|
-
| `editorFocus` | `{editor, event}` | Emitted when editor gains focus |
|
|
289
|
-
| `editorBlur` | `{editor, event}` | Emitted when editor loses focus |
|
|
290
|
-
|
|
291
|
-
### Configuration Examples
|
|
292
|
-
|
|
293
|
-
```typescript
|
|
294
|
-
import {
|
|
295
|
-
DEFAULT_TOOLBAR_CONFIG,
|
|
296
|
-
DEFAULT_BUBBLE_MENU_CONFIG,
|
|
297
|
-
SLASH_COMMAND_KEYS,
|
|
298
|
-
} from "@flogeez/angular-tiptap-editor";
|
|
299
|
-
|
|
300
|
-
// Minimal toolbar
|
|
301
|
-
const minimalToolbar = {
|
|
302
|
-
bold: true,
|
|
303
|
-
italic: true,
|
|
304
|
-
bulletList: true,
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
// Full toolbar with clear button
|
|
308
|
-
const fullToolbar = {
|
|
309
|
-
...DEFAULT_TOOLBAR_CONFIG,
|
|
310
|
-
clear: true, // Add clear button
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
// Bubble menu with table support
|
|
314
|
-
const bubbleMenuWithTable = {
|
|
315
|
-
...DEFAULT_BUBBLE_MENU_CONFIG,
|
|
316
|
-
table: true, // Enable table bubble menu
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
// Slash commands configuration
|
|
320
|
-
const slashCommands = {
|
|
321
|
-
commands: [], // Will be populated by filterSlashCommands()
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
// Available slash command keys
|
|
325
|
-
console.log(SLASH_COMMAND_KEYS); // ["heading1", "heading2", "heading3", "bulletList", "orderedList", "blockquote", "code", "image", "horizontalRule", "table"]
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
## 🌍 Internationalization
|
|
329
|
-
|
|
330
|
-
The editor supports English and French with automatic browser language detection:
|
|
331
|
-
|
|
332
|
-
```typescript
|
|
333
|
-
// Force English
|
|
334
|
-
<angular-tiptap-editor [locale]="'en'" />
|
|
335
|
-
|
|
336
|
-
// Force French
|
|
337
|
-
<angular-tiptap-editor [locale]="'fr'" />
|
|
338
|
-
|
|
339
|
-
// Auto-detect (default)
|
|
340
|
-
<angular-tiptap-editor />
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
### Available Translations
|
|
344
|
-
|
|
345
|
-
- **English (en)**: Default language with complete translations
|
|
346
|
-
- **French (fr)**: Full French translation including:
|
|
347
|
-
- Toolbar buttons
|
|
348
|
-
- Bubble menu items
|
|
349
|
-
- Slash commands
|
|
350
|
-
- Placeholder text
|
|
351
|
-
- Error messages
|
|
352
|
-
- Word/character count (with proper pluralization)
|
|
353
|
-
|
|
354
|
-
### Custom Slash Commands
|
|
355
|
-
|
|
356
|
-
```typescript
|
|
357
|
-
import {
|
|
358
|
-
filterSlashCommands,
|
|
359
|
-
SLASH_COMMAND_KEYS,
|
|
360
|
-
} from "@flogeez/angular-tiptap-editor";
|
|
361
|
-
|
|
362
|
-
// Filter available slash commands
|
|
363
|
-
const activeCommands = new Set(["heading1", "heading2", "bulletList", "table"]);
|
|
364
|
-
const commands = filterSlashCommands(activeCommands);
|
|
365
|
-
|
|
366
|
-
// Use in component
|
|
367
|
-
slashCommandsConfig = {
|
|
368
|
-
commands: commands,
|
|
369
|
-
};
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
## 🏗️ Architecture
|
|
373
|
-
|
|
374
|
-
### Service-Based Design
|
|
375
|
-
|
|
376
|
-
The library follows a clean service-based architecture:
|
|
377
|
-
|
|
378
|
-
- **`EditorCommandsService`**: Centralized service for all editor commands
|
|
379
|
-
- **`TiptapI18nService`**: Internationalization service with automatic language detection
|
|
380
|
-
- **`ImageService`**: Advanced image handling with compression and resizing
|
|
381
|
-
- **`filterSlashCommands()`**: Utility function for managing slash commands
|
|
382
|
-
|
|
383
|
-
### Modern Angular Patterns
|
|
384
|
-
|
|
385
|
-
- **Signals**: Used throughout for reactive state management
|
|
386
|
-
- **Dependency Injection**: Clean service injection with `inject()`
|
|
387
|
-
- **Standalone Components**: All components are standalone for better tree-shaking
|
|
388
|
-
- **TypeScript**: Strict typing with comprehensive interfaces
|
|
389
|
-
|
|
390
|
-
### Default Configurations
|
|
391
|
-
|
|
392
|
-
The library provides default configurations that can be imported and customized:
|
|
393
|
-
|
|
394
|
-
```typescript
|
|
395
|
-
import {
|
|
396
|
-
DEFAULT_TOOLBAR_CONFIG,
|
|
397
|
-
DEFAULT_BUBBLE_MENU_CONFIG,
|
|
398
|
-
DEFAULT_IMAGE_BUBBLE_MENU_CONFIG,
|
|
399
|
-
DEFAULT_TABLE_MENU_CONFIG,
|
|
400
|
-
SLASH_COMMAND_KEYS,
|
|
401
|
-
} from "@flogeez/angular-tiptap-editor";
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
## 🔧 Development
|
|
405
|
-
|
|
406
|
-
### Build Library
|
|
407
|
-
|
|
408
|
-
```bash
|
|
409
|
-
npm run build:lib
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
### Watch Mode (Development)
|
|
413
|
-
|
|
414
|
-
```bash
|
|
415
|
-
npm run dev
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
This runs the library in watch mode and starts the demo application.
|
|
419
|
-
|
|
420
|
-
### Available Scripts
|
|
421
|
-
|
|
422
|
-
- `npm start` - Start demo application
|
|
423
|
-
- `npm run build` - Build demo application
|
|
424
|
-
- `npm run build:lib` - Build library
|
|
425
|
-
- `npm run watch:lib` - Watch library changes
|
|
426
|
-
- `npm run dev` - Development mode (watch + serve)
|
|
427
|
-
|
|
428
|
-
## 📝 License
|
|
429
|
-
|
|
430
|
-
MIT License - see [LICENSE](LICENSE) file for details.
|
|
431
|
-
|
|
432
|
-
## 🤝 Contributing
|
|
433
|
-
|
|
434
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
435
|
-
|
|
436
|
-
## 🔗 Links
|
|
437
|
-
|
|
438
|
-
- 🎮 [Live Demo](https://flogeez.github.io/angular-tiptap-editor/)
|
|
439
|
-
- 📖 [Tiptap Documentation](https://tiptap.dev/)
|
|
440
|
-
- 🅰️ [Angular Documentation](https://angular.dev/)
|
|
441
|
-
- 📦 [NPM Package](https://www.npmjs.com/package/@flogeez/angular-tiptap-editor)
|
|
442
|
-
- 🐛 [Report Issues](https://github.com/FloGeez/angular-tiptap-editor/issues)
|
|
443
|
-
- 💡 [Feature Requests](https://github.com/FloGeez/angular-tiptap-editor/issues)
|
|
444
|
-
|
|
445
|
-
## 🆕 What's New
|
|
446
|
-
|
|
447
|
-
### Latest Updates
|
|
448
|
-
|
|
449
|
-
- ✅ **Table Support**: Full table management with bubble menus
|
|
450
|
-
- ✅ **Slash Commands**: Intuitive content insertion commands
|
|
451
|
-
- ✅ **Word/Character Count**: Real-time counting with proper pluralization
|
|
452
|
-
- ✅ **Service Architecture**: Clean `EditorCommandsService` for better maintainability
|
|
453
|
-
- ✅ **Default Configurations**: Importable default configs for easy customization
|
|
454
|
-
- ✅ **Office Paste**: Clean pasting from Microsoft Office applications
|
|
455
|
-
- ✅ **Enhanced i18n**: Improved internationalization with better architecture
|
|
456
|
-
|
|
457
|
-
---
|
|
458
|
-
|
|
459
|
-
Made with ❤️ by [FloGeez](https://github.com/FloGeez)
|
|
1
|
+
# Angular Tiptap Editor
|
|
2
|
+
|
|
3
|
+
A modern, customizable rich-text editor for Angular applications, built with Tiptap and featuring complete internationalization support.
|
|
4
|
+
|
|
5
|
+
[](https://stackblitz.com/edit/angular-tiptap-editor)
|
|
6
|
+
|
|
7
|
+
## 🚀 Features
|
|
8
|
+
|
|
9
|
+
- **Modern Angular**: Built with Angular 18+ with Signals and modern patterns
|
|
10
|
+
- **Rich Text Editing**: Powered by Tiptap v3.3.0 with extensive formatting options
|
|
11
|
+
- **Table Support**: Full table management with bubble menus and cell selection
|
|
12
|
+
- **Slash Commands**: Intuitive slash commands for quick content insertion
|
|
13
|
+
- **Internationalization**: Full i18n support (English & French) with auto-detection
|
|
14
|
+
- **Customizable**: Highly configurable toolbar, bubble menus, and slash commands
|
|
15
|
+
- **Image Support**: Advanced image handling with resizing, compression, and bubble menus
|
|
16
|
+
- **Height Control**: Configurable editor height with scrolling
|
|
17
|
+
- **Word/Character Count**: Real-time word and character counting with proper pluralization
|
|
18
|
+
- **Office Paste**: Clean pasting from Microsoft Office applications
|
|
19
|
+
- **TypeScript**: Full TypeScript support with strict typing
|
|
20
|
+
- **Accessibility**: Built with accessibility best practices
|
|
21
|
+
- **Service Architecture**: Clean service-based architecture with `EditorCommandsService`
|
|
22
|
+
|
|
23
|
+
## 📦 Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @flogeez/angular-tiptap-editor
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### CSS Styles
|
|
30
|
+
|
|
31
|
+
Add the required CSS to your `angular.json` file in the `styles` array:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"styles": [
|
|
36
|
+
...
|
|
37
|
+
"node_modules/@fontsource/material-symbols-outlined/index.css",
|
|
38
|
+
"node_modules/@flogeez/angular-tiptap-editor/src/lib/styles/index.css",
|
|
39
|
+
...
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 🎯 Quick Start
|
|
45
|
+
|
|
46
|
+
### 1. Basic Usage
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { Component } from "@angular/core";
|
|
50
|
+
import { AngularTiptapEditorComponent } from "@flogeez/angular-tiptap-editor";
|
|
51
|
+
|
|
52
|
+
@Component({
|
|
53
|
+
selector: "app-example",
|
|
54
|
+
standalone: true,
|
|
55
|
+
imports: [AngularTiptapEditorComponent],
|
|
56
|
+
template: `
|
|
57
|
+
<angular-tiptap-editor
|
|
58
|
+
[content]="content"
|
|
59
|
+
(contentChange)="onContentChange($event)"
|
|
60
|
+
/>
|
|
61
|
+
`,
|
|
62
|
+
})
|
|
63
|
+
export class ExampleComponent {
|
|
64
|
+
content = "<p>Hello <strong>World</strong>!</p>";
|
|
65
|
+
|
|
66
|
+
onContentChange(newContent: string) {
|
|
67
|
+
this.content = newContent;
|
|
68
|
+
console.log("Content updated:", newContent);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 2. With Custom Configuration
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { Component } from "@angular/core";
|
|
77
|
+
import {
|
|
78
|
+
AngularTiptapEditorComponent,
|
|
79
|
+
DEFAULT_TOOLBAR_CONFIG,
|
|
80
|
+
DEFAULT_BUBBLE_MENU_CONFIG,
|
|
81
|
+
} from "@flogeez/angular-tiptap-editor";
|
|
82
|
+
|
|
83
|
+
@Component({
|
|
84
|
+
selector: "app-advanced",
|
|
85
|
+
standalone: true,
|
|
86
|
+
imports: [AngularTiptapEditorComponent],
|
|
87
|
+
template: `
|
|
88
|
+
<angular-tiptap-editor
|
|
89
|
+
[content]="content"
|
|
90
|
+
[toolbar]="toolbarConfig"
|
|
91
|
+
[bubbleMenu]="bubbleMenuConfig"
|
|
92
|
+
[slashCommands]="slashCommandsConfig"
|
|
93
|
+
[locale]="'en'"
|
|
94
|
+
[height]="400"
|
|
95
|
+
[showCharacterCount]="true"
|
|
96
|
+
[showWordCount]="true"
|
|
97
|
+
(contentChange)="onContentChange($event)"
|
|
98
|
+
/>
|
|
99
|
+
`,
|
|
100
|
+
})
|
|
101
|
+
export class AdvancedComponent {
|
|
102
|
+
content = "<h1>Welcome!</h1><p>Start editing...</p>";
|
|
103
|
+
|
|
104
|
+
// Use default configurations as base
|
|
105
|
+
toolbarConfig = {
|
|
106
|
+
...DEFAULT_TOOLBAR_CONFIG,
|
|
107
|
+
clear: true, // Add clear button
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
bubbleMenuConfig = {
|
|
111
|
+
...DEFAULT_BUBBLE_MENU_CONFIG,
|
|
112
|
+
table: true, // Enable table bubble menu
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
slashCommandsConfig = {
|
|
116
|
+
commands: [], // Will be populated by the library
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
onContentChange(newContent: string) {
|
|
120
|
+
this.content = newContent;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 3. With Form Integration
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { Component } from "@angular/core";
|
|
129
|
+
import { FormControl, ReactiveFormsModule } from "@angular/forms";
|
|
130
|
+
import { AngularTiptapEditorComponent } from "@flogeez/angular-tiptap-editor";
|
|
131
|
+
|
|
132
|
+
@Component({
|
|
133
|
+
selector: "app-form",
|
|
134
|
+
standalone: true,
|
|
135
|
+
imports: [AngularTiptapEditorComponent, ReactiveFormsModule],
|
|
136
|
+
template: `
|
|
137
|
+
<form>
|
|
138
|
+
<angular-tiptap-editor
|
|
139
|
+
[formControl]="contentControl"
|
|
140
|
+
placeholder="Enter your content here..."
|
|
141
|
+
[showCharacterCount]="true"
|
|
142
|
+
[showWordCount]="true"
|
|
143
|
+
/>
|
|
144
|
+
<button type="submit">Submit</button>
|
|
145
|
+
</form>
|
|
146
|
+
`,
|
|
147
|
+
})
|
|
148
|
+
export class FormComponent {
|
|
149
|
+
contentControl = new FormControl("<p>Initial content</p>");
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 4. Using EditorCommandsService
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { Component, inject } from "@angular/core";
|
|
157
|
+
import { EditorCommandsService } from "@flogeez/angular-tiptap-editor";
|
|
158
|
+
|
|
159
|
+
@Component({
|
|
160
|
+
selector: "app-commands",
|
|
161
|
+
standalone: true,
|
|
162
|
+
template: `
|
|
163
|
+
<div>
|
|
164
|
+
<button (click)="clearContent()">Clear Content</button>
|
|
165
|
+
<button (click)="focusEditor()">Focus Editor</button>
|
|
166
|
+
<button (click)="setContent()">Set Content</button>
|
|
167
|
+
</div>
|
|
168
|
+
`,
|
|
169
|
+
})
|
|
170
|
+
export class CommandsComponent {
|
|
171
|
+
private editorCommandsService = inject(EditorCommandsService);
|
|
172
|
+
private editor: Editor | null = null;
|
|
173
|
+
|
|
174
|
+
onEditorCreated(editor: Editor) {
|
|
175
|
+
this.editor = editor;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
clearContent() {
|
|
179
|
+
if (this.editor) {
|
|
180
|
+
this.editorCommandsService.clearContent(this.editor);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
focusEditor() {
|
|
185
|
+
if (this.editor) {
|
|
186
|
+
this.editorCommandsService.focus(this.editor);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
setContent() {
|
|
191
|
+
if (this.editor) {
|
|
192
|
+
this.editorCommandsService.setContent(
|
|
193
|
+
this.editor,
|
|
194
|
+
"<h1>New Content</h1>"
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## ✨ Key Features
|
|
202
|
+
|
|
203
|
+
### 📊 Table Management
|
|
204
|
+
|
|
205
|
+
Full table support with intuitive bubble menus:
|
|
206
|
+
|
|
207
|
+
- **Table Creation**: Insert tables via slash commands (`/table`)
|
|
208
|
+
- **Cell Selection**: Click and drag to select multiple cells
|
|
209
|
+
- **Bubble Menus**: Context-aware menus for table operations
|
|
210
|
+
- **Row/Column Management**: Add, remove, and merge cells
|
|
211
|
+
- **Styling**: Custom table styling with proper borders
|
|
212
|
+
|
|
213
|
+
### ⚡ Slash Commands
|
|
214
|
+
|
|
215
|
+
Quick content insertion with slash commands:
|
|
216
|
+
|
|
217
|
+
- **Headings**: `/h1`, `/h2`, `/h3`
|
|
218
|
+
- **Lists**: `/bullet`, `/numbered`
|
|
219
|
+
- **Blocks**: `/quote`, `/code`, `/line`
|
|
220
|
+
- **Media**: `/image`, `/table`
|
|
221
|
+
- **Fully Internationalized**: All commands translated
|
|
222
|
+
|
|
223
|
+
### 🖼️ Advanced Image Handling
|
|
224
|
+
|
|
225
|
+
Professional image management:
|
|
226
|
+
|
|
227
|
+
- **Drag & Drop**: Drag images directly into the editor
|
|
228
|
+
- **File Selection**: Click to select images from device
|
|
229
|
+
- **Auto-Compression**: Images automatically compressed (max 1920x1080)
|
|
230
|
+
- **Resizable**: Images can be resized with handles
|
|
231
|
+
- **Bubble Menu**: Context menu for image operations
|
|
232
|
+
|
|
233
|
+
### 📝 Word & Character Counting
|
|
234
|
+
|
|
235
|
+
Real-time content statistics:
|
|
236
|
+
|
|
237
|
+
- **Live Updates**: Counters update as you type
|
|
238
|
+
- **Proper Pluralization**: "1 word" vs "2 words"
|
|
239
|
+
- **Separate Counts**: Independent word and character counts
|
|
240
|
+
- **Configurable**: Show/hide individual counters
|
|
241
|
+
|
|
242
|
+
## 🎨 Demo
|
|
243
|
+
|
|
244
|
+
### 🌐 Live Demo
|
|
245
|
+
|
|
246
|
+
Try the interactive demo online: **[https://flogeez.github.io/angular-tiptap-editor/](https://flogeez.github.io/angular-tiptap-editor/)**
|
|
247
|
+
|
|
248
|
+
### 🖥️ Run Locally
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
git clone https://github.com/FloGeez/angular-tiptap-editor.git
|
|
252
|
+
cd angular-tiptap-editor
|
|
253
|
+
npm install
|
|
254
|
+
npm start
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Open [http://localhost:4200](http://localhost:4200) to view the demo.
|
|
258
|
+
|
|
259
|
+
## 📖 Documentation
|
|
260
|
+
|
|
261
|
+
### API Reference
|
|
262
|
+
|
|
263
|
+
#### Inputs
|
|
264
|
+
|
|
265
|
+
| Input | Type | Default | Description |
|
|
266
|
+
| -------------------- | --------------------- | ------------------- | ---------------------------- |
|
|
267
|
+
| `content` | `string` | `""` | Initial HTML content |
|
|
268
|
+
| `placeholder` | `string` | `"Start typing..."` | Placeholder text |
|
|
269
|
+
| `locale` | `'en' \| 'fr'` | Auto-detect | Editor language |
|
|
270
|
+
| `editable` | `boolean` | `true` | Whether editor is editable |
|
|
271
|
+
| `height` | `number` | `undefined` | Fixed height in pixels |
|
|
272
|
+
| `maxHeight` | `number` | `undefined` | Maximum height in pixels |
|
|
273
|
+
| `minHeight` | `number` | `200` | Minimum height in pixels |
|
|
274
|
+
| `showToolbar` | `boolean` | `true` | Show toolbar |
|
|
275
|
+
| `showBubbleMenu` | `boolean` | `true` | Show bubble menu |
|
|
276
|
+
| `showCharacterCount` | `boolean` | `true` | Show character counter |
|
|
277
|
+
| `showWordCount` | `boolean` | `true` | Show word counter |
|
|
278
|
+
| `toolbar` | `ToolbarConfig` | All enabled | Toolbar configuration |
|
|
279
|
+
| `bubbleMenu` | `BubbleMenuConfig` | All enabled | Bubble menu configuration |
|
|
280
|
+
| `slashCommands` | `SlashCommandsConfig` | All enabled | Slash commands configuration |
|
|
281
|
+
|
|
282
|
+
#### Outputs
|
|
283
|
+
|
|
284
|
+
| Output | Type | Description |
|
|
285
|
+
| --------------- | ----------------- | ------------------------------- |
|
|
286
|
+
| `contentChange` | `string` | Emitted when content changes |
|
|
287
|
+
| `editorCreated` | `Editor` | Emitted when editor is created |
|
|
288
|
+
| `editorFocus` | `{editor, event}` | Emitted when editor gains focus |
|
|
289
|
+
| `editorBlur` | `{editor, event}` | Emitted when editor loses focus |
|
|
290
|
+
|
|
291
|
+
### Configuration Examples
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
import {
|
|
295
|
+
DEFAULT_TOOLBAR_CONFIG,
|
|
296
|
+
DEFAULT_BUBBLE_MENU_CONFIG,
|
|
297
|
+
SLASH_COMMAND_KEYS,
|
|
298
|
+
} from "@flogeez/angular-tiptap-editor";
|
|
299
|
+
|
|
300
|
+
// Minimal toolbar
|
|
301
|
+
const minimalToolbar = {
|
|
302
|
+
bold: true,
|
|
303
|
+
italic: true,
|
|
304
|
+
bulletList: true,
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
// Full toolbar with clear button
|
|
308
|
+
const fullToolbar = {
|
|
309
|
+
...DEFAULT_TOOLBAR_CONFIG,
|
|
310
|
+
clear: true, // Add clear button
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
// Bubble menu with table support
|
|
314
|
+
const bubbleMenuWithTable = {
|
|
315
|
+
...DEFAULT_BUBBLE_MENU_CONFIG,
|
|
316
|
+
table: true, // Enable table bubble menu
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
// Slash commands configuration
|
|
320
|
+
const slashCommands = {
|
|
321
|
+
commands: [], // Will be populated by filterSlashCommands()
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
// Available slash command keys
|
|
325
|
+
console.log(SLASH_COMMAND_KEYS); // ["heading1", "heading2", "heading3", "bulletList", "orderedList", "blockquote", "code", "image", "horizontalRule", "table"]
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## 🌍 Internationalization
|
|
329
|
+
|
|
330
|
+
The editor supports English and French with automatic browser language detection:
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
// Force English
|
|
334
|
+
<angular-tiptap-editor [locale]="'en'" />
|
|
335
|
+
|
|
336
|
+
// Force French
|
|
337
|
+
<angular-tiptap-editor [locale]="'fr'" />
|
|
338
|
+
|
|
339
|
+
// Auto-detect (default)
|
|
340
|
+
<angular-tiptap-editor />
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Available Translations
|
|
344
|
+
|
|
345
|
+
- **English (en)**: Default language with complete translations
|
|
346
|
+
- **French (fr)**: Full French translation including:
|
|
347
|
+
- Toolbar buttons
|
|
348
|
+
- Bubble menu items
|
|
349
|
+
- Slash commands
|
|
350
|
+
- Placeholder text
|
|
351
|
+
- Error messages
|
|
352
|
+
- Word/character count (with proper pluralization)
|
|
353
|
+
|
|
354
|
+
### Custom Slash Commands
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
import {
|
|
358
|
+
filterSlashCommands,
|
|
359
|
+
SLASH_COMMAND_KEYS,
|
|
360
|
+
} from "@flogeez/angular-tiptap-editor";
|
|
361
|
+
|
|
362
|
+
// Filter available slash commands
|
|
363
|
+
const activeCommands = new Set(["heading1", "heading2", "bulletList", "table"]);
|
|
364
|
+
const commands = filterSlashCommands(activeCommands);
|
|
365
|
+
|
|
366
|
+
// Use in component
|
|
367
|
+
slashCommandsConfig = {
|
|
368
|
+
commands: commands,
|
|
369
|
+
};
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
## 🏗️ Architecture
|
|
373
|
+
|
|
374
|
+
### Service-Based Design
|
|
375
|
+
|
|
376
|
+
The library follows a clean service-based architecture:
|
|
377
|
+
|
|
378
|
+
- **`EditorCommandsService`**: Centralized service for all editor commands
|
|
379
|
+
- **`TiptapI18nService`**: Internationalization service with automatic language detection
|
|
380
|
+
- **`ImageService`**: Advanced image handling with compression and resizing
|
|
381
|
+
- **`filterSlashCommands()`**: Utility function for managing slash commands
|
|
382
|
+
|
|
383
|
+
### Modern Angular Patterns
|
|
384
|
+
|
|
385
|
+
- **Signals**: Used throughout for reactive state management
|
|
386
|
+
- **Dependency Injection**: Clean service injection with `inject()`
|
|
387
|
+
- **Standalone Components**: All components are standalone for better tree-shaking
|
|
388
|
+
- **TypeScript**: Strict typing with comprehensive interfaces
|
|
389
|
+
|
|
390
|
+
### Default Configurations
|
|
391
|
+
|
|
392
|
+
The library provides default configurations that can be imported and customized:
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
import {
|
|
396
|
+
DEFAULT_TOOLBAR_CONFIG,
|
|
397
|
+
DEFAULT_BUBBLE_MENU_CONFIG,
|
|
398
|
+
DEFAULT_IMAGE_BUBBLE_MENU_CONFIG,
|
|
399
|
+
DEFAULT_TABLE_MENU_CONFIG,
|
|
400
|
+
SLASH_COMMAND_KEYS,
|
|
401
|
+
} from "@flogeez/angular-tiptap-editor";
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## 🔧 Development
|
|
405
|
+
|
|
406
|
+
### Build Library
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
npm run build:lib
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Watch Mode (Development)
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
npm run dev
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
This runs the library in watch mode and starts the demo application.
|
|
419
|
+
|
|
420
|
+
### Available Scripts
|
|
421
|
+
|
|
422
|
+
- `npm start` - Start demo application
|
|
423
|
+
- `npm run build` - Build demo application
|
|
424
|
+
- `npm run build:lib` - Build library
|
|
425
|
+
- `npm run watch:lib` - Watch library changes
|
|
426
|
+
- `npm run dev` - Development mode (watch + serve)
|
|
427
|
+
|
|
428
|
+
## 📝 License
|
|
429
|
+
|
|
430
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
431
|
+
|
|
432
|
+
## 🤝 Contributing
|
|
433
|
+
|
|
434
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
435
|
+
|
|
436
|
+
## 🔗 Links
|
|
437
|
+
|
|
438
|
+
- 🎮 [Live Demo](https://flogeez.github.io/angular-tiptap-editor/)
|
|
439
|
+
- 📖 [Tiptap Documentation](https://tiptap.dev/)
|
|
440
|
+
- 🅰️ [Angular Documentation](https://angular.dev/)
|
|
441
|
+
- 📦 [NPM Package](https://www.npmjs.com/package/@flogeez/angular-tiptap-editor)
|
|
442
|
+
- 🐛 [Report Issues](https://github.com/FloGeez/angular-tiptap-editor/issues)
|
|
443
|
+
- 💡 [Feature Requests](https://github.com/FloGeez/angular-tiptap-editor/issues)
|
|
444
|
+
|
|
445
|
+
## 🆕 What's New
|
|
446
|
+
|
|
447
|
+
### Latest Updates
|
|
448
|
+
|
|
449
|
+
- ✅ **Table Support**: Full table management with bubble menus
|
|
450
|
+
- ✅ **Slash Commands**: Intuitive content insertion commands
|
|
451
|
+
- ✅ **Word/Character Count**: Real-time counting with proper pluralization
|
|
452
|
+
- ✅ **Service Architecture**: Clean `EditorCommandsService` for better maintainability
|
|
453
|
+
- ✅ **Default Configurations**: Importable default configs for easy customization
|
|
454
|
+
- ✅ **Office Paste**: Clean pasting from Microsoft Office applications
|
|
455
|
+
- ✅ **Enhanced i18n**: Improved internationalization with better architecture
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
Made with ❤️ by [FloGeez](https://github.com/FloGeez)
|