@seniorsistemas/angular-components 19.5.5 → 19.6.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.
Files changed (98) hide show
  1. package/accordion/README.md +95 -59
  2. package/calendar-mask/lib/calendar-mask/calendar-mask.directive.d.ts +4 -0
  3. package/datepicker/README.md +175 -0
  4. package/datepicker/index.d.ts +5 -0
  5. package/datepicker/lib/datepicker/date.utils.d.ts +21 -0
  6. package/datepicker/lib/datepicker/datepicker.component.d.ts +254 -0
  7. package/datepicker/lib/datepicker/models/index.d.ts +16 -0
  8. package/datepicker/public-api.d.ts +2 -0
  9. package/dynamic-form/dynamic-form/components/lookup/lookup.component.d.ts +3 -1
  10. package/dynamic-form/dynamic-form/components/lookup/models/lookup-alert-config.d.ts +5 -0
  11. package/dynamic-form/dynamic-form/form-field/configurations/fields/calendar-field.d.ts +119 -24
  12. package/dynamic-form/dynamic-form/form-field/configurations/fields/lookup-field.d.ts +6 -0
  13. package/dynamic-form/dynamic-form/form-field/fields/calendar/calendar-field.component.d.ts +6 -23
  14. package/dynamic-form/public-api.d.ts +1 -0
  15. package/editor/README.md +229 -0
  16. package/editor/index.d.ts +5 -0
  17. package/editor/lib/editor/editor.component.d.ts +127 -0
  18. package/editor/lib/editor/link-dialog/link-dialog.component.d.ts +18 -0
  19. package/editor/lib/editor/models/index.d.ts +12 -0
  20. package/editor/lib/editor/toolbar-button/editor-toolbar-button.component.d.ts +10 -0
  21. package/editor/public-api.d.ts +2 -0
  22. package/esm2022/calendar-mask/lib/calendar-mask/calendar-mask.directive.mjs +5 -1
  23. package/esm2022/datepicker/lib/datepicker/date.utils.mjs +182 -0
  24. package/esm2022/datepicker/lib/datepicker/datepicker.component.mjs +1062 -0
  25. package/esm2022/datepicker/lib/datepicker/models/index.mjs +2 -0
  26. package/esm2022/datepicker/public-api.mjs +2 -0
  27. package/esm2022/datepicker/seniorsistemas-angular-components-datepicker.mjs +5 -0
  28. package/esm2022/dynamic-form/dynamic-form/components/lookup/lookup.component.mjs +11 -5
  29. package/esm2022/dynamic-form/dynamic-form/components/lookup/models/lookup-alert-config.mjs +2 -0
  30. package/esm2022/dynamic-form/dynamic-form/form-field/configurations/fields/calendar-field.mjs +1 -1
  31. package/esm2022/dynamic-form/dynamic-form/form-field/configurations/fields/lookup-field.mjs +1 -1
  32. package/esm2022/dynamic-form/dynamic-form/form-field/fields/autocomplete/autocomplete-field.component.mjs +2 -2
  33. package/esm2022/dynamic-form/dynamic-form/form-field/fields/calendar/calendar-field.component.mjs +23 -116
  34. package/esm2022/dynamic-form/dynamic-form/form-field/fields/lookup/lookup-field.component.mjs +3 -3
  35. package/esm2022/dynamic-form/public-api.mjs +1 -1
  36. package/esm2022/editor/lib/editor/editor.component.mjs +375 -0
  37. package/esm2022/editor/lib/editor/link-dialog/link-dialog.component.mjs +48 -0
  38. package/esm2022/editor/lib/editor/models/index.mjs +3 -0
  39. package/esm2022/editor/lib/editor/toolbar-button/editor-toolbar-button.component.mjs +17 -0
  40. package/esm2022/editor/public-api.mjs +3 -0
  41. package/esm2022/editor/seniorsistemas-angular-components-editor.mjs +5 -0
  42. package/esm2022/inline-edit/lib/inline-edit/components/fields/inline-edit-calendar/inline-edit-calendar.component.mjs +22 -12
  43. package/esm2022/inline-edit/lib/inline-edit/inline-edit.module.mjs +5 -5
  44. package/esm2022/lib/locale/fallback.mjs +82 -3
  45. package/esm2022/optional-fields/editor/editor-field/editor-field.component.mjs +5 -6
  46. package/esm2022/optional-fields/editor/editor-field.mjs +1 -1
  47. package/esm2022/panel/lib/panel/panel.component.mjs +7 -3
  48. package/esm2022/select/lib/select/select.component.mjs +4 -8
  49. package/esm2022/shared/lib/accessibility/datepicker-no-period-tab.directive.mjs +5 -1
  50. package/fesm2022/seniorsistemas-angular-components-calendar-mask.mjs +4 -0
  51. package/fesm2022/seniorsistemas-angular-components-calendar-mask.mjs.map +1 -1
  52. package/fesm2022/seniorsistemas-angular-components-datepicker.mjs +1250 -0
  53. package/fesm2022/seniorsistemas-angular-components-datepicker.mjs.map +1 -0
  54. package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs +49 -135
  55. package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs.map +1 -1
  56. package/fesm2022/seniorsistemas-angular-components-editor.mjs +437 -0
  57. package/fesm2022/seniorsistemas-angular-components-editor.mjs.map +1 -0
  58. package/fesm2022/seniorsistemas-angular-components-inline-edit.mjs +24 -15
  59. package/fesm2022/seniorsistemas-angular-components-inline-edit.mjs.map +1 -1
  60. package/fesm2022/seniorsistemas-angular-components-optional-fields-editor.mjs +4 -5
  61. package/fesm2022/seniorsistemas-angular-components-optional-fields-editor.mjs.map +1 -1
  62. package/fesm2022/seniorsistemas-angular-components-panel.mjs +6 -2
  63. package/fesm2022/seniorsistemas-angular-components-panel.mjs.map +1 -1
  64. package/fesm2022/seniorsistemas-angular-components-select.mjs +3 -7
  65. package/fesm2022/seniorsistemas-angular-components-select.mjs.map +1 -1
  66. package/fesm2022/seniorsistemas-angular-components-shared.mjs +4 -0
  67. package/fesm2022/seniorsistemas-angular-components-shared.mjs.map +1 -1
  68. package/fesm2022/seniorsistemas-angular-components.mjs +81 -2
  69. package/fesm2022/seniorsistemas-angular-components.mjs.map +1 -1
  70. package/inline-edit/lib/inline-edit/components/fields/inline-edit-calendar/inline-edit-calendar.component.d.ts +6 -4
  71. package/inline-edit/lib/inline-edit/inline-edit.module.d.ts +2 -2
  72. package/loading-state/README.md +57 -17
  73. package/optional-fields/editor/editor-field.d.ts +9 -6
  74. package/package.json +74 -8
  75. package/panel/README.md +12 -1
  76. package/panel/lib/panel/panel.component.d.ts +3 -1
  77. package/schematics/collection.json +4 -0
  78. package/schematics/migrations/migrate-p-datepicker/index.d.ts +2 -0
  79. package/schematics/migrations/migrate-p-datepicker/index.js +141 -0
  80. package/schematics/migrations/migrate-p-datepicker/index.js.map +1 -0
  81. package/schematics/migrations/migrate-p-datepicker/index.test.d.ts +1 -0
  82. package/schematics/migrations/migrate-p-datepicker/index.test.js +392 -0
  83. package/schematics/migrations/migrate-p-datepicker/index.test.js.map +1 -0
  84. package/schematics/migrations.json +10 -0
  85. package/schematics/utils/ast-utils.d.ts +28 -0
  86. package/schematics/utils/ast-utils.js +116 -0
  87. package/schematics/utils/ast-utils.js.map +1 -0
  88. package/schematics/utils/ast-utils.test.d.ts +1 -0
  89. package/schematics/utils/ast-utils.test.js +138 -0
  90. package/schematics/utils/ast-utils.test.js.map +1 -0
  91. package/schematics/utils/workspace-utils.d.ts +6 -0
  92. package/schematics/utils/workspace-utils.js +37 -0
  93. package/schematics/utils/workspace-utils.js.map +1 -0
  94. package/schematics/utils/workspace-utils.test.d.ts +1 -0
  95. package/schematics/utils/workspace-utils.test.js +152 -0
  96. package/schematics/utils/workspace-utils.test.js.map +1 -0
  97. package/shared/lib/accessibility/datepicker-no-period-tab.directive.d.ts +4 -0
  98. package/stats-card/README.md +80 -45
@@ -0,0 +1,437 @@
1
+ import { NgClass, NgStyle } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, Component, input, output, ChangeDetectionStrategy, ChangeDetectorRef, DestroyRef, viewChild, effect, forwardRef } from '@angular/core';
4
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
+ import { FormGroup, FormControl, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
6
+ import { take } from 'rxjs/operators';
7
+ import * as i1 from '@ngx-translate/core';
8
+ import { TranslateService, TranslateModule } from '@ngx-translate/core';
9
+ import { ActiveDialog, DialogComponent, DialogService } from '@seniorsistemas/angular-components/dialog';
10
+ import { Editor } from '@tiptap/core';
11
+ export { Extension } from '@tiptap/core';
12
+ import { Color } from '@tiptap/extension-color';
13
+ import Highlight from '@tiptap/extension-highlight';
14
+ import Image from '@tiptap/extension-image';
15
+ import Placeholder from '@tiptap/extension-placeholder';
16
+ import Subscript from '@tiptap/extension-subscript';
17
+ import Superscript from '@tiptap/extension-superscript';
18
+ import TextAlign from '@tiptap/extension-text-align';
19
+ import { TextStyle } from '@tiptap/extension-text-style';
20
+ import Underline from '@tiptap/extension-underline';
21
+ import StarterKit from '@tiptap/starter-kit';
22
+ import * as i3 from '@seniorsistemas/angular-components/button';
23
+ import { ButtonModule } from '@seniorsistemas/angular-components/button';
24
+ import * as i2 from '@seniorsistemas/angular-components/dynamic-form';
25
+ import { DynamicFormModule } from '@seniorsistemas/angular-components/dynamic-form';
26
+ import * as i4 from '@seniorsistemas/angular-components/template';
27
+ import { TemplateModule } from '@seniorsistemas/angular-components/template';
28
+
29
+ class LinkDialogComponent {
30
+ activeDialog = inject(ActiveDialog);
31
+ translateService = inject(TranslateService);
32
+ initialUrl = '';
33
+ form = new FormGroup({ url: new FormControl('') });
34
+ configs = [];
35
+ ngOnInit() {
36
+ this.form.setValue({ url: this.initialUrl });
37
+ this.configs = [
38
+ {
39
+ type: 'row',
40
+ fields: [
41
+ {
42
+ type: 'string',
43
+ name: 'url',
44
+ label: this.translateService.instant('platform.angular_components.editor_link_url_label'),
45
+ placeholder: this.translateService.instant('platform.angular_components.editor_link_url_placeholder'),
46
+ },
47
+ ],
48
+ },
49
+ ];
50
+ }
51
+ confirm() {
52
+ this.activeDialog.close(this.form.value.url?.trim() ?? '');
53
+ }
54
+ cancel() {
55
+ this.activeDialog.dismiss();
56
+ }
57
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LinkDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
58
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: LinkDialogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<s-dialog [header]=\"'platform.angular_components.editor_insert_link' | translate\">\n <ng-template sTemplate=\"body\">\n <s-dynamic-form [form]=\"form\" [configs]=\"configs\" />\n </ng-template>\n <ng-template sTemplate=\"footer\">\n <div style=\"display:flex; justify-content:flex-end; gap:8px; width:100%\">\n <s-button\n [label]=\"'platform.angular_components.cancel' | translate\"\n priority=\"secondary\"\n (clicked)=\"cancel()\"\n />\n <s-button\n [label]=\"'platform.angular_components.editor_confirm' | translate\"\n priority=\"primary\"\n (clicked)=\"confirm()\"\n />\n </div>\n </ng-template>\n</s-dialog>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "component", type: DialogComponent, selector: "s-dialog", inputs: ["header", "visible", "size", "contentClassName", "escapeOnEsc", "destroyClickOutside", "closeAriaLabel"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: DynamicFormModule }, { kind: "component", type: i2.DynamicFormComponent, selector: "s-dynamic-form", inputs: ["id", "configs", "fields", "form", "errorMessages"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3.ButtonComponent, selector: "s-button", inputs: ["id", "label", "tooltip", "tooltipPosition", "iconClass", "rightIconClass", "caret", "styleClass", "baseZIndex", "disabled", "auxiliary", "type", "priority", "menuOptions", "size", "slide", "animation", "badge", "iconColor", "menuAriaLabel", "ariaLabel"], outputs: ["clicked"] }, { kind: "ngmodule", type: TemplateModule }, { kind: "directive", type: i4.TemplateDirective, selector: "[sTemplate]", inputs: ["sTemplate"] }] });
59
+ }
60
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LinkDialogComponent, decorators: [{
61
+ type: Component,
62
+ args: [{ standalone: true, imports: [ReactiveFormsModule, TranslateModule, DialogComponent, DynamicFormModule, ButtonModule, TemplateModule], template: "<s-dialog [header]=\"'platform.angular_components.editor_insert_link' | translate\">\n <ng-template sTemplate=\"body\">\n <s-dynamic-form [form]=\"form\" [configs]=\"configs\" />\n </ng-template>\n <ng-template sTemplate=\"footer\">\n <div style=\"display:flex; justify-content:flex-end; gap:8px; width:100%\">\n <s-button\n [label]=\"'platform.angular_components.cancel' | translate\"\n priority=\"secondary\"\n (clicked)=\"cancel()\"\n />\n <s-button\n [label]=\"'platform.angular_components.editor_confirm' | translate\"\n priority=\"primary\"\n (clicked)=\"confirm()\"\n />\n </div>\n </ng-template>\n</s-dialog>\n" }]
63
+ }] });
64
+
65
+ class EditorToolbarButtonComponent {
66
+ icon = input.required();
67
+ label = input.required();
68
+ active = input(false);
69
+ disabled = input(false);
70
+ clicked = output();
71
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EditorToolbarButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
72
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: EditorToolbarButtonComponent, isStandalone: true, selector: "s-editor-toolbar-button", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", 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 } }, outputs: { clicked: "clicked" }, host: { styleAttribute: "display: contents" }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"inline-flex items-center justify-center w-7 h-7 p-0 border-0 bg-transparent rounded cursor-pointer text-base leading-none transition-colors duration-150 disabled:opacity-[.35] disabled:cursor-not-allowed\"\n [ngClass]=\"{\n 'bg-[#ebebfa]': active(),\n 'text-[#5c5ce6]': active(),\n 'hover:bg-[#ddddf7]': active(),\n 'text-[#3d3d4d]': !active(),\n 'enabled:hover:bg-[#e8e8f0]': !active(),\n 'enabled:hover:text-[#1e1e2e]': !active()\n }\"\n [disabled]=\"disabled()\"\n [title]=\"label()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-pressed]=\"active()\"\n (click)=\"clicked.emit()\"\n>\n <i [class]=\"icon()\"></i>\n</button>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
73
+ }
74
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EditorToolbarButtonComponent, decorators: [{
75
+ type: Component,
76
+ args: [{ selector: 's-editor-toolbar-button', standalone: true, imports: [NgClass], host: { style: 'display: contents' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n type=\"button\"\n class=\"inline-flex items-center justify-center w-7 h-7 p-0 border-0 bg-transparent rounded cursor-pointer text-base leading-none transition-colors duration-150 disabled:opacity-[.35] disabled:cursor-not-allowed\"\n [ngClass]=\"{\n 'bg-[#ebebfa]': active(),\n 'text-[#5c5ce6]': active(),\n 'hover:bg-[#ddddf7]': active(),\n 'text-[#3d3d4d]': !active(),\n 'enabled:hover:bg-[#e8e8f0]': !active(),\n 'enabled:hover:text-[#1e1e2e]': !active()\n }\"\n [disabled]=\"disabled()\"\n [title]=\"label()\"\n [attr.aria-label]=\"label()\"\n [attr.aria-pressed]=\"active()\"\n (click)=\"clicked.emit()\"\n>\n <i [class]=\"icon()\"></i>\n</button>\n" }]
77
+ }] });
78
+
79
+ /**
80
+ * @description Componente de editor de texto rico (WYSIWYG) construído sobre o Tiptap/ProseMirror.
81
+ * Substitui o `p-editor` do PrimeNG sem dependência externa de licença comercial.
82
+ * Implementa {@link ControlValueAccessor} para integração com Angular Forms.
83
+ *
84
+ * @example
85
+ * ```html
86
+ * <s-editor
87
+ * formControlName="descricao"
88
+ * [readonly]="false"
89
+ * (textChange)="onTextChange($event)" />
90
+ * ```
91
+ */
92
+ class EditorComponent {
93
+ cdr = inject(ChangeDetectorRef);
94
+ dialogService = inject(DialogService);
95
+ translateService = inject(TranslateService);
96
+ destroyRef = inject(DestroyRef);
97
+ /**
98
+ * @description Coloca o editor em modo somente leitura.
99
+ * @default false
100
+ */
101
+ readonly = input(false);
102
+ /**
103
+ * @description Lista de formatos habilitados na toolbar. Quando vazio, todos os formatos são exibidos.
104
+ */
105
+ formats = input();
106
+ /**
107
+ * @description Texto de dica exibido quando o editor está vazio.
108
+ */
109
+ placeholder = input();
110
+ /**
111
+ * @description Estilos inline aplicados ao container do editor.
112
+ */
113
+ style = input();
114
+ /**
115
+ * @description Classes CSS adicionais aplicadas ao container do editor.
116
+ */
117
+ styleClass = input();
118
+ /**
119
+ * @description Extensões Tiptap adicionais para estender o comportamento padrão do editor.
120
+ */
121
+ extensions = input([]);
122
+ /**
123
+ * @description Emitido quando o editor é inicializado e está pronto para uso.
124
+ */
125
+ editorInit = output();
126
+ /**
127
+ * @description Emitido sempre que o conteúdo do editor é alterado.
128
+ */
129
+ textChange = output();
130
+ /**
131
+ * @description Emitido quando a seleção de texto no editor muda.
132
+ */
133
+ selectionChange = output();
134
+ editorContainer = viewChild.required('editorContainer');
135
+ imageInput = viewChild.required('imageInput');
136
+ editor;
137
+ _formDisabled = false;
138
+ _currentPlaceholder = '';
139
+ activeStates = {
140
+ isBold: false,
141
+ isItalic: false,
142
+ isUnderline: false,
143
+ isStrike: false,
144
+ isBulletList: false,
145
+ isOrderedList: false,
146
+ isBlockquote: false,
147
+ isCode: false,
148
+ isSubscript: false,
149
+ isSuperscript: false,
150
+ isAlignLeft: false,
151
+ isAlignCenter: false,
152
+ isAlignRight: false,
153
+ currentHeading: 0,
154
+ currentColor: '#000000',
155
+ currentHighlight: 'transparent',
156
+ canUndo: false,
157
+ canRedo: false,
158
+ };
159
+ _value = '';
160
+ _onChange = () => { };
161
+ _onTouched = () => { };
162
+ constructor() {
163
+ effect(() => {
164
+ if (this.editor) {
165
+ this.editor.setEditable(!this.readonly() && !this._formDisabled);
166
+ this.cdr.markForCheck();
167
+ }
168
+ });
169
+ effect(() => {
170
+ this._currentPlaceholder = this.placeholder() ?? '';
171
+ this.editor?.view.dispatch(this.editor.state.tr);
172
+ });
173
+ }
174
+ ngAfterViewInit() {
175
+ this.initEditor();
176
+ }
177
+ ngOnDestroy() {
178
+ this.editor?.destroy();
179
+ }
180
+ writeValue(value) {
181
+ this._value = value ?? '';
182
+ if (this.editor) {
183
+ this.editor.chain().setMeta('addToHistory', false).setContent(this._value, { emitUpdate: false }).run();
184
+ this.cdr.markForCheck();
185
+ }
186
+ }
187
+ registerOnChange(fn) {
188
+ this._onChange = fn;
189
+ }
190
+ registerOnTouched(fn) {
191
+ this._onTouched = fn;
192
+ }
193
+ setDisabledState(isDisabled) {
194
+ this._formDisabled = isDisabled;
195
+ this.editor?.setEditable(!isDisabled && !this.readonly());
196
+ this.cdr.markForCheck();
197
+ }
198
+ isFormatAllowed(format) {
199
+ const formats = this.formats();
200
+ return !formats?.length || formats.includes(format);
201
+ }
202
+ hasAnyFormatBeforeUndoRedo() {
203
+ const formatsBeforeUndoRedo = [
204
+ 'header', 'bold', 'italic', 'underline', 'strike', 'subscript', 'superscript',
205
+ 'color', 'highlight', 'list', 'align', 'blockquote', 'code-block', 'link', 'image',
206
+ ];
207
+ return formatsBeforeUndoRedo.some(f => this.isFormatAllowed(f));
208
+ }
209
+ toggleBold() {
210
+ this.editor?.chain().focus().toggleBold().run();
211
+ }
212
+ toggleItalic() {
213
+ this.editor?.chain().focus().toggleItalic().run();
214
+ }
215
+ toggleUnderline() {
216
+ this.editor?.chain().focus().toggleUnderline().run();
217
+ }
218
+ toggleStrike() {
219
+ this.editor?.chain().focus().toggleStrike().run();
220
+ }
221
+ toggleBulletList() {
222
+ this.editor?.chain().focus().toggleBulletList().run();
223
+ }
224
+ toggleOrderedList() {
225
+ this.editor?.chain().focus().toggleOrderedList().run();
226
+ }
227
+ toggleBlockquote() {
228
+ this.editor?.chain().focus().toggleBlockquote().run();
229
+ }
230
+ toggleCode() {
231
+ this.editor?.chain().focus().toggleCode().run();
232
+ }
233
+ toggleSubscript() {
234
+ this.editor?.chain().focus().toggleSubscript().run();
235
+ }
236
+ toggleSuperscript() {
237
+ this.editor?.chain().focus().toggleSuperscript().run();
238
+ }
239
+ setTextAlign(align) {
240
+ this.editor?.chain().focus().setTextAlign(align).run();
241
+ }
242
+ setColor(color) {
243
+ this.editor?.chain().focus().setColor(color).run();
244
+ }
245
+ setHighlight(color) {
246
+ this.editor?.chain().focus().setHighlight({ color }).run();
247
+ }
248
+ clearFormatting() {
249
+ this.editor?.chain().focus().clearNodes().unsetAllMarks().run();
250
+ }
251
+ onHeadingChange(event) {
252
+ const level = parseInt(event.target.value);
253
+ if (isNaN(level) || level === 0) {
254
+ this.editor?.chain().focus().setParagraph().run();
255
+ }
256
+ else {
257
+ this.editor?.chain().focus().setHeading({ level }).run();
258
+ }
259
+ }
260
+ setLink() {
261
+ const existingUrl = this.editor?.getAttributes('link')['href'] ?? '';
262
+ const ref = this.dialogService.open(LinkDialogComponent, { size: 'sm' });
263
+ ref.componentInstance.initialUrl = existingUrl;
264
+ ref.closed
265
+ .pipe(take(1), takeUntilDestroyed(this.destroyRef))
266
+ .subscribe((url) => {
267
+ if (url === '') {
268
+ this.editor?.chain().focus().extendMarkRange('link').unsetLink().run();
269
+ }
270
+ else {
271
+ this.editor?.chain().focus().extendMarkRange('link').setLink({ href: url }).run();
272
+ }
273
+ });
274
+ }
275
+ setImage() {
276
+ this.imageInput().nativeElement.click();
277
+ }
278
+ onImageFileSelected(event) {
279
+ const input = event.target;
280
+ const file = input.files?.[0];
281
+ if (!file)
282
+ return;
283
+ const reader = new FileReader();
284
+ reader.onload = (e) => {
285
+ const src = e.target?.result;
286
+ this.editor?.chain().focus().setImage({ src }).run();
287
+ input.value = '';
288
+ this.cdr.markForCheck();
289
+ };
290
+ reader.readAsDataURL(file);
291
+ }
292
+ undo() {
293
+ this.editor?.chain().focus().undo().run();
294
+ }
295
+ redo() {
296
+ this.editor?.chain().focus().redo().run();
297
+ }
298
+ onToolbarKeydown(event) {
299
+ if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key))
300
+ return;
301
+ event.preventDefault();
302
+ const toolbar = event.currentTarget;
303
+ const focusable = this.getToolbarFocusable(toolbar);
304
+ if (!focusable.length)
305
+ return;
306
+ const currentIndex = focusable.findIndex(el => el === document.activeElement);
307
+ let nextIndex;
308
+ switch (event.key) {
309
+ case 'ArrowRight':
310
+ nextIndex = (currentIndex + 1) % focusable.length;
311
+ break;
312
+ case 'ArrowLeft':
313
+ nextIndex = (currentIndex - 1 + focusable.length) % focusable.length;
314
+ break;
315
+ case 'Home':
316
+ nextIndex = 0;
317
+ break;
318
+ default:
319
+ nextIndex = focusable.length - 1;
320
+ break;
321
+ }
322
+ focusable.forEach((el, i) => el.setAttribute('tabindex', i === nextIndex ? '0' : '-1'));
323
+ focusable[nextIndex].focus();
324
+ }
325
+ onToolbarFocusIn(event) {
326
+ const target = event.target;
327
+ const toolbar = event.currentTarget;
328
+ const focusable = this.getToolbarFocusable(toolbar);
329
+ if (focusable.includes(target)) {
330
+ focusable.forEach(el => el.setAttribute('tabindex', el === target ? '0' : '-1'));
331
+ }
332
+ }
333
+ getToolbarFocusable(toolbar) {
334
+ return Array.from(toolbar.querySelectorAll('button:not([disabled]), select, label[tabindex]'));
335
+ }
336
+ initEditor() {
337
+ this.editor = new Editor({
338
+ element: this.editorContainer().nativeElement,
339
+ extensions: [
340
+ StarterKit.configure({
341
+ link: { openOnClick: false },
342
+ underline: false,
343
+ }),
344
+ Underline,
345
+ Image,
346
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
347
+ TextStyle,
348
+ Color,
349
+ Highlight.configure({ multicolor: true }),
350
+ Placeholder.configure({ placeholder: () => this._currentPlaceholder }),
351
+ Subscript,
352
+ Superscript,
353
+ ...this.extensions(),
354
+ ],
355
+ content: this._value,
356
+ editable: !this.readonly(),
357
+ editorProps: {
358
+ attributes: {
359
+ role: 'textbox',
360
+ 'aria-multiline': 'true',
361
+ 'aria-label': this.translateService.instant('platform.angular_components.editor_content_area'),
362
+ },
363
+ },
364
+ onUpdate: ({ editor }) => {
365
+ const html = editor.getHTML();
366
+ const text = editor.getText();
367
+ this._value = html;
368
+ this._onChange(html);
369
+ this.textChange.emit({ htmlValue: html, textValue: text });
370
+ this.syncActiveStates();
371
+ this.cdr.markForCheck();
372
+ },
373
+ onBlur: () => {
374
+ this._onTouched();
375
+ },
376
+ onSelectionUpdate: ({ editor }) => {
377
+ this.syncActiveStates();
378
+ const { from, to, empty } = editor.state.selection;
379
+ this.selectionChange.emit({ from, to, empty });
380
+ this.cdr.markForCheck();
381
+ },
382
+ });
383
+ this.syncActiveStates();
384
+ this.cdr.markForCheck();
385
+ this.editorInit.emit(this.editor);
386
+ }
387
+ syncActiveStates() {
388
+ if (!this.editor)
389
+ return;
390
+ const e = this.editor;
391
+ this.activeStates = {
392
+ isBold: e.isActive('bold'),
393
+ isItalic: e.isActive('italic'),
394
+ isUnderline: e.isActive('underline'),
395
+ isStrike: e.isActive('strike'),
396
+ isBulletList: e.isActive('bulletList'),
397
+ isOrderedList: e.isActive('orderedList'),
398
+ isBlockquote: e.isActive('blockquote'),
399
+ isCode: e.isActive('code'),
400
+ isSubscript: e.isActive('subscript'),
401
+ isSuperscript: e.isActive('superscript'),
402
+ isAlignLeft: e.isActive({ textAlign: 'left' }),
403
+ isAlignCenter: e.isActive({ textAlign: 'center' }),
404
+ isAlignRight: e.isActive({ textAlign: 'right' }),
405
+ currentHeading: [1, 2, 3].find((level) => e.isActive('heading', { level })) ?? 0,
406
+ currentColor: e.getAttributes('textStyle')['color'] || '#000000',
407
+ currentHighlight: e.getAttributes('highlight')['color'] || 'transparent',
408
+ canUndo: e.can().undo(),
409
+ canRedo: e.can().redo(),
410
+ };
411
+ }
412
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
413
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: EditorComponent, isStandalone: true, selector: "s-editor", inputs: { readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, formats: { classPropertyName: "formats", publicName: "formats", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, extensions: { classPropertyName: "extensions", publicName: "extensions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { editorInit: "editorInit", textChange: "textChange", selectionChange: "selectionChange" }, providers: [
414
+ {
415
+ provide: NG_VALUE_ACCESSOR,
416
+ useExisting: forwardRef(() => EditorComponent),
417
+ multi: true,
418
+ },
419
+ ], viewQueries: [{ propertyName: "editorContainer", first: true, predicate: ["editorContainer"], descendants: true, isSignal: true }, { propertyName: "imageInput", first: true, predicate: ["imageInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"rounded bg-white flex flex-col border border-grayscale-30 transition-[border-color,box-shadow] duration-150 focus-within:border-[#5c5ce6] focus-within:shadow-[0_0_0_2px_rgba(92,92,230,0.15)]\"\n [ngClass]=\"styleClass()\"\n [ngStyle]=\"style()\"\n [class.s-editor--readonly]=\"readonly()\"\n>\n @if (!readonly()) {\n <div\n class=\"rounded-t flex flex-wrap items-center gap-0.5 border-b border-grayscale-30 bg-[#f9f9fb] px-2 py-1.5\"\n role=\"toolbar\"\n [attr.aria-label]=\"'platform.angular_components.editor_toolbar' | translate\"\n (keydown)=\"onToolbarKeydown($event)\"\n (focusin)=\"onToolbarFocusIn($event)\"\n >\n @if (isFormatAllowed('header')) {\n <select\n class=\"rounded bg-white h-7 cursor-pointer border border-grayscale-30 px-1.5 text-[13px] text-[#3d3d4d] outline-none transition-colors duration-150 focus:border-[#5c5ce6]\"\n (change)=\"onHeadingChange($event)\"\n [attr.aria-label]=\"'platform.angular_components.editor_heading_level' | translate\"\n >\n <option\n [value]=\"0\"\n [selected]=\"activeStates.currentHeading === 0\"\n >\n {{ 'platform.angular_components.editor_heading_normal' | translate }}\n </option>\n <option\n [value]=\"1\"\n [selected]=\"activeStates.currentHeading === 1\"\n >\n {{ 'platform.angular_components.editor_heading_1' | translate }}\n </option>\n <option\n [value]=\"2\"\n [selected]=\"activeStates.currentHeading === 2\"\n >\n {{ 'platform.angular_components.editor_heading_2' | translate }}\n </option>\n <option\n [value]=\"3\"\n [selected]=\"activeStates.currentHeading === 3\"\n >\n {{ 'platform.angular_components.editor_heading_3' | translate }}\n </option>\n </select>\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n }\n\n @if (isFormatAllowed('bold')) {\n <s-editor-toolbar-button\n icon=\"fa fa-bold\"\n [label]=\"'platform.angular_components.editor_bold' | translate\"\n [active]=\"activeStates.isBold\"\n (clicked)=\"toggleBold()\"\n />\n }\n\n @if (isFormatAllowed('italic')) {\n <s-editor-toolbar-button\n icon=\"fa fa-italic\"\n [label]=\"'platform.angular_components.editor_italic' | translate\"\n [active]=\"activeStates.isItalic\"\n (clicked)=\"toggleItalic()\"\n />\n }\n\n @if (isFormatAllowed('underline')) {\n <s-editor-toolbar-button\n icon=\"fa fa-underline\"\n [label]=\"'platform.angular_components.editor_underline' | translate\"\n [active]=\"activeStates.isUnderline\"\n (clicked)=\"toggleUnderline()\"\n />\n }\n\n @if (isFormatAllowed('strike')) {\n <s-editor-toolbar-button\n icon=\"fa fa-strikethrough\"\n [label]=\"'platform.angular_components.editor_strikethrough' | translate\"\n [active]=\"activeStates.isStrike\"\n (clicked)=\"toggleStrike()\"\n />\n }\n\n @if (isFormatAllowed('subscript')) {\n <s-editor-toolbar-button\n icon=\"fa fa-subscript\"\n [label]=\"'platform.angular_components.editor_subscript' | translate\"\n [active]=\"activeStates.isSubscript\"\n (clicked)=\"toggleSubscript()\"\n />\n }\n\n @if (isFormatAllowed('superscript')) {\n <s-editor-toolbar-button\n icon=\"fa fa-superscript\"\n [label]=\"'platform.angular_components.editor_superscript' | translate\"\n [active]=\"activeStates.isSuperscript\"\n (clicked)=\"toggleSuperscript()\"\n />\n }\n\n @if (isFormatAllowed('color')) {\n <label\n tabindex=\"0\"\n class=\"relative flex h-7 w-7 cursor-pointer items-center justify-center rounded bg-white transition-colors duration-150 hover:bg-[#f0f0f8]\"\n [attr.title]=\"'platform.angular_components.editor_text_color' | translate\"\n [attr.aria-label]=\"'platform.angular_components.editor_text_color' | translate\"\n (keydown.enter)=\"$event.preventDefault(); colorInput.click()\"\n (keydown.space)=\"$event.preventDefault(); colorInput.click()\"\n >\n <span class=\"flex flex-col items-center gap-px\">\n <i class=\"fa fa-font text-[11px] text-[#3d3d4d]\"></i>\n <span\n class=\"h-[3px] w-3.5 rounded-sm\"\n [style.background-color]=\"activeStates.currentColor\"\n ></span>\n </span>\n <input\n #colorInput\n type=\"color\"\n class=\"absolute inset-0 h-full w-full cursor-pointer opacity-0\"\n [value]=\"activeStates.currentColor\"\n (input)=\"setColor($any($event.target).value)\"\n />\n </label>\n }\n\n @if (isFormatAllowed('highlight')) {\n <label\n tabindex=\"0\"\n class=\"relative flex h-7 w-7 cursor-pointer items-center justify-center rounded bg-white transition-colors duration-150 hover:bg-[#f0f0f8]\"\n [attr.title]=\"'platform.angular_components.editor_background_color' | translate\"\n [attr.aria-label]=\"'platform.angular_components.editor_background_color' | translate\"\n (keydown.enter)=\"$event.preventDefault(); highlightInput.click()\"\n (keydown.space)=\"$event.preventDefault(); highlightInput.click()\"\n >\n <span class=\"flex flex-col items-center gap-px\">\n <i class=\"fa fa-highlighter text-[11px] text-[#3d3d4d]\"></i>\n <span\n class=\"h-[3px] w-3.5 rounded-sm\"\n [style.background-color]=\"activeStates.currentHighlight === 'transparent' ? '#ffff00' : activeStates.currentHighlight\"\n ></span>\n </span>\n <input\n #highlightInput\n type=\"color\"\n class=\"absolute inset-0 h-full w-full cursor-pointer opacity-0\"\n [value]=\"activeStates.currentHighlight === 'transparent' ? '#ffff00' : activeStates.currentHighlight\"\n (input)=\"setHighlight($any($event.target).value)\"\n />\n </label>\n }\n\n @if (isFormatAllowed('list')) {\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n <s-editor-toolbar-button\n icon=\"fa fa-list-ul\"\n [label]=\"'platform.angular_components.editor_bullet_list' | translate\"\n [active]=\"activeStates.isBulletList\"\n (clicked)=\"toggleBulletList()\"\n />\n <s-editor-toolbar-button\n icon=\"fa fa-list-ol\"\n [label]=\"'platform.angular_components.editor_ordered_list' | translate\"\n [active]=\"activeStates.isOrderedList\"\n (clicked)=\"toggleOrderedList()\"\n />\n }\n\n @if (isFormatAllowed('align')) {\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n <s-editor-toolbar-button\n icon=\"fa fa-align-left\"\n [label]=\"'platform.angular_components.editor_align_left' | translate\"\n [active]=\"activeStates.isAlignLeft\"\n (clicked)=\"setTextAlign('left')\"\n />\n <s-editor-toolbar-button\n icon=\"fa fa-align-center\"\n [label]=\"'platform.angular_components.editor_align_center' | translate\"\n [active]=\"activeStates.isAlignCenter\"\n (clicked)=\"setTextAlign('center')\"\n />\n <s-editor-toolbar-button\n icon=\"fa fa-align-right\"\n [label]=\"'platform.angular_components.editor_align_right' | translate\"\n [active]=\"activeStates.isAlignRight\"\n (clicked)=\"setTextAlign('right')\"\n />\n }\n\n @if (isFormatAllowed('blockquote')) {\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n <s-editor-toolbar-button\n icon=\"fa fa-quote-right\"\n [label]=\"'platform.angular_components.editor_blockquote' | translate\"\n [active]=\"activeStates.isBlockquote\"\n (clicked)=\"toggleBlockquote()\"\n />\n }\n\n @if (isFormatAllowed('code-block')) {\n <s-editor-toolbar-button\n icon=\"fa fa-code\"\n [label]=\"'platform.angular_components.editor_inline_code' | translate\"\n [active]=\"activeStates.isCode\"\n (clicked)=\"toggleCode()\"\n />\n }\n\n @if (isFormatAllowed('link')) {\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n <s-editor-toolbar-button\n icon=\"fa fa-link\"\n [label]=\"'platform.angular_components.editor_insert_link' | translate\"\n (clicked)=\"setLink()\"\n />\n }\n\n @if (isFormatAllowed('image')) {\n <s-editor-toolbar-button\n icon=\"fa fa-image\"\n [label]=\"'platform.angular_components.editor_insert_image' | translate\"\n (clicked)=\"setImage()\"\n />\n }\n\n @if (hasAnyFormatBeforeUndoRedo()) {\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n }\n\n <s-editor-toolbar-button\n icon=\"fa fa-undo\"\n [label]=\"('platform.angular_components.editor_undo' | translate) + ' (Ctrl+Z)'\"\n [disabled]=\"!activeStates.canUndo\"\n (clicked)=\"undo()\"\n />\n <s-editor-toolbar-button\n icon=\"fa fa-redo\"\n [label]=\"('platform.angular_components.editor_redo' | translate) + ' (Ctrl+Y)'\"\n [disabled]=\"!activeStates.canRedo\"\n (clicked)=\"redo()\"\n />\n\n @if (isFormatAllowed('clean')) {\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n <s-editor-toolbar-button\n icon=\"fa fa-remove-format\"\n [label]=\"'platform.angular_components.editor_clear_formatting' | translate\"\n (clicked)=\"clearFormatting()\"\n />\n }\n </div>\n }\n\n <div\n #editorContainer\n class=\"s-editor-content flex-1\"\n ></div>\n <input\n #imageInput\n type=\"file\"\n accept=\"image/*\"\n style=\"display: none\"\n aria-hidden=\"true\"\n (change)=\"onImageFileSelected($event)\"\n />\n</div>\n", styles: [".s-editor--readonly ::ng-deep .ProseMirror{cursor:default}.s-editor-content ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:#9ca3af;pointer-events:none;float:left;height:0}.s-editor-content ::ng-deep .ProseMirror{padding:12px 16px;min-height:150px;outline:none!important;color:#1e1e2e;font-size:14px;line-height:1.6}.s-editor-content ::ng-deep .ProseMirror>*+*{margin-top:.5em}.s-editor-content ::ng-deep .ProseMirror p{margin:0}.s-editor-content ::ng-deep .ProseMirror h1{font-size:1.75em;font-weight:700;line-height:1.2;margin:.75em 0 .25em}.s-editor-content ::ng-deep .ProseMirror h1:first-child{margin-top:0}.s-editor-content ::ng-deep .ProseMirror h2{font-size:1.4em;font-weight:600;line-height:1.3;margin:.75em 0 .25em}.s-editor-content ::ng-deep .ProseMirror h2:first-child{margin-top:0}.s-editor-content ::ng-deep .ProseMirror h3{font-size:1.15em;font-weight:600;line-height:1.4;margin:.75em 0 .25em}.s-editor-content ::ng-deep .ProseMirror h3:first-child{margin-top:0}.s-editor-content ::ng-deep .ProseMirror ul{list-style:disc;padding-left:1.5em}.s-editor-content ::ng-deep .ProseMirror ol{list-style:decimal;padding-left:1.5em}.s-editor-content ::ng-deep .ProseMirror li{margin:.2em 0}.s-editor-content ::ng-deep .ProseMirror li p{margin:0}.s-editor-content ::ng-deep .ProseMirror blockquote{border-left:3px solid #5c5ce6;padding-left:1em;margin:.75em 0;color:#6b6b80;font-style:italic}.s-editor-content ::ng-deep .ProseMirror code{background:#f0f0f8;border-radius:3px;padding:.15em .4em;font-family:Courier New,Courier,monospace;font-size:.875em;color:#c026d3}.s-editor-content ::ng-deep .ProseMirror pre{background:#1e1e2e;color:#cdd6f4;border-radius:6px;padding:1em 1.25em;overflow-x:auto;font-family:Courier New,Courier,monospace;font-size:.875em;line-height:1.5}.s-editor-content ::ng-deep .ProseMirror pre code{background:none;padding:0;color:inherit;font-size:inherit}.s-editor-content ::ng-deep .ProseMirror a{color:#5c5ce6;text-decoration:underline;cursor:pointer}.s-editor-content ::ng-deep .ProseMirror a:hover{color:#4040b0}.s-editor-content ::ng-deep .ProseMirror img{max-width:100%;height:auto;border-radius:4px;display:block}.s-editor-content ::ng-deep .ProseMirror hr{border:none;border-top:2px solid #e8e8f0;margin:1em 0}.s-editor-content ::ng-deep .ProseMirror sub{font-size:.75em;vertical-align:sub}.s-editor-content ::ng-deep .ProseMirror sup{font-size:.75em;vertical-align:super}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "component", type: EditorToolbarButtonComponent, selector: "s-editor-toolbar-button", inputs: ["icon", "label", "active", "disabled"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
420
+ }
421
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: EditorComponent, decorators: [{
422
+ type: Component,
423
+ args: [{ selector: 's-editor', standalone: true, imports: [NgClass, NgStyle, TranslateModule, EditorToolbarButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
424
+ {
425
+ provide: NG_VALUE_ACCESSOR,
426
+ useExisting: forwardRef(() => EditorComponent),
427
+ multi: true,
428
+ },
429
+ ], template: "<div\n class=\"rounded bg-white flex flex-col border border-grayscale-30 transition-[border-color,box-shadow] duration-150 focus-within:border-[#5c5ce6] focus-within:shadow-[0_0_0_2px_rgba(92,92,230,0.15)]\"\n [ngClass]=\"styleClass()\"\n [ngStyle]=\"style()\"\n [class.s-editor--readonly]=\"readonly()\"\n>\n @if (!readonly()) {\n <div\n class=\"rounded-t flex flex-wrap items-center gap-0.5 border-b border-grayscale-30 bg-[#f9f9fb] px-2 py-1.5\"\n role=\"toolbar\"\n [attr.aria-label]=\"'platform.angular_components.editor_toolbar' | translate\"\n (keydown)=\"onToolbarKeydown($event)\"\n (focusin)=\"onToolbarFocusIn($event)\"\n >\n @if (isFormatAllowed('header')) {\n <select\n class=\"rounded bg-white h-7 cursor-pointer border border-grayscale-30 px-1.5 text-[13px] text-[#3d3d4d] outline-none transition-colors duration-150 focus:border-[#5c5ce6]\"\n (change)=\"onHeadingChange($event)\"\n [attr.aria-label]=\"'platform.angular_components.editor_heading_level' | translate\"\n >\n <option\n [value]=\"0\"\n [selected]=\"activeStates.currentHeading === 0\"\n >\n {{ 'platform.angular_components.editor_heading_normal' | translate }}\n </option>\n <option\n [value]=\"1\"\n [selected]=\"activeStates.currentHeading === 1\"\n >\n {{ 'platform.angular_components.editor_heading_1' | translate }}\n </option>\n <option\n [value]=\"2\"\n [selected]=\"activeStates.currentHeading === 2\"\n >\n {{ 'platform.angular_components.editor_heading_2' | translate }}\n </option>\n <option\n [value]=\"3\"\n [selected]=\"activeStates.currentHeading === 3\"\n >\n {{ 'platform.angular_components.editor_heading_3' | translate }}\n </option>\n </select>\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n }\n\n @if (isFormatAllowed('bold')) {\n <s-editor-toolbar-button\n icon=\"fa fa-bold\"\n [label]=\"'platform.angular_components.editor_bold' | translate\"\n [active]=\"activeStates.isBold\"\n (clicked)=\"toggleBold()\"\n />\n }\n\n @if (isFormatAllowed('italic')) {\n <s-editor-toolbar-button\n icon=\"fa fa-italic\"\n [label]=\"'platform.angular_components.editor_italic' | translate\"\n [active]=\"activeStates.isItalic\"\n (clicked)=\"toggleItalic()\"\n />\n }\n\n @if (isFormatAllowed('underline')) {\n <s-editor-toolbar-button\n icon=\"fa fa-underline\"\n [label]=\"'platform.angular_components.editor_underline' | translate\"\n [active]=\"activeStates.isUnderline\"\n (clicked)=\"toggleUnderline()\"\n />\n }\n\n @if (isFormatAllowed('strike')) {\n <s-editor-toolbar-button\n icon=\"fa fa-strikethrough\"\n [label]=\"'platform.angular_components.editor_strikethrough' | translate\"\n [active]=\"activeStates.isStrike\"\n (clicked)=\"toggleStrike()\"\n />\n }\n\n @if (isFormatAllowed('subscript')) {\n <s-editor-toolbar-button\n icon=\"fa fa-subscript\"\n [label]=\"'platform.angular_components.editor_subscript' | translate\"\n [active]=\"activeStates.isSubscript\"\n (clicked)=\"toggleSubscript()\"\n />\n }\n\n @if (isFormatAllowed('superscript')) {\n <s-editor-toolbar-button\n icon=\"fa fa-superscript\"\n [label]=\"'platform.angular_components.editor_superscript' | translate\"\n [active]=\"activeStates.isSuperscript\"\n (clicked)=\"toggleSuperscript()\"\n />\n }\n\n @if (isFormatAllowed('color')) {\n <label\n tabindex=\"0\"\n class=\"relative flex h-7 w-7 cursor-pointer items-center justify-center rounded bg-white transition-colors duration-150 hover:bg-[#f0f0f8]\"\n [attr.title]=\"'platform.angular_components.editor_text_color' | translate\"\n [attr.aria-label]=\"'platform.angular_components.editor_text_color' | translate\"\n (keydown.enter)=\"$event.preventDefault(); colorInput.click()\"\n (keydown.space)=\"$event.preventDefault(); colorInput.click()\"\n >\n <span class=\"flex flex-col items-center gap-px\">\n <i class=\"fa fa-font text-[11px] text-[#3d3d4d]\"></i>\n <span\n class=\"h-[3px] w-3.5 rounded-sm\"\n [style.background-color]=\"activeStates.currentColor\"\n ></span>\n </span>\n <input\n #colorInput\n type=\"color\"\n class=\"absolute inset-0 h-full w-full cursor-pointer opacity-0\"\n [value]=\"activeStates.currentColor\"\n (input)=\"setColor($any($event.target).value)\"\n />\n </label>\n }\n\n @if (isFormatAllowed('highlight')) {\n <label\n tabindex=\"0\"\n class=\"relative flex h-7 w-7 cursor-pointer items-center justify-center rounded bg-white transition-colors duration-150 hover:bg-[#f0f0f8]\"\n [attr.title]=\"'platform.angular_components.editor_background_color' | translate\"\n [attr.aria-label]=\"'platform.angular_components.editor_background_color' | translate\"\n (keydown.enter)=\"$event.preventDefault(); highlightInput.click()\"\n (keydown.space)=\"$event.preventDefault(); highlightInput.click()\"\n >\n <span class=\"flex flex-col items-center gap-px\">\n <i class=\"fa fa-highlighter text-[11px] text-[#3d3d4d]\"></i>\n <span\n class=\"h-[3px] w-3.5 rounded-sm\"\n [style.background-color]=\"activeStates.currentHighlight === 'transparent' ? '#ffff00' : activeStates.currentHighlight\"\n ></span>\n </span>\n <input\n #highlightInput\n type=\"color\"\n class=\"absolute inset-0 h-full w-full cursor-pointer opacity-0\"\n [value]=\"activeStates.currentHighlight === 'transparent' ? '#ffff00' : activeStates.currentHighlight\"\n (input)=\"setHighlight($any($event.target).value)\"\n />\n </label>\n }\n\n @if (isFormatAllowed('list')) {\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n <s-editor-toolbar-button\n icon=\"fa fa-list-ul\"\n [label]=\"'platform.angular_components.editor_bullet_list' | translate\"\n [active]=\"activeStates.isBulletList\"\n (clicked)=\"toggleBulletList()\"\n />\n <s-editor-toolbar-button\n icon=\"fa fa-list-ol\"\n [label]=\"'platform.angular_components.editor_ordered_list' | translate\"\n [active]=\"activeStates.isOrderedList\"\n (clicked)=\"toggleOrderedList()\"\n />\n }\n\n @if (isFormatAllowed('align')) {\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n <s-editor-toolbar-button\n icon=\"fa fa-align-left\"\n [label]=\"'platform.angular_components.editor_align_left' | translate\"\n [active]=\"activeStates.isAlignLeft\"\n (clicked)=\"setTextAlign('left')\"\n />\n <s-editor-toolbar-button\n icon=\"fa fa-align-center\"\n [label]=\"'platform.angular_components.editor_align_center' | translate\"\n [active]=\"activeStates.isAlignCenter\"\n (clicked)=\"setTextAlign('center')\"\n />\n <s-editor-toolbar-button\n icon=\"fa fa-align-right\"\n [label]=\"'platform.angular_components.editor_align_right' | translate\"\n [active]=\"activeStates.isAlignRight\"\n (clicked)=\"setTextAlign('right')\"\n />\n }\n\n @if (isFormatAllowed('blockquote')) {\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n <s-editor-toolbar-button\n icon=\"fa fa-quote-right\"\n [label]=\"'platform.angular_components.editor_blockquote' | translate\"\n [active]=\"activeStates.isBlockquote\"\n (clicked)=\"toggleBlockquote()\"\n />\n }\n\n @if (isFormatAllowed('code-block')) {\n <s-editor-toolbar-button\n icon=\"fa fa-code\"\n [label]=\"'platform.angular_components.editor_inline_code' | translate\"\n [active]=\"activeStates.isCode\"\n (clicked)=\"toggleCode()\"\n />\n }\n\n @if (isFormatAllowed('link')) {\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n <s-editor-toolbar-button\n icon=\"fa fa-link\"\n [label]=\"'platform.angular_components.editor_insert_link' | translate\"\n (clicked)=\"setLink()\"\n />\n }\n\n @if (isFormatAllowed('image')) {\n <s-editor-toolbar-button\n icon=\"fa fa-image\"\n [label]=\"'platform.angular_components.editor_insert_image' | translate\"\n (clicked)=\"setImage()\"\n />\n }\n\n @if (hasAnyFormatBeforeUndoRedo()) {\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n }\n\n <s-editor-toolbar-button\n icon=\"fa fa-undo\"\n [label]=\"('platform.angular_components.editor_undo' | translate) + ' (Ctrl+Z)'\"\n [disabled]=\"!activeStates.canUndo\"\n (clicked)=\"undo()\"\n />\n <s-editor-toolbar-button\n icon=\"fa fa-redo\"\n [label]=\"('platform.angular_components.editor_redo' | translate) + ' (Ctrl+Y)'\"\n [disabled]=\"!activeStates.canRedo\"\n (clicked)=\"redo()\"\n />\n\n @if (isFormatAllowed('clean')) {\n <span class=\"mx-1 inline-block h-5 w-px shrink-0 bg-[#d1d1dc]\"></span>\n <s-editor-toolbar-button\n icon=\"fa fa-remove-format\"\n [label]=\"'platform.angular_components.editor_clear_formatting' | translate\"\n (clicked)=\"clearFormatting()\"\n />\n }\n </div>\n }\n\n <div\n #editorContainer\n class=\"s-editor-content flex-1\"\n ></div>\n <input\n #imageInput\n type=\"file\"\n accept=\"image/*\"\n style=\"display: none\"\n aria-hidden=\"true\"\n (change)=\"onImageFileSelected($event)\"\n />\n</div>\n", styles: [".s-editor--readonly ::ng-deep .ProseMirror{cursor:default}.s-editor-content ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:#9ca3af;pointer-events:none;float:left;height:0}.s-editor-content ::ng-deep .ProseMirror{padding:12px 16px;min-height:150px;outline:none!important;color:#1e1e2e;font-size:14px;line-height:1.6}.s-editor-content ::ng-deep .ProseMirror>*+*{margin-top:.5em}.s-editor-content ::ng-deep .ProseMirror p{margin:0}.s-editor-content ::ng-deep .ProseMirror h1{font-size:1.75em;font-weight:700;line-height:1.2;margin:.75em 0 .25em}.s-editor-content ::ng-deep .ProseMirror h1:first-child{margin-top:0}.s-editor-content ::ng-deep .ProseMirror h2{font-size:1.4em;font-weight:600;line-height:1.3;margin:.75em 0 .25em}.s-editor-content ::ng-deep .ProseMirror h2:first-child{margin-top:0}.s-editor-content ::ng-deep .ProseMirror h3{font-size:1.15em;font-weight:600;line-height:1.4;margin:.75em 0 .25em}.s-editor-content ::ng-deep .ProseMirror h3:first-child{margin-top:0}.s-editor-content ::ng-deep .ProseMirror ul{list-style:disc;padding-left:1.5em}.s-editor-content ::ng-deep .ProseMirror ol{list-style:decimal;padding-left:1.5em}.s-editor-content ::ng-deep .ProseMirror li{margin:.2em 0}.s-editor-content ::ng-deep .ProseMirror li p{margin:0}.s-editor-content ::ng-deep .ProseMirror blockquote{border-left:3px solid #5c5ce6;padding-left:1em;margin:.75em 0;color:#6b6b80;font-style:italic}.s-editor-content ::ng-deep .ProseMirror code{background:#f0f0f8;border-radius:3px;padding:.15em .4em;font-family:Courier New,Courier,monospace;font-size:.875em;color:#c026d3}.s-editor-content ::ng-deep .ProseMirror pre{background:#1e1e2e;color:#cdd6f4;border-radius:6px;padding:1em 1.25em;overflow-x:auto;font-family:Courier New,Courier,monospace;font-size:.875em;line-height:1.5}.s-editor-content ::ng-deep .ProseMirror pre code{background:none;padding:0;color:inherit;font-size:inherit}.s-editor-content ::ng-deep .ProseMirror a{color:#5c5ce6;text-decoration:underline;cursor:pointer}.s-editor-content ::ng-deep .ProseMirror a:hover{color:#4040b0}.s-editor-content ::ng-deep .ProseMirror img{max-width:100%;height:auto;border-radius:4px;display:block}.s-editor-content ::ng-deep .ProseMirror hr{border:none;border-top:2px solid #e8e8f0;margin:1em 0}.s-editor-content ::ng-deep .ProseMirror sub{font-size:.75em;vertical-align:sub}.s-editor-content ::ng-deep .ProseMirror sup{font-size:.75em;vertical-align:super}\n"] }]
430
+ }], ctorParameters: () => [] });
431
+
432
+ /**
433
+ * Generated bundle index. Do not edit.
434
+ */
435
+
436
+ export { EditorComponent };
437
+ //# sourceMappingURL=seniorsistemas-angular-components-editor.mjs.map