@flogeez/angular-tiptap-editor 0.5.2 → 0.5.4

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, Component, Injectable, signal, computed, viewChild, inject, effect, ViewChild, Directive, DestroyRef } from '@angular/core';
2
+ import { input, output, Component, Injectable, signal, computed, viewChild, inject, PLATFORM_ID, effect, HostListener, ViewChild, Directive, DestroyRef } from '@angular/core';
3
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';
@@ -22,8 +22,8 @@ import TableCell from '@tiptap/extension-table-cell';
22
22
  import TableHeader from '@tiptap/extension-table-header';
23
23
  import tippy from 'tippy.js';
24
24
  import { CellSelection } from '@tiptap/pm/tables';
25
+ import { isPlatformBrowser, CommonModule } from '@angular/common';
25
26
  import { isObservable, firstValueFrom, concat, defer, of, tap } from 'rxjs';
26
- import { CommonModule } from '@angular/common';
27
27
  import { Plugin as Plugin$1, PluginKey as PluginKey$1 } from 'prosemirror-state';
28
28
  import { NG_VALUE_ACCESSOR, NgControl } from '@angular/forms';
29
29
 
@@ -523,11 +523,12 @@ const TableExtension = Extension.create({
523
523
  class TiptapButtonComponent {
524
524
  constructor() {
525
525
  // Inputs
526
- this.icon = input.required();
526
+ this.icon = input("");
527
527
  this.title = input.required();
528
528
  this.active = input(false);
529
529
  this.disabled = input(false);
530
530
  this.color = input();
531
+ this.backgroundColor = input();
531
532
  this.variant = input("default");
532
533
  this.size = input("medium");
533
534
  this.iconSize = input("medium");
@@ -538,7 +539,7 @@ class TiptapButtonComponent {
538
539
  event.preventDefault();
539
540
  }
540
541
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
541
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.0", type: TiptapButtonComponent, isStandalone: true, selector: "tiptap-button", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, iconSize: { classPropertyName: "iconSize", publicName: "iconSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClick: "onClick" }, ngImport: i0, template: `
542
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapButtonComponent, isStandalone: true, selector: "tiptap-button", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, backgroundColor: { classPropertyName: "backgroundColor", publicName: "backgroundColor", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, iconSize: { classPropertyName: "iconSize", publicName: "iconSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClick: "onClick" }, ngImport: i0, template: `
542
543
  <button
543
544
  class="tiptap-button"
544
545
  [class.is-active]="active()"
@@ -549,23 +550,26 @@ class TiptapButtonComponent {
549
550
  [class.medium]="size() === 'medium'"
550
551
  [class.large]="size() === 'large'"
551
552
  [class.has-custom-color]="!!color()"
553
+ [class.has-custom-bg]="!!backgroundColor()"
552
554
  [disabled]="disabled()"
553
555
  [style.color]="color()"
556
+ [style.background-color]="backgroundColor()"
554
557
  [attr.title]="title()"
555
558
  (mousedown)="onMouseDown($event)"
556
559
  (click)="onClick.emit($event)"
557
560
  type="button"
558
561
  >
559
- <span
560
- class="material-symbols-outlined"
561
- [class.icon-small]="iconSize() === 'small'"
562
- [class.icon-medium]="iconSize() === 'medium'"
563
- [class.icon-large]="iconSize() === 'large'"
564
- >{{ icon() }}</span
565
- >
562
+ @if (icon()) {
563
+ <span
564
+ class="material-symbols-outlined"
565
+ [class.icon-small]="iconSize() === 'small'"
566
+ [class.icon-medium]="iconSize() === 'medium'"
567
+ [class.icon-large]="iconSize() === 'large'"
568
+ >{{ icon() }}</span>
569
+ }
566
570
  <ng-content></ng-content>
567
571
  </button>
568
- `, isInline: true, styles: [".tiptap-button{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;border-radius:var(--ate-border-radius, 8px);cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);color:var(--ate-toolbar-button-color, var(--ate-text-secondary));position:relative;overflow:hidden}.tiptap-button:before{content:\"\";position:absolute;inset:0;background:var(--ate-primary);opacity:0;transition:opacity .2s ease;border-radius:var(--ate-border-radius, 8px)}.tiptap-button:hover:not(.has-custom-color){color:var(--ate-toolbar-button-active-color, var(--ate-primary));background:var(--ate-toolbar-button-hover-background, transparent);transform:translateY(-1px)}.tiptap-button.has-custom-color:hover{background:var(--ate-toolbar-button-hover-background, transparent);transform:translateY(-1px)}.tiptap-button:hover:before{opacity:.1}.tiptap-button:active{transform:translateY(0)}.tiptap-button.is-active:not(.has-custom-color){color:var(--ate-toolbar-button-active-color, var(--ate-primary));background:var(--ate-toolbar-button-active-background, var(--ate-primary-light))}.tiptap-button.is-active.has-custom-color{background:var(--ate-toolbar-button-active-background, var(--ate-primary-light))}.tiptap-button:disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.tiptap-button .material-symbols-outlined{font-size:20px;position:relative;z-index:1}.tiptap-button .material-symbols-outlined.icon-small{font-size:16px}.tiptap-button .material-symbols-outlined.icon-medium{font-size:20px}.tiptap-button .material-symbols-outlined.icon-large{font-size:24px}.tiptap-button.text-button{width:auto;padding:0 12px;font-size:14px;font-weight:500;gap:8px}.tiptap-button.color-button{width:28px;height:28px;border-radius:50%;border:2px solid transparent;transition:all .2s ease}.tiptap-button.color-button:hover{border-color:var(--ate-border);transform:scale(1.1)}.tiptap-button.color-button.is-active{border-color:var(--ate-primary);box-shadow:0 0 0 2px var(--ate-primary-light)}.tiptap-button.danger{color:var(--ate-error-color, #ef4444)}.tiptap-button.danger:hover{background:var(--ate-error-bg, rgba(239, 68, 68, .1))}.tiptap-button.danger:before{background:var(--ate-error-color, #ef4444)}.tiptap-button.small{width:24px;height:24px}.tiptap-button.medium{width:32px;height:32px}.tiptap-button.large{width:40px;height:40px}@keyframes pulse{0%,to{box-shadow:0 0 0 0 var(--ate-primary-light-alpha)}50%{box-shadow:0 0 0 4px transparent}}.tiptap-button.is-active.pulse{animation:pulse 2s infinite}@media (max-width: 768px){.tiptap-button{width:32px;height:32px}.tiptap-button .material-symbols-outlined{font-size:18px}.tiptap-button.text-button{padding:0 8px;font-size:13px}}\n"] }); }
572
+ `, isInline: true, styles: [".tiptap-button{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;border-radius:var(--ate-border-radius, 8px);cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);color:var(--ate-toolbar-button-color, var(--ate-text-secondary));position:relative;overflow:hidden}.tiptap-button:before{content:\"\";position:absolute;inset:0;background:var(--ate-primary);opacity:0;transition:opacity .2s ease;border-radius:var(--ate-border-radius, 8px)}.tiptap-button:hover:not(.has-custom-color){color:var(--ate-toolbar-button-active-color, var(--ate-primary));background:var(--ate-toolbar-button-hover-background, transparent);transform:translateY(-1px)}.tiptap-button.has-custom-color:hover:not(.has-custom-bg){background:var(--ate-toolbar-button-hover-background, transparent);transform:translateY(-1px)}.tiptap-button.has-custom-bg:hover{transform:translateY(-1px);filter:brightness(.9)}.tiptap-button:hover:before{opacity:.1}.tiptap-button:active{transform:translateY(0)}.tiptap-button.is-active:not(.has-custom-color){color:var(--ate-toolbar-button-active-color, var(--ate-primary));background:var(--ate-toolbar-button-active-background, var(--ate-primary-light))}.tiptap-button.is-active.has-custom-color{background:var(--ate-toolbar-button-active-background, var(--ate-primary-light))}.tiptap-button:disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.tiptap-button .material-symbols-outlined{font-size:20px;position:relative;z-index:1}.tiptap-button .material-symbols-outlined.icon-small{font-size:16px}.tiptap-button .material-symbols-outlined.icon-medium{font-size:20px}.tiptap-button .material-symbols-outlined.icon-large{font-size:24px}.tiptap-button.text-button{width:auto;padding:0 12px;font-size:14px;font-weight:500;gap:8px}.tiptap-button.color-button{width:28px;height:28px;border-radius:50%;border:2px solid transparent;transition:all .2s ease}.tiptap-button.color-button:hover{border-color:var(--ate-border);transform:scale(1.1)}.tiptap-button.color-button.is-active{border-color:var(--ate-primary);box-shadow:0 0 0 2px var(--ate-primary-light)}.tiptap-button.danger{color:var(--ate-error-color, #ef4444)}.tiptap-button.danger:hover{background:var(--ate-error-bg, rgba(239, 68, 68, .1))}.tiptap-button.danger:before{background:var(--ate-error-color, #ef4444)}.tiptap-button.small{width:24px;height:24px}.tiptap-button.medium{width:32px;height:32px}.tiptap-button.large{width:40px;height:40px}@keyframes pulse{0%,to{box-shadow:0 0 0 0 var(--ate-primary-light-alpha)}50%{box-shadow:0 0 0 4px transparent}}.tiptap-button.is-active.pulse{animation:pulse 2s infinite}@media (max-width: 768px){.tiptap-button{width:32px;height:32px}.tiptap-button .material-symbols-outlined{font-size:18px}.tiptap-button.text-button{padding:0 8px;font-size:13px}}\n"] }); }
569
573
  }
570
574
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapButtonComponent, decorators: [{
571
575
  type: Component,
@@ -580,23 +584,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
580
584
  [class.medium]="size() === 'medium'"
581
585
  [class.large]="size() === 'large'"
582
586
  [class.has-custom-color]="!!color()"
587
+ [class.has-custom-bg]="!!backgroundColor()"
583
588
  [disabled]="disabled()"
584
589
  [style.color]="color()"
590
+ [style.background-color]="backgroundColor()"
585
591
  [attr.title]="title()"
586
592
  (mousedown)="onMouseDown($event)"
587
593
  (click)="onClick.emit($event)"
588
594
  type="button"
589
595
  >
590
- <span
591
- class="material-symbols-outlined"
592
- [class.icon-small]="iconSize() === 'small'"
593
- [class.icon-medium]="iconSize() === 'medium'"
594
- [class.icon-large]="iconSize() === 'large'"
595
- >{{ icon() }}</span
596
- >
596
+ @if (icon()) {
597
+ <span
598
+ class="material-symbols-outlined"
599
+ [class.icon-small]="iconSize() === 'small'"
600
+ [class.icon-medium]="iconSize() === 'medium'"
601
+ [class.icon-large]="iconSize() === 'large'"
602
+ >{{ icon() }}</span>
603
+ }
597
604
  <ng-content></ng-content>
598
605
  </button>
599
- `, styles: [".tiptap-button{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;border-radius:var(--ate-border-radius, 8px);cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);color:var(--ate-toolbar-button-color, var(--ate-text-secondary));position:relative;overflow:hidden}.tiptap-button:before{content:\"\";position:absolute;inset:0;background:var(--ate-primary);opacity:0;transition:opacity .2s ease;border-radius:var(--ate-border-radius, 8px)}.tiptap-button:hover:not(.has-custom-color){color:var(--ate-toolbar-button-active-color, var(--ate-primary));background:var(--ate-toolbar-button-hover-background, transparent);transform:translateY(-1px)}.tiptap-button.has-custom-color:hover{background:var(--ate-toolbar-button-hover-background, transparent);transform:translateY(-1px)}.tiptap-button:hover:before{opacity:.1}.tiptap-button:active{transform:translateY(0)}.tiptap-button.is-active:not(.has-custom-color){color:var(--ate-toolbar-button-active-color, var(--ate-primary));background:var(--ate-toolbar-button-active-background, var(--ate-primary-light))}.tiptap-button.is-active.has-custom-color{background:var(--ate-toolbar-button-active-background, var(--ate-primary-light))}.tiptap-button:disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.tiptap-button .material-symbols-outlined{font-size:20px;position:relative;z-index:1}.tiptap-button .material-symbols-outlined.icon-small{font-size:16px}.tiptap-button .material-symbols-outlined.icon-medium{font-size:20px}.tiptap-button .material-symbols-outlined.icon-large{font-size:24px}.tiptap-button.text-button{width:auto;padding:0 12px;font-size:14px;font-weight:500;gap:8px}.tiptap-button.color-button{width:28px;height:28px;border-radius:50%;border:2px solid transparent;transition:all .2s ease}.tiptap-button.color-button:hover{border-color:var(--ate-border);transform:scale(1.1)}.tiptap-button.color-button.is-active{border-color:var(--ate-primary);box-shadow:0 0 0 2px var(--ate-primary-light)}.tiptap-button.danger{color:var(--ate-error-color, #ef4444)}.tiptap-button.danger:hover{background:var(--ate-error-bg, rgba(239, 68, 68, .1))}.tiptap-button.danger:before{background:var(--ate-error-color, #ef4444)}.tiptap-button.small{width:24px;height:24px}.tiptap-button.medium{width:32px;height:32px}.tiptap-button.large{width:40px;height:40px}@keyframes pulse{0%,to{box-shadow:0 0 0 0 var(--ate-primary-light-alpha)}50%{box-shadow:0 0 0 4px transparent}}.tiptap-button.is-active.pulse{animation:pulse 2s infinite}@media (max-width: 768px){.tiptap-button{width:32px;height:32px}.tiptap-button .material-symbols-outlined{font-size:18px}.tiptap-button.text-button{padding:0 8px;font-size:13px}}\n"] }]
606
+ `, styles: [".tiptap-button{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;border-radius:var(--ate-border-radius, 8px);cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);color:var(--ate-toolbar-button-color, var(--ate-text-secondary));position:relative;overflow:hidden}.tiptap-button:before{content:\"\";position:absolute;inset:0;background:var(--ate-primary);opacity:0;transition:opacity .2s ease;border-radius:var(--ate-border-radius, 8px)}.tiptap-button:hover:not(.has-custom-color){color:var(--ate-toolbar-button-active-color, var(--ate-primary));background:var(--ate-toolbar-button-hover-background, transparent);transform:translateY(-1px)}.tiptap-button.has-custom-color:hover:not(.has-custom-bg){background:var(--ate-toolbar-button-hover-background, transparent);transform:translateY(-1px)}.tiptap-button.has-custom-bg:hover{transform:translateY(-1px);filter:brightness(.9)}.tiptap-button:hover:before{opacity:.1}.tiptap-button:active{transform:translateY(0)}.tiptap-button.is-active:not(.has-custom-color){color:var(--ate-toolbar-button-active-color, var(--ate-primary));background:var(--ate-toolbar-button-active-background, var(--ate-primary-light))}.tiptap-button.is-active.has-custom-color{background:var(--ate-toolbar-button-active-background, var(--ate-primary-light))}.tiptap-button:disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.tiptap-button .material-symbols-outlined{font-size:20px;position:relative;z-index:1}.tiptap-button .material-symbols-outlined.icon-small{font-size:16px}.tiptap-button .material-symbols-outlined.icon-medium{font-size:20px}.tiptap-button .material-symbols-outlined.icon-large{font-size:24px}.tiptap-button.text-button{width:auto;padding:0 12px;font-size:14px;font-weight:500;gap:8px}.tiptap-button.color-button{width:28px;height:28px;border-radius:50%;border:2px solid transparent;transition:all .2s ease}.tiptap-button.color-button:hover{border-color:var(--ate-border);transform:scale(1.1)}.tiptap-button.color-button.is-active{border-color:var(--ate-primary);box-shadow:0 0 0 2px var(--ate-primary-light)}.tiptap-button.danger{color:var(--ate-error-color, #ef4444)}.tiptap-button.danger:hover{background:var(--ate-error-bg, rgba(239, 68, 68, .1))}.tiptap-button.danger:before{background:var(--ate-error-color, #ef4444)}.tiptap-button.small{width:24px;height:24px}.tiptap-button.medium{width:32px;height:32px}.tiptap-button.large{width:40px;height:40px}@keyframes pulse{0%,to{box-shadow:0 0 0 0 var(--ate-primary-light-alpha)}50%{box-shadow:0 0 0 4px transparent}}.tiptap-button.is-active.pulse{animation:pulse 2s infinite}@media (max-width: 768px){.tiptap-button{width:32px;height:32px}.tiptap-button .material-symbols-outlined{font-size:18px}.tiptap-button.text-button{padding:0 8px;font-size:13px}}\n"] }]
600
607
  }] });
601
608
 
602
609
  class ColorPickerService {
@@ -714,6 +721,23 @@ class ColorPickerService {
714
721
  .join("")
715
722
  .toLowerCase());
716
723
  }
724
+ /**
725
+ * Calculate the brightness of a color to determine if it's "light" or "dark".
726
+ * Returns a value between 0 and 255.
727
+ */
728
+ getLuminance(color) {
729
+ const hex = this.normalizeColor(color).replace("#", "");
730
+ const r = parseInt(hex.substring(0, 2), 16);
731
+ const g = parseInt(hex.substring(2, 4), 16);
732
+ const b = parseInt(hex.substring(4, 6), 16);
733
+ return (r * 299 + g * 587 + b * 114) / 1000;
734
+ }
735
+ /**
736
+ * Returns 'black' or 'white' based on the input color contrast.
737
+ */
738
+ getContrastColor(color) {
739
+ return this.getLuminance(color) > 128 ? "black" : "white";
740
+ }
717
741
  /**
718
742
  * Apply a color to the current selection.
719
743
  */
@@ -746,6 +770,94 @@ class ColorPickerService {
746
770
  }
747
771
  chain.run();
748
772
  }
773
+ /**
774
+ * Find the first explicitly applied highlight color within a selection.
775
+ */
776
+ findFirstAppliedHighlight(editor, selection) {
777
+ const { from, to } = selection;
778
+ let found = null;
779
+ editor.state.doc.nodesBetween(from, to, (node) => {
780
+ if (found)
781
+ return false;
782
+ const highlightMark = node.marks.find((m) => m.type.name === "highlight");
783
+ const color = highlightMark?.attrs?.color;
784
+ if (color) {
785
+ found = this.normalizeColor(color);
786
+ return false;
787
+ }
788
+ return;
789
+ });
790
+ return found;
791
+ }
792
+ /**
793
+ * Get the current highlight color for the selection.
794
+ */
795
+ getCurrentHighlight(editor, selection) {
796
+ const sel = selection ??
797
+ {
798
+ from: editor.state.selection.from,
799
+ to: editor.state.selection.to,
800
+ };
801
+ const found = this.findFirstAppliedHighlight(editor, sel);
802
+ if (found)
803
+ return found;
804
+ const attrs = editor.getAttributes("highlight") || {};
805
+ if (attrs.color)
806
+ return this.normalizeColor(attrs.color);
807
+ return "#ffff00"; // Default highlight color yellow
808
+ }
809
+ /**
810
+ * Check if a highlight is explicitly applied on the selection.
811
+ */
812
+ hasHighlightApplied(editor, selection) {
813
+ const sel = selection ??
814
+ {
815
+ from: editor.state.selection.from,
816
+ to: editor.state.selection.to,
817
+ };
818
+ const { from, to } = sel;
819
+ if (from === to) {
820
+ const attrs = editor.getAttributes("highlight") || {};
821
+ return !!attrs.color;
822
+ }
823
+ const found = this.findFirstAppliedHighlight(editor, sel);
824
+ if (found)
825
+ return true;
826
+ const attrs = editor.getAttributes("highlight") || {};
827
+ return !!attrs.color;
828
+ }
829
+ /**
830
+ * Apply a highlight color to the current selection.
831
+ */
832
+ applyHighlight(editor, color, options = {}) {
833
+ const sel = this.getStoredSelection() ?? editor.state.selection;
834
+ const { addToHistory = true } = options;
835
+ let chain = editor.chain().focus();
836
+ if (sel) {
837
+ chain = chain.setTextSelection(sel);
838
+ }
839
+ chain.setHighlight({ color });
840
+ if (!addToHistory) {
841
+ chain.setMeta("addToHistory", false);
842
+ }
843
+ chain.run();
844
+ }
845
+ /**
846
+ * Unset highlight on the current selection.
847
+ */
848
+ unsetHighlight(editor, options = {}) {
849
+ const sel = this.getStoredSelection() ?? editor.state.selection;
850
+ const { addToHistory = true } = options;
851
+ let chain = editor.chain().focus();
852
+ if (sel) {
853
+ chain = chain.setTextSelection(sel);
854
+ }
855
+ chain.unsetHighlight();
856
+ if (!addToHistory) {
857
+ chain.setMeta("addToHistory", false);
858
+ }
859
+ chain.run();
860
+ }
749
861
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: ColorPickerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
750
862
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: ColorPickerService, providedIn: "root" }); }
751
863
  }
@@ -766,6 +878,7 @@ const ENGLISH_TRANSLATIONS = {
766
878
  superscript: "Superscript",
767
879
  subscript: "Subscript",
768
880
  highlight: "Highlight",
881
+ highlightPicker: "Background Color",
769
882
  heading1: "Heading 1",
770
883
  heading2: "Heading 2",
771
884
  heading3: "Heading 3",
@@ -784,6 +897,8 @@ const ENGLISH_TRANSLATIONS = {
784
897
  redo: "Redo",
785
898
  clear: "Clear",
786
899
  textColor: "Text Color",
900
+ customColor: "Custom Color",
901
+ presets: "Presets",
787
902
  },
788
903
  bubbleMenu: {
789
904
  bold: "Bold",
@@ -794,6 +909,7 @@ const ENGLISH_TRANSLATIONS = {
794
909
  superscript: "Superscript",
795
910
  subscript: "Subscript",
796
911
  highlight: "Highlight",
912
+ highlightPicker: "Background Color",
797
913
  textColor: "Text Color",
798
914
  link: "Link",
799
915
  addLink: "Add Link",
@@ -802,6 +918,8 @@ const ENGLISH_TRANSLATIONS = {
802
918
  linkUrl: "Link URL",
803
919
  linkText: "Link Text",
804
920
  openLink: "Open Link",
921
+ customColor: "Custom Color",
922
+ presets: "Presets",
805
923
  },
806
924
  slashCommands: {
807
925
  heading1: {
@@ -924,6 +1042,7 @@ const FRENCH_TRANSLATIONS = {
924
1042
  superscript: "Exposant",
925
1043
  subscript: "Indice",
926
1044
  highlight: "Surligner",
1045
+ highlightPicker: "Couleur de fond",
927
1046
  heading1: "Titre 1",
928
1047
  heading2: "Titre 2",
929
1048
  heading3: "Titre 3",
@@ -942,6 +1061,8 @@ const FRENCH_TRANSLATIONS = {
942
1061
  redo: "Refaire",
943
1062
  clear: "Vider",
944
1063
  textColor: "Couleur texte",
1064
+ customColor: "Couleur personnalisée",
1065
+ presets: "Préréglages",
945
1066
  },
946
1067
  bubbleMenu: {
947
1068
  bold: "Gras",
@@ -952,6 +1073,7 @@ const FRENCH_TRANSLATIONS = {
952
1073
  superscript: "Exposant",
953
1074
  subscript: "Indice",
954
1075
  highlight: "Surligner",
1076
+ highlightPicker: "Couleur de fond",
955
1077
  textColor: "Couleur texte",
956
1078
  link: "Lien",
957
1079
  addLink: "Ajouter un lien",
@@ -960,6 +1082,8 @@ const FRENCH_TRANSLATIONS = {
960
1082
  linkUrl: "URL du lien",
961
1083
  linkText: "Texte du lien",
962
1084
  openLink: "Ouvrir le lien",
1085
+ customColor: "Couleur personnalisée",
1086
+ presets: "Préréglages",
963
1087
  },
964
1088
  slashCommands: {
965
1089
  heading1: {
@@ -1150,35 +1274,83 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
1150
1274
  }]
1151
1275
  }], ctorParameters: () => [] });
1152
1276
 
1153
- class TiptapTextColorPickerComponent {
1277
+ const PRESET_COLORS = [
1278
+ "#000000", "#666666", "#CCCCCC", "#FFFFFF",
1279
+ "#F44336", "#FF9800", "#FFEB3B", "#4CAF50",
1280
+ "#00BCD4", "#2196F3", "#9C27B0", "#E91E63"
1281
+ ];
1282
+ class TiptapColorPickerComponent {
1154
1283
  constructor() {
1155
1284
  this.editor = input.required();
1285
+ this.mode = input("text");
1156
1286
  this.interactionChange = output();
1157
1287
  this.requestUpdate = output();
1158
1288
  this.colorInputRef = viewChild("colorInput");
1289
+ this.wrapperRef = viewChild("wrapperRef");
1159
1290
  this.colorPickerSvc = inject(ColorPickerService);
1160
1291
  this.i18nService = inject(TiptapI18nService);
1292
+ this.platformId = inject(PLATFORM_ID);
1161
1293
  this.t = this.i18nService.toolbar;
1294
+ this.presets = PRESET_COLORS;
1162
1295
  this.previewColor = signal(null);
1163
1296
  this.isPicking = signal(false);
1164
1297
  this.editorChange = signal(0);
1298
+ this.showDropdown = signal(false);
1165
1299
  this.currentColor = computed(() => {
1166
1300
  this.editorChange();
1167
1301
  if (this.previewColor())
1168
1302
  return this.previewColor();
1169
- return this.colorPickerSvc.getCurrentColor(this.editor());
1303
+ const editor = this.editor();
1304
+ return this.mode() === "text"
1305
+ ? this.colorPickerSvc.getCurrentColor(editor)
1306
+ : this.colorPickerSvc.getCurrentHighlight(editor);
1307
+ });
1308
+ this.hexValue = computed(() => {
1309
+ const color = this.currentColor();
1310
+ return color.replace('#', '').toUpperCase();
1170
1311
  });
1171
1312
  this.hasColorApplied = computed(() => {
1172
1313
  this.editorChange();
1173
- return this.previewColor()
1174
- ? true
1175
- : this.colorPickerSvc.hasColorApplied(this.editor());
1314
+ if (this.previewColor())
1315
+ return true;
1316
+ const editor = this.editor();
1317
+ return this.mode() === "text"
1318
+ ? this.colorPickerSvc.hasColorApplied(editor)
1319
+ : this.colorPickerSvc.hasHighlightApplied(editor);
1176
1320
  });
1177
- this._syncEffect = void effect(() => {
1178
- const el = this.colorInputRef()?.nativeElement;
1179
- if (!el)
1180
- return;
1181
- el.value = this.currentColor();
1321
+ /**
1322
+ * Determine the icon to display.
1323
+ */
1324
+ this.buttonIcon = computed(() => {
1325
+ if (this.mode() === "text")
1326
+ return "format_color_text";
1327
+ return "format_color_fill";
1328
+ });
1329
+ /**
1330
+ * Determine the background color of the button.
1331
+ */
1332
+ this.buttonBgColor = computed(() => {
1333
+ const color = this.currentColor();
1334
+ if (this.mode() === "highlight") {
1335
+ return this.hasColorApplied() ? color : "";
1336
+ }
1337
+ if (this.hasColorApplied() && this.colorPickerSvc.getLuminance(color) > 200) {
1338
+ return "#333333";
1339
+ }
1340
+ return "";
1341
+ });
1342
+ /**
1343
+ * Determine the text/icon color of the button.
1344
+ */
1345
+ this.buttonTextColor = computed(() => {
1346
+ const color = this.currentColor();
1347
+ if (this.mode() === "text") {
1348
+ return this.hasColorApplied() ? color : "var(--ate-text-secondary)";
1349
+ }
1350
+ if (this.hasColorApplied()) {
1351
+ return this.colorPickerSvc.getLuminance(color) > 128 ? "#000000" : "#ffffff";
1352
+ }
1353
+ return "var(--ate-text-secondary)";
1182
1354
  });
1183
1355
  effect(() => {
1184
1356
  const ed = this.editor();
@@ -1195,160 +1367,288 @@ class TiptapTextColorPickerComponent {
1195
1367
  };
1196
1368
  });
1197
1369
  }
1370
+ onDocumentClick(event) {
1371
+ if (!isPlatformBrowser(this.platformId))
1372
+ return;
1373
+ const wrapper = this.wrapperRef()?.nativeElement;
1374
+ if (wrapper && !wrapper.contains(event.target)) {
1375
+ if (this.showDropdown()) {
1376
+ this.closeDropdown();
1377
+ }
1378
+ }
1379
+ }
1380
+ onEscape(event) {
1381
+ if (this.showDropdown()) {
1382
+ this.closeDropdown();
1383
+ }
1384
+ }
1198
1385
  /**
1199
1386
  * Notify Angular that the editor state should be re-read.
1200
1387
  */
1201
1388
  notifyEditorChange() {
1202
1389
  this.editorChange.update((v) => v + 1);
1203
1390
  }
1204
- /**
1205
- * Keep the native <input type="color"> in sync with selection changes.
1206
- */
1207
- syncColorInputValue() {
1208
- this.previewColor.set(null);
1209
- this.isPicking.set(false);
1210
- // Reason: force recomputation from editor selection when bubble menu re-opens.
1211
- this.notifyEditorChange();
1212
- }
1213
- /**
1214
- * Programmatically click the hidden color input.
1215
- */
1216
- triggerPicker() {
1217
- this.colorInputRef()?.nativeElement.click();
1391
+ toggleDropdown() {
1392
+ if (this.showDropdown()) {
1393
+ this.closeDropdown();
1394
+ }
1395
+ else {
1396
+ this.openDropdown();
1397
+ }
1218
1398
  }
1219
- /**
1220
- * Preserve selection while interacting with native color input.
1221
- */
1222
- onColorMouseDown(event) {
1223
- event.stopPropagation();
1224
- this.colorPickerSvc.captureSelection(this.editor());
1225
- this.isPicking.set(true);
1399
+ openDropdown() {
1400
+ this.showDropdown.set(true);
1226
1401
  this.interactionChange.emit(true);
1402
+ this.colorPickerSvc.captureSelection(this.editor());
1227
1403
  }
1228
- /**
1229
- * Called when the native color picker is closed.
1230
- */
1231
- onColorPickerClose() {
1232
- this.previewColor.set(null);
1233
- this.isPicking.set(false);
1234
- // Commit the final color to history
1235
- const inputEl = this.colorInputRef()?.nativeElement;
1236
- if (inputEl) {
1237
- this.colorPickerSvc.applyColor(this.editor(), inputEl.value, {
1238
- addToHistory: true,
1239
- });
1240
- }
1241
- this.colorPickerSvc.done();
1404
+ closeDropdown() {
1405
+ this.showDropdown.set(false);
1242
1406
  this.interactionChange.emit(false);
1407
+ this.done();
1408
+ }
1409
+ isColorActive(color) {
1410
+ return this.colorPickerSvc.normalizeColor(this.currentColor()) === this.colorPickerSvc.normalizeColor(color);
1411
+ }
1412
+ applyColor(color, addToHistory = true) {
1413
+ const editor = this.editor();
1414
+ if (this.mode() === "text") {
1415
+ this.colorPickerSvc.applyColor(editor, color, { addToHistory });
1416
+ }
1417
+ else {
1418
+ this.colorPickerSvc.applyHighlight(editor, color, { addToHistory });
1419
+ }
1420
+ this.notifyEditorChange();
1243
1421
  this.requestUpdate.emit();
1244
1422
  }
1245
- /**
1246
- * Apply selected color.
1247
- */
1248
- onColorInput(event) {
1423
+ onHexInput(event) {
1424
+ const input = event.target;
1425
+ let value = input.value.trim();
1426
+ if (!value.startsWith("#")) {
1427
+ value = "#" + value;
1428
+ }
1429
+ if (/^#[0-9A-Fa-f]{3,6}$/.test(value)) {
1430
+ this.applyColor(value, false);
1431
+ }
1432
+ }
1433
+ onHexChange(event) {
1434
+ const input = event.target;
1435
+ let value = input.value.trim();
1436
+ if (!value.startsWith("#")) {
1437
+ value = "#" + value;
1438
+ }
1439
+ if (/^#[0-9A-Fa-f]{3,6}$/.test(value)) {
1440
+ this.applyColor(value, true);
1441
+ }
1442
+ }
1443
+ triggerNativePicker() {
1444
+ this.colorInputRef()?.nativeElement.click();
1445
+ }
1446
+ onNativeInput(event) {
1249
1447
  const inputEl = event.target;
1250
1448
  const color = inputEl.value;
1251
- // Update the UI immediately while the user drags in the native picker.
1252
- this.previewColor.set(this.colorPickerSvc.normalizeColor(color));
1253
- // Live preview WITHOUT history pollution
1254
- this.colorPickerSvc.applyColor(this.editor(), color, {
1255
- addToHistory: false,
1256
- });
1257
- this.requestUpdate.emit();
1449
+ this.applyColor(color, false);
1450
+ }
1451
+ onNativeChange(event) {
1452
+ const inputEl = event.target;
1453
+ const color = inputEl.value;
1454
+ this.applyColor(color, true);
1258
1455
  }
1259
- /**
1260
- * Prevent opening the native picker when clicking the clear badge.
1261
- */
1262
1456
  onClearBadgeMouseDown(event) {
1263
1457
  event.preventDefault();
1264
1458
  event.stopPropagation();
1265
1459
  }
1266
- /**
1267
- * Clear color via the badge.
1268
- */
1269
1460
  onClearBadgeClick(event) {
1270
1461
  event.preventDefault();
1271
1462
  event.stopPropagation();
1272
- this.previewColor.set(null);
1273
- this.isPicking.set(false);
1274
- this.colorPickerSvc.unsetColor(this.editor());
1463
+ if (this.mode() === "text") {
1464
+ this.colorPickerSvc.unsetColor(this.editor());
1465
+ }
1466
+ else {
1467
+ this.colorPickerSvc.unsetHighlight(this.editor());
1468
+ }
1469
+ this.showDropdown.set(false);
1470
+ this.interactionChange.emit(false);
1275
1471
  this.requestUpdate.emit();
1276
1472
  }
1277
- /**
1278
- * Called when the color picker is done interacting.
1279
- */
1473
+ syncColorInputValue() {
1474
+ this.notifyEditorChange();
1475
+ }
1280
1476
  done() {
1281
1477
  this.colorPickerSvc.done();
1282
1478
  }
1283
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapTextColorPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1284
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapTextColorPickerComponent, isStandalone: true, selector: "tiptap-text-color-picker", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { interactionChange: "interactionChange", requestUpdate: "requestUpdate" }, viewQueries: [{ propertyName: "colorInputRef", first: true, predicate: ["colorInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
1285
- <div class="text-color-picker-container">
1286
- <tiptap-button
1287
- icon="format_color_text"
1288
- [title]="t().textColor"
1289
- [color]="hasColorApplied() ? currentColor() : 'var(--ate-text)'"
1290
- (onClick)="triggerPicker()"
1291
- >
1292
- <input
1293
- #colorInput
1294
- type="color"
1295
- [value]="currentColor()"
1296
- (mousedown)="onColorMouseDown($event)"
1297
- (input)="onColorInput($event)"
1298
- (change)="onColorPickerClose()"
1299
- (blur)="onColorPickerClose()"
1479
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapColorPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1480
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapColorPickerComponent, isStandalone: true, selector: "tiptap-color-picker", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { interactionChange: "interactionChange", requestUpdate: "requestUpdate" }, host: { listeners: { "document:mousedown": "onDocumentClick($event)", "document:keydown.escape": "onEscape($event)" } }, viewQueries: [{ propertyName: "colorInputRef", first: true, predicate: ["colorInput"], descendants: true, isSignal: true }, { propertyName: "wrapperRef", first: true, predicate: ["wrapperRef"], descendants: true, isSignal: true }], ngImport: i0, template: `
1481
+ <div class="color-picker-wrapper" #wrapperRef>
1482
+ <div class="color-picker-container" [class.is-highlight]="mode() === 'highlight'">
1483
+ <tiptap-button
1484
+ [icon]="buttonIcon()"
1485
+ [title]="mode() === 'text' ? t().textColor : t().highlight"
1486
+ [color]="buttonTextColor()"
1487
+ [backgroundColor]="buttonBgColor()"
1488
+ (onClick)="toggleDropdown()"
1300
1489
  />
1301
- </tiptap-button>
1302
1490
 
1303
- @if (hasColorApplied()) {
1304
- <button
1305
- class="btn-clear-badge"
1306
- type="button"
1307
- [title]="t().clear"
1308
- (mousedown)="onClearBadgeMouseDown($event)"
1309
- (click)="onClearBadgeClick($event)"
1310
- >
1311
- <span class="material-symbols-outlined">close</span>
1312
- </button>
1491
+ @if (hasColorApplied()) {
1492
+ <button
1493
+ class="btn-clear-badge"
1494
+ type="button"
1495
+ [title]="t().clear"
1496
+ (mousedown)="onClearBadgeMouseDown($event)"
1497
+ (click)="onClearBadgeClick($event)"
1498
+ >
1499
+ <span class="material-symbols-outlined">close</span>
1500
+ </button>
1501
+ }
1502
+ </div>
1503
+
1504
+ @if (showDropdown()) {
1505
+ <div class="color-picker-dropdown compact" (mousedown)="$event.stopPropagation()">
1506
+ <!-- Presets Row -->
1507
+ <div class="dropdown-row presets">
1508
+ <div class="color-grid">
1509
+ @for (color of presets; track color) {
1510
+ <button
1511
+ class="color-swatch"
1512
+ [style.backgroundColor]="color"
1513
+ [class.is-active]="isColorActive(color)"
1514
+ [title]="color"
1515
+ (click)="applyColor(color)"
1516
+ ></button>
1517
+ }
1518
+ </div>
1519
+ </div>
1520
+
1521
+ <!-- Custom Row -->
1522
+ <div class="dropdown-row controls">
1523
+ <div class="hex-input-wrapper">
1524
+ <span class="hex-hash">#</span>
1525
+ <input
1526
+ #hexInput
1527
+ type="text"
1528
+ class="hex-input"
1529
+ [value]="hexValue()"
1530
+ (input)="onHexInput($event)"
1531
+ (change)="onHexChange($event)"
1532
+ maxlength="6"
1533
+ placeholder="000000"
1534
+ />
1535
+ </div>
1536
+
1537
+ <div class="native-trigger-wrapper">
1538
+ <button class="btn-native-picker" (click)="triggerNativePicker()" [style.backgroundColor]="currentColor()" [title]="t().customColor">
1539
+ <span class="material-symbols-outlined">colorize</span>
1540
+ </button>
1541
+ <input
1542
+ #colorInput
1543
+ type="color"
1544
+ class="hidden-native-input"
1545
+ [value]="currentColor()"
1546
+ (input)="onNativeInput($event)"
1547
+ (change)="onNativeChange($event)"
1548
+ />
1549
+ </div>
1550
+
1551
+ <div class="divider-v"></div>
1552
+
1553
+ <button class="btn-clear-compact" (click)="onClearBadgeClick($event)" [title]="t().clear">
1554
+ <span class="material-symbols-outlined">format_color_reset</span>
1555
+ </button>
1556
+ </div>
1557
+ </div>
1313
1558
  }
1314
1559
  </div>
1315
- `, isInline: true, styles: [".text-color-picker-container{position:relative;display:inline-flex;align-items:center}.text-color-picker-container tiptap-button{position:relative}.btn-clear-badge{position:absolute;top:-4px;right:-4px;width:14px;height:14px;padding:0;border:none;border-radius:999px;background:#0f172abf;color:#fff;display:flex;align-items:center;justify-content:center;z-index:10;opacity:0;pointer-events:none;transition:opacity .12s ease}.text-color-picker-container:hover .btn-clear-badge{opacity:1;pointer-events:auto}.btn-clear-badge .material-symbols-outlined{font-size:10px;line-height:1}input[type=color]{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer;z-index:5}\n"], dependencies: [{ kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "variant", "size", "iconSize"], outputs: ["onClick"] }] }); }
1560
+ `, isInline: true, styles: [".color-picker-wrapper{position:relative;display:inline-block}.color-picker-container{position:relative;display:inline-flex;align-items:center}.btn-clear-badge{position:absolute;top:-4px;right:-4px;width:14px;height:14px;padding:0;border:none;border-radius:999px;background:#0f172abf;color:#fff;display:flex;align-items:center;justify-content:center;z-index:10;opacity:0;pointer-events:none;transition:opacity .12s ease}.color-picker-container:hover .btn-clear-badge{opacity:1;pointer-events:auto}.btn-clear-badge .material-symbols-outlined{font-size:10px;line-height:1}.color-picker-dropdown.compact{position:absolute;top:calc(100% + 8px);left:50%;transform:translate(-50%);z-index:2000;background:var(--ate-menu-bg, #ffffff);border:1px solid var(--ate-border, #e2e8f0);border-radius:var(--ate-border-radius, 12px);box-shadow:0 10px 25px -5px #0000001a,0 8px 10px -6px #0000001a;padding:8px 12px;width:310px;display:flex;flex-direction:column;gap:8px;animation:slideDown .2s cubic-bezier(0,0,.2,1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}@keyframes slideDown{0%{opacity:0;transform:translate(-50%,-10px)}to{opacity:1;transform:translate(-50%)}}.dropdown-row{display:flex;align-items:center;width:100%}.dropdown-row.presets{justify-content:center}.dropdown-row.controls{gap:8px;justify-content:space-between;padding-top:4px;border-top:1px solid var(--ate-border, #e2e8f0)}.color-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:4px;width:100%}.color-swatch{width:100%;aspect-ratio:1;border-radius:4px;border:1px solid rgba(0,0,0,.1);cursor:pointer;padding:0;transition:all .12s ease}.color-swatch:hover{transform:scale(1.15);box-shadow:0 4px 6px -1px #0000001a;z-index:1}.color-swatch.is-active{border-color:var(--ate-primary, #3b82f6);box-shadow:0 0 0 2px #3b82f64d}.divider-v{width:1px;height:24px;background:var(--ate-border, #e2e8f0)}.btn-clear-compact{display:flex;align-items:center;justify-content:center;width:32px;height:32px;background:var(--ate-surface-secondary, #f1f5f9);border:none;border-radius:6px;color:var(--ate-text-secondary, #64748b);cursor:pointer;transition:all .15s ease}.btn-clear-compact:hover{background:#fee2e2;color:#ef4444}.btn-clear-compact .material-symbols-outlined{font-size:18px}.dropdown-divider{height:1px;background:var(--ate-border, #e2e8f0);margin:0 -16px}.custom-row{display:flex;align-items:center;gap:12px}.hex-input-wrapper{flex:1;display:flex;align-items:center;background:var(--ate-surface-secondary, #f8fafc);border:1px solid var(--ate-border, #e2e8f0);border-radius:6px;padding:0 8px;height:32px;transition:border-color .15s ease}.hex-input-wrapper:focus-within{border-color:var(--ate-primary, #3b82f6);background:var(--ate-menu-bg, #ffffff)}.hex-hash{color:var(--ate-text-muted, #94a3b8);font-family:monospace;font-size:.875rem}.hex-input{background:transparent;border:none;outline:none;color:var(--ate-text, #1e293b);font-family:monospace;font-size:.875rem;width:100%;padding-left:4px}.native-trigger-wrapper{position:relative;width:32px;height:32px}.btn-native-picker{width:100%;height:100%;border-radius:8px;border:1px solid var(--ate-border, #e2e8f0);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.2);transition:transform .15s ease}.btn-native-picker:hover{transform:scale(1.05)}.btn-native-picker .material-symbols-outlined{font-size:20px}.hidden-native-input{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer}.dropdown-footer{margin-top:4px}.btn-clear-full{width:100%;display:flex;align-items:center;justify-content:center;gap:8px;height:36px;background:var(--ate-surface-secondary, #f1f5f9);border:none;border-radius:8px;color:var(--ate-text, #475569);font-size:.875rem;font-weight:500;cursor:pointer;transition:all .15s ease}.btn-clear-full:hover{background:#fee2e2;color:#ef4444}.btn-clear-full .material-symbols-outlined{font-size:18px}\n"], dependencies: [{ kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "backgroundColor", "variant", "size", "iconSize"], outputs: ["onClick"] }] }); }
1316
1561
  }
1317
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapTextColorPickerComponent, decorators: [{
1562
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapColorPickerComponent, decorators: [{
1318
1563
  type: Component,
1319
- args: [{ selector: "tiptap-text-color-picker", standalone: true, imports: [TiptapButtonComponent], template: `
1320
- <div class="text-color-picker-container">
1321
- <tiptap-button
1322
- icon="format_color_text"
1323
- [title]="t().textColor"
1324
- [color]="hasColorApplied() ? currentColor() : 'var(--ate-text)'"
1325
- (onClick)="triggerPicker()"
1326
- >
1327
- <input
1328
- #colorInput
1329
- type="color"
1330
- [value]="currentColor()"
1331
- (mousedown)="onColorMouseDown($event)"
1332
- (input)="onColorInput($event)"
1333
- (change)="onColorPickerClose()"
1334
- (blur)="onColorPickerClose()"
1564
+ args: [{ selector: "tiptap-color-picker", standalone: true, imports: [TiptapButtonComponent], template: `
1565
+ <div class="color-picker-wrapper" #wrapperRef>
1566
+ <div class="color-picker-container" [class.is-highlight]="mode() === 'highlight'">
1567
+ <tiptap-button
1568
+ [icon]="buttonIcon()"
1569
+ [title]="mode() === 'text' ? t().textColor : t().highlight"
1570
+ [color]="buttonTextColor()"
1571
+ [backgroundColor]="buttonBgColor()"
1572
+ (onClick)="toggleDropdown()"
1335
1573
  />
1336
- </tiptap-button>
1337
1574
 
1338
- @if (hasColorApplied()) {
1339
- <button
1340
- class="btn-clear-badge"
1341
- type="button"
1342
- [title]="t().clear"
1343
- (mousedown)="onClearBadgeMouseDown($event)"
1344
- (click)="onClearBadgeClick($event)"
1345
- >
1346
- <span class="material-symbols-outlined">close</span>
1347
- </button>
1575
+ @if (hasColorApplied()) {
1576
+ <button
1577
+ class="btn-clear-badge"
1578
+ type="button"
1579
+ [title]="t().clear"
1580
+ (mousedown)="onClearBadgeMouseDown($event)"
1581
+ (click)="onClearBadgeClick($event)"
1582
+ >
1583
+ <span class="material-symbols-outlined">close</span>
1584
+ </button>
1585
+ }
1586
+ </div>
1587
+
1588
+ @if (showDropdown()) {
1589
+ <div class="color-picker-dropdown compact" (mousedown)="$event.stopPropagation()">
1590
+ <!-- Presets Row -->
1591
+ <div class="dropdown-row presets">
1592
+ <div class="color-grid">
1593
+ @for (color of presets; track color) {
1594
+ <button
1595
+ class="color-swatch"
1596
+ [style.backgroundColor]="color"
1597
+ [class.is-active]="isColorActive(color)"
1598
+ [title]="color"
1599
+ (click)="applyColor(color)"
1600
+ ></button>
1601
+ }
1602
+ </div>
1603
+ </div>
1604
+
1605
+ <!-- Custom Row -->
1606
+ <div class="dropdown-row controls">
1607
+ <div class="hex-input-wrapper">
1608
+ <span class="hex-hash">#</span>
1609
+ <input
1610
+ #hexInput
1611
+ type="text"
1612
+ class="hex-input"
1613
+ [value]="hexValue()"
1614
+ (input)="onHexInput($event)"
1615
+ (change)="onHexChange($event)"
1616
+ maxlength="6"
1617
+ placeholder="000000"
1618
+ />
1619
+ </div>
1620
+
1621
+ <div class="native-trigger-wrapper">
1622
+ <button class="btn-native-picker" (click)="triggerNativePicker()" [style.backgroundColor]="currentColor()" [title]="t().customColor">
1623
+ <span class="material-symbols-outlined">colorize</span>
1624
+ </button>
1625
+ <input
1626
+ #colorInput
1627
+ type="color"
1628
+ class="hidden-native-input"
1629
+ [value]="currentColor()"
1630
+ (input)="onNativeInput($event)"
1631
+ (change)="onNativeChange($event)"
1632
+ />
1633
+ </div>
1634
+
1635
+ <div class="divider-v"></div>
1636
+
1637
+ <button class="btn-clear-compact" (click)="onClearBadgeClick($event)" [title]="t().clear">
1638
+ <span class="material-symbols-outlined">format_color_reset</span>
1639
+ </button>
1640
+ </div>
1641
+ </div>
1348
1642
  }
1349
1643
  </div>
1350
- `, styles: [".text-color-picker-container{position:relative;display:inline-flex;align-items:center}.text-color-picker-container tiptap-button{position:relative}.btn-clear-badge{position:absolute;top:-4px;right:-4px;width:14px;height:14px;padding:0;border:none;border-radius:999px;background:#0f172abf;color:#fff;display:flex;align-items:center;justify-content:center;z-index:10;opacity:0;pointer-events:none;transition:opacity .12s ease}.text-color-picker-container:hover .btn-clear-badge{opacity:1;pointer-events:auto}.btn-clear-badge .material-symbols-outlined{font-size:10px;line-height:1}input[type=color]{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer;z-index:5}\n"] }]
1351
- }], ctorParameters: () => [] });
1644
+ `, styles: [".color-picker-wrapper{position:relative;display:inline-block}.color-picker-container{position:relative;display:inline-flex;align-items:center}.btn-clear-badge{position:absolute;top:-4px;right:-4px;width:14px;height:14px;padding:0;border:none;border-radius:999px;background:#0f172abf;color:#fff;display:flex;align-items:center;justify-content:center;z-index:10;opacity:0;pointer-events:none;transition:opacity .12s ease}.color-picker-container:hover .btn-clear-badge{opacity:1;pointer-events:auto}.btn-clear-badge .material-symbols-outlined{font-size:10px;line-height:1}.color-picker-dropdown.compact{position:absolute;top:calc(100% + 8px);left:50%;transform:translate(-50%);z-index:2000;background:var(--ate-menu-bg, #ffffff);border:1px solid var(--ate-border, #e2e8f0);border-radius:var(--ate-border-radius, 12px);box-shadow:0 10px 25px -5px #0000001a,0 8px 10px -6px #0000001a;padding:8px 12px;width:310px;display:flex;flex-direction:column;gap:8px;animation:slideDown .2s cubic-bezier(0,0,.2,1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}@keyframes slideDown{0%{opacity:0;transform:translate(-50%,-10px)}to{opacity:1;transform:translate(-50%)}}.dropdown-row{display:flex;align-items:center;width:100%}.dropdown-row.presets{justify-content:center}.dropdown-row.controls{gap:8px;justify-content:space-between;padding-top:4px;border-top:1px solid var(--ate-border, #e2e8f0)}.color-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:4px;width:100%}.color-swatch{width:100%;aspect-ratio:1;border-radius:4px;border:1px solid rgba(0,0,0,.1);cursor:pointer;padding:0;transition:all .12s ease}.color-swatch:hover{transform:scale(1.15);box-shadow:0 4px 6px -1px #0000001a;z-index:1}.color-swatch.is-active{border-color:var(--ate-primary, #3b82f6);box-shadow:0 0 0 2px #3b82f64d}.divider-v{width:1px;height:24px;background:var(--ate-border, #e2e8f0)}.btn-clear-compact{display:flex;align-items:center;justify-content:center;width:32px;height:32px;background:var(--ate-surface-secondary, #f1f5f9);border:none;border-radius:6px;color:var(--ate-text-secondary, #64748b);cursor:pointer;transition:all .15s ease}.btn-clear-compact:hover{background:#fee2e2;color:#ef4444}.btn-clear-compact .material-symbols-outlined{font-size:18px}.dropdown-divider{height:1px;background:var(--ate-border, #e2e8f0);margin:0 -16px}.custom-row{display:flex;align-items:center;gap:12px}.hex-input-wrapper{flex:1;display:flex;align-items:center;background:var(--ate-surface-secondary, #f8fafc);border:1px solid var(--ate-border, #e2e8f0);border-radius:6px;padding:0 8px;height:32px;transition:border-color .15s ease}.hex-input-wrapper:focus-within{border-color:var(--ate-primary, #3b82f6);background:var(--ate-menu-bg, #ffffff)}.hex-hash{color:var(--ate-text-muted, #94a3b8);font-family:monospace;font-size:.875rem}.hex-input{background:transparent;border:none;outline:none;color:var(--ate-text, #1e293b);font-family:monospace;font-size:.875rem;width:100%;padding-left:4px}.native-trigger-wrapper{position:relative;width:32px;height:32px}.btn-native-picker{width:100%;height:100%;border-radius:8px;border:1px solid var(--ate-border, #e2e8f0);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.2);transition:transform .15s ease}.btn-native-picker:hover{transform:scale(1.05)}.btn-native-picker .material-symbols-outlined{font-size:20px}.hidden-native-input{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer}.dropdown-footer{margin-top:4px}.btn-clear-full{width:100%;display:flex;align-items:center;justify-content:center;gap:8px;height:36px;background:var(--ate-surface-secondary, #f1f5f9);border:none;border-radius:8px;color:var(--ate-text, #475569);font-size:.875rem;font-weight:500;cursor:pointer;transition:all .15s ease}.btn-clear-full:hover{background:#fee2e2;color:#ef4444}.btn-clear-full .material-symbols-outlined{font-size:18px}\n"] }]
1645
+ }], ctorParameters: () => [], propDecorators: { onDocumentClick: [{
1646
+ type: HostListener,
1647
+ args: ['document:mousedown', ['$event']]
1648
+ }], onEscape: [{
1649
+ type: HostListener,
1650
+ args: ['document:keydown.escape', ['$event']]
1651
+ }] } });
1352
1652
 
1353
1653
  class TiptapBubbleMenuComponent {
1354
1654
  /**
@@ -1378,6 +1678,7 @@ class TiptapBubbleMenuComponent {
1378
1678
  this.tippyInstance = null;
1379
1679
  this.updateTimeout = null;
1380
1680
  this.isColorPickerInteracting = false;
1681
+ this.isToolbarInteracting = signal(false);
1381
1682
  this.bubbleMenuConfig = computed(() => ({
1382
1683
  bold: true,
1383
1684
  italic: true,
@@ -1401,11 +1702,18 @@ class TiptapBubbleMenuComponent {
1401
1702
  const ed = this.editor();
1402
1703
  if (!ed)
1403
1704
  return;
1404
- if (!this.isColorPickerInteracting && this.textColorPicker) {
1405
- this.textColorPicker.done();
1705
+ if (!this.isColorPickerInteracting) {
1706
+ if (this.textColorPicker)
1707
+ this.textColorPicker.done();
1708
+ if (this.highlightPicker)
1709
+ this.highlightPicker.done();
1406
1710
  }
1407
1711
  const { selection } = ed.state;
1408
1712
  const { from, to } = selection;
1713
+ if (this.isToolbarInteracting()) {
1714
+ this.hideTippy();
1715
+ return;
1716
+ }
1409
1717
  const hasTextSelection = from !== to && !(selection instanceof CellSelection);
1410
1718
  const isImageSelected = ed.isActive("image") || ed.isActive("resizableImage");
1411
1719
  const isTableCellSelected = ed.isActive("tableCell") || ed.isActive("tableHeader");
@@ -1433,8 +1741,11 @@ class TiptapBubbleMenuComponent {
1433
1741
  this.handleBlur = () => {
1434
1742
  // Masquer le menu quand l'éditeur perd le focus
1435
1743
  setTimeout(() => {
1436
- if (!this.isColorPickerInteracting && this.textColorPicker) {
1437
- this.textColorPicker.done();
1744
+ if (!this.isColorPickerInteracting) {
1745
+ if (this.textColorPicker)
1746
+ this.textColorPicker.done();
1747
+ if (this.highlightPicker)
1748
+ this.highlightPicker.done();
1438
1749
  this.hideTippy();
1439
1750
  }
1440
1751
  }, 100);
@@ -1569,6 +1880,7 @@ class TiptapBubbleMenuComponent {
1569
1880
  });
1570
1881
  this.tippyInstance.show();
1571
1882
  this.textColorPicker?.syncColorInputValue();
1883
+ this.highlightPicker?.syncColorInputValue();
1572
1884
  }
1573
1885
  hideTippy() {
1574
1886
  if (this.tippyInstance) {
@@ -1617,8 +1929,12 @@ class TiptapBubbleMenuComponent {
1617
1929
  break;
1618
1930
  }
1619
1931
  }
1932
+ setToolbarInteracting(isInteracting) {
1933
+ this.isToolbarInteracting.set(isInteracting);
1934
+ this.updateMenu();
1935
+ }
1620
1936
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapBubbleMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1621
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapBubbleMenuComponent, isStandalone: true, selector: "tiptap-bubble-menu", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "menuRef", first: true, predicate: ["menuRef"], descendants: true }, { propertyName: "textColorPicker", first: true, predicate: ["textColorPicker"], descendants: true }], ngImport: i0, template: `
1937
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapBubbleMenuComponent, isStandalone: true, selector: "tiptap-bubble-menu", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "menuRef", first: true, predicate: ["menuRef"], descendants: true }, { propertyName: "textColorPicker", first: true, predicate: ["textColorPicker"], descendants: true }, { propertyName: "highlightPicker", first: true, predicate: ["highlightPicker"], descendants: true }], ngImport: i0, template: `
1622
1938
  <div #menuRef class="bubble-menu">
1623
1939
  @if (bubbleMenuConfig().bold) {
1624
1940
  <tiptap-button
@@ -1669,9 +1985,18 @@ class TiptapBubbleMenuComponent {
1669
1985
  [active]="isActive('highlight')"
1670
1986
  (click)="onCommand('highlight', $event)"
1671
1987
  ></tiptap-button>
1988
+ } @if (bubbleMenuConfig().highlightPicker) {
1989
+ <tiptap-color-picker
1990
+ #highlightPicker
1991
+ mode="highlight"
1992
+ [editor]="editor()"
1993
+ (interactionChange)="onColorPickerInteractionChange($event)"
1994
+ (requestUpdate)="updateMenu()"
1995
+ />
1672
1996
  } @if (bubbleMenuConfig().textColor) {
1673
- <tiptap-text-color-picker
1997
+ <tiptap-color-picker
1674
1998
  #textColorPicker
1999
+ mode="text"
1675
2000
  [editor]="editor()"
1676
2001
  (interactionChange)="onColorPickerInteractionChange($event)"
1677
2002
  (requestUpdate)="updateMenu()"
@@ -1695,14 +2020,17 @@ class TiptapBubbleMenuComponent {
1695
2020
  ></tiptap-button>
1696
2021
  }
1697
2022
  </div>
1698
- `, isInline: true, dependencies: [{ kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "variant", "size", "iconSize"], outputs: ["onClick"] }, { kind: "component", type: TiptapTextColorPickerComponent, selector: "tiptap-text-color-picker", inputs: ["editor"], outputs: ["interactionChange", "requestUpdate"] }] }); }
2023
+ `, isInline: true, dependencies: [{ kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "backgroundColor", "variant", "size", "iconSize"], outputs: ["onClick"] }, { kind: "component", type: TiptapColorPickerComponent, selector: "tiptap-color-picker", inputs: ["editor", "mode"], outputs: ["interactionChange", "requestUpdate"] }] }); }
1699
2024
  }
1700
2025
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapBubbleMenuComponent, decorators: [{
1701
2026
  type: Component,
1702
2027
  args: [{
1703
2028
  selector: "tiptap-bubble-menu",
1704
2029
  standalone: true,
1705
- imports: [TiptapButtonComponent, TiptapTextColorPickerComponent],
2030
+ imports: [
2031
+ TiptapButtonComponent,
2032
+ TiptapColorPickerComponent,
2033
+ ],
1706
2034
  template: `
1707
2035
  <div #menuRef class="bubble-menu">
1708
2036
  @if (bubbleMenuConfig().bold) {
@@ -1754,9 +2082,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
1754
2082
  [active]="isActive('highlight')"
1755
2083
  (click)="onCommand('highlight', $event)"
1756
2084
  ></tiptap-button>
2085
+ } @if (bubbleMenuConfig().highlightPicker) {
2086
+ <tiptap-color-picker
2087
+ #highlightPicker
2088
+ mode="highlight"
2089
+ [editor]="editor()"
2090
+ (interactionChange)="onColorPickerInteractionChange($event)"
2091
+ (requestUpdate)="updateMenu()"
2092
+ />
1757
2093
  } @if (bubbleMenuConfig().textColor) {
1758
- <tiptap-text-color-picker
2094
+ <tiptap-color-picker
1759
2095
  #textColorPicker
2096
+ mode="text"
1760
2097
  [editor]="editor()"
1761
2098
  (interactionChange)="onColorPickerInteractionChange($event)"
1762
2099
  (requestUpdate)="updateMenu()"
@@ -1788,6 +2125,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
1788
2125
  }], textColorPicker: [{
1789
2126
  type: ViewChild,
1790
2127
  args: ["textColorPicker", { static: false }]
2128
+ }], highlightPicker: [{
2129
+ type: ViewChild,
2130
+ args: ["highlightPicker", { static: false }]
1791
2131
  }] } });
1792
2132
 
1793
2133
  class TiptapSeparatorComponent {
@@ -2272,6 +2612,7 @@ class TiptapImageBubbleMenuComponent {
2272
2612
  this.tippyInstance = null;
2273
2613
  this.imageService = inject(ImageService);
2274
2614
  this.updateTimeout = null;
2615
+ this.isToolbarInteracting = signal(false);
2275
2616
  this.imageBubbleMenuConfig = computed(() => ({
2276
2617
  changeImage: true,
2277
2618
  resizeSmall: true,
@@ -2298,6 +2639,10 @@ class TiptapImageBubbleMenuComponent {
2298
2639
  const ed = this.editor();
2299
2640
  if (!ed)
2300
2641
  return;
2642
+ if (this.isToolbarInteracting()) {
2643
+ this.hideTippy();
2644
+ return;
2645
+ }
2301
2646
  const isImageSelected = ed.isActive("resizableImage") || ed.isActive("image");
2302
2647
  // Ne montrer le menu image que si :
2303
2648
  // - Une image est sélectionnée
@@ -2512,6 +2857,10 @@ class TiptapImageBubbleMenuComponent {
2512
2857
  ed.chain().focus().deleteSelection().run();
2513
2858
  }
2514
2859
  }
2860
+ setToolbarInteracting(isInteracting) {
2861
+ this.isToolbarInteracting.set(isInteracting);
2862
+ this.updateMenu();
2863
+ }
2515
2864
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapImageBubbleMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2516
2865
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapImageBubbleMenuComponent, isStandalone: true, selector: "tiptap-image-bubble-menu", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "menuRef", first: true, predicate: ["menuRef"], descendants: true }], ngImport: i0, template: `
2517
2866
  <div #menuRef class="bubble-menu">
@@ -2562,7 +2911,7 @@ class TiptapImageBubbleMenuComponent {
2562
2911
  ></tiptap-button>
2563
2912
  }
2564
2913
  </div>
2565
- `, isInline: true, dependencies: [{ kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "variant", "size", "iconSize"], outputs: ["onClick"] }, { kind: "component", type: TiptapSeparatorComponent, selector: "tiptap-separator", inputs: ["orientation", "size"] }] }); }
2914
+ `, isInline: true, dependencies: [{ kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "backgroundColor", "variant", "size", "iconSize"], outputs: ["onClick"] }, { kind: "component", type: TiptapSeparatorComponent, selector: "tiptap-separator", inputs: ["orientation", "size"] }] }); }
2566
2915
  }
2567
2916
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapImageBubbleMenuComponent, decorators: [{
2568
2917
  type: Component,
@@ -3122,7 +3471,7 @@ class TiptapTableBubbleMenuComponent {
3122
3471
  ></tiptap-button>
3123
3472
  }
3124
3473
  </div>
3125
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "variant", "size", "iconSize"], outputs: ["onClick"] }, { kind: "component", type: TiptapSeparatorComponent, selector: "tiptap-separator", inputs: ["orientation", "size"] }] }); }
3474
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "backgroundColor", "variant", "size", "iconSize"], outputs: ["onClick"] }, { kind: "component", type: TiptapSeparatorComponent, selector: "tiptap-separator", inputs: ["orientation", "size"] }] }); }
3126
3475
  }
3127
3476
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapTableBubbleMenuComponent, decorators: [{
3128
3477
  type: Component,
@@ -3428,7 +3777,7 @@ class TiptapCellBubbleMenuComponent {
3428
3777
  ></tiptap-button>
3429
3778
  }
3430
3779
  </div>
3431
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "variant", "size", "iconSize"], outputs: ["onClick"] }] }); }
3780
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "backgroundColor", "variant", "size", "iconSize"], outputs: ["onClick"] }] }); }
3432
3781
  }
3433
3782
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapCellBubbleMenuComponent, decorators: [{
3434
3783
  type: Component,
@@ -3466,6 +3815,7 @@ class TiptapToolbarComponent {
3466
3815
  this.imageError = output();
3467
3816
  this.imageService = inject(ImageService);
3468
3817
  this.i18nService = inject(TiptapI18nService);
3818
+ this.isColorPickerInteracting = false;
3469
3819
  // Computed values pour les traductions
3470
3820
  this.t = this.i18nService.toolbar;
3471
3821
  }
@@ -3558,6 +3908,12 @@ class TiptapToolbarComponent {
3558
3908
  onImageError(error) {
3559
3909
  this.imageError.emit(error);
3560
3910
  }
3911
+ onColorPickerInteractionChange(isInteracting) {
3912
+ this.isColorPickerInteracting = isInteracting;
3913
+ }
3914
+ onColorPickerUpdate() {
3915
+ // This can be used to trigger external updates if needed
3916
+ }
3561
3917
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapToolbarComponent, deps: [{ token: EditorCommandsService }], target: i0.ɵɵFactoryTarget.Component }); }
3562
3918
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapToolbarComponent, isStandalone: true, selector: "tiptap-toolbar", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { imageUploaded: "imageUploaded", imageError: "imageError" }, ngImport: i0, template: `
3563
3919
  <div class="tiptap-toolbar">
@@ -3625,9 +3981,22 @@ class TiptapToolbarComponent {
3625
3981
  [disabled]="!canExecute('toggleHighlight')"
3626
3982
  (onClick)="toggleHighlight()"
3627
3983
  />
3984
+ } @if (config().highlightPicker) {
3985
+ <tiptap-color-picker
3986
+ mode="highlight"
3987
+ [editor]="editor()"
3988
+ (interactionChange)="onColorPickerInteractionChange($event)"
3989
+ (requestUpdate)="onColorPickerUpdate()"
3990
+ />
3628
3991
  } @if (config().textColor) {
3629
- <tiptap-text-color-picker [editor]="editor()" />
3630
- } @if (config().separator && (config().heading1 || config().heading2 ||
3992
+ <tiptap-color-picker
3993
+ mode="text"
3994
+ [editor]="editor()"
3995
+ (interactionChange)="onColorPickerInteractionChange($event)"
3996
+ (requestUpdate)="onColorPickerUpdate()"
3997
+ />
3998
+ }
3999
+ @if (config().separator && (config().heading1 || config().heading2 ||
3631
4000
  config().heading3)) {
3632
4001
  <tiptap-separator />
3633
4002
  } @if (config().heading1) {
@@ -3761,14 +4130,14 @@ class TiptapToolbarComponent {
3761
4130
  />
3762
4131
  }
3763
4132
  </div>
3764
- `, isInline: true, styles: [".tiptap-toolbar{display:flex;align-items:center;gap:4px;padding:4px 8px;background:var(--ate-toolbar-background);border-bottom:1px solid var(--ate-toolbar-border-color);flex-wrap:wrap;min-height:32px;position:relative;-webkit-backdrop-filter:blur(var(--ate-menu-blur, 16px));backdrop-filter:blur(var(--ate-menu-blur, 16px))}.toolbar-group{display:flex;align-items:center;gap:2px;padding:0 4px}.toolbar-separator{width:1px;height:24px;background:var(--ate-toolbar-border-color);margin:0 4px}@media (max-width: 768px){.tiptap-toolbar{padding:6px 8px;gap:2px}.toolbar-group{gap:1px}}@keyframes toolbarSlideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.tiptap-toolbar{animation:toolbarSlideIn .3s cubic-bezier(.4,0,.2,1)}\n"], dependencies: [{ kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "variant", "size", "iconSize"], outputs: ["onClick"] }, { kind: "component", type: TiptapSeparatorComponent, selector: "tiptap-separator", inputs: ["orientation", "size"] }, { kind: "component", type: TiptapTextColorPickerComponent, selector: "tiptap-text-color-picker", inputs: ["editor"], outputs: ["interactionChange", "requestUpdate"] }] }); }
4133
+ `, isInline: true, styles: [".tiptap-toolbar{display:flex;align-items:center;gap:4px;padding:4px 8px;background:var(--ate-toolbar-background);border-bottom:1px solid var(--ate-toolbar-border-color);flex-wrap:wrap;min-height:32px;position:relative;z-index:50;-webkit-backdrop-filter:blur(var(--ate-menu-blur, 16px));backdrop-filter:blur(var(--ate-menu-blur, 16px));border-top-left-radius:calc(var(--ate-border-radius, 8px) - var(--ate-border-width, 2px));border-top-right-radius:calc(var(--ate-border-radius, 8px) - var(--ate-border-width, 2px))}.toolbar-group{display:flex;align-items:center;gap:2px;padding:0 4px}.toolbar-separator{width:1px;height:24px;background:var(--ate-toolbar-border-color);margin:0 4px}@media (max-width: 768px){.tiptap-toolbar{padding:6px 8px;gap:2px}.toolbar-group{gap:1px}}@keyframes toolbarSlideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.tiptap-toolbar{animation:toolbarSlideIn .3s cubic-bezier(.4,0,.2,1)}\n"], dependencies: [{ kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "backgroundColor", "variant", "size", "iconSize"], outputs: ["onClick"] }, { kind: "component", type: TiptapSeparatorComponent, selector: "tiptap-separator", inputs: ["orientation", "size"] }, { kind: "component", type: TiptapColorPickerComponent, selector: "tiptap-color-picker", inputs: ["editor", "mode"], outputs: ["interactionChange", "requestUpdate"] }] }); }
3765
4134
  }
3766
4135
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapToolbarComponent, decorators: [{
3767
4136
  type: Component,
3768
4137
  args: [{ selector: "tiptap-toolbar", standalone: true, imports: [
3769
4138
  TiptapButtonComponent,
3770
4139
  TiptapSeparatorComponent,
3771
- TiptapTextColorPickerComponent,
4140
+ TiptapColorPickerComponent,
3772
4141
  ], template: `
3773
4142
  <div class="tiptap-toolbar">
3774
4143
  @if (config().bold) {
@@ -3835,9 +4204,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
3835
4204
  [disabled]="!canExecute('toggleHighlight')"
3836
4205
  (onClick)="toggleHighlight()"
3837
4206
  />
4207
+ } @if (config().highlightPicker) {
4208
+ <tiptap-color-picker
4209
+ mode="highlight"
4210
+ [editor]="editor()"
4211
+ (interactionChange)="onColorPickerInteractionChange($event)"
4212
+ (requestUpdate)="onColorPickerUpdate()"
4213
+ />
3838
4214
  } @if (config().textColor) {
3839
- <tiptap-text-color-picker [editor]="editor()" />
3840
- } @if (config().separator && (config().heading1 || config().heading2 ||
4215
+ <tiptap-color-picker
4216
+ mode="text"
4217
+ [editor]="editor()"
4218
+ (interactionChange)="onColorPickerInteractionChange($event)"
4219
+ (requestUpdate)="onColorPickerUpdate()"
4220
+ />
4221
+ }
4222
+ @if (config().separator && (config().heading1 || config().heading2 ||
3841
4223
  config().heading3)) {
3842
4224
  <tiptap-separator />
3843
4225
  } @if (config().heading1) {
@@ -3971,7 +4353,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
3971
4353
  />
3972
4354
  }
3973
4355
  </div>
3974
- `, styles: [".tiptap-toolbar{display:flex;align-items:center;gap:4px;padding:4px 8px;background:var(--ate-toolbar-background);border-bottom:1px solid var(--ate-toolbar-border-color);flex-wrap:wrap;min-height:32px;position:relative;-webkit-backdrop-filter:blur(var(--ate-menu-blur, 16px));backdrop-filter:blur(var(--ate-menu-blur, 16px))}.toolbar-group{display:flex;align-items:center;gap:2px;padding:0 4px}.toolbar-separator{width:1px;height:24px;background:var(--ate-toolbar-border-color);margin:0 4px}@media (max-width: 768px){.tiptap-toolbar{padding:6px 8px;gap:2px}.toolbar-group{gap:1px}}@keyframes toolbarSlideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.tiptap-toolbar{animation:toolbarSlideIn .3s cubic-bezier(.4,0,.2,1)}\n"] }]
4356
+ `, styles: [".tiptap-toolbar{display:flex;align-items:center;gap:4px;padding:4px 8px;background:var(--ate-toolbar-background);border-bottom:1px solid var(--ate-toolbar-border-color);flex-wrap:wrap;min-height:32px;position:relative;z-index:50;-webkit-backdrop-filter:blur(var(--ate-menu-blur, 16px));backdrop-filter:blur(var(--ate-menu-blur, 16px));border-top-left-radius:calc(var(--ate-border-radius, 8px) - var(--ate-border-width, 2px));border-top-right-radius:calc(var(--ate-border-radius, 8px) - var(--ate-border-width, 2px))}.toolbar-group{display:flex;align-items:center;gap:2px;padding:0 4px}.toolbar-separator{width:1px;height:24px;background:var(--ate-toolbar-border-color);margin:0 4px}@media (max-width: 768px){.tiptap-toolbar{padding:6px 8px;gap:2px}.toolbar-group{gap:1px}}@keyframes toolbarSlideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.tiptap-toolbar{animation:toolbarSlideIn .3s cubic-bezier(.4,0,.2,1)}\n"] }]
3975
4357
  }], ctorParameters: () => [{ type: EditorCommandsService }] });
3976
4358
 
3977
4359
  /**
@@ -4495,7 +4877,8 @@ const DEFAULT_TOOLBAR_CONFIG = {
4495
4877
  code: true,
4496
4878
  superscript: false,
4497
4879
  subscript: false,
4498
- highlight: true,
4880
+ highlight: false,
4881
+ highlightPicker: true,
4499
4882
  heading1: true,
4500
4883
  heading2: true,
4501
4884
  heading3: true,
@@ -4525,7 +4908,8 @@ const DEFAULT_BUBBLE_MENU_CONFIG = {
4525
4908
  code: true,
4526
4909
  superscript: false,
4527
4910
  subscript: false,
4528
- highlight: true,
4911
+ highlight: false,
4912
+ highlightPicker: true,
4529
4913
  textColor: true,
4530
4914
  link: true,
4531
4915
  separator: true,
@@ -4559,6 +4943,16 @@ const DEFAULT_CELL_MENU_CONFIG = {
4559
4943
  };
4560
4944
  // La configuration des slash commands est gérée dynamiquement via slashCommandsConfigComputed
4561
4945
  class AngularTiptapEditorComponent {
4946
+ hideBubbleMenus() {
4947
+ this.textMenuComp()?.setToolbarInteracting(true);
4948
+ this.imageMenuComp()?.setToolbarInteracting(true);
4949
+ this.tableMenuComp()?.hideTippy();
4950
+ this.cellMenuComp()?.hideTippy();
4951
+ }
4952
+ showBubbleMenus() {
4953
+ this.textMenuComp()?.setToolbarInteracting(false);
4954
+ this.imageMenuComp()?.setToolbarInteracting(false);
4955
+ }
4562
4956
  constructor() {
4563
4957
  this.content = input("");
4564
4958
  this.placeholder = input("");
@@ -4616,6 +5010,11 @@ class AngularTiptapEditorComponent {
4616
5010
  this.editorBlur = output();
4617
5011
  // ViewChild avec signal
4618
5012
  this.editorElement = viewChild.required("editorElement");
5013
+ // Signaux pour les menus (Références vers les composants)
5014
+ this.textMenuComp = viewChild(TiptapBubbleMenuComponent);
5015
+ this.imageMenuComp = viewChild(TiptapImageBubbleMenuComponent);
5016
+ this.tableMenuComp = viewChild(TiptapTableBubbleMenuComponent);
5017
+ this.cellMenuComp = viewChild(TiptapCellBubbleMenuComponent);
4619
5018
  // Signals privés pour l'état interne
4620
5019
  this._editor = signal(null);
4621
5020
  this._characterCount = signal(0);
@@ -5016,7 +5415,7 @@ class AngularTiptapEditorComponent {
5016
5415
  }
5017
5416
  }
5018
5417
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AngularTiptapEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5019
- 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 }, fillContainer: { classPropertyName: "fillContainer", publicName: "fillContainer", 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 }, showWordCount: { classPropertyName: "showWordCount", publicName: "showWordCount", 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 }, slashCommands: { classPropertyName: "slashCommands", publicName: "slashCommands", isSignal: true, isRequired: false, transformFunction: null }, customSlashCommands: { classPropertyName: "customSlashCommands", publicName: "customSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, tiptapExtensions: { classPropertyName: "tiptapExtensions", publicName: "tiptapExtensions", isSignal: true, isRequired: false, transformFunction: null }, tiptapOptions: { classPropertyName: "tiptapOptions", publicName: "tiptapOptions", 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 }, imageUploadHandler: { classPropertyName: "imageUploadHandler", publicName: "imageUploadHandler", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contentChange: "contentChange", editorCreated: "editorCreated", editorUpdate: "editorUpdate", editorFocus: "editorFocus", editorBlur: "editorBlur" }, host: { properties: { "class.fill-container": "fillContainer()" } }, viewQueries: [{ propertyName: "editorElement", first: true, predicate: ["editorElement"], descendants: true, isSignal: true }], hostDirectives: [{ directive: NoopValueAccessorDirective }], ngImport: i0, template: `
5418
+ 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 }, fillContainer: { classPropertyName: "fillContainer", publicName: "fillContainer", 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 }, showWordCount: { classPropertyName: "showWordCount", publicName: "showWordCount", 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 }, slashCommands: { classPropertyName: "slashCommands", publicName: "slashCommands", isSignal: true, isRequired: false, transformFunction: null }, customSlashCommands: { classPropertyName: "customSlashCommands", publicName: "customSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, tiptapExtensions: { classPropertyName: "tiptapExtensions", publicName: "tiptapExtensions", isSignal: true, isRequired: false, transformFunction: null }, tiptapOptions: { classPropertyName: "tiptapOptions", publicName: "tiptapOptions", 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 }, imageUploadHandler: { classPropertyName: "imageUploadHandler", publicName: "imageUploadHandler", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contentChange: "contentChange", editorCreated: "editorCreated", editorUpdate: "editorUpdate", editorFocus: "editorFocus", editorBlur: "editorBlur" }, host: { properties: { "class.fill-container": "fillContainer()" } }, viewQueries: [{ propertyName: "editorElement", first: true, predicate: ["editorElement"], descendants: true, isSignal: true }, { propertyName: "textMenuComp", first: true, predicate: TiptapBubbleMenuComponent, descendants: true, isSignal: true }, { propertyName: "imageMenuComp", first: true, predicate: TiptapImageBubbleMenuComponent, descendants: true, isSignal: true }, { propertyName: "tableMenuComp", first: true, predicate: TiptapTableBubbleMenuComponent, descendants: true, isSignal: true }, { propertyName: "cellMenuComp", first: true, predicate: TiptapCellBubbleMenuComponent, descendants: true, isSignal: true }], hostDirectives: [{ directive: NoopValueAccessorDirective }], ngImport: i0, template: `
5020
5419
  <div class="tiptap-editor" [class.fill-container]="fillContainer()">
5021
5420
  <!-- Toolbar -->
5022
5421
  @if (showToolbar() && editor()) {
@@ -5024,6 +5423,8 @@ class AngularTiptapEditorComponent {
5024
5423
  [editor]="editor()!"
5025
5424
  [config]="toolbarConfig()"
5026
5425
  [imageUpload]="imageUploadConfig()"
5426
+ (mouseenter)="hideBubbleMenus()"
5427
+ (mouseleave)="showBubbleMenus()"
5027
5428
  />
5028
5429
  }
5029
5430
 
@@ -5105,7 +5506,7 @@ class AngularTiptapEditorComponent {
5105
5506
  </div>
5106
5507
  }
5107
5508
  </div>
5108
- `, isInline: true, styles: [":host{--ate-primary: #2563eb;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 90%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 95%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-surface: #ffffff;--ate-surface-secondary: #f8f9fa;--ate-surface-tertiary: #f1f5f9;--ate-text: #2d3748;--ate-text-secondary: #64748b;--ate-text-muted: #a0aec0;--ate-border: #e2e8f0;--ate-highlight-bg: #fef08a;--ate-highlight-color: #854d0e;--ate-button-hover: #f1f5f9;--ate-button-active: #e2e8f0;--ate-menu-bg: rgba(255, 255, 255, .98);--ate-menu-border: var(--ate-border);--ate-menu-shadow: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -2px rgba(0, 0, 0, .05);--ate-menu-blur: 16px;--ate-error-color: #c53030;--ate-error-bg: #fed7d7;--ate-error-border: #feb2b2;--ate-border-color: var(--ate-border);--ate-border-width: 2px;--ate-border-radius: 8px;--ate-focus-color: var(--ate-primary);--ate-background: var(--ate-surface);--ate-text-color: var(--ate-text);--ate-placeholder-color: var(--ate-text-muted);--ate-line-height: 1.6;--ate-content-padding: 16px;--ate-toolbar-background: var(--ate-surface-secondary);--ate-toolbar-border-color: var(--ate-border);--ate-toolbar-button-color: var(--ate-text-secondary);--ate-toolbar-button-hover-background: transparent;--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-counter-color: var(--ate-text-secondary);--ate-counter-background: var(--ate-surface-secondary);--ate-counter-border-color: var(--ate-border);--ate-drag-background: #f0f8ff;--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-border);--ate-blockquote-background: var(--ate-surface-secondary);--ate-code-background: var(--ate-surface-secondary);--ate-code-color: var(--ate-text);--ate-code-block-background: #181825;--ate-code-block-color: #e2e8f0;--ate-code-border-color: var(--ate-border);--ate-code-block-border-color: var(--ate-border);--ate-image-border-radius: 8px;--ate-image-selected-color: var(--ate-primary);--ate-scrollbar-width: 10px;--ate-scrollbar-thumb: var(--ate-border);--ate-scrollbar-thumb-hover: var(--ate-text-muted);--ate-scrollbar-track: transparent;--ate-table-border-color: var(--ate-border);--ate-table-header-background: var(--ate-surface-secondary);--ate-table-header-color: var(--ate-text);--ate-table-cell-background: var(--ate-surface);--ate-table-cell-selected-background: var(--ate-primary-light);--ate-table-resize-handle-color: var(--ate-primary);--ate-table-row-hover-background: var(--ate-primary-lighter)}:host(.dark),:host([data-theme=\"dark\"]){--ate-primary: #3b82f6;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 92%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 80%);--ate-surface: #020617;--ate-surface-secondary: #0f172a;--ate-surface-tertiary: #1e293b;--ate-text: #f8fafc;--ate-text-secondary: #94a3b8;--ate-text-muted: #64748b;--ate-border: #1e293b;--ate-highlight-bg: #854d0e;--ate-highlight-color: #fef08a;--ate-button-hover: #1e293b;--ate-button-active: #0f172a;--ate-menu-bg: rgba(15, 23, 42, .95);--ate-menu-border: rgba(255, 255, 255, .1);--ate-menu-shadow: 0 20px 25px -5px rgba(0, 0, 0, .3), 0 10px 10px -5px rgba(0, 0, 0, .2);--ate-menu-blur: 16px;--ate-error-color: #f87171;--ate-error-bg: #450a0a;--ate-error-border: #7f1d1d;--ate-drag-background: var(--ate-surface-tertiary);--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-primary);--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-button-hover: var(--ate-surface-tertiary);--ate-button-active: var(--ate-surface-secondary);--ate-scrollbar-thumb: var(--ate-surface-tertiary);--ate-scrollbar-thumb-hover: var(--ate-text-muted)}:host(.fill-container){display:block;height:100%}.tiptap-editor{border:var(--ate-border-width) solid var(--ate-border-color);border-radius:var(--ate-border-radius);background:var(--ate-background);overflow:hidden;transition:border-color .2s ease}.tiptap-editor.fill-container{display:flex;flex-direction:column;height:100%}.tiptap-editor.fill-container .tiptap-content{flex:1;min-height:0;overflow-y:auto}.tiptap-editor:focus-within{border-color:var(--ate-focus-color)}.tiptap-content{padding:var(--ate-content-padding);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;scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}.tiptap-content::-webkit-scrollbar{width:var(--ate-scrollbar-width);height:var(--ate-scrollbar-width)}.tiptap-content::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.tiptap-content::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.tiptap-content::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}.tiptap-content.drag-over{background:var(--ate-drag-background);border:2px dashed var(--ate-drag-border-color)}.character-count{padding:8px var(--ate-content-padding);font-size:12px;color:var(--ate-counter-color);text-align:right;border-top:1px solid var(--ate-counter-border-color);background:var(--ate-counter-background);transition:color .2s ease}.character-count.limit-reached{color:var(--ate-error-color, #ef4444);font-weight:600}:host ::ng-deep .ProseMirror{outline:none;line-height:var(--ate-line-height);color:var(--ate-text-color);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 var(--ate-blockquote-border-color);margin:1em 0;font-style:italic;background:var(--ate-blockquote-background);padding:.5em 1em;border-radius:0 4px 4px 0}:host ::ng-deep .ProseMirror code{background:var(--ate-code-background);color:var(--ate-code-color);border:1px solid var(--ate-code-border-color);padding:.2em .4em;border-radius:3px;font-family:Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .ProseMirror pre{background:var(--ate-code-block-background);color:var(--ate-code-block-color);border:1px solid var(--ate-code-block-border-color);padding:1em;border-radius:6px;overflow-x:auto;margin:1em 0}:host ::ng-deep .ProseMirror pre code{background:none;color:inherit;border:none;padding:0}:host ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:var(--ate-placeholder-color);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:var(--ate-image-border-radius)}:host ::ng-deep .ProseMirror img:hover{border-color:var(--ate-border-color);box-shadow:0 2px 4px #0000001a}:host ::ng-deep .ProseMirror img.ProseMirror-selectednode{border-color:var(--ate-image-selected-color);box-shadow:0 0 0 3px var(--ate-primary-light-alpha);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 var(--ate-primary);outline-offset:2px;border-radius:16px;box-shadow:0 0 0 4px var(--ate-primary-light-alpha)}: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:var(--ate-primary);border:2px solid var(--ate-surface);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:var(--ate-primary);box-shadow:0 3px 8px #0000004d}:host ::ng-deep .resize-handle:active{background:var(--ate-primary)}: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}:host ::ng-deep .ProseMirror table{border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed;width:100%;border-radius:8px;overflow:hidden}:host ::ng-deep .ProseMirror table td,:host ::ng-deep .ProseMirror table th{border:none;border-right:1px solid var(--ate-table-border-color);border-bottom:1px solid var(--ate-table-border-color);box-sizing:border-box;min-width:1em;padding:8px 12px;position:relative;vertical-align:top;text-align:left}:host ::ng-deep .ProseMirror table td{background:var(--ate-table-cell-background)}:host ::ng-deep .ProseMirror table td:first-child,:host ::ng-deep .ProseMirror table th:first-child{border-left:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child td,:host ::ng-deep .ProseMirror table tr:first-child th{border-top:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child th:first-child{border-top-left-radius:8px}:host ::ng-deep .ProseMirror table tr:first-child th:last-child{border-top-right-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:first-child{border-bottom-left-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:last-child{border-bottom-right-radius:8px}:host ::ng-deep .ProseMirror table th{background:var(--ate-table-header-background);font-weight:600;color:var(--ate-table-header-color)}:host ::ng-deep .ProseMirror table .selectedCell:after{background:var(--ate-table-cell-selected-background);content:\"\";inset:0;pointer-events:none;position:absolute;z-index:2}:host ::ng-deep .ProseMirror table .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;background-color:var(--ate-table-resize-handle-color);opacity:0;transition:opacity .2s ease}:host ::ng-deep .ProseMirror table:hover .column-resize-handle{opacity:1}:host ::ng-deep .ProseMirror table .column-resize-handle:hover{background-color:var(--ate-focus-color)}:host ::ng-deep .ProseMirror .tableWrapper{overflow-x:auto;margin:1em 0;border-radius:8px}:host ::ng-deep .ProseMirror .tableWrapper table{margin:0;border-radius:8px;min-width:600px;overflow:hidden}:host ::ng-deep .ProseMirror table p{margin:0}:host ::ng-deep .ProseMirror table tbody tr:hover td{background-color:var(--ate-table-row-hover-background)}\n"], dependencies: [{ kind: "component", type: TiptapToolbarComponent, selector: "tiptap-toolbar", inputs: ["editor", "config", "imageUpload"], outputs: ["imageUploaded", "imageError"] }, { kind: "component", type: TiptapBubbleMenuComponent, selector: "tiptap-bubble-menu", inputs: ["editor", "config"] }, { kind: "component", type: TiptapImageBubbleMenuComponent, selector: "tiptap-image-bubble-menu", inputs: ["editor", "config"] }, { kind: "component", type: TiptapTableBubbleMenuComponent, selector: "tiptap-table-bubble-menu", inputs: ["editor", "config"] }, { kind: "component", type: TiptapCellBubbleMenuComponent, selector: "tiptap-cell-bubble-menu", inputs: ["editor", "config"] }, { kind: "component", type: TiptapSlashCommandsComponent, selector: "tiptap-slash-commands", inputs: ["editor", "config"], outputs: ["imageUploadRequested"] }] }); }
5509
+ `, isInline: true, styles: [":host{--ate-primary: #2563eb;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 90%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 95%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-surface: #ffffff;--ate-surface-secondary: #f8f9fa;--ate-surface-tertiary: #f1f5f9;--ate-text: #2d3748;--ate-text-secondary: #64748b;--ate-text-muted: #a0aec0;--ate-border: #e2e8f0;--ate-highlight-bg: #fef08a;--ate-highlight-color: #854d0e;--ate-button-hover: #f1f5f9;--ate-button-active: #e2e8f0;--ate-menu-bg: rgba(255, 255, 255, .98);--ate-menu-border: var(--ate-border);--ate-menu-shadow: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -2px rgba(0, 0, 0, .05);--ate-menu-blur: 16px;--ate-error-color: #c53030;--ate-error-bg: #fed7d7;--ate-error-border: #feb2b2;--ate-border-color: var(--ate-border);--ate-border-width: 2px;--ate-border-radius: 8px;--ate-focus-color: var(--ate-primary);--ate-background: var(--ate-surface);--ate-text-color: var(--ate-text);--ate-placeholder-color: var(--ate-text-muted);--ate-line-height: 1.6;--ate-content-padding: 16px;--ate-toolbar-background: var(--ate-surface-secondary);--ate-toolbar-border-color: var(--ate-border);--ate-toolbar-button-color: var(--ate-text-secondary);--ate-toolbar-button-hover-background: transparent;--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-counter-color: var(--ate-text-secondary);--ate-counter-background: var(--ate-surface-secondary);--ate-counter-border-color: var(--ate-border);--ate-drag-background: #f0f8ff;--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-border);--ate-blockquote-background: var(--ate-surface-secondary);--ate-code-background: var(--ate-surface-secondary);--ate-code-color: var(--ate-text);--ate-code-block-background: #181825;--ate-code-block-color: #e2e8f0;--ate-code-border-color: var(--ate-border);--ate-code-block-border-color: var(--ate-border);--ate-image-border-radius: 8px;--ate-image-selected-color: var(--ate-primary);--ate-scrollbar-width: 10px;--ate-scrollbar-thumb: var(--ate-border);--ate-scrollbar-thumb-hover: var(--ate-text-muted);--ate-scrollbar-track: transparent;--ate-table-border-color: var(--ate-border);--ate-table-header-background: var(--ate-surface-secondary);--ate-table-header-color: var(--ate-text);--ate-table-cell-background: var(--ate-surface);--ate-table-cell-selected-background: var(--ate-primary-light);--ate-table-resize-handle-color: var(--ate-primary);--ate-table-row-hover-background: var(--ate-primary-lighter)}:host(.dark),:host([data-theme=\"dark\"]){--ate-primary: #3b82f6;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 92%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 80%);--ate-surface: #020617;--ate-surface-secondary: #0f172a;--ate-surface-tertiary: #1e293b;--ate-text: #f8fafc;--ate-text-secondary: #94a3b8;--ate-text-muted: #64748b;--ate-border: #1e293b;--ate-highlight-bg: #854d0e;--ate-highlight-color: #fef08a;--ate-button-hover: #1e293b;--ate-button-active: #0f172a;--ate-menu-bg: rgba(15, 23, 42, .95);--ate-menu-border: rgba(255, 255, 255, .1);--ate-menu-shadow: 0 20px 25px -5px rgba(0, 0, 0, .3), 0 10px 10px -5px rgba(0, 0, 0, .2);--ate-menu-blur: 16px;--ate-error-color: #f87171;--ate-error-bg: #450a0a;--ate-error-border: #7f1d1d;--ate-drag-background: var(--ate-surface-tertiary);--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-primary);--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-button-hover: var(--ate-surface-tertiary);--ate-button-active: var(--ate-surface-secondary);--ate-scrollbar-thumb: var(--ate-surface-tertiary);--ate-scrollbar-thumb-hover: var(--ate-text-muted)}:host(.fill-container){display:block;height:100%}.tiptap-editor{border:var(--ate-border-width) solid var(--ate-border-color);border-radius:var(--ate-border-radius);background:var(--ate-background);overflow:visible;transition:border-color .2s ease;position:relative}.tiptap-editor.fill-container{display:flex;flex-direction:column;height:100%}.tiptap-editor.fill-container .tiptap-content{flex:1;min-height:0;overflow-y:auto}.tiptap-editor:focus-within{border-color:var(--ate-focus-color)}.tiptap-content{padding:var(--ate-content-padding);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;scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}.tiptap-content::-webkit-scrollbar{width:var(--ate-scrollbar-width);height:var(--ate-scrollbar-width)}.tiptap-content::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.tiptap-content::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.tiptap-content::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}.tiptap-content.drag-over{background:var(--ate-drag-background);border:2px dashed var(--ate-drag-border-color)}.character-count{padding:8px var(--ate-content-padding);font-size:12px;color:var(--ate-counter-color);text-align:right;border-top:1px solid var(--ate-counter-border-color);background:var(--ate-counter-background);transition:color .2s ease;border-bottom-left-radius:calc(var(--ate-border-radius) - var(--ate-border-width));border-bottom-right-radius:calc(var(--ate-border-radius) - var(--ate-border-width))}.character-count.limit-reached{color:var(--ate-error-color, #ef4444);font-weight:600}:host ::ng-deep .ProseMirror{outline:none;line-height:var(--ate-line-height);color:var(--ate-text-color);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 var(--ate-blockquote-border-color);margin:1em 0;font-style:italic;background:var(--ate-blockquote-background);padding:.5em 1em;border-radius:0 4px 4px 0}:host ::ng-deep .ProseMirror code{background:var(--ate-code-background);color:var(--ate-code-color);border:1px solid var(--ate-code-border-color);padding:.2em .4em;border-radius:3px;font-family:Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .ProseMirror pre{background:var(--ate-code-block-background);color:var(--ate-code-block-color);border:1px solid var(--ate-code-block-border-color);padding:1em;border-radius:6px;overflow-x:auto;margin:1em 0}:host ::ng-deep .ProseMirror pre code{background:none;color:inherit;border:none;padding:0}:host ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:var(--ate-placeholder-color);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:var(--ate-image-border-radius)}:host ::ng-deep .ProseMirror img:hover{border-color:var(--ate-border-color);box-shadow:0 2px 4px #0000001a}:host ::ng-deep .ProseMirror img.ProseMirror-selectednode{border-color:var(--ate-image-selected-color);box-shadow:0 0 0 3px var(--ate-primary-light-alpha);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 var(--ate-primary);outline-offset:2px;border-radius:16px;box-shadow:0 0 0 4px var(--ate-primary-light-alpha)}: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:var(--ate-primary);border:2px solid var(--ate-surface);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:var(--ate-primary);box-shadow:0 3px 8px #0000004d}:host ::ng-deep .resize-handle:active{background:var(--ate-primary)}: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}:host ::ng-deep .ProseMirror table{border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed;width:100%;border-radius:8px;overflow:hidden}:host ::ng-deep .ProseMirror table td,:host ::ng-deep .ProseMirror table th{border:none;border-right:1px solid var(--ate-table-border-color);border-bottom:1px solid var(--ate-table-border-color);box-sizing:border-box;min-width:1em;padding:8px 12px;position:relative;vertical-align:top;text-align:left}:host ::ng-deep .ProseMirror table td{background:var(--ate-table-cell-background)}:host ::ng-deep .ProseMirror table td:first-child,:host ::ng-deep .ProseMirror table th:first-child{border-left:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child td,:host ::ng-deep .ProseMirror table tr:first-child th{border-top:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child th:first-child{border-top-left-radius:8px}:host ::ng-deep .ProseMirror table tr:first-child th:last-child{border-top-right-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:first-child{border-bottom-left-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:last-child{border-bottom-right-radius:8px}:host ::ng-deep .ProseMirror table th{background:var(--ate-table-header-background);font-weight:600;color:var(--ate-table-header-color)}:host ::ng-deep .ProseMirror table .selectedCell:after{background:var(--ate-table-cell-selected-background);content:\"\";inset:0;pointer-events:none;position:absolute;z-index:2}:host ::ng-deep .ProseMirror table .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;background-color:var(--ate-table-resize-handle-color);opacity:0;transition:opacity .2s ease}:host ::ng-deep .ProseMirror table:hover .column-resize-handle{opacity:1}:host ::ng-deep .ProseMirror table .column-resize-handle:hover{background-color:var(--ate-focus-color)}:host ::ng-deep .ProseMirror .tableWrapper{overflow-x:auto;margin:1em 0;border-radius:8px}:host ::ng-deep .ProseMirror .tableWrapper table{margin:0;border-radius:8px;min-width:600px;overflow:hidden}:host ::ng-deep .ProseMirror table p{margin:0}:host ::ng-deep .ProseMirror table tbody tr:hover td{background-color:var(--ate-table-row-hover-background)}\n"], dependencies: [{ kind: "component", type: TiptapToolbarComponent, selector: "tiptap-toolbar", inputs: ["editor", "config", "imageUpload"], outputs: ["imageUploaded", "imageError"] }, { kind: "component", type: TiptapBubbleMenuComponent, selector: "tiptap-bubble-menu", inputs: ["editor", "config"] }, { kind: "component", type: TiptapImageBubbleMenuComponent, selector: "tiptap-image-bubble-menu", inputs: ["editor", "config"] }, { kind: "component", type: TiptapTableBubbleMenuComponent, selector: "tiptap-table-bubble-menu", inputs: ["editor", "config"] }, { kind: "component", type: TiptapCellBubbleMenuComponent, selector: "tiptap-cell-bubble-menu", inputs: ["editor", "config"] }, { kind: "component", type: TiptapSlashCommandsComponent, selector: "tiptap-slash-commands", inputs: ["editor", "config"], outputs: ["imageUploadRequested"] }] }); }
5109
5510
  }
5110
5511
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AngularTiptapEditorComponent, decorators: [{
5111
5512
  type: Component,
@@ -5126,6 +5527,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
5126
5527
  [editor]="editor()!"
5127
5528
  [config]="toolbarConfig()"
5128
5529
  [imageUpload]="imageUploadConfig()"
5530
+ (mouseenter)="hideBubbleMenus()"
5531
+ (mouseleave)="showBubbleMenus()"
5129
5532
  />
5130
5533
  }
5131
5534
 
@@ -5207,7 +5610,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
5207
5610
  </div>
5208
5611
  }
5209
5612
  </div>
5210
- `, styles: [":host{--ate-primary: #2563eb;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 90%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 95%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-surface: #ffffff;--ate-surface-secondary: #f8f9fa;--ate-surface-tertiary: #f1f5f9;--ate-text: #2d3748;--ate-text-secondary: #64748b;--ate-text-muted: #a0aec0;--ate-border: #e2e8f0;--ate-highlight-bg: #fef08a;--ate-highlight-color: #854d0e;--ate-button-hover: #f1f5f9;--ate-button-active: #e2e8f0;--ate-menu-bg: rgba(255, 255, 255, .98);--ate-menu-border: var(--ate-border);--ate-menu-shadow: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -2px rgba(0, 0, 0, .05);--ate-menu-blur: 16px;--ate-error-color: #c53030;--ate-error-bg: #fed7d7;--ate-error-border: #feb2b2;--ate-border-color: var(--ate-border);--ate-border-width: 2px;--ate-border-radius: 8px;--ate-focus-color: var(--ate-primary);--ate-background: var(--ate-surface);--ate-text-color: var(--ate-text);--ate-placeholder-color: var(--ate-text-muted);--ate-line-height: 1.6;--ate-content-padding: 16px;--ate-toolbar-background: var(--ate-surface-secondary);--ate-toolbar-border-color: var(--ate-border);--ate-toolbar-button-color: var(--ate-text-secondary);--ate-toolbar-button-hover-background: transparent;--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-counter-color: var(--ate-text-secondary);--ate-counter-background: var(--ate-surface-secondary);--ate-counter-border-color: var(--ate-border);--ate-drag-background: #f0f8ff;--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-border);--ate-blockquote-background: var(--ate-surface-secondary);--ate-code-background: var(--ate-surface-secondary);--ate-code-color: var(--ate-text);--ate-code-block-background: #181825;--ate-code-block-color: #e2e8f0;--ate-code-border-color: var(--ate-border);--ate-code-block-border-color: var(--ate-border);--ate-image-border-radius: 8px;--ate-image-selected-color: var(--ate-primary);--ate-scrollbar-width: 10px;--ate-scrollbar-thumb: var(--ate-border);--ate-scrollbar-thumb-hover: var(--ate-text-muted);--ate-scrollbar-track: transparent;--ate-table-border-color: var(--ate-border);--ate-table-header-background: var(--ate-surface-secondary);--ate-table-header-color: var(--ate-text);--ate-table-cell-background: var(--ate-surface);--ate-table-cell-selected-background: var(--ate-primary-light);--ate-table-resize-handle-color: var(--ate-primary);--ate-table-row-hover-background: var(--ate-primary-lighter)}:host(.dark),:host([data-theme=\"dark\"]){--ate-primary: #3b82f6;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 92%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 80%);--ate-surface: #020617;--ate-surface-secondary: #0f172a;--ate-surface-tertiary: #1e293b;--ate-text: #f8fafc;--ate-text-secondary: #94a3b8;--ate-text-muted: #64748b;--ate-border: #1e293b;--ate-highlight-bg: #854d0e;--ate-highlight-color: #fef08a;--ate-button-hover: #1e293b;--ate-button-active: #0f172a;--ate-menu-bg: rgba(15, 23, 42, .95);--ate-menu-border: rgba(255, 255, 255, .1);--ate-menu-shadow: 0 20px 25px -5px rgba(0, 0, 0, .3), 0 10px 10px -5px rgba(0, 0, 0, .2);--ate-menu-blur: 16px;--ate-error-color: #f87171;--ate-error-bg: #450a0a;--ate-error-border: #7f1d1d;--ate-drag-background: var(--ate-surface-tertiary);--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-primary);--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-button-hover: var(--ate-surface-tertiary);--ate-button-active: var(--ate-surface-secondary);--ate-scrollbar-thumb: var(--ate-surface-tertiary);--ate-scrollbar-thumb-hover: var(--ate-text-muted)}:host(.fill-container){display:block;height:100%}.tiptap-editor{border:var(--ate-border-width) solid var(--ate-border-color);border-radius:var(--ate-border-radius);background:var(--ate-background);overflow:hidden;transition:border-color .2s ease}.tiptap-editor.fill-container{display:flex;flex-direction:column;height:100%}.tiptap-editor.fill-container .tiptap-content{flex:1;min-height:0;overflow-y:auto}.tiptap-editor:focus-within{border-color:var(--ate-focus-color)}.tiptap-content{padding:var(--ate-content-padding);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;scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}.tiptap-content::-webkit-scrollbar{width:var(--ate-scrollbar-width);height:var(--ate-scrollbar-width)}.tiptap-content::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.tiptap-content::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.tiptap-content::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}.tiptap-content.drag-over{background:var(--ate-drag-background);border:2px dashed var(--ate-drag-border-color)}.character-count{padding:8px var(--ate-content-padding);font-size:12px;color:var(--ate-counter-color);text-align:right;border-top:1px solid var(--ate-counter-border-color);background:var(--ate-counter-background);transition:color .2s ease}.character-count.limit-reached{color:var(--ate-error-color, #ef4444);font-weight:600}:host ::ng-deep .ProseMirror{outline:none;line-height:var(--ate-line-height);color:var(--ate-text-color);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 var(--ate-blockquote-border-color);margin:1em 0;font-style:italic;background:var(--ate-blockquote-background);padding:.5em 1em;border-radius:0 4px 4px 0}:host ::ng-deep .ProseMirror code{background:var(--ate-code-background);color:var(--ate-code-color);border:1px solid var(--ate-code-border-color);padding:.2em .4em;border-radius:3px;font-family:Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .ProseMirror pre{background:var(--ate-code-block-background);color:var(--ate-code-block-color);border:1px solid var(--ate-code-block-border-color);padding:1em;border-radius:6px;overflow-x:auto;margin:1em 0}:host ::ng-deep .ProseMirror pre code{background:none;color:inherit;border:none;padding:0}:host ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:var(--ate-placeholder-color);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:var(--ate-image-border-radius)}:host ::ng-deep .ProseMirror img:hover{border-color:var(--ate-border-color);box-shadow:0 2px 4px #0000001a}:host ::ng-deep .ProseMirror img.ProseMirror-selectednode{border-color:var(--ate-image-selected-color);box-shadow:0 0 0 3px var(--ate-primary-light-alpha);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 var(--ate-primary);outline-offset:2px;border-radius:16px;box-shadow:0 0 0 4px var(--ate-primary-light-alpha)}: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:var(--ate-primary);border:2px solid var(--ate-surface);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:var(--ate-primary);box-shadow:0 3px 8px #0000004d}:host ::ng-deep .resize-handle:active{background:var(--ate-primary)}: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}:host ::ng-deep .ProseMirror table{border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed;width:100%;border-radius:8px;overflow:hidden}:host ::ng-deep .ProseMirror table td,:host ::ng-deep .ProseMirror table th{border:none;border-right:1px solid var(--ate-table-border-color);border-bottom:1px solid var(--ate-table-border-color);box-sizing:border-box;min-width:1em;padding:8px 12px;position:relative;vertical-align:top;text-align:left}:host ::ng-deep .ProseMirror table td{background:var(--ate-table-cell-background)}:host ::ng-deep .ProseMirror table td:first-child,:host ::ng-deep .ProseMirror table th:first-child{border-left:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child td,:host ::ng-deep .ProseMirror table tr:first-child th{border-top:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child th:first-child{border-top-left-radius:8px}:host ::ng-deep .ProseMirror table tr:first-child th:last-child{border-top-right-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:first-child{border-bottom-left-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:last-child{border-bottom-right-radius:8px}:host ::ng-deep .ProseMirror table th{background:var(--ate-table-header-background);font-weight:600;color:var(--ate-table-header-color)}:host ::ng-deep .ProseMirror table .selectedCell:after{background:var(--ate-table-cell-selected-background);content:\"\";inset:0;pointer-events:none;position:absolute;z-index:2}:host ::ng-deep .ProseMirror table .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;background-color:var(--ate-table-resize-handle-color);opacity:0;transition:opacity .2s ease}:host ::ng-deep .ProseMirror table:hover .column-resize-handle{opacity:1}:host ::ng-deep .ProseMirror table .column-resize-handle:hover{background-color:var(--ate-focus-color)}:host ::ng-deep .ProseMirror .tableWrapper{overflow-x:auto;margin:1em 0;border-radius:8px}:host ::ng-deep .ProseMirror .tableWrapper table{margin:0;border-radius:8px;min-width:600px;overflow:hidden}:host ::ng-deep .ProseMirror table p{margin:0}:host ::ng-deep .ProseMirror table tbody tr:hover td{background-color:var(--ate-table-row-hover-background)}\n"] }]
5613
+ `, styles: [":host{--ate-primary: #2563eb;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 90%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 95%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-surface: #ffffff;--ate-surface-secondary: #f8f9fa;--ate-surface-tertiary: #f1f5f9;--ate-text: #2d3748;--ate-text-secondary: #64748b;--ate-text-muted: #a0aec0;--ate-border: #e2e8f0;--ate-highlight-bg: #fef08a;--ate-highlight-color: #854d0e;--ate-button-hover: #f1f5f9;--ate-button-active: #e2e8f0;--ate-menu-bg: rgba(255, 255, 255, .98);--ate-menu-border: var(--ate-border);--ate-menu-shadow: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -2px rgba(0, 0, 0, .05);--ate-menu-blur: 16px;--ate-error-color: #c53030;--ate-error-bg: #fed7d7;--ate-error-border: #feb2b2;--ate-border-color: var(--ate-border);--ate-border-width: 2px;--ate-border-radius: 8px;--ate-focus-color: var(--ate-primary);--ate-background: var(--ate-surface);--ate-text-color: var(--ate-text);--ate-placeholder-color: var(--ate-text-muted);--ate-line-height: 1.6;--ate-content-padding: 16px;--ate-toolbar-background: var(--ate-surface-secondary);--ate-toolbar-border-color: var(--ate-border);--ate-toolbar-button-color: var(--ate-text-secondary);--ate-toolbar-button-hover-background: transparent;--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-counter-color: var(--ate-text-secondary);--ate-counter-background: var(--ate-surface-secondary);--ate-counter-border-color: var(--ate-border);--ate-drag-background: #f0f8ff;--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-border);--ate-blockquote-background: var(--ate-surface-secondary);--ate-code-background: var(--ate-surface-secondary);--ate-code-color: var(--ate-text);--ate-code-block-background: #181825;--ate-code-block-color: #e2e8f0;--ate-code-border-color: var(--ate-border);--ate-code-block-border-color: var(--ate-border);--ate-image-border-radius: 8px;--ate-image-selected-color: var(--ate-primary);--ate-scrollbar-width: 10px;--ate-scrollbar-thumb: var(--ate-border);--ate-scrollbar-thumb-hover: var(--ate-text-muted);--ate-scrollbar-track: transparent;--ate-table-border-color: var(--ate-border);--ate-table-header-background: var(--ate-surface-secondary);--ate-table-header-color: var(--ate-text);--ate-table-cell-background: var(--ate-surface);--ate-table-cell-selected-background: var(--ate-primary-light);--ate-table-resize-handle-color: var(--ate-primary);--ate-table-row-hover-background: var(--ate-primary-lighter)}:host(.dark),:host([data-theme=\"dark\"]){--ate-primary: #3b82f6;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 92%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 80%);--ate-surface: #020617;--ate-surface-secondary: #0f172a;--ate-surface-tertiary: #1e293b;--ate-text: #f8fafc;--ate-text-secondary: #94a3b8;--ate-text-muted: #64748b;--ate-border: #1e293b;--ate-highlight-bg: #854d0e;--ate-highlight-color: #fef08a;--ate-button-hover: #1e293b;--ate-button-active: #0f172a;--ate-menu-bg: rgba(15, 23, 42, .95);--ate-menu-border: rgba(255, 255, 255, .1);--ate-menu-shadow: 0 20px 25px -5px rgba(0, 0, 0, .3), 0 10px 10px -5px rgba(0, 0, 0, .2);--ate-menu-blur: 16px;--ate-error-color: #f87171;--ate-error-bg: #450a0a;--ate-error-border: #7f1d1d;--ate-drag-background: var(--ate-surface-tertiary);--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-primary);--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-button-hover: var(--ate-surface-tertiary);--ate-button-active: var(--ate-surface-secondary);--ate-scrollbar-thumb: var(--ate-surface-tertiary);--ate-scrollbar-thumb-hover: var(--ate-text-muted)}:host(.fill-container){display:block;height:100%}.tiptap-editor{border:var(--ate-border-width) solid var(--ate-border-color);border-radius:var(--ate-border-radius);background:var(--ate-background);overflow:visible;transition:border-color .2s ease;position:relative}.tiptap-editor.fill-container{display:flex;flex-direction:column;height:100%}.tiptap-editor.fill-container .tiptap-content{flex:1;min-height:0;overflow-y:auto}.tiptap-editor:focus-within{border-color:var(--ate-focus-color)}.tiptap-content{padding:var(--ate-content-padding);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;scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}.tiptap-content::-webkit-scrollbar{width:var(--ate-scrollbar-width);height:var(--ate-scrollbar-width)}.tiptap-content::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.tiptap-content::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.tiptap-content::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}.tiptap-content.drag-over{background:var(--ate-drag-background);border:2px dashed var(--ate-drag-border-color)}.character-count{padding:8px var(--ate-content-padding);font-size:12px;color:var(--ate-counter-color);text-align:right;border-top:1px solid var(--ate-counter-border-color);background:var(--ate-counter-background);transition:color .2s ease;border-bottom-left-radius:calc(var(--ate-border-radius) - var(--ate-border-width));border-bottom-right-radius:calc(var(--ate-border-radius) - var(--ate-border-width))}.character-count.limit-reached{color:var(--ate-error-color, #ef4444);font-weight:600}:host ::ng-deep .ProseMirror{outline:none;line-height:var(--ate-line-height);color:var(--ate-text-color);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 var(--ate-blockquote-border-color);margin:1em 0;font-style:italic;background:var(--ate-blockquote-background);padding:.5em 1em;border-radius:0 4px 4px 0}:host ::ng-deep .ProseMirror code{background:var(--ate-code-background);color:var(--ate-code-color);border:1px solid var(--ate-code-border-color);padding:.2em .4em;border-radius:3px;font-family:Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .ProseMirror pre{background:var(--ate-code-block-background);color:var(--ate-code-block-color);border:1px solid var(--ate-code-block-border-color);padding:1em;border-radius:6px;overflow-x:auto;margin:1em 0}:host ::ng-deep .ProseMirror pre code{background:none;color:inherit;border:none;padding:0}:host ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:var(--ate-placeholder-color);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:var(--ate-image-border-radius)}:host ::ng-deep .ProseMirror img:hover{border-color:var(--ate-border-color);box-shadow:0 2px 4px #0000001a}:host ::ng-deep .ProseMirror img.ProseMirror-selectednode{border-color:var(--ate-image-selected-color);box-shadow:0 0 0 3px var(--ate-primary-light-alpha);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 var(--ate-primary);outline-offset:2px;border-radius:16px;box-shadow:0 0 0 4px var(--ate-primary-light-alpha)}: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:var(--ate-primary);border:2px solid var(--ate-surface);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:var(--ate-primary);box-shadow:0 3px 8px #0000004d}:host ::ng-deep .resize-handle:active{background:var(--ate-primary)}: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}:host ::ng-deep .ProseMirror table{border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed;width:100%;border-radius:8px;overflow:hidden}:host ::ng-deep .ProseMirror table td,:host ::ng-deep .ProseMirror table th{border:none;border-right:1px solid var(--ate-table-border-color);border-bottom:1px solid var(--ate-table-border-color);box-sizing:border-box;min-width:1em;padding:8px 12px;position:relative;vertical-align:top;text-align:left}:host ::ng-deep .ProseMirror table td{background:var(--ate-table-cell-background)}:host ::ng-deep .ProseMirror table td:first-child,:host ::ng-deep .ProseMirror table th:first-child{border-left:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child td,:host ::ng-deep .ProseMirror table tr:first-child th{border-top:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child th:first-child{border-top-left-radius:8px}:host ::ng-deep .ProseMirror table tr:first-child th:last-child{border-top-right-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:first-child{border-bottom-left-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:last-child{border-bottom-right-radius:8px}:host ::ng-deep .ProseMirror table th{background:var(--ate-table-header-background);font-weight:600;color:var(--ate-table-header-color)}:host ::ng-deep .ProseMirror table .selectedCell:after{background:var(--ate-table-cell-selected-background);content:\"\";inset:0;pointer-events:none;position:absolute;z-index:2}:host ::ng-deep .ProseMirror table .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;background-color:var(--ate-table-resize-handle-color);opacity:0;transition:opacity .2s ease}:host ::ng-deep .ProseMirror table:hover .column-resize-handle{opacity:1}:host ::ng-deep .ProseMirror table .column-resize-handle:hover{background-color:var(--ate-focus-color)}:host ::ng-deep .ProseMirror .tableWrapper{overflow-x:auto;margin:1em 0;border-radius:8px}:host ::ng-deep .ProseMirror .tableWrapper table{margin:0;border-radius:8px;min-width:600px;overflow:hidden}:host ::ng-deep .ProseMirror table p{margin:0}:host ::ng-deep .ProseMirror table tbody tr:hover td{background-color:var(--ate-table-row-hover-background)}\n"] }]
5211
5614
  }], ctorParameters: () => [] });
5212
5615
 
5213
5616
  /*