@flogeez/angular-tiptap-editor 3.0.1 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -5,8 +5,26 @@ import { Editor, NodeConfig, Extension, Node as Node$2, Mark, EditorOptions, JSO
5
5
  import { Observable } from 'rxjs';
6
6
  import { Node as Node$1 } from '@tiptap/pm/model';
7
7
  import { ControlValueAccessor } from '@angular/forms';
8
+ import * as _popperjs_core from '@popperjs/core';
8
9
  import { Decoration, EditorView, NodeView } from '@tiptap/pm/view';
9
10
 
11
+ /**
12
+ * Interface representing a single item in the slash commands menu.
13
+ */
14
+ interface AteSlashCommandItem {
15
+ title: string;
16
+ description: string;
17
+ icon: string;
18
+ keywords: string[];
19
+ command: (editor: Editor) => void;
20
+ }
21
+ /**
22
+ * Custom slash commands configuration.
23
+ */
24
+ interface AteCustomSlashCommands {
25
+ commands?: AteSlashCommandItem[];
26
+ }
27
+
10
28
  type SupportedLocale = "en" | "fr" | (string & {});
11
29
  interface AteTranslations {
12
30
  toolbar: {
@@ -138,11 +156,15 @@ interface AteTranslations {
138
156
  invalidFileType: string;
139
157
  dragDropText: string;
140
158
  changeImage: string;
159
+ downloadImage: string;
141
160
  deleteImage: string;
142
161
  resizeSmall: string;
143
162
  resizeMedium: string;
144
163
  resizeLarge: string;
145
164
  resizeOriginal: string;
165
+ alignLeft: string;
166
+ alignCenter: string;
167
+ alignRight: string;
146
168
  resizing: string;
147
169
  compressing: string;
148
170
  compressionError: string;
@@ -312,11 +334,15 @@ declare class AteI18nService {
312
334
  invalidFileType: string;
313
335
  dragDropText: string;
314
336
  changeImage: string;
337
+ downloadImage: string;
315
338
  deleteImage: string;
316
339
  resizeSmall: string;
317
340
  resizeMedium: string;
318
341
  resizeLarge: string;
319
342
  resizeOriginal: string;
343
+ alignLeft: string;
344
+ alignCenter: string;
345
+ alignRight: string;
320
346
  resizing: string;
321
347
  compressing: string;
322
348
  compressionError: string;
@@ -401,17 +427,6 @@ declare class AteI18nService {
401
427
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<AteI18nService>;
402
428
  }
403
429
 
404
- interface AteSlashCommandItem {
405
- title: string;
406
- description: string;
407
- icon: string;
408
- keywords: string[];
409
- command: (editor: Editor) => void;
410
- }
411
- interface AteCustomSlashCommands {
412
- commands?: AteSlashCommandItem[];
413
- }
414
-
415
430
  type AteStateCalculator = (editor: Editor) => Partial<{
416
431
  [K in keyof AteEditorStateSnapshot]: AteEditorStateSnapshot[K] extends object ? Partial<AteEditorStateSnapshot[K]> : AteEditorStateSnapshot[K];
417
432
  }>;
@@ -690,6 +705,7 @@ declare class AteEditorCommandsService {
690
705
  insertContent(editor: Editor, content: string): void;
691
706
  insertImage(editor: Editor, options?: AteImageUploadOptions): Promise<void>;
692
707
  uploadImage(editor: Editor, file: File, options?: AteImageUploadOptions): Promise<void>;
708
+ downloadImage(editor: Editor): void;
693
709
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AteEditorCommandsService, never>;
694
710
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<AteEditorCommandsService>;
695
711
  }
@@ -768,7 +784,7 @@ interface AteCustomBubbleMenuItem {
768
784
  /**
769
785
  * Clés des options du menu bulle d'image
770
786
  */
771
- declare const ATE_IMAGE_BUBBLE_MENU_KEYS: readonly ["changeImage", "resizeSmall", "resizeMedium", "resizeLarge", "resizeOriginal", "deleteImage", "separator"];
787
+ declare const ATE_IMAGE_BUBBLE_MENU_KEYS: readonly ["changeImage", "downloadImage", "resizeSmall", "resizeMedium", "resizeLarge", "resizeOriginal", "alignLeft", "alignCenter", "alignRight", "deleteImage", "separator"];
772
788
  type AteImageBubbleMenuKey = (typeof ATE_IMAGE_BUBBLE_MENU_KEYS)[number];
773
789
  type AteImageBubbleMenuConfig = Partial<Record<AteImageBubbleMenuKey, boolean>>;
774
790
  /**
@@ -974,6 +990,8 @@ interface AteEditorConfig {
974
990
  showTableMenu?: boolean;
975
991
  /** Show or hide the cell menu */
976
992
  showCellMenu?: boolean;
993
+ /** Whether to allow image downloading from bubble menu */
994
+ downloadImage?: boolean;
977
995
  /** Enable or disable slash commands (/) */
978
996
  enableSlashCommands?: boolean;
979
997
  /** Maximum number of characters allowed */
@@ -1063,7 +1081,7 @@ declare class AngularTiptapEditorComponent implements AfterViewInit, OnDestroy {
1063
1081
  showBubbleMenu: _angular_core.InputSignal<boolean | undefined>;
1064
1082
  bubbleMenu: _angular_core.InputSignal<Partial<AteBubbleMenuConfig> | undefined>;
1065
1083
  showImageBubbleMenu: _angular_core.InputSignal<boolean | undefined>;
1066
- imageBubbleMenu: _angular_core.InputSignal<Partial<Partial<Record<"separator" | "changeImage" | "resizeSmall" | "resizeMedium" | "resizeLarge" | "resizeOriginal" | "deleteImage", boolean>>> | undefined>;
1084
+ imageBubbleMenu: _angular_core.InputSignal<Partial<Partial<Record<"separator" | "alignLeft" | "alignCenter" | "alignRight" | "changeImage" | "downloadImage" | "resizeSmall" | "resizeMedium" | "resizeLarge" | "resizeOriginal" | "deleteImage", boolean>>> | undefined>;
1067
1085
  toolbar: _angular_core.InputSignal<Partial<AteToolbarConfig> | undefined>;
1068
1086
  showTableBubbleMenu: _angular_core.InputSignal<boolean | undefined>;
1069
1087
  tableBubbleMenu: _angular_core.InputSignal<Partial<Partial<Record<"addColumnBefore" | "addColumnAfter" | "deleteColumn" | "addRowBefore" | "addRowAfter" | "deleteRow" | "deleteTable" | "toggleHeaderColumn" | "toggleHeaderRow" | "separator", boolean>>> | undefined>;
@@ -1144,7 +1162,7 @@ declare class AngularTiptapEditorComponent implements AfterViewInit, OnDestroy {
1144
1162
  readonly finalShowBubbleMenu: _angular_core.Signal<boolean>;
1145
1163
  readonly finalBubbleMenuConfig: _angular_core.Signal<AteBubbleMenuConfig>;
1146
1164
  readonly finalShowImageBubbleMenu: _angular_core.Signal<boolean>;
1147
- readonly finalImageBubbleMenuConfig: _angular_core.Signal<Partial<Record<"separator" | "changeImage" | "resizeSmall" | "resizeMedium" | "resizeLarge" | "resizeOriginal" | "deleteImage", boolean>>>;
1165
+ readonly finalImageBubbleMenuConfig: _angular_core.Signal<Partial<Record<"separator" | "alignLeft" | "alignCenter" | "alignRight" | "changeImage" | "downloadImage" | "resizeSmall" | "resizeMedium" | "resizeLarge" | "resizeOriginal" | "deleteImage", boolean>>>;
1148
1166
  readonly finalShowTableBubbleMenu: _angular_core.Signal<boolean>;
1149
1167
  readonly finalTableBubbleMenuConfig: _angular_core.Signal<Partial<Record<"addColumnBefore" | "addColumnAfter" | "deleteColumn" | "addRowBefore" | "addRowAfter" | "deleteRow" | "deleteTable" | "toggleHeaderColumn" | "toggleHeaderRow" | "separator", boolean>>>;
1150
1168
  readonly finalShowCellBubbleMenu: _angular_core.Signal<boolean>;
@@ -1162,15 +1180,11 @@ declare class AngularTiptapEditorComponent implements AfterViewInit, OnDestroy {
1162
1180
  readonly finalAngularNodesConfig: _angular_core.Signal<AteAngularNode[]>;
1163
1181
  readonly finalImageUploadConfig: _angular_core.Signal<{
1164
1182
  maxSize: number;
1165
- quality: number;
1166
- maxWidth: number;
1167
- maxHeight: number;
1168
- allowedTypes: string[];
1183
+ quality?: number;
1184
+ maxWidth?: number;
1185
+ maxHeight?: number;
1186
+ allowedTypes?: string[];
1169
1187
  handler?: AteImageUploadHandler;
1170
- enableDragDrop: boolean;
1171
- showPreview: boolean;
1172
- multiple: boolean;
1173
- compressImages: boolean;
1174
1188
  }>;
1175
1189
  readonly finalImageUploadHandler: _angular_core.Signal<AteImageUploadHandler | undefined>;
1176
1190
  readonly currentTranslations: _angular_core.Signal<_flogeez_angular_tiptap_editor.AteTranslations>;
@@ -1208,6 +1222,7 @@ declare class AngularTiptapEditorComponent implements AfterViewInit, OnDestroy {
1208
1222
  showImageBubbleMenu?: boolean;
1209
1223
  showTableMenu?: boolean;
1210
1224
  showCellMenu?: boolean;
1225
+ downloadImage?: boolean;
1211
1226
  enableSlashCommands?: boolean;
1212
1227
  maxCharacters?: number;
1213
1228
  toolbar?: AteToolbarConfig;
@@ -1267,6 +1282,35 @@ declare class AngularTiptapEditorComponent implements AfterViewInit, OnDestroy {
1267
1282
  */
1268
1283
  declare function provideAteEditor(config?: AteEditorConfig): EnvironmentProviders;
1269
1284
 
1285
+ declare class AteTooltipDirective implements OnDestroy {
1286
+ private readonly el;
1287
+ private tippyInstance;
1288
+ content: _angular_core.InputSignal<string | null>;
1289
+ placement: _angular_core.InputSignal<_popperjs_core.Placement>;
1290
+ delay: _angular_core.InputSignal<number | [number, number]>;
1291
+ disabled: _angular_core.InputSignal<boolean>;
1292
+ /**
1293
+ * Computed logic for ARIA shortcuts.
1294
+ */
1295
+ protected readonly ariaShortcut: _angular_core.Signal<string | null>;
1296
+ /**
1297
+ * Computed logic for Tippy content.
1298
+ * Includes strict escaping of dynamic content to prevent XSS.
1299
+ */
1300
+ private readonly processedTooltip;
1301
+ constructor();
1302
+ ngOnDestroy(): void;
1303
+ /**
1304
+ * Basic HTML escaping for security.
1305
+ * Effectively neutralizes scripts or malicious HTML tags.
1306
+ */
1307
+ private escapeHtml;
1308
+ private initTippy;
1309
+ private destroyTippy;
1310
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AteTooltipDirective, never>;
1311
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AteTooltipDirective, "[ateTooltip]", never, { "content": { "alias": "ateTooltip"; "required": false; "isSignal": true; }; "placement": { "alias": "ateTooltipPlacement"; "required": false; "isSignal": true; }; "delay": { "alias": "ateTooltipDelay"; "required": false; "isSignal": true; }; "disabled": { "alias": "ateTooltipDisabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1312
+ }
1313
+
1270
1314
  declare class AteImageService {
1271
1315
  /** Signals for image state */
1272
1316
  selectedImage: _angular_core.WritableSignal<AteImageData | null>;
@@ -1306,6 +1350,8 @@ declare class AteImageService {
1306
1350
  } | null;
1307
1351
  /** Remove the selected image */
1308
1352
  deleteImage(editor: Editor): void;
1353
+ /** Download the current image */
1354
+ downloadImage(editor: Editor): void;
1309
1355
  private updateSelectedImage;
1310
1356
  /** Validate file type and size */
1311
1357
  validateImage(file: File, options?: {
@@ -1463,6 +1509,7 @@ declare const ATE_DEFAULT_BUBBLE_MENU_CONFIG: AteBubbleMenuConfig;
1463
1509
  declare const ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG: AteImageBubbleMenuConfig;
1464
1510
  declare const ATE_DEFAULT_TABLE_MENU_CONFIG: AteTableBubbleMenuConfig;
1465
1511
  declare const ATE_DEFAULT_CELL_MENU_CONFIG: AteCellBubbleMenuConfig;
1512
+ declare const ATE_DEFAULT_IMAGE_UPLOAD_CONFIG: AteImageUploadConfig;
1466
1513
 
1467
1514
  /**
1468
1515
  * Ultimate default configuration for the Angular Tiptap Editor.
@@ -1650,5 +1697,5 @@ declare function createAngularComponentExtension<T = unknown>(injector: Injector
1650
1697
  */
1651
1698
  declare function registerAngularComponent<T = unknown>(injectorOrOptions: Injector | RegisterAngularComponentOptions<T>, maybeOptions?: RegisterAngularComponentOptions<T>): Node$2;
1652
1699
 
1653
- export { ATE_BUBBLE_MENU_KEYS, ATE_CELL_BUBBLE_MENU_KEYS, ATE_DEFAULT_BUBBLE_MENU_CONFIG, ATE_DEFAULT_CELL_MENU_CONFIG, ATE_DEFAULT_CONFIG, ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, ATE_DEFAULT_SLASH_COMMANDS_CONFIG, ATE_DEFAULT_TABLE_MENU_CONFIG, ATE_DEFAULT_TOOLBAR_CONFIG, ATE_GLOBAL_CONFIG, ATE_IMAGE_BUBBLE_MENU_KEYS, ATE_INITIAL_EDITOR_STATE, ATE_SLASH_COMMAND_KEYS, ATE_TABLE_BUBBLE_MENU_KEYS, ATE_TOOLBAR_KEYS, AngularTiptapEditorComponent, AteAngularNodeView, AteColorPickerService, AteDiscoveryCalculator, AteEditorCommandsService, AteI18nService, AteImageCalculator, AteImageService, AteLinkService, AteMarksCalculator, AteNodeViewRenderer, AteNoopValueAccessorDirective, AteSelectionCalculator, AteStructureCalculator, AteTableCalculator, createAngularComponentExtension, createDefaultSlashCommands, filterSlashCommands, provideAteEditor, registerAngularComponent };
1700
+ export { ATE_BUBBLE_MENU_KEYS, ATE_CELL_BUBBLE_MENU_KEYS, ATE_DEFAULT_BUBBLE_MENU_CONFIG, ATE_DEFAULT_CELL_MENU_CONFIG, ATE_DEFAULT_CONFIG, ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, ATE_DEFAULT_IMAGE_UPLOAD_CONFIG, ATE_DEFAULT_SLASH_COMMANDS_CONFIG, ATE_DEFAULT_TABLE_MENU_CONFIG, ATE_DEFAULT_TOOLBAR_CONFIG, ATE_GLOBAL_CONFIG, ATE_IMAGE_BUBBLE_MENU_KEYS, ATE_INITIAL_EDITOR_STATE, ATE_SLASH_COMMAND_KEYS, ATE_TABLE_BUBBLE_MENU_KEYS, ATE_TOOLBAR_KEYS, AngularTiptapEditorComponent, AteAngularNodeView, AteColorPickerService, AteDiscoveryCalculator, AteEditorCommandsService, AteI18nService, AteImageCalculator, AteImageService, AteLinkService, AteMarksCalculator, AteNodeViewRenderer, AteNoopValueAccessorDirective, AteSelectionCalculator, AteStructureCalculator, AteTableCalculator, AteTooltipDirective, createAngularComponentExtension, createDefaultSlashCommands, filterSlashCommands, provideAteEditor, registerAngularComponent };
1654
1701
  export type { AteAngularNode, AteBubbleMenuConfig, AteBubbleMenuKey, AteCellBubbleMenuConfig, AteCellBubbleMenuKey, AteColorEditMode, AteColorPickerSelection, AteComponentRenderOptions, AteCustomBubbleMenuItem, AteCustomSlashCommands, AteCustomToolbarItem, AteEditorConfig, AteEditorStateSnapshot, AteImageBubbleMenuConfig, AteImageBubbleMenuKey, AteImageData, AteImageUploadConfig, AteImageUploadContext, AteImageUploadHandler, AteImageUploadHandlerResult, AteImageUploadOptions, AteImageUploadResult, AteResizeOptions, AteSlashCommandItem, AteSlashCommandKey, AteSlashCommandsConfig, AteStateCalculator, AteTableBubbleMenuConfig, AteTableBubbleMenuKey, AteToolbarConfig, AteToolbarKey, AteTranslations, RegisterAngularComponentOptions, SupportedLocale };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flogeez/angular-tiptap-editor",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "A modern, customizable rich-text editor for Angular (18+), built with Tiptap and featuring complete internationalization support",
5
5
  "keywords": [
6
6
  "angular",
@@ -1,44 +1,41 @@
1
- /* Styles globaux pour les menus contextuels Tiptap */
2
- .tippy-box {
3
- /* Par défaut Tippy limite à 350px */
1
+ /* Global styles for Tiptap bubble menus & Slash menu */
2
+ .tippy-box[data-theme~="ate-bubble-menu"],
3
+ .tippy-box[data-theme~="slash-menu"] {
4
+ /* Default Tippy limits to 350px */
4
5
  max-width: none !important;
5
6
  background: transparent !important;
6
7
  box-shadow: none !important;
7
8
  }
8
9
 
9
- .tippy-content {
10
- /* Le container interne ne doit pas rajouter de padding, on gère dans .bubble-menu */
11
- padding: 0;
10
+ .tippy-box[data-theme~="ate-bubble-menu"] .tippy-content,
11
+ .tippy-box[data-theme~="slash-menu"] .tippy-content {
12
+ /* Internal container shouldn't add padding, we handle it in .bubble-menu or .slash-commands-menu */
13
+ padding: 0 !important;
12
14
  }
13
15
 
14
- .tippy-box .bubble-menu {
16
+ /* Scoped bubble-menu styles - Restoring original design exactly as requested */
17
+ .tippy-box[data-theme~="ate-bubble-menu"] .bubble-menu {
15
18
  display: flex !important;
16
19
  align-items: center;
17
- gap: 6px;
20
+ gap: var(--ate-menu-gap, 2px);
18
21
  background: var(--ate-menu-bg, rgb(255, 255, 255)) !important;
19
22
  border: 1px solid var(--ate-menu-border, rgba(0, 0, 0, 0.1));
20
23
  border-radius: var(--ate-menu-border-radius, 12px);
21
- padding: var(--ate-menu-padding, 6px);
24
+ padding: var(--ate-menu-padding, 4px);
22
25
  box-shadow: var(--ate-menu-shadow, 0 8px 32px rgba(0, 0, 0, 0.12));
23
26
  z-index: 1000;
24
27
  animation: slideUp 0.18s cubic-bezier(0, 0, 0.2, 1);
25
28
  white-space: nowrap;
26
29
  }
27
30
 
28
- /* Cache le menu intelligemment si la source (le slash) est scrollée hors vue */
29
- .tippy-box[data-reference-hidden] {
31
+ /* Hidden state when reference scrolls out of view */
32
+ .tippy-box[data-theme~="ate-bubble-menu"][data-reference-hidden],
33
+ .tippy-box[data-theme~="slash-menu"][data-reference-hidden] {
30
34
  opacity: 0 !important;
31
35
  transition: opacity 0.18s cubic-bezier(0, 0, 0.2, 1);
32
36
  pointer-events: none !important;
33
37
  }
34
38
 
35
- .bubble-menu .ate-separator {
36
- width: 1px;
37
- height: 28px;
38
- background: color-mix(in srgb, var(--ate-menu-border), transparent 50%);
39
- margin: 0 4px;
40
- }
41
-
42
39
  @keyframes slideUp {
43
40
  from {
44
41
  opacity: 0;
@@ -0,0 +1,47 @@
1
+ /* ate-tooltip tippy theme */
2
+ .tippy-box[data-theme~="ate-tooltip"] {
3
+ background-color: var(--ate-tooltip-bg, #0f172a);
4
+ color: var(--ate-tooltip-color, #e2e8f0);
5
+ border-radius: var(--ate-sub-border-radius, 6px);
6
+ font-size: 12px;
7
+ line-height: 1.4;
8
+ padding: 0;
9
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
10
+ border: 1px solid rgba(255, 255, 255, 0.1);
11
+ pointer-events: none;
12
+ transition: opacity 0.1s ease-out;
13
+ text-align: center;
14
+ }
15
+
16
+ .tippy-box[data-theme~="ate-tooltip"] .tippy-content {
17
+ padding: 4px 6px;
18
+ }
19
+
20
+ /* Multi-line support */
21
+ .tippy-box[data-theme~="ate-tooltip"] .ate-tooltip-label {
22
+ display: block;
23
+ color: var(--ate-tooltip-color, #e2e8f0);
24
+ }
25
+
26
+ .tippy-box[data-theme~="ate-tooltip"] .ate-tooltip-shortcut {
27
+ display: block;
28
+ font-size: 10px;
29
+ opacity: 0.6;
30
+ margin-top: 2px;
31
+ font-family:
32
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
33
+ monospace;
34
+ }
35
+
36
+ .tippy-box[data-theme~="ate-tooltip"] .ate-tooltip-shortcut kbd {
37
+ background: none;
38
+ border: none;
39
+ padding: 0;
40
+ color: inherit;
41
+ font: inherit;
42
+ }
43
+
44
+ /* Visibility state */
45
+ .tippy-box[data-theme~="ate-tooltip"][data-state="hidden"] {
46
+ opacity: 0;
47
+ }
@@ -1,20 +1,21 @@
1
1
  @import "./ate-bubble-menu.global.css";
2
+ @import "./ate-tooltip.global.css";
2
3
  @import "./material-symbols.css";
3
4
 
4
- /* Styles pour les liens */
5
+ /* Styles for links */
5
6
  .ate-link {
6
- color: var(--ate-primary, #1d4ed8);
7
+ color: var(--ate-primary, #2563eb);
7
8
  text-decoration: underline;
8
9
  cursor: pointer;
9
10
  transition: color 0.2s ease;
10
11
  }
11
12
 
12
13
  .ate-link:hover {
13
- color: var(--ate-primary-light-alpha, #1d4ed8);
14
+ color: var(--ate-primary-hover, #153ca9);
14
15
  text-decoration: underline;
15
16
  }
16
17
 
17
- /* Styles pour la surbrillance */
18
+ /* Styles for highlight */
18
19
  .ate-highlight {
19
20
  background-color: var(--ate-highlight-bg, #fef08a);
20
21
  padding: 0.1em 0.2em;
@@ -22,7 +23,7 @@
22
23
  color: var(--ate-highlight-color, #854d0e);
23
24
  }
24
25
 
25
- /* Styles pour les alignements de texte - Tiptap utilise des classes */
26
+ /* Styles for text alignment - Tiptap uses classes */
26
27
  .ProseMirror .has-text-align-left {
27
28
  text-align: left;
28
29
  }