@flogeez/angular-tiptap-editor 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -329,104 +329,104 @@ const UploadProgress = Extension.create({
329
329
  // Créer un élément de progression
330
330
  const uploadElement = document.createElement("div");
331
331
  uploadElement.className = "upload-progress-widget";
332
- uploadElement.innerHTML = `
333
- <div class="upload-skeleton">
334
- <div class="upload-content">
335
- <div class="upload-icon">
336
- <span class="material-symbols-outlined spinning">image</span>
337
- </div>
338
- <div class="upload-info">
339
- <div class="upload-message">${uploadMessage}</div>
340
- <div class="progress-bar">
341
- <div class="progress-fill" style="width: ${uploadProgress}%"></div>
342
- </div>
343
- <div class="progress-text">${uploadProgress}%</div>
344
- </div>
345
- </div>
346
- </div>
332
+ uploadElement.innerHTML = `
333
+ <div class="upload-skeleton">
334
+ <div class="upload-content">
335
+ <div class="upload-icon">
336
+ <span class="material-symbols-outlined spinning">image</span>
337
+ </div>
338
+ <div class="upload-info">
339
+ <div class="upload-message">${uploadMessage}</div>
340
+ <div class="progress-bar">
341
+ <div class="progress-fill" style="width: ${uploadProgress}%"></div>
342
+ </div>
343
+ <div class="progress-text">${uploadProgress}%</div>
344
+ </div>
345
+ </div>
346
+ </div>
347
347
  `;
348
348
  // Ajouter les styles si pas déjà fait
349
349
  if (!document.querySelector("#upload-progress-styles")) {
350
350
  const style = document.createElement("style");
351
351
  style.id = "upload-progress-styles";
352
- style.textContent = `
353
- .upload-progress-widget {
354
- display: block;
355
- margin: 8px 0;
356
- max-width: 400px;
357
- }
358
- .upload-skeleton {
359
- background: var(--ate-surface-secondary);
360
- border: 2px dashed var(--ate-border-color);
361
- border-radius: var(--ate-border-radius);
362
- padding: 16px;
363
- display: flex;
364
- align-items: center;
365
- justify-content: center;
366
- min-height: 120px;
367
- animation: pulse 2s infinite;
368
- }
369
- @keyframes pulse {
370
- 0%, 100% { background-color: var(--ate-surface-secondary); }
371
- 50% { background-color: var(--ate-surface-tertiary); }
372
- }
373
- .upload-content {
374
- display: flex;
375
- flex-direction: column;
376
- align-items: center;
377
- gap: 12px;
378
- text-align: center;
379
- }
380
- .upload-icon {
381
- display: flex;
382
- align-items: center;
383
- justify-content: center;
384
- width: 48px;
385
- height: 48px;
386
- background: var(--ate-primary-light);
387
- border-radius: 50%;
388
- color: var(--ate-primary);
389
- }
390
- .upload-icon .material-symbols-outlined {
391
- font-size: 24px;
392
- }
393
- .spinning {
394
- animation: spin 1s linear infinite;
395
- }
396
- @keyframes spin {
397
- from { transform: rotate(0deg); }
398
- to { transform: rotate(360deg); }
399
- }
400
- .upload-info {
401
- display: flex;
402
- flex-direction: column;
403
- gap: 8px;
404
- width: 100%;
405
- max-width: 200px;
406
- }
407
- .upload-message {
408
- font-size: 14px;
409
- color: var(--ate-text);
410
- font-weight: 500;
411
- }
412
- .progress-bar {
413
- width: 100%;
414
- height: 6px;
415
- background: var(--ate-border-color);
416
- border-radius: 3px;
417
- overflow: hidden;
418
- }
419
- .progress-fill {
420
- height: 100%;
421
- background: var(--ate-primary);
422
- border-radius: 3px;
423
- transition: width 0.3s ease;
424
- }
425
- .progress-text {
426
- font-size: 12px;
427
- color: var(--ate-text-secondary);
428
- font-weight: 500;
429
- }
352
+ style.textContent = `
353
+ .upload-progress-widget {
354
+ display: block;
355
+ margin: 8px 0;
356
+ max-width: 400px;
357
+ }
358
+ .upload-skeleton {
359
+ background: var(--ate-surface-secondary);
360
+ border: 2px dashed var(--ate-border-color);
361
+ border-radius: var(--ate-border-radius);
362
+ padding: 16px;
363
+ display: flex;
364
+ align-items: center;
365
+ justify-content: center;
366
+ min-height: 120px;
367
+ animation: pulse 2s infinite;
368
+ }
369
+ @keyframes pulse {
370
+ 0%, 100% { background-color: var(--ate-surface-secondary); }
371
+ 50% { background-color: var(--ate-surface-tertiary); }
372
+ }
373
+ .upload-content {
374
+ display: flex;
375
+ flex-direction: column;
376
+ align-items: center;
377
+ gap: 12px;
378
+ text-align: center;
379
+ }
380
+ .upload-icon {
381
+ display: flex;
382
+ align-items: center;
383
+ justify-content: center;
384
+ width: 48px;
385
+ height: 48px;
386
+ background: var(--ate-primary-light);
387
+ border-radius: 50%;
388
+ color: var(--ate-primary);
389
+ }
390
+ .upload-icon .material-symbols-outlined {
391
+ font-size: 24px;
392
+ }
393
+ .spinning {
394
+ animation: spin 1s linear infinite;
395
+ }
396
+ @keyframes spin {
397
+ from { transform: rotate(0deg); }
398
+ to { transform: rotate(360deg); }
399
+ }
400
+ .upload-info {
401
+ display: flex;
402
+ flex-direction: column;
403
+ gap: 8px;
404
+ width: 100%;
405
+ max-width: 200px;
406
+ }
407
+ .upload-message {
408
+ font-size: 14px;
409
+ color: var(--ate-text);
410
+ font-weight: 500;
411
+ }
412
+ .progress-bar {
413
+ width: 100%;
414
+ height: 6px;
415
+ background: var(--ate-border-color);
416
+ border-radius: 3px;
417
+ overflow: hidden;
418
+ }
419
+ .progress-fill {
420
+ height: 100%;
421
+ background: var(--ate-primary);
422
+ border-radius: 3px;
423
+ transition: width 0.3s ease;
424
+ }
425
+ .progress-text {
426
+ font-size: 12px;
427
+ color: var(--ate-text-secondary);
428
+ font-weight: 500;
429
+ }
430
430
  `;
431
431
  document.head.appendChild(style);
432
432
  }
@@ -450,21 +450,21 @@ const UploadProgress = Extension.create({
450
450
  // Mettre à jour le contenu de l'élément existant
451
451
  const existingElement = document.querySelector(".upload-progress-widget");
452
452
  if (existingElement) {
453
- existingElement.innerHTML = `
454
- <div class="upload-skeleton">
455
- <div class="upload-content">
456
- <div class="upload-icon">
457
- <span class="material-symbols-outlined spinning">image</span>
458
- </div>
459
- <div class="upload-info">
460
- <div class="upload-message">${uploadMessage}</div>
461
- <div class="progress-bar">
462
- <div class="progress-fill" style="width: ${uploadProgress}%"></div>
463
- </div>
464
- <div class="progress-text">${uploadProgress}%</div>
465
- </div>
466
- </div>
467
- </div>
453
+ existingElement.innerHTML = `
454
+ <div class="upload-skeleton">
455
+ <div class="upload-content">
456
+ <div class="upload-icon">
457
+ <span class="material-symbols-outlined spinning">image</span>
458
+ </div>
459
+ <div class="upload-info">
460
+ <div class="upload-message">${uploadMessage}</div>
461
+ <div class="progress-bar">
462
+ <div class="progress-fill" style="width: ${uploadProgress}%"></div>
463
+ </div>
464
+ <div class="progress-text">${uploadProgress}%</div>
465
+ </div>
466
+ </div>
467
+ </div>
468
468
  `;
469
469
  }
470
470
  return state; // Garder les décorations existantes
@@ -703,72 +703,72 @@ class TiptapButtonComponent {
703
703
  event.preventDefault();
704
704
  }
705
705
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
706
- 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: `
707
- <button
708
- class="tiptap-button"
709
- [class.is-active]="active()"
710
- [class.is-disabled]="disabled()"
711
- [class.text-button]="variant() === 'text'"
712
- [class.danger]="variant() === 'danger'"
713
- [class.small]="size() === 'small'"
714
- [class.medium]="size() === 'medium'"
715
- [class.large]="size() === 'large'"
716
- [class.has-custom-color]="!!color()"
717
- [class.has-custom-bg]="!!backgroundColor()"
718
- [disabled]="disabled()"
719
- [style.color]="color()"
720
- [style.background-color]="backgroundColor()"
721
- [attr.title]="title()"
722
- [attr.aria-label]="title()"
723
- (mousedown)="onMouseDown($event)"
724
- (click)="onClick.emit($event)"
725
- type="button"
726
- >
727
- @if (icon()) {
728
- <span
729
- class="material-symbols-outlined"
730
- [class.icon-small]="iconSize() === 'small'"
731
- [class.icon-medium]="iconSize() === 'medium'"
732
- [class.icon-large]="iconSize() === 'large'"
733
- >{{ icon() }}</span>
734
- }
735
- <ng-content></ng-content>
736
- </button>
706
+ 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: `
707
+ <button
708
+ class="tiptap-button"
709
+ [class.is-active]="active()"
710
+ [class.is-disabled]="disabled()"
711
+ [class.text-button]="variant() === 'text'"
712
+ [class.danger]="variant() === 'danger'"
713
+ [class.small]="size() === 'small'"
714
+ [class.medium]="size() === 'medium'"
715
+ [class.large]="size() === 'large'"
716
+ [class.has-custom-color]="!!color()"
717
+ [class.has-custom-bg]="!!backgroundColor()"
718
+ [disabled]="disabled()"
719
+ [style.color]="color()"
720
+ [style.background-color]="backgroundColor()"
721
+ [attr.title]="title()"
722
+ [attr.aria-label]="title()"
723
+ (mousedown)="onMouseDown($event)"
724
+ (click)="onClick.emit($event)"
725
+ type="button"
726
+ >
727
+ @if (icon()) {
728
+ <span
729
+ class="material-symbols-outlined"
730
+ [class.icon-small]="iconSize() === 'small'"
731
+ [class.icon-medium]="iconSize() === 'medium'"
732
+ [class.icon-large]="iconSize() === 'large'"
733
+ >{{ icon() }}</span>
734
+ }
735
+ <ng-content></ng-content>
736
+ </button>
737
737
  `, 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-sub-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-sub-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{color:var(--ate-error-color, #ef4444);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"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
738
738
  }
739
739
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapButtonComponent, decorators: [{
740
740
  type: Component,
741
- args: [{ selector: "tiptap-button", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
742
- <button
743
- class="tiptap-button"
744
- [class.is-active]="active()"
745
- [class.is-disabled]="disabled()"
746
- [class.text-button]="variant() === 'text'"
747
- [class.danger]="variant() === 'danger'"
748
- [class.small]="size() === 'small'"
749
- [class.medium]="size() === 'medium'"
750
- [class.large]="size() === 'large'"
751
- [class.has-custom-color]="!!color()"
752
- [class.has-custom-bg]="!!backgroundColor()"
753
- [disabled]="disabled()"
754
- [style.color]="color()"
755
- [style.background-color]="backgroundColor()"
756
- [attr.title]="title()"
757
- [attr.aria-label]="title()"
758
- (mousedown)="onMouseDown($event)"
759
- (click)="onClick.emit($event)"
760
- type="button"
761
- >
762
- @if (icon()) {
763
- <span
764
- class="material-symbols-outlined"
765
- [class.icon-small]="iconSize() === 'small'"
766
- [class.icon-medium]="iconSize() === 'medium'"
767
- [class.icon-large]="iconSize() === 'large'"
768
- >{{ icon() }}</span>
769
- }
770
- <ng-content></ng-content>
771
- </button>
741
+ args: [{ selector: "tiptap-button", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
742
+ <button
743
+ class="tiptap-button"
744
+ [class.is-active]="active()"
745
+ [class.is-disabled]="disabled()"
746
+ [class.text-button]="variant() === 'text'"
747
+ [class.danger]="variant() === 'danger'"
748
+ [class.small]="size() === 'small'"
749
+ [class.medium]="size() === 'medium'"
750
+ [class.large]="size() === 'large'"
751
+ [class.has-custom-color]="!!color()"
752
+ [class.has-custom-bg]="!!backgroundColor()"
753
+ [disabled]="disabled()"
754
+ [style.color]="color()"
755
+ [style.background-color]="backgroundColor()"
756
+ [attr.title]="title()"
757
+ [attr.aria-label]="title()"
758
+ (mousedown)="onMouseDown($event)"
759
+ (click)="onClick.emit($event)"
760
+ type="button"
761
+ >
762
+ @if (icon()) {
763
+ <span
764
+ class="material-symbols-outlined"
765
+ [class.icon-small]="iconSize() === 'small'"
766
+ [class.icon-medium]="iconSize() === 'medium'"
767
+ [class.icon-large]="iconSize() === 'large'"
768
+ >{{ icon() }}</span>
769
+ }
770
+ <ng-content></ng-content>
771
+ </button>
772
772
  `, styles: [".tiptap-button{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;border-radius:var(--ate-sub-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-sub-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{color:var(--ate-error-color, #ef4444);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"] }]
773
773
  }] });
774
774
 
@@ -778,28 +778,28 @@ class TiptapSeparatorComponent {
778
778
  this.size = input("medium");
779
779
  }
780
780
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapSeparatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
781
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.0", type: TiptapSeparatorComponent, isStandalone: true, selector: "tiptap-separator", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
782
- <div
783
- class="tiptap-separator"
784
- [class.vertical]="orientation() === 'vertical'"
785
- [class.horizontal]="orientation() === 'horizontal'"
786
- [class.small]="size() === 'small'"
787
- [class.medium]="size() === 'medium'"
788
- [class.large]="size() === 'large'"
789
- ></div>
781
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.0", type: TiptapSeparatorComponent, isStandalone: true, selector: "tiptap-separator", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
782
+ <div
783
+ class="tiptap-separator"
784
+ [class.vertical]="orientation() === 'vertical'"
785
+ [class.horizontal]="orientation() === 'horizontal'"
786
+ [class.small]="size() === 'small'"
787
+ [class.medium]="size() === 'medium'"
788
+ [class.large]="size() === 'large'"
789
+ ></div>
790
790
  `, isInline: true, styles: [".tiptap-separator{background-color:var(--ate-border, #e2e8f0);margin:0}.tiptap-separator.vertical{width:1px;height:24px;margin:0 8px}.tiptap-separator.horizontal{height:1px;width:100%;margin:8px 0}.tiptap-separator.small.vertical{height:16px;margin:0 4px}.tiptap-separator.small.horizontal{margin:4px 0}.tiptap-separator.medium.vertical{height:24px;margin:0 8px}.tiptap-separator.medium.horizontal{margin:8px 0}.tiptap-separator.large.vertical{height:32px;margin:0 12px}.tiptap-separator.large.horizontal{margin:12px 0}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
791
791
  }
792
792
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapSeparatorComponent, decorators: [{
793
793
  type: Component,
794
- args: [{ selector: "tiptap-separator", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
795
- <div
796
- class="tiptap-separator"
797
- [class.vertical]="orientation() === 'vertical'"
798
- [class.horizontal]="orientation() === 'horizontal'"
799
- [class.small]="size() === 'small'"
800
- [class.medium]="size() === 'medium'"
801
- [class.large]="size() === 'large'"
802
- ></div>
794
+ args: [{ selector: "tiptap-separator", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
795
+ <div
796
+ class="tiptap-separator"
797
+ [class.vertical]="orientation() === 'vertical'"
798
+ [class.horizontal]="orientation() === 'horizontal'"
799
+ [class.small]="size() === 'small'"
800
+ [class.medium]="size() === 'medium'"
801
+ [class.large]="size() === 'large'"
802
+ ></div>
803
803
  `, styles: [".tiptap-separator{background-color:var(--ate-border, #e2e8f0);margin:0}.tiptap-separator.vertical{width:1px;height:24px;margin:0 8px}.tiptap-separator.horizontal{height:1px;width:100%;margin:8px 0}.tiptap-separator.small.vertical{height:16px;margin:0 4px}.tiptap-separator.small.horizontal{margin:4px 0}.tiptap-separator.medium.vertical{height:24px;margin:0 8px}.tiptap-separator.medium.horizontal{margin:8px 0}.tiptap-separator.large.vertical{height:32px;margin:0 12px}.tiptap-separator.large.horizontal{margin:12px 0}\n"] }]
804
804
  }] });
805
805
 
@@ -955,6 +955,8 @@ const ENGLISH_TRANSLATIONS = {
955
955
  linkPrompt: "Enter link URL",
956
956
  linkUrlPrompt: "Enter URL",
957
957
  confirmDelete: "Are you sure you want to delete this?",
958
+ toggleEdit: "Switch to Edit Mode",
959
+ viewMode: "Switch to View Mode",
958
960
  },
959
961
  common: {
960
962
  cancel: "Cancel",
@@ -1129,6 +1131,8 @@ const FRENCH_TRANSLATIONS = {
1129
1131
  linkPrompt: "Entrez l'URL du lien",
1130
1132
  linkUrlPrompt: "Entrez l'URL",
1131
1133
  confirmDelete: "Êtes-vous sûr de vouloir supprimer ceci ?",
1134
+ toggleEdit: "Passer en mode édition",
1135
+ viewMode: "Passer en mode affichage",
1132
1136
  },
1133
1137
  common: {
1134
1138
  cancel: "Annuler",
@@ -1349,14 +1353,16 @@ class ImageService {
1349
1353
  }
1350
1354
  }
1351
1355
  /** Validate file type and size */
1352
- validateImage(file, maxSize = 10 * 1024 * 1024) {
1353
- if (!file.type.startsWith("image/")) {
1356
+ validateImage(file, options) {
1357
+ const maxSize = options?.maxSize || 10 * 1024 * 1024;
1358
+ const allowedTypes = options?.allowedTypes || [];
1359
+ if (allowedTypes.length > 0 && !allowedTypes.includes(file.type)) {
1354
1360
  return { valid: false, error: this.t().invalidFileType };
1355
1361
  }
1356
1362
  if (file.size > maxSize) {
1357
1363
  return {
1358
1364
  valid: false,
1359
- error: `${this.t().imageTooLarge} (max ${maxSize / 1024 / 1024}MB)`,
1365
+ error: `${this.t().imageTooLarge} (max ${Math.round(maxSize / 1024 / 1024)}MB)`,
1360
1366
  };
1361
1367
  }
1362
1368
  return { valid: true };
@@ -1419,7 +1425,10 @@ class ImageService {
1419
1425
  this.uploadProgress.set(10);
1420
1426
  this.uploadMessage.set(this.t().validating);
1421
1427
  this.forceEditorUpdate();
1422
- const validation = this.validateImage(file);
1428
+ const validation = this.validateImage(file, {
1429
+ maxSize: options?.maxSize,
1430
+ allowedTypes: options?.allowedTypes
1431
+ });
1423
1432
  if (!validation.valid)
1424
1433
  throw new Error(validation.error);
1425
1434
  this.uploadProgress.set(30);
@@ -1495,7 +1504,13 @@ class ImageService {
1495
1504
  return new Promise((resolve, reject) => {
1496
1505
  const input = document.createElement("input");
1497
1506
  input.type = "file";
1498
- input.accept = options?.['accept'] || "image/*";
1507
+ // Use allowedTypes if provided, otherwise default to image/*
1508
+ if (options?.allowedTypes && options.allowedTypes.length > 0) {
1509
+ input.accept = options.allowedTypes.join(",");
1510
+ }
1511
+ else {
1512
+ input.accept = "image/*";
1513
+ }
1499
1514
  input.style.display = "none";
1500
1515
  input.addEventListener("change", async (e) => {
1501
1516
  const file = e.target.files?.[0];
@@ -2368,60 +2383,60 @@ class TiptapColorPickerComponent {
2368
2383
  this.colorPickerSvc.close();
2369
2384
  }
2370
2385
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapColorPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2371
- 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 }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, anchorToText: { classPropertyName: "anchorToText", publicName: "anchorToText", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2372
- <div class="color-picker-wrapper">
2373
- <div class="color-picker-container" [class.is-highlight]="mode() === 'highlight'">
2374
- <tiptap-button
2375
- [icon]="buttonIcon()"
2376
- [title]="mode() === 'text' ? t().textColor : t().highlight"
2377
- [color]="buttonTextColor()"
2378
- [backgroundColor]="buttonBgColor()"
2379
- [disabled]="disabled() || !state().isEditable"
2380
- (onClick)="onToggle($event)"
2381
- />
2382
-
2383
- @if (hasColorApplied()) {
2384
- <button
2385
- class="btn-clear-badge"
2386
- type="button"
2387
- [title]="t().clear"
2388
- [attr.aria-label]="t().clear"
2389
- (click)="onClear($event)"
2390
- >
2391
- <span class="material-symbols-outlined">close</span>
2392
- </button>
2393
- }
2394
- </div>
2395
- </div>
2386
+ 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 }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, anchorToText: { classPropertyName: "anchorToText", publicName: "anchorToText", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2387
+ <div class="color-picker-wrapper">
2388
+ <div class="color-picker-container" [class.is-highlight]="mode() === 'highlight'">
2389
+ <tiptap-button
2390
+ [icon]="buttonIcon()"
2391
+ [title]="mode() === 'text' ? t().textColor : t().highlight"
2392
+ [color]="buttonTextColor()"
2393
+ [backgroundColor]="buttonBgColor()"
2394
+ [disabled]="disabled() || !state().isEditable"
2395
+ (onClick)="onToggle($event)"
2396
+ />
2397
+
2398
+ @if (hasColorApplied()) {
2399
+ <button
2400
+ class="btn-clear-badge"
2401
+ type="button"
2402
+ [title]="t().clear"
2403
+ [attr.aria-label]="t().clear"
2404
+ (click)="onClear($event)"
2405
+ >
2406
+ <span class="material-symbols-outlined">close</span>
2407
+ </button>
2408
+ }
2409
+ </div>
2410
+ </div>
2396
2411
  `, isInline: true, styles: [".color-picker-wrapper{position:relative;display:inline-block}.color-picker-container{position:relative;display:inline-flex;align-items:center}.btn-clear-badge{position:absolute;top:-4px;right:-4px;width:14px;height:14px;padding:0;border:none;border-radius:999px;background:#0f172abf;color:#fff;display:flex;align-items:center;justify-content:center;z-index:10;opacity:0;pointer-events:none;transition:opacity .12s ease}.color-picker-container:hover .btn-clear-badge{opacity:1;pointer-events:auto}.btn-clear-badge .material-symbols-outlined{font-size:10px;line-height:1}\n"], dependencies: [{ kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "backgroundColor", "variant", "size", "iconSize"], outputs: ["onClick"] }, { kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2397
2412
  }
2398
2413
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapColorPickerComponent, decorators: [{
2399
2414
  type: Component,
2400
- args: [{ selector: "tiptap-color-picker", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TiptapButtonComponent, CommonModule], template: `
2401
- <div class="color-picker-wrapper">
2402
- <div class="color-picker-container" [class.is-highlight]="mode() === 'highlight'">
2403
- <tiptap-button
2404
- [icon]="buttonIcon()"
2405
- [title]="mode() === 'text' ? t().textColor : t().highlight"
2406
- [color]="buttonTextColor()"
2407
- [backgroundColor]="buttonBgColor()"
2408
- [disabled]="disabled() || !state().isEditable"
2409
- (onClick)="onToggle($event)"
2410
- />
2411
-
2412
- @if (hasColorApplied()) {
2413
- <button
2414
- class="btn-clear-badge"
2415
- type="button"
2416
- [title]="t().clear"
2417
- [attr.aria-label]="t().clear"
2418
- (click)="onClear($event)"
2419
- >
2420
- <span class="material-symbols-outlined">close</span>
2421
- </button>
2422
- }
2423
- </div>
2424
- </div>
2415
+ args: [{ selector: "tiptap-color-picker", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TiptapButtonComponent, CommonModule], template: `
2416
+ <div class="color-picker-wrapper">
2417
+ <div class="color-picker-container" [class.is-highlight]="mode() === 'highlight'">
2418
+ <tiptap-button
2419
+ [icon]="buttonIcon()"
2420
+ [title]="mode() === 'text' ? t().textColor : t().highlight"
2421
+ [color]="buttonTextColor()"
2422
+ [backgroundColor]="buttonBgColor()"
2423
+ [disabled]="disabled() || !state().isEditable"
2424
+ (onClick)="onToggle($event)"
2425
+ />
2426
+
2427
+ @if (hasColorApplied()) {
2428
+ <button
2429
+ class="btn-clear-badge"
2430
+ type="button"
2431
+ [title]="t().clear"
2432
+ [attr.aria-label]="t().clear"
2433
+ (click)="onClear($event)"
2434
+ >
2435
+ <span class="material-symbols-outlined">close</span>
2436
+ </button>
2437
+ }
2438
+ </div>
2439
+ </div>
2425
2440
  `, styles: [".color-picker-wrapper{position:relative;display:inline-block}.color-picker-container{position:relative;display:inline-flex;align-items:center}.btn-clear-badge{position:absolute;top:-4px;right:-4px;width:14px;height:14px;padding:0;border:none;border-radius:999px;background:#0f172abf;color:#fff;display:flex;align-items:center;justify-content:center;z-index:10;opacity:0;pointer-events:none;transition:opacity .12s ease}.color-picker-container:hover .btn-clear-badge{opacity:1;pointer-events:auto}.btn-clear-badge .material-symbols-outlined{font-size:10px;line-height:1}\n"] }]
2426
2441
  }] });
2427
2442
 
@@ -2443,241 +2458,241 @@ class TiptapToolbarComponent {
2443
2458
  this.editorCommands.execute(editor, command, ...args);
2444
2459
  }
2445
2460
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2446
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapToolbarComponent, isStandalone: true, selector: "tiptap-toolbar", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null }, floating: { classPropertyName: "floating", publicName: "floating", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2447
- <div class="tiptap-toolbar" [class.floating]="floating()">
2448
- @if (config().bold) {
2449
- <tiptap-button
2450
- icon="format_bold"
2451
- [title]="t().bold"
2452
- [active]="state().marks.bold"
2453
- [disabled]="!state().can.toggleBold"
2454
- (onClick)="onCommand('toggleBold')"
2455
- />
2456
- } @if (config().italic) {
2457
- <tiptap-button
2458
- icon="format_italic"
2459
- [title]="t().italic"
2460
- [active]="state().marks.italic"
2461
- [disabled]="!state().can.toggleItalic"
2462
- (onClick)="onCommand('toggleItalic')"
2463
- />
2464
- } @if (config().underline) {
2465
- <tiptap-button
2466
- icon="format_underlined"
2467
- [title]="t().underline"
2468
- [active]="state().marks.underline"
2469
- [disabled]="!state().can.toggleUnderline"
2470
- (onClick)="onCommand('toggleUnderline')"
2471
- />
2472
- } @if (config().strike) {
2473
- <tiptap-button
2474
- icon="strikethrough_s"
2475
- [title]="t().strike"
2476
- [active]="state().marks.strike"
2477
- [disabled]="!state().can.toggleStrike"
2478
- (onClick)="onCommand('toggleStrike')"
2479
- />
2480
- } @if (config().code) {
2481
- <tiptap-button
2482
- icon="code"
2483
- [title]="t().code"
2484
- [active]="state().marks.code"
2485
- [disabled]="!state().can.toggleCode"
2486
- (onClick)="onCommand('toggleCode')"
2487
- />
2488
- } @if (config().codeBlock) {
2489
- <tiptap-button
2490
- icon="terminal"
2491
- [title]="t().codeBlock"
2492
- [active]="state().nodes.isCodeBlock"
2493
- [disabled]="!state().can.toggleCodeBlock"
2494
- (onClick)="onCommand('toggleCodeBlock')"
2495
- />
2496
- } @if (config().superscript) {
2497
- <tiptap-button
2498
- icon="superscript"
2499
- [title]="t().superscript"
2500
- [active]="state().marks.superscript"
2501
- [disabled]="!state().can.toggleSuperscript"
2502
- (onClick)="onCommand('toggleSuperscript')"
2503
- />
2504
- } @if (config().subscript) {
2505
- <tiptap-button
2506
- icon="subscript"
2507
- [title]="t().subscript"
2508
- [active]="state().marks.subscript"
2509
- [disabled]="!state().can.toggleSubscript"
2510
- (onClick)="onCommand('toggleSubscript')"
2511
- />
2512
- } @if (config().highlight) {
2513
- <tiptap-button
2514
- icon="highlight"
2515
- [title]="t().highlight"
2516
- [active]="state().marks.highlight"
2517
- [disabled]="!state().can.toggleHighlight"
2518
- (onClick)="onCommand('toggleHighlight')"
2519
- />
2520
- } @if (config().highlightPicker) {
2521
- <tiptap-color-picker
2522
- mode="highlight"
2523
- [editor]="editor()"
2524
- [disabled]="!state().can.setHighlight"
2525
- />
2526
- } @if (config().textColor) {
2527
- <tiptap-color-picker
2528
- mode="text"
2529
- [editor]="editor()"
2530
- [disabled]="!state().can.setColor"
2531
- />
2532
- }
2533
-
2534
- @if (config().separator && (config().heading1 || config().heading2 || config().heading3)) {
2535
- <tiptap-separator />
2536
- } @if (config().heading1) {
2537
- <tiptap-button
2538
- icon="format_h1"
2539
- [title]="t().heading1"
2540
- [active]="state().nodes.h1"
2541
- [disabled]="!state().can.toggleHeading1"
2542
- (onClick)="onCommand('toggleHeading', 1)"
2543
- />
2544
- } @if (config().heading2) {
2545
- <tiptap-button
2546
- icon="format_h2"
2547
- [title]="t().heading2"
2548
- [active]="state().nodes.h2"
2549
- [disabled]="!state().can.toggleHeading2"
2550
- (onClick)="onCommand('toggleHeading', 2)"
2551
- />
2552
- } @if (config().heading3) {
2553
- <tiptap-button
2554
- icon="format_h3"
2555
- [title]="t().heading3"
2556
- [active]="state().nodes.h3"
2557
- [disabled]="!state().can.toggleHeading3"
2558
- (onClick)="onCommand('toggleHeading', 3)"
2559
- />
2560
- } @if (config().separator && (config().bulletList || config().orderedList || config().blockquote)) {
2561
- <tiptap-separator />
2562
- } @if (config().bulletList) {
2563
- <tiptap-button
2564
- icon="format_list_bulleted"
2565
- [title]="t().bulletList"
2566
- [active]="state().nodes.isBulletList"
2567
- [disabled]="!state().can.toggleBulletList"
2568
- (onClick)="onCommand('toggleBulletList')"
2569
- />
2570
- } @if (config().orderedList) {
2571
- <tiptap-button
2572
- icon="format_list_numbered"
2573
- [title]="t().orderedList"
2574
- [active]="state().nodes.isOrderedList"
2575
- [disabled]="!state().can.toggleOrderedList"
2576
- (onClick)="onCommand('toggleOrderedList')"
2577
- />
2578
- } @if (config().blockquote) {
2579
- <tiptap-button
2580
- icon="format_quote"
2581
- [title]="t().blockquote"
2582
- [active]="state().nodes.isBlockquote"
2583
- [disabled]="!state().can.toggleBlockquote"
2584
- (onClick)="onCommand('toggleBlockquote')"
2585
- />
2586
- } @if (config().separator && (config().alignLeft || config().alignCenter || config().alignRight || config().alignJustify)) {
2587
- <tiptap-separator />
2588
- } @if (config().alignLeft) {
2589
- <tiptap-button
2590
- icon="format_align_left"
2591
- [title]="t().alignLeft"
2592
- [active]="state().nodes.alignLeft"
2593
- [disabled]="!state().can.setTextAlignLeft"
2594
- (onClick)="onCommand('setTextAlign', 'left')"
2595
- />
2596
- } @if (config().alignCenter) {
2597
- <tiptap-button
2598
- icon="format_align_center"
2599
- [title]="t().alignCenter"
2600
- [active]="state().nodes.alignCenter"
2601
- [disabled]="!state().can.setTextAlignCenter"
2602
- (onClick)="onCommand('setTextAlign', 'center')"
2603
- />
2604
- } @if (config().alignRight) {
2605
- <tiptap-button
2606
- icon="format_align_right"
2607
- [title]="t().alignRight"
2608
- [active]="state().nodes.alignRight"
2609
- [disabled]="!state().can.setTextAlignRight"
2610
- (onClick)="onCommand('setTextAlign', 'right')"
2611
- />
2612
- } @if (config().alignJustify) {
2613
- <tiptap-button
2614
- icon="format_align_justify"
2615
- [title]="t().alignJustify"
2616
- [active]="state().nodes.alignJustify"
2617
- [disabled]="!state().can.setTextAlignJustify"
2618
- (onClick)="onCommand('setTextAlign', 'justify')"
2619
- />
2620
- } @if (config().separator && (config().link || config().horizontalRule)) {
2621
- <tiptap-separator />
2622
- } @if (config().link) {
2623
- <tiptap-button
2624
- icon="link"
2625
- [title]="t().link"
2626
- [active]="state().marks.link"
2627
- [disabled]="!state().can.toggleLink"
2628
- (onClick)="onCommand('toggleLink', $event)"
2629
- />
2630
- } @if (config().horizontalRule) {
2631
- <tiptap-button
2632
- icon="horizontal_rule"
2633
- [title]="t().horizontalRule"
2634
- [disabled]="!state().can.insertHorizontalRule"
2635
- (onClick)="onCommand('insertHorizontalRule')"
2636
- />
2637
- } @if (config().table) {
2638
- <tiptap-button
2639
- icon="table_view"
2640
- [title]="t().table"
2641
- [disabled]="!state().can.insertTable"
2642
- (onClick)="onCommand('insertTable')"
2643
- />
2644
- } @if (config().separator && config().image) {
2645
- <tiptap-separator />
2646
- } @if (config().image) {
2647
- <tiptap-button
2648
- icon="image"
2649
- [title]="t().image"
2650
- [disabled]="!state().can.insertImage"
2651
- (onClick)="onCommand('insertImage', imageUpload())"
2652
- />
2653
- } @if (config().separator && (config().undo || config().redo)) {
2654
- <tiptap-separator />
2655
- } @if (config().undo) {
2656
- <tiptap-button
2657
- icon="undo"
2658
- [title]="t().undo"
2659
- [disabled]="!state().can.undo"
2660
- (onClick)="onCommand('undo')"
2661
- />
2662
- } @if (config().redo) {
2663
- <tiptap-button
2664
- icon="redo"
2665
- [title]="t().redo"
2666
- [disabled]="!state().can.redo"
2667
- (onClick)="onCommand('redo')"
2668
- />
2669
- } @if (config().separator && config().clear) {
2670
- <tiptap-separator />
2671
- } @if (config().clear) {
2672
- <tiptap-button
2673
- icon="delete"
2674
- [title]="t().clear"
2675
- [disabled]="!state().isEditable"
2676
- (onClick)="onCommand('clearContent')"
2677
- />
2678
- }
2679
- </div>
2680
- `, isInline: true, styles: [":host{display:block;transition:opacity .3s ease}:host-context(.floating-toolbar){position:sticky;top:3rem;left:0;right:0;z-index:100;display:flex;height:0;overflow:visible;pointer-events:none;opacity:0}:host-context(.floating-toolbar:focus-within),:host-context(.floating-toolbar:hover){opacity:1}.tiptap-toolbar{display:flex;align-items:center;gap:4px;padding:var(--ate-toolbar-padding);background:var(--ate-toolbar-background);border-bottom:1px solid var(--ate-toolbar-border-color);flex-wrap:wrap;min-height:32px;position:relative;z-index:50;border-top-left-radius:calc(var(--ate-menu-border-radius, 8px) - var(--ate-border-width, 2px));border-top-right-radius:calc(var(--ate-menu-border-radius, 8px) - var(--ate-border-width, 2px))}.tiptap-toolbar.floating{pointer-events:auto;border-radius:var(--ate-menu-border-radius, 8px);border:1px solid var(--ate-menu-border)!important;box-shadow:var(--ate-menu-shadow)!important;background:var(--ate-menu-bg)!important;padding:var(--ate-menu-padding)!important;flex-wrap:nowrap;overflow-x:auto;max-width:95vw;scrollbar-width:none;transform:translateY(0);transition:transform .3s cubic-bezier(.4,0,.2,1)}.tiptap-toolbar.floating::-webkit-scrollbar{display:none}:host-context(.floating-toolbar:focus-within) .tiptap-toolbar.floating,:host-context(.floating-toolbar:hover) .tiptap-toolbar.floating{transform:translateY(-2rem)}@media (max-width: 768px){.tiptap-toolbar{padding:6px 8px;gap:2px}}@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", "disabled", "anchorToText"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2461
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapToolbarComponent, isStandalone: true, selector: "tiptap-toolbar", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null }, floating: { classPropertyName: "floating", publicName: "floating", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2462
+ <div class="tiptap-toolbar" [class.floating]="floating()">
2463
+ @if (config().bold) {
2464
+ <tiptap-button
2465
+ icon="format_bold"
2466
+ [title]="t().bold"
2467
+ [active]="state().marks.bold"
2468
+ [disabled]="!state().can.toggleBold"
2469
+ (onClick)="onCommand('toggleBold')"
2470
+ />
2471
+ } @if (config().italic) {
2472
+ <tiptap-button
2473
+ icon="format_italic"
2474
+ [title]="t().italic"
2475
+ [active]="state().marks.italic"
2476
+ [disabled]="!state().can.toggleItalic"
2477
+ (onClick)="onCommand('toggleItalic')"
2478
+ />
2479
+ } @if (config().underline) {
2480
+ <tiptap-button
2481
+ icon="format_underlined"
2482
+ [title]="t().underline"
2483
+ [active]="state().marks.underline"
2484
+ [disabled]="!state().can.toggleUnderline"
2485
+ (onClick)="onCommand('toggleUnderline')"
2486
+ />
2487
+ } @if (config().strike) {
2488
+ <tiptap-button
2489
+ icon="strikethrough_s"
2490
+ [title]="t().strike"
2491
+ [active]="state().marks.strike"
2492
+ [disabled]="!state().can.toggleStrike"
2493
+ (onClick)="onCommand('toggleStrike')"
2494
+ />
2495
+ } @if (config().code) {
2496
+ <tiptap-button
2497
+ icon="code"
2498
+ [title]="t().code"
2499
+ [active]="state().marks.code"
2500
+ [disabled]="!state().can.toggleCode"
2501
+ (onClick)="onCommand('toggleCode')"
2502
+ />
2503
+ } @if (config().codeBlock) {
2504
+ <tiptap-button
2505
+ icon="terminal"
2506
+ [title]="t().codeBlock"
2507
+ [active]="state().nodes.isCodeBlock"
2508
+ [disabled]="!state().can.toggleCodeBlock"
2509
+ (onClick)="onCommand('toggleCodeBlock')"
2510
+ />
2511
+ } @if (config().superscript) {
2512
+ <tiptap-button
2513
+ icon="superscript"
2514
+ [title]="t().superscript"
2515
+ [active]="state().marks.superscript"
2516
+ [disabled]="!state().can.toggleSuperscript"
2517
+ (onClick)="onCommand('toggleSuperscript')"
2518
+ />
2519
+ } @if (config().subscript) {
2520
+ <tiptap-button
2521
+ icon="subscript"
2522
+ [title]="t().subscript"
2523
+ [active]="state().marks.subscript"
2524
+ [disabled]="!state().can.toggleSubscript"
2525
+ (onClick)="onCommand('toggleSubscript')"
2526
+ />
2527
+ } @if (config().highlight) {
2528
+ <tiptap-button
2529
+ icon="highlight"
2530
+ [title]="t().highlight"
2531
+ [active]="state().marks.highlight"
2532
+ [disabled]="!state().can.toggleHighlight"
2533
+ (onClick)="onCommand('toggleHighlight')"
2534
+ />
2535
+ } @if (config().highlightPicker) {
2536
+ <tiptap-color-picker
2537
+ mode="highlight"
2538
+ [editor]="editor()"
2539
+ [disabled]="!state().can.setHighlight"
2540
+ />
2541
+ } @if (config().textColor) {
2542
+ <tiptap-color-picker
2543
+ mode="text"
2544
+ [editor]="editor()"
2545
+ [disabled]="!state().can.setColor"
2546
+ />
2547
+ }
2548
+
2549
+ @if (config().separator && (config().heading1 || config().heading2 || config().heading3)) {
2550
+ <tiptap-separator />
2551
+ } @if (config().heading1) {
2552
+ <tiptap-button
2553
+ icon="format_h1"
2554
+ [title]="t().heading1"
2555
+ [active]="state().nodes.h1"
2556
+ [disabled]="!state().can.toggleHeading1"
2557
+ (onClick)="onCommand('toggleHeading', 1)"
2558
+ />
2559
+ } @if (config().heading2) {
2560
+ <tiptap-button
2561
+ icon="format_h2"
2562
+ [title]="t().heading2"
2563
+ [active]="state().nodes.h2"
2564
+ [disabled]="!state().can.toggleHeading2"
2565
+ (onClick)="onCommand('toggleHeading', 2)"
2566
+ />
2567
+ } @if (config().heading3) {
2568
+ <tiptap-button
2569
+ icon="format_h3"
2570
+ [title]="t().heading3"
2571
+ [active]="state().nodes.h3"
2572
+ [disabled]="!state().can.toggleHeading3"
2573
+ (onClick)="onCommand('toggleHeading', 3)"
2574
+ />
2575
+ } @if (config().separator && (config().bulletList || config().orderedList || config().blockquote)) {
2576
+ <tiptap-separator />
2577
+ } @if (config().bulletList) {
2578
+ <tiptap-button
2579
+ icon="format_list_bulleted"
2580
+ [title]="t().bulletList"
2581
+ [active]="state().nodes.isBulletList"
2582
+ [disabled]="!state().can.toggleBulletList"
2583
+ (onClick)="onCommand('toggleBulletList')"
2584
+ />
2585
+ } @if (config().orderedList) {
2586
+ <tiptap-button
2587
+ icon="format_list_numbered"
2588
+ [title]="t().orderedList"
2589
+ [active]="state().nodes.isOrderedList"
2590
+ [disabled]="!state().can.toggleOrderedList"
2591
+ (onClick)="onCommand('toggleOrderedList')"
2592
+ />
2593
+ } @if (config().blockquote) {
2594
+ <tiptap-button
2595
+ icon="format_quote"
2596
+ [title]="t().blockquote"
2597
+ [active]="state().nodes.isBlockquote"
2598
+ [disabled]="!state().can.toggleBlockquote"
2599
+ (onClick)="onCommand('toggleBlockquote')"
2600
+ />
2601
+ } @if (config().separator && (config().alignLeft || config().alignCenter || config().alignRight || config().alignJustify)) {
2602
+ <tiptap-separator />
2603
+ } @if (config().alignLeft) {
2604
+ <tiptap-button
2605
+ icon="format_align_left"
2606
+ [title]="t().alignLeft"
2607
+ [active]="state().nodes.alignLeft"
2608
+ [disabled]="!state().can.setTextAlignLeft"
2609
+ (onClick)="onCommand('setTextAlign', 'left')"
2610
+ />
2611
+ } @if (config().alignCenter) {
2612
+ <tiptap-button
2613
+ icon="format_align_center"
2614
+ [title]="t().alignCenter"
2615
+ [active]="state().nodes.alignCenter"
2616
+ [disabled]="!state().can.setTextAlignCenter"
2617
+ (onClick)="onCommand('setTextAlign', 'center')"
2618
+ />
2619
+ } @if (config().alignRight) {
2620
+ <tiptap-button
2621
+ icon="format_align_right"
2622
+ [title]="t().alignRight"
2623
+ [active]="state().nodes.alignRight"
2624
+ [disabled]="!state().can.setTextAlignRight"
2625
+ (onClick)="onCommand('setTextAlign', 'right')"
2626
+ />
2627
+ } @if (config().alignJustify) {
2628
+ <tiptap-button
2629
+ icon="format_align_justify"
2630
+ [title]="t().alignJustify"
2631
+ [active]="state().nodes.alignJustify"
2632
+ [disabled]="!state().can.setTextAlignJustify"
2633
+ (onClick)="onCommand('setTextAlign', 'justify')"
2634
+ />
2635
+ } @if (config().separator && (config().link || config().horizontalRule)) {
2636
+ <tiptap-separator />
2637
+ } @if (config().link) {
2638
+ <tiptap-button
2639
+ icon="link"
2640
+ [title]="t().link"
2641
+ [active]="state().marks.link"
2642
+ [disabled]="!state().can.toggleLink"
2643
+ (onClick)="onCommand('toggleLink', $event)"
2644
+ />
2645
+ } @if (config().horizontalRule) {
2646
+ <tiptap-button
2647
+ icon="horizontal_rule"
2648
+ [title]="t().horizontalRule"
2649
+ [disabled]="!state().can.insertHorizontalRule"
2650
+ (onClick)="onCommand('insertHorizontalRule')"
2651
+ />
2652
+ } @if (config().table) {
2653
+ <tiptap-button
2654
+ icon="table_view"
2655
+ [title]="t().table"
2656
+ [disabled]="!state().can.insertTable"
2657
+ (onClick)="onCommand('insertTable')"
2658
+ />
2659
+ } @if (config().separator && config().image) {
2660
+ <tiptap-separator />
2661
+ } @if (config().image) {
2662
+ <tiptap-button
2663
+ icon="image"
2664
+ [title]="t().image"
2665
+ [disabled]="!state().can.insertImage"
2666
+ (onClick)="onCommand('insertImage', imageUpload())"
2667
+ />
2668
+ } @if (config().separator && (config().undo || config().redo)) {
2669
+ <tiptap-separator />
2670
+ } @if (config().undo) {
2671
+ <tiptap-button
2672
+ icon="undo"
2673
+ [title]="t().undo"
2674
+ [disabled]="!state().can.undo"
2675
+ (onClick)="onCommand('undo')"
2676
+ />
2677
+ } @if (config().redo) {
2678
+ <tiptap-button
2679
+ icon="redo"
2680
+ [title]="t().redo"
2681
+ [disabled]="!state().can.redo"
2682
+ (onClick)="onCommand('redo')"
2683
+ />
2684
+ } @if (config().separator && config().clear) {
2685
+ <tiptap-separator />
2686
+ } @if (config().clear) {
2687
+ <tiptap-button
2688
+ icon="delete"
2689
+ [title]="t().clear"
2690
+ [disabled]="!state().isEditable"
2691
+ (onClick)="onCommand('clearContent')"
2692
+ />
2693
+ }
2694
+ </div>
2695
+ `, isInline: true, styles: [":host{display:block;transition:opacity .3s ease}:host-context(.floating-toolbar){position:sticky;top:3rem;left:0;right:0;z-index:100;display:flex;height:0;overflow:visible;pointer-events:none;opacity:0}:host-context(.floating-toolbar:focus-within),:host-context(.floating-toolbar:hover){opacity:1}.tiptap-toolbar{display:flex;align-items:center;gap:4px;padding:var(--ate-toolbar-padding);background:var(--ate-toolbar-background);border-bottom:1px solid var(--ate-toolbar-border-color);flex-wrap:wrap;min-height:32px;position:relative;z-index:50;border-top-left-radius:calc(var(--ate-menu-border-radius, 12px) - var(--ate-border-width, 2px));border-top-right-radius:calc(var(--ate-menu-border-radius, 12px) - var(--ate-border-width, 2px))}.tiptap-toolbar.floating{pointer-events:auto;border-radius:var(--ate-menu-border-radius, 12px);border:1px solid var(--ate-menu-border)!important;box-shadow:var(--ate-menu-shadow)!important;background:var(--ate-menu-bg)!important;padding:var(--ate-menu-padding)!important;flex-wrap:nowrap;overflow-x:auto;max-width:95vw;scrollbar-width:none;transform:translateY(0);transition:transform .3s cubic-bezier(.4,0,.2,1)}.tiptap-toolbar.floating::-webkit-scrollbar{display:none}:host-context(.floating-toolbar:focus-within) .tiptap-toolbar.floating,:host-context(.floating-toolbar:hover) .tiptap-toolbar.floating{transform:translateY(-2rem)}@media (max-width: 768px){.tiptap-toolbar{padding:6px 8px;gap:2px}}@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", "disabled", "anchorToText"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2681
2696
  }
2682
2697
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapToolbarComponent, decorators: [{
2683
2698
  type: Component,
@@ -2685,241 +2700,241 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
2685
2700
  TiptapButtonComponent,
2686
2701
  TiptapSeparatorComponent,
2687
2702
  TiptapColorPickerComponent,
2688
- ], template: `
2689
- <div class="tiptap-toolbar" [class.floating]="floating()">
2690
- @if (config().bold) {
2691
- <tiptap-button
2692
- icon="format_bold"
2693
- [title]="t().bold"
2694
- [active]="state().marks.bold"
2695
- [disabled]="!state().can.toggleBold"
2696
- (onClick)="onCommand('toggleBold')"
2697
- />
2698
- } @if (config().italic) {
2699
- <tiptap-button
2700
- icon="format_italic"
2701
- [title]="t().italic"
2702
- [active]="state().marks.italic"
2703
- [disabled]="!state().can.toggleItalic"
2704
- (onClick)="onCommand('toggleItalic')"
2705
- />
2706
- } @if (config().underline) {
2707
- <tiptap-button
2708
- icon="format_underlined"
2709
- [title]="t().underline"
2710
- [active]="state().marks.underline"
2711
- [disabled]="!state().can.toggleUnderline"
2712
- (onClick)="onCommand('toggleUnderline')"
2713
- />
2714
- } @if (config().strike) {
2715
- <tiptap-button
2716
- icon="strikethrough_s"
2717
- [title]="t().strike"
2718
- [active]="state().marks.strike"
2719
- [disabled]="!state().can.toggleStrike"
2720
- (onClick)="onCommand('toggleStrike')"
2721
- />
2722
- } @if (config().code) {
2723
- <tiptap-button
2724
- icon="code"
2725
- [title]="t().code"
2726
- [active]="state().marks.code"
2727
- [disabled]="!state().can.toggleCode"
2728
- (onClick)="onCommand('toggleCode')"
2729
- />
2730
- } @if (config().codeBlock) {
2731
- <tiptap-button
2732
- icon="terminal"
2733
- [title]="t().codeBlock"
2734
- [active]="state().nodes.isCodeBlock"
2735
- [disabled]="!state().can.toggleCodeBlock"
2736
- (onClick)="onCommand('toggleCodeBlock')"
2737
- />
2738
- } @if (config().superscript) {
2739
- <tiptap-button
2740
- icon="superscript"
2741
- [title]="t().superscript"
2742
- [active]="state().marks.superscript"
2743
- [disabled]="!state().can.toggleSuperscript"
2744
- (onClick)="onCommand('toggleSuperscript')"
2745
- />
2746
- } @if (config().subscript) {
2747
- <tiptap-button
2748
- icon="subscript"
2749
- [title]="t().subscript"
2750
- [active]="state().marks.subscript"
2751
- [disabled]="!state().can.toggleSubscript"
2752
- (onClick)="onCommand('toggleSubscript')"
2753
- />
2754
- } @if (config().highlight) {
2755
- <tiptap-button
2756
- icon="highlight"
2757
- [title]="t().highlight"
2758
- [active]="state().marks.highlight"
2759
- [disabled]="!state().can.toggleHighlight"
2760
- (onClick)="onCommand('toggleHighlight')"
2761
- />
2762
- } @if (config().highlightPicker) {
2763
- <tiptap-color-picker
2764
- mode="highlight"
2765
- [editor]="editor()"
2766
- [disabled]="!state().can.setHighlight"
2767
- />
2768
- } @if (config().textColor) {
2769
- <tiptap-color-picker
2770
- mode="text"
2771
- [editor]="editor()"
2772
- [disabled]="!state().can.setColor"
2773
- />
2774
- }
2775
-
2776
- @if (config().separator && (config().heading1 || config().heading2 || config().heading3)) {
2777
- <tiptap-separator />
2778
- } @if (config().heading1) {
2779
- <tiptap-button
2780
- icon="format_h1"
2781
- [title]="t().heading1"
2782
- [active]="state().nodes.h1"
2783
- [disabled]="!state().can.toggleHeading1"
2784
- (onClick)="onCommand('toggleHeading', 1)"
2785
- />
2786
- } @if (config().heading2) {
2787
- <tiptap-button
2788
- icon="format_h2"
2789
- [title]="t().heading2"
2790
- [active]="state().nodes.h2"
2791
- [disabled]="!state().can.toggleHeading2"
2792
- (onClick)="onCommand('toggleHeading', 2)"
2793
- />
2794
- } @if (config().heading3) {
2795
- <tiptap-button
2796
- icon="format_h3"
2797
- [title]="t().heading3"
2798
- [active]="state().nodes.h3"
2799
- [disabled]="!state().can.toggleHeading3"
2800
- (onClick)="onCommand('toggleHeading', 3)"
2801
- />
2802
- } @if (config().separator && (config().bulletList || config().orderedList || config().blockquote)) {
2803
- <tiptap-separator />
2804
- } @if (config().bulletList) {
2805
- <tiptap-button
2806
- icon="format_list_bulleted"
2807
- [title]="t().bulletList"
2808
- [active]="state().nodes.isBulletList"
2809
- [disabled]="!state().can.toggleBulletList"
2810
- (onClick)="onCommand('toggleBulletList')"
2811
- />
2812
- } @if (config().orderedList) {
2813
- <tiptap-button
2814
- icon="format_list_numbered"
2815
- [title]="t().orderedList"
2816
- [active]="state().nodes.isOrderedList"
2817
- [disabled]="!state().can.toggleOrderedList"
2818
- (onClick)="onCommand('toggleOrderedList')"
2819
- />
2820
- } @if (config().blockquote) {
2821
- <tiptap-button
2822
- icon="format_quote"
2823
- [title]="t().blockquote"
2824
- [active]="state().nodes.isBlockquote"
2825
- [disabled]="!state().can.toggleBlockquote"
2826
- (onClick)="onCommand('toggleBlockquote')"
2827
- />
2828
- } @if (config().separator && (config().alignLeft || config().alignCenter || config().alignRight || config().alignJustify)) {
2829
- <tiptap-separator />
2830
- } @if (config().alignLeft) {
2831
- <tiptap-button
2832
- icon="format_align_left"
2833
- [title]="t().alignLeft"
2834
- [active]="state().nodes.alignLeft"
2835
- [disabled]="!state().can.setTextAlignLeft"
2836
- (onClick)="onCommand('setTextAlign', 'left')"
2837
- />
2838
- } @if (config().alignCenter) {
2839
- <tiptap-button
2840
- icon="format_align_center"
2841
- [title]="t().alignCenter"
2842
- [active]="state().nodes.alignCenter"
2843
- [disabled]="!state().can.setTextAlignCenter"
2844
- (onClick)="onCommand('setTextAlign', 'center')"
2845
- />
2846
- } @if (config().alignRight) {
2847
- <tiptap-button
2848
- icon="format_align_right"
2849
- [title]="t().alignRight"
2850
- [active]="state().nodes.alignRight"
2851
- [disabled]="!state().can.setTextAlignRight"
2852
- (onClick)="onCommand('setTextAlign', 'right')"
2853
- />
2854
- } @if (config().alignJustify) {
2855
- <tiptap-button
2856
- icon="format_align_justify"
2857
- [title]="t().alignJustify"
2858
- [active]="state().nodes.alignJustify"
2859
- [disabled]="!state().can.setTextAlignJustify"
2860
- (onClick)="onCommand('setTextAlign', 'justify')"
2861
- />
2862
- } @if (config().separator && (config().link || config().horizontalRule)) {
2863
- <tiptap-separator />
2864
- } @if (config().link) {
2865
- <tiptap-button
2866
- icon="link"
2867
- [title]="t().link"
2868
- [active]="state().marks.link"
2869
- [disabled]="!state().can.toggleLink"
2870
- (onClick)="onCommand('toggleLink', $event)"
2871
- />
2872
- } @if (config().horizontalRule) {
2873
- <tiptap-button
2874
- icon="horizontal_rule"
2875
- [title]="t().horizontalRule"
2876
- [disabled]="!state().can.insertHorizontalRule"
2877
- (onClick)="onCommand('insertHorizontalRule')"
2878
- />
2879
- } @if (config().table) {
2880
- <tiptap-button
2881
- icon="table_view"
2882
- [title]="t().table"
2883
- [disabled]="!state().can.insertTable"
2884
- (onClick)="onCommand('insertTable')"
2885
- />
2886
- } @if (config().separator && config().image) {
2887
- <tiptap-separator />
2888
- } @if (config().image) {
2889
- <tiptap-button
2890
- icon="image"
2891
- [title]="t().image"
2892
- [disabled]="!state().can.insertImage"
2893
- (onClick)="onCommand('insertImage', imageUpload())"
2894
- />
2895
- } @if (config().separator && (config().undo || config().redo)) {
2896
- <tiptap-separator />
2897
- } @if (config().undo) {
2898
- <tiptap-button
2899
- icon="undo"
2900
- [title]="t().undo"
2901
- [disabled]="!state().can.undo"
2902
- (onClick)="onCommand('undo')"
2903
- />
2904
- } @if (config().redo) {
2905
- <tiptap-button
2906
- icon="redo"
2907
- [title]="t().redo"
2908
- [disabled]="!state().can.redo"
2909
- (onClick)="onCommand('redo')"
2910
- />
2911
- } @if (config().separator && config().clear) {
2912
- <tiptap-separator />
2913
- } @if (config().clear) {
2914
- <tiptap-button
2915
- icon="delete"
2916
- [title]="t().clear"
2917
- [disabled]="!state().isEditable"
2918
- (onClick)="onCommand('clearContent')"
2919
- />
2920
- }
2921
- </div>
2922
- `, styles: [":host{display:block;transition:opacity .3s ease}:host-context(.floating-toolbar){position:sticky;top:3rem;left:0;right:0;z-index:100;display:flex;height:0;overflow:visible;pointer-events:none;opacity:0}:host-context(.floating-toolbar:focus-within),:host-context(.floating-toolbar:hover){opacity:1}.tiptap-toolbar{display:flex;align-items:center;gap:4px;padding:var(--ate-toolbar-padding);background:var(--ate-toolbar-background);border-bottom:1px solid var(--ate-toolbar-border-color);flex-wrap:wrap;min-height:32px;position:relative;z-index:50;border-top-left-radius:calc(var(--ate-menu-border-radius, 8px) - var(--ate-border-width, 2px));border-top-right-radius:calc(var(--ate-menu-border-radius, 8px) - var(--ate-border-width, 2px))}.tiptap-toolbar.floating{pointer-events:auto;border-radius:var(--ate-menu-border-radius, 8px);border:1px solid var(--ate-menu-border)!important;box-shadow:var(--ate-menu-shadow)!important;background:var(--ate-menu-bg)!important;padding:var(--ate-menu-padding)!important;flex-wrap:nowrap;overflow-x:auto;max-width:95vw;scrollbar-width:none;transform:translateY(0);transition:transform .3s cubic-bezier(.4,0,.2,1)}.tiptap-toolbar.floating::-webkit-scrollbar{display:none}:host-context(.floating-toolbar:focus-within) .tiptap-toolbar.floating,:host-context(.floating-toolbar:hover) .tiptap-toolbar.floating{transform:translateY(-2rem)}@media (max-width: 768px){.tiptap-toolbar{padding:6px 8px;gap:2px}}@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"] }]
2703
+ ], template: `
2704
+ <div class="tiptap-toolbar" [class.floating]="floating()">
2705
+ @if (config().bold) {
2706
+ <tiptap-button
2707
+ icon="format_bold"
2708
+ [title]="t().bold"
2709
+ [active]="state().marks.bold"
2710
+ [disabled]="!state().can.toggleBold"
2711
+ (onClick)="onCommand('toggleBold')"
2712
+ />
2713
+ } @if (config().italic) {
2714
+ <tiptap-button
2715
+ icon="format_italic"
2716
+ [title]="t().italic"
2717
+ [active]="state().marks.italic"
2718
+ [disabled]="!state().can.toggleItalic"
2719
+ (onClick)="onCommand('toggleItalic')"
2720
+ />
2721
+ } @if (config().underline) {
2722
+ <tiptap-button
2723
+ icon="format_underlined"
2724
+ [title]="t().underline"
2725
+ [active]="state().marks.underline"
2726
+ [disabled]="!state().can.toggleUnderline"
2727
+ (onClick)="onCommand('toggleUnderline')"
2728
+ />
2729
+ } @if (config().strike) {
2730
+ <tiptap-button
2731
+ icon="strikethrough_s"
2732
+ [title]="t().strike"
2733
+ [active]="state().marks.strike"
2734
+ [disabled]="!state().can.toggleStrike"
2735
+ (onClick)="onCommand('toggleStrike')"
2736
+ />
2737
+ } @if (config().code) {
2738
+ <tiptap-button
2739
+ icon="code"
2740
+ [title]="t().code"
2741
+ [active]="state().marks.code"
2742
+ [disabled]="!state().can.toggleCode"
2743
+ (onClick)="onCommand('toggleCode')"
2744
+ />
2745
+ } @if (config().codeBlock) {
2746
+ <tiptap-button
2747
+ icon="terminal"
2748
+ [title]="t().codeBlock"
2749
+ [active]="state().nodes.isCodeBlock"
2750
+ [disabled]="!state().can.toggleCodeBlock"
2751
+ (onClick)="onCommand('toggleCodeBlock')"
2752
+ />
2753
+ } @if (config().superscript) {
2754
+ <tiptap-button
2755
+ icon="superscript"
2756
+ [title]="t().superscript"
2757
+ [active]="state().marks.superscript"
2758
+ [disabled]="!state().can.toggleSuperscript"
2759
+ (onClick)="onCommand('toggleSuperscript')"
2760
+ />
2761
+ } @if (config().subscript) {
2762
+ <tiptap-button
2763
+ icon="subscript"
2764
+ [title]="t().subscript"
2765
+ [active]="state().marks.subscript"
2766
+ [disabled]="!state().can.toggleSubscript"
2767
+ (onClick)="onCommand('toggleSubscript')"
2768
+ />
2769
+ } @if (config().highlight) {
2770
+ <tiptap-button
2771
+ icon="highlight"
2772
+ [title]="t().highlight"
2773
+ [active]="state().marks.highlight"
2774
+ [disabled]="!state().can.toggleHighlight"
2775
+ (onClick)="onCommand('toggleHighlight')"
2776
+ />
2777
+ } @if (config().highlightPicker) {
2778
+ <tiptap-color-picker
2779
+ mode="highlight"
2780
+ [editor]="editor()"
2781
+ [disabled]="!state().can.setHighlight"
2782
+ />
2783
+ } @if (config().textColor) {
2784
+ <tiptap-color-picker
2785
+ mode="text"
2786
+ [editor]="editor()"
2787
+ [disabled]="!state().can.setColor"
2788
+ />
2789
+ }
2790
+
2791
+ @if (config().separator && (config().heading1 || config().heading2 || config().heading3)) {
2792
+ <tiptap-separator />
2793
+ } @if (config().heading1) {
2794
+ <tiptap-button
2795
+ icon="format_h1"
2796
+ [title]="t().heading1"
2797
+ [active]="state().nodes.h1"
2798
+ [disabled]="!state().can.toggleHeading1"
2799
+ (onClick)="onCommand('toggleHeading', 1)"
2800
+ />
2801
+ } @if (config().heading2) {
2802
+ <tiptap-button
2803
+ icon="format_h2"
2804
+ [title]="t().heading2"
2805
+ [active]="state().nodes.h2"
2806
+ [disabled]="!state().can.toggleHeading2"
2807
+ (onClick)="onCommand('toggleHeading', 2)"
2808
+ />
2809
+ } @if (config().heading3) {
2810
+ <tiptap-button
2811
+ icon="format_h3"
2812
+ [title]="t().heading3"
2813
+ [active]="state().nodes.h3"
2814
+ [disabled]="!state().can.toggleHeading3"
2815
+ (onClick)="onCommand('toggleHeading', 3)"
2816
+ />
2817
+ } @if (config().separator && (config().bulletList || config().orderedList || config().blockquote)) {
2818
+ <tiptap-separator />
2819
+ } @if (config().bulletList) {
2820
+ <tiptap-button
2821
+ icon="format_list_bulleted"
2822
+ [title]="t().bulletList"
2823
+ [active]="state().nodes.isBulletList"
2824
+ [disabled]="!state().can.toggleBulletList"
2825
+ (onClick)="onCommand('toggleBulletList')"
2826
+ />
2827
+ } @if (config().orderedList) {
2828
+ <tiptap-button
2829
+ icon="format_list_numbered"
2830
+ [title]="t().orderedList"
2831
+ [active]="state().nodes.isOrderedList"
2832
+ [disabled]="!state().can.toggleOrderedList"
2833
+ (onClick)="onCommand('toggleOrderedList')"
2834
+ />
2835
+ } @if (config().blockquote) {
2836
+ <tiptap-button
2837
+ icon="format_quote"
2838
+ [title]="t().blockquote"
2839
+ [active]="state().nodes.isBlockquote"
2840
+ [disabled]="!state().can.toggleBlockquote"
2841
+ (onClick)="onCommand('toggleBlockquote')"
2842
+ />
2843
+ } @if (config().separator && (config().alignLeft || config().alignCenter || config().alignRight || config().alignJustify)) {
2844
+ <tiptap-separator />
2845
+ } @if (config().alignLeft) {
2846
+ <tiptap-button
2847
+ icon="format_align_left"
2848
+ [title]="t().alignLeft"
2849
+ [active]="state().nodes.alignLeft"
2850
+ [disabled]="!state().can.setTextAlignLeft"
2851
+ (onClick)="onCommand('setTextAlign', 'left')"
2852
+ />
2853
+ } @if (config().alignCenter) {
2854
+ <tiptap-button
2855
+ icon="format_align_center"
2856
+ [title]="t().alignCenter"
2857
+ [active]="state().nodes.alignCenter"
2858
+ [disabled]="!state().can.setTextAlignCenter"
2859
+ (onClick)="onCommand('setTextAlign', 'center')"
2860
+ />
2861
+ } @if (config().alignRight) {
2862
+ <tiptap-button
2863
+ icon="format_align_right"
2864
+ [title]="t().alignRight"
2865
+ [active]="state().nodes.alignRight"
2866
+ [disabled]="!state().can.setTextAlignRight"
2867
+ (onClick)="onCommand('setTextAlign', 'right')"
2868
+ />
2869
+ } @if (config().alignJustify) {
2870
+ <tiptap-button
2871
+ icon="format_align_justify"
2872
+ [title]="t().alignJustify"
2873
+ [active]="state().nodes.alignJustify"
2874
+ [disabled]="!state().can.setTextAlignJustify"
2875
+ (onClick)="onCommand('setTextAlign', 'justify')"
2876
+ />
2877
+ } @if (config().separator && (config().link || config().horizontalRule)) {
2878
+ <tiptap-separator />
2879
+ } @if (config().link) {
2880
+ <tiptap-button
2881
+ icon="link"
2882
+ [title]="t().link"
2883
+ [active]="state().marks.link"
2884
+ [disabled]="!state().can.toggleLink"
2885
+ (onClick)="onCommand('toggleLink', $event)"
2886
+ />
2887
+ } @if (config().horizontalRule) {
2888
+ <tiptap-button
2889
+ icon="horizontal_rule"
2890
+ [title]="t().horizontalRule"
2891
+ [disabled]="!state().can.insertHorizontalRule"
2892
+ (onClick)="onCommand('insertHorizontalRule')"
2893
+ />
2894
+ } @if (config().table) {
2895
+ <tiptap-button
2896
+ icon="table_view"
2897
+ [title]="t().table"
2898
+ [disabled]="!state().can.insertTable"
2899
+ (onClick)="onCommand('insertTable')"
2900
+ />
2901
+ } @if (config().separator && config().image) {
2902
+ <tiptap-separator />
2903
+ } @if (config().image) {
2904
+ <tiptap-button
2905
+ icon="image"
2906
+ [title]="t().image"
2907
+ [disabled]="!state().can.insertImage"
2908
+ (onClick)="onCommand('insertImage', imageUpload())"
2909
+ />
2910
+ } @if (config().separator && (config().undo || config().redo)) {
2911
+ <tiptap-separator />
2912
+ } @if (config().undo) {
2913
+ <tiptap-button
2914
+ icon="undo"
2915
+ [title]="t().undo"
2916
+ [disabled]="!state().can.undo"
2917
+ (onClick)="onCommand('undo')"
2918
+ />
2919
+ } @if (config().redo) {
2920
+ <tiptap-button
2921
+ icon="redo"
2922
+ [title]="t().redo"
2923
+ [disabled]="!state().can.redo"
2924
+ (onClick)="onCommand('redo')"
2925
+ />
2926
+ } @if (config().separator && config().clear) {
2927
+ <tiptap-separator />
2928
+ } @if (config().clear) {
2929
+ <tiptap-button
2930
+ icon="delete"
2931
+ [title]="t().clear"
2932
+ [disabled]="!state().isEditable"
2933
+ (onClick)="onCommand('clearContent')"
2934
+ />
2935
+ }
2936
+ </div>
2937
+ `, styles: [":host{display:block;transition:opacity .3s ease}:host-context(.floating-toolbar){position:sticky;top:3rem;left:0;right:0;z-index:100;display:flex;height:0;overflow:visible;pointer-events:none;opacity:0}:host-context(.floating-toolbar:focus-within),:host-context(.floating-toolbar:hover){opacity:1}.tiptap-toolbar{display:flex;align-items:center;gap:4px;padding:var(--ate-toolbar-padding);background:var(--ate-toolbar-background);border-bottom:1px solid var(--ate-toolbar-border-color);flex-wrap:wrap;min-height:32px;position:relative;z-index:50;border-top-left-radius:calc(var(--ate-menu-border-radius, 12px) - var(--ate-border-width, 2px));border-top-right-radius:calc(var(--ate-menu-border-radius, 12px) - var(--ate-border-width, 2px))}.tiptap-toolbar.floating{pointer-events:auto;border-radius:var(--ate-menu-border-radius, 12px);border:1px solid var(--ate-menu-border)!important;box-shadow:var(--ate-menu-shadow)!important;background:var(--ate-menu-bg)!important;padding:var(--ate-menu-padding)!important;flex-wrap:nowrap;overflow-x:auto;max-width:95vw;scrollbar-width:none;transform:translateY(0);transition:transform .3s cubic-bezier(.4,0,.2,1)}.tiptap-toolbar.floating::-webkit-scrollbar{display:none}:host-context(.floating-toolbar:focus-within) .tiptap-toolbar.floating,:host-context(.floating-toolbar:hover) .tiptap-toolbar.floating{transform:translateY(-2rem)}@media (max-width: 768px){.tiptap-toolbar{padding:6px 8px;gap:2px}}@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"] }]
2923
2938
  }] });
2924
2939
 
2925
2940
  /**
@@ -3202,96 +3217,96 @@ class TiptapBubbleMenuComponent extends TiptapBaseBubbleMenu {
3202
3217
  // premature closing when clicking between 'sibling' menu instances.
3203
3218
  }
3204
3219
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapBubbleMenuComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3205
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapBubbleMenuComponent, isStandalone: true, selector: "tiptap-bubble-menu", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
3206
- <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3207
- @if (bubbleMenuConfig().bold) {
3208
- <tiptap-button
3209
- icon="format_bold"
3210
- [title]="t().bold"
3211
- [active]="state().marks.bold"
3212
- [disabled]="!state().can.toggleBold"
3213
- (onClick)="onCommand('toggleBold', $event)"
3214
- ></tiptap-button>
3215
- } @if (bubbleMenuConfig().italic) {
3216
- <tiptap-button
3217
- icon="format_italic"
3218
- [title]="t().italic"
3219
- [active]="state().marks.italic"
3220
- [disabled]="!state().can.toggleItalic"
3221
- (onClick)="onCommand('toggleItalic', $event)"
3222
- ></tiptap-button>
3223
- } @if (bubbleMenuConfig().underline) {
3224
- <tiptap-button
3225
- icon="format_underlined"
3226
- [title]="t().underline"
3227
- [active]="state().marks.underline"
3228
- [disabled]="!state().can.toggleUnderline"
3229
- (onClick)="onCommand('toggleUnderline', $event)"
3230
- ></tiptap-button>
3231
- } @if (bubbleMenuConfig().strike) {
3232
- <tiptap-button
3233
- icon="strikethrough_s"
3234
- [title]="t().strike"
3235
- [active]="state().marks.strike"
3236
- [disabled]="!state().can.toggleStrike"
3237
- (onClick)="onCommand('toggleStrike', $event)"
3238
- ></tiptap-button>
3239
- } @if (bubbleMenuConfig().code) {
3240
- <tiptap-button
3241
- icon="code"
3242
- [title]="t().code"
3243
- [active]="state().marks.code"
3244
- [disabled]="!state().can.toggleCode"
3245
- (onClick)="onCommand('toggleCode', $event)"
3246
- ></tiptap-button>
3247
- } @if (bubbleMenuConfig().superscript) {
3248
- <tiptap-button
3249
- icon="superscript"
3250
- [title]="t().superscript"
3251
- [active]="state().marks.superscript"
3252
- [disabled]="!state().can.toggleSuperscript"
3253
- (onClick)="onCommand('toggleSuperscript', $event)"
3254
- ></tiptap-button>
3255
- } @if (bubbleMenuConfig().subscript) {
3256
- <tiptap-button
3257
- icon="subscript"
3258
- [title]="t().subscript"
3259
- [active]="state().marks.subscript"
3260
- [disabled]="!state().can.toggleSubscript"
3261
- (onClick)="onCommand('toggleSubscript', $event)"
3262
- ></tiptap-button>
3263
- } @if (bubbleMenuConfig().highlight) {
3264
- <tiptap-button
3265
- icon="highlight"
3266
- [title]="t().highlight"
3267
- [active]="state().marks.highlight"
3268
- [disabled]="!state().can.toggleHighlight"
3269
- (onClick)="onCommand('toggleHighlight', $event)"
3270
- ></tiptap-button>
3271
- } @if (bubbleMenuConfig().highlightPicker) {
3272
- <tiptap-color-picker
3273
- mode="highlight"
3274
- [editor]="editor()"
3275
- [disabled]="!state().can.setHighlight"
3276
- [anchorToText]="true"
3277
- />
3278
- } @if (bubbleMenuConfig().textColor) {
3279
- <tiptap-color-picker
3280
- mode="text"
3281
- [editor]="editor()"
3282
- [disabled]="!state().can.setColor"
3283
- [anchorToText]="true"
3284
- />
3285
- } @if (bubbleMenuConfig().link) {
3286
- <tiptap-button
3287
- icon="link"
3288
- [title]="t().link"
3289
- [active]="state().marks.link"
3290
- [disabled]="!state().can.toggleLink"
3291
- (onClick)="onCommand('toggleLink', $event)"
3292
- ></tiptap-button>
3293
- }
3294
- </div>
3220
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapBubbleMenuComponent, isStandalone: true, selector: "tiptap-bubble-menu", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
3221
+ <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3222
+ @if (bubbleMenuConfig().bold) {
3223
+ <tiptap-button
3224
+ icon="format_bold"
3225
+ [title]="t().bold"
3226
+ [active]="state().marks.bold"
3227
+ [disabled]="!state().can.toggleBold"
3228
+ (onClick)="onCommand('toggleBold', $event)"
3229
+ ></tiptap-button>
3230
+ } @if (bubbleMenuConfig().italic) {
3231
+ <tiptap-button
3232
+ icon="format_italic"
3233
+ [title]="t().italic"
3234
+ [active]="state().marks.italic"
3235
+ [disabled]="!state().can.toggleItalic"
3236
+ (onClick)="onCommand('toggleItalic', $event)"
3237
+ ></tiptap-button>
3238
+ } @if (bubbleMenuConfig().underline) {
3239
+ <tiptap-button
3240
+ icon="format_underlined"
3241
+ [title]="t().underline"
3242
+ [active]="state().marks.underline"
3243
+ [disabled]="!state().can.toggleUnderline"
3244
+ (onClick)="onCommand('toggleUnderline', $event)"
3245
+ ></tiptap-button>
3246
+ } @if (bubbleMenuConfig().strike) {
3247
+ <tiptap-button
3248
+ icon="strikethrough_s"
3249
+ [title]="t().strike"
3250
+ [active]="state().marks.strike"
3251
+ [disabled]="!state().can.toggleStrike"
3252
+ (onClick)="onCommand('toggleStrike', $event)"
3253
+ ></tiptap-button>
3254
+ } @if (bubbleMenuConfig().code) {
3255
+ <tiptap-button
3256
+ icon="code"
3257
+ [title]="t().code"
3258
+ [active]="state().marks.code"
3259
+ [disabled]="!state().can.toggleCode"
3260
+ (onClick)="onCommand('toggleCode', $event)"
3261
+ ></tiptap-button>
3262
+ } @if (bubbleMenuConfig().superscript) {
3263
+ <tiptap-button
3264
+ icon="superscript"
3265
+ [title]="t().superscript"
3266
+ [active]="state().marks.superscript"
3267
+ [disabled]="!state().can.toggleSuperscript"
3268
+ (onClick)="onCommand('toggleSuperscript', $event)"
3269
+ ></tiptap-button>
3270
+ } @if (bubbleMenuConfig().subscript) {
3271
+ <tiptap-button
3272
+ icon="subscript"
3273
+ [title]="t().subscript"
3274
+ [active]="state().marks.subscript"
3275
+ [disabled]="!state().can.toggleSubscript"
3276
+ (onClick)="onCommand('toggleSubscript', $event)"
3277
+ ></tiptap-button>
3278
+ } @if (bubbleMenuConfig().highlight) {
3279
+ <tiptap-button
3280
+ icon="highlight"
3281
+ [title]="t().highlight"
3282
+ [active]="state().marks.highlight"
3283
+ [disabled]="!state().can.toggleHighlight"
3284
+ (onClick)="onCommand('toggleHighlight', $event)"
3285
+ ></tiptap-button>
3286
+ } @if (bubbleMenuConfig().highlightPicker) {
3287
+ <tiptap-color-picker
3288
+ mode="highlight"
3289
+ [editor]="editor()"
3290
+ [disabled]="!state().can.setHighlight"
3291
+ [anchorToText]="true"
3292
+ />
3293
+ } @if (bubbleMenuConfig().textColor) {
3294
+ <tiptap-color-picker
3295
+ mode="text"
3296
+ [editor]="editor()"
3297
+ [disabled]="!state().can.setColor"
3298
+ [anchorToText]="true"
3299
+ />
3300
+ } @if (bubbleMenuConfig().link) {
3301
+ <tiptap-button
3302
+ icon="link"
3303
+ [title]="t().link"
3304
+ [active]="state().marks.link"
3305
+ [disabled]="!state().can.toggleLink"
3306
+ (onClick)="onCommand('toggleLink', $event)"
3307
+ ></tiptap-button>
3308
+ }
3309
+ </div>
3295
3310
  `, 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", "disabled", "anchorToText"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3296
3311
  }
3297
3312
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapBubbleMenuComponent, decorators: [{
@@ -3304,96 +3319,96 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
3304
3319
  TiptapButtonComponent,
3305
3320
  TiptapColorPickerComponent,
3306
3321
  ],
3307
- template: `
3308
- <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3309
- @if (bubbleMenuConfig().bold) {
3310
- <tiptap-button
3311
- icon="format_bold"
3312
- [title]="t().bold"
3313
- [active]="state().marks.bold"
3314
- [disabled]="!state().can.toggleBold"
3315
- (onClick)="onCommand('toggleBold', $event)"
3316
- ></tiptap-button>
3317
- } @if (bubbleMenuConfig().italic) {
3318
- <tiptap-button
3319
- icon="format_italic"
3320
- [title]="t().italic"
3321
- [active]="state().marks.italic"
3322
- [disabled]="!state().can.toggleItalic"
3323
- (onClick)="onCommand('toggleItalic', $event)"
3324
- ></tiptap-button>
3325
- } @if (bubbleMenuConfig().underline) {
3326
- <tiptap-button
3327
- icon="format_underlined"
3328
- [title]="t().underline"
3329
- [active]="state().marks.underline"
3330
- [disabled]="!state().can.toggleUnderline"
3331
- (onClick)="onCommand('toggleUnderline', $event)"
3332
- ></tiptap-button>
3333
- } @if (bubbleMenuConfig().strike) {
3334
- <tiptap-button
3335
- icon="strikethrough_s"
3336
- [title]="t().strike"
3337
- [active]="state().marks.strike"
3338
- [disabled]="!state().can.toggleStrike"
3339
- (onClick)="onCommand('toggleStrike', $event)"
3340
- ></tiptap-button>
3341
- } @if (bubbleMenuConfig().code) {
3342
- <tiptap-button
3343
- icon="code"
3344
- [title]="t().code"
3345
- [active]="state().marks.code"
3346
- [disabled]="!state().can.toggleCode"
3347
- (onClick)="onCommand('toggleCode', $event)"
3348
- ></tiptap-button>
3349
- } @if (bubbleMenuConfig().superscript) {
3350
- <tiptap-button
3351
- icon="superscript"
3352
- [title]="t().superscript"
3353
- [active]="state().marks.superscript"
3354
- [disabled]="!state().can.toggleSuperscript"
3355
- (onClick)="onCommand('toggleSuperscript', $event)"
3356
- ></tiptap-button>
3357
- } @if (bubbleMenuConfig().subscript) {
3358
- <tiptap-button
3359
- icon="subscript"
3360
- [title]="t().subscript"
3361
- [active]="state().marks.subscript"
3362
- [disabled]="!state().can.toggleSubscript"
3363
- (onClick)="onCommand('toggleSubscript', $event)"
3364
- ></tiptap-button>
3365
- } @if (bubbleMenuConfig().highlight) {
3366
- <tiptap-button
3367
- icon="highlight"
3368
- [title]="t().highlight"
3369
- [active]="state().marks.highlight"
3370
- [disabled]="!state().can.toggleHighlight"
3371
- (onClick)="onCommand('toggleHighlight', $event)"
3372
- ></tiptap-button>
3373
- } @if (bubbleMenuConfig().highlightPicker) {
3374
- <tiptap-color-picker
3375
- mode="highlight"
3376
- [editor]="editor()"
3377
- [disabled]="!state().can.setHighlight"
3378
- [anchorToText]="true"
3379
- />
3380
- } @if (bubbleMenuConfig().textColor) {
3381
- <tiptap-color-picker
3382
- mode="text"
3383
- [editor]="editor()"
3384
- [disabled]="!state().can.setColor"
3385
- [anchorToText]="true"
3386
- />
3387
- } @if (bubbleMenuConfig().link) {
3388
- <tiptap-button
3389
- icon="link"
3390
- [title]="t().link"
3391
- [active]="state().marks.link"
3392
- [disabled]="!state().can.toggleLink"
3393
- (onClick)="onCommand('toggleLink', $event)"
3394
- ></tiptap-button>
3395
- }
3396
- </div>
3322
+ template: `
3323
+ <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3324
+ @if (bubbleMenuConfig().bold) {
3325
+ <tiptap-button
3326
+ icon="format_bold"
3327
+ [title]="t().bold"
3328
+ [active]="state().marks.bold"
3329
+ [disabled]="!state().can.toggleBold"
3330
+ (onClick)="onCommand('toggleBold', $event)"
3331
+ ></tiptap-button>
3332
+ } @if (bubbleMenuConfig().italic) {
3333
+ <tiptap-button
3334
+ icon="format_italic"
3335
+ [title]="t().italic"
3336
+ [active]="state().marks.italic"
3337
+ [disabled]="!state().can.toggleItalic"
3338
+ (onClick)="onCommand('toggleItalic', $event)"
3339
+ ></tiptap-button>
3340
+ } @if (bubbleMenuConfig().underline) {
3341
+ <tiptap-button
3342
+ icon="format_underlined"
3343
+ [title]="t().underline"
3344
+ [active]="state().marks.underline"
3345
+ [disabled]="!state().can.toggleUnderline"
3346
+ (onClick)="onCommand('toggleUnderline', $event)"
3347
+ ></tiptap-button>
3348
+ } @if (bubbleMenuConfig().strike) {
3349
+ <tiptap-button
3350
+ icon="strikethrough_s"
3351
+ [title]="t().strike"
3352
+ [active]="state().marks.strike"
3353
+ [disabled]="!state().can.toggleStrike"
3354
+ (onClick)="onCommand('toggleStrike', $event)"
3355
+ ></tiptap-button>
3356
+ } @if (bubbleMenuConfig().code) {
3357
+ <tiptap-button
3358
+ icon="code"
3359
+ [title]="t().code"
3360
+ [active]="state().marks.code"
3361
+ [disabled]="!state().can.toggleCode"
3362
+ (onClick)="onCommand('toggleCode', $event)"
3363
+ ></tiptap-button>
3364
+ } @if (bubbleMenuConfig().superscript) {
3365
+ <tiptap-button
3366
+ icon="superscript"
3367
+ [title]="t().superscript"
3368
+ [active]="state().marks.superscript"
3369
+ [disabled]="!state().can.toggleSuperscript"
3370
+ (onClick)="onCommand('toggleSuperscript', $event)"
3371
+ ></tiptap-button>
3372
+ } @if (bubbleMenuConfig().subscript) {
3373
+ <tiptap-button
3374
+ icon="subscript"
3375
+ [title]="t().subscript"
3376
+ [active]="state().marks.subscript"
3377
+ [disabled]="!state().can.toggleSubscript"
3378
+ (onClick)="onCommand('toggleSubscript', $event)"
3379
+ ></tiptap-button>
3380
+ } @if (bubbleMenuConfig().highlight) {
3381
+ <tiptap-button
3382
+ icon="highlight"
3383
+ [title]="t().highlight"
3384
+ [active]="state().marks.highlight"
3385
+ [disabled]="!state().can.toggleHighlight"
3386
+ (onClick)="onCommand('toggleHighlight', $event)"
3387
+ ></tiptap-button>
3388
+ } @if (bubbleMenuConfig().highlightPicker) {
3389
+ <tiptap-color-picker
3390
+ mode="highlight"
3391
+ [editor]="editor()"
3392
+ [disabled]="!state().can.setHighlight"
3393
+ [anchorToText]="true"
3394
+ />
3395
+ } @if (bubbleMenuConfig().textColor) {
3396
+ <tiptap-color-picker
3397
+ mode="text"
3398
+ [editor]="editor()"
3399
+ [disabled]="!state().can.setColor"
3400
+ [anchorToText]="true"
3401
+ />
3402
+ } @if (bubbleMenuConfig().link) {
3403
+ <tiptap-button
3404
+ icon="link"
3405
+ [title]="t().link"
3406
+ [active]="state().marks.link"
3407
+ [disabled]="!state().can.toggleLink"
3408
+ (onClick)="onCommand('toggleLink', $event)"
3409
+ ></tiptap-button>
3410
+ }
3411
+ </div>
3397
3412
  `,
3398
3413
  }]
3399
3414
  }] });
@@ -3412,6 +3427,7 @@ class TiptapImageBubbleMenuComponent extends TiptapBaseBubbleMenu {
3412
3427
  deleteImage: true,
3413
3428
  separator: true,
3414
3429
  });
3430
+ this.imageUpload = input({});
3415
3431
  this.imageBubbleMenuConfig = computed(() => ({
3416
3432
  changeImage: this.config().changeImage ?? true,
3417
3433
  resizeSmall: this.config().resizeSmall ?? true,
@@ -3493,12 +3509,7 @@ class TiptapImageBubbleMenuComponent extends TiptapBaseBubbleMenu {
3493
3509
  return;
3494
3510
  try {
3495
3511
  // Use dedicated method to replace an existing image
3496
- await this.imageService.selectAndReplaceImage(ed, {
3497
- quality: 0.8,
3498
- maxWidth: 1920,
3499
- maxHeight: 1080,
3500
- accept: "image/*",
3501
- });
3512
+ await this.imageService.selectAndReplaceImage(ed, this.imageUpload());
3502
3513
  }
3503
3514
  catch (error) {
3504
3515
  console.error(this.i18nService.imageUpload().uploadError, error);
@@ -3511,55 +3522,55 @@ class TiptapImageBubbleMenuComponent extends TiptapBaseBubbleMenu {
3511
3522
  }
3512
3523
  }
3513
3524
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapImageBubbleMenuComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3514
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapImageBubbleMenuComponent, isStandalone: true, selector: "tiptap-image-bubble-menu", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
3515
- <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3516
- @if (imageBubbleMenuConfig().changeImage) {
3517
- <tiptap-button
3518
- icon="drive_file_rename_outline"
3519
- [title]="t().changeImage"
3520
- (onClick)="onCommand('changeImage', $event)"
3521
- ></tiptap-button>
3522
- } @if (imageBubbleMenuConfig().separator && hasResizeButtons()) {
3523
- <tiptap-separator />
3524
- } @if (imageBubbleMenuConfig().resizeSmall) {
3525
- <tiptap-button
3526
- icon="crop_square"
3527
- iconSize="small"
3528
- [title]="t().resizeSmall"
3529
- (onClick)="onCommand('resizeSmall', $event)"
3530
- ></tiptap-button>
3531
- } @if (imageBubbleMenuConfig().resizeMedium) {
3532
- <tiptap-button
3533
- icon="crop_square"
3534
- iconSize="medium"
3535
- [title]="t().resizeMedium"
3536
- (onClick)="onCommand('resizeMedium', $event)"
3537
- ></tiptap-button>
3538
- } @if (imageBubbleMenuConfig().resizeLarge) {
3539
- <tiptap-button
3540
- icon="crop_square"
3541
- iconSize="large"
3542
- [title]="t().resizeLarge"
3543
- (onClick)="onCommand('resizeLarge', $event)"
3544
- ></tiptap-button>
3545
- } @if (imageBubbleMenuConfig().resizeOriginal) {
3546
- <tiptap-button
3547
- icon="photo_size_select_actual"
3548
- [title]="t().resizeOriginal"
3549
- (onClick)="onCommand('resizeOriginal', $event)"
3550
- ></tiptap-button>
3551
- } @if (imageBubbleMenuConfig().separator &&
3552
- imageBubbleMenuConfig().deleteImage) {
3553
- <tiptap-separator />
3554
- } @if (imageBubbleMenuConfig().deleteImage) {
3555
- <tiptap-button
3556
- icon="delete"
3557
- [title]="t().deleteImage"
3558
- variant="danger"
3559
- (onClick)="onCommand('deleteImage', $event)"
3560
- ></tiptap-button>
3561
- }
3562
- </div>
3525
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapImageBubbleMenuComponent, isStandalone: true, selector: "tiptap-image-bubble-menu", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
3526
+ <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3527
+ @if (imageBubbleMenuConfig().changeImage) {
3528
+ <tiptap-button
3529
+ icon="drive_file_rename_outline"
3530
+ [title]="t().changeImage"
3531
+ (onClick)="onCommand('changeImage', $event)"
3532
+ ></tiptap-button>
3533
+ } @if (imageBubbleMenuConfig().separator && hasResizeButtons()) {
3534
+ <tiptap-separator />
3535
+ } @if (imageBubbleMenuConfig().resizeSmall) {
3536
+ <tiptap-button
3537
+ icon="crop_square"
3538
+ iconSize="small"
3539
+ [title]="t().resizeSmall"
3540
+ (onClick)="onCommand('resizeSmall', $event)"
3541
+ ></tiptap-button>
3542
+ } @if (imageBubbleMenuConfig().resizeMedium) {
3543
+ <tiptap-button
3544
+ icon="crop_square"
3545
+ iconSize="medium"
3546
+ [title]="t().resizeMedium"
3547
+ (onClick)="onCommand('resizeMedium', $event)"
3548
+ ></tiptap-button>
3549
+ } @if (imageBubbleMenuConfig().resizeLarge) {
3550
+ <tiptap-button
3551
+ icon="crop_square"
3552
+ iconSize="large"
3553
+ [title]="t().resizeLarge"
3554
+ (onClick)="onCommand('resizeLarge', $event)"
3555
+ ></tiptap-button>
3556
+ } @if (imageBubbleMenuConfig().resizeOriginal) {
3557
+ <tiptap-button
3558
+ icon="photo_size_select_actual"
3559
+ [title]="t().resizeOriginal"
3560
+ (onClick)="onCommand('resizeOriginal', $event)"
3561
+ ></tiptap-button>
3562
+ } @if (imageBubbleMenuConfig().separator &&
3563
+ imageBubbleMenuConfig().deleteImage) {
3564
+ <tiptap-separator />
3565
+ } @if (imageBubbleMenuConfig().deleteImage) {
3566
+ <tiptap-button
3567
+ icon="delete"
3568
+ [title]="t().deleteImage"
3569
+ variant="danger"
3570
+ (onClick)="onCommand('deleteImage', $event)"
3571
+ ></tiptap-button>
3572
+ }
3573
+ </div>
3563
3574
  `, 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3564
3575
  }
3565
3576
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapImageBubbleMenuComponent, decorators: [{
@@ -3569,55 +3580,55 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
3569
3580
  standalone: true,
3570
3581
  changeDetection: ChangeDetectionStrategy.OnPush,
3571
3582
  imports: [TiptapButtonComponent, TiptapSeparatorComponent],
3572
- template: `
3573
- <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3574
- @if (imageBubbleMenuConfig().changeImage) {
3575
- <tiptap-button
3576
- icon="drive_file_rename_outline"
3577
- [title]="t().changeImage"
3578
- (onClick)="onCommand('changeImage', $event)"
3579
- ></tiptap-button>
3580
- } @if (imageBubbleMenuConfig().separator && hasResizeButtons()) {
3581
- <tiptap-separator />
3582
- } @if (imageBubbleMenuConfig().resizeSmall) {
3583
- <tiptap-button
3584
- icon="crop_square"
3585
- iconSize="small"
3586
- [title]="t().resizeSmall"
3587
- (onClick)="onCommand('resizeSmall', $event)"
3588
- ></tiptap-button>
3589
- } @if (imageBubbleMenuConfig().resizeMedium) {
3590
- <tiptap-button
3591
- icon="crop_square"
3592
- iconSize="medium"
3593
- [title]="t().resizeMedium"
3594
- (onClick)="onCommand('resizeMedium', $event)"
3595
- ></tiptap-button>
3596
- } @if (imageBubbleMenuConfig().resizeLarge) {
3597
- <tiptap-button
3598
- icon="crop_square"
3599
- iconSize="large"
3600
- [title]="t().resizeLarge"
3601
- (onClick)="onCommand('resizeLarge', $event)"
3602
- ></tiptap-button>
3603
- } @if (imageBubbleMenuConfig().resizeOriginal) {
3604
- <tiptap-button
3605
- icon="photo_size_select_actual"
3606
- [title]="t().resizeOriginal"
3607
- (onClick)="onCommand('resizeOriginal', $event)"
3608
- ></tiptap-button>
3609
- } @if (imageBubbleMenuConfig().separator &&
3610
- imageBubbleMenuConfig().deleteImage) {
3611
- <tiptap-separator />
3612
- } @if (imageBubbleMenuConfig().deleteImage) {
3613
- <tiptap-button
3614
- icon="delete"
3615
- [title]="t().deleteImage"
3616
- variant="danger"
3617
- (onClick)="onCommand('deleteImage', $event)"
3618
- ></tiptap-button>
3619
- }
3620
- </div>
3583
+ template: `
3584
+ <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3585
+ @if (imageBubbleMenuConfig().changeImage) {
3586
+ <tiptap-button
3587
+ icon="drive_file_rename_outline"
3588
+ [title]="t().changeImage"
3589
+ (onClick)="onCommand('changeImage', $event)"
3590
+ ></tiptap-button>
3591
+ } @if (imageBubbleMenuConfig().separator && hasResizeButtons()) {
3592
+ <tiptap-separator />
3593
+ } @if (imageBubbleMenuConfig().resizeSmall) {
3594
+ <tiptap-button
3595
+ icon="crop_square"
3596
+ iconSize="small"
3597
+ [title]="t().resizeSmall"
3598
+ (onClick)="onCommand('resizeSmall', $event)"
3599
+ ></tiptap-button>
3600
+ } @if (imageBubbleMenuConfig().resizeMedium) {
3601
+ <tiptap-button
3602
+ icon="crop_square"
3603
+ iconSize="medium"
3604
+ [title]="t().resizeMedium"
3605
+ (onClick)="onCommand('resizeMedium', $event)"
3606
+ ></tiptap-button>
3607
+ } @if (imageBubbleMenuConfig().resizeLarge) {
3608
+ <tiptap-button
3609
+ icon="crop_square"
3610
+ iconSize="large"
3611
+ [title]="t().resizeLarge"
3612
+ (onClick)="onCommand('resizeLarge', $event)"
3613
+ ></tiptap-button>
3614
+ } @if (imageBubbleMenuConfig().resizeOriginal) {
3615
+ <tiptap-button
3616
+ icon="photo_size_select_actual"
3617
+ [title]="t().resizeOriginal"
3618
+ (onClick)="onCommand('resizeOriginal', $event)"
3619
+ ></tiptap-button>
3620
+ } @if (imageBubbleMenuConfig().separator &&
3621
+ imageBubbleMenuConfig().deleteImage) {
3622
+ <tiptap-separator />
3623
+ } @if (imageBubbleMenuConfig().deleteImage) {
3624
+ <tiptap-button
3625
+ icon="delete"
3626
+ [title]="t().deleteImage"
3627
+ variant="danger"
3628
+ (onClick)="onCommand('deleteImage', $event)"
3629
+ ></tiptap-button>
3630
+ }
3631
+ </div>
3621
3632
  `,
3622
3633
  }]
3623
3634
  }] });
@@ -3695,94 +3706,94 @@ class TiptapTableBubbleMenuComponent extends TiptapBaseBubbleMenu {
3695
3706
  this.editorCommands.execute(editor, command);
3696
3707
  }
3697
3708
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapTableBubbleMenuComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3698
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapTableBubbleMenuComponent, isStandalone: true, selector: "tiptap-table-bubble-menu", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
3699
- <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3700
- <!-- Row actions -->
3701
- @if (config().addRowBefore !== false) {
3702
- <tiptap-button
3703
- icon="add_row_above"
3704
- [title]="t().addRowBefore"
3705
- [disabled]="!state().can.addRowBefore"
3706
- (onClick)="onCommand('addRowBefore', $event)"
3707
- ></tiptap-button>
3708
- } @if (config().addRowAfter !== false) {
3709
- <tiptap-button
3710
- icon="add_row_below"
3711
- [title]="t().addRowAfter"
3712
- [disabled]="!state().can.addRowAfter"
3713
- (onClick)="onCommand('addRowAfter', $event)"
3714
- ></tiptap-button>
3715
- } @if (config().deleteRow !== false) {
3716
- <tiptap-button
3717
- icon="delete"
3718
- [title]="t().deleteRow"
3719
- variant="danger"
3720
- [disabled]="!state().can.deleteRow"
3721
- (onClick)="onCommand('deleteRow', $event)"
3722
- ></tiptap-button>
3723
- } @if (config().separator !== false) {
3724
- <tiptap-separator />
3725
- }
3726
-
3727
- <!-- Column actions -->
3728
- @if (config().addColumnBefore !== false) {
3729
- <tiptap-button
3730
- icon="add_column_left"
3731
- [title]="t().addColumnBefore"
3732
- [disabled]="!state().can.addColumnBefore"
3733
- (onClick)="onCommand('addColumnBefore', $event)"
3734
- ></tiptap-button>
3735
- } @if (config().addColumnAfter !== false) {
3736
- <tiptap-button
3737
- icon="add_column_right"
3738
- [title]="t().addColumnAfter"
3739
- [disabled]="!state().can.addColumnAfter"
3740
- (onClick)="onCommand('addColumnAfter', $event)"
3741
- ></tiptap-button>
3742
- } @if (config().deleteColumn !== false) {
3743
- <tiptap-button
3744
- icon="delete"
3745
- [title]="t().deleteColumn"
3746
- variant="danger"
3747
- [disabled]="!state().can.deleteColumn"
3748
- (onClick)="onCommand('deleteColumn', $event)"
3749
- ></tiptap-button>
3750
- } @if (config().separator !== false) {
3751
- <tiptap-separator />
3752
- }
3753
-
3754
- <!-- Cell actions -->
3755
- @if (config().toggleHeaderRow !== false) {
3756
- <tiptap-button
3757
- icon="toolbar"
3758
- [title]="t().toggleHeaderRow"
3759
- [active]="state().nodes.isTableHeaderRow"
3760
- [disabled]="!state().can.toggleHeaderRow"
3761
- (onClick)="onCommand('toggleHeaderRow', $event)"
3762
- ></tiptap-button>
3763
- } @if (config().toggleHeaderColumn !== false) {
3764
- <tiptap-button
3765
- icon="dock_to_right"
3766
- [title]="t().toggleHeaderColumn"
3767
- [active]="state().nodes.isTableHeaderColumn"
3768
- [disabled]="!state().can.toggleHeaderColumn"
3769
- (onClick)="onCommand('toggleHeaderColumn', $event)"
3770
- ></tiptap-button>
3771
- } @if (config().separator !== false && config().deleteTable !== false) {
3772
- <tiptap-separator />
3773
- }
3774
-
3775
- <!-- Table actions -->
3776
- @if (config().deleteTable !== false) {
3777
- <tiptap-button
3778
- icon="delete_forever"
3779
- [title]="t().deleteTable"
3780
- variant="danger"
3781
- [disabled]="!state().can.deleteTable"
3782
- (onClick)="onCommand('deleteTable', $event)"
3783
- ></tiptap-button>
3784
- }
3785
- </div>
3709
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapTableBubbleMenuComponent, isStandalone: true, selector: "tiptap-table-bubble-menu", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
3710
+ <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3711
+ <!-- Row actions -->
3712
+ @if (config().addRowBefore !== false) {
3713
+ <tiptap-button
3714
+ icon="add_row_above"
3715
+ [title]="t().addRowBefore"
3716
+ [disabled]="!state().can.addRowBefore"
3717
+ (onClick)="onCommand('addRowBefore', $event)"
3718
+ ></tiptap-button>
3719
+ } @if (config().addRowAfter !== false) {
3720
+ <tiptap-button
3721
+ icon="add_row_below"
3722
+ [title]="t().addRowAfter"
3723
+ [disabled]="!state().can.addRowAfter"
3724
+ (onClick)="onCommand('addRowAfter', $event)"
3725
+ ></tiptap-button>
3726
+ } @if (config().deleteRow !== false) {
3727
+ <tiptap-button
3728
+ icon="delete"
3729
+ [title]="t().deleteRow"
3730
+ variant="danger"
3731
+ [disabled]="!state().can.deleteRow"
3732
+ (onClick)="onCommand('deleteRow', $event)"
3733
+ ></tiptap-button>
3734
+ } @if (config().separator !== false) {
3735
+ <tiptap-separator />
3736
+ }
3737
+
3738
+ <!-- Column actions -->
3739
+ @if (config().addColumnBefore !== false) {
3740
+ <tiptap-button
3741
+ icon="add_column_left"
3742
+ [title]="t().addColumnBefore"
3743
+ [disabled]="!state().can.addColumnBefore"
3744
+ (onClick)="onCommand('addColumnBefore', $event)"
3745
+ ></tiptap-button>
3746
+ } @if (config().addColumnAfter !== false) {
3747
+ <tiptap-button
3748
+ icon="add_column_right"
3749
+ [title]="t().addColumnAfter"
3750
+ [disabled]="!state().can.addColumnAfter"
3751
+ (onClick)="onCommand('addColumnAfter', $event)"
3752
+ ></tiptap-button>
3753
+ } @if (config().deleteColumn !== false) {
3754
+ <tiptap-button
3755
+ icon="delete"
3756
+ [title]="t().deleteColumn"
3757
+ variant="danger"
3758
+ [disabled]="!state().can.deleteColumn"
3759
+ (onClick)="onCommand('deleteColumn', $event)"
3760
+ ></tiptap-button>
3761
+ } @if (config().separator !== false) {
3762
+ <tiptap-separator />
3763
+ }
3764
+
3765
+ <!-- Cell actions -->
3766
+ @if (config().toggleHeaderRow !== false) {
3767
+ <tiptap-button
3768
+ icon="toolbar"
3769
+ [title]="t().toggleHeaderRow"
3770
+ [active]="state().nodes.isTableHeaderRow"
3771
+ [disabled]="!state().can.toggleHeaderRow"
3772
+ (onClick)="onCommand('toggleHeaderRow', $event)"
3773
+ ></tiptap-button>
3774
+ } @if (config().toggleHeaderColumn !== false) {
3775
+ <tiptap-button
3776
+ icon="dock_to_right"
3777
+ [title]="t().toggleHeaderColumn"
3778
+ [active]="state().nodes.isTableHeaderColumn"
3779
+ [disabled]="!state().can.toggleHeaderColumn"
3780
+ (onClick)="onCommand('toggleHeaderColumn', $event)"
3781
+ ></tiptap-button>
3782
+ } @if (config().separator !== false && config().deleteTable !== false) {
3783
+ <tiptap-separator />
3784
+ }
3785
+
3786
+ <!-- Table actions -->
3787
+ @if (config().deleteTable !== false) {
3788
+ <tiptap-button
3789
+ icon="delete_forever"
3790
+ [title]="t().deleteTable"
3791
+ variant="danger"
3792
+ [disabled]="!state().can.deleteTable"
3793
+ (onClick)="onCommand('deleteTable', $event)"
3794
+ ></tiptap-button>
3795
+ }
3796
+ </div>
3786
3797
  `, 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3787
3798
  }
3788
3799
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapTableBubbleMenuComponent, decorators: [{
@@ -3792,94 +3803,94 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
3792
3803
  standalone: true,
3793
3804
  changeDetection: ChangeDetectionStrategy.OnPush,
3794
3805
  imports: [CommonModule, TiptapButtonComponent, TiptapSeparatorComponent],
3795
- template: `
3796
- <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3797
- <!-- Row actions -->
3798
- @if (config().addRowBefore !== false) {
3799
- <tiptap-button
3800
- icon="add_row_above"
3801
- [title]="t().addRowBefore"
3802
- [disabled]="!state().can.addRowBefore"
3803
- (onClick)="onCommand('addRowBefore', $event)"
3804
- ></tiptap-button>
3805
- } @if (config().addRowAfter !== false) {
3806
- <tiptap-button
3807
- icon="add_row_below"
3808
- [title]="t().addRowAfter"
3809
- [disabled]="!state().can.addRowAfter"
3810
- (onClick)="onCommand('addRowAfter', $event)"
3811
- ></tiptap-button>
3812
- } @if (config().deleteRow !== false) {
3813
- <tiptap-button
3814
- icon="delete"
3815
- [title]="t().deleteRow"
3816
- variant="danger"
3817
- [disabled]="!state().can.deleteRow"
3818
- (onClick)="onCommand('deleteRow', $event)"
3819
- ></tiptap-button>
3820
- } @if (config().separator !== false) {
3821
- <tiptap-separator />
3822
- }
3823
-
3824
- <!-- Column actions -->
3825
- @if (config().addColumnBefore !== false) {
3826
- <tiptap-button
3827
- icon="add_column_left"
3828
- [title]="t().addColumnBefore"
3829
- [disabled]="!state().can.addColumnBefore"
3830
- (onClick)="onCommand('addColumnBefore', $event)"
3831
- ></tiptap-button>
3832
- } @if (config().addColumnAfter !== false) {
3833
- <tiptap-button
3834
- icon="add_column_right"
3835
- [title]="t().addColumnAfter"
3836
- [disabled]="!state().can.addColumnAfter"
3837
- (onClick)="onCommand('addColumnAfter', $event)"
3838
- ></tiptap-button>
3839
- } @if (config().deleteColumn !== false) {
3840
- <tiptap-button
3841
- icon="delete"
3842
- [title]="t().deleteColumn"
3843
- variant="danger"
3844
- [disabled]="!state().can.deleteColumn"
3845
- (onClick)="onCommand('deleteColumn', $event)"
3846
- ></tiptap-button>
3847
- } @if (config().separator !== false) {
3848
- <tiptap-separator />
3849
- }
3850
-
3851
- <!-- Cell actions -->
3852
- @if (config().toggleHeaderRow !== false) {
3853
- <tiptap-button
3854
- icon="toolbar"
3855
- [title]="t().toggleHeaderRow"
3856
- [active]="state().nodes.isTableHeaderRow"
3857
- [disabled]="!state().can.toggleHeaderRow"
3858
- (onClick)="onCommand('toggleHeaderRow', $event)"
3859
- ></tiptap-button>
3860
- } @if (config().toggleHeaderColumn !== false) {
3861
- <tiptap-button
3862
- icon="dock_to_right"
3863
- [title]="t().toggleHeaderColumn"
3864
- [active]="state().nodes.isTableHeaderColumn"
3865
- [disabled]="!state().can.toggleHeaderColumn"
3866
- (onClick)="onCommand('toggleHeaderColumn', $event)"
3867
- ></tiptap-button>
3868
- } @if (config().separator !== false && config().deleteTable !== false) {
3869
- <tiptap-separator />
3870
- }
3871
-
3872
- <!-- Table actions -->
3873
- @if (config().deleteTable !== false) {
3874
- <tiptap-button
3875
- icon="delete_forever"
3876
- [title]="t().deleteTable"
3877
- variant="danger"
3878
- [disabled]="!state().can.deleteTable"
3879
- (onClick)="onCommand('deleteTable', $event)"
3880
- ></tiptap-button>
3881
- }
3882
- </div>
3806
+ template: `
3807
+ <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3808
+ <!-- Row actions -->
3809
+ @if (config().addRowBefore !== false) {
3810
+ <tiptap-button
3811
+ icon="add_row_above"
3812
+ [title]="t().addRowBefore"
3813
+ [disabled]="!state().can.addRowBefore"
3814
+ (onClick)="onCommand('addRowBefore', $event)"
3815
+ ></tiptap-button>
3816
+ } @if (config().addRowAfter !== false) {
3817
+ <tiptap-button
3818
+ icon="add_row_below"
3819
+ [title]="t().addRowAfter"
3820
+ [disabled]="!state().can.addRowAfter"
3821
+ (onClick)="onCommand('addRowAfter', $event)"
3822
+ ></tiptap-button>
3823
+ } @if (config().deleteRow !== false) {
3824
+ <tiptap-button
3825
+ icon="delete"
3826
+ [title]="t().deleteRow"
3827
+ variant="danger"
3828
+ [disabled]="!state().can.deleteRow"
3829
+ (onClick)="onCommand('deleteRow', $event)"
3830
+ ></tiptap-button>
3831
+ } @if (config().separator !== false) {
3832
+ <tiptap-separator />
3833
+ }
3834
+
3835
+ <!-- Column actions -->
3836
+ @if (config().addColumnBefore !== false) {
3837
+ <tiptap-button
3838
+ icon="add_column_left"
3839
+ [title]="t().addColumnBefore"
3840
+ [disabled]="!state().can.addColumnBefore"
3841
+ (onClick)="onCommand('addColumnBefore', $event)"
3842
+ ></tiptap-button>
3843
+ } @if (config().addColumnAfter !== false) {
3844
+ <tiptap-button
3845
+ icon="add_column_right"
3846
+ [title]="t().addColumnAfter"
3847
+ [disabled]="!state().can.addColumnAfter"
3848
+ (onClick)="onCommand('addColumnAfter', $event)"
3849
+ ></tiptap-button>
3850
+ } @if (config().deleteColumn !== false) {
3851
+ <tiptap-button
3852
+ icon="delete"
3853
+ [title]="t().deleteColumn"
3854
+ variant="danger"
3855
+ [disabled]="!state().can.deleteColumn"
3856
+ (onClick)="onCommand('deleteColumn', $event)"
3857
+ ></tiptap-button>
3858
+ } @if (config().separator !== false) {
3859
+ <tiptap-separator />
3860
+ }
3861
+
3862
+ <!-- Cell actions -->
3863
+ @if (config().toggleHeaderRow !== false) {
3864
+ <tiptap-button
3865
+ icon="toolbar"
3866
+ [title]="t().toggleHeaderRow"
3867
+ [active]="state().nodes.isTableHeaderRow"
3868
+ [disabled]="!state().can.toggleHeaderRow"
3869
+ (onClick)="onCommand('toggleHeaderRow', $event)"
3870
+ ></tiptap-button>
3871
+ } @if (config().toggleHeaderColumn !== false) {
3872
+ <tiptap-button
3873
+ icon="dock_to_right"
3874
+ [title]="t().toggleHeaderColumn"
3875
+ [active]="state().nodes.isTableHeaderColumn"
3876
+ [disabled]="!state().can.toggleHeaderColumn"
3877
+ (onClick)="onCommand('toggleHeaderColumn', $event)"
3878
+ ></tiptap-button>
3879
+ } @if (config().separator !== false && config().deleteTable !== false) {
3880
+ <tiptap-separator />
3881
+ }
3882
+
3883
+ <!-- Table actions -->
3884
+ @if (config().deleteTable !== false) {
3885
+ <tiptap-button
3886
+ icon="delete_forever"
3887
+ [title]="t().deleteTable"
3888
+ variant="danger"
3889
+ [disabled]="!state().can.deleteTable"
3890
+ (onClick)="onCommand('deleteTable', $event)"
3891
+ ></tiptap-button>
3892
+ }
3893
+ </div>
3883
3894
  `,
3884
3895
  }]
3885
3896
  }] });
@@ -3952,25 +3963,25 @@ class TiptapCellBubbleMenuComponent extends TiptapBaseBubbleMenu {
3952
3963
  this.editorCommands.execute(editor, command);
3953
3964
  }
3954
3965
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapCellBubbleMenuComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3955
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapCellBubbleMenuComponent, isStandalone: true, selector: "tiptap-cell-bubble-menu", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
3956
- <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3957
- <!-- Cell specific actions -->
3958
- @if (config().mergeCells !== false && !state().selection.isSingleCell) {
3959
- <tiptap-button
3960
- icon="cell_merge"
3961
- [title]="i18n().table().mergeCells"
3962
- [disabled]="!state().can.mergeCells"
3963
- (onClick)="onCommand('mergeCells', $event)"
3964
- ></tiptap-button>
3965
- } @if (config().splitCell !== false && state().selection.isSingleCell) {
3966
- <tiptap-button
3967
- icon="split_scene"
3968
- [title]="i18n().table().splitCell"
3969
- [disabled]="!state().can.splitCell"
3970
- (onClick)="onCommand('splitCell', $event)"
3971
- ></tiptap-button>
3972
- }
3973
- </div>
3966
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapCellBubbleMenuComponent, isStandalone: true, selector: "tiptap-cell-bubble-menu", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
3967
+ <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3968
+ <!-- Cell specific actions -->
3969
+ @if (config().mergeCells !== false && !state().selection.isSingleCell) {
3970
+ <tiptap-button
3971
+ icon="cell_merge"
3972
+ [title]="i18n().table().mergeCells"
3973
+ [disabled]="!state().can.mergeCells"
3974
+ (onClick)="onCommand('mergeCells', $event)"
3975
+ ></tiptap-button>
3976
+ } @if (config().splitCell !== false && state().selection.isSingleCell) {
3977
+ <tiptap-button
3978
+ icon="split_scene"
3979
+ [title]="i18n().table().splitCell"
3980
+ [disabled]="!state().can.splitCell"
3981
+ (onClick)="onCommand('splitCell', $event)"
3982
+ ></tiptap-button>
3983
+ }
3984
+ </div>
3974
3985
  `, 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3975
3986
  }
3976
3987
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapCellBubbleMenuComponent, decorators: [{
@@ -3980,25 +3991,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
3980
3991
  standalone: true,
3981
3992
  changeDetection: ChangeDetectionStrategy.OnPush,
3982
3993
  imports: [CommonModule, TiptapButtonComponent],
3983
- template: `
3984
- <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3985
- <!-- Cell specific actions -->
3986
- @if (config().mergeCells !== false && !state().selection.isSingleCell) {
3987
- <tiptap-button
3988
- icon="cell_merge"
3989
- [title]="i18n().table().mergeCells"
3990
- [disabled]="!state().can.mergeCells"
3991
- (onClick)="onCommand('mergeCells', $event)"
3992
- ></tiptap-button>
3993
- } @if (config().splitCell !== false && state().selection.isSingleCell) {
3994
- <tiptap-button
3995
- icon="split_scene"
3996
- [title]="i18n().table().splitCell"
3997
- [disabled]="!state().can.splitCell"
3998
- (onClick)="onCommand('splitCell', $event)"
3999
- ></tiptap-button>
4000
- }
4001
- </div>
3994
+ template: `
3995
+ <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
3996
+ <!-- Cell specific actions -->
3997
+ @if (config().mergeCells !== false && !state().selection.isSingleCell) {
3998
+ <tiptap-button
3999
+ icon="cell_merge"
4000
+ [title]="i18n().table().mergeCells"
4001
+ [disabled]="!state().can.mergeCells"
4002
+ (onClick)="onCommand('mergeCells', $event)"
4003
+ ></tiptap-button>
4004
+ } @if (config().splitCell !== false && state().selection.isSingleCell) {
4005
+ <tiptap-button
4006
+ icon="split_scene"
4007
+ [title]="i18n().table().splitCell"
4008
+ [disabled]="!state().can.splitCell"
4009
+ (onClick)="onCommand('splitCell', $event)"
4010
+ ></tiptap-button>
4011
+ }
4012
+ </div>
4002
4013
  `,
4003
4014
  }]
4004
4015
  }] });
@@ -4214,108 +4225,108 @@ class TiptapLinkBubbleMenuComponent {
4214
4225
  this.hideTippy();
4215
4226
  }
4216
4227
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapLinkBubbleMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4217
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.0", type: TiptapLinkBubbleMenuComponent, isStandalone: true, selector: "tiptap-link-bubble-menu", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "linkInput", first: true, predicate: ["linkInput"], descendants: true }, { propertyName: "menuRef", first: true, predicate: ["menuRef"], descendants: true }], ngImport: i0, template: `
4218
- <div
4219
- #menuRef
4220
- class="bubble-menu"
4221
- (mousedown)="onMouseDown($event)"
4222
- (click)="$event.stopPropagation()"
4223
- >
4224
- <div class="link-input-row">
4225
- <div class="url-input-container">
4226
- <span class="material-symbols-outlined icon-link">link</span>
4227
- <input
4228
- #linkInput
4229
- type="text"
4230
- class="url-field"
4231
- [placeholder]="t().linkUrl"
4232
- [ngModel]="editUrl()"
4233
- (ngModelChange)="editUrl.set($event)"
4234
- (focus)="onFocus()"
4235
- (blur)="onBlur()"
4236
- (keydown.enter)="onApply($event)"
4237
- (keydown.escape)="onCancel($event)"
4238
- />
4239
- </div>
4240
-
4241
- <div class="action-buttons">
4242
- <tiptap-button
4243
- icon="check"
4244
- [title]="common().apply"
4245
- color="var(--ate-primary)"
4246
- [disabled]="!editUrl().trim()"
4247
- (onClick)="onApply($event)"
4248
- ></tiptap-button>
4249
- <tiptap-button
4250
- icon="open_in_new"
4251
- [title]="t().openLink"
4252
- [disabled]="!currentUrl()"
4253
- (onClick)="onOpenLink($event)"
4254
- ></tiptap-button>
4255
- <tiptap-separator />
4256
- <tiptap-button
4257
- icon="link_off"
4258
- [title]="t().removeLink"
4259
- variant="danger"
4260
- [disabled]="!currentUrl()"
4261
- (onClick)="onRemove($event)"
4262
- ></tiptap-button>
4263
- </div>
4264
- </div>
4265
- </div>
4228
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.0", type: TiptapLinkBubbleMenuComponent, isStandalone: true, selector: "tiptap-link-bubble-menu", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "linkInput", first: true, predicate: ["linkInput"], descendants: true }, { propertyName: "menuRef", first: true, predicate: ["menuRef"], descendants: true }], ngImport: i0, template: `
4229
+ <div
4230
+ #menuRef
4231
+ class="bubble-menu"
4232
+ (mousedown)="onMouseDown($event)"
4233
+ (click)="$event.stopPropagation()"
4234
+ >
4235
+ <div class="link-input-row">
4236
+ <div class="url-input-container">
4237
+ <span class="material-symbols-outlined icon-link">link</span>
4238
+ <input
4239
+ #linkInput
4240
+ type="text"
4241
+ class="url-field"
4242
+ [placeholder]="t().linkUrl"
4243
+ [ngModel]="editUrl()"
4244
+ (ngModelChange)="editUrl.set($event)"
4245
+ (focus)="onFocus()"
4246
+ (blur)="onBlur()"
4247
+ (keydown.enter)="onApply($event)"
4248
+ (keydown.escape)="onCancel($event)"
4249
+ />
4250
+ </div>
4251
+
4252
+ <div class="action-buttons">
4253
+ <tiptap-button
4254
+ icon="check"
4255
+ [title]="common().apply"
4256
+ color="var(--ate-primary)"
4257
+ [disabled]="!editUrl().trim()"
4258
+ (onClick)="onApply($event)"
4259
+ ></tiptap-button>
4260
+ <tiptap-button
4261
+ icon="open_in_new"
4262
+ [title]="t().openLink"
4263
+ [disabled]="!currentUrl()"
4264
+ (onClick)="onOpenLink($event)"
4265
+ ></tiptap-button>
4266
+ <tiptap-separator />
4267
+ <tiptap-button
4268
+ icon="link_off"
4269
+ [title]="t().removeLink"
4270
+ variant="danger"
4271
+ [disabled]="!currentUrl()"
4272
+ (onClick)="onRemove($event)"
4273
+ ></tiptap-button>
4274
+ </div>
4275
+ </div>
4276
+ </div>
4266
4277
  `, isInline: true, styles: [".link-input-row{display:flex;align-items:center;gap:6px}.url-input-container{flex:1;display:flex;align-items:center;background:var(--ate-surface-secondary, #f8fafc);border:1px solid var(--ate-border, #e2e8f0);border-radius:8px;padding:0 10px;height:32px;transition:all .15s ease}.url-input-container:focus-within{border-color:var(--ate-primary, #3b82f6);background:var(--ate-surface, #ffffff);box-shadow:0 0 0 2px var(--ate-primary-light, rgba(59, 130, 246, .1))}.icon-link{font-size:16px;color:var(--ate-text-muted, #94a3b8);margin-right:6px}.url-field{background:transparent;border:none;outline:none;color:var(--ate-text, #1e293b);font-size:13px;width:100%;font-family:inherit}.action-buttons{display:flex;align-items:center;gap:2px}\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: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4267
4278
  }
4268
4279
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapLinkBubbleMenuComponent, decorators: [{
4269
4280
  type: Component,
4270
- args: [{ selector: "tiptap-link-bubble-menu", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TiptapButtonComponent, TiptapSeparatorComponent, FormsModule], template: `
4271
- <div
4272
- #menuRef
4273
- class="bubble-menu"
4274
- (mousedown)="onMouseDown($event)"
4275
- (click)="$event.stopPropagation()"
4276
- >
4277
- <div class="link-input-row">
4278
- <div class="url-input-container">
4279
- <span class="material-symbols-outlined icon-link">link</span>
4280
- <input
4281
- #linkInput
4282
- type="text"
4283
- class="url-field"
4284
- [placeholder]="t().linkUrl"
4285
- [ngModel]="editUrl()"
4286
- (ngModelChange)="editUrl.set($event)"
4287
- (focus)="onFocus()"
4288
- (blur)="onBlur()"
4289
- (keydown.enter)="onApply($event)"
4290
- (keydown.escape)="onCancel($event)"
4291
- />
4292
- </div>
4293
-
4294
- <div class="action-buttons">
4295
- <tiptap-button
4296
- icon="check"
4297
- [title]="common().apply"
4298
- color="var(--ate-primary)"
4299
- [disabled]="!editUrl().trim()"
4300
- (onClick)="onApply($event)"
4301
- ></tiptap-button>
4302
- <tiptap-button
4303
- icon="open_in_new"
4304
- [title]="t().openLink"
4305
- [disabled]="!currentUrl()"
4306
- (onClick)="onOpenLink($event)"
4307
- ></tiptap-button>
4308
- <tiptap-separator />
4309
- <tiptap-button
4310
- icon="link_off"
4311
- [title]="t().removeLink"
4312
- variant="danger"
4313
- [disabled]="!currentUrl()"
4314
- (onClick)="onRemove($event)"
4315
- ></tiptap-button>
4316
- </div>
4317
- </div>
4318
- </div>
4281
+ args: [{ selector: "tiptap-link-bubble-menu", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TiptapButtonComponent, TiptapSeparatorComponent, FormsModule], template: `
4282
+ <div
4283
+ #menuRef
4284
+ class="bubble-menu"
4285
+ (mousedown)="onMouseDown($event)"
4286
+ (click)="$event.stopPropagation()"
4287
+ >
4288
+ <div class="link-input-row">
4289
+ <div class="url-input-container">
4290
+ <span class="material-symbols-outlined icon-link">link</span>
4291
+ <input
4292
+ #linkInput
4293
+ type="text"
4294
+ class="url-field"
4295
+ [placeholder]="t().linkUrl"
4296
+ [ngModel]="editUrl()"
4297
+ (ngModelChange)="editUrl.set($event)"
4298
+ (focus)="onFocus()"
4299
+ (blur)="onBlur()"
4300
+ (keydown.enter)="onApply($event)"
4301
+ (keydown.escape)="onCancel($event)"
4302
+ />
4303
+ </div>
4304
+
4305
+ <div class="action-buttons">
4306
+ <tiptap-button
4307
+ icon="check"
4308
+ [title]="common().apply"
4309
+ color="var(--ate-primary)"
4310
+ [disabled]="!editUrl().trim()"
4311
+ (onClick)="onApply($event)"
4312
+ ></tiptap-button>
4313
+ <tiptap-button
4314
+ icon="open_in_new"
4315
+ [title]="t().openLink"
4316
+ [disabled]="!currentUrl()"
4317
+ (onClick)="onOpenLink($event)"
4318
+ ></tiptap-button>
4319
+ <tiptap-separator />
4320
+ <tiptap-button
4321
+ icon="link_off"
4322
+ [title]="t().removeLink"
4323
+ variant="danger"
4324
+ [disabled]="!currentUrl()"
4325
+ (onClick)="onRemove($event)"
4326
+ ></tiptap-button>
4327
+ </div>
4328
+ </div>
4329
+ </div>
4319
4330
  `, styles: [".link-input-row{display:flex;align-items:center;gap:6px}.url-input-container{flex:1;display:flex;align-items:center;background:var(--ate-surface-secondary, #f8fafc);border:1px solid var(--ate-border, #e2e8f0);border-radius:8px;padding:0 10px;height:32px;transition:all .15s ease}.url-input-container:focus-within{border-color:var(--ate-primary, #3b82f6);background:var(--ate-surface, #ffffff);box-shadow:0 0 0 2px var(--ate-primary-light, rgba(59, 130, 246, .1))}.icon-link{font-size:16px;color:var(--ate-text-muted, #94a3b8);margin-right:6px}.url-field{background:transparent;border:none;outline:none;color:var(--ate-text, #1e293b);font-size:13px;width:100%;font-family:inherit}.action-buttons{display:flex;align-items:center;gap:2px}\n"] }]
4320
4331
  }], ctorParameters: () => [], propDecorators: { linkInput: [{
4321
4332
  type: ViewChild,
@@ -4576,174 +4587,174 @@ class TiptapColorBubbleMenuComponent {
4576
4587
  }, 150);
4577
4588
  }
4578
4589
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapColorBubbleMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4579
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapColorBubbleMenuComponent, isStandalone: true, selector: "tiptap-color-bubble-menu", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "colorInputRef", first: true, predicate: ["colorInput"], descendants: true, isSignal: true }, { propertyName: "menuRef", first: true, predicate: ["menuRef"], descendants: true }], ngImport: i0, template: `
4580
- <div
4581
- #menuRef
4582
- class="bubble-menu color-bubble-menu"
4583
- (mousedown)="onMouseDown($event)"
4584
- (click)="$event.stopPropagation()"
4585
- >
4586
- <div class="color-picker-container">
4587
- <div class="dropdown-row presets">
4588
- <div class="color-grid">
4589
- @for (color of presets; track color) {
4590
- <tiptap-button
4591
- class="color-swatch-btn"
4592
- size="small"
4593
- [title]="color"
4594
- [active]="isColorActive(color)"
4595
- [backgroundColor]="color"
4596
- (onClick)="applyColor(color, true, $event)"
4597
- ></tiptap-button>
4598
- }
4599
- </div>
4600
- </div>
4601
-
4602
- <div class="dropdown-row controls">
4603
- <div class="hex-input-wrapper">
4604
- <span class="hex-hash">#</span>
4605
- <input
4606
- #hexInput
4607
- type="text"
4608
- class="hex-input"
4609
- [value]="hexValue()"
4610
- [attr.aria-label]="t().customColor"
4611
- (input)="onHexInput($event)"
4612
- (change)="onHexChange($event)"
4613
- (keydown.enter)="onApply($event)"
4614
- (focus)="onFocus()"
4615
- (blur)="onBlur()"
4616
- maxlength="6"
4617
- placeholder="000000"
4618
- />
4619
- </div>
4620
-
4621
- <div class="native-trigger-wrapper">
4622
- <tiptap-button
4623
- class="btn-native-picker-trigger"
4624
- icon="colorize"
4625
- [title]="t().customColor"
4626
- [backgroundColor]="currentColor()"
4627
- (onClick)="triggerNativePicker($event)"
4628
- ></tiptap-button>
4629
- <input
4630
- #colorInput
4631
- type="color"
4632
- class="hidden-native-input"
4633
- [value]="currentColor()"
4634
- [attr.aria-label]="t().customColor"
4635
- (input)="onNativeInput($event)"
4636
- (change)="onNativeChange($event)"
4637
- (focus)="onFocus()"
4638
- (blur)="onBlur()"
4639
- />
4640
- </div>
4641
-
4642
- <tiptap-button
4643
- icon="check"
4644
- [title]="common().apply"
4645
- color="var(--ate-primary)"
4646
- (onClick)="onApply($event)"
4647
- ></tiptap-button>
4648
-
4649
- <tiptap-separator />
4650
-
4651
- <tiptap-button
4652
- icon="format_color_reset"
4653
- [title]="t().clear"
4654
- variant="danger"
4655
- (onClick)="onClearColor($event)"
4656
- ></tiptap-button>
4657
- </div>
4658
-
4659
- </div>
4660
- </div>
4590
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapColorBubbleMenuComponent, isStandalone: true, selector: "tiptap-color-bubble-menu", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "colorInputRef", first: true, predicate: ["colorInput"], descendants: true, isSignal: true }, { propertyName: "menuRef", first: true, predicate: ["menuRef"], descendants: true }], ngImport: i0, template: `
4591
+ <div
4592
+ #menuRef
4593
+ class="bubble-menu color-bubble-menu"
4594
+ (mousedown)="onMouseDown($event)"
4595
+ (click)="$event.stopPropagation()"
4596
+ >
4597
+ <div class="color-picker-container">
4598
+ <div class="dropdown-row presets">
4599
+ <div class="color-grid">
4600
+ @for (color of presets; track color) {
4601
+ <tiptap-button
4602
+ class="color-swatch-btn"
4603
+ size="small"
4604
+ [title]="color"
4605
+ [active]="isColorActive(color)"
4606
+ [backgroundColor]="color"
4607
+ (onClick)="applyColor(color, true, $event)"
4608
+ ></tiptap-button>
4609
+ }
4610
+ </div>
4611
+ </div>
4612
+
4613
+ <div class="dropdown-row controls">
4614
+ <div class="hex-input-wrapper">
4615
+ <span class="hex-hash">#</span>
4616
+ <input
4617
+ #hexInput
4618
+ type="text"
4619
+ class="hex-input"
4620
+ [value]="hexValue()"
4621
+ [attr.aria-label]="t().customColor"
4622
+ (input)="onHexInput($event)"
4623
+ (change)="onHexChange($event)"
4624
+ (keydown.enter)="onApply($event)"
4625
+ (focus)="onFocus()"
4626
+ (blur)="onBlur()"
4627
+ maxlength="6"
4628
+ placeholder="000000"
4629
+ />
4630
+ </div>
4631
+
4632
+ <div class="native-trigger-wrapper">
4633
+ <tiptap-button
4634
+ class="btn-native-picker-trigger"
4635
+ icon="colorize"
4636
+ [title]="t().customColor"
4637
+ [backgroundColor]="currentColor()"
4638
+ (onClick)="triggerNativePicker($event)"
4639
+ ></tiptap-button>
4640
+ <input
4641
+ #colorInput
4642
+ type="color"
4643
+ class="hidden-native-input"
4644
+ [value]="currentColor()"
4645
+ [attr.aria-label]="t().customColor"
4646
+ (input)="onNativeInput($event)"
4647
+ (change)="onNativeChange($event)"
4648
+ (focus)="onFocus()"
4649
+ (blur)="onBlur()"
4650
+ />
4651
+ </div>
4652
+
4653
+ <tiptap-button
4654
+ icon="check"
4655
+ [title]="common().apply"
4656
+ color="var(--ate-primary)"
4657
+ (onClick)="onApply($event)"
4658
+ ></tiptap-button>
4659
+
4660
+ <tiptap-separator />
4661
+
4662
+ <tiptap-button
4663
+ icon="format_color_reset"
4664
+ [title]="t().clear"
4665
+ variant="danger"
4666
+ (onClick)="onClearColor($event)"
4667
+ ></tiptap-button>
4668
+ </div>
4669
+
4670
+ </div>
4671
+ </div>
4661
4672
  `, isInline: true, styles: [".color-picker-container{display:flex;flex-direction:column;gap:8px}.dropdown-row{display:flex;align-items:center;width:100%}.dropdown-row.presets{justify-content:center}.dropdown-row.controls{gap:8px;justify-content:space-between;padding-top:4px;border-top:1px solid var(--ate-border, #e2e8f0)}.color-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:4px;width:100%}:host ::ng-deep .color-swatch-btn .tiptap-button{width:100%;aspect-ratio:1;height:auto;border-radius:4px;border:1px solid rgba(0,0,0,.1);padding:0}:host ::ng-deep .color-swatch-btn .tiptap-button.is-active{border-color:var(--ate-primary, #3b82f6);box-shadow:0 0 0 2px #3b82f64d}:host ::ng-deep .btn-native-picker-trigger .tiptap-button{color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.2)}.divider-v{width:1px;height:24px;background:var(--ate-border, #e2e8f0)}.hex-input-wrapper{flex:1;display:flex;align-items:center;background:var(--ate-surface-secondary, #f8fafc);border:1px solid var(--ate-border, #e2e8f0);border-radius:8px;padding:0 10px;height:32px;transition:border-color .15s ease}.hex-input-wrapper:focus-within{border-color:var(--ate-primary, #3b82f6);background:var(--ate-menu-bg, #ffffff)}.hex-hash{color:var(--ate-text-muted, #94a3b8);font-family:monospace;font-size:.875rem}.hex-input{background:transparent;border:none;outline:none;color:var(--ate-text, #1e293b);font-family:monospace;font-size:.875rem;width:100%;padding-left:4px}.native-trigger-wrapper{position:relative;width:32px;height:32px}.hidden-native-input{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4662
4673
  }
4663
4674
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapColorBubbleMenuComponent, decorators: [{
4664
4675
  type: Component,
4665
- args: [{ selector: "tiptap-color-bubble-menu", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, FormsModule, TiptapButtonComponent, TiptapSeparatorComponent], template: `
4666
- <div
4667
- #menuRef
4668
- class="bubble-menu color-bubble-menu"
4669
- (mousedown)="onMouseDown($event)"
4670
- (click)="$event.stopPropagation()"
4671
- >
4672
- <div class="color-picker-container">
4673
- <div class="dropdown-row presets">
4674
- <div class="color-grid">
4675
- @for (color of presets; track color) {
4676
- <tiptap-button
4677
- class="color-swatch-btn"
4678
- size="small"
4679
- [title]="color"
4680
- [active]="isColorActive(color)"
4681
- [backgroundColor]="color"
4682
- (onClick)="applyColor(color, true, $event)"
4683
- ></tiptap-button>
4684
- }
4685
- </div>
4686
- </div>
4687
-
4688
- <div class="dropdown-row controls">
4689
- <div class="hex-input-wrapper">
4690
- <span class="hex-hash">#</span>
4691
- <input
4692
- #hexInput
4693
- type="text"
4694
- class="hex-input"
4695
- [value]="hexValue()"
4696
- [attr.aria-label]="t().customColor"
4697
- (input)="onHexInput($event)"
4698
- (change)="onHexChange($event)"
4699
- (keydown.enter)="onApply($event)"
4700
- (focus)="onFocus()"
4701
- (blur)="onBlur()"
4702
- maxlength="6"
4703
- placeholder="000000"
4704
- />
4705
- </div>
4706
-
4707
- <div class="native-trigger-wrapper">
4708
- <tiptap-button
4709
- class="btn-native-picker-trigger"
4710
- icon="colorize"
4711
- [title]="t().customColor"
4712
- [backgroundColor]="currentColor()"
4713
- (onClick)="triggerNativePicker($event)"
4714
- ></tiptap-button>
4715
- <input
4716
- #colorInput
4717
- type="color"
4718
- class="hidden-native-input"
4719
- [value]="currentColor()"
4720
- [attr.aria-label]="t().customColor"
4721
- (input)="onNativeInput($event)"
4722
- (change)="onNativeChange($event)"
4723
- (focus)="onFocus()"
4724
- (blur)="onBlur()"
4725
- />
4726
- </div>
4727
-
4728
- <tiptap-button
4729
- icon="check"
4730
- [title]="common().apply"
4731
- color="var(--ate-primary)"
4732
- (onClick)="onApply($event)"
4733
- ></tiptap-button>
4734
-
4735
- <tiptap-separator />
4736
-
4737
- <tiptap-button
4738
- icon="format_color_reset"
4739
- [title]="t().clear"
4740
- variant="danger"
4741
- (onClick)="onClearColor($event)"
4742
- ></tiptap-button>
4743
- </div>
4744
-
4745
- </div>
4746
- </div>
4676
+ args: [{ selector: "tiptap-color-bubble-menu", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, FormsModule, TiptapButtonComponent, TiptapSeparatorComponent], template: `
4677
+ <div
4678
+ #menuRef
4679
+ class="bubble-menu color-bubble-menu"
4680
+ (mousedown)="onMouseDown($event)"
4681
+ (click)="$event.stopPropagation()"
4682
+ >
4683
+ <div class="color-picker-container">
4684
+ <div class="dropdown-row presets">
4685
+ <div class="color-grid">
4686
+ @for (color of presets; track color) {
4687
+ <tiptap-button
4688
+ class="color-swatch-btn"
4689
+ size="small"
4690
+ [title]="color"
4691
+ [active]="isColorActive(color)"
4692
+ [backgroundColor]="color"
4693
+ (onClick)="applyColor(color, true, $event)"
4694
+ ></tiptap-button>
4695
+ }
4696
+ </div>
4697
+ </div>
4698
+
4699
+ <div class="dropdown-row controls">
4700
+ <div class="hex-input-wrapper">
4701
+ <span class="hex-hash">#</span>
4702
+ <input
4703
+ #hexInput
4704
+ type="text"
4705
+ class="hex-input"
4706
+ [value]="hexValue()"
4707
+ [attr.aria-label]="t().customColor"
4708
+ (input)="onHexInput($event)"
4709
+ (change)="onHexChange($event)"
4710
+ (keydown.enter)="onApply($event)"
4711
+ (focus)="onFocus()"
4712
+ (blur)="onBlur()"
4713
+ maxlength="6"
4714
+ placeholder="000000"
4715
+ />
4716
+ </div>
4717
+
4718
+ <div class="native-trigger-wrapper">
4719
+ <tiptap-button
4720
+ class="btn-native-picker-trigger"
4721
+ icon="colorize"
4722
+ [title]="t().customColor"
4723
+ [backgroundColor]="currentColor()"
4724
+ (onClick)="triggerNativePicker($event)"
4725
+ ></tiptap-button>
4726
+ <input
4727
+ #colorInput
4728
+ type="color"
4729
+ class="hidden-native-input"
4730
+ [value]="currentColor()"
4731
+ [attr.aria-label]="t().customColor"
4732
+ (input)="onNativeInput($event)"
4733
+ (change)="onNativeChange($event)"
4734
+ (focus)="onFocus()"
4735
+ (blur)="onBlur()"
4736
+ />
4737
+ </div>
4738
+
4739
+ <tiptap-button
4740
+ icon="check"
4741
+ [title]="common().apply"
4742
+ color="var(--ate-primary)"
4743
+ (onClick)="onApply($event)"
4744
+ ></tiptap-button>
4745
+
4746
+ <tiptap-separator />
4747
+
4748
+ <tiptap-button
4749
+ icon="format_color_reset"
4750
+ [title]="t().clear"
4751
+ variant="danger"
4752
+ (onClick)="onClearColor($event)"
4753
+ ></tiptap-button>
4754
+ </div>
4755
+
4756
+ </div>
4757
+ </div>
4747
4758
  `, styles: [".color-picker-container{display:flex;flex-direction:column;gap:8px}.dropdown-row{display:flex;align-items:center;width:100%}.dropdown-row.presets{justify-content:center}.dropdown-row.controls{gap:8px;justify-content:space-between;padding-top:4px;border-top:1px solid var(--ate-border, #e2e8f0)}.color-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:4px;width:100%}:host ::ng-deep .color-swatch-btn .tiptap-button{width:100%;aspect-ratio:1;height:auto;border-radius:4px;border:1px solid rgba(0,0,0,.1);padding:0}:host ::ng-deep .color-swatch-btn .tiptap-button.is-active{border-color:var(--ate-primary, #3b82f6);box-shadow:0 0 0 2px #3b82f64d}:host ::ng-deep .btn-native-picker-trigger .tiptap-button{color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.2)}.divider-v{width:1px;height:24px;background:var(--ate-border, #e2e8f0)}.hex-input-wrapper{flex:1;display:flex;align-items:center;background:var(--ate-surface-secondary, #f8fafc);border:1px solid var(--ate-border, #e2e8f0);border-radius:8px;padding:0 10px;height:32px;transition:border-color .15s ease}.hex-input-wrapper:focus-within{border-color:var(--ate-primary, #3b82f6);background:var(--ate-menu-bg, #ffffff)}.hex-hash{color:var(--ate-text-muted, #94a3b8);font-family:monospace;font-size:.875rem}.hex-input{background:transparent;border:none;outline:none;color:var(--ate-text, #1e293b);font-family:monospace;font-size:.875rem;width:100%;padding-left:4px}.native-trigger-wrapper{position:relative;width:32px;height:32px}.hidden-native-input{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer}\n"] }]
4748
4759
  }], ctorParameters: () => [], propDecorators: { menuRef: [{
4749
4760
  type: ViewChild,
@@ -4845,7 +4856,7 @@ function createDefaultSlashCommands(i18n, commands, imageOptions) {
4845
4856
  quality: imageOptions?.quality,
4846
4857
  maxWidth: imageOptions?.maxWidth,
4847
4858
  maxHeight: imageOptions?.maxHeight,
4848
- accept: imageOptions?.allowedTypes?.join(',')
4859
+ allowedTypes: imageOptions?.allowedTypes
4849
4860
  }),
4850
4861
  },
4851
4862
  {
@@ -5195,54 +5206,94 @@ class TiptapSlashCommandsComponent {
5195
5206
  }));
5196
5207
  }
5197
5208
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapSlashCommandsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5198
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapSlashCommandsComponent, isStandalone: true, selector: "tiptap-slash-commands", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "menuRef", first: true, predicate: ["menuRef"], descendants: true }], ngImport: i0, template: `
5199
- <div #menuRef class="slash-commands-menu">
5200
- @for (command of filteredCommands(); track command.title) {
5201
- <div
5202
- class="slash-command-item"
5203
- [class.selected]="$index === selectedIndex()"
5204
- (mousedown)="executeCommand(command); $event.preventDefault(); $event.stopPropagation()"
5205
- (mouseenter)="selectedIndex.set($index)"
5206
- >
5207
- <div class="slash-command-icon">
5208
- <span class="material-symbols-outlined">{{ command.icon }}</span>
5209
- </div>
5210
- <div class="slash-command-content">
5211
- <div class="slash-command-title">{{ command.title }}</div>
5212
- <div class="slash-command-description">{{ command.description }}</div>
5213
- </div>
5214
- </div>
5215
- }
5216
- </div>
5217
- `, isInline: true, styles: [".slash-commands-menu{background:var(--ate-menu-bg);border:1px solid var(--ate-menu-border);border-radius:var(--ate-border-radius, 12px);box-shadow:var(--ate-menu-shadow);padding:var(--ate-menu-padding);max-height:320px;overflow-y:auto;min-width:280px;outline:none;animation:slashMenuFadeIn .2s cubic-bezier(0,0,.2,1);scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}.slash-commands-menu::-webkit-scrollbar{width:var(--ate-scrollbar-width)}.slash-commands-menu::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.slash-commands-menu::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.slash-commands-menu::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}@keyframes slashMenuFadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.slash-command-item{display:flex;align-items:center;gap:12px;padding:var(--ate-menu-padding);border-radius:var(--ate-border-radius, 8px);cursor:pointer;transition:all .15s ease;border:var(--ate-border-width, 1px) solid transparent;outline:none;margin-bottom:2px}.slash-command-item:last-child{margin-bottom:0}.slash-command-item:hover{background:var(--ate-surface-secondary)}.slash-command-item.selected{background:var(--ate-primary-light);border-color:var(--ate-primary-light-alpha)}.slash-command-icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;background:var(--ate-surface-tertiary);border-radius:var(--ate-sub-border-radius, 8px);color:var(--ate-primary);flex-shrink:0;transition:all .15s ease}.slash-command-item.selected .slash-command-icon{background:var(--ate-primary);color:var(--ate-primary-contrast, #ffffff)}.slash-command-icon .material-symbols-outlined{font-size:18px}.slash-command-content{flex:1;min-width:0}.slash-command-title{font-weight:500;color:var(--ate-text);font-size:14px;margin-bottom:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.slash-command-description{color:var(--ate-text-secondary);font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5209
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: TiptapSlashCommandsComponent, isStandalone: true, selector: "tiptap-slash-commands", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "menuRef", first: true, predicate: ["menuRef"], descendants: true }], ngImport: i0, template: `
5210
+ <div #menuRef class="slash-commands-menu">
5211
+ @for (command of filteredCommands(); track command.title) {
5212
+ <div
5213
+ class="slash-command-item"
5214
+ [class.selected]="$index === selectedIndex()"
5215
+ (mousedown)="executeCommand(command); $event.preventDefault(); $event.stopPropagation()"
5216
+ (mouseenter)="selectedIndex.set($index)"
5217
+ >
5218
+ <div class="slash-command-icon">
5219
+ <span class="material-symbols-outlined">{{ command.icon }}</span>
5220
+ </div>
5221
+ <div class="slash-command-content">
5222
+ <div class="slash-command-title">{{ command.title }}</div>
5223
+ <div class="slash-command-description">{{ command.description }}</div>
5224
+ </div>
5225
+ </div>
5226
+ }
5227
+ </div>
5228
+ `, isInline: true, styles: [".slash-commands-menu{background:var(--ate-menu-bg);border:1px solid var(--ate-menu-border);border-radius:var(--ate-menu-border-radius, 12px);box-shadow:var(--ate-menu-shadow);padding:var(--ate-menu-padding);max-height:320px;overflow-y:auto;min-width:280px;outline:none;animation:slashMenuFadeIn .2s cubic-bezier(0,0,.2,1);scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}.slash-commands-menu::-webkit-scrollbar{width:var(--ate-scrollbar-width)}.slash-commands-menu::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.slash-commands-menu::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.slash-commands-menu::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}@keyframes slashMenuFadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.slash-command-item{display:flex;align-items:center;gap:12px;padding:var(--ate-menu-padding);border-radius:var(--ate-menu-border-radius, 8px);cursor:pointer;transition:all .15s ease;border:var(--ate-border-width, 1px) solid transparent;outline:none;margin-bottom:2px}.slash-command-item:last-child{margin-bottom:0}.slash-command-item:hover{background:var(--ate-surface-secondary)}.slash-command-item.selected{background:var(--ate-primary-light);border-color:var(--ate-primary-light-alpha)}.slash-command-icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;background:var(--ate-surface-tertiary);border-radius:var(--ate-sub-border-radius, 8px);color:var(--ate-primary);flex-shrink:0;transition:all .15s ease}.slash-command-item.selected .slash-command-icon{background:var(--ate-primary);color:var(--ate-primary-contrast, #ffffff)}.slash-command-icon .material-symbols-outlined{font-size:18px}.slash-command-content{flex:1;min-width:0}.slash-command-title{font-weight:500;color:var(--ate-text);font-size:14px;margin-bottom:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.slash-command-description{color:var(--ate-text-secondary);font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5218
5229
  }
5219
5230
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapSlashCommandsComponent, decorators: [{
5220
5231
  type: Component,
5221
- args: [{ selector: "tiptap-slash-commands", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
5222
- <div #menuRef class="slash-commands-menu">
5223
- @for (command of filteredCommands(); track command.title) {
5224
- <div
5225
- class="slash-command-item"
5226
- [class.selected]="$index === selectedIndex()"
5227
- (mousedown)="executeCommand(command); $event.preventDefault(); $event.stopPropagation()"
5228
- (mouseenter)="selectedIndex.set($index)"
5229
- >
5230
- <div class="slash-command-icon">
5231
- <span class="material-symbols-outlined">{{ command.icon }}</span>
5232
- </div>
5233
- <div class="slash-command-content">
5234
- <div class="slash-command-title">{{ command.title }}</div>
5235
- <div class="slash-command-description">{{ command.description }}</div>
5236
- </div>
5237
- </div>
5238
- }
5239
- </div>
5240
- `, styles: [".slash-commands-menu{background:var(--ate-menu-bg);border:1px solid var(--ate-menu-border);border-radius:var(--ate-border-radius, 12px);box-shadow:var(--ate-menu-shadow);padding:var(--ate-menu-padding);max-height:320px;overflow-y:auto;min-width:280px;outline:none;animation:slashMenuFadeIn .2s cubic-bezier(0,0,.2,1);scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}.slash-commands-menu::-webkit-scrollbar{width:var(--ate-scrollbar-width)}.slash-commands-menu::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.slash-commands-menu::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.slash-commands-menu::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}@keyframes slashMenuFadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.slash-command-item{display:flex;align-items:center;gap:12px;padding:var(--ate-menu-padding);border-radius:var(--ate-border-radius, 8px);cursor:pointer;transition:all .15s ease;border:var(--ate-border-width, 1px) solid transparent;outline:none;margin-bottom:2px}.slash-command-item:last-child{margin-bottom:0}.slash-command-item:hover{background:var(--ate-surface-secondary)}.slash-command-item.selected{background:var(--ate-primary-light);border-color:var(--ate-primary-light-alpha)}.slash-command-icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;background:var(--ate-surface-tertiary);border-radius:var(--ate-sub-border-radius, 8px);color:var(--ate-primary);flex-shrink:0;transition:all .15s ease}.slash-command-item.selected .slash-command-icon{background:var(--ate-primary);color:var(--ate-primary-contrast, #ffffff)}.slash-command-icon .material-symbols-outlined{font-size:18px}.slash-command-content{flex:1;min-width:0}.slash-command-title{font-weight:500;color:var(--ate-text);font-size:14px;margin-bottom:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.slash-command-description{color:var(--ate-text-secondary);font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"] }]
5232
+ args: [{ selector: "tiptap-slash-commands", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
5233
+ <div #menuRef class="slash-commands-menu">
5234
+ @for (command of filteredCommands(); track command.title) {
5235
+ <div
5236
+ class="slash-command-item"
5237
+ [class.selected]="$index === selectedIndex()"
5238
+ (mousedown)="executeCommand(command); $event.preventDefault(); $event.stopPropagation()"
5239
+ (mouseenter)="selectedIndex.set($index)"
5240
+ >
5241
+ <div class="slash-command-icon">
5242
+ <span class="material-symbols-outlined">{{ command.icon }}</span>
5243
+ </div>
5244
+ <div class="slash-command-content">
5245
+ <div class="slash-command-title">{{ command.title }}</div>
5246
+ <div class="slash-command-description">{{ command.description }}</div>
5247
+ </div>
5248
+ </div>
5249
+ }
5250
+ </div>
5251
+ `, styles: [".slash-commands-menu{background:var(--ate-menu-bg);border:1px solid var(--ate-menu-border);border-radius:var(--ate-menu-border-radius, 12px);box-shadow:var(--ate-menu-shadow);padding:var(--ate-menu-padding);max-height:320px;overflow-y:auto;min-width:280px;outline:none;animation:slashMenuFadeIn .2s cubic-bezier(0,0,.2,1);scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}.slash-commands-menu::-webkit-scrollbar{width:var(--ate-scrollbar-width)}.slash-commands-menu::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.slash-commands-menu::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.slash-commands-menu::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}@keyframes slashMenuFadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.slash-command-item{display:flex;align-items:center;gap:12px;padding:var(--ate-menu-padding);border-radius:var(--ate-menu-border-radius, 8px);cursor:pointer;transition:all .15s ease;border:var(--ate-border-width, 1px) solid transparent;outline:none;margin-bottom:2px}.slash-command-item:last-child{margin-bottom:0}.slash-command-item:hover{background:var(--ate-surface-secondary)}.slash-command-item.selected{background:var(--ate-primary-light);border-color:var(--ate-primary-light-alpha)}.slash-command-icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;background:var(--ate-surface-tertiary);border-radius:var(--ate-sub-border-radius, 8px);color:var(--ate-primary);flex-shrink:0;transition:all .15s ease}.slash-command-item.selected .slash-command-icon{background:var(--ate-primary);color:var(--ate-primary-contrast, #ffffff)}.slash-command-icon .material-symbols-outlined{font-size:18px}.slash-command-content{flex:1;min-width:0}.slash-command-title{font-weight:500;color:var(--ate-text);font-size:14px;margin-bottom:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.slash-command-description{color:var(--ate-text-secondary);font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"] }]
5241
5252
  }], ctorParameters: () => [], propDecorators: { menuRef: [{
5242
5253
  type: ViewChild,
5243
5254
  args: ["menuRef", { static: false }]
5244
5255
  }] } });
5245
5256
 
5257
+ /**
5258
+ * Edit Toggle Component
5259
+ * Allows switching between editable and readonly modes
5260
+ */
5261
+ class TiptapEditToggleComponent {
5262
+ constructor() {
5263
+ this.editable = input.required();
5264
+ this.translations = input.required();
5265
+ this.toggle = output();
5266
+ }
5267
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapEditToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5268
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.0", type: TiptapEditToggleComponent, isStandalone: true, selector: "tiptap-edit-toggle", inputs: { editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: true, transformFunction: null }, translations: { classPropertyName: "translations", publicName: "translations", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { toggle: "toggle" }, ngImport: i0, template: `
5269
+ <div class="ate-edit-toggle-container" [class.is-editable]="editable()">
5270
+ <tiptap-button
5271
+ [icon]="editable() ? 'visibility' : 'edit'"
5272
+ [title]="editable() ? translations().editor.viewMode : translations().editor.toggleEdit"
5273
+ (onClick)="toggle.emit($event)"
5274
+ size="medium"
5275
+ iconSize="small"
5276
+ backgroundColor="var(--ate-primary-lighter)"
5277
+ />
5278
+ </div>
5279
+ `, isInline: true, styles: [".ate-edit-toggle-container{position:absolute;margin-top:16px;right:16px;z-index:50}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TiptapButtonComponent, selector: "tiptap-button", inputs: ["icon", "title", "active", "disabled", "color", "backgroundColor", "variant", "size", "iconSize"], outputs: ["onClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5280
+ }
5281
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: TiptapEditToggleComponent, decorators: [{
5282
+ type: Component,
5283
+ args: [{ selector: "tiptap-edit-toggle", standalone: true, imports: [CommonModule, TiptapButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
5284
+ <div class="ate-edit-toggle-container" [class.is-editable]="editable()">
5285
+ <tiptap-button
5286
+ [icon]="editable() ? 'visibility' : 'edit'"
5287
+ [title]="editable() ? translations().editor.viewMode : translations().editor.toggleEdit"
5288
+ (onClick)="toggle.emit($event)"
5289
+ size="medium"
5290
+ iconSize="small"
5291
+ backgroundColor="var(--ate-primary-lighter)"
5292
+ />
5293
+ </div>
5294
+ `, styles: [".ate-edit-toggle-container{position:absolute;margin-top:16px;right:16px;z-index:50}\n"] }]
5295
+ }] });
5296
+
5246
5297
  class NoopValueAccessorDirective {
5247
5298
  writeValue(obj) { }
5248
5299
  registerOnChange(fn) { }
@@ -5600,6 +5651,8 @@ class AngularTiptapEditorComponent {
5600
5651
  this.editorCommandsService.setToolbarInteracting(false);
5601
5652
  }
5602
5653
  constructor() {
5654
+ /** Configuration globale de l'éditeur */
5655
+ this.config = input({});
5603
5656
  this.content = input("");
5604
5657
  this.placeholder = input("");
5605
5658
  this.editable = input(true);
@@ -5621,6 +5674,8 @@ class AngularTiptapEditorComponent {
5621
5674
  this.autofocus = input(false);
5622
5675
  this.seamless = input(false);
5623
5676
  this.floatingToolbar = input(false);
5677
+ this.showEditToggle = input(false);
5678
+ this.spellcheck = input(true);
5624
5679
  this.tiptapExtensions = input([]);
5625
5680
  this.tiptapOptions = input({});
5626
5681
  // Nouveaux inputs pour les bubble menus
@@ -5667,6 +5722,7 @@ class AngularTiptapEditorComponent {
5667
5722
  this.editorUpdate = output();
5668
5723
  this.editorFocus = output();
5669
5724
  this.editorBlur = output();
5725
+ this.editableChange = output();
5670
5726
  // ViewChild with signal
5671
5727
  this.editorElement = viewChild.required("editorElement");
5672
5728
  // Private signals for internal state
@@ -5686,63 +5742,121 @@ class AngularTiptapEditorComponent {
5686
5742
  this._isFormControlDisabled = signal(false);
5687
5743
  this.isFormControlDisabled = this._isFormControlDisabled.asReadonly();
5688
5744
  // Combined disabled state (Input + FormControl)
5689
- this.mergedDisabled = computed(() => this.disabled() || this.isFormControlDisabled());
5745
+ this.mergedDisabled = computed(() => (this.config().disabled ?? this.disabled()) || this.isFormControlDisabled());
5690
5746
  // Computed for editor states
5691
5747
  this.isEditorReady = computed(() => this.editor() !== null);
5692
- // Computed for toolbar configuration
5693
- this.toolbarConfig = computed(() => Object.keys(this.toolbar()).length === 0
5694
- ? DEFAULT_TOOLBAR_CONFIG
5695
- : this.toolbar());
5696
- // Computed for bubble menu configuration
5697
- this.bubbleMenuConfig = computed(() => Object.keys(this.bubbleMenu()).length === 0
5698
- ? DEFAULT_BUBBLE_MENU_CONFIG
5699
- : { ...DEFAULT_BUBBLE_MENU_CONFIG, ...this.bubbleMenu() });
5700
- // Computed for image bubble menu configuration
5701
- this.imageBubbleMenuConfig = computed(() => Object.keys(this.imageBubbleMenu()).length === 0
5702
- ? DEFAULT_IMAGE_BUBBLE_MENU_CONFIG
5703
- : { ...DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, ...this.imageBubbleMenu() });
5704
- // Computed for table bubble menu configuration
5705
- this.tableBubbleMenuConfig = computed(() => Object.keys(this.tableBubbleMenu()).length === 0
5706
- ? DEFAULT_TABLE_MENU_CONFIG
5707
- : { ...DEFAULT_TABLE_MENU_CONFIG, ...this.tableBubbleMenu() });
5708
- // Computed for cell bubble menu configuration
5709
- this.cellBubbleMenuConfig = computed(() => Object.keys(this.cellBubbleMenu()).length === 0
5710
- ? DEFAULT_CELL_MENU_CONFIG
5711
- : { ...DEFAULT_CELL_MENU_CONFIG, ...this.cellBubbleMenu() });
5712
- // Computed for image upload configuration
5713
- this.imageUploadConfig = computed(() => ({
5714
- maxSize: 5,
5715
- maxWidth: 1920,
5716
- maxHeight: 1080,
5717
- allowedTypes: ["image/jpeg", "image/png", "image/gif", "image/webp"],
5718
- enableDragDrop: true,
5719
- showPreview: true,
5720
- multiple: false,
5721
- compressImages: true,
5722
- quality: 0.8,
5723
- ...this.imageUpload(),
5724
- }));
5725
- // Computed for slash commands configuration
5726
- this.slashCommandsConfigComputed = computed(() => {
5748
+ // ============================================
5749
+ // UNIFIED CONFIGURATION COMPUTED PROPERTIES
5750
+ // ============================================
5751
+ // Appearance & Fundamentals
5752
+ this.finalSeamless = computed(() => {
5753
+ const fromConfig = this.config().mode;
5754
+ if (fromConfig !== undefined)
5755
+ return fromConfig === 'seamless';
5756
+ return this.seamless();
5757
+ });
5758
+ this.finalPlaceholder = computed(() => this.config().placeholder ?? (this.placeholder() || this.currentTranslations().editor.placeholder));
5759
+ this.finalFillContainer = computed(() => this.config().fillContainer ?? this.fillContainer());
5760
+ this.finalShowFooter = computed(() => this.config().showFooter ?? this.showFooter());
5761
+ this.finalShowEditToggle = computed(() => this.config().showEditToggle ?? this.showEditToggle());
5762
+ this.finalHeight = computed(() => this.config().height ?? (this.height() ? `${this.height()}px` : undefined));
5763
+ this.finalMinHeight = computed(() => this.config().minHeight ?? (this.minHeight() ? `${this.minHeight()}px` : undefined));
5764
+ this.finalMaxHeight = computed(() => this.config().maxHeight ?? (this.maxHeight() ? `${this.maxHeight()}px` : undefined));
5765
+ this.finalSpellcheck = computed(() => this.config().spellcheck ?? this.spellcheck());
5766
+ this.finalEnableOfficePaste = computed(() => this.config().enableOfficePaste ?? this.enableOfficePaste());
5767
+ // Features
5768
+ this.finalShowToolbar = computed(() => this.config().showToolbar ?? this.showToolbar());
5769
+ this.finalToolbarConfig = computed(() => {
5770
+ const fromConfig = this.config().toolbar;
5771
+ const base = DEFAULT_TOOLBAR_CONFIG;
5772
+ if (fromConfig)
5773
+ return { ...base, ...fromConfig };
5774
+ const fromInput = this.toolbar();
5775
+ return Object.keys(fromInput).length === 0 ? base : { ...base, ...fromInput };
5776
+ });
5777
+ this.finalFloatingToolbar = computed(() => this.config().floatingToolbar ?? this.floatingToolbar());
5778
+ this.finalShowBubbleMenu = computed(() => this.config().showBubbleMenu ?? this.showBubbleMenu());
5779
+ this.finalBubbleMenuConfig = computed(() => {
5780
+ const fromConfig = this.config().bubbleMenu;
5781
+ const base = DEFAULT_BUBBLE_MENU_CONFIG;
5782
+ if (fromConfig)
5783
+ return { ...base, ...fromConfig };
5784
+ return Object.keys(this.bubbleMenu()).length === 0 ? base : { ...base, ...this.bubbleMenu() };
5785
+ });
5786
+ this.finalShowImageBubbleMenu = computed(() => this.config().showImageBubbleMenu ?? this.showImageBubbleMenu());
5787
+ this.finalImageBubbleMenuConfig = computed(() => {
5788
+ const fromConfig = this.config().imageBubbleMenu;
5789
+ const base = DEFAULT_IMAGE_BUBBLE_MENU_CONFIG;
5790
+ if (fromConfig)
5791
+ return { ...base, ...fromConfig };
5792
+ return Object.keys(this.imageBubbleMenu()).length === 0 ? base : { ...base, ...this.imageBubbleMenu() };
5793
+ });
5794
+ this.finalShowTableBubbleMenu = computed(() => this.config().showTableMenu ?? this.showTableBubbleMenu());
5795
+ this.finalTableBubbleMenuConfig = computed(() => {
5796
+ const fromConfig = this.config().tableBubbleMenu;
5797
+ const base = DEFAULT_TABLE_MENU_CONFIG;
5798
+ if (fromConfig)
5799
+ return { ...base, ...fromConfig };
5800
+ return Object.keys(this.tableBubbleMenu()).length === 0 ? base : { ...base, ...this.tableBubbleMenu() };
5801
+ });
5802
+ this.finalShowCellBubbleMenu = computed(() => this.config().showCellMenu ?? this.showCellBubbleMenu());
5803
+ this.finalCellBubbleMenuConfig = computed(() => {
5804
+ const fromConfig = this.config().cellBubbleMenu;
5805
+ const base = DEFAULT_CELL_MENU_CONFIG;
5806
+ if (fromConfig)
5807
+ return { ...base, ...fromConfig };
5808
+ return Object.keys(this.cellBubbleMenu()).length === 0 ? base : { ...base, ...this.cellBubbleMenu() };
5809
+ });
5810
+ this.finalEnableSlashCommands = computed(() => this.config().enableSlashCommands ?? this.enableSlashCommands());
5811
+ this.finalSlashCommandsConfig = computed(() => {
5812
+ const fromConfig = this.config().slashCommands;
5727
5813
  const customConfig = this.customSlashCommands();
5728
- if (customConfig) {
5814
+ if (customConfig)
5729
5815
  return customConfig;
5816
+ let baseConfig = this.slashCommands();
5817
+ if (fromConfig) {
5818
+ baseConfig = fromConfig;
5730
5819
  }
5731
- // Utilise l'utilitaire filterSlashCommands qui gère maintenant
5732
- // les défauts, le filtrage et l'ajout de commandes personnalisées
5733
5820
  return {
5734
- commands: filterSlashCommands(this.slashCommands(), this.i18nService, this.editorCommandsService, this.imageUploadConfig()),
5821
+ commands: filterSlashCommands(baseConfig, this.i18nService, this.editorCommandsService, this.finalImageUploadConfig()),
5822
+ };
5823
+ });
5824
+ // Behavior
5825
+ this.finalAutofocus = computed(() => this.config().autofocus ?? this.autofocus());
5826
+ this.finalMaxCharacters = computed(() => this.config().maxCharacters ?? this.maxCharacters());
5827
+ this.finalShowCharacterCount = computed(() => this.config().showCharacterCount ?? this.showCharacterCount());
5828
+ this.finalShowWordCount = computed(() => this.config().showWordCount ?? this.showWordCount());
5829
+ this.finalLocale = computed(() => this.config().locale ?? this.locale());
5830
+ // Image Upload
5831
+ this.finalImageUploadConfig = computed(() => {
5832
+ const fromConfig = this.config().imageUpload;
5833
+ const fromInput = this.imageUpload();
5834
+ const merged = {
5835
+ maxSize: 5, // Default 5MB
5836
+ maxWidth: 1920,
5837
+ maxHeight: 1080,
5838
+ allowedTypes: ["image/jpeg", "image/png", "image/gif", "image/webp"],
5839
+ enableDragDrop: true,
5840
+ showPreview: true,
5841
+ multiple: false,
5842
+ compressImages: true,
5843
+ quality: 0.8,
5844
+ ...fromInput,
5845
+ ...fromConfig,
5846
+ };
5847
+ return {
5848
+ ...merged,
5849
+ maxSize: merged.maxSize * 1024 * 1024 // Convert MB to bytes for internal service
5735
5850
  };
5736
5851
  });
5737
- // Computed for current translations (allows per-instance override via [locale] input)
5852
+ this.finalImageUploadHandler = computed(() => this.config().imageUpload?.handler ?? this.imageUploadHandler());
5853
+ // Computed for current translations (allows per-instance override via config or input)
5738
5854
  this.currentTranslations = computed(() => {
5739
- const localeOverride = this.locale();
5855
+ const localeOverride = this.finalLocale();
5740
5856
  if (localeOverride) {
5741
- // If a specific language is provided to this instance, try to retrieve it
5742
5857
  const allTranslations = this.i18nService.allTranslations();
5743
5858
  return allTranslations[localeOverride] || this.i18nService.translations();
5744
5859
  }
5745
- // Otherwise, follow the global service language
5746
5860
  return this.i18nService.translations();
5747
5861
  });
5748
5862
  this._destroyRef = inject(DestroyRef);
@@ -5774,16 +5888,16 @@ class AngularTiptapEditorComponent {
5774
5888
  });
5775
5889
  // Effect to update height properties
5776
5890
  effect(() => {
5777
- const minHeight = this.minHeight();
5778
- const height = this.height();
5779
- const maxHeight = this.maxHeight();
5891
+ const minHeight = this.finalMinHeight();
5892
+ const height = this.finalHeight();
5893
+ const maxHeight = this.finalMaxHeight();
5780
5894
  const element = this.editorElement()?.nativeElement;
5781
5895
  // Automatically calculate if scroll is needed
5782
5896
  const needsScroll = height !== undefined || maxHeight !== undefined;
5783
5897
  if (element) {
5784
5898
  element.style.setProperty("--editor-min-height", `${minHeight}px`);
5785
- element.style.setProperty("--editor-height", height ? `${height}px` : "auto");
5786
- element.style.setProperty("--editor-max-height", maxHeight ? `${maxHeight}px` : "none");
5899
+ element.style.setProperty("--editor-height", height ?? "auto");
5900
+ element.style.setProperty("--editor-max-height", maxHeight ?? "none");
5787
5901
  element.style.setProperty("--editor-overflow", needsScroll ? "auto" : "visible");
5788
5902
  }
5789
5903
  });
@@ -5800,20 +5914,17 @@ class AngularTiptapEditorComponent {
5800
5914
  });
5801
5915
  // Effect to synchronize image upload handler with the service
5802
5916
  effect(() => {
5803
- const handler = this.imageUploadHandler();
5917
+ const handler = this.finalImageUploadHandler();
5804
5918
  this.editorCommandsService.uploadHandler = handler || null;
5805
5919
  });
5806
5920
  // Effect to update character count limit dynamically
5807
5921
  effect(() => {
5808
5922
  const editor = this.editor();
5809
- const limit = this.maxCharacters();
5923
+ const limit = this.finalMaxCharacters();
5810
5924
  if (editor && editor.extensionManager) {
5811
5925
  const characterCountExtension = editor.extensionManager.extensions.find((ext) => ext.name === "characterCount");
5812
5926
  if (characterCountExtension) {
5813
5927
  characterCountExtension.options.limit = limit;
5814
- // Force TipTap to recognize the option change if possible
5815
- // Some extensions need re-creation, but characterCount plugin
5816
- // reads this.options.limit in its filterTransaction.
5817
5928
  }
5818
5929
  }
5819
5930
  });
@@ -5840,7 +5951,7 @@ class AngularTiptapEditorComponent {
5840
5951
  types: ["textStyle"],
5841
5952
  }),
5842
5953
  Placeholder.configure({
5843
- placeholder: this.placeholder() || this.i18nService.editor().placeholder,
5954
+ placeholder: this.finalPlaceholder(),
5844
5955
  }),
5845
5956
  Underline,
5846
5957
  Superscript,
@@ -5888,16 +5999,16 @@ class AngularTiptapEditorComponent {
5888
5999
  }),
5889
6000
  ];
5890
6001
  // Ajouter l'extension Office Paste si activée
5891
- if (this.enableOfficePaste()) {
6002
+ if (this.finalEnableOfficePaste()) {
5892
6003
  extensions.push(OfficePaste.configure({
5893
6004
  // Configuration par défaut pour une meilleure compatibilité
5894
6005
  transformPastedHTML: true,
5895
6006
  transformPastedText: true,
5896
6007
  }));
5897
6008
  }
5898
- if (this.showCharacterCount() || this.showWordCount()) {
6009
+ if (this.finalShowCharacterCount() || this.finalShowWordCount()) {
5899
6010
  extensions.push(CharacterCount.configure({
5900
- limit: this.maxCharacters(),
6011
+ limit: this.finalMaxCharacters(),
5901
6012
  }));
5902
6013
  }
5903
6014
  // Allow addition of custom extensions, but avoid duplicates by filtering by name
@@ -5917,10 +6028,15 @@ class AngularTiptapEditorComponent {
5917
6028
  const newEditor = new Editor({
5918
6029
  ...userOptions,
5919
6030
  element: this.editorElement().nativeElement,
5920
- extensions,
6031
+ extensions: extensions,
5921
6032
  content: this.content(),
5922
6033
  editable: this.editable() && !this.mergedDisabled(),
5923
- autofocus: this.autofocus(),
6034
+ autofocus: this.finalAutofocus(),
6035
+ editorProps: {
6036
+ attributes: {
6037
+ spellcheck: this.finalSpellcheck().toString(),
6038
+ },
6039
+ },
5924
6040
  onUpdate: ({ editor, transaction }) => {
5925
6041
  const html = editor.getHTML();
5926
6042
  // Anti-écho : mémoriser ce qu'on émet pour éviter la boucle
@@ -5958,8 +6074,14 @@ class AngularTiptapEditorComponent {
5958
6074
  // Stocker la référence de l'éditeur immédiatement
5959
6075
  this._editor.set(newEditor);
5960
6076
  }
6077
+ toggleEditMode(event) {
6078
+ event.preventDefault();
6079
+ event.stopPropagation();
6080
+ const newEditable = !this.editable();
6081
+ this.editableChange.emit(newEditable);
6082
+ }
5961
6083
  updateCharacterCount(editor) {
5962
- if ((this.showCharacterCount() || this.showWordCount()) && editor.storage["characterCount"]) {
6084
+ if ((this.finalShowCharacterCount() || this.finalShowWordCount()) && editor.storage["characterCount"]) {
5963
6085
  const storage = editor.storage["characterCount"];
5964
6086
  this._characterCount.set(storage.characters());
5965
6087
  this._wordCount.set(storage.words());
@@ -5986,7 +6108,7 @@ class AngularTiptapEditorComponent {
5986
6108
  const currentEditor = this.editor();
5987
6109
  if (currentEditor) {
5988
6110
  try {
5989
- const config = this.imageUploadConfig();
6111
+ const config = this.finalImageUploadConfig();
5990
6112
  await this.editorCommandsService.uploadImage(currentEditor, file, {
5991
6113
  quality: config.quality,
5992
6114
  maxWidth: config.maxWidth,
@@ -6077,132 +6199,143 @@ class AngularTiptapEditorComponent {
6077
6199
  }
6078
6200
  }
6079
6201
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AngularTiptapEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6080
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: AngularTiptapEditorComponent, isStandalone: true, selector: "angular-tiptap-editor", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, fillContainer: { classPropertyName: "fillContainer", publicName: "fillContainer", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, showCharacterCount: { classPropertyName: "showCharacterCount", publicName: "showCharacterCount", isSignal: true, isRequired: false, transformFunction: null }, showWordCount: { classPropertyName: "showWordCount", publicName: "showWordCount", isSignal: true, isRequired: false, transformFunction: null }, maxCharacters: { classPropertyName: "maxCharacters", publicName: "maxCharacters", isSignal: true, isRequired: false, transformFunction: null }, enableOfficePaste: { classPropertyName: "enableOfficePaste", publicName: "enableOfficePaste", isSignal: true, isRequired: false, transformFunction: null }, enableSlashCommands: { classPropertyName: "enableSlashCommands", publicName: "enableSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, slashCommands: { classPropertyName: "slashCommands", publicName: "slashCommands", isSignal: true, isRequired: false, transformFunction: null }, customSlashCommands: { classPropertyName: "customSlashCommands", publicName: "customSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, seamless: { classPropertyName: "seamless", publicName: "seamless", isSignal: true, isRequired: false, transformFunction: null }, floatingToolbar: { classPropertyName: "floatingToolbar", publicName: "floatingToolbar", isSignal: true, isRequired: false, transformFunction: null }, tiptapExtensions: { classPropertyName: "tiptapExtensions", publicName: "tiptapExtensions", isSignal: true, isRequired: false, transformFunction: null }, tiptapOptions: { classPropertyName: "tiptapOptions", publicName: "tiptapOptions", isSignal: true, isRequired: false, transformFunction: null }, showBubbleMenu: { classPropertyName: "showBubbleMenu", publicName: "showBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, bubbleMenu: { classPropertyName: "bubbleMenu", publicName: "bubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showImageBubbleMenu: { classPropertyName: "showImageBubbleMenu", publicName: "showImageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, imageBubbleMenu: { classPropertyName: "imageBubbleMenu", publicName: "imageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, toolbar: { classPropertyName: "toolbar", publicName: "toolbar", isSignal: true, isRequired: false, transformFunction: null }, showTableBubbleMenu: { classPropertyName: "showTableBubbleMenu", publicName: "showTableBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, tableBubbleMenu: { classPropertyName: "tableBubbleMenu", publicName: "tableBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showCellBubbleMenu: { classPropertyName: "showCellBubbleMenu", publicName: "showCellBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, cellBubbleMenu: { classPropertyName: "cellBubbleMenu", publicName: "cellBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, stateCalculators: { classPropertyName: "stateCalculators", publicName: "stateCalculators", isSignal: true, isRequired: false, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null }, imageUploadHandler: { classPropertyName: "imageUploadHandler", publicName: "imageUploadHandler", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contentChange: "contentChange", editorCreated: "editorCreated", editorUpdate: "editorUpdate", editorFocus: "editorFocus", editorBlur: "editorBlur" }, host: { properties: { "class.fill-container": "fillContainer()", "class.floating-toolbar": "floatingToolbar()", "class.is-readonly": "!editable() && !mergedDisabled()", "class.is-disabled": "mergedDisabled()", "style.--ate-border-width": "seamless() || mergedDisabled() ? '0' : null", "style.--ate-background": "seamless() ? 'transparent' : (mergedDisabled() ? 'var(--ate-surface-tertiary)' : null)", "style.--ate-toolbar-border-color": "seamless() ? 'transparent' : null", "style.--ate-counter-background": "seamless() ? 'transparent' : null", "style.--ate-counter-border-color": "seamless() ? 'transparent' : null" } }, providers: [
6202
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.0", type: AngularTiptapEditorComponent, isStandalone: true, selector: "angular-tiptap-editor", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, fillContainer: { classPropertyName: "fillContainer", publicName: "fillContainer", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, showCharacterCount: { classPropertyName: "showCharacterCount", publicName: "showCharacterCount", isSignal: true, isRequired: false, transformFunction: null }, showWordCount: { classPropertyName: "showWordCount", publicName: "showWordCount", isSignal: true, isRequired: false, transformFunction: null }, maxCharacters: { classPropertyName: "maxCharacters", publicName: "maxCharacters", isSignal: true, isRequired: false, transformFunction: null }, enableOfficePaste: { classPropertyName: "enableOfficePaste", publicName: "enableOfficePaste", isSignal: true, isRequired: false, transformFunction: null }, enableSlashCommands: { classPropertyName: "enableSlashCommands", publicName: "enableSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, slashCommands: { classPropertyName: "slashCommands", publicName: "slashCommands", isSignal: true, isRequired: false, transformFunction: null }, customSlashCommands: { classPropertyName: "customSlashCommands", publicName: "customSlashCommands", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, seamless: { classPropertyName: "seamless", publicName: "seamless", isSignal: true, isRequired: false, transformFunction: null }, floatingToolbar: { classPropertyName: "floatingToolbar", publicName: "floatingToolbar", isSignal: true, isRequired: false, transformFunction: null }, showEditToggle: { classPropertyName: "showEditToggle", publicName: "showEditToggle", isSignal: true, isRequired: false, transformFunction: null }, spellcheck: { classPropertyName: "spellcheck", publicName: "spellcheck", isSignal: true, isRequired: false, transformFunction: null }, tiptapExtensions: { classPropertyName: "tiptapExtensions", publicName: "tiptapExtensions", isSignal: true, isRequired: false, transformFunction: null }, tiptapOptions: { classPropertyName: "tiptapOptions", publicName: "tiptapOptions", isSignal: true, isRequired: false, transformFunction: null }, showBubbleMenu: { classPropertyName: "showBubbleMenu", publicName: "showBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, bubbleMenu: { classPropertyName: "bubbleMenu", publicName: "bubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showImageBubbleMenu: { classPropertyName: "showImageBubbleMenu", publicName: "showImageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, imageBubbleMenu: { classPropertyName: "imageBubbleMenu", publicName: "imageBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, toolbar: { classPropertyName: "toolbar", publicName: "toolbar", isSignal: true, isRequired: false, transformFunction: null }, showTableBubbleMenu: { classPropertyName: "showTableBubbleMenu", publicName: "showTableBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, tableBubbleMenu: { classPropertyName: "tableBubbleMenu", publicName: "tableBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, showCellBubbleMenu: { classPropertyName: "showCellBubbleMenu", publicName: "showCellBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, cellBubbleMenu: { classPropertyName: "cellBubbleMenu", publicName: "cellBubbleMenu", isSignal: true, isRequired: false, transformFunction: null }, stateCalculators: { classPropertyName: "stateCalculators", publicName: "stateCalculators", isSignal: true, isRequired: false, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null }, imageUploadHandler: { classPropertyName: "imageUploadHandler", publicName: "imageUploadHandler", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contentChange: "contentChange", editorCreated: "editorCreated", editorUpdate: "editorUpdate", editorFocus: "editorFocus", editorBlur: "editorBlur", editableChange: "editableChange" }, host: { properties: { "class.fill-container": "finalFillContainer()", "class.floating-toolbar": "finalFloatingToolbar()", "class.is-readonly": "!editable() && !mergedDisabled()", "class.is-disabled": "mergedDisabled()", "style.--ate-border-width": "finalSeamless() || mergedDisabled() ? '0' : null", "style.--ate-background": "finalSeamless() ? 'transparent' : (mergedDisabled() ? 'var(--ate-surface-tertiary)' : null)", "style.--ate-toolbar-border-color": "finalSeamless() ? 'transparent' : null", "style.--ate-counter-background": "finalSeamless() ? 'transparent' : null", "style.--ate-counter-border-color": "finalSeamless() ? 'transparent' : null", "class.dark": "config().theme === 'dark'", "attr.data-theme": "config().theme" } }, providers: [
6081
6203
  EditorCommandsService,
6082
6204
  ImageService,
6083
6205
  ColorPickerService,
6084
6206
  LinkService,
6085
- ], viewQueries: [{ propertyName: "editorElement", first: true, predicate: ["editorElement"], descendants: true, isSignal: true }], hostDirectives: [{ directive: NoopValueAccessorDirective }], ngImport: i0, template: `
6086
- <div class="tiptap-editor">
6087
- <!-- Toolbar -->
6088
- @if (editable() && !mergedDisabled() && showToolbar() && editor()) {
6089
- <tiptap-toolbar
6090
- [editor]="editor()!"
6091
- [config]="toolbarConfig()"
6092
- [imageUpload]="imageUploadConfig()"
6093
- [floating]="floatingToolbar()"
6094
- (mouseenter)="hideBubbleMenus()"
6095
- (mouseleave)="showBubbleMenus()"
6096
- />
6097
- }
6098
-
6099
- <!-- Editor Content -->
6100
- <div
6101
- #editorElement
6102
- class="tiptap-content"
6103
- [class.drag-over]="isDragOver()"
6104
- (dragover)="onDragOver($event)"
6105
- (drop)="onDrop($event)"
6106
- (click)="onEditorClick($event)"
6107
- ></div>
6108
-
6109
- <!-- Text Bubble Menu -->
6110
- @if (editable() && showBubbleMenu() && editor()) {
6111
- <tiptap-bubble-menu
6112
- [editor]="editor()!"
6113
- [config]="bubbleMenuConfig()"
6114
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6115
- ></tiptap-bubble-menu>
6116
- }
6117
-
6118
- <!-- Image Bubble Menu -->
6119
- @if (editable() && showImageBubbleMenu() && editor()) {
6120
- <tiptap-image-bubble-menu
6121
- [editor]="editor()!"
6122
- [config]="imageBubbleMenuConfig()"
6123
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6124
- ></tiptap-image-bubble-menu>
6125
- }
6126
-
6127
- <!-- Link Bubble Menu -->
6128
- @if (editable() && editor()) {
6129
- <tiptap-link-bubble-menu
6130
- [editor]="editor()!"
6131
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6132
- ></tiptap-link-bubble-menu>
6133
- }
6134
-
6135
- <!-- Color Bubble Menu -->
6136
- @if (editable() && editor()) {
6137
- <tiptap-color-bubble-menu
6138
- [editor]="editor()!"
6139
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6140
- ></tiptap-color-bubble-menu>
6141
- }
6142
-
6143
- <!-- Slash Commands -->
6144
- @if (editable() && enableSlashCommands() && editor()) {
6145
- <tiptap-slash-commands
6146
- [editor]="editor()!"
6147
- [config]="slashCommandsConfigComputed()"
6148
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6149
- ></tiptap-slash-commands>
6150
- }
6151
-
6152
- <!-- Table Menu -->
6153
- @if (editable() && editor()) {
6154
- <tiptap-table-bubble-menu
6155
- [editor]="editor()!"
6156
- [config]="tableBubbleMenuConfig()"
6157
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6158
- ></tiptap-table-bubble-menu>
6159
- }
6160
-
6161
- <!-- Cell Menu -->
6162
- @if (editable() && editor()) {
6163
- <tiptap-cell-bubble-menu
6164
- [editor]="editor()!"
6165
- [config]="cellBubbleMenuConfig()"
6166
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6167
- ></tiptap-cell-bubble-menu>
6168
- }
6169
-
6170
- <!-- Counters -->
6171
- @if (editable() && !mergedDisabled() && showFooter() && (showCharacterCount() || showWordCount())) {
6172
- <div class="character-count" [class.limit-reached]="maxCharacters() && characterCount() >= maxCharacters()!">
6173
- @if (showCharacterCount()) {
6174
- {{ characterCount() }}
6175
- {{ currentTranslations().editor.character }}{{ characterCount() > 1 ? "s" : "" }}
6176
- @if (maxCharacters()) {
6177
- / {{ maxCharacters() }}
6178
- }
6179
- }
6180
-
6181
- @if (showCharacterCount() && showWordCount()) {
6182
- ,
6183
- }
6184
-
6185
- @if (showWordCount()) {
6186
- {{ wordCount() }}
6187
- {{ currentTranslations().editor.word }}{{ wordCount() > 1 ? "s" : "" }}
6188
- }
6189
- </div>
6190
- }
6191
- </div>
6192
- `, isInline: true, styles: [":host{--ate-primary: #2563eb;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 90%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 95%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-surface: #ffffff;--ate-surface-secondary: #f8f9fa;--ate-surface-tertiary: #f1f5f9;--ate-text: #2d3748;--ate-text-secondary: #64748b;--ate-text-muted: #a0aec0;--ate-border: #e2e8f0;--ate-highlight-bg: #fef08a;--ate-highlight-color: #854d0e;--ate-button-hover: #f1f5f9;--ate-button-active: #e2e8f0;--ate-error-color: #c53030;--ate-error-bg: #fed7d7;--ate-error-border: #feb2b2;--ate-border-color: var(--ate-border);--ate-border-width: 2px;--ate-border-radius: 12px;--ate-focus-color: var(--ate-primary);--ate-background: var(--ate-surface);--ate-sub-border-radius: 8px;--ate-text-color: var(--ate-text);--ate-placeholder-color: var(--ate-text-muted);--ate-line-height: 1.6;--ate-content-padding: 16px;--ate-menu-bg: var(--ate-surface-secondary);--ate-menu-border: var(--ate-border);--ate-menu-shadow: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -2px rgba(0, 0, 0, .05);--ate-menu-padding: 6px;--ate-toolbar-padding: var(--ate-menu-padding);--ate-toolbar-background: var(--ate-surface-secondary);--ate-toolbar-border-color: var(--ate-border);--ate-toolbar-button-color: var(--ate-text-secondary);--ate-toolbar-button-hover-background: transparent;--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-counter-color: var(--ate-text-secondary);--ate-counter-background: var(--ate-surface-secondary);--ate-counter-border-color: var(--ate-border);--ate-drag-background: #f0f8ff;--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-border);--ate-blockquote-background: var(--ate-surface-secondary);--ate-code-background: var(--ate-surface-secondary);--ate-code-color: var(--ate-text-secondary);--ate-code-border-color: var(--ate-border);--ate-code-block-background: #0f172a;--ate-code-block-color: #e2e8f0;--ate-code-block-border-color: var(--ate-border);--ate-image-border-radius: var(--ate-sub-border-radius);--ate-image-selected-color: var(--ate-primary);--ate-scrollbar-width: 10px;--ate-scrollbar-thumb: var(--ate-border);--ate-scrollbar-thumb-hover: var(--ate-text-muted);--ate-scrollbar-track: transparent;--ate-table-border-color: var(--ate-border);--ate-table-header-background: var(--ate-surface-secondary);--ate-table-header-color: var(--ate-text);--ate-table-cell-background: var(--ate-surface);--ate-table-cell-selected-background: var(--ate-primary-light);--ate-table-resize-handle-color: var(--ate-primary);--ate-table-row-hover-background: var(--ate-primary-lighter)}:host(.dark),:host([data-theme=\"dark\"]){--ate-primary: #3b82f6;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 92%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 80%);--ate-surface: #020617;--ate-surface-secondary: #0f172a;--ate-surface-tertiary: #1e293b;--ate-text: #f8fafc;--ate-text-secondary: #94a3b8;--ate-text-muted: #64748b;--ate-border: #1e293b;--ate-highlight-bg: #854d0e;--ate-highlight-color: #fef08a;--ate-button-hover: #1e293b;--ate-button-active: #0f172a;--ate-menu-border: rgba(255, 255, 255, .1);--ate-menu-shadow: 0 20px 25px -5px rgba(0, 0, 0, .3), 0 10px 10px -5px rgba(0, 0, 0, .2);--ate-error-color: #f87171;--ate-error-bg: #450a0a;--ate-error-border: #7f1d1d;--ate-drag-background: var(--ate-surface-tertiary);--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-primary);--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-button-hover: var(--ate-surface-tertiary);--ate-button-active: var(--ate-surface-secondary);--ate-scrollbar-thumb: var(--ate-surface-tertiary);--ate-scrollbar-thumb-hover: var(--ate-text-muted)}:host(.fill-container){display:block;height:100%}.tiptap-editor{border:var(--ate-border-width) solid var(--ate-border-color);border-radius:var(--ate-border-radius);background:var(--ate-background);overflow:hidden;transition:border-color .2s ease;position:relative}:host(.floating-toolbar) .tiptap-editor{overflow:visible}:host(.fill-container) .tiptap-editor{display:flex;flex-direction:column;height:100%}:host(.fill-container) .tiptap-content{flex:1;min-height:0;overflow-y:auto}.tiptap-editor:focus-within{border-color:var(--ate-focus-color)}.tiptap-content{min-height:var(--editor-min-height, 200px);height:var(--editor-height, auto);max-height:var(--editor-max-height, none);overflow-y:var(--editor-overflow, visible);outline:none;position:relative;scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}:host(.is-disabled) .tiptap-content{cursor:not-allowed;opacity:.7;-webkit-user-select:none;user-select:none;pointer-events:none;background-color:var(--ate-surface-tertiary)}:host(.is-readonly) .tiptap-content{cursor:default;-webkit-user-select:text;user-select:text}:host(.is-readonly) .tiptap-content ::ng-deep .tiptap-link{cursor:pointer;pointer-events:auto}.tiptap-content::-webkit-scrollbar{width:var(--ate-scrollbar-width);height:var(--ate-scrollbar-width)}.tiptap-content::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.tiptap-content::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.tiptap-content::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}.tiptap-content.drag-over{background:var(--ate-drag-background);border:2px dashed var(--ate-drag-border-color)}.character-count{padding:8px var(--ate-content-padding);font-size:12px;color:var(--ate-counter-color);text-align:right;border-top:1px solid var(--ate-counter-border-color);background:var(--ate-counter-background);transition:color .2s ease;border-bottom-left-radius:calc(var(--ate-border-radius) - var(--ate-border-width));border-bottom-right-radius:calc(var(--ate-border-radius) - var(--ate-border-width))}.character-count.limit-reached{color:var(--ate-error-color, #ef4444);font-weight:600}:host ::ng-deep .ProseMirror{padding:var(--ate-content-padding);outline:none;line-height:var(--ate-line-height);color:var(--ate-text-color);min-height:100%;height:100%;word-wrap:break-word;overflow-wrap:break-word}:host ::ng-deep .ProseMirror h1{font-size:2em;font-weight:700;margin-top:0;margin-bottom:.5em}:host ::ng-deep .ProseMirror h2{font-size:1.5em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror h3{font-size:1.25em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror p{margin:.5em 0}:host ::ng-deep .ProseMirror ul,:host ::ng-deep .ProseMirror ol{padding-left:2em;margin:.5em 0}:host ::ng-deep .ProseMirror blockquote{border-left:4px solid var(--ate-blockquote-border-color);margin:1em 0;background:var(--ate-blockquote-background);padding:.5em 1em;border-radius:0 4px 4px 0}:host ::ng-deep .ProseMirror code{background:var(--ate-code-background);color:var(--ate-code-color);border:1px solid var(--ate-code-border-color);padding:.15em .4em;border-radius:4px;font-family:JetBrains Mono,Fira Code,Monaco,Consolas,monospace;font-size:.85em;font-weight:500}:host ::ng-deep .ProseMirror pre{background:var(--ate-code-block-background);color:var(--ate-code-block-color);border:1px solid var(--ate-code-block-border-color);padding:1em;border-radius:var(--ate-border-radius);overflow-x:auto;margin:1em 0}:host ::ng-deep .ProseMirror pre code{background:none;color:inherit;border:none;padding:0}:host ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:var(--ate-placeholder-color);pointer-events:none;float:left;height:0}:host ::ng-deep .ProseMirror[contenteditable=false]{pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img{cursor:default;pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img:hover{transform:none;box-shadow:0 2px 8px #0000001a}:host ::ng-deep .ProseMirror[contenteditable=false] img.ProseMirror-selectednode{outline:none}:host ::ng-deep .ProseMirror img{position:relative;display:inline-block;max-width:100%;height:auto;cursor:pointer;transition:all .2s ease;border:2px solid transparent;border-radius:var(--ate-image-border-radius)}:host ::ng-deep .ProseMirror img:hover{border-color:var(--ate-border-color);box-shadow:0 2px 4px #0000001a}:host ::ng-deep .ProseMirror img.ProseMirror-selectednode{border-color:var(--ate-image-selected-color);box-shadow:0 0 0 3px var(--ate-primary-light-alpha);transition:all .2s ease}:host ::ng-deep .ProseMirror .tiptap-image{max-width:100%;height:auto;border-radius:16px;box-shadow:0 4px 20px #00000014;margin:.5em 0;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);display:block;filter:brightness(1) contrast(1)}:host ::ng-deep .ProseMirror .tiptap-image:hover{box-shadow:0 8px 30px #0000001f;filter:brightness(1.02) contrast(1.02)}:host ::ng-deep .ProseMirror .tiptap-image.ProseMirror-selectednode{outline:2px solid var(--ate-primary);outline-offset:2px;border-radius:16px;box-shadow:0 0 0 4px var(--ate-primary-light-alpha)}:host ::ng-deep .image-container{margin:.5em 0;text-align:center;border-radius:16px;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1)}:host ::ng-deep .image-container.image-align-left{text-align:left}:host ::ng-deep .image-container.image-align-center{text-align:center}:host ::ng-deep .image-container.image-align-right{text-align:right}:host ::ng-deep .image-container img{display:inline-block;max-width:100%;height:auto;border-radius:16px}:host ::ng-deep .resizable-image-container{position:relative;display:inline-block;margin:.5em 0}:host ::ng-deep .resize-controls{position:absolute;inset:0;pointer-events:none;z-index:1000}:host ::ng-deep .resize-handle{position:absolute;width:12px;height:12px;background:var(--ate-primary);border:2px solid var(--ate-surface);border-radius:50%;pointer-events:all;cursor:pointer;z-index:1001;transition:all .15s ease;box-shadow:0 2px 6px #0003}:host ::ng-deep .resize-handle:hover{background:var(--ate-primary);box-shadow:0 3px 8px #0000004d}:host ::ng-deep .resize-handle:active{background:var(--ate-primary)}:host ::ng-deep .resize-handle-n:hover,:host ::ng-deep .resize-handle-s:hover{transform:translate(-50%) scale(1.2)}:host ::ng-deep .resize-handle-w:hover,:host ::ng-deep .resize-handle-e:hover{transform:translateY(-50%) scale(1.2)}:host ::ng-deep .resize-handle-n:active,:host ::ng-deep .resize-handle-s:active{transform:translate(-50%) scale(.9)}:host ::ng-deep .resize-handle-w:active,:host ::ng-deep .resize-handle-e:active{transform:translateY(-50%) scale(.9)}:host ::ng-deep .resize-handle-nw:hover,:host ::ng-deep .resize-handle-ne:hover,:host ::ng-deep .resize-handle-sw:hover,:host ::ng-deep .resize-handle-se:hover{transform:scale(1.2)}:host ::ng-deep .resize-handle-nw:active,:host ::ng-deep .resize-handle-ne:active,:host ::ng-deep .resize-handle-sw:active,:host ::ng-deep .resize-handle-se:active{transform:scale(.9)}:host ::ng-deep .resize-handle-nw{top:0;left:-6px;cursor:nw-resize}:host ::ng-deep .resize-handle-n{top:0;left:50%;transform:translate(-50%);cursor:n-resize}:host ::ng-deep .resize-handle-ne{top:0;right:-6px;cursor:ne-resize}:host ::ng-deep .resize-handle-w{top:50%;left:-6px;transform:translateY(-50%);cursor:w-resize}:host ::ng-deep .resize-handle-e{top:50%;right:-6px;transform:translateY(-50%);cursor:e-resize}:host ::ng-deep .resize-handle-sw{bottom:0;left:-6px;cursor:sw-resize}:host ::ng-deep .resize-handle-s{bottom:0;left:50%;transform:translate(-50%);cursor:s-resize}:host ::ng-deep .resize-handle-se{bottom:0;right:-6px;cursor:se-resize}:host ::ng-deep body.resizing{-webkit-user-select:none;user-select:none;cursor:crosshair}:host ::ng-deep body.resizing .ProseMirror{pointer-events:none}:host ::ng-deep body.resizing .ProseMirror .tiptap-image{pointer-events:none}:host ::ng-deep .image-size-info{position:absolute;bottom:-20px;left:50%;transform:translate(-50%);background:#000c;color:#fff;padding:2px 6px;border-radius:3px;font-size:11px;white-space:nowrap;opacity:0;transition:opacity .2s ease}:host ::ng-deep .image-container:hover .image-size-info{opacity:1}:host ::ng-deep .ProseMirror table{border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed;width:100%;border-radius:8px;overflow:hidden}:host ::ng-deep .ProseMirror table td,:host ::ng-deep .ProseMirror table th{border:none;border-right:1px solid var(--ate-table-border-color);border-bottom:1px solid var(--ate-table-border-color);box-sizing:border-box;min-width:1em;padding:8px 12px;position:relative;vertical-align:top;text-align:left}:host ::ng-deep .ProseMirror table td{background:var(--ate-table-cell-background)}:host ::ng-deep .ProseMirror table td:first-child,:host ::ng-deep .ProseMirror table th:first-child{border-left:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child td,:host ::ng-deep .ProseMirror table tr:first-child th{border-top:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child th:first-child{border-top-left-radius:8px}:host ::ng-deep .ProseMirror table tr:first-child th:last-child{border-top-right-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:first-child{border-bottom-left-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:last-child{border-bottom-right-radius:8px}:host ::ng-deep .ProseMirror table th{background:var(--ate-table-header-background);font-weight:600;color:var(--ate-table-header-color)}:host ::ng-deep .ProseMirror table .selectedCell:after{background:var(--ate-table-cell-selected-background);content:\"\";inset:0;pointer-events:none;position:absolute;z-index:2}:host ::ng-deep .ProseMirror table .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;background-color:var(--ate-table-resize-handle-color);opacity:0;transition:opacity .2s ease}:host ::ng-deep .ProseMirror table:hover .column-resize-handle{opacity:1}:host ::ng-deep .ProseMirror table .column-resize-handle:hover{background-color:var(--ate-focus-color)}:host ::ng-deep .ProseMirror .tableWrapper{overflow-x:auto;margin:1em 0;border-radius:8px}:host ::ng-deep .ProseMirror .tableWrapper table{margin:0;border-radius:8px;min-width:600px;overflow:hidden}:host ::ng-deep .ProseMirror table p{margin:0}:host ::ng-deep .ProseMirror table tbody tr:hover td{background-color:var(--ate-table-row-hover-background)}\n"], dependencies: [{ kind: "component", type: TiptapToolbarComponent, selector: "tiptap-toolbar", inputs: ["editor", "config", "imageUpload", "floating"] }, { kind: "component", type: TiptapBubbleMenuComponent, selector: "tiptap-bubble-menu", inputs: ["config"] }, { kind: "component", type: TiptapImageBubbleMenuComponent, selector: "tiptap-image-bubble-menu", inputs: ["config"] }, { kind: "component", type: TiptapTableBubbleMenuComponent, selector: "tiptap-table-bubble-menu", inputs: ["config"] }, { kind: "component", type: TiptapCellBubbleMenuComponent, selector: "tiptap-cell-bubble-menu", inputs: ["config"] }, { kind: "component", type: TiptapSlashCommandsComponent, selector: "tiptap-slash-commands", inputs: ["editor", "config"] }, { kind: "component", type: TiptapLinkBubbleMenuComponent, selector: "tiptap-link-bubble-menu", inputs: ["editor"] }, { kind: "component", type: TiptapColorBubbleMenuComponent, selector: "tiptap-color-bubble-menu", inputs: ["editor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6207
+ ], viewQueries: [{ propertyName: "editorElement", first: true, predicate: ["editorElement"], descendants: true, isSignal: true }], hostDirectives: [{ directive: NoopValueAccessorDirective }], ngImport: i0, template: `
6208
+ <div class="tiptap-editor">
6209
+ <!-- Toolbar -->
6210
+ @if (editable() && !mergedDisabled() && finalShowToolbar() && editor()) {
6211
+ <tiptap-toolbar
6212
+ [editor]="editor()!"
6213
+ [config]="finalToolbarConfig()"
6214
+ [imageUpload]="finalImageUploadConfig()"
6215
+ [floating]="finalFloatingToolbar()"
6216
+ (mouseenter)="hideBubbleMenus()"
6217
+ (mouseleave)="showBubbleMenus()"
6218
+ />
6219
+ }
6220
+
6221
+ @if (finalShowEditToggle() && !mergedDisabled()) {
6222
+ <tiptap-edit-toggle
6223
+ [editable]="editable()"
6224
+ [translations]="currentTranslations()"
6225
+ (toggle)="toggleEditMode($event)"
6226
+ />
6227
+ }
6228
+
6229
+ <!-- Editor Content -->
6230
+ <div
6231
+ #editorElement
6232
+ class="tiptap-content"
6233
+ [class.drag-over]="isDragOver()"
6234
+ (dragover)="onDragOver($event)"
6235
+ (drop)="onDrop($event)"
6236
+ (click)="onEditorClick($event)"
6237
+ ></div>
6238
+
6239
+ <!-- Text Bubble Menu -->
6240
+ @if (editable() && finalShowBubbleMenu() && editor()) {
6241
+ <tiptap-bubble-menu
6242
+ [editor]="editor()!"
6243
+ [config]="finalBubbleMenuConfig()"
6244
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6245
+ ></tiptap-bubble-menu>
6246
+ }
6247
+
6248
+ <!-- Image Bubble Menu -->
6249
+ @if (editable() && finalShowImageBubbleMenu() && editor()) {
6250
+ <tiptap-image-bubble-menu
6251
+ [editor]="editor()!"
6252
+ [config]="finalImageBubbleMenuConfig()"
6253
+ [imageUpload]="finalImageUploadConfig()"
6254
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6255
+ ></tiptap-image-bubble-menu>
6256
+ }
6257
+
6258
+ <!-- Link Bubble Menu -->
6259
+ @if (editable() && editor()) {
6260
+ <tiptap-link-bubble-menu
6261
+ [editor]="editor()!"
6262
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6263
+ ></tiptap-link-bubble-menu>
6264
+ }
6265
+
6266
+ <!-- Color Bubble Menu -->
6267
+ @if (editable() && editor()) {
6268
+ <tiptap-color-bubble-menu
6269
+ [editor]="editor()!"
6270
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6271
+ ></tiptap-color-bubble-menu>
6272
+ }
6273
+
6274
+ <!-- Slash Commands -->
6275
+ @if (editable() && finalEnableSlashCommands() && editor()) {
6276
+ <tiptap-slash-commands
6277
+ [editor]="editor()!"
6278
+ [config]="finalSlashCommandsConfig()"
6279
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6280
+ ></tiptap-slash-commands>
6281
+ }
6282
+
6283
+ <!-- Table Menu -->
6284
+ @if (editable() && finalShowTableBubbleMenu() && editor()) {
6285
+ <tiptap-table-bubble-menu
6286
+ [editor]="editor()!"
6287
+ [config]="finalTableBubbleMenuConfig()"
6288
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6289
+ ></tiptap-table-bubble-menu>
6290
+ }
6291
+
6292
+ <!-- Cell Menu -->
6293
+ @if (editable() && finalShowCellBubbleMenu() && editor()) {
6294
+ <tiptap-cell-bubble-menu
6295
+ [editor]="editor()!"
6296
+ [config]="finalCellBubbleMenuConfig()"
6297
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6298
+ ></tiptap-cell-bubble-menu>
6299
+ }
6300
+
6301
+ <!-- Counters -->
6302
+ @if (editable() && !mergedDisabled() && finalShowFooter() && (finalShowCharacterCount() || finalShowWordCount())) {
6303
+ <div class="character-count" [class.limit-reached]="finalMaxCharacters() && characterCount() >= finalMaxCharacters()!">
6304
+ @if (finalShowCharacterCount()) {
6305
+ {{ characterCount() }}
6306
+ {{ currentTranslations().editor.character }}{{ characterCount() > 1 ? "s" : "" }}
6307
+ @if (finalMaxCharacters()) {
6308
+ / {{ finalMaxCharacters() }}
6309
+ }
6310
+ }
6311
+
6312
+ @if (finalShowCharacterCount() && finalShowWordCount()) {
6313
+ ,
6314
+ }
6315
+
6316
+ @if (finalShowWordCount()) {
6317
+ {{ wordCount() }}
6318
+ {{ currentTranslations().editor.word }}{{ wordCount() > 1 ? "s" : "" }}
6319
+ }
6320
+ </div>
6321
+ }
6322
+ </div>
6323
+ `, isInline: true, styles: [":host{--ate-primary: #2563eb;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 90%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 95%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-surface: #ffffff;--ate-surface-secondary: #f8f9fa;--ate-surface-tertiary: #f1f5f9;--ate-text: #2d3748;--ate-text-secondary: #64748b;--ate-text-muted: #a0aec0;--ate-border: #e2e8f0;--ate-highlight-bg: #fef08a;--ate-highlight-color: #854d0e;--ate-button-hover: #f1f5f9;--ate-button-active: #e2e8f0;--ate-error-color: #c53030;--ate-error-bg: #fed7d7;--ate-error-border: #feb2b2;--ate-border-color: var(--ate-border);--ate-border-width: 2px;--ate-border-radius: 12px;--ate-focus-color: var(--ate-primary);--ate-background: var(--ate-surface);--ate-sub-border-radius: 8px;--ate-text-color: var(--ate-text);--ate-placeholder-color: var(--ate-text-muted);--ate-line-height: 1.6;--ate-content-padding: 16px;--ate-menu-bg: var(--ate-surface);--ate-menu-border-radius: var(--ate-border-radius);--ate-menu-border: var(--ate-border);--ate-menu-shadow: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -2px rgba(0, 0, 0, .05);--ate-menu-padding: 6px;--ate-toolbar-padding: var(--ate-menu-padding);--ate-toolbar-background: var(--ate-surface-secondary);--ate-toolbar-border-color: var(--ate-border);--ate-toolbar-button-color: var(--ate-text-secondary);--ate-toolbar-button-hover-background: transparent;--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-counter-color: var(--ate-text-secondary);--ate-counter-background: var(--ate-surface-secondary);--ate-counter-border-color: var(--ate-border);--ate-drag-background: #f0f8ff;--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-border);--ate-blockquote-background: var(--ate-surface-secondary);--ate-code-background: var(--ate-surface-secondary);--ate-code-color: var(--ate-text-secondary);--ate-code-border-color: var(--ate-border);--ate-code-block-background: #0f172a;--ate-code-block-color: #e2e8f0;--ate-code-block-border-color: var(--ate-border);--ate-image-border-radius: 16px;--ate-image-selected-color: var(--ate-primary);--ate-scrollbar-width: 10px;--ate-scrollbar-thumb: var(--ate-border);--ate-scrollbar-thumb-hover: var(--ate-text-muted);--ate-scrollbar-track: transparent;--ate-table-border-color: var(--ate-border);--ate-table-header-background: var(--ate-surface-secondary);--ate-table-header-color: var(--ate-text);--ate-table-cell-background: var(--ate-surface);--ate-table-cell-selected-background: var(--ate-primary-light);--ate-table-resize-handle-color: var(--ate-primary);--ate-table-row-hover-background: var(--ate-primary-lighter)}:host(.dark),:host([data-theme=\"dark\"]){--ate-primary: #3b82f6;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 92%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 80%);--ate-surface: #020617;--ate-surface-secondary: #0f172a;--ate-surface-tertiary: #1e293b;--ate-text: #f8fafc;--ate-text-secondary: #94a3b8;--ate-text-muted: #64748b;--ate-border: #1e293b;--ate-highlight-bg: #854d0e;--ate-highlight-color: #fef08a;--ate-button-hover: #1e293b;--ate-button-active: #0f172a;--ate-menu-border: rgba(255, 255, 255, .1);--ate-menu-shadow: 0 20px 25px -5px rgba(0, 0, 0, .3), 0 10px 10px -5px rgba(0, 0, 0, .2);--ate-error-color: #f87171;--ate-error-bg: #450a0a;--ate-error-border: #7f1d1d;--ate-drag-background: var(--ate-surface-tertiary);--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-primary);--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-button-hover: var(--ate-surface-tertiary);--ate-button-active: var(--ate-surface-secondary);--ate-scrollbar-thumb: var(--ate-surface-tertiary);--ate-scrollbar-thumb-hover: var(--ate-text-muted)}:host(.fill-container){display:block;height:100%}.tiptap-editor{border:var(--ate-border-width) solid var(--ate-border-color);border-radius:var(--ate-border-radius);background:var(--ate-background);overflow:visible;transition:border-color .2s ease;position:relative}:host(.floating-toolbar) .tiptap-editor{overflow:visible}:host(.fill-container) .tiptap-editor{display:flex;flex-direction:column;height:100%}:host(.fill-container) .tiptap-content-wrapper{flex:1;min-height:0}:host(.fill-container) .tiptap-content{flex:1;min-height:0;overflow-y:auto}.tiptap-editor:focus-within{border-color:var(--ate-focus-color)}.tiptap-content{min-height:var(--editor-min-height, 200px);height:var(--editor-height, auto);max-height:var(--editor-max-height, none);overflow-y:var(--editor-overflow, visible);outline:none;position:relative;scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}:host(.is-disabled) .tiptap-content{cursor:not-allowed;opacity:.7;-webkit-user-select:none;user-select:none;pointer-events:none;background-color:var(--ate-surface-tertiary)}:host(.is-readonly) .tiptap-content{cursor:default;-webkit-user-select:text;user-select:text}:host(.is-readonly) .tiptap-content ::ng-deep .tiptap-link{cursor:pointer;pointer-events:auto}.tiptap-content::-webkit-scrollbar{width:var(--ate-scrollbar-width)}.tiptap-content-wrapper{position:relative;display:flex;flex-direction:column;min-height:0}.tiptap-content-wrapper .tiptap-content{flex:1}.tiptap-content::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.tiptap-content::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.tiptap-content::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}.tiptap-content.drag-over{background:var(--ate-drag-background);border:2px dashed var(--ate-drag-border-color)}.character-count{font-size:12px;color:var(--ate-counter-color);text-align:right;border-top:1px solid var(--ate-counter-border-color);background:var(--ate-counter-background);transition:color .2s ease;border-bottom-left-radius:calc(var(--ate-border-radius) - var(--ate-border-width));border-bottom-right-radius:calc(var(--ate-border-radius) - var(--ate-border-width))}.character-count.limit-reached{color:var(--ate-error-color, #ef4444);font-weight:600}:host ::ng-deep .ProseMirror{padding:var(--ate-content-padding);outline:none;line-height:var(--ate-line-height);color:var(--ate-text-color);min-height:100%;height:100%;word-wrap:break-word;overflow-wrap:break-word}:host ::ng-deep .ProseMirror h1{font-size:2em;font-weight:700;margin-top:0;margin-bottom:.5em}:host ::ng-deep .ProseMirror h2{font-size:1.5em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror h3{font-size:1.25em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror p{margin:.5em 0}:host ::ng-deep .ProseMirror ul,:host ::ng-deep .ProseMirror ol{padding-left:2em;margin:.5em 0}:host ::ng-deep .ProseMirror blockquote{border-left:4px solid var(--ate-blockquote-border-color);margin:1em 0;background:var(--ate-blockquote-background);padding:.5em 1em;border-radius:0 4px 4px 0}:host ::ng-deep .ProseMirror code{background:var(--ate-code-background);color:var(--ate-code-color);border:1px solid var(--ate-code-border-color);padding:.15em .4em;border-radius:4px;font-family:JetBrains Mono,Fira Code,Monaco,Consolas,monospace;font-size:.85em;font-weight:500}:host ::ng-deep .ProseMirror pre{background:var(--ate-code-block-background);color:var(--ate-code-block-color);border:1px solid var(--ate-code-block-border-color);padding:1em;border-radius:var(--ate-border-radius);overflow-x:auto;margin:1em 0}:host ::ng-deep .ProseMirror pre code{background:none;color:inherit;border:none;padding:0}:host ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:var(--ate-placeholder-color);pointer-events:none;float:left;height:0}:host ::ng-deep .ProseMirror[contenteditable=false]{pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img{cursor:default;pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img:hover{transform:none;box-shadow:0 2px 8px #0000001a}:host ::ng-deep .ProseMirror[contenteditable=false] img.ProseMirror-selectednode{outline:none}:host ::ng-deep .ProseMirror img{position:relative;display:inline-block;max-width:100%;height:auto;cursor:pointer;transition:all .2s ease;border:2px solid transparent;border-radius:var(--ate-image-border-radius)}:host ::ng-deep .ProseMirror img:hover{border-color:var(--ate-border-color);box-shadow:0 2px 4px #0000001a}:host ::ng-deep .ProseMirror img.ProseMirror-selectednode{border-color:var(--ate-image-selected-color);box-shadow:0 0 0 3px var(--ate-primary-light-alpha);transition:all .2s ease}:host ::ng-deep .ProseMirror .tiptap-image{max-width:100%;height:auto;border-radius:var(--ate-image-border-radius);box-shadow:0 4px 20px #00000014;margin:.5em 0;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);display:block;filter:brightness(1) contrast(1)}:host ::ng-deep .ProseMirror .tiptap-image:hover{box-shadow:0 8px 30px #0000001f;filter:brightness(1.02) contrast(1.02)}:host ::ng-deep .ProseMirror .tiptap-image.ProseMirror-selectednode{outline:2px solid var(--ate-primary);outline-offset:2px;border-radius:var(--ate-image-border-radius);box-shadow:0 0 0 4px var(--ate-primary-light-alpha)}:host ::ng-deep .image-container{margin:.5em 0;text-align:center;border-radius:16px;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1)}:host ::ng-deep .image-container.image-align-left{text-align:left}:host ::ng-deep .image-container.image-align-center{text-align:center}:host ::ng-deep .image-container.image-align-right{text-align:right}:host ::ng-deep .image-container img{display:inline-block;max-width:100%;height:auto;border-radius:16px}:host ::ng-deep .resizable-image-container{position:relative;display:inline-block;margin:.5em 0}:host ::ng-deep .resize-controls{position:absolute;inset:0;pointer-events:none;z-index:1000}:host ::ng-deep .resize-handle{position:absolute;width:12px;height:12px;background:var(--ate-primary);border:2px solid var(--ate-surface);border-radius:50%;pointer-events:all;cursor:pointer;z-index:1001;transition:all .15s ease;box-shadow:0 2px 6px #0003}:host ::ng-deep .resize-handle:hover{background:var(--ate-primary);box-shadow:0 3px 8px #0000004d}:host ::ng-deep .resize-handle:active{background:var(--ate-primary)}:host ::ng-deep .resize-handle-n:hover,:host ::ng-deep .resize-handle-s:hover{transform:translate(-50%) scale(1.2)}:host ::ng-deep .resize-handle-w:hover,:host ::ng-deep .resize-handle-e:hover{transform:translateY(-50%) scale(1.2)}:host ::ng-deep .resize-handle-n:active,:host ::ng-deep .resize-handle-s:active{transform:translate(-50%) scale(.9)}:host ::ng-deep .resize-handle-w:active,:host ::ng-deep .resize-handle-e:active{transform:translateY(-50%) scale(.9)}:host ::ng-deep .resize-handle-nw:hover,:host ::ng-deep .resize-handle-ne:hover,:host ::ng-deep .resize-handle-sw:hover,:host ::ng-deep .resize-handle-se:hover{transform:scale(1.2)}:host ::ng-deep .resize-handle-nw:active,:host ::ng-deep .resize-handle-ne:active,:host ::ng-deep .resize-handle-sw:active,:host ::ng-deep .resize-handle-se:active{transform:scale(.9)}:host ::ng-deep .resize-handle-nw{top:0;left:-6px;cursor:nw-resize}:host ::ng-deep .resize-handle-n{top:0;left:50%;transform:translate(-50%);cursor:n-resize}:host ::ng-deep .resize-handle-ne{top:0;right:-6px;cursor:ne-resize}:host ::ng-deep .resize-handle-w{top:50%;left:-6px;transform:translateY(-50%);cursor:w-resize}:host ::ng-deep .resize-handle-e{top:50%;right:-6px;transform:translateY(-50%);cursor:e-resize}:host ::ng-deep .resize-handle-sw{bottom:0;left:-6px;cursor:sw-resize}:host ::ng-deep .resize-handle-s{bottom:0;left:50%;transform:translate(-50%);cursor:s-resize}:host ::ng-deep .resize-handle-se{bottom:0;right:-6px;cursor:se-resize}:host ::ng-deep body.resizing{-webkit-user-select:none;user-select:none;cursor:crosshair}:host ::ng-deep body.resizing .ProseMirror{pointer-events:none}:host ::ng-deep body.resizing .ProseMirror .tiptap-image{pointer-events:none}:host ::ng-deep .image-size-info{position:absolute;bottom:-20px;left:50%;transform:translate(-50%);background:#000c;color:#fff;padding:2px 6px;border-radius:3px;font-size:11px;white-space:nowrap;opacity:0;transition:opacity .2s ease}:host ::ng-deep .image-container:hover .image-size-info{opacity:1}:host ::ng-deep .ProseMirror table{border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed;width:100%;border-radius:8px;overflow:hidden}:host ::ng-deep .ProseMirror table td,:host ::ng-deep .ProseMirror table th{border:none;border-right:1px solid var(--ate-table-border-color);border-bottom:1px solid var(--ate-table-border-color);box-sizing:border-box;min-width:1em;padding:8px 12px;position:relative;vertical-align:top;text-align:left}:host ::ng-deep .ProseMirror table td{background:var(--ate-table-cell-background)}:host ::ng-deep .ProseMirror table td:first-child,:host ::ng-deep .ProseMirror table th:first-child{border-left:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child td,:host ::ng-deep .ProseMirror table tr:first-child th{border-top:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child th:first-child{border-top-left-radius:8px}:host ::ng-deep .ProseMirror table tr:first-child th:last-child{border-top-right-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:first-child{border-bottom-left-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:last-child{border-bottom-right-radius:8px}:host ::ng-deep .ProseMirror table th{background:var(--ate-table-header-background);font-weight:600;color:var(--ate-table-header-color)}:host ::ng-deep .ProseMirror table .selectedCell:after{background:var(--ate-table-cell-selected-background);content:\"\";inset:0;pointer-events:none;position:absolute;z-index:2}:host ::ng-deep .ProseMirror table .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;background-color:var(--ate-table-resize-handle-color);opacity:0;transition:opacity .2s ease}:host ::ng-deep .ProseMirror table:hover .column-resize-handle{opacity:1}:host ::ng-deep .ProseMirror table .column-resize-handle:hover{background-color:var(--ate-focus-color)}:host ::ng-deep .ProseMirror .tableWrapper{overflow-x:auto;margin:1em 0;border-radius:8px}:host ::ng-deep .ProseMirror .tableWrapper table{margin:0;border-radius:8px;min-width:600px;overflow:hidden}:host ::ng-deep .ProseMirror table p{margin:0}:host ::ng-deep .ProseMirror table tbody tr:hover td{background-color:var(--ate-table-row-hover-background)}\n"], dependencies: [{ kind: "component", type: TiptapToolbarComponent, selector: "tiptap-toolbar", inputs: ["editor", "config", "imageUpload", "floating"] }, { kind: "component", type: TiptapBubbleMenuComponent, selector: "tiptap-bubble-menu", inputs: ["config"] }, { kind: "component", type: TiptapImageBubbleMenuComponent, selector: "tiptap-image-bubble-menu", inputs: ["config", "imageUpload"] }, { kind: "component", type: TiptapTableBubbleMenuComponent, selector: "tiptap-table-bubble-menu", inputs: ["config"] }, { kind: "component", type: TiptapCellBubbleMenuComponent, selector: "tiptap-cell-bubble-menu", inputs: ["config"] }, { kind: "component", type: TiptapSlashCommandsComponent, selector: "tiptap-slash-commands", inputs: ["editor", "config"] }, { kind: "component", type: TiptapLinkBubbleMenuComponent, selector: "tiptap-link-bubble-menu", inputs: ["editor"] }, { kind: "component", type: TiptapColorBubbleMenuComponent, selector: "tiptap-color-bubble-menu", inputs: ["editor"] }, { kind: "component", type: TiptapEditToggleComponent, selector: "tiptap-edit-toggle", inputs: ["editable", "translations"], outputs: ["toggle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6193
6324
  }
6194
6325
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: AngularTiptapEditorComponent, decorators: [{
6195
6326
  type: Component,
6196
6327
  args: [{ selector: "angular-tiptap-editor", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [NoopValueAccessorDirective], host: {
6197
- '[class.fill-container]': 'fillContainer()',
6198
- '[class.floating-toolbar]': 'floatingToolbar()',
6328
+ '[class.fill-container]': 'finalFillContainer()',
6329
+ '[class.floating-toolbar]': 'finalFloatingToolbar()',
6199
6330
  '[class.is-readonly]': '!editable() && !mergedDisabled()',
6200
6331
  '[class.is-disabled]': 'mergedDisabled()',
6201
- '[style.--ate-border-width]': "seamless() || mergedDisabled() ? '0' : null",
6202
- '[style.--ate-background]': "seamless() ? 'transparent' : (mergedDisabled() ? 'var(--ate-surface-tertiary)' : null)",
6203
- '[style.--ate-toolbar-border-color]': "seamless() ? 'transparent' : null",
6204
- '[style.--ate-counter-background]': "seamless() ? 'transparent' : null",
6205
- '[style.--ate-counter-border-color]': "seamless() ? 'transparent' : null",
6332
+ '[style.--ate-border-width]': "finalSeamless() || mergedDisabled() ? '0' : null",
6333
+ '[style.--ate-background]': "finalSeamless() ? 'transparent' : (mergedDisabled() ? 'var(--ate-surface-tertiary)' : null)",
6334
+ '[style.--ate-toolbar-border-color]': "finalSeamless() ? 'transparent' : null",
6335
+ '[style.--ate-counter-background]': "finalSeamless() ? 'transparent' : null",
6336
+ '[style.--ate-counter-border-color]': "finalSeamless() ? 'transparent' : null",
6337
+ '[class.dark]': "config().theme === 'dark'",
6338
+ '[attr.data-theme]': "config().theme",
6206
6339
  }, imports: [
6207
6340
  TiptapToolbarComponent,
6208
6341
  TiptapBubbleMenuComponent,
@@ -6212,119 +6345,129 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
6212
6345
  TiptapSlashCommandsComponent,
6213
6346
  TiptapLinkBubbleMenuComponent,
6214
6347
  TiptapColorBubbleMenuComponent,
6348
+ TiptapEditToggleComponent,
6215
6349
  ], providers: [
6216
6350
  EditorCommandsService,
6217
6351
  ImageService,
6218
6352
  ColorPickerService,
6219
6353
  LinkService,
6220
- ], template: `
6221
- <div class="tiptap-editor">
6222
- <!-- Toolbar -->
6223
- @if (editable() && !mergedDisabled() && showToolbar() && editor()) {
6224
- <tiptap-toolbar
6225
- [editor]="editor()!"
6226
- [config]="toolbarConfig()"
6227
- [imageUpload]="imageUploadConfig()"
6228
- [floating]="floatingToolbar()"
6229
- (mouseenter)="hideBubbleMenus()"
6230
- (mouseleave)="showBubbleMenus()"
6231
- />
6232
- }
6233
-
6234
- <!-- Editor Content -->
6235
- <div
6236
- #editorElement
6237
- class="tiptap-content"
6238
- [class.drag-over]="isDragOver()"
6239
- (dragover)="onDragOver($event)"
6240
- (drop)="onDrop($event)"
6241
- (click)="onEditorClick($event)"
6242
- ></div>
6243
-
6244
- <!-- Text Bubble Menu -->
6245
- @if (editable() && showBubbleMenu() && editor()) {
6246
- <tiptap-bubble-menu
6247
- [editor]="editor()!"
6248
- [config]="bubbleMenuConfig()"
6249
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6250
- ></tiptap-bubble-menu>
6251
- }
6252
-
6253
- <!-- Image Bubble Menu -->
6254
- @if (editable() && showImageBubbleMenu() && editor()) {
6255
- <tiptap-image-bubble-menu
6256
- [editor]="editor()!"
6257
- [config]="imageBubbleMenuConfig()"
6258
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6259
- ></tiptap-image-bubble-menu>
6260
- }
6261
-
6262
- <!-- Link Bubble Menu -->
6263
- @if (editable() && editor()) {
6264
- <tiptap-link-bubble-menu
6265
- [editor]="editor()!"
6266
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6267
- ></tiptap-link-bubble-menu>
6268
- }
6269
-
6270
- <!-- Color Bubble Menu -->
6271
- @if (editable() && editor()) {
6272
- <tiptap-color-bubble-menu
6273
- [editor]="editor()!"
6274
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6275
- ></tiptap-color-bubble-menu>
6276
- }
6277
-
6278
- <!-- Slash Commands -->
6279
- @if (editable() && enableSlashCommands() && editor()) {
6280
- <tiptap-slash-commands
6281
- [editor]="editor()!"
6282
- [config]="slashCommandsConfigComputed()"
6283
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6284
- ></tiptap-slash-commands>
6285
- }
6286
-
6287
- <!-- Table Menu -->
6288
- @if (editable() && editor()) {
6289
- <tiptap-table-bubble-menu
6290
- [editor]="editor()!"
6291
- [config]="tableBubbleMenuConfig()"
6292
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6293
- ></tiptap-table-bubble-menu>
6294
- }
6295
-
6296
- <!-- Cell Menu -->
6297
- @if (editable() && editor()) {
6298
- <tiptap-cell-bubble-menu
6299
- [editor]="editor()!"
6300
- [config]="cellBubbleMenuConfig()"
6301
- [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6302
- ></tiptap-cell-bubble-menu>
6303
- }
6304
-
6305
- <!-- Counters -->
6306
- @if (editable() && !mergedDisabled() && showFooter() && (showCharacterCount() || showWordCount())) {
6307
- <div class="character-count" [class.limit-reached]="maxCharacters() && characterCount() >= maxCharacters()!">
6308
- @if (showCharacterCount()) {
6309
- {{ characterCount() }}
6310
- {{ currentTranslations().editor.character }}{{ characterCount() > 1 ? "s" : "" }}
6311
- @if (maxCharacters()) {
6312
- / {{ maxCharacters() }}
6313
- }
6314
- }
6315
-
6316
- @if (showCharacterCount() && showWordCount()) {
6317
- ,
6318
- }
6319
-
6320
- @if (showWordCount()) {
6321
- {{ wordCount() }}
6322
- {{ currentTranslations().editor.word }}{{ wordCount() > 1 ? "s" : "" }}
6323
- }
6324
- </div>
6325
- }
6326
- </div>
6327
- `, styles: [":host{--ate-primary: #2563eb;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 90%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 95%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-surface: #ffffff;--ate-surface-secondary: #f8f9fa;--ate-surface-tertiary: #f1f5f9;--ate-text: #2d3748;--ate-text-secondary: #64748b;--ate-text-muted: #a0aec0;--ate-border: #e2e8f0;--ate-highlight-bg: #fef08a;--ate-highlight-color: #854d0e;--ate-button-hover: #f1f5f9;--ate-button-active: #e2e8f0;--ate-error-color: #c53030;--ate-error-bg: #fed7d7;--ate-error-border: #feb2b2;--ate-border-color: var(--ate-border);--ate-border-width: 2px;--ate-border-radius: 12px;--ate-focus-color: var(--ate-primary);--ate-background: var(--ate-surface);--ate-sub-border-radius: 8px;--ate-text-color: var(--ate-text);--ate-placeholder-color: var(--ate-text-muted);--ate-line-height: 1.6;--ate-content-padding: 16px;--ate-menu-bg: var(--ate-surface-secondary);--ate-menu-border: var(--ate-border);--ate-menu-shadow: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -2px rgba(0, 0, 0, .05);--ate-menu-padding: 6px;--ate-toolbar-padding: var(--ate-menu-padding);--ate-toolbar-background: var(--ate-surface-secondary);--ate-toolbar-border-color: var(--ate-border);--ate-toolbar-button-color: var(--ate-text-secondary);--ate-toolbar-button-hover-background: transparent;--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-counter-color: var(--ate-text-secondary);--ate-counter-background: var(--ate-surface-secondary);--ate-counter-border-color: var(--ate-border);--ate-drag-background: #f0f8ff;--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-border);--ate-blockquote-background: var(--ate-surface-secondary);--ate-code-background: var(--ate-surface-secondary);--ate-code-color: var(--ate-text-secondary);--ate-code-border-color: var(--ate-border);--ate-code-block-background: #0f172a;--ate-code-block-color: #e2e8f0;--ate-code-block-border-color: var(--ate-border);--ate-image-border-radius: var(--ate-sub-border-radius);--ate-image-selected-color: var(--ate-primary);--ate-scrollbar-width: 10px;--ate-scrollbar-thumb: var(--ate-border);--ate-scrollbar-thumb-hover: var(--ate-text-muted);--ate-scrollbar-track: transparent;--ate-table-border-color: var(--ate-border);--ate-table-header-background: var(--ate-surface-secondary);--ate-table-header-color: var(--ate-text);--ate-table-cell-background: var(--ate-surface);--ate-table-cell-selected-background: var(--ate-primary-light);--ate-table-resize-handle-color: var(--ate-primary);--ate-table-row-hover-background: var(--ate-primary-lighter)}:host(.dark),:host([data-theme=\"dark\"]){--ate-primary: #3b82f6;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 92%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 80%);--ate-surface: #020617;--ate-surface-secondary: #0f172a;--ate-surface-tertiary: #1e293b;--ate-text: #f8fafc;--ate-text-secondary: #94a3b8;--ate-text-muted: #64748b;--ate-border: #1e293b;--ate-highlight-bg: #854d0e;--ate-highlight-color: #fef08a;--ate-button-hover: #1e293b;--ate-button-active: #0f172a;--ate-menu-border: rgba(255, 255, 255, .1);--ate-menu-shadow: 0 20px 25px -5px rgba(0, 0, 0, .3), 0 10px 10px -5px rgba(0, 0, 0, .2);--ate-error-color: #f87171;--ate-error-bg: #450a0a;--ate-error-border: #7f1d1d;--ate-drag-background: var(--ate-surface-tertiary);--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-primary);--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-button-hover: var(--ate-surface-tertiary);--ate-button-active: var(--ate-surface-secondary);--ate-scrollbar-thumb: var(--ate-surface-tertiary);--ate-scrollbar-thumb-hover: var(--ate-text-muted)}:host(.fill-container){display:block;height:100%}.tiptap-editor{border:var(--ate-border-width) solid var(--ate-border-color);border-radius:var(--ate-border-radius);background:var(--ate-background);overflow:hidden;transition:border-color .2s ease;position:relative}:host(.floating-toolbar) .tiptap-editor{overflow:visible}:host(.fill-container) .tiptap-editor{display:flex;flex-direction:column;height:100%}:host(.fill-container) .tiptap-content{flex:1;min-height:0;overflow-y:auto}.tiptap-editor:focus-within{border-color:var(--ate-focus-color)}.tiptap-content{min-height:var(--editor-min-height, 200px);height:var(--editor-height, auto);max-height:var(--editor-max-height, none);overflow-y:var(--editor-overflow, visible);outline:none;position:relative;scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}:host(.is-disabled) .tiptap-content{cursor:not-allowed;opacity:.7;-webkit-user-select:none;user-select:none;pointer-events:none;background-color:var(--ate-surface-tertiary)}:host(.is-readonly) .tiptap-content{cursor:default;-webkit-user-select:text;user-select:text}:host(.is-readonly) .tiptap-content ::ng-deep .tiptap-link{cursor:pointer;pointer-events:auto}.tiptap-content::-webkit-scrollbar{width:var(--ate-scrollbar-width);height:var(--ate-scrollbar-width)}.tiptap-content::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.tiptap-content::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.tiptap-content::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}.tiptap-content.drag-over{background:var(--ate-drag-background);border:2px dashed var(--ate-drag-border-color)}.character-count{padding:8px var(--ate-content-padding);font-size:12px;color:var(--ate-counter-color);text-align:right;border-top:1px solid var(--ate-counter-border-color);background:var(--ate-counter-background);transition:color .2s ease;border-bottom-left-radius:calc(var(--ate-border-radius) - var(--ate-border-width));border-bottom-right-radius:calc(var(--ate-border-radius) - var(--ate-border-width))}.character-count.limit-reached{color:var(--ate-error-color, #ef4444);font-weight:600}:host ::ng-deep .ProseMirror{padding:var(--ate-content-padding);outline:none;line-height:var(--ate-line-height);color:var(--ate-text-color);min-height:100%;height:100%;word-wrap:break-word;overflow-wrap:break-word}:host ::ng-deep .ProseMirror h1{font-size:2em;font-weight:700;margin-top:0;margin-bottom:.5em}:host ::ng-deep .ProseMirror h2{font-size:1.5em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror h3{font-size:1.25em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror p{margin:.5em 0}:host ::ng-deep .ProseMirror ul,:host ::ng-deep .ProseMirror ol{padding-left:2em;margin:.5em 0}:host ::ng-deep .ProseMirror blockquote{border-left:4px solid var(--ate-blockquote-border-color);margin:1em 0;background:var(--ate-blockquote-background);padding:.5em 1em;border-radius:0 4px 4px 0}:host ::ng-deep .ProseMirror code{background:var(--ate-code-background);color:var(--ate-code-color);border:1px solid var(--ate-code-border-color);padding:.15em .4em;border-radius:4px;font-family:JetBrains Mono,Fira Code,Monaco,Consolas,monospace;font-size:.85em;font-weight:500}:host ::ng-deep .ProseMirror pre{background:var(--ate-code-block-background);color:var(--ate-code-block-color);border:1px solid var(--ate-code-block-border-color);padding:1em;border-radius:var(--ate-border-radius);overflow-x:auto;margin:1em 0}:host ::ng-deep .ProseMirror pre code{background:none;color:inherit;border:none;padding:0}:host ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:var(--ate-placeholder-color);pointer-events:none;float:left;height:0}:host ::ng-deep .ProseMirror[contenteditable=false]{pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img{cursor:default;pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img:hover{transform:none;box-shadow:0 2px 8px #0000001a}:host ::ng-deep .ProseMirror[contenteditable=false] img.ProseMirror-selectednode{outline:none}:host ::ng-deep .ProseMirror img{position:relative;display:inline-block;max-width:100%;height:auto;cursor:pointer;transition:all .2s ease;border:2px solid transparent;border-radius:var(--ate-image-border-radius)}:host ::ng-deep .ProseMirror img:hover{border-color:var(--ate-border-color);box-shadow:0 2px 4px #0000001a}:host ::ng-deep .ProseMirror img.ProseMirror-selectednode{border-color:var(--ate-image-selected-color);box-shadow:0 0 0 3px var(--ate-primary-light-alpha);transition:all .2s ease}:host ::ng-deep .ProseMirror .tiptap-image{max-width:100%;height:auto;border-radius:16px;box-shadow:0 4px 20px #00000014;margin:.5em 0;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);display:block;filter:brightness(1) contrast(1)}:host ::ng-deep .ProseMirror .tiptap-image:hover{box-shadow:0 8px 30px #0000001f;filter:brightness(1.02) contrast(1.02)}:host ::ng-deep .ProseMirror .tiptap-image.ProseMirror-selectednode{outline:2px solid var(--ate-primary);outline-offset:2px;border-radius:16px;box-shadow:0 0 0 4px var(--ate-primary-light-alpha)}:host ::ng-deep .image-container{margin:.5em 0;text-align:center;border-radius:16px;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1)}:host ::ng-deep .image-container.image-align-left{text-align:left}:host ::ng-deep .image-container.image-align-center{text-align:center}:host ::ng-deep .image-container.image-align-right{text-align:right}:host ::ng-deep .image-container img{display:inline-block;max-width:100%;height:auto;border-radius:16px}:host ::ng-deep .resizable-image-container{position:relative;display:inline-block;margin:.5em 0}:host ::ng-deep .resize-controls{position:absolute;inset:0;pointer-events:none;z-index:1000}:host ::ng-deep .resize-handle{position:absolute;width:12px;height:12px;background:var(--ate-primary);border:2px solid var(--ate-surface);border-radius:50%;pointer-events:all;cursor:pointer;z-index:1001;transition:all .15s ease;box-shadow:0 2px 6px #0003}:host ::ng-deep .resize-handle:hover{background:var(--ate-primary);box-shadow:0 3px 8px #0000004d}:host ::ng-deep .resize-handle:active{background:var(--ate-primary)}:host ::ng-deep .resize-handle-n:hover,:host ::ng-deep .resize-handle-s:hover{transform:translate(-50%) scale(1.2)}:host ::ng-deep .resize-handle-w:hover,:host ::ng-deep .resize-handle-e:hover{transform:translateY(-50%) scale(1.2)}:host ::ng-deep .resize-handle-n:active,:host ::ng-deep .resize-handle-s:active{transform:translate(-50%) scale(.9)}:host ::ng-deep .resize-handle-w:active,:host ::ng-deep .resize-handle-e:active{transform:translateY(-50%) scale(.9)}:host ::ng-deep .resize-handle-nw:hover,:host ::ng-deep .resize-handle-ne:hover,:host ::ng-deep .resize-handle-sw:hover,:host ::ng-deep .resize-handle-se:hover{transform:scale(1.2)}:host ::ng-deep .resize-handle-nw:active,:host ::ng-deep .resize-handle-ne:active,:host ::ng-deep .resize-handle-sw:active,:host ::ng-deep .resize-handle-se:active{transform:scale(.9)}:host ::ng-deep .resize-handle-nw{top:0;left:-6px;cursor:nw-resize}:host ::ng-deep .resize-handle-n{top:0;left:50%;transform:translate(-50%);cursor:n-resize}:host ::ng-deep .resize-handle-ne{top:0;right:-6px;cursor:ne-resize}:host ::ng-deep .resize-handle-w{top:50%;left:-6px;transform:translateY(-50%);cursor:w-resize}:host ::ng-deep .resize-handle-e{top:50%;right:-6px;transform:translateY(-50%);cursor:e-resize}:host ::ng-deep .resize-handle-sw{bottom:0;left:-6px;cursor:sw-resize}:host ::ng-deep .resize-handle-s{bottom:0;left:50%;transform:translate(-50%);cursor:s-resize}:host ::ng-deep .resize-handle-se{bottom:0;right:-6px;cursor:se-resize}:host ::ng-deep body.resizing{-webkit-user-select:none;user-select:none;cursor:crosshair}:host ::ng-deep body.resizing .ProseMirror{pointer-events:none}:host ::ng-deep body.resizing .ProseMirror .tiptap-image{pointer-events:none}:host ::ng-deep .image-size-info{position:absolute;bottom:-20px;left:50%;transform:translate(-50%);background:#000c;color:#fff;padding:2px 6px;border-radius:3px;font-size:11px;white-space:nowrap;opacity:0;transition:opacity .2s ease}:host ::ng-deep .image-container:hover .image-size-info{opacity:1}:host ::ng-deep .ProseMirror table{border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed;width:100%;border-radius:8px;overflow:hidden}:host ::ng-deep .ProseMirror table td,:host ::ng-deep .ProseMirror table th{border:none;border-right:1px solid var(--ate-table-border-color);border-bottom:1px solid var(--ate-table-border-color);box-sizing:border-box;min-width:1em;padding:8px 12px;position:relative;vertical-align:top;text-align:left}:host ::ng-deep .ProseMirror table td{background:var(--ate-table-cell-background)}:host ::ng-deep .ProseMirror table td:first-child,:host ::ng-deep .ProseMirror table th:first-child{border-left:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child td,:host ::ng-deep .ProseMirror table tr:first-child th{border-top:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child th:first-child{border-top-left-radius:8px}:host ::ng-deep .ProseMirror table tr:first-child th:last-child{border-top-right-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:first-child{border-bottom-left-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:last-child{border-bottom-right-radius:8px}:host ::ng-deep .ProseMirror table th{background:var(--ate-table-header-background);font-weight:600;color:var(--ate-table-header-color)}:host ::ng-deep .ProseMirror table .selectedCell:after{background:var(--ate-table-cell-selected-background);content:\"\";inset:0;pointer-events:none;position:absolute;z-index:2}:host ::ng-deep .ProseMirror table .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;background-color:var(--ate-table-resize-handle-color);opacity:0;transition:opacity .2s ease}:host ::ng-deep .ProseMirror table:hover .column-resize-handle{opacity:1}:host ::ng-deep .ProseMirror table .column-resize-handle:hover{background-color:var(--ate-focus-color)}:host ::ng-deep .ProseMirror .tableWrapper{overflow-x:auto;margin:1em 0;border-radius:8px}:host ::ng-deep .ProseMirror .tableWrapper table{margin:0;border-radius:8px;min-width:600px;overflow:hidden}:host ::ng-deep .ProseMirror table p{margin:0}:host ::ng-deep .ProseMirror table tbody tr:hover td{background-color:var(--ate-table-row-hover-background)}\n"] }]
6354
+ ], template: `
6355
+ <div class="tiptap-editor">
6356
+ <!-- Toolbar -->
6357
+ @if (editable() && !mergedDisabled() && finalShowToolbar() && editor()) {
6358
+ <tiptap-toolbar
6359
+ [editor]="editor()!"
6360
+ [config]="finalToolbarConfig()"
6361
+ [imageUpload]="finalImageUploadConfig()"
6362
+ [floating]="finalFloatingToolbar()"
6363
+ (mouseenter)="hideBubbleMenus()"
6364
+ (mouseleave)="showBubbleMenus()"
6365
+ />
6366
+ }
6367
+
6368
+ @if (finalShowEditToggle() && !mergedDisabled()) {
6369
+ <tiptap-edit-toggle
6370
+ [editable]="editable()"
6371
+ [translations]="currentTranslations()"
6372
+ (toggle)="toggleEditMode($event)"
6373
+ />
6374
+ }
6375
+
6376
+ <!-- Editor Content -->
6377
+ <div
6378
+ #editorElement
6379
+ class="tiptap-content"
6380
+ [class.drag-over]="isDragOver()"
6381
+ (dragover)="onDragOver($event)"
6382
+ (drop)="onDrop($event)"
6383
+ (click)="onEditorClick($event)"
6384
+ ></div>
6385
+
6386
+ <!-- Text Bubble Menu -->
6387
+ @if (editable() && finalShowBubbleMenu() && editor()) {
6388
+ <tiptap-bubble-menu
6389
+ [editor]="editor()!"
6390
+ [config]="finalBubbleMenuConfig()"
6391
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6392
+ ></tiptap-bubble-menu>
6393
+ }
6394
+
6395
+ <!-- Image Bubble Menu -->
6396
+ @if (editable() && finalShowImageBubbleMenu() && editor()) {
6397
+ <tiptap-image-bubble-menu
6398
+ [editor]="editor()!"
6399
+ [config]="finalImageBubbleMenuConfig()"
6400
+ [imageUpload]="finalImageUploadConfig()"
6401
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6402
+ ></tiptap-image-bubble-menu>
6403
+ }
6404
+
6405
+ <!-- Link Bubble Menu -->
6406
+ @if (editable() && editor()) {
6407
+ <tiptap-link-bubble-menu
6408
+ [editor]="editor()!"
6409
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6410
+ ></tiptap-link-bubble-menu>
6411
+ }
6412
+
6413
+ <!-- Color Bubble Menu -->
6414
+ @if (editable() && editor()) {
6415
+ <tiptap-color-bubble-menu
6416
+ [editor]="editor()!"
6417
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6418
+ ></tiptap-color-bubble-menu>
6419
+ }
6420
+
6421
+ <!-- Slash Commands -->
6422
+ @if (editable() && finalEnableSlashCommands() && editor()) {
6423
+ <tiptap-slash-commands
6424
+ [editor]="editor()!"
6425
+ [config]="finalSlashCommandsConfig()"
6426
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6427
+ ></tiptap-slash-commands>
6428
+ }
6429
+
6430
+ <!-- Table Menu -->
6431
+ @if (editable() && finalShowTableBubbleMenu() && editor()) {
6432
+ <tiptap-table-bubble-menu
6433
+ [editor]="editor()!"
6434
+ [config]="finalTableBubbleMenuConfig()"
6435
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6436
+ ></tiptap-table-bubble-menu>
6437
+ }
6438
+
6439
+ <!-- Cell Menu -->
6440
+ @if (editable() && finalShowCellBubbleMenu() && editor()) {
6441
+ <tiptap-cell-bubble-menu
6442
+ [editor]="editor()!"
6443
+ [config]="finalCellBubbleMenuConfig()"
6444
+ [style.display]="editorFullyInitialized() ? 'block' : 'none'"
6445
+ ></tiptap-cell-bubble-menu>
6446
+ }
6447
+
6448
+ <!-- Counters -->
6449
+ @if (editable() && !mergedDisabled() && finalShowFooter() && (finalShowCharacterCount() || finalShowWordCount())) {
6450
+ <div class="character-count" [class.limit-reached]="finalMaxCharacters() && characterCount() >= finalMaxCharacters()!">
6451
+ @if (finalShowCharacterCount()) {
6452
+ {{ characterCount() }}
6453
+ {{ currentTranslations().editor.character }}{{ characterCount() > 1 ? "s" : "" }}
6454
+ @if (finalMaxCharacters()) {
6455
+ / {{ finalMaxCharacters() }}
6456
+ }
6457
+ }
6458
+
6459
+ @if (finalShowCharacterCount() && finalShowWordCount()) {
6460
+ ,
6461
+ }
6462
+
6463
+ @if (finalShowWordCount()) {
6464
+ {{ wordCount() }}
6465
+ {{ currentTranslations().editor.word }}{{ wordCount() > 1 ? "s" : "" }}
6466
+ }
6467
+ </div>
6468
+ }
6469
+ </div>
6470
+ `, styles: [":host{--ate-primary: #2563eb;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 90%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 95%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-surface: #ffffff;--ate-surface-secondary: #f8f9fa;--ate-surface-tertiary: #f1f5f9;--ate-text: #2d3748;--ate-text-secondary: #64748b;--ate-text-muted: #a0aec0;--ate-border: #e2e8f0;--ate-highlight-bg: #fef08a;--ate-highlight-color: #854d0e;--ate-button-hover: #f1f5f9;--ate-button-active: #e2e8f0;--ate-error-color: #c53030;--ate-error-bg: #fed7d7;--ate-error-border: #feb2b2;--ate-border-color: var(--ate-border);--ate-border-width: 2px;--ate-border-radius: 12px;--ate-focus-color: var(--ate-primary);--ate-background: var(--ate-surface);--ate-sub-border-radius: 8px;--ate-text-color: var(--ate-text);--ate-placeholder-color: var(--ate-text-muted);--ate-line-height: 1.6;--ate-content-padding: 16px;--ate-menu-bg: var(--ate-surface);--ate-menu-border-radius: var(--ate-border-radius);--ate-menu-border: var(--ate-border);--ate-menu-shadow: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -2px rgba(0, 0, 0, .05);--ate-menu-padding: 6px;--ate-toolbar-padding: var(--ate-menu-padding);--ate-toolbar-background: var(--ate-surface-secondary);--ate-toolbar-border-color: var(--ate-border);--ate-toolbar-button-color: var(--ate-text-secondary);--ate-toolbar-button-hover-background: transparent;--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-counter-color: var(--ate-text-secondary);--ate-counter-background: var(--ate-surface-secondary);--ate-counter-border-color: var(--ate-border);--ate-drag-background: #f0f8ff;--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-border);--ate-blockquote-background: var(--ate-surface-secondary);--ate-code-background: var(--ate-surface-secondary);--ate-code-color: var(--ate-text-secondary);--ate-code-border-color: var(--ate-border);--ate-code-block-background: #0f172a;--ate-code-block-color: #e2e8f0;--ate-code-block-border-color: var(--ate-border);--ate-image-border-radius: 16px;--ate-image-selected-color: var(--ate-primary);--ate-scrollbar-width: 10px;--ate-scrollbar-thumb: var(--ate-border);--ate-scrollbar-thumb-hover: var(--ate-text-muted);--ate-scrollbar-track: transparent;--ate-table-border-color: var(--ate-border);--ate-table-header-background: var(--ate-surface-secondary);--ate-table-header-color: var(--ate-text);--ate-table-cell-background: var(--ate-surface);--ate-table-cell-selected-background: var(--ate-primary-light);--ate-table-resize-handle-color: var(--ate-primary);--ate-table-row-hover-background: var(--ate-primary-lighter)}:host(.dark),:host([data-theme=\"dark\"]){--ate-primary: #3b82f6;--ate-primary-contrast: #ffffff;--ate-primary-light: color-mix(in srgb, var(--ate-primary), transparent 85%);--ate-primary-lighter: color-mix(in srgb, var(--ate-primary), transparent 92%);--ate-primary-light-alpha: color-mix(in srgb, var(--ate-primary), transparent 80%);--ate-surface: #020617;--ate-surface-secondary: #0f172a;--ate-surface-tertiary: #1e293b;--ate-text: #f8fafc;--ate-text-secondary: #94a3b8;--ate-text-muted: #64748b;--ate-border: #1e293b;--ate-highlight-bg: #854d0e;--ate-highlight-color: #fef08a;--ate-button-hover: #1e293b;--ate-button-active: #0f172a;--ate-menu-border: rgba(255, 255, 255, .1);--ate-menu-shadow: 0 20px 25px -5px rgba(0, 0, 0, .3), 0 10px 10px -5px rgba(0, 0, 0, .2);--ate-error-color: #f87171;--ate-error-bg: #450a0a;--ate-error-border: #7f1d1d;--ate-drag-background: var(--ate-surface-tertiary);--ate-drag-border-color: var(--ate-primary);--ate-blockquote-border-color: var(--ate-primary);--ate-toolbar-button-active-background: var(--ate-primary-light);--ate-toolbar-button-active-color: var(--ate-primary);--ate-button-hover: var(--ate-surface-tertiary);--ate-button-active: var(--ate-surface-secondary);--ate-scrollbar-thumb: var(--ate-surface-tertiary);--ate-scrollbar-thumb-hover: var(--ate-text-muted)}:host(.fill-container){display:block;height:100%}.tiptap-editor{border:var(--ate-border-width) solid var(--ate-border-color);border-radius:var(--ate-border-radius);background:var(--ate-background);overflow:visible;transition:border-color .2s ease;position:relative}:host(.floating-toolbar) .tiptap-editor{overflow:visible}:host(.fill-container) .tiptap-editor{display:flex;flex-direction:column;height:100%}:host(.fill-container) .tiptap-content-wrapper{flex:1;min-height:0}:host(.fill-container) .tiptap-content{flex:1;min-height:0;overflow-y:auto}.tiptap-editor:focus-within{border-color:var(--ate-focus-color)}.tiptap-content{min-height:var(--editor-min-height, 200px);height:var(--editor-height, auto);max-height:var(--editor-max-height, none);overflow-y:var(--editor-overflow, visible);outline:none;position:relative;scrollbar-width:thin;scrollbar-color:var(--ate-scrollbar-thumb) var(--ate-scrollbar-track)}:host(.is-disabled) .tiptap-content{cursor:not-allowed;opacity:.7;-webkit-user-select:none;user-select:none;pointer-events:none;background-color:var(--ate-surface-tertiary)}:host(.is-readonly) .tiptap-content{cursor:default;-webkit-user-select:text;user-select:text}:host(.is-readonly) .tiptap-content ::ng-deep .tiptap-link{cursor:pointer;pointer-events:auto}.tiptap-content::-webkit-scrollbar{width:var(--ate-scrollbar-width)}.tiptap-content-wrapper{position:relative;display:flex;flex-direction:column;min-height:0}.tiptap-content-wrapper .tiptap-content{flex:1}.tiptap-content::-webkit-scrollbar-track{background:var(--ate-scrollbar-track)}.tiptap-content::-webkit-scrollbar-thumb{background:var(--ate-scrollbar-thumb);border:3px solid transparent;background-clip:content-box;border-radius:10px}.tiptap-content::-webkit-scrollbar-thumb:hover{background:var(--ate-scrollbar-thumb-hover);background-clip:content-box}.tiptap-content.drag-over{background:var(--ate-drag-background);border:2px dashed var(--ate-drag-border-color)}.character-count{font-size:12px;color:var(--ate-counter-color);text-align:right;border-top:1px solid var(--ate-counter-border-color);background:var(--ate-counter-background);transition:color .2s ease;border-bottom-left-radius:calc(var(--ate-border-radius) - var(--ate-border-width));border-bottom-right-radius:calc(var(--ate-border-radius) - var(--ate-border-width))}.character-count.limit-reached{color:var(--ate-error-color, #ef4444);font-weight:600}:host ::ng-deep .ProseMirror{padding:var(--ate-content-padding);outline:none;line-height:var(--ate-line-height);color:var(--ate-text-color);min-height:100%;height:100%;word-wrap:break-word;overflow-wrap:break-word}:host ::ng-deep .ProseMirror h1{font-size:2em;font-weight:700;margin-top:0;margin-bottom:.5em}:host ::ng-deep .ProseMirror h2{font-size:1.5em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror h3{font-size:1.25em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror p{margin:.5em 0}:host ::ng-deep .ProseMirror ul,:host ::ng-deep .ProseMirror ol{padding-left:2em;margin:.5em 0}:host ::ng-deep .ProseMirror blockquote{border-left:4px solid var(--ate-blockquote-border-color);margin:1em 0;background:var(--ate-blockquote-background);padding:.5em 1em;border-radius:0 4px 4px 0}:host ::ng-deep .ProseMirror code{background:var(--ate-code-background);color:var(--ate-code-color);border:1px solid var(--ate-code-border-color);padding:.15em .4em;border-radius:4px;font-family:JetBrains Mono,Fira Code,Monaco,Consolas,monospace;font-size:.85em;font-weight:500}:host ::ng-deep .ProseMirror pre{background:var(--ate-code-block-background);color:var(--ate-code-block-color);border:1px solid var(--ate-code-block-border-color);padding:1em;border-radius:var(--ate-border-radius);overflow-x:auto;margin:1em 0}:host ::ng-deep .ProseMirror pre code{background:none;color:inherit;border:none;padding:0}:host ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:var(--ate-placeholder-color);pointer-events:none;float:left;height:0}:host ::ng-deep .ProseMirror[contenteditable=false]{pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img{cursor:default;pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img:hover{transform:none;box-shadow:0 2px 8px #0000001a}:host ::ng-deep .ProseMirror[contenteditable=false] img.ProseMirror-selectednode{outline:none}:host ::ng-deep .ProseMirror img{position:relative;display:inline-block;max-width:100%;height:auto;cursor:pointer;transition:all .2s ease;border:2px solid transparent;border-radius:var(--ate-image-border-radius)}:host ::ng-deep .ProseMirror img:hover{border-color:var(--ate-border-color);box-shadow:0 2px 4px #0000001a}:host ::ng-deep .ProseMirror img.ProseMirror-selectednode{border-color:var(--ate-image-selected-color);box-shadow:0 0 0 3px var(--ate-primary-light-alpha);transition:all .2s ease}:host ::ng-deep .ProseMirror .tiptap-image{max-width:100%;height:auto;border-radius:var(--ate-image-border-radius);box-shadow:0 4px 20px #00000014;margin:.5em 0;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);display:block;filter:brightness(1) contrast(1)}:host ::ng-deep .ProseMirror .tiptap-image:hover{box-shadow:0 8px 30px #0000001f;filter:brightness(1.02) contrast(1.02)}:host ::ng-deep .ProseMirror .tiptap-image.ProseMirror-selectednode{outline:2px solid var(--ate-primary);outline-offset:2px;border-radius:var(--ate-image-border-radius);box-shadow:0 0 0 4px var(--ate-primary-light-alpha)}:host ::ng-deep .image-container{margin:.5em 0;text-align:center;border-radius:16px;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1)}:host ::ng-deep .image-container.image-align-left{text-align:left}:host ::ng-deep .image-container.image-align-center{text-align:center}:host ::ng-deep .image-container.image-align-right{text-align:right}:host ::ng-deep .image-container img{display:inline-block;max-width:100%;height:auto;border-radius:16px}:host ::ng-deep .resizable-image-container{position:relative;display:inline-block;margin:.5em 0}:host ::ng-deep .resize-controls{position:absolute;inset:0;pointer-events:none;z-index:1000}:host ::ng-deep .resize-handle{position:absolute;width:12px;height:12px;background:var(--ate-primary);border:2px solid var(--ate-surface);border-radius:50%;pointer-events:all;cursor:pointer;z-index:1001;transition:all .15s ease;box-shadow:0 2px 6px #0003}:host ::ng-deep .resize-handle:hover{background:var(--ate-primary);box-shadow:0 3px 8px #0000004d}:host ::ng-deep .resize-handle:active{background:var(--ate-primary)}:host ::ng-deep .resize-handle-n:hover,:host ::ng-deep .resize-handle-s:hover{transform:translate(-50%) scale(1.2)}:host ::ng-deep .resize-handle-w:hover,:host ::ng-deep .resize-handle-e:hover{transform:translateY(-50%) scale(1.2)}:host ::ng-deep .resize-handle-n:active,:host ::ng-deep .resize-handle-s:active{transform:translate(-50%) scale(.9)}:host ::ng-deep .resize-handle-w:active,:host ::ng-deep .resize-handle-e:active{transform:translateY(-50%) scale(.9)}:host ::ng-deep .resize-handle-nw:hover,:host ::ng-deep .resize-handle-ne:hover,:host ::ng-deep .resize-handle-sw:hover,:host ::ng-deep .resize-handle-se:hover{transform:scale(1.2)}:host ::ng-deep .resize-handle-nw:active,:host ::ng-deep .resize-handle-ne:active,:host ::ng-deep .resize-handle-sw:active,:host ::ng-deep .resize-handle-se:active{transform:scale(.9)}:host ::ng-deep .resize-handle-nw{top:0;left:-6px;cursor:nw-resize}:host ::ng-deep .resize-handle-n{top:0;left:50%;transform:translate(-50%);cursor:n-resize}:host ::ng-deep .resize-handle-ne{top:0;right:-6px;cursor:ne-resize}:host ::ng-deep .resize-handle-w{top:50%;left:-6px;transform:translateY(-50%);cursor:w-resize}:host ::ng-deep .resize-handle-e{top:50%;right:-6px;transform:translateY(-50%);cursor:e-resize}:host ::ng-deep .resize-handle-sw{bottom:0;left:-6px;cursor:sw-resize}:host ::ng-deep .resize-handle-s{bottom:0;left:50%;transform:translate(-50%);cursor:s-resize}:host ::ng-deep .resize-handle-se{bottom:0;right:-6px;cursor:se-resize}:host ::ng-deep body.resizing{-webkit-user-select:none;user-select:none;cursor:crosshair}:host ::ng-deep body.resizing .ProseMirror{pointer-events:none}:host ::ng-deep body.resizing .ProseMirror .tiptap-image{pointer-events:none}:host ::ng-deep .image-size-info{position:absolute;bottom:-20px;left:50%;transform:translate(-50%);background:#000c;color:#fff;padding:2px 6px;border-radius:3px;font-size:11px;white-space:nowrap;opacity:0;transition:opacity .2s ease}:host ::ng-deep .image-container:hover .image-size-info{opacity:1}:host ::ng-deep .ProseMirror table{border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed;width:100%;border-radius:8px;overflow:hidden}:host ::ng-deep .ProseMirror table td,:host ::ng-deep .ProseMirror table th{border:none;border-right:1px solid var(--ate-table-border-color);border-bottom:1px solid var(--ate-table-border-color);box-sizing:border-box;min-width:1em;padding:8px 12px;position:relative;vertical-align:top;text-align:left}:host ::ng-deep .ProseMirror table td{background:var(--ate-table-cell-background)}:host ::ng-deep .ProseMirror table td:first-child,:host ::ng-deep .ProseMirror table th:first-child{border-left:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child td,:host ::ng-deep .ProseMirror table tr:first-child th{border-top:1px solid var(--ate-table-border-color)}:host ::ng-deep .ProseMirror table tr:first-child th:first-child{border-top-left-radius:8px}:host ::ng-deep .ProseMirror table tr:first-child th:last-child{border-top-right-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:first-child{border-bottom-left-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:last-child{border-bottom-right-radius:8px}:host ::ng-deep .ProseMirror table th{background:var(--ate-table-header-background);font-weight:600;color:var(--ate-table-header-color)}:host ::ng-deep .ProseMirror table .selectedCell:after{background:var(--ate-table-cell-selected-background);content:\"\";inset:0;pointer-events:none;position:absolute;z-index:2}:host ::ng-deep .ProseMirror table .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;background-color:var(--ate-table-resize-handle-color);opacity:0;transition:opacity .2s ease}:host ::ng-deep .ProseMirror table:hover .column-resize-handle{opacity:1}:host ::ng-deep .ProseMirror table .column-resize-handle:hover{background-color:var(--ate-focus-color)}:host ::ng-deep .ProseMirror .tableWrapper{overflow-x:auto;margin:1em 0;border-radius:8px}:host ::ng-deep .ProseMirror .tableWrapper table{margin:0;border-radius:8px;min-width:600px;overflow:hidden}:host ::ng-deep .ProseMirror table p{margin:0}:host ::ng-deep .ProseMirror table tbody tr:hover td{background-color:var(--ate-table-row-hover-background)}\n"] }]
6328
6471
  }], ctorParameters: () => [] });
6329
6472
 
6330
6473
  /*