@flogeez/angular-tiptap-editor 0.2.4 → 0.2.6
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
CHANGED
|
@@ -6,7 +6,7 @@ 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
|
|
9
|
+
- **Modern Angular**: Built with Angular 18+
|
|
10
10
|
- **Rich Text Editing**: Powered by Tiptap with extensive formatting options
|
|
11
11
|
- **Internationalization**: Full i18n support (English & French) with auto-detection
|
|
12
12
|
- **Customizable**: Highly configurable toolbar, bubble menus, and slash commands
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, output, Component, signal, computed, Injectable, inject, effect, ViewChild, viewChild,
|
|
3
|
-
import {
|
|
2
|
+
import { input, output, Component, signal, computed, Injectable, inject, effect, ViewChild, Directive, viewChild, DestroyRef } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { Node, nodeInputRule, mergeAttributes, Extension, Editor } from '@tiptap/core';
|
|
5
5
|
import StarterKit from '@tiptap/starter-kit';
|
|
6
6
|
import Placeholder from '@tiptap/extension-placeholder';
|
|
@@ -16,6 +16,8 @@ import { Plugin, PluginKey } from '@tiptap/pm/state';
|
|
|
16
16
|
import { DecorationSet, Decoration } from '@tiptap/pm/view';
|
|
17
17
|
import tippy from 'tippy.js';
|
|
18
18
|
import { Plugin as Plugin$1, PluginKey as PluginKey$1 } from 'prosemirror-state';
|
|
19
|
+
import { NG_VALUE_ACCESSOR, NgControl } from '@angular/forms';
|
|
20
|
+
import { tap } from 'rxjs';
|
|
19
21
|
|
|
20
22
|
const ResizableImage = Node.create({
|
|
21
23
|
name: "resizableImage",
|
|
@@ -3495,6 +3497,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
|
|
|
3495
3497
|
args: ["menuRef", { static: false }]
|
|
3496
3498
|
}] } });
|
|
3497
3499
|
|
|
3500
|
+
class NoopValueAccessorDirective {
|
|
3501
|
+
writeValue(obj) { }
|
|
3502
|
+
registerOnChange(fn) { }
|
|
3503
|
+
registerOnTouched(fn) { }
|
|
3504
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: NoopValueAccessorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
3505
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.0", type: NoopValueAccessorDirective, isStandalone: true, providers: [
|
|
3506
|
+
{
|
|
3507
|
+
provide: NG_VALUE_ACCESSOR,
|
|
3508
|
+
multi: true,
|
|
3509
|
+
useExisting: NoopValueAccessorDirective,
|
|
3510
|
+
},
|
|
3511
|
+
], ngImport: i0 }); }
|
|
3512
|
+
}
|
|
3513
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: NoopValueAccessorDirective, decorators: [{
|
|
3514
|
+
type: Directive,
|
|
3515
|
+
args: [{
|
|
3516
|
+
standalone: true,
|
|
3517
|
+
providers: [
|
|
3518
|
+
{
|
|
3519
|
+
provide: NG_VALUE_ACCESSOR,
|
|
3520
|
+
multi: true,
|
|
3521
|
+
useExisting: NoopValueAccessorDirective,
|
|
3522
|
+
},
|
|
3523
|
+
],
|
|
3524
|
+
}]
|
|
3525
|
+
}] });
|
|
3526
|
+
|
|
3498
3527
|
// Configuration par défaut de la toolbar
|
|
3499
3528
|
const DEFAULT_TOOLBAR_CONFIG = {
|
|
3500
3529
|
bold: true,
|
|
@@ -3546,8 +3575,7 @@ const DEFAULT_IMAGE_BUBBLE_MENU_CONFIG = {
|
|
|
3546
3575
|
separator: true,
|
|
3547
3576
|
};
|
|
3548
3577
|
class AngularTiptapEditorComponent {
|
|
3549
|
-
constructor(
|
|
3550
|
-
this.imageService = imageService;
|
|
3578
|
+
constructor() {
|
|
3551
3579
|
// Nouveaux inputs avec signal
|
|
3552
3580
|
this.content = input("");
|
|
3553
3581
|
this.placeholder = input("");
|
|
@@ -3647,10 +3675,11 @@ class AngularTiptapEditorComponent {
|
|
|
3647
3675
|
// Configuration par défaut si aucune n'est fournie
|
|
3648
3676
|
return { commands: undefined }; // Le composant utilisera DEFAULT_SLASH_COMMANDS
|
|
3649
3677
|
});
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
this.
|
|
3678
|
+
this._destroyRef = inject(DestroyRef);
|
|
3679
|
+
// NgControl pour gérer les FormControls
|
|
3680
|
+
this.ngControl = inject(NgControl, { self: true, optional: true });
|
|
3653
3681
|
this.i18nService = inject(TiptapI18nService);
|
|
3682
|
+
this.imageService = inject(ImageService);
|
|
3654
3683
|
// Effet pour gérer le changement de langue
|
|
3655
3684
|
effect(() => {
|
|
3656
3685
|
const locale = this.locale();
|
|
@@ -3690,14 +3719,11 @@ class AngularTiptapEditorComponent {
|
|
|
3690
3719
|
}
|
|
3691
3720
|
});
|
|
3692
3721
|
}
|
|
3693
|
-
ngOnInit() {
|
|
3694
|
-
// L'initialisation se fait maintenant dans ngAfterViewInit
|
|
3695
|
-
}
|
|
3696
3722
|
ngAfterViewInit() {
|
|
3697
|
-
//
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3723
|
+
// La vue est déjà complètement initialisée dans ngAfterViewInit
|
|
3724
|
+
this.initEditor();
|
|
3725
|
+
// S'abonner aux changements du FormControl
|
|
3726
|
+
this.setupFormControlSubscription();
|
|
3701
3727
|
}
|
|
3702
3728
|
ngOnDestroy() {
|
|
3703
3729
|
const currentEditor = this.editor();
|
|
@@ -3764,18 +3790,18 @@ class AngularTiptapEditorComponent {
|
|
|
3764
3790
|
onUpdate: ({ editor, transaction }) => {
|
|
3765
3791
|
const html = editor.getHTML();
|
|
3766
3792
|
this.contentChange.emit(html);
|
|
3767
|
-
//
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3793
|
+
// Mettre à jour le FormControl si il existe (dans le prochain cycle)
|
|
3794
|
+
if (this.ngControl?.control) {
|
|
3795
|
+
setTimeout(() => {
|
|
3796
|
+
this.ngControl.control.setValue(html, {
|
|
3797
|
+
emitEvent: false,
|
|
3798
|
+
});
|
|
3799
|
+
}, 0);
|
|
3800
|
+
}
|
|
3771
3801
|
this.editorUpdate.emit({ editor, transaction });
|
|
3772
3802
|
this.updateCharacterCount(editor);
|
|
3773
3803
|
},
|
|
3774
|
-
onSelectionUpdate: ({ editor, transaction }) => {
|
|
3775
|
-
// Note: La mise à jour des états des boutons est maintenant gérée par TiptapBubbleMenuComponent
|
|
3776
|
-
},
|
|
3777
3804
|
onCreate: ({ editor }) => {
|
|
3778
|
-
this.editor.set(editor);
|
|
3779
3805
|
this.editorCreated.emit(editor);
|
|
3780
3806
|
this.updateCharacterCount(editor);
|
|
3781
3807
|
// Marquer l'éditeur comme complètement initialisé après un court délai
|
|
@@ -3788,10 +3814,20 @@ class AngularTiptapEditorComponent {
|
|
|
3788
3814
|
this.editorFocus.emit({ editor, event });
|
|
3789
3815
|
},
|
|
3790
3816
|
onBlur: ({ editor, event }) => {
|
|
3791
|
-
|
|
3817
|
+
// Marquer le FormControl comme touché si il existe
|
|
3818
|
+
if (this.ngControl?.control) {
|
|
3819
|
+
this.ngControl.control.markAsTouched();
|
|
3820
|
+
}
|
|
3792
3821
|
this.editorBlur.emit({ editor, event });
|
|
3793
3822
|
},
|
|
3794
3823
|
});
|
|
3824
|
+
// Stocker la référence de l'éditeur immédiatement
|
|
3825
|
+
this.editor.set(newEditor);
|
|
3826
|
+
// Vérifier si on a un contenu initial via l'input content()
|
|
3827
|
+
const initialContent = this.content();
|
|
3828
|
+
if (initialContent) {
|
|
3829
|
+
this.setContent(initialContent, false);
|
|
3830
|
+
}
|
|
3795
3831
|
}
|
|
3796
3832
|
updateCharacterCount(editor) {
|
|
3797
3833
|
if (this.showCharacterCount() && editor.storage["characterCount"]) {
|
|
@@ -3880,19 +3916,37 @@ class AngularTiptapEditorComponent {
|
|
|
3880
3916
|
clearContent() {
|
|
3881
3917
|
this.editor()?.commands.clearContent();
|
|
3882
3918
|
}
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3919
|
+
normalizeHTML(html) {
|
|
3920
|
+
if (!html)
|
|
3921
|
+
return "";
|
|
3922
|
+
// Normaliser les espaces et retours à la ligne pour une comparaison fiable
|
|
3923
|
+
return html
|
|
3924
|
+
.replace(/\s+/g, " ") // Remplacer espaces multiples par un seul
|
|
3925
|
+
.replace(/>\s+</g, "><") // Supprimer espaces entre balises
|
|
3926
|
+
.replace(/<br\s*\/?>/gi, "<br>") // Normaliser les <br>
|
|
3927
|
+
.trim();
|
|
3928
|
+
}
|
|
3929
|
+
checkInitialFormValue() {
|
|
3930
|
+
// Vérifier si on a une valeur initiale dans le FormControl
|
|
3931
|
+
if (this.ngControl?.control?.value) {
|
|
3932
|
+
console.log("Found initial FormControl value:", this.ngControl.control.value);
|
|
3933
|
+
this.setContent(this.ngControl.control.value, false);
|
|
3888
3934
|
}
|
|
3889
3935
|
}
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3936
|
+
setupFormControlSubscription() {
|
|
3937
|
+
const control = this.ngControl?.control;
|
|
3938
|
+
if (control) {
|
|
3939
|
+
control.valueChanges
|
|
3940
|
+
.pipe(tap((value) => {
|
|
3941
|
+
const editor = this.editor();
|
|
3942
|
+
if (editor && value !== editor.getHTML()) {
|
|
3943
|
+
this.setContent(value, false);
|
|
3944
|
+
}
|
|
3945
|
+
}), takeUntilDestroyed(this._destroyRef))
|
|
3946
|
+
.subscribe();
|
|
3947
|
+
}
|
|
3895
3948
|
}
|
|
3949
|
+
// Méthode pour gérer l'état disabled
|
|
3896
3950
|
setDisabledState(isDisabled) {
|
|
3897
3951
|
const currentEditor = this.editor();
|
|
3898
3952
|
if (currentEditor) {
|
|
@@ -3917,14 +3971,8 @@ class AngularTiptapEditorComponent {
|
|
|
3917
3971
|
}, 0);
|
|
3918
3972
|
}
|
|
3919
3973
|
}
|
|
3920
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AngularTiptapEditorComponent, deps: [
|
|
3921
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: AngularTiptapEditorComponent, isStandalone: true, selector: "angular-tiptap-editor", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, showCharacterCount: { classPropertyName: "showCharacterCount", publicName: "showCharacterCount", isSignal: true, isRequired: false, transformFunction: null }, maxCharacters: { classPropertyName: "maxCharacters", publicName: "maxCharacters", isSignal: true, isRequired: false, transformFunction: null }, enableOfficePaste: { classPropertyName: "enableOfficePaste", publicName: "enableOfficePaste", isSignal: true, isRequired: false, transformFunction: null }, enableSlashCommands: { classPropertyName: "enableSlashCommands", publicName: "enableSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, slashCommandsConfig: { classPropertyName: "slashCommandsConfig", publicName: "slashCommandsConfig", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, showBubbleMenu: { classPropertyName: "showBubbleMenu", publicName: "showBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, bubbleMenu: { classPropertyName: "bubbleMenu", publicName: "bubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showImageBubbleMenu: { classPropertyName: "showImageBubbleMenu", publicName: "showImageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, imageBubbleMenu: { classPropertyName: "imageBubbleMenu", publicName: "imageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, toolbar: { classPropertyName: "toolbar", publicName: "toolbar", isSignal: true, isRequired: false, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contentChange: "contentChange", editorCreated: "editorCreated", editorUpdate: "editorUpdate", editorFocus: "editorFocus", editorBlur: "editorBlur" },
|
|
3922
|
-
{
|
|
3923
|
-
provide: NG_VALUE_ACCESSOR,
|
|
3924
|
-
useExisting: forwardRef(() => AngularTiptapEditorComponent),
|
|
3925
|
-
multi: true,
|
|
3926
|
-
},
|
|
3927
|
-
], viewQueries: [{ propertyName: "editorElement", first: true, predicate: ["editorElement"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
3974
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AngularTiptapEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3975
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: AngularTiptapEditorComponent, isStandalone: true, selector: "angular-tiptap-editor", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, showCharacterCount: { classPropertyName: "showCharacterCount", publicName: "showCharacterCount", isSignal: true, isRequired: false, transformFunction: null }, maxCharacters: { classPropertyName: "maxCharacters", publicName: "maxCharacters", isSignal: true, isRequired: false, transformFunction: null }, enableOfficePaste: { classPropertyName: "enableOfficePaste", publicName: "enableOfficePaste", isSignal: true, isRequired: false, transformFunction: null }, enableSlashCommands: { classPropertyName: "enableSlashCommands", publicName: "enableSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, slashCommandsConfig: { classPropertyName: "slashCommandsConfig", publicName: "slashCommandsConfig", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, showBubbleMenu: { classPropertyName: "showBubbleMenu", publicName: "showBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, bubbleMenu: { classPropertyName: "bubbleMenu", publicName: "bubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showImageBubbleMenu: { classPropertyName: "showImageBubbleMenu", publicName: "showImageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, imageBubbleMenu: { classPropertyName: "imageBubbleMenu", publicName: "imageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, toolbar: { classPropertyName: "toolbar", publicName: "toolbar", isSignal: true, isRequired: false, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contentChange: "contentChange", editorCreated: "editorCreated", editorUpdate: "editorUpdate", editorFocus: "editorFocus", editorBlur: "editorBlur" }, viewQueries: [{ propertyName: "editorElement", first: true, predicate: ["editorElement"], descendants: true, isSignal: true }], hostDirectives: [{ directive: NoopValueAccessorDirective }], ngImport: i0, template: `
|
|
3928
3976
|
<div class="tiptap-editor">
|
|
3929
3977
|
<!-- Toolbar -->
|
|
3930
3978
|
@if (showToolbar() && editor()) {
|
|
@@ -3993,7 +4041,7 @@ class AngularTiptapEditorComponent {
|
|
|
3993
4041
|
}
|
|
3994
4042
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AngularTiptapEditorComponent, decorators: [{
|
|
3995
4043
|
type: Component,
|
|
3996
|
-
args: [{ selector: "angular-tiptap-editor", standalone: true, imports: [
|
|
4044
|
+
args: [{ selector: "angular-tiptap-editor", standalone: true, hostDirectives: [NoopValueAccessorDirective], imports: [
|
|
3997
4045
|
TiptapToolbarComponent,
|
|
3998
4046
|
TiptapImageUploadComponent,
|
|
3999
4047
|
TiptapBubbleMenuComponent,
|
|
@@ -4064,14 +4112,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
|
|
|
4064
4112
|
</div>
|
|
4065
4113
|
}
|
|
4066
4114
|
</div>
|
|
4067
|
-
`,
|
|
4068
|
-
|
|
4069
|
-
provide: NG_VALUE_ACCESSOR,
|
|
4070
|
-
useExisting: forwardRef(() => AngularTiptapEditorComponent),
|
|
4071
|
-
multi: true,
|
|
4072
|
-
},
|
|
4073
|
-
], styles: [".tiptap-editor{border:2px solid #e2e8f0;border-radius:8px;background:#fff;box-shadow:0 2px 4px #0000001a;overflow:hidden;transition:border-color .2s ease}.tiptap-editor:focus-within{border-color:#3182ce;box-shadow:0 0 0 3px #3182ce1a}.tiptap-content{padding:16px;min-height:var(--editor-min-height, 200px);height:var(--editor-height, auto);max-height:var(--editor-max-height, none);overflow-y:var(--editor-overflow, visible);outline:none;position:relative}.tiptap-content.drag-over{background:#f0f8ff;border:2px dashed #3182ce}.character-count{padding:8px 16px;font-size:12px;color:#718096;text-align:right;border-top:1px solid #e2e8f0;background:#f8f9fa}.image-upload-container{position:relative;display:inline-block}:host ::ng-deep .ProseMirror{outline:none;line-height:1.6;color:#2d3748;min-height:100%;height:100%;word-wrap:break-word;overflow-wrap:break-word}:host ::ng-deep .ProseMirror h1{font-size:2em;font-weight:700;margin-top:0;margin-bottom:.5em}:host ::ng-deep .ProseMirror h2{font-size:1.5em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror h3{font-size:1.25em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror p{margin:.5em 0}:host ::ng-deep .ProseMirror ul,:host ::ng-deep .ProseMirror ol{padding-left:2em;margin:.5em 0}:host ::ng-deep .ProseMirror blockquote{border-left:4px solid #e2e8f0;margin:1em 0;font-style:italic;background:#f8f9fa;padding:.5em 1em;border-radius:0 4px 4px 0}:host ::ng-deep .ProseMirror code{background:#f1f5f9;padding:.2em .4em;border-radius:3px;font-family:Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .ProseMirror pre{background:#1a202c;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;margin:1em 0}:host ::ng-deep .ProseMirror pre code{background:none;color:inherit;padding:0}:host ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:#a0aec0;pointer-events:none;float:left;height:0}:host ::ng-deep .ProseMirror[contenteditable=false]{pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img{cursor:default;pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img:hover{transform:none;box-shadow:0 2px 8px #0000001a}:host ::ng-deep .ProseMirror[contenteditable=false] img.ProseMirror-selectednode{outline:none}:host ::ng-deep .ProseMirror img{position:relative;display:inline-block;max-width:100%;height:auto;cursor:pointer;transition:all .2s ease;border:2px solid transparent;border-radius:8px}:host ::ng-deep .ProseMirror img:hover{border-color:#e2e8f0;box-shadow:0 2px 4px #0000001a}:host ::ng-deep .ProseMirror img.ProseMirror-selectednode{border-color:#3182ce;box-shadow:0 0 0 3px #3182ce1a;transition:all .2s ease}:host ::ng-deep .ProseMirror .tiptap-image{max-width:100%;height:auto;border-radius:16px;box-shadow:0 4px 20px #00000014;margin:.5em 0;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);display:block;filter:brightness(1) contrast(1)}:host ::ng-deep .ProseMirror .tiptap-image:hover{box-shadow:0 8px 30px #0000001f;filter:brightness(1.02) contrast(1.02)}:host ::ng-deep .ProseMirror .tiptap-image.ProseMirror-selectednode{outline:2px solid #6366f1;outline-offset:2px;border-radius:16px;box-shadow:0 0 0 4px #6366f11a}:host ::ng-deep .image-container{margin:.5em 0;text-align:center;border-radius:16px;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1)}:host ::ng-deep .image-container.image-align-left{text-align:left}:host ::ng-deep .image-container.image-align-center{text-align:center}:host ::ng-deep .image-container.image-align-right{text-align:right}:host ::ng-deep .image-container img{display:inline-block;max-width:100%;height:auto;border-radius:16px}:host ::ng-deep .resizable-image-container{position:relative;display:inline-block;margin:.5em 0}:host ::ng-deep .resize-controls{position:absolute;inset:0;pointer-events:none;z-index:1000}:host ::ng-deep .resize-handle{position:absolute;width:12px;height:12px;background:#3b82f6;border:2px solid white;border-radius:50%;pointer-events:all;cursor:pointer;z-index:1001;transition:all .15s ease;box-shadow:0 2px 6px #0003}:host ::ng-deep .resize-handle:hover{background:#2563eb;box-shadow:0 3px 8px #0000004d}:host ::ng-deep .resize-handle:active{background:#1d4ed8}:host ::ng-deep .resize-handle-n:hover,:host ::ng-deep .resize-handle-s:hover{transform:translate(-50%) scale(1.2)}:host ::ng-deep .resize-handle-w:hover,:host ::ng-deep .resize-handle-e:hover{transform:translateY(-50%) scale(1.2)}:host ::ng-deep .resize-handle-n:active,:host ::ng-deep .resize-handle-s:active{transform:translate(-50%) scale(.9)}:host ::ng-deep .resize-handle-w:active,:host ::ng-deep .resize-handle-e:active{transform:translateY(-50%) scale(.9)}:host ::ng-deep .resize-handle-nw:hover,:host ::ng-deep .resize-handle-ne:hover,:host ::ng-deep .resize-handle-sw:hover,:host ::ng-deep .resize-handle-se:hover{transform:scale(1.2)}:host ::ng-deep .resize-handle-nw:active,:host ::ng-deep .resize-handle-ne:active,:host ::ng-deep .resize-handle-sw:active,:host ::ng-deep .resize-handle-se:active{transform:scale(.9)}:host ::ng-deep .resize-handle-nw{top:0;left:-6px;cursor:nw-resize}:host ::ng-deep .resize-handle-n{top:0;left:50%;transform:translate(-50%);cursor:n-resize}:host ::ng-deep .resize-handle-ne{top:0;right:-6px;cursor:ne-resize}:host ::ng-deep .resize-handle-w{top:50%;left:-6px;transform:translateY(-50%);cursor:w-resize}:host ::ng-deep .resize-handle-e{top:50%;right:-6px;transform:translateY(-50%);cursor:e-resize}:host ::ng-deep .resize-handle-sw{bottom:0;left:-6px;cursor:sw-resize}:host ::ng-deep .resize-handle-s{bottom:0;left:50%;transform:translate(-50%);cursor:s-resize}:host ::ng-deep .resize-handle-se{bottom:0;right:-6px;cursor:se-resize}:host ::ng-deep body.resizing{-webkit-user-select:none;user-select:none;cursor:crosshair}:host ::ng-deep body.resizing .ProseMirror{pointer-events:none}:host ::ng-deep body.resizing .ProseMirror .tiptap-image{pointer-events:none}:host ::ng-deep .image-size-info{position:absolute;bottom:-20px;left:50%;transform:translate(-50%);background:#000c;color:#fff;padding:2px 6px;border-radius:3px;font-size:11px;white-space:nowrap;opacity:0;transition:opacity .2s ease}:host ::ng-deep .image-container:hover .image-size-info{opacity:1}\n"] }]
|
|
4074
|
-
}], ctorParameters: () => [{ type: ImageService }] });
|
|
4115
|
+
`, styles: [".tiptap-editor{border:2px solid #e2e8f0;border-radius:8px;background:#fff;box-shadow:0 2px 4px #0000001a;overflow:hidden;transition:border-color .2s ease}.tiptap-editor:focus-within{border-color:#3182ce;box-shadow:0 0 0 3px #3182ce1a}.tiptap-content{padding:16px;min-height:var(--editor-min-height, 200px);height:var(--editor-height, auto);max-height:var(--editor-max-height, none);overflow-y:var(--editor-overflow, visible);outline:none;position:relative}.tiptap-content.drag-over{background:#f0f8ff;border:2px dashed #3182ce}.character-count{padding:8px 16px;font-size:12px;color:#718096;text-align:right;border-top:1px solid #e2e8f0;background:#f8f9fa}.image-upload-container{position:relative;display:inline-block}:host ::ng-deep .ProseMirror{outline:none;line-height:1.6;color:#2d3748;min-height:100%;height:100%;word-wrap:break-word;overflow-wrap:break-word}:host ::ng-deep .ProseMirror h1{font-size:2em;font-weight:700;margin-top:0;margin-bottom:.5em}:host ::ng-deep .ProseMirror h2{font-size:1.5em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror h3{font-size:1.25em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror p{margin:.5em 0}:host ::ng-deep .ProseMirror ul,:host ::ng-deep .ProseMirror ol{padding-left:2em;margin:.5em 0}:host ::ng-deep .ProseMirror blockquote{border-left:4px solid #e2e8f0;margin:1em 0;font-style:italic;background:#f8f9fa;padding:.5em 1em;border-radius:0 4px 4px 0}:host ::ng-deep .ProseMirror code{background:#f1f5f9;padding:.2em .4em;border-radius:3px;font-family:Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .ProseMirror pre{background:#1a202c;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;margin:1em 0}:host ::ng-deep .ProseMirror pre code{background:none;color:inherit;padding:0}:host ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:#a0aec0;pointer-events:none;float:left;height:0}:host ::ng-deep .ProseMirror[contenteditable=false]{pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img{cursor:default;pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img:hover{transform:none;box-shadow:0 2px 8px #0000001a}:host ::ng-deep .ProseMirror[contenteditable=false] img.ProseMirror-selectednode{outline:none}:host ::ng-deep .ProseMirror img{position:relative;display:inline-block;max-width:100%;height:auto;cursor:pointer;transition:all .2s ease;border:2px solid transparent;border-radius:8px}:host ::ng-deep .ProseMirror img:hover{border-color:#e2e8f0;box-shadow:0 2px 4px #0000001a}:host ::ng-deep .ProseMirror img.ProseMirror-selectednode{border-color:#3182ce;box-shadow:0 0 0 3px #3182ce1a;transition:all .2s ease}:host ::ng-deep .ProseMirror .tiptap-image{max-width:100%;height:auto;border-radius:16px;box-shadow:0 4px 20px #00000014;margin:.5em 0;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);display:block;filter:brightness(1) contrast(1)}:host ::ng-deep .ProseMirror .tiptap-image:hover{box-shadow:0 8px 30px #0000001f;filter:brightness(1.02) contrast(1.02)}:host ::ng-deep .ProseMirror .tiptap-image.ProseMirror-selectednode{outline:2px solid #6366f1;outline-offset:2px;border-radius:16px;box-shadow:0 0 0 4px #6366f11a}:host ::ng-deep .image-container{margin:.5em 0;text-align:center;border-radius:16px;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1)}:host ::ng-deep .image-container.image-align-left{text-align:left}:host ::ng-deep .image-container.image-align-center{text-align:center}:host ::ng-deep .image-container.image-align-right{text-align:right}:host ::ng-deep .image-container img{display:inline-block;max-width:100%;height:auto;border-radius:16px}:host ::ng-deep .resizable-image-container{position:relative;display:inline-block;margin:.5em 0}:host ::ng-deep .resize-controls{position:absolute;inset:0;pointer-events:none;z-index:1000}:host ::ng-deep .resize-handle{position:absolute;width:12px;height:12px;background:#3b82f6;border:2px solid white;border-radius:50%;pointer-events:all;cursor:pointer;z-index:1001;transition:all .15s ease;box-shadow:0 2px 6px #0003}:host ::ng-deep .resize-handle:hover{background:#2563eb;box-shadow:0 3px 8px #0000004d}:host ::ng-deep .resize-handle:active{background:#1d4ed8}:host ::ng-deep .resize-handle-n:hover,:host ::ng-deep .resize-handle-s:hover{transform:translate(-50%) scale(1.2)}:host ::ng-deep .resize-handle-w:hover,:host ::ng-deep .resize-handle-e:hover{transform:translateY(-50%) scale(1.2)}:host ::ng-deep .resize-handle-n:active,:host ::ng-deep .resize-handle-s:active{transform:translate(-50%) scale(.9)}:host ::ng-deep .resize-handle-w:active,:host ::ng-deep .resize-handle-e:active{transform:translateY(-50%) scale(.9)}:host ::ng-deep .resize-handle-nw:hover,:host ::ng-deep .resize-handle-ne:hover,:host ::ng-deep .resize-handle-sw:hover,:host ::ng-deep .resize-handle-se:hover{transform:scale(1.2)}:host ::ng-deep .resize-handle-nw:active,:host ::ng-deep .resize-handle-ne:active,:host ::ng-deep .resize-handle-sw:active,:host ::ng-deep .resize-handle-se:active{transform:scale(.9)}:host ::ng-deep .resize-handle-nw{top:0;left:-6px;cursor:nw-resize}:host ::ng-deep .resize-handle-n{top:0;left:50%;transform:translate(-50%);cursor:n-resize}:host ::ng-deep .resize-handle-ne{top:0;right:-6px;cursor:ne-resize}:host ::ng-deep .resize-handle-w{top:50%;left:-6px;transform:translateY(-50%);cursor:w-resize}:host ::ng-deep .resize-handle-e{top:50%;right:-6px;transform:translateY(-50%);cursor:e-resize}:host ::ng-deep .resize-handle-sw{bottom:0;left:-6px;cursor:sw-resize}:host ::ng-deep .resize-handle-s{bottom:0;left:50%;transform:translate(-50%);cursor:s-resize}:host ::ng-deep .resize-handle-se{bottom:0;right:-6px;cursor:se-resize}:host ::ng-deep body.resizing{-webkit-user-select:none;user-select:none;cursor:crosshair}:host ::ng-deep body.resizing .ProseMirror{pointer-events:none}:host ::ng-deep body.resizing .ProseMirror .tiptap-image{pointer-events:none}:host ::ng-deep .image-size-info{position:absolute;bottom:-20px;left:50%;transform:translate(-50%);background:#000c;color:#fff;padding:2px 6px;border-radius:3px;font-size:11px;white-space:nowrap;opacity:0;transition:opacity .2s ease}:host ::ng-deep .image-container:hover .image-size-info{opacity:1}\n"] }]
|
|
4116
|
+
}], ctorParameters: () => [] });
|
|
4075
4117
|
|
|
4076
4118
|
/**
|
|
4077
4119
|
* Factory function pour créer les slash commands traduits
|
|
@@ -4236,5 +4278,5 @@ const SLASH_COMMAND_KEYS = {
|
|
|
4236
4278
|
* Generated bundle index. Do not edit.
|
|
4237
4279
|
*/
|
|
4238
4280
|
|
|
4239
|
-
export { AngularTiptapEditorComponent, DEFAULT_BUBBLE_MENU_CONFIG, DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, DEFAULT_SLASH_COMMANDS, DEFAULT_TOOLBAR_CONFIG, TiptapI18nService, createI18nSlashCommands };
|
|
4281
|
+
export { AngularTiptapEditorComponent, DEFAULT_BUBBLE_MENU_CONFIG, DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, DEFAULT_SLASH_COMMANDS, DEFAULT_TOOLBAR_CONFIG, NoopValueAccessorDirective, TiptapI18nService, createI18nSlashCommands };
|
|
4240
4282
|
//# sourceMappingURL=flogeez-angular-tiptap-editor.mjs.map
|