rapid-text-editor 1.0.15 → 1.0.17

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.
@@ -23,11 +23,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
23
23
  }], ctorParameters: function () { return []; } });
24
24
 
25
25
  class RapidTextEditorComponent {
26
- constructor(dialog, el, renderer, elRef) {
26
+ constructor(dialog, el, renderer, elRef, _change) {
27
27
  this.dialog = dialog;
28
28
  this.el = el;
29
29
  this.renderer = renderer;
30
30
  this.elRef = elRef;
31
+ this._change = _change;
31
32
  this.contentCapture = false;
32
33
  this.height = "auto";
33
34
  this.width = "auto";
@@ -45,6 +46,7 @@ class RapidTextEditorComponent {
45
46
  this.selectedHead = 'P';
46
47
  this.selectedFont = '14';
47
48
  }
49
+ this._change.detectChanges();
48
50
  };
49
51
  this.onTouched = () => { };
50
52
  console.log('Build -1');
@@ -56,6 +58,8 @@ class RapidTextEditorComponent {
56
58
  else {
57
59
  console.log('Content capture is disabled.');
58
60
  }
61
+ // this.initializeEditorContent('');
62
+ // this.ensureParagraphAndFocus();
59
63
  }
60
64
  ngOnChanges(changes) {
61
65
  if (changes['height'] || changes['width']) {
@@ -88,6 +92,57 @@ class RapidTextEditorComponent {
88
92
  else {
89
93
  console.error('Editor element not found.');
90
94
  }
95
+ const observer = new MutationObserver(() => this.updateCurrentFormat());
96
+ observer.observe(this.editor.nativeElement, {
97
+ childList: true,
98
+ characterData: true,
99
+ subtree: true
100
+ });
101
+ // this.initializeEditorContent('');
102
+ // this.ensureParagraphAndFocus();
103
+ }
104
+ ensureParagraphAndFocus() {
105
+ const editor = document.getElementById('editor');
106
+ if (!editor)
107
+ return;
108
+ // If editor is empty or doesn't have a <p> as the last element
109
+ if (!editor.innerHTML.trim()) {
110
+ editor.innerHTML = '<p style="font-size:14px; font-weight:normal;">\u200B</p>';
111
+ }
112
+ else {
113
+ const firstChild = editor.firstChild;
114
+ if (!firstChild || firstChild.tagName !== 'P') {
115
+ const content = editor.innerHTML;
116
+ editor.innerHTML = `<p style="font-size:14px; font-weight:normal;">${content}</p>`;
117
+ }
118
+ }
119
+ const p = editor.querySelector('p');
120
+ if (p) {
121
+ const range = document.createRange();
122
+ range.selectNodeContents(p);
123
+ range.collapse(true);
124
+ const selection = window.getSelection();
125
+ if (selection) {
126
+ selection.removeAllRanges();
127
+ selection.addRange(range);
128
+ }
129
+ }
130
+ // Focus the editor
131
+ editor.focus();
132
+ }
133
+ initializeEditorContent(data) {
134
+ const editor = document.getElementById('editor');
135
+ if (!editor)
136
+ return;
137
+ // If content has no HTML tags, wrap with <p>
138
+ const hasHtmlTags = /<[^>]+>/.test(data);
139
+ if (!hasHtmlTags) {
140
+ editor.innerHTML = `<p style="font-size:14px; font-weight: normal;">${data}</p>`;
141
+ // this.ensureParagraphAndFocus();
142
+ }
143
+ else {
144
+ editor.innerHTML = data;
145
+ }
91
146
  }
92
147
  onContentChange() {
93
148
  if (this.contentCapture) {
@@ -119,8 +174,94 @@ class RapidTextEditorComponent {
119
174
  onBlur() {
120
175
  this.onTouched();
121
176
  }
177
+ // setFontSize(event: Event) {
178
+ // const select = event.target as HTMLSelectElement;
179
+ // const size = select.value;
180
+ // const selection = window.getSelection();
181
+ // if (!selection || selection.rangeCount === 0) return;
182
+ // const range = selection.getRangeAt(0);
183
+ // if (!range.collapsed) {
184
+ // const parent = selection.anchorNode?.parentElement;
185
+ // if (
186
+ // parent &&
187
+ // parent.classList &&
188
+ // Array.from(parent.classList).some((c: string) => c.startsWith('fs-'))
189
+ // ) {
190
+ // parent.style.fontSize = `${size}px`;
191
+ // parent.className = `fs-${size}`;
192
+ // } else {
193
+ // const span = document.createElement('span');
194
+ // span.style.fontSize = `${size}px`;
195
+ // span.classList.add(`fs-${size}`);
196
+ // range.surroundContents(span);
197
+ // }
198
+ // }
199
+ // else {
200
+ // const span = document.createElement('span');
201
+ // span.style.fontSize = `${size}px`;
202
+ // span.classList.add(`fs-${size}`);
203
+ // span.appendChild(document.createTextNode('\u200B')); // zero-width space
204
+ // range.insertNode(span);
205
+ // const newRange = document.createRange();
206
+ // newRange.setStart(span.firstChild as Node, 1);
207
+ // newRange.collapse(true);
208
+ // selection.removeAllRanges();
209
+ // selection.addRange(newRange);
210
+ // }
211
+ // }
212
+ onEditorKeyUp(event) {
213
+ // handle Enter or arrow keys
214
+ if (event.key === 'Enter' || event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'BackSpace') {
215
+ this.updateCurrentFormat();
216
+ }
217
+ }
218
+ updateCurrentFormat() {
219
+ const selection = window.getSelection();
220
+ if (!selection || selection.rangeCount === 0)
221
+ return;
222
+ const anchorNode = selection.anchorNode;
223
+ if (!anchorNode)
224
+ return;
225
+ let parentElem = anchorNode.nodeType === Node.ELEMENT_NODE
226
+ ? anchorNode
227
+ : anchorNode.parentElement;
228
+ if (!parentElem)
229
+ return;
230
+ let detectedHead = 'P';
231
+ let detectedFont = '14'; // default
232
+ // Traverse upward to detect formatting
233
+ while (parentElem && parentElem !== this.editor.nativeElement) {
234
+ const tag = parentElem.tagName.toUpperCase();
235
+ // Detect heading
236
+ if (['H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'P'].includes(tag)) {
237
+ detectedHead = tag;
238
+ }
239
+ // Detect inline font-size from style or class
240
+ const fontSize = window.getComputedStyle(parentElem).fontSize;
241
+ if (fontSize) {
242
+ const px = parseInt(fontSize.replace('px', ''), 10);
243
+ if (!isNaN(px)) {
244
+ detectedFont = px.toString();
245
+ break; // found the closest valid font size
246
+ }
247
+ }
248
+ parentElem = parentElem.parentElement;
249
+ }
250
+ // Update bound properties if changed
251
+ let changed = false;
252
+ if (this.selectedHead !== detectedHead) {
253
+ this.selectedHead = detectedHead;
254
+ changed = true;
255
+ }
256
+ if (this.selectedFont !== detectedFont) {
257
+ this.selectedFont = detectedFont;
258
+ changed = true;
259
+ }
260
+ if (changed) {
261
+ this._change.detectChanges();
262
+ }
263
+ }
122
264
  setFontSize(event) {
123
- var _a;
124
265
  const select = event.target;
125
266
  const size = select.value;
126
267
  const selection = window.getSelection();
@@ -128,32 +269,41 @@ class RapidTextEditorComponent {
128
269
  return;
129
270
  const range = selection.getRangeAt(0);
130
271
  if (!range.collapsed) {
131
- const parent = (_a = selection.anchorNode) === null || _a === void 0 ? void 0 : _a.parentElement;
132
- if (parent &&
133
- parent.classList &&
134
- Array.from(parent.classList).some((c) => c.startsWith('fs-'))) {
135
- parent.style.fontSize = `${size}px`;
136
- parent.className = `fs-${size}`;
137
- }
138
- else {
139
- const span = document.createElement('span');
140
- span.style.fontSize = `${size}px`;
141
- span.classList.add(`fs-${size}`);
272
+ // Non-empty selection
273
+ const span = document.createElement('span');
274
+ span.style.setProperty('font-size', `${size}px`, 'important');
275
+ span.classList.add(`fs-${size}`);
276
+ try {
142
277
  range.surroundContents(span);
143
278
  }
279
+ catch (_a) {
280
+ // If selection spans multiple elements, use execCommand fallback
281
+ document.execCommand('fontSize', false, '7'); // temporary largest size
282
+ document.querySelectorAll('font[size="7"]').forEach((el) => {
283
+ el.removeAttribute('size');
284
+ el.style.setProperty('font-size', `${size}px`, 'important');
285
+ el.classList.add(`fs-${size}`);
286
+ });
287
+ }
144
288
  }
145
289
  else {
290
+ // Collapsed selection (no text selected)
146
291
  const span = document.createElement('span');
147
- span.style.fontSize = `${size}px`;
292
+ span.style.setProperty('font-size', `${size}px`, 'important');
148
293
  span.classList.add(`fs-${size}`);
149
294
  span.appendChild(document.createTextNode('\u200B')); // zero-width space
150
295
  range.insertNode(span);
296
+ // Move cursor inside span
151
297
  const newRange = document.createRange();
152
298
  newRange.setStart(span.firstChild, 1);
153
299
  newRange.collapse(true);
154
300
  selection.removeAllRanges();
155
301
  selection.addRange(newRange);
156
302
  }
303
+ const content = this.editor.nativeElement.innerHTML;
304
+ this.onChange(content);
305
+ this.updateCurrentFormat();
306
+ this._change.detectChanges();
157
307
  }
158
308
  setHeading(event) {
159
309
  const select = event.target;
@@ -168,33 +318,33 @@ class RapidTextEditorComponent {
168
318
  const newElem = document.createElement(tag);
169
319
  switch (tag) {
170
320
  case 'H1':
171
- newElem.style.fontSize = '32px';
172
- newElem.style.fontWeight = 'bold';
321
+ newElem.style.setProperty('font-size', '32px', 'important');
322
+ newElem.style.setProperty('font-weight', 'bold', 'important');
173
323
  break;
174
324
  case 'H2':
175
- newElem.style.fontSize = '28px';
176
- newElem.style.fontWeight = 'bold';
325
+ newElem.style.setProperty('font-size', '28px', 'important');
326
+ newElem.style.setProperty('font-weight', 'bold', 'important');
177
327
  break;
178
328
  case 'H3':
179
- newElem.style.fontSize = '24px';
180
- newElem.style.fontWeight = 'bold';
329
+ newElem.style.setProperty('font-size', '24px', 'important');
330
+ newElem.style.setProperty('font-weight', 'bold', 'important');
181
331
  break;
182
332
  case 'H4':
183
- newElem.style.fontSize = '20px';
184
- newElem.style.fontWeight = 'bold';
333
+ newElem.style.setProperty('font-size', '20px', 'important');
334
+ newElem.style.setProperty('font-weight', 'bold', 'important');
185
335
  break;
186
336
  case 'H5':
187
- newElem.style.fontSize = '18px';
188
- newElem.style.fontWeight = '600';
337
+ newElem.style.setProperty('font-size', '18px', 'important');
338
+ newElem.style.setProperty('font-weight', '600', 'important');
189
339
  break;
190
340
  case 'H6':
191
- newElem.style.fontSize = '16px';
192
- newElem.style.fontWeight = '600';
341
+ newElem.style.setProperty('font-size', '16px', 'important');
342
+ newElem.style.setProperty('font-weight', '600', 'important');
193
343
  break;
194
344
  case 'P':
195
345
  default:
196
- newElem.style.fontSize = '14px';
197
- newElem.style.fontWeight = 'normal';
346
+ newElem.style.setProperty('font-size', '14px', 'important');
347
+ newElem.style.setProperty('font-weight', 'normal', 'important');
198
348
  break;
199
349
  }
200
350
  const selectedText = selection.toString();
@@ -202,7 +352,7 @@ class RapidTextEditorComponent {
202
352
  newElem.textContent = selectedText;
203
353
  }
204
354
  else {
205
- newElem.innerHTML = '\u200B'; // Zero-width space to keep cursor visible
355
+ newElem.innerHTML = '\u200B'; // Keeps cursor visible
206
356
  }
207
357
  range.deleteContents();
208
358
  range.insertNode(newElem);
@@ -553,11 +703,11 @@ class RapidTextEditorComponent {
553
703
  }
554
704
  }
555
705
  createTableHTML(rowCount, colCount) {
556
- let tableHTML = '<table border="1" style="">';
706
+ let tableHTML = '<table style="font-size: 14px; width: 100%; border: 1px solid black; border-collapse: collapse;">';
557
707
  for (let i = 0; i < rowCount; i++) {
558
708
  tableHTML += '<tr>';
559
709
  for (let j = 0; j < colCount; j++) {
560
- tableHTML += `<td style="font-size: 14px; min-width: 1.5em; height: 2em; padding: .4em; border: 1px solid black"
710
+ tableHTML += `<td style="border: 1px solid black; border-collapse: collapse; height: 2em; padding: .4em; "
561
711
  role="textbox" contenteditable="true"></td>`;
562
712
  }
563
713
  tableHTML += '</tr>';
@@ -604,19 +754,25 @@ class RapidTextEditorComponent {
604
754
  }
605
755
  submitContent() {
606
756
  const editor = this.editor.nativeElement;
757
+ if (!editor)
758
+ return;
607
759
  const content = editor.innerHTML; // Get the HTML content from the editor
608
760
  const plainTextContent = editor.innerText; // Optionally, get plain text content
761
+ if (!editor.innerHTML.trim()) {
762
+ editor.innerHTML = '<p style="font-size:14px; font-weight:normal;">\u200B</p>';
763
+ // this.ensureParagraphAndFocus();
764
+ }
609
765
  this.onChange(content);
610
766
  }
611
767
  }
612
- RapidTextEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: RapidTextEditorComponent, deps: [{ token: i1.MatDialog }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
768
+ RapidTextEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: RapidTextEditorComponent, deps: [{ token: i1.MatDialog }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
613
769
  RapidTextEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: RapidTextEditorComponent, selector: "rapid-text-editor", inputs: { contentCapture: "contentCapture", height: "height", width: "width" }, outputs: { contentChange: "contentChange" }, providers: [
614
770
  {
615
771
  provide: NG_VALUE_ACCESSOR,
616
772
  useExisting: forwardRef(() => RapidTextEditorComponent),
617
773
  multi: true
618
774
  }
619
- ], viewQueries: [{ propertyName: "editor", first: true, predicate: ["editor"], descendants: true, static: true }, { propertyName: "tableDialog", first: true, predicate: ["tableDialog"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"dimension\">\r\n <div class=\"rich-text-editor\">\r\n <!-- Toolbar -->\r\n <div class=\"toolbar\">\r\n <select class=\"select-wrapper\" [(ngModel)]=\"selectedHead\" (change)=\"setHeading($event)\">\r\n <option value=\"P\" style=\"font-size: 14px;\">Paragraph</option>\r\n <option value=\"H1\" style=\"font-size: 32px; font-weight: bold;\">H1</option>\r\n <option value=\"H2\" style=\"font-size: 28px; font-weight: bold;\">H2</option>\r\n <option value=\"H3\" style=\"font-size: 24px; font-weight: bold;\">H3</option>\r\n <option value=\"H4\" style=\"font-size: 20px; font-weight: bold;\">H4</option>\r\n <option value=\"H5\" style=\"font-size: 18px; font-weight: 600;\">H5</option>\r\n <option value=\"H6\" style=\"font-size: 16px; font-weight: 600;\">H6</option>\r\n </select>\r\n <select class=\"select-wrapper\" (change)=\"onChange(null)\" [(ngModel)]=\"selectedFont\"\r\n (change)=\"setFontSize($event)\">\r\n <option style=\"font-size: 12px;\" value=\"12\">12px</option>\r\n <option style=\"font-size: 14px;\" value=\"14\" selected>14px</option>\r\n <option style=\"font-size: 16px;\" value=\"16\">16px</option>\r\n <option style=\"font-size: 18px;\" value=\"18\">18px</option>\r\n <option style=\"font-size: 24px;\" value=\"24\">24px</option>\r\n <option style=\"font-size: 32px;\" value=\"32\">32px</option>\r\n <option style=\"font-size: 48px;\" value=\"48\">48px</option>\r\n </select>\r\n <button (click)=\"format('bold')\" type=\"button\" aria-label=\"Bold\">\r\n <mat-icon>format_bold</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('italic')\" type=\"button\" aria-label=\"Italic\">\r\n <mat-icon>format_italic</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('underline')\" type=\"button\" aria-label=\"Underline\">\r\n <mat-icon>format_underline</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('strikethrough')\" type=\"button\" aria-label=\"Strikethrough\">\r\n <mat-icon>strikethrough_s</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyLeft')\" type=\"button\" aria-label=\"Align Left\">\r\n <mat-icon>format_align_left</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyCenter')\" type=\"button\" aria-label=\"Center\">\r\n <mat-icon>format_align_center</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyRight')\" type=\"button\" aria-label=\"Align Right\">\r\n <mat-icon>format_align_right</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyFull')\" type=\"button\" aria-label=\"Justify\">\r\n <mat-icon>format_align_justify</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('insertUnorderedList')\" type=\"button\" aria-label=\"Unordered List\">\r\n <mat-icon>format_list_bulleted</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('insertOrderedList')\" type=\"button\" aria-label=\"Ordered List\">\r\n <mat-icon>format_list_numbered</mat-icon>\r\n </button>\r\n <button color=\"secondary\" aria-label=\"Insert Image\" type=\"button\"\r\n style=\"position: relative; display: inline-flex; align-items: center; justify-content: center;\">\r\n <input type=\"file\" (change)=\"insertImageToEditor($event)\"\r\n style=\"position: absolute; left: -50%; top: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer;\"\r\n aria-hidden=\"true\" />\r\n <mat-icon style=\"pointer-events: none;\">insert_photo_outlined</mat-icon>\r\n </button>\r\n <button (click)=\"openTableDialog($event)\" type=\"button\" color=\"secondary\"\r\n aria-label=\"Choose table rows and columns\">\r\n <mat-icon>border_all</mat-icon>\r\n </button>\r\n\r\n <button class=\"mb-1\" (click)=\"makeFirstRowHeader()\" type=\"button\" color=\"secondary\" aria-label=\"Make Header\">\r\n <span style=\"font-size: 20px;\" class=\"material-symbols-outlined\">\r\n page_header\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"editor\" id=\"editor\" contenteditable=\"true\" #editor (input)=\"submitContent()\" (blur)=\"onBlur()\"\r\n (drop)=\"drop($event)\" (dragover)=\"allowDrop($event)\">\r\n </div>\r\n </div>\r\n <ng-template #tableDialog let-dialogRef=\"dialogRef\">\r\n <h2 mat-dialog-title>Choose Table Size</h2>\r\n <mat-dialog-content>\r\n <div class=\"grid-container\">\r\n <div *ngFor=\"let cell of grid; let i = index\" [ngClass]=\"{\r\n 'grid-item': true,\r\n 'highlighted': i % 7 < cols && Math.floor(i / 7) < rows\r\n }\" (mouseenter)=\"updatePreview(i % 7 + 1, Math.floor(i / 7) + 1)\"\r\n (click)=\"updateSelection(i % 7 + 1, Math.floor(i / 7) + 1, dialogRef)\"></div>\r\n </div>\r\n <p>{{ rows }} x {{ cols }} </p>\r\n </mat-dialog-content>\r\n </ng-template>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.rich-text-editor{border:1px solid #ccc;border-radius:5px;font-family:Calibri}::ng-deep .editor{position:relative;min-height:300px;border:1px solid #ccc;padding:5px;overflow-y:auto;font-family:Calibri!important;outline:none!important;font-size:14px}::ng-deep .editor table{width:100%;border-collapse:collapse;margin:5px}.fs-12{font-size:12px}.fs-13{font-size:13px}.fs-14{font-size:14px}.fs-16{font-size:16px}.fs-18{font-size:18px}.fs-20{font-size:20px}.fs-24{font-size:24px}.fs-28{font-size:28px}.editor h1{font-size:32px;font-weight:700;margin:0}.editor h2{font-size:28px;font-weight:700;margin:0}.editor h3{font-size:24px;font-weight:700;margin:0}.editor h4{font-size:20px;font-weight:700;margin:0}.editor h5{font-size:18px;font-weight:600;margin:0}.editor h6{font-size:16px;font-weight:600;margin:0}.editor p{font-size:14px;font-weight:400;margin:0}button{width:20px;height:20px;background:none;border:none;margin-left:5px;cursor:pointer}button[mat-icon-button]{margin:0 4px;width:20px!important;height:20px;background:none;border:none}.small-icon-button{width:30px;height:30px;padding:4px}.small-icon-button mat-icon{font-size:16px}button[mat-icon-button]{position:relative;overflow:hidden}input[type=file]{padding:5px;cursor:pointer;margin-left:10px}.fileInput{display:flex;justify-content:center;align-items:center}.select-wrapper{display:inline-block;position:relative;width:70px}.select-wrapper select{appearance:none;width:100%;padding:10px 40px 10px 15px;font-size:16px;color:#333;background-color:#f4f4f4;border:1px solid #ddd;cursor:pointer;outline:none}.select-wrapper:after{content:\"\\25bc\";position:absolute;top:50%;right:15px;transform:translateY(-50%);pointer-events:none;color:#777;font-size:12px}.select-wrapper select:hover{background-color:#e9e9e9;border-color:#bbb}.select-wrapper select:focus{border-color:#007bff;background-color:#fff}.select-wrapper option{padding:8px;font-size:16px;color:#333;background-color:#fff}.toolbar{display:flex;flex-wrap:wrap;align-items:center;background-color:#f4f4f4;padding:10px;border-radius:8px;box-shadow:0 2px 8px #0000001a;gap:10px}.select-wrapper{padding:8px;font-size:14px;border:1px solid #ddd;cursor:pointer;background-color:#fff}.select-wrapper:focus{outline:none;border-color:#007bff}button{border:none;border-radius:5px;padding:8px;cursor:pointer;display:flex;align-items:center;justify-content:center}button:hover{color:#007bff}mat-icon{font-size:20px;color:inherit}input[type=number]{width:60px;padding:5px;font-size:14px;border:1px solid #ddd;border-radius:5px;text-align:center}input[type=file]{border:1px solid #ddd;border-radius:5px;padding:5px;font-size:14px;background-color:#fff;cursor:pointer}input[type=file]:hover{border-color:#007bff}.table{width:100px;height:30px;color:#007bff!important;font-weight:700;border:1px solid #007bff}.table:hover{background-color:#0056b3;color:#fff!important}.submit{margin-top:10px;width:100px;height:30px;color:#007bff!important;font-weight:700;border:1px solid #007bff}.submit:hover{border:none;background-color:#0056b3;color:#fff!important}.custom-dialog-container{width:auto;max-width:200px}.grid-container{display:grid;grid-template-columns:repeat(7,20px);grid-gap:5px;gap:5px}.grid-item{width:20px;height:20px;border:1px solid #ddd}.highlighted{background-color:#2196f3}div[contenteditable=false]{display:inline-block;position:relative;resize:both;overflow:hidden;border:1px dashed #ccc;margin:5px}div[contenteditable=false]:hover{border-color:#007bff}div[contenteditable=false] img{display:block;width:100%;height:auto}.uploaded-images{display:flex;flex-wrap:wrap;margin-bottom:20px}.image-preview{margin:10px;padding:5px;border:1px dashed #ccc;cursor:pointer}.image-preview img{max-width:100px;max-height:100px;object-fit:cover}.editor{border:1px solid #ccc;min-height:300px;padding:20px;position:relative}.remove_btn{position:relative;top:10px}\n"], components: [{ type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
775
+ ], viewQueries: [{ propertyName: "editor", first: true, predicate: ["editor"], descendants: true, static: true }, { propertyName: "tableDialog", first: true, predicate: ["tableDialog"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"dimension\">\r\n <div class=\"rich-text-editor\">\r\n <!-- Toolbar -->\r\n <div class=\"toolbar\">\r\n <select class=\"select-wrapper\" [(ngModel)]=\"selectedHead\" (change)=\"setHeading($event)\">\r\n <option value=\"P\" style=\"font-size: 14px !important;\">Paragraph</option>\r\n <option value=\"H1\" style=\"font-size: 32px !important; font-weight: bold !important;\">H1</option>\r\n <option value=\"H2\" style=\"font-size: 28px !important; font-weight: bold !important;\">H2</option>\r\n <option value=\"H3\" style=\"font-size: 24px !important; font-weight: bold !important;\">H3</option>\r\n <option value=\"H4\" style=\"font-size: 20px !important; font-weight: bold !important;\">H4</option>\r\n <option value=\"H5\" style=\"font-size: 18px !important; font-weight: 600 !important;\">H5</option>\r\n <option value=\"H6\" style=\"font-size: 16px !important; font-weight: 600 !important;\">H6</option>\r\n </select>\r\n <select class=\"select-wrapper\" [(ngModel)]=\"selectedFont\"\r\n (change)=\"setFontSize($event)\">\r\n <option style=\"font-size: 12px !important;\" value=\"12\">12px</option>\r\n <option style=\"font-size: 14px !important;\" value=\"14\" selected>14px</option>\r\n <option style=\"font-size: 16px !important;\" value=\"16\">16px</option>\r\n <option style=\"font-size: 18px !important;\" value=\"18\">18px</option>\r\n <option style=\"font-size: 20px !important;\" value=\"20\">20px</option> \r\n <option style=\"font-size: 24px !important;\" value=\"24\">24px</option>\r\n <option style=\"font-size: 28px !important;\" value=\"28\">28px</option>\r\n <option style=\"font-size: 32px !important;\" value=\"32\">32px</option>\r\n <option style=\"font-size: 48px !important;\" value=\"48\">48px</option>\r\n </select>\r\n <button (click)=\"format('bold')\" type=\"button\" aria-label=\"Bold\">\r\n <mat-icon>format_bold</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('italic')\" type=\"button\" aria-label=\"Italic\">\r\n <mat-icon>format_italic</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('underline')\" type=\"button\" aria-label=\"Underline\">\r\n <mat-icon>format_underline</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('strikethrough')\" type=\"button\" aria-label=\"Strikethrough\">\r\n <mat-icon>strikethrough_s</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyLeft')\" type=\"button\" aria-label=\"Align Left\">\r\n <mat-icon>format_align_left</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyCenter')\" type=\"button\" aria-label=\"Center\">\r\n <mat-icon>format_align_center</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyRight')\" type=\"button\" aria-label=\"Align Right\">\r\n <mat-icon>format_align_right</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyFull')\" type=\"button\" aria-label=\"Justify\">\r\n <mat-icon>format_align_justify</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('insertUnorderedList')\" type=\"button\" aria-label=\"Unordered List\">\r\n <mat-icon>format_list_bulleted</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('insertOrderedList')\" type=\"button\" aria-label=\"Ordered List\">\r\n <mat-icon>format_list_numbered</mat-icon>\r\n </button>\r\n <button color=\"secondary\" aria-label=\"Insert Image\" type=\"button\"\r\n style=\"position: relative; display: inline-flex; align-items: center; justify-content: center;\">\r\n <input type=\"file\" (change)=\"insertImageToEditor($event)\"\r\n style=\"position: absolute; left: -50%; top: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer;\"\r\n aria-hidden=\"true\" />\r\n <mat-icon style=\"pointer-events: none;\">insert_photo_outlined</mat-icon>\r\n </button>\r\n <button (click)=\"openTableDialog($event)\" type=\"button\" color=\"secondary\"\r\n aria-label=\"Choose table rows and columns\">\r\n <mat-icon>border_all</mat-icon>\r\n </button>\r\n\r\n <button class=\"mb-1\" (click)=\"makeFirstRowHeader()\" type=\"button\" color=\"secondary\" aria-label=\"Make Header\">\r\n <span style=\"font-size: 20px;\" class=\"material-symbols-outlined\">\r\n page_header\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"editor\" id=\"editor\" contenteditable=\"true\" #editor (input)=\"submitContent()\" (blur)=\"onBlur()\" (keyup)=\"onEditorKeyUp($event)\" (mouseup)=\"updateCurrentFormat()\"\r\n (drop)=\"drop($event)\" (dragover)=\"allowDrop($event)\">\r\n </div>\r\n </div>\r\n <ng-template #tableDialog let-dialogRef=\"dialogRef\">\r\n <h2 mat-dialog-title>Choose Table Size</h2>\r\n <mat-dialog-content>\r\n <div class=\"grid-container\">\r\n <div *ngFor=\"let cell of grid; let i = index\" [ngClass]=\"{\r\n 'grid-item': true,\r\n 'highlighted': i % 7 < cols && Math.floor(i / 7) < rows\r\n }\" (mouseenter)=\"updatePreview(i % 7 + 1, Math.floor(i / 7) + 1)\"\r\n (click)=\"updateSelection(i % 7 + 1, Math.floor(i / 7) + 1, dialogRef)\"></div>\r\n </div>\r\n <p>{{ rows }} x {{ cols }} </p>\r\n </mat-dialog-content>\r\n </ng-template>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.rich-text-editor{border:1px solid #ccc;border-radius:5px;font-family:Calibri}::ng-deep .editor{position:relative;min-height:300px;border:1px solid #ccc;padding:5px;overflow-y:auto;font-family:Calibri;outline:none!important;font-size:14px}::ng-deep .editor table{width:100%}::ng-deep .editor table,::ng-deep .editor th,::ng-deep .editor td{border:1px solid black;border-collapse:collapse}::ng-deep .editor th,::ng-deep .editor td{padding:.4rem}::ng-deep .editor th{background-color:#f3f3f3}.fs-12{font-size:12px!important}.fs-13{font-size:13px!important}.fs-14{font-size:14px!important}.fs-16{font-size:16px!important}.fs-18{font-size:18px!important}.fs-20{font-size:20px!important}.fs-24{font-size:24px!important}.fs-28{font-size:28px!important}.editor h1{font-size:32px!important;font-weight:700!important;margin:0}.editor h2{font-size:28px!important;font-weight:700!important;margin:0}.editor h3{font-size:24px!important;font-weight:700!important;margin:0}.editor h4{font-size:20px!important;font-weight:700!important;margin:0}.editor h5{font-size:18px!important;font-weight:600!important;margin:0}.editor h6{font-size:16px!important;font-weight:600!important;margin:0}.editor p{font-size:14px!important;font-weight:400;margin:0}button{width:20px;height:20px;background:none;border:none;margin-left:5px;cursor:pointer}button[mat-icon-button]{margin:0 4px;width:20px!important;height:20px;background:none;border:none}.small-icon-button{width:30px;height:30px;padding:4px}.small-icon-button mat-icon{font-size:16px}button[mat-icon-button]{position:relative;overflow:hidden}input[type=file]{padding:5px;cursor:pointer;margin-left:10px}.fileInput{display:flex;justify-content:center;align-items:center}.select-wrapper{display:inline-block;position:relative;width:70px}.select-wrapper select{appearance:none;width:100%;padding:10px 40px 10px 15px;font-size:16px;color:#333;background-color:#f4f4f4;border:1px solid #ddd;cursor:pointer;outline:none}.select-wrapper:after{content:\"\\25bc\";position:absolute;top:50%;right:15px;transform:translateY(-50%);pointer-events:none;color:#777;font-size:12px}.select-wrapper select:hover{background-color:#e9e9e9;border-color:#bbb}.select-wrapper select:focus{border-color:#007bff;background-color:#fff}.select-wrapper option{padding:8px;font-size:16px;color:#333;background-color:#fff}.toolbar{display:flex;flex-wrap:wrap;align-items:center;background-color:#f4f4f4;padding:10px;border-radius:8px;box-shadow:0 2px 8px #0000001a;gap:10px}.select-wrapper{padding:8px;font-size:14px;border:1px solid #ddd;cursor:pointer;background-color:#fff}.select-wrapper:focus{outline:none;border-color:#007bff}button{border:none;border-radius:5px;padding:8px;cursor:pointer;display:flex;align-items:center;justify-content:center}button:hover{color:#007bff}mat-icon{font-size:20px;color:inherit}input[type=number]{width:60px;padding:5px;font-size:14px;border:1px solid #ddd;border-radius:5px;text-align:center}input[type=file]{border:1px solid #ddd;border-radius:5px;padding:5px;font-size:14px;background-color:#fff;cursor:pointer}input[type=file]:hover{border-color:#007bff}.table{width:100px;height:30px;color:#007bff!important;font-weight:700;border:1px solid #007bff}.table:hover{background-color:#0056b3;color:#fff!important}.submit{margin-top:10px;width:100px;height:30px;color:#007bff!important;font-weight:700;border:1px solid #007bff}.submit:hover{border:none;background-color:#0056b3;color:#fff!important}.custom-dialog-container{width:auto;max-width:200px}.grid-container{display:grid;grid-template-columns:repeat(7,20px);grid-gap:5px;gap:5px}.grid-item{width:20px;height:20px;border:1px solid #ddd}.highlighted{background-color:#2196f3}div[contenteditable=false]{display:inline-block;position:relative;resize:both;overflow:hidden;border:1px dashed #ccc;margin:5px}div[contenteditable=false]:hover{border-color:#007bff}div[contenteditable=false] img{display:block;width:100%;height:auto}.uploaded-images{display:flex;flex-wrap:wrap;margin-bottom:20px}.image-preview{margin:10px;padding:5px;border:1px dashed #ccc;cursor:pointer}.image-preview img{max-width:100px;max-height:100px;object-fit:cover}.editor{border:1px solid #ccc;min-height:300px;padding:20px;position:relative}.remove_btn{position:relative;top:10px}\n"], components: [{ type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
620
776
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: RapidTextEditorComponent, decorators: [{
621
777
  type: Component,
622
778
  args: [{ selector: 'rapid-text-editor', providers: [
@@ -625,8 +781,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
625
781
  useExisting: forwardRef(() => RapidTextEditorComponent),
626
782
  multi: true
627
783
  }
628
- ], template: "<div class=\"dimension\">\r\n <div class=\"rich-text-editor\">\r\n <!-- Toolbar -->\r\n <div class=\"toolbar\">\r\n <select class=\"select-wrapper\" [(ngModel)]=\"selectedHead\" (change)=\"setHeading($event)\">\r\n <option value=\"P\" style=\"font-size: 14px;\">Paragraph</option>\r\n <option value=\"H1\" style=\"font-size: 32px; font-weight: bold;\">H1</option>\r\n <option value=\"H2\" style=\"font-size: 28px; font-weight: bold;\">H2</option>\r\n <option value=\"H3\" style=\"font-size: 24px; font-weight: bold;\">H3</option>\r\n <option value=\"H4\" style=\"font-size: 20px; font-weight: bold;\">H4</option>\r\n <option value=\"H5\" style=\"font-size: 18px; font-weight: 600;\">H5</option>\r\n <option value=\"H6\" style=\"font-size: 16px; font-weight: 600;\">H6</option>\r\n </select>\r\n <select class=\"select-wrapper\" (change)=\"onChange(null)\" [(ngModel)]=\"selectedFont\"\r\n (change)=\"setFontSize($event)\">\r\n <option style=\"font-size: 12px;\" value=\"12\">12px</option>\r\n <option style=\"font-size: 14px;\" value=\"14\" selected>14px</option>\r\n <option style=\"font-size: 16px;\" value=\"16\">16px</option>\r\n <option style=\"font-size: 18px;\" value=\"18\">18px</option>\r\n <option style=\"font-size: 24px;\" value=\"24\">24px</option>\r\n <option style=\"font-size: 32px;\" value=\"32\">32px</option>\r\n <option style=\"font-size: 48px;\" value=\"48\">48px</option>\r\n </select>\r\n <button (click)=\"format('bold')\" type=\"button\" aria-label=\"Bold\">\r\n <mat-icon>format_bold</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('italic')\" type=\"button\" aria-label=\"Italic\">\r\n <mat-icon>format_italic</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('underline')\" type=\"button\" aria-label=\"Underline\">\r\n <mat-icon>format_underline</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('strikethrough')\" type=\"button\" aria-label=\"Strikethrough\">\r\n <mat-icon>strikethrough_s</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyLeft')\" type=\"button\" aria-label=\"Align Left\">\r\n <mat-icon>format_align_left</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyCenter')\" type=\"button\" aria-label=\"Center\">\r\n <mat-icon>format_align_center</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyRight')\" type=\"button\" aria-label=\"Align Right\">\r\n <mat-icon>format_align_right</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyFull')\" type=\"button\" aria-label=\"Justify\">\r\n <mat-icon>format_align_justify</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('insertUnorderedList')\" type=\"button\" aria-label=\"Unordered List\">\r\n <mat-icon>format_list_bulleted</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('insertOrderedList')\" type=\"button\" aria-label=\"Ordered List\">\r\n <mat-icon>format_list_numbered</mat-icon>\r\n </button>\r\n <button color=\"secondary\" aria-label=\"Insert Image\" type=\"button\"\r\n style=\"position: relative; display: inline-flex; align-items: center; justify-content: center;\">\r\n <input type=\"file\" (change)=\"insertImageToEditor($event)\"\r\n style=\"position: absolute; left: -50%; top: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer;\"\r\n aria-hidden=\"true\" />\r\n <mat-icon style=\"pointer-events: none;\">insert_photo_outlined</mat-icon>\r\n </button>\r\n <button (click)=\"openTableDialog($event)\" type=\"button\" color=\"secondary\"\r\n aria-label=\"Choose table rows and columns\">\r\n <mat-icon>border_all</mat-icon>\r\n </button>\r\n\r\n <button class=\"mb-1\" (click)=\"makeFirstRowHeader()\" type=\"button\" color=\"secondary\" aria-label=\"Make Header\">\r\n <span style=\"font-size: 20px;\" class=\"material-symbols-outlined\">\r\n page_header\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"editor\" id=\"editor\" contenteditable=\"true\" #editor (input)=\"submitContent()\" (blur)=\"onBlur()\"\r\n (drop)=\"drop($event)\" (dragover)=\"allowDrop($event)\">\r\n </div>\r\n </div>\r\n <ng-template #tableDialog let-dialogRef=\"dialogRef\">\r\n <h2 mat-dialog-title>Choose Table Size</h2>\r\n <mat-dialog-content>\r\n <div class=\"grid-container\">\r\n <div *ngFor=\"let cell of grid; let i = index\" [ngClass]=\"{\r\n 'grid-item': true,\r\n 'highlighted': i % 7 < cols && Math.floor(i / 7) < rows\r\n }\" (mouseenter)=\"updatePreview(i % 7 + 1, Math.floor(i / 7) + 1)\"\r\n (click)=\"updateSelection(i % 7 + 1, Math.floor(i / 7) + 1, dialogRef)\"></div>\r\n </div>\r\n <p>{{ rows }} x {{ cols }} </p>\r\n </mat-dialog-content>\r\n </ng-template>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.rich-text-editor{border:1px solid #ccc;border-radius:5px;font-family:Calibri}::ng-deep .editor{position:relative;min-height:300px;border:1px solid #ccc;padding:5px;overflow-y:auto;font-family:Calibri!important;outline:none!important;font-size:14px}::ng-deep .editor table{width:100%;border-collapse:collapse;margin:5px}.fs-12{font-size:12px}.fs-13{font-size:13px}.fs-14{font-size:14px}.fs-16{font-size:16px}.fs-18{font-size:18px}.fs-20{font-size:20px}.fs-24{font-size:24px}.fs-28{font-size:28px}.editor h1{font-size:32px;font-weight:700;margin:0}.editor h2{font-size:28px;font-weight:700;margin:0}.editor h3{font-size:24px;font-weight:700;margin:0}.editor h4{font-size:20px;font-weight:700;margin:0}.editor h5{font-size:18px;font-weight:600;margin:0}.editor h6{font-size:16px;font-weight:600;margin:0}.editor p{font-size:14px;font-weight:400;margin:0}button{width:20px;height:20px;background:none;border:none;margin-left:5px;cursor:pointer}button[mat-icon-button]{margin:0 4px;width:20px!important;height:20px;background:none;border:none}.small-icon-button{width:30px;height:30px;padding:4px}.small-icon-button mat-icon{font-size:16px}button[mat-icon-button]{position:relative;overflow:hidden}input[type=file]{padding:5px;cursor:pointer;margin-left:10px}.fileInput{display:flex;justify-content:center;align-items:center}.select-wrapper{display:inline-block;position:relative;width:70px}.select-wrapper select{appearance:none;width:100%;padding:10px 40px 10px 15px;font-size:16px;color:#333;background-color:#f4f4f4;border:1px solid #ddd;cursor:pointer;outline:none}.select-wrapper:after{content:\"\\25bc\";position:absolute;top:50%;right:15px;transform:translateY(-50%);pointer-events:none;color:#777;font-size:12px}.select-wrapper select:hover{background-color:#e9e9e9;border-color:#bbb}.select-wrapper select:focus{border-color:#007bff;background-color:#fff}.select-wrapper option{padding:8px;font-size:16px;color:#333;background-color:#fff}.toolbar{display:flex;flex-wrap:wrap;align-items:center;background-color:#f4f4f4;padding:10px;border-radius:8px;box-shadow:0 2px 8px #0000001a;gap:10px}.select-wrapper{padding:8px;font-size:14px;border:1px solid #ddd;cursor:pointer;background-color:#fff}.select-wrapper:focus{outline:none;border-color:#007bff}button{border:none;border-radius:5px;padding:8px;cursor:pointer;display:flex;align-items:center;justify-content:center}button:hover{color:#007bff}mat-icon{font-size:20px;color:inherit}input[type=number]{width:60px;padding:5px;font-size:14px;border:1px solid #ddd;border-radius:5px;text-align:center}input[type=file]{border:1px solid #ddd;border-radius:5px;padding:5px;font-size:14px;background-color:#fff;cursor:pointer}input[type=file]:hover{border-color:#007bff}.table{width:100px;height:30px;color:#007bff!important;font-weight:700;border:1px solid #007bff}.table:hover{background-color:#0056b3;color:#fff!important}.submit{margin-top:10px;width:100px;height:30px;color:#007bff!important;font-weight:700;border:1px solid #007bff}.submit:hover{border:none;background-color:#0056b3;color:#fff!important}.custom-dialog-container{width:auto;max-width:200px}.grid-container{display:grid;grid-template-columns:repeat(7,20px);grid-gap:5px;gap:5px}.grid-item{width:20px;height:20px;border:1px solid #ddd}.highlighted{background-color:#2196f3}div[contenteditable=false]{display:inline-block;position:relative;resize:both;overflow:hidden;border:1px dashed #ccc;margin:5px}div[contenteditable=false]:hover{border-color:#007bff}div[contenteditable=false] img{display:block;width:100%;height:auto}.uploaded-images{display:flex;flex-wrap:wrap;margin-bottom:20px}.image-preview{margin:10px;padding:5px;border:1px dashed #ccc;cursor:pointer}.image-preview img{max-width:100px;max-height:100px;object-fit:cover}.editor{border:1px solid #ccc;min-height:300px;padding:20px;position:relative}.remove_btn{position:relative;top:10px}\n"] }]
629
- }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ElementRef }]; }, propDecorators: { contentCapture: [{
784
+ ], template: "<div class=\"dimension\">\r\n <div class=\"rich-text-editor\">\r\n <!-- Toolbar -->\r\n <div class=\"toolbar\">\r\n <select class=\"select-wrapper\" [(ngModel)]=\"selectedHead\" (change)=\"setHeading($event)\">\r\n <option value=\"P\" style=\"font-size: 14px !important;\">Paragraph</option>\r\n <option value=\"H1\" style=\"font-size: 32px !important; font-weight: bold !important;\">H1</option>\r\n <option value=\"H2\" style=\"font-size: 28px !important; font-weight: bold !important;\">H2</option>\r\n <option value=\"H3\" style=\"font-size: 24px !important; font-weight: bold !important;\">H3</option>\r\n <option value=\"H4\" style=\"font-size: 20px !important; font-weight: bold !important;\">H4</option>\r\n <option value=\"H5\" style=\"font-size: 18px !important; font-weight: 600 !important;\">H5</option>\r\n <option value=\"H6\" style=\"font-size: 16px !important; font-weight: 600 !important;\">H6</option>\r\n </select>\r\n <select class=\"select-wrapper\" [(ngModel)]=\"selectedFont\"\r\n (change)=\"setFontSize($event)\">\r\n <option style=\"font-size: 12px !important;\" value=\"12\">12px</option>\r\n <option style=\"font-size: 14px !important;\" value=\"14\" selected>14px</option>\r\n <option style=\"font-size: 16px !important;\" value=\"16\">16px</option>\r\n <option style=\"font-size: 18px !important;\" value=\"18\">18px</option>\r\n <option style=\"font-size: 20px !important;\" value=\"20\">20px</option> \r\n <option style=\"font-size: 24px !important;\" value=\"24\">24px</option>\r\n <option style=\"font-size: 28px !important;\" value=\"28\">28px</option>\r\n <option style=\"font-size: 32px !important;\" value=\"32\">32px</option>\r\n <option style=\"font-size: 48px !important;\" value=\"48\">48px</option>\r\n </select>\r\n <button (click)=\"format('bold')\" type=\"button\" aria-label=\"Bold\">\r\n <mat-icon>format_bold</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('italic')\" type=\"button\" aria-label=\"Italic\">\r\n <mat-icon>format_italic</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('underline')\" type=\"button\" aria-label=\"Underline\">\r\n <mat-icon>format_underline</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('strikethrough')\" type=\"button\" aria-label=\"Strikethrough\">\r\n <mat-icon>strikethrough_s</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyLeft')\" type=\"button\" aria-label=\"Align Left\">\r\n <mat-icon>format_align_left</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyCenter')\" type=\"button\" aria-label=\"Center\">\r\n <mat-icon>format_align_center</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyRight')\" type=\"button\" aria-label=\"Align Right\">\r\n <mat-icon>format_align_right</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('justifyFull')\" type=\"button\" aria-label=\"Justify\">\r\n <mat-icon>format_align_justify</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('insertUnorderedList')\" type=\"button\" aria-label=\"Unordered List\">\r\n <mat-icon>format_list_bulleted</mat-icon>\r\n </button>\r\n\r\n <button (click)=\"format('insertOrderedList')\" type=\"button\" aria-label=\"Ordered List\">\r\n <mat-icon>format_list_numbered</mat-icon>\r\n </button>\r\n <button color=\"secondary\" aria-label=\"Insert Image\" type=\"button\"\r\n style=\"position: relative; display: inline-flex; align-items: center; justify-content: center;\">\r\n <input type=\"file\" (change)=\"insertImageToEditor($event)\"\r\n style=\"position: absolute; left: -50%; top: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer;\"\r\n aria-hidden=\"true\" />\r\n <mat-icon style=\"pointer-events: none;\">insert_photo_outlined</mat-icon>\r\n </button>\r\n <button (click)=\"openTableDialog($event)\" type=\"button\" color=\"secondary\"\r\n aria-label=\"Choose table rows and columns\">\r\n <mat-icon>border_all</mat-icon>\r\n </button>\r\n\r\n <button class=\"mb-1\" (click)=\"makeFirstRowHeader()\" type=\"button\" color=\"secondary\" aria-label=\"Make Header\">\r\n <span style=\"font-size: 20px;\" class=\"material-symbols-outlined\">\r\n page_header\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"editor\" id=\"editor\" contenteditable=\"true\" #editor (input)=\"submitContent()\" (blur)=\"onBlur()\" (keyup)=\"onEditorKeyUp($event)\" (mouseup)=\"updateCurrentFormat()\"\r\n (drop)=\"drop($event)\" (dragover)=\"allowDrop($event)\">\r\n </div>\r\n </div>\r\n <ng-template #tableDialog let-dialogRef=\"dialogRef\">\r\n <h2 mat-dialog-title>Choose Table Size</h2>\r\n <mat-dialog-content>\r\n <div class=\"grid-container\">\r\n <div *ngFor=\"let cell of grid; let i = index\" [ngClass]=\"{\r\n 'grid-item': true,\r\n 'highlighted': i % 7 < cols && Math.floor(i / 7) < rows\r\n }\" (mouseenter)=\"updatePreview(i % 7 + 1, Math.floor(i / 7) + 1)\"\r\n (click)=\"updateSelection(i % 7 + 1, Math.floor(i / 7) + 1, dialogRef)\"></div>\r\n </div>\r\n <p>{{ rows }} x {{ cols }} </p>\r\n </mat-dialog-content>\r\n </ng-template>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.rich-text-editor{border:1px solid #ccc;border-radius:5px;font-family:Calibri}::ng-deep .editor{position:relative;min-height:300px;border:1px solid #ccc;padding:5px;overflow-y:auto;font-family:Calibri;outline:none!important;font-size:14px}::ng-deep .editor table{width:100%}::ng-deep .editor table,::ng-deep .editor th,::ng-deep .editor td{border:1px solid black;border-collapse:collapse}::ng-deep .editor th,::ng-deep .editor td{padding:.4rem}::ng-deep .editor th{background-color:#f3f3f3}.fs-12{font-size:12px!important}.fs-13{font-size:13px!important}.fs-14{font-size:14px!important}.fs-16{font-size:16px!important}.fs-18{font-size:18px!important}.fs-20{font-size:20px!important}.fs-24{font-size:24px!important}.fs-28{font-size:28px!important}.editor h1{font-size:32px!important;font-weight:700!important;margin:0}.editor h2{font-size:28px!important;font-weight:700!important;margin:0}.editor h3{font-size:24px!important;font-weight:700!important;margin:0}.editor h4{font-size:20px!important;font-weight:700!important;margin:0}.editor h5{font-size:18px!important;font-weight:600!important;margin:0}.editor h6{font-size:16px!important;font-weight:600!important;margin:0}.editor p{font-size:14px!important;font-weight:400;margin:0}button{width:20px;height:20px;background:none;border:none;margin-left:5px;cursor:pointer}button[mat-icon-button]{margin:0 4px;width:20px!important;height:20px;background:none;border:none}.small-icon-button{width:30px;height:30px;padding:4px}.small-icon-button mat-icon{font-size:16px}button[mat-icon-button]{position:relative;overflow:hidden}input[type=file]{padding:5px;cursor:pointer;margin-left:10px}.fileInput{display:flex;justify-content:center;align-items:center}.select-wrapper{display:inline-block;position:relative;width:70px}.select-wrapper select{appearance:none;width:100%;padding:10px 40px 10px 15px;font-size:16px;color:#333;background-color:#f4f4f4;border:1px solid #ddd;cursor:pointer;outline:none}.select-wrapper:after{content:\"\\25bc\";position:absolute;top:50%;right:15px;transform:translateY(-50%);pointer-events:none;color:#777;font-size:12px}.select-wrapper select:hover{background-color:#e9e9e9;border-color:#bbb}.select-wrapper select:focus{border-color:#007bff;background-color:#fff}.select-wrapper option{padding:8px;font-size:16px;color:#333;background-color:#fff}.toolbar{display:flex;flex-wrap:wrap;align-items:center;background-color:#f4f4f4;padding:10px;border-radius:8px;box-shadow:0 2px 8px #0000001a;gap:10px}.select-wrapper{padding:8px;font-size:14px;border:1px solid #ddd;cursor:pointer;background-color:#fff}.select-wrapper:focus{outline:none;border-color:#007bff}button{border:none;border-radius:5px;padding:8px;cursor:pointer;display:flex;align-items:center;justify-content:center}button:hover{color:#007bff}mat-icon{font-size:20px;color:inherit}input[type=number]{width:60px;padding:5px;font-size:14px;border:1px solid #ddd;border-radius:5px;text-align:center}input[type=file]{border:1px solid #ddd;border-radius:5px;padding:5px;font-size:14px;background-color:#fff;cursor:pointer}input[type=file]:hover{border-color:#007bff}.table{width:100px;height:30px;color:#007bff!important;font-weight:700;border:1px solid #007bff}.table:hover{background-color:#0056b3;color:#fff!important}.submit{margin-top:10px;width:100px;height:30px;color:#007bff!important;font-weight:700;border:1px solid #007bff}.submit:hover{border:none;background-color:#0056b3;color:#fff!important}.custom-dialog-container{width:auto;max-width:200px}.grid-container{display:grid;grid-template-columns:repeat(7,20px);grid-gap:5px;gap:5px}.grid-item{width:20px;height:20px;border:1px solid #ddd}.highlighted{background-color:#2196f3}div[contenteditable=false]{display:inline-block;position:relative;resize:both;overflow:hidden;border:1px dashed #ccc;margin:5px}div[contenteditable=false]:hover{border-color:#007bff}div[contenteditable=false] img{display:block;width:100%;height:auto}.uploaded-images{display:flex;flex-wrap:wrap;margin-bottom:20px}.image-preview{margin:10px;padding:5px;border:1px dashed #ccc;cursor:pointer}.image-preview img{max-width:100px;max-height:100px;object-fit:cover}.editor{border:1px solid #ccc;min-height:300px;padding:20px;position:relative}.remove_btn{position:relative;top:10px}\n"] }]
785
+ }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { contentCapture: [{
630
786
  type: Input
631
787
  }], height: [{
632
788
  type: Input