@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.
- package/CHANGELOG.md +11 -1
- package/README.md +1 -0
- package/fesm2022/flogeez-angular-tiptap-editor.mjs +284 -89
- package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
- package/index.d.ts +9 -3
- package/package.json +1 -1
|
@@ -523,11 +523,12 @@ const TableExtension = Extension.create({
|
|
|
523
523
|
class TiptapButtonComponent {
|
|
524
524
|
constructor() {
|
|
525
525
|
// Inputs
|
|
526
|
-
this.icon = input
|
|
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.
|
|
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
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
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
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
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
|
-
|
|
1238
|
-
|
|
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
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
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
|
-
|
|
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:
|
|
1284
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type:
|
|
1285
|
-
<div class="
|
|
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="
|
|
1288
|
-
[title]="t().textColor"
|
|
1289
|
-
[color]="
|
|
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: [".
|
|
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:
|
|
1472
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapColorPickerComponent, decorators: [{
|
|
1318
1473
|
type: Component,
|
|
1319
|
-
args: [{ selector: "tiptap-
|
|
1320
|
-
<div class="
|
|
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="
|
|
1323
|
-
[title]="t().textColor"
|
|
1324
|
-
[color]="
|
|
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: [".
|
|
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
|
|
1405
|
-
this.textColorPicker
|
|
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
|
|
1437
|
-
this.textColorPicker
|
|
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-
|
|
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:
|
|
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: [
|
|
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-
|
|
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-
|
|
3630
|
-
}
|
|
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:
|
|
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
|
-
|
|
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-
|
|
3840
|
-
}
|
|
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:
|
|
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:
|
|
4722
|
+
highlight: false,
|
|
4723
|
+
highlightPicker: true,
|
|
4529
4724
|
textColor: true,
|
|
4530
4725
|
link: true,
|
|
4531
4726
|
separator: true,
|