@flogeez/angular-tiptap-editor 2.2.0 → 2.2.2
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/CHANGELOG.md +13 -1
- package/README.md +63 -46
- package/fesm2022/flogeez-angular-tiptap-editor.mjs +619 -384
- package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
- package/index.d.ts +59 -80
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,18 @@ All notable changes to `@flogeez/angular-tiptap-editor` will be documented in th
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), with the exception that the major version is specifically aligned with the major version of [Tiptap](https://tiptap.dev).
|
|
7
7
|
|
|
8
|
+
## [2.2.2] - 2026-01-26
|
|
9
|
+
|
|
10
|
+
### Refactored
|
|
11
|
+
|
|
12
|
+
- **Sub-Bubble Menus**: Introduced a new dedicated base class `AteBaseSubBubbleMenu` for specialized menus (link and color). This refactoring centralizes common Tippy.js logic and transition behaviors while preserving the unique anchoring and state-locking requirements of each sub-menu.
|
|
13
|
+
|
|
14
|
+
## [2.2.1] - 2026-01-25
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **Custom Menu Items**: Added support for custom items in both the `Toolbar` and the `Bubble Menu` via the `custom` property in `AteToolbarConfig` and `AteBubbleMenuConfig`. This allows developers to easily extend the editor's UI with project-specific actions.
|
|
19
|
+
|
|
8
20
|
## [2.2.0] - 2026-01-21
|
|
9
21
|
|
|
10
22
|
### Changed
|
|
@@ -122,7 +134,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
122
134
|
|
|
123
135
|
### Breaking Changes
|
|
124
136
|
|
|
125
|
-
- **Service Injection**: If you were injecting `EditorCommandsService` (or other internal services) directly into your own global services/components, it will no longer work. You must now interact with the editor via its public API (`@ViewChild`).
|
|
137
|
+
- **Service Injection**: If you were injecting `EditorCommandsService` (or other internal services) directly into your own global services/components, it will no longer work. You must now interact with the editor via its public API (`@ViewChild or viewChild()`).
|
|
126
138
|
|
|
127
139
|
## [0.6.0] - 2026-01-14
|
|
128
140
|
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A modern, customizable rich-text editor for Angular applications, built with Tiptap and featuring complete internationalization support.
|
|
4
4
|
|
|
5
|
-
[](https://flogeez.github.io/angular-tiptap-editor/) [](https://stackblitz.com/edit/angular-tiptap-editor)
|
|
5
|
+
[](https://www.npmjs.com/package/@flogeez/angular-tiptap-editor) [](https://flogeez.github.io/angular-tiptap-editor/) [](https://stackblitz.com/edit/angular-tiptap-editor)
|
|
6
6
|
|
|
7
7
|
## 🚀 Features
|
|
8
8
|
|
|
@@ -16,7 +16,7 @@ A modern, customizable rich-text editor for Angular applications, built with Tip
|
|
|
16
16
|
- **Built-in i18n**: English & French support with a reactive, extensible locale system.
|
|
17
17
|
- **Word/Character Count**: Real-time statistics with proper pluralization support.
|
|
18
18
|
- **Office-Ready**: Cleaned-up pasting from Microsoft Word and Excel to maintain layout integrity.
|
|
19
|
-
- **Service Driven**: Deep programmatic control via `
|
|
19
|
+
- **Service Driven**: Deep programmatic control via `AteEditorCommandsService` and isolated instances.
|
|
20
20
|
- **A11y First**: Built with accessibility best practices and full keyboard navigation.
|
|
21
21
|
|
|
22
22
|
## 💎 Why this editor?
|
|
@@ -69,7 +69,9 @@ import { AngularTiptapEditorComponent } from "@flogeez/angular-tiptap-editor";
|
|
|
69
69
|
selector: "app-example",
|
|
70
70
|
standalone: true,
|
|
71
71
|
imports: [AngularTiptapEditorComponent],
|
|
72
|
-
template: `
|
|
72
|
+
template: `
|
|
73
|
+
<angular-tiptap-editor [content]="content" (contentChange)="onContentChange($event)" />
|
|
74
|
+
`,
|
|
73
75
|
})
|
|
74
76
|
export class ExampleComponent {
|
|
75
77
|
content = "<p>Hello <strong>World</strong>!</p>";
|
|
@@ -87,14 +89,21 @@ The editor can be fully configured using a single `[config]` object, which provi
|
|
|
87
89
|
|
|
88
90
|
```typescript
|
|
89
91
|
import { Component } from "@angular/core";
|
|
90
|
-
import {
|
|
92
|
+
import {
|
|
93
|
+
AngularTiptapEditorComponent,
|
|
94
|
+
AteEditorConfig,
|
|
95
|
+
ATE_DEFAULT_TOOLBAR_CONFIG,
|
|
96
|
+
} from "@flogeez/angular-tiptap-editor";
|
|
91
97
|
|
|
92
98
|
@Component({
|
|
93
99
|
selector: "app-advanced",
|
|
94
100
|
standalone: true,
|
|
95
101
|
imports: [AngularTiptapEditorComponent],
|
|
96
102
|
template: `
|
|
97
|
-
<angular-tiptap-editor
|
|
103
|
+
<angular-tiptap-editor
|
|
104
|
+
[content]="content"
|
|
105
|
+
[config]="editorConfig"
|
|
106
|
+
(contentChange)="onContentChange($event)" />
|
|
98
107
|
`,
|
|
99
108
|
})
|
|
100
109
|
export class AdvancedComponent {
|
|
@@ -109,7 +118,7 @@ export class AdvancedComponent {
|
|
|
109
118
|
|
|
110
119
|
// Customize the toolbar by enabling specific features
|
|
111
120
|
toolbar: {
|
|
112
|
-
...
|
|
121
|
+
...ATE_DEFAULT_TOOLBAR_CONFIG,
|
|
113
122
|
clear: true, // Enable the 'Clear' button
|
|
114
123
|
highlight: false, // Disable the highlight button
|
|
115
124
|
},
|
|
@@ -142,7 +151,10 @@ import { AngularTiptapEditorComponent } from "@flogeez/angular-tiptap-editor";
|
|
|
142
151
|
standalone: true,
|
|
143
152
|
imports: [AngularTiptapEditorComponent],
|
|
144
153
|
template: `
|
|
145
|
-
<angular-tiptap-editor
|
|
154
|
+
<angular-tiptap-editor
|
|
155
|
+
[content]="content"
|
|
156
|
+
[tiptapExtensions]="extensions"
|
|
157
|
+
(contentChange)="content = $event" />
|
|
146
158
|
`,
|
|
147
159
|
})
|
|
148
160
|
export class CustomExtensionsComponent {
|
|
@@ -187,7 +199,7 @@ export class FormComponent {
|
|
|
187
199
|
|
|
188
200
|
```typescript
|
|
189
201
|
import { Component, inject } from "@angular/core";
|
|
190
|
-
import {
|
|
202
|
+
import { AteEditorCommandsService } from "@flogeez/angular-tiptap-editor";
|
|
191
203
|
|
|
192
204
|
@Component({
|
|
193
205
|
selector: "app-commands",
|
|
@@ -205,7 +217,7 @@ import { EditorCommandsService } from "@flogeez/angular-tiptap-editor";
|
|
|
205
217
|
`,
|
|
206
218
|
})
|
|
207
219
|
export class CommandsComponent {
|
|
208
|
-
private editorCommandsService = inject(
|
|
220
|
+
private editorCommandsService = inject(AteEditorCommandsService);
|
|
209
221
|
private editor: Editor | null = null;
|
|
210
222
|
|
|
211
223
|
onEditorCreated(editor: Editor) {
|
|
@@ -247,13 +259,13 @@ Any TipTap **Mark** or **Node** you add to `tiptapExtensions` is automatically t
|
|
|
247
259
|
|
|
248
260
|
If you need to extract complex data (like attributes, depth, or custom logic), you can provide a custom `StateCalculator`.
|
|
249
261
|
|
|
250
|
-
1.
|
|
262
|
+
1. **Define a Calculator**:
|
|
251
263
|
|
|
252
264
|
```typescript
|
|
253
|
-
import {
|
|
265
|
+
import { AteStateCalculator } from "@flogeez/angular-tiptap-editor";
|
|
254
266
|
|
|
255
267
|
// This function will be called on every editor update
|
|
256
|
-
export const MyCustomCalculator:
|
|
268
|
+
export const MyCustomCalculator: AteStateCalculator = editor => {
|
|
257
269
|
return {
|
|
258
270
|
custom: {
|
|
259
271
|
hasHighPriority: editor.isActive("priority"),
|
|
@@ -264,18 +276,18 @@ export const MyCustomCalculator: StateCalculator = editor => {
|
|
|
264
276
|
};
|
|
265
277
|
```
|
|
266
278
|
|
|
267
|
-
2.
|
|
279
|
+
2. **Register it in the Template**:
|
|
268
280
|
|
|
269
281
|
```html
|
|
270
282
|
<angular-tiptap-editor [stateCalculators]="[MyCustomCalculator]" />
|
|
271
283
|
```
|
|
272
284
|
|
|
273
|
-
3.
|
|
285
|
+
3. **Consume it anywhere**:
|
|
274
286
|
|
|
275
287
|
```typescript
|
|
276
288
|
@Component({ ... })
|
|
277
289
|
export class MyToolbarComponent {
|
|
278
|
-
private editorCommands = inject(
|
|
290
|
+
private editorCommands = inject(AteEditorCommandsService);
|
|
279
291
|
|
|
280
292
|
// Access your custom data reactively!
|
|
281
293
|
isHighPriority = computed(() => this.editorCommands.editorState().custom?.hasHighPriority);
|
|
@@ -309,9 +321,9 @@ Quick content insertion with slash commands:
|
|
|
309
321
|
The `slashCommands` object also allows you to add completely custom command items:
|
|
310
322
|
|
|
311
323
|
```typescript
|
|
312
|
-
import {
|
|
324
|
+
import { AteSlashCommandsConfig } from "@flogeez/angular-tiptap-editor";
|
|
313
325
|
|
|
314
|
-
slashCommands:
|
|
326
|
+
slashCommands: AteSlashCommandsConfig = {
|
|
315
327
|
// Toggle native commands
|
|
316
328
|
heading1: true,
|
|
317
329
|
image: false,
|
|
@@ -351,7 +363,10 @@ The handler can return either an **Observable** or a **Promise**.
|
|
|
351
363
|
import { Component, inject } from "@angular/core";
|
|
352
364
|
import { HttpClient } from "@angular/common/http";
|
|
353
365
|
import { map } from "rxjs/operators";
|
|
354
|
-
import {
|
|
366
|
+
import {
|
|
367
|
+
AngularTiptapEditorComponent,
|
|
368
|
+
AteImageUploadHandler,
|
|
369
|
+
} from "@flogeez/angular-tiptap-editor";
|
|
355
370
|
|
|
356
371
|
@Component({
|
|
357
372
|
selector: "app-custom-upload",
|
|
@@ -368,11 +383,13 @@ export class CustomUploadComponent {
|
|
|
368
383
|
private http = inject(HttpClient);
|
|
369
384
|
content = "";
|
|
370
385
|
|
|
371
|
-
uploadHandler:
|
|
386
|
+
uploadHandler: AteImageUploadHandler = ctx => {
|
|
372
387
|
const formData = new FormData();
|
|
373
388
|
formData.append("image", ctx.file);
|
|
374
389
|
|
|
375
|
-
return this.http
|
|
390
|
+
return this.http
|
|
391
|
+
.post<{ url: string }>("/api/upload", formData)
|
|
392
|
+
.pipe(map(result => ({ src: result.url })));
|
|
376
393
|
};
|
|
377
394
|
|
|
378
395
|
onContentChange(newContent: string) {
|
|
@@ -384,7 +401,7 @@ export class CustomUploadComponent {
|
|
|
384
401
|
#### Using Promise (async/await)
|
|
385
402
|
|
|
386
403
|
```typescript
|
|
387
|
-
uploadHandler:
|
|
404
|
+
uploadHandler: AteImageUploadHandler = async ctx => {
|
|
388
405
|
const formData = new FormData();
|
|
389
406
|
formData.append("image", ctx.file);
|
|
390
407
|
|
|
@@ -463,11 +480,11 @@ Open [http://localhost:4200](http://localhost:4200) to view the demo.
|
|
|
463
480
|
| `enableOfficePaste` | `boolean` | `true` | Enable smart Office pasting |
|
|
464
481
|
| `showCharacterCount` | `boolean` | `true` | Show character counter |
|
|
465
482
|
| `showWordCount` | `boolean` | `true` | Show word counter |
|
|
466
|
-
| `toolbar` | `
|
|
467
|
-
| `bubbleMenu` | `
|
|
468
|
-
| `slashCommands` | `
|
|
469
|
-
| `imageUploadHandler` | `
|
|
470
|
-
| `stateCalculators` | `
|
|
483
|
+
| `toolbar` | `AteToolbarConfig` | All enabled | Detailed toolbar configuration |
|
|
484
|
+
| `bubbleMenu` | `AteBubbleMenuConfig` | All enabled | Detailed bubble menu configuration |
|
|
485
|
+
| `slashCommands` | `AteSlashCommandsConfig` | All enabled | Detailed slash commands config |
|
|
486
|
+
| `imageUploadHandler` | `AteImageUploadHandler` | `undefined` | Custom image upload function |
|
|
487
|
+
| `stateCalculators` | `AteStateCalculator[]` | `[]` | Custom reactive state logic |
|
|
471
488
|
| `tiptapExtensions` | `(Extension \| Node \| Mark)[]` | `[]` | Additional Tiptap extensions |
|
|
472
489
|
| `tiptapOptions` | `Partial<EditorOptions>` | `{}` | Additional Tiptap editor options |
|
|
473
490
|
|
|
@@ -507,12 +524,12 @@ export interface AteEditorConfig {
|
|
|
507
524
|
maxCharacters?: number;
|
|
508
525
|
|
|
509
526
|
// Complex Modules
|
|
510
|
-
toolbar?:
|
|
511
|
-
bubbleMenu?:
|
|
512
|
-
imageBubbleMenu?:
|
|
513
|
-
tableBubbleMenu?:
|
|
514
|
-
cellBubbleMenu?:
|
|
515
|
-
slashCommands?:
|
|
527
|
+
toolbar?: AteToolbarConfig;
|
|
528
|
+
bubbleMenu?: AteBubbleMenuConfig;
|
|
529
|
+
imageBubbleMenu?: AteImageBubbleMenuConfig;
|
|
530
|
+
tableBubbleMenu?: AteTableBubbleMenuConfig;
|
|
531
|
+
cellBubbleMenu?: AteCellBubbleMenuConfig;
|
|
532
|
+
slashCommands?: AteSlashCommandsConfig;
|
|
516
533
|
imageUpload?: AteImageUploadConfig;
|
|
517
534
|
}
|
|
518
535
|
```
|
|
@@ -524,7 +541,7 @@ The `imageUpload` property in `AteEditorConfig` provides fine-grained control ov
|
|
|
524
541
|
```typescript
|
|
525
542
|
export interface AteImageUploadConfig {
|
|
526
543
|
/** Custom handler to upload files to a server */
|
|
527
|
-
handler?:
|
|
544
|
+
handler?: AteImageUploadHandler;
|
|
528
545
|
/** Maximum file size in bytes (default: 10MB) */
|
|
529
546
|
maxFileSize?: number;
|
|
530
547
|
/** Accepted file types (default: 'image/*') */
|
|
@@ -560,14 +577,14 @@ The editor comes with built-in support for **English (en)** and **French (fr)**,
|
|
|
560
577
|
|
|
561
578
|
### Adding Custom Languages
|
|
562
579
|
|
|
563
|
-
You can easily extend the editor with new languages or override existing labels using the `
|
|
580
|
+
You can easily extend the editor with new languages or override existing labels using the `AteI18nService`:
|
|
564
581
|
|
|
565
582
|
```typescript
|
|
566
|
-
import {
|
|
583
|
+
import { AteI18nService } from "@flogeez/angular-tiptap-editor";
|
|
567
584
|
|
|
568
585
|
@Component({ ... })
|
|
569
586
|
export class MyComponent {
|
|
570
|
-
constructor(private i18nService:
|
|
587
|
+
constructor(private i18nService: AteI18nService) {
|
|
571
588
|
// Add Spanish support
|
|
572
589
|
this.i18nService.addTranslations('es', {
|
|
573
590
|
toolbar: { bold: 'Negrita', italic: 'Cursiva', ... },
|
|
@@ -651,7 +668,7 @@ angular-tiptap-editor {
|
|
|
651
668
|
|
|
652
669
|
### ⚡ Reactive State & OnPush
|
|
653
670
|
|
|
654
|
-
The library exposes a reactive `editorState` signal via the `
|
|
671
|
+
The library exposes a reactive `editorState` signal via the `AteEditorCommandsService`. This signal contains everything you need to build custom UIs around the editor:
|
|
655
672
|
|
|
656
673
|
- **Active State**: Check if `bold`, `italic`, or custom marks are active.
|
|
657
674
|
- **Commands Availability**: Check if `undo`, `redo`, or custom commands can be executed.
|
|
@@ -686,13 +703,13 @@ The library uses a **Snapshot & Signal** pattern to bridge Tiptap and Angular.
|
|
|
686
703
|
|
|
687
704
|
### Core Services
|
|
688
705
|
|
|
689
|
-
- **`
|
|
690
|
-
- **`
|
|
691
|
-
- **`
|
|
706
|
+
- **`AteEditorCommandsService`**: Exposes the `editorState` signal and provides a centralized API for executing Tiptap commands.
|
|
707
|
+
- **`AteImageService`**: Manages the image processing pipeline (selection, compression, and server-side upload handling).
|
|
708
|
+
- **`AteI18nService`**: Reactive translation service with support for browser locale auto-detection.
|
|
692
709
|
|
|
693
710
|
### Isolated Instances
|
|
694
711
|
|
|
695
|
-
Each component instance provides its own set of services (`
|
|
712
|
+
Each component instance provides its own set of services (`AteEditorCommandsService`, `AteImageService`, etc.) at the component level. This ensures that multiple editors on the same page maintain independent states and configurations without interference.
|
|
696
713
|
|
|
697
714
|
### Modern Angular Integration
|
|
698
715
|
|
|
@@ -706,11 +723,11 @@ The library provides default configurations that can be imported and customized:
|
|
|
706
723
|
|
|
707
724
|
```typescript
|
|
708
725
|
import {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
726
|
+
ATE_DEFAULT_TOOLBAR_CONFIG,
|
|
727
|
+
ATE_DEFAULT_BUBBLE_MENU_CONFIG,
|
|
728
|
+
ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG,
|
|
729
|
+
ATE_DEFAULT_TABLE_MENU_CONFIG,
|
|
730
|
+
ATE_DEFAULT_SLASH_COMMANDS_CONFIG,
|
|
714
731
|
} from "@flogeez/angular-tiptap-editor";
|
|
715
732
|
```
|
|
716
733
|
|