@flogeez/angular-tiptap-editor 0.5.2 → 0.5.3

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.
@@ -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",
@@ -794,6 +907,7 @@ const ENGLISH_TRANSLATIONS = {
794
907
  superscript: "Superscript",
795
908
  subscript: "Subscript",
796
909
  highlight: "Highlight",
910
+ highlightPicker: "Background Color",
797
911
  textColor: "Text Color",
798
912
  link: "Link",
799
913
  addLink: "Add Link",
@@ -924,6 +1038,7 @@ const FRENCH_TRANSLATIONS = {
924
1038
  superscript: "Exposant",
925
1039
  subscript: "Indice",
926
1040
  highlight: "Surligner",
1041
+ highlightPicker: "Couleur de fond",
927
1042
  heading1: "Titre 1",
928
1043
  heading2: "Titre 2",
929
1044
  heading3: "Titre 3",
@@ -952,6 +1067,7 @@ const FRENCH_TRANSLATIONS = {
952
1067
  superscript: "Exposant",
953
1068
  subscript: "Indice",
954
1069
  highlight: "Surligner",
1070
+ highlightPicker: "Couleur de fond",
955
1071
  textColor: "Couleur texte",
956
1072
  link: "Lien",
957
1073
  addLink: "Ajouter un lien",
@@ -1150,9 +1266,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
1150
1266
  }]
1151
1267
  }], ctorParameters: () => [] });
1152
1268
 
1153
- class TiptapTextColorPickerComponent {
1269
+ class TiptapColorPickerComponent {
1154
1270
  constructor() {
1155
1271
  this.editor = input.required();
1272
+ this.mode = input("text");
1156
1273
  this.interactionChange = output();
1157
1274
  this.requestUpdate = output();
1158
1275
  this.colorInputRef = viewChild("colorInput");
@@ -1166,13 +1283,56 @@ class TiptapTextColorPickerComponent {
1166
1283
  this.editorChange();
1167
1284
  if (this.previewColor())
1168
1285
  return this.previewColor();
1169
- return this.colorPickerSvc.getCurrentColor(this.editor());
1286
+ const editor = this.editor();
1287
+ return this.mode() === "text"
1288
+ ? this.colorPickerSvc.getCurrentColor(editor)
1289
+ : this.colorPickerSvc.getCurrentHighlight(editor);
1170
1290
  });
1171
1291
  this.hasColorApplied = computed(() => {
1172
1292
  this.editorChange();
1173
- return this.previewColor()
1174
- ? true
1175
- : this.colorPickerSvc.hasColorApplied(this.editor());
1293
+ if (this.previewColor())
1294
+ return true;
1295
+ const editor = this.editor();
1296
+ return this.mode() === "text"
1297
+ ? this.colorPickerSvc.hasColorApplied(editor)
1298
+ : this.colorPickerSvc.hasHighlightApplied(editor);
1299
+ });
1300
+ /**
1301
+ * Determine the icon to display.
1302
+ */
1303
+ this.buttonIcon = computed(() => {
1304
+ if (this.mode() === "text")
1305
+ return "format_color_text";
1306
+ return "format_color_fill";
1307
+ });
1308
+ /**
1309
+ * Determine the background color of the button.
1310
+ */
1311
+ this.buttonBgColor = computed(() => {
1312
+ const color = this.currentColor();
1313
+ if (this.mode() === "highlight") {
1314
+ return this.hasColorApplied() ? color : "";
1315
+ }
1316
+ // Mode TEXT: Provide contrast background if the text color is too light
1317
+ // (especially useful when the text color is white on a light toolbar)
1318
+ if (this.hasColorApplied() && this.colorPickerSvc.getLuminance(color) > 200) {
1319
+ return "#333333";
1320
+ }
1321
+ return "";
1322
+ });
1323
+ /**
1324
+ * Determine the text/icon color of the button.
1325
+ */
1326
+ this.buttonTextColor = computed(() => {
1327
+ const color = this.currentColor();
1328
+ if (this.mode() === "text") {
1329
+ return this.hasColorApplied() ? color : "var(--ate-text-secondary)";
1330
+ }
1331
+ // For highlight, if background is set, use black/white contrast for icon
1332
+ if (this.hasColorApplied()) {
1333
+ return this.colorPickerSvc.getLuminance(color) > 128 ? "#000000" : "#ffffff";
1334
+ }
1335
+ return "var(--ate-text-secondary)";
1176
1336
  });
1177
1337
  this._syncEffect = void effect(() => {
1178
1338
  const el = this.colorInputRef()?.nativeElement;
@@ -1207,86 +1367,81 @@ class TiptapTextColorPickerComponent {
1207
1367
  syncColorInputValue() {
1208
1368
  this.previewColor.set(null);
1209
1369
  this.isPicking.set(false);
1210
- // Reason: force recomputation from editor selection when bubble menu re-opens.
1211
1370
  this.notifyEditorChange();
1212
1371
  }
1213
- /**
1214
- * Programmatically click the hidden color input.
1215
- */
1216
1372
  triggerPicker() {
1217
1373
  this.colorInputRef()?.nativeElement.click();
1218
1374
  }
1219
- /**
1220
- * Preserve selection while interacting with native color input.
1221
- */
1222
1375
  onColorMouseDown(event) {
1223
1376
  event.stopPropagation();
1224
1377
  this.colorPickerSvc.captureSelection(this.editor());
1225
1378
  this.isPicking.set(true);
1226
1379
  this.interactionChange.emit(true);
1227
1380
  }
1228
- /**
1229
- * Called when the native color picker is closed.
1230
- */
1231
1381
  onColorPickerClose() {
1232
1382
  this.previewColor.set(null);
1233
1383
  this.isPicking.set(false);
1234
- // Commit the final color to history
1235
1384
  const inputEl = this.colorInputRef()?.nativeElement;
1236
1385
  if (inputEl) {
1237
- this.colorPickerSvc.applyColor(this.editor(), inputEl.value, {
1238
- addToHistory: true,
1239
- });
1386
+ if (this.mode() === "text") {
1387
+ this.colorPickerSvc.applyColor(this.editor(), inputEl.value, {
1388
+ addToHistory: true,
1389
+ });
1390
+ }
1391
+ else {
1392
+ this.colorPickerSvc.applyHighlight(this.editor(), inputEl.value, {
1393
+ addToHistory: true,
1394
+ });
1395
+ }
1240
1396
  }
1241
1397
  this.colorPickerSvc.done();
1242
1398
  this.interactionChange.emit(false);
1243
1399
  this.requestUpdate.emit();
1244
1400
  }
1245
- /**
1246
- * Apply selected color.
1247
- */
1248
1401
  onColorInput(event) {
1249
1402
  const inputEl = event.target;
1250
1403
  const color = inputEl.value;
1251
- // Update the UI immediately while the user drags in the native picker.
1252
1404
  this.previewColor.set(this.colorPickerSvc.normalizeColor(color));
1253
- // Live preview WITHOUT history pollution
1254
- this.colorPickerSvc.applyColor(this.editor(), color, {
1255
- addToHistory: false,
1256
- });
1405
+ if (this.mode() === "text") {
1406
+ this.colorPickerSvc.applyColor(this.editor(), color, {
1407
+ addToHistory: false,
1408
+ });
1409
+ }
1410
+ else {
1411
+ this.colorPickerSvc.applyHighlight(this.editor(), color, {
1412
+ addToHistory: false,
1413
+ });
1414
+ }
1257
1415
  this.requestUpdate.emit();
1258
1416
  }
1259
- /**
1260
- * Prevent opening the native picker when clicking the clear badge.
1261
- */
1262
1417
  onClearBadgeMouseDown(event) {
1263
1418
  event.preventDefault();
1264
1419
  event.stopPropagation();
1265
1420
  }
1266
- /**
1267
- * Clear color via the badge.
1268
- */
1269
1421
  onClearBadgeClick(event) {
1270
1422
  event.preventDefault();
1271
1423
  event.stopPropagation();
1272
1424
  this.previewColor.set(null);
1273
1425
  this.isPicking.set(false);
1274
- this.colorPickerSvc.unsetColor(this.editor());
1426
+ if (this.mode() === "text") {
1427
+ this.colorPickerSvc.unsetColor(this.editor());
1428
+ }
1429
+ else {
1430
+ this.colorPickerSvc.unsetHighlight(this.editor());
1431
+ }
1275
1432
  this.requestUpdate.emit();
1276
1433
  }
1277
- /**
1278
- * Called when the color picker is done interacting.
1279
- */
1280
1434
  done() {
1281
1435
  this.colorPickerSvc.done();
1282
1436
  }
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">
1437
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapColorPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1438
+ 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" }, viewQueries: [{ propertyName: "colorInputRef", first: true, predicate: ["colorInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
1439
+ <div class="color-picker-container" [class.is-highlight]="mode() === 'highlight'">
1286
1440
  <tiptap-button
1287
- icon="format_color_text"
1288
- [title]="t().textColor"
1289
- [color]="hasColorApplied() ? currentColor() : 'var(--ate-text)'"
1441
+ [icon]="buttonIcon()"
1442
+ [title]="mode() === 'text' ? t().textColor : t().highlight"
1443
+ [color]="buttonTextColor()"
1444
+ [backgroundColor]="buttonBgColor()"
1290
1445
  (onClick)="triggerPicker()"
1291
1446
  >
1292
1447
  <input
@@ -1312,16 +1467,17 @@ class TiptapTextColorPickerComponent {
1312
1467
  </button>
1313
1468
  }
1314
1469
  </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"] }] }); }
1470
+ `, isInline: true, styles: [".color-picker-container{position:relative;display:inline-flex;align-items:center}.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}.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", "backgroundColor", "variant", "size", "iconSize"], outputs: ["onClick"] }] }); }
1316
1471
  }
1317
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapTextColorPickerComponent, decorators: [{
1472
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapColorPickerComponent, decorators: [{
1318
1473
  type: Component,
1319
- args: [{ selector: "tiptap-text-color-picker", standalone: true, imports: [TiptapButtonComponent], template: `
1320
- <div class="text-color-picker-container">
1474
+ args: [{ selector: "tiptap-color-picker", standalone: true, imports: [TiptapButtonComponent], template: `
1475
+ <div class="color-picker-container" [class.is-highlight]="mode() === 'highlight'">
1321
1476
  <tiptap-button
1322
- icon="format_color_text"
1323
- [title]="t().textColor"
1324
- [color]="hasColorApplied() ? currentColor() : 'var(--ate-text)'"
1477
+ [icon]="buttonIcon()"
1478
+ [title]="mode() === 'text' ? t().textColor : t().highlight"
1479
+ [color]="buttonTextColor()"
1480
+ [backgroundColor]="buttonBgColor()"
1325
1481
  (onClick)="triggerPicker()"
1326
1482
  >
1327
1483
  <input
@@ -1347,7 +1503,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
1347
1503
  </button>
1348
1504
  }
1349
1505
  </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"] }]
1506
+ `, styles: [".color-picker-container{position:relative;display:inline-flex;align-items:center}.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}.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
1507
  }], ctorParameters: () => [] });
1352
1508
 
1353
1509
  class TiptapBubbleMenuComponent {
@@ -1401,8 +1557,11 @@ class TiptapBubbleMenuComponent {
1401
1557
  const ed = this.editor();
1402
1558
  if (!ed)
1403
1559
  return;
1404
- if (!this.isColorPickerInteracting && this.textColorPicker) {
1405
- this.textColorPicker.done();
1560
+ if (!this.isColorPickerInteracting) {
1561
+ if (this.textColorPicker)
1562
+ this.textColorPicker.done();
1563
+ if (this.highlightPicker)
1564
+ this.highlightPicker.done();
1406
1565
  }
1407
1566
  const { selection } = ed.state;
1408
1567
  const { from, to } = selection;
@@ -1433,8 +1592,11 @@ class TiptapBubbleMenuComponent {
1433
1592
  this.handleBlur = () => {
1434
1593
  // Masquer le menu quand l'éditeur perd le focus
1435
1594
  setTimeout(() => {
1436
- if (!this.isColorPickerInteracting && this.textColorPicker) {
1437
- this.textColorPicker.done();
1595
+ if (!this.isColorPickerInteracting) {
1596
+ if (this.textColorPicker)
1597
+ this.textColorPicker.done();
1598
+ if (this.highlightPicker)
1599
+ this.highlightPicker.done();
1438
1600
  this.hideTippy();
1439
1601
  }
1440
1602
  }, 100);
@@ -1569,6 +1731,7 @@ class TiptapBubbleMenuComponent {
1569
1731
  });
1570
1732
  this.tippyInstance.show();
1571
1733
  this.textColorPicker?.syncColorInputValue();
1734
+ this.highlightPicker?.syncColorInputValue();
1572
1735
  }
1573
1736
  hideTippy() {
1574
1737
  if (this.tippyInstance) {
@@ -1618,7 +1781,7 @@ class TiptapBubbleMenuComponent {
1618
1781
  }
1619
1782
  }
1620
1783
  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: `
1784
+ 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
1785
  <div #menuRef class="bubble-menu">
1623
1786
  @if (bubbleMenuConfig().bold) {
1624
1787
  <tiptap-button
@@ -1669,9 +1832,18 @@ class TiptapBubbleMenuComponent {
1669
1832
  [active]="isActive('highlight')"
1670
1833
  (click)="onCommand('highlight', $event)"
1671
1834
  ></tiptap-button>
1835
+ } @if (bubbleMenuConfig().highlightPicker) {
1836
+ <tiptap-color-picker
1837
+ #highlightPicker
1838
+ mode="highlight"
1839
+ [editor]="editor()"
1840
+ (interactionChange)="onColorPickerInteractionChange($event)"
1841
+ (requestUpdate)="updateMenu()"
1842
+ />
1672
1843
  } @if (bubbleMenuConfig().textColor) {
1673
- <tiptap-text-color-picker
1844
+ <tiptap-color-picker
1674
1845
  #textColorPicker
1846
+ mode="text"
1675
1847
  [editor]="editor()"
1676
1848
  (interactionChange)="onColorPickerInteractionChange($event)"
1677
1849
  (requestUpdate)="updateMenu()"
@@ -1695,14 +1867,17 @@ class TiptapBubbleMenuComponent {
1695
1867
  ></tiptap-button>
1696
1868
  }
1697
1869
  </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"] }] }); }
1870
+ `, 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
1871
  }
1700
1872
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapBubbleMenuComponent, decorators: [{
1701
1873
  type: Component,
1702
1874
  args: [{
1703
1875
  selector: "tiptap-bubble-menu",
1704
1876
  standalone: true,
1705
- imports: [TiptapButtonComponent, TiptapTextColorPickerComponent],
1877
+ imports: [
1878
+ TiptapButtonComponent,
1879
+ TiptapColorPickerComponent,
1880
+ ],
1706
1881
  template: `
1707
1882
  <div #menuRef class="bubble-menu">
1708
1883
  @if (bubbleMenuConfig().bold) {
@@ -1754,9 +1929,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
1754
1929
  [active]="isActive('highlight')"
1755
1930
  (click)="onCommand('highlight', $event)"
1756
1931
  ></tiptap-button>
1932
+ } @if (bubbleMenuConfig().highlightPicker) {
1933
+ <tiptap-color-picker
1934
+ #highlightPicker
1935
+ mode="highlight"
1936
+ [editor]="editor()"
1937
+ (interactionChange)="onColorPickerInteractionChange($event)"
1938
+ (requestUpdate)="updateMenu()"
1939
+ />
1757
1940
  } @if (bubbleMenuConfig().textColor) {
1758
- <tiptap-text-color-picker
1941
+ <tiptap-color-picker
1759
1942
  #textColorPicker
1943
+ mode="text"
1760
1944
  [editor]="editor()"
1761
1945
  (interactionChange)="onColorPickerInteractionChange($event)"
1762
1946
  (requestUpdate)="updateMenu()"
@@ -1788,6 +1972,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
1788
1972
  }], textColorPicker: [{
1789
1973
  type: ViewChild,
1790
1974
  args: ["textColorPicker", { static: false }]
1975
+ }], highlightPicker: [{
1976
+ type: ViewChild,
1977
+ args: ["highlightPicker", { static: false }]
1791
1978
  }] } });
1792
1979
 
1793
1980
  class TiptapSeparatorComponent {
@@ -2562,7 +2749,7 @@ class TiptapImageBubbleMenuComponent {
2562
2749
  ></tiptap-button>
2563
2750
  }
2564
2751
  </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"] }] }); }
2752
+ `, 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
2753
  }
2567
2754
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapImageBubbleMenuComponent, decorators: [{
2568
2755
  type: Component,
@@ -3122,7 +3309,7 @@ class TiptapTableBubbleMenuComponent {
3122
3309
  ></tiptap-button>
3123
3310
  }
3124
3311
  </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"] }] }); }
3312
+ `, 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
3313
  }
3127
3314
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapTableBubbleMenuComponent, decorators: [{
3128
3315
  type: Component,
@@ -3428,7 +3615,7 @@ class TiptapCellBubbleMenuComponent {
3428
3615
  ></tiptap-button>
3429
3616
  }
3430
3617
  </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"] }] }); }
3618
+ `, 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
3619
  }
3433
3620
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapCellBubbleMenuComponent, decorators: [{
3434
3621
  type: Component,
@@ -3625,9 +3812,12 @@ class TiptapToolbarComponent {
3625
3812
  [disabled]="!canExecute('toggleHighlight')"
3626
3813
  (onClick)="toggleHighlight()"
3627
3814
  />
3815
+ } @if (config().highlightPicker) {
3816
+ <tiptap-color-picker mode="highlight" [editor]="editor()" />
3628
3817
  } @if (config().textColor) {
3629
- <tiptap-text-color-picker [editor]="editor()" />
3630
- } @if (config().separator && (config().heading1 || config().heading2 ||
3818
+ <tiptap-color-picker mode="text" [editor]="editor()" />
3819
+ }
3820
+ @if (config().separator && (config().heading1 || config().heading2 ||
3631
3821
  config().heading3)) {
3632
3822
  <tiptap-separator />
3633
3823
  } @if (config().heading1) {
@@ -3761,14 +3951,14 @@ class TiptapToolbarComponent {
3761
3951
  />
3762
3952
  }
3763
3953
  </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"] }] }); }
3954
+ `, 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", "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
3955
  }
3766
3956
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapToolbarComponent, decorators: [{
3767
3957
  type: Component,
3768
3958
  args: [{ selector: "tiptap-toolbar", standalone: true, imports: [
3769
3959
  TiptapButtonComponent,
3770
3960
  TiptapSeparatorComponent,
3771
- TiptapTextColorPickerComponent,
3961
+ TiptapColorPickerComponent,
3772
3962
  ], template: `
3773
3963
  <div class="tiptap-toolbar">
3774
3964
  @if (config().bold) {
@@ -3835,9 +4025,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
3835
4025
  [disabled]="!canExecute('toggleHighlight')"
3836
4026
  (onClick)="toggleHighlight()"
3837
4027
  />
4028
+ } @if (config().highlightPicker) {
4029
+ <tiptap-color-picker mode="highlight" [editor]="editor()" />
3838
4030
  } @if (config().textColor) {
3839
- <tiptap-text-color-picker [editor]="editor()" />
3840
- } @if (config().separator && (config().heading1 || config().heading2 ||
4031
+ <tiptap-color-picker mode="text" [editor]="editor()" />
4032
+ }
4033
+ @if (config().separator && (config().heading1 || config().heading2 ||
3841
4034
  config().heading3)) {
3842
4035
  <tiptap-separator />
3843
4036
  } @if (config().heading1) {
@@ -4495,7 +4688,8 @@ const DEFAULT_TOOLBAR_CONFIG = {
4495
4688
  code: true,
4496
4689
  superscript: false,
4497
4690
  subscript: false,
4498
- highlight: true,
4691
+ highlight: false,
4692
+ highlightPicker: true,
4499
4693
  heading1: true,
4500
4694
  heading2: true,
4501
4695
  heading3: true,
@@ -4525,7 +4719,8 @@ const DEFAULT_BUBBLE_MENU_CONFIG = {
4525
4719
  code: true,
4526
4720
  superscript: false,
4527
4721
  subscript: false,
4528
- highlight: true,
4722
+ highlight: false,
4723
+ highlightPicker: true,
4529
4724
  textColor: true,
4530
4725
  link: true,
4531
4726
  separator: true,