@flogeez/angular-tiptap-editor 0.6.0 → 2.0.0

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 CHANGED
@@ -5,6 +5,28 @@ 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).
7
7
 
8
+ ## [0.7.0] - 2026-01-17
9
+
10
+ ### Added
11
+ - **Extensible I18n**: The translation system is now open. You can add any language (e.g., `es`, `it`) via `addTranslations()`, and the `SupportedLocale` type now accepts any string with autocomplete for default languages.
12
+ - **Per-Instance I18n Override**: Added ability to define a specific language for a given editor instance via the `[locale]` input, without affecting the global language of other editors.
13
+ - **Global I18n Singleton**: The translation service is now a global singleton (`providedIn: 'root'`), allowing for application-wide language switching with a single call.
14
+ - **Seamless Mode**: Added `[seamless]` input to remove borders, backgrounds, and paddings.
15
+ - **Floating Toolbar**: Added `[floatingToolbar]` option for a sticky, auto-hiding toolbar with glassmorphism that only appears on focus or hover.
16
+ - **Improved Read-Only**: Refined the `[editable]="false"` behavior. Clicking in the empty space of a read-only editor no longer forces focus or moves the cursor. The toolbar and footer now correctly reflect the read-only state.
17
+ - **Code Block Support**: Added dedicated `CodeBlock` button to the toolbar and slash commands.
18
+ - **Precise Inline Code**: Separated "Inline Code" and "Code Block" in menus and translations for better clarity.
19
+
20
+ ### Fixed
21
+ - **Inline Code Toggle**: Fixed a reactivity bug where the "Code" button in the toolbar became disabled when already inside a code mark, preventing it from being toggled off.
22
+
23
+ ### Changed
24
+ - **Service Isolation**: `EditorCommandsService`, `LinkService`, `ColorPickerService`, and `ImageService` are no longer global (`root`). They are now provided at the component level for each editor instance, ensuring perfect isolation in multi-editor scenarios.
25
+ - **Internal Refactoring**: Systemic use of `currentTranslations` (computed signal) across all internal components for perfect reactivity to language changes.
26
+
27
+ ### Breaking Changes
28
+ - **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`).
29
+
8
30
  ## [0.6.0] - 2026-01-14
9
31
 
10
32
  ### Added
package/README.md CHANGED
@@ -6,19 +6,35 @@ A modern, customizable rich-text editor for Angular applications, built with Tip
6
6
 
7
7
  ## 🚀 Features
8
8
 
9
- - **Modern Angular**: Built with Angular 18+ with Signals and modern patterns
10
- - **Rich Text Editing**: Powered by Tiptap v2 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`
9
+ - **Modern Angular**: Built with Angular 18+ using Signals and modern patterns for peak performance.
10
+ - **Full Rich Text Power**: Powered by Tiptap v2 with extensive formatting and block capabilities.
11
+ - **Modern UX (Notion-like)**: Intuitive slash commands and bubble menus for a keyboard-first experience.
12
+ - **Highly Customizable**: Easily configure toolbars, bubble menus, and slash command items.
13
+ - **Signal-Based Reactivity**: Pure Signal architecture natively compatible with `ChangeDetectionStrategy.OnPush`.
14
+ - **Advanced Table Support**: Full table management with cell selection and context-aware bubble menus.
15
+ - **Professional Media**: Advanced image handling with resizing, auto-compression, and custom uploaders.
16
+ - **Built-in i18n**: English & French support with a reactive, extensible locale system.
17
+ - **Word/Character Count**: Real-time statistics with proper pluralization support.
18
+ - **Office-Ready**: Cleaned-up pasting from Microsoft Word and Excel to maintain layout integrity.
19
+ - **Service Driven**: Deep programmatic control via `EditorCommandsService` and isolated instances.
20
+ - **A11y First**: Built with accessibility best practices and full keyboard navigation.
21
+
22
+ ## 💎 Why this editor?
23
+
24
+ Most Angular wrappers for Tiptap provide a basic component but leave the heavy lifting to you. **Angular Tiptap Editor** is built to solve common production hurdles:
25
+
26
+ - **True Scalability**: Thanks to **isolated services** provided at the component level, you can host multiple independent editors with different configurations and languages on the same page without a single state leak.
27
+ - **OnPush by Default**: The entire UI (toolbar, menus) is powered by **Angular Signals**. The `editorState` snapshot logic ensures that your components only re-render when necessary, even in complex `OnPush` applications.
28
+ - **Deep i18n & Extensibility**: Not just English/French — you can inject **custom translations** and **custom Tiptap extensions**. Our `DiscoveryCalculator` automatically tracks any new mark or node you add, making them reactive without extra code.
29
+ - **Clean Office UX**: Professional-grade pasting from **Word and Excel** plus smart image handling (auto-compression, resizing handles) ensures a polished experience for end-users.
30
+
31
+ ## 🛠️ Extensions included
32
+
33
+ The library comes with a pre-configured set of standard and custom extensions:
34
+
35
+ - **Nodes**: `StarterKit`, `Heading`, `Table`, `Image`, `HorizontalRule`, `CodeBlock`.
36
+ - **Marks**: `Bold`, `Italic`, `Underline`, `Strike`, `Code`, `Link`, `Highlight`, `TextStyle`, `Color`, `Superscript`, `Subscript`.
37
+ - **Utilities**: `Placeholder`, `CharacterCount`, `Typography`, `Focus`, `BubbleMenu`, `Gapcursor`, `Dropcursor`, `ResizableImage` (Custom).
22
38
 
23
39
  ## 📦 Installation
24
40
 
@@ -188,7 +204,7 @@ export class FormComponent {
188
204
  }
189
205
  ```
190
206
 
191
- ### 4. Using EditorCommandsService
207
+ ### 5. Using EditorCommandsService
192
208
 
193
209
  ```typescript
194
210
  import { Component, inject } from "@angular/core";
@@ -242,7 +258,7 @@ export class CommandsComponent {
242
258
  }
243
259
  ```
244
260
 
245
- ### 5. Extending Reactive Editor State
261
+ ### 6. Extending Reactive Editor State
246
262
 
247
263
  The editor features a dual-layer state architecture: **Automatic Tracking** for simple extensions and **Custom Calculators** for advanced needs.
248
264
 
@@ -420,6 +436,8 @@ The `ImageUploadContext` provides:
420
436
 
421
437
  The handler must return an `ImageUploadHandlerResult` with at least a `src` property containing the image URL.
422
438
 
439
+ ---
440
+
423
441
 
424
442
  ### 📝 Word & Character Counting
425
443
 
@@ -462,56 +480,76 @@ Open [http://localhost:4200](http://localhost:4200) to view the demo.
462
480
  | `height` | `number` | `undefined` | Fixed height in pixels |
463
481
  | `maxHeight` | `number` | `undefined` | Maximum height in pixels |
464
482
  | `minHeight` | `number` | `200` | Minimum height in pixels |
483
+ | `maxCharacters` | `number` | `undefined` | Character limit |
465
484
  | `fillContainer` | `boolean` | `false` | Fill parent container height |
466
485
  | `autofocus` | `boolean \| 'start' \| 'end' \| 'all'` | `false` | Auto-focus behavior |
467
486
  | `showToolbar` | `boolean` | `true` | Show toolbar |
468
- | `showBubbleMenu` | `boolean` | `true` | Show bubble menu |
487
+ | `showBubbleMenu` | `boolean` | `true` | Show text bubble menu |
488
+ | `showImageBubbleMenu`| `boolean` | `true` | Show image bubble menu |
489
+ | `showTableBubbleMenu`| `boolean` | `true` | Show table bubble menu |
490
+ | `showCellBubbleMenu` | `boolean` | `true` | Show cell bubble menu |
491
+ | `enableSlashCommands`| `boolean` | `true` | Enable slash commands functionality|
492
+ | `enableOfficePaste` | `boolean` | `true` | Enable smart Office pasting |
469
493
  | `showCharacterCount` | `boolean` | `true` | Show character counter |
470
494
  | `showWordCount` | `boolean` | `true` | Show word counter |
471
495
  | `toolbar` | `ToolbarConfig` | All enabled | Toolbar configuration |
472
496
  | `bubbleMenu` | `BubbleMenuConfig` | All enabled | Bubble menu configuration |
497
+ | `imageBubbleMenu` | `ImageBubbleMenuConfig` | All enabled | Image bubble menu config |
498
+ | `tableBubbleMenu` | `TableBubbleMenuConfig` | All enabled | Table bubble menu config |
499
+ | `cellBubbleMenu` | `CellBubbleMenuConfig` | All enabled | Cell bubble menu config |
473
500
  | `slashCommands` | `SlashCommandsConfig` | All enabled | Slash commands configuration |
474
501
  | `imageUploadHandler` | `ImageUploadHandler` | `undefined` | Custom image upload function |
502
+ | `stateCalculators` | `StateCalculator[]` | `[]` | Custom reactive state logic |
475
503
  | `tiptapExtensions` | `(Extension \| Node \| Mark)[]` | `[]` | Additional Tiptap extensions |
476
504
  | `tiptapOptions` | `Partial<EditorOptions>` | `{}` | Additional Tiptap editor options |
477
505
 
478
506
 
479
-
480
507
  #### Outputs
481
508
 
482
509
  | Output | Type | Description |
483
510
  | --------------- | ----------------- | ------------------------------- |
484
511
  | `contentChange` | `string` | Emitted when content changes |
485
512
  | `editorCreated` | `Editor` | Emitted when editor is created |
513
+ | `editorUpdate` | `{editor, trans}` | Emitted on every editor update |
486
514
  | `editorFocus` | `{editor, event}` | Emitted when editor gains focus |
487
515
  | `editorBlur` | `{editor, event}` | Emitted when editor loses focus |
488
516
 
489
517
 
490
518
  ## 🌍 Internationalization
491
519
 
492
- The editor supports English and French with automatic browser language detection:
520
+ The editor comes with built-in support for **English (en)** and **French (fr)**, featuring automatic browser language detection.
493
521
 
494
- ```typescript
495
- // Force English
496
- <angular-tiptap-editor [locale]="'en'" />
522
+ ### Basic Usage
497
523
 
498
- // Force French
524
+ ```typescript
525
+ // Force a specific language
499
526
  <angular-tiptap-editor [locale]="'fr'" />
500
527
 
501
528
  // Auto-detect (default)
502
529
  <angular-tiptap-editor />
503
530
  ```
504
531
 
505
- ### Available Translations
532
+ ### Adding Custom Languages
533
+
534
+ You can easily extend the editor with new languages or override existing labels using the `TiptapI18nService`:
506
535
 
507
- - **English (en)**: Default language with complete translations
508
- - **French (fr)**: Full French translation including:
509
- - Toolbar buttons
510
- - Bubble menu items
511
- - Slash commands
512
- - Placeholder text
513
- - Error messages
514
- - Word/character count (with proper pluralization)
536
+ ```typescript
537
+ import { TiptapI18nService } from "@flogeez/angular-tiptap-editor";
538
+
539
+ @Component({ ... })
540
+ export class MyComponent {
541
+ constructor(private i18nService: TiptapI18nService) {
542
+ // Add Spanish support
543
+ this.i18nService.addTranslations('es', {
544
+ toolbar: { bold: 'Negrita', italic: 'Cursiva', ... },
545
+ editor: { placeholder: 'Empieza a escribir...' }
546
+ });
547
+
548
+ // Switch to Spanish
549
+ this.i18nService.setLocale('es');
550
+ }
551
+ }
552
+ ```
515
553
 
516
554
 
517
555
  ### 🎨 CSS Custom Properties
@@ -584,6 +622,30 @@ angular-tiptap-editor {
584
622
  ```
585
623
 
586
624
 
625
+ ### ⚡ Reactive State & OnPush
626
+
627
+ The library exposes a reactive `editorState` signal via the `EditorCommandsService`. This signal contains everything you need to build custom UIs around the editor:
628
+
629
+ - **Active State**: Check if `bold`, `italic`, or custom marks are active.
630
+ - **Commands Availability**: Check if `undo`, `redo`, or custom commands can be executed.
631
+ - **Structural Data**: Access table status, image attributes, or selection details.
632
+
633
+ Since it's built with Signals, your custom toolbar items or UI overlays will only re-render when the specific data they consume changes, making it extremely efficient for `OnPush` applications.
634
+
635
+ ---
636
+
637
+ ### 🧩 Custom Tiptap Extensions
638
+
639
+ You are not limited to the built-in extensions. Pass any Tiptap extension, mark, or node:
640
+
641
+ ```html
642
+ <angular-tiptap-editor [tiptapExtensions]="[MyCustomExtension]" />
643
+ ```
644
+
645
+ Any custom extension is automatically detected and its state (active/can) is added to the reactive `editorState` snapshot.
646
+
647
+ ---
648
+
587
649
  ## 🏗️ Architecture
588
650
 
589
651
  ### Reactive State Management