@libs-ui/components-inputs-quill 0.2.324-0 → 0.2.326-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.
- package/{indent-attributor → blots-custom}/indent-attributor.component.d.ts +1 -1
- package/blots-custom/index.d.ts +4 -0
- package/esm2022/blots-custom/indent-attributor.component.mjs +20 -0
- package/esm2022/blots-custom/index.mjs +5 -0
- package/esm2022/index.mjs +2 -1
- package/esm2022/quill.component.mjs +7 -76
- package/esm2022/quill2x.component.mjs +634 -0
- package/esm2022/utils/quill.define.mjs +107 -2
- package/esm2022/utils/quill2x.define.mjs +233 -0
- package/fesm2022/libs-ui-components-inputs-quill.mjs +1022 -143
- package/fesm2022/libs-ui-components-inputs-quill.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/package.json +17 -17
- package/quill2x.component.d.ts +126 -0
- package/utils/quill.define.d.ts +1 -0
- package/utils/quill2x.define.d.ts +5 -0
- package/esm2022/indent-attributor/indent-attributor.component.mjs +0 -20
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NgTemplateOutlet } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { signal, input, output, ChangeDetectionStrategy, Component, computed, inject, model, viewChild, ChangeDetectorRef, effect, untracked } from '@angular/core';
|
|
3
|
+
import { signal, input, output, ChangeDetectionStrategy, Component, computed, inject, model, viewChild, ChangeDetectorRef, effect, untracked, DestroyRef } from '@angular/core';
|
|
4
4
|
import { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
|
|
5
5
|
import { LibsUiComponentsButtonsSelectColorComponent } from '@libs-ui/components-buttons-select-color';
|
|
6
6
|
import { LibsUiComponentsDropdownComponent } from '@libs-ui/components-dropdown';
|
|
@@ -14,82 +14,15 @@ import { LibsUiComponentsSkeletonComponent } from '@libs-ui/components-skeleton'
|
|
|
14
14
|
import { LibsUiComponentsSpinnerComponent } from '@libs-ui/components-spinner';
|
|
15
15
|
import { LibsUiDynamicComponentService } from '@libs-ui/services-dynamic-component';
|
|
16
16
|
import { LibsUiNotificationService } from '@libs-ui/services-notification';
|
|
17
|
-
import { patternUrl, convertFileToBase64_ObjectUrl, get, set, isNil, xssFilter, ERROR_MESSAGE_EMPTY_VALID, ERROR_MESSAGE_MIN_LENGTH, ERROR_MESSAGE_MAX_LENGTH, getLabelBySizeFile } from '@libs-ui/utils';
|
|
17
|
+
import { patternUrl, convertFileToBase64_ObjectUrl, get, set, isNil, xssFilter, ERROR_MESSAGE_EMPTY_VALID, ERROR_MESSAGE_MIN_LENGTH, ERROR_MESSAGE_MAX_LENGTH, getLabelBySizeFile, setStylesElement, UtilsKeyCodeConstant, isTruthy } from '@libs-ui/utils';
|
|
18
18
|
import * as i1 from '@ngx-translate/core';
|
|
19
19
|
import { TranslateService, TranslateModule } from '@ngx-translate/core';
|
|
20
20
|
import Quill from 'quill';
|
|
21
21
|
import { Subject, lastValueFrom, timer, fromEvent, takeUntil } from 'rxjs';
|
|
22
22
|
import { LibsUiComponentsModalComponent } from '@libs-ui/components-modal';
|
|
23
23
|
import { returnListObject } from '@libs-ui/services-http-request';
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class QuillDivBlot extends Block {
|
|
27
|
-
static tagName = 'div';
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const ImageFormat = Quill.import('formats/image');
|
|
31
|
-
class CustomImageBlot extends ImageFormat {
|
|
32
|
-
static create(value) {
|
|
33
|
-
const node = super.create(value);
|
|
34
|
-
node.classList.add('libs-ui-quill-format-image');
|
|
35
|
-
return node;
|
|
36
|
-
}
|
|
37
|
-
formats() {
|
|
38
|
-
return {}; // Tránh Quill tự động thêm thẻ `<span>`
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const Embed = Quill.import('blots/embed');
|
|
43
|
-
class QuillMentionBlot extends Embed {
|
|
44
|
-
static blotName = 'mention';
|
|
45
|
-
static tagName = 'span';
|
|
46
|
-
static className = 'libs-ui-quill-mention';
|
|
47
|
-
static create(data) {
|
|
48
|
-
const node = super.create();
|
|
49
|
-
node.innerText += data.value;
|
|
50
|
-
node.setAttribute('id', data.id);
|
|
51
|
-
node.setAttribute('feId', data.feId);
|
|
52
|
-
node.setAttribute('value', data.value);
|
|
53
|
-
return node;
|
|
54
|
-
}
|
|
55
|
-
static value(domNode) {
|
|
56
|
-
return {
|
|
57
|
-
id: domNode.getAttribute('id'),
|
|
58
|
-
feId: domNode.getAttribute('feId'),
|
|
59
|
-
value: domNode.getAttribute('value'),
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
attach() {
|
|
63
|
-
super.attach();
|
|
64
|
-
if (!this.mounted) {
|
|
65
|
-
this.mounted = true;
|
|
66
|
-
this.clickHandler = this.getClickHandler;
|
|
67
|
-
this.domNode.addEventListener('click', this.clickHandler, false);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
getClickHandler(event) {
|
|
71
|
-
event.stopPropagation();
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const parchment = Quill.import('parchment');
|
|
76
|
-
const pixelLevels = [1, 2, 3, 4, 5, 6, 7, 8];
|
|
77
|
-
const tabMultiplier = 3;
|
|
78
|
-
class IndentAttributor extends parchment.Attributor.Style {
|
|
79
|
-
constructor(formatName, styleProperty, attributorOptions) {
|
|
80
|
-
super(formatName, styleProperty, attributorOptions);
|
|
81
|
-
}
|
|
82
|
-
add(node, value) {
|
|
83
|
-
return super.add(node, `${+value * tabMultiplier}em`);
|
|
84
|
-
}
|
|
85
|
-
value(node) {
|
|
86
|
-
return parseFloat(super.value(node)) / tabMultiplier || undefined; // Don't return NaN
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
const indentStyle = new IndentAttributor('indent', 'margin-left', {
|
|
90
|
-
scope: parchment.Scope.BLOCK,
|
|
91
|
-
whitelist: pixelLevels.map((value) => `${value * tabMultiplier}em`),
|
|
92
|
-
});
|
|
24
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
25
|
+
import Quill2x, { Delta } from 'quill2x';
|
|
93
26
|
|
|
94
27
|
class LibsUiComponentsInputsQuillLinkComponent {
|
|
95
28
|
dataLink = signal({ title: '', link: '' });
|
|
@@ -358,6 +291,21 @@ const toolBarOptions = (mode, hasIconImage, hasIconPersonalize) => {
|
|
|
358
291
|
mode: ['default', 'basic'],
|
|
359
292
|
width: 1,
|
|
360
293
|
},
|
|
294
|
+
{
|
|
295
|
+
type: 'script.sub',
|
|
296
|
+
mode: [],
|
|
297
|
+
width: 32,
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
type: 'script.super',
|
|
301
|
+
mode: [],
|
|
302
|
+
width: 32,
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
type: 'line',
|
|
306
|
+
mode: [],
|
|
307
|
+
width: 1,
|
|
308
|
+
},
|
|
361
309
|
{
|
|
362
310
|
type: 'adjust',
|
|
363
311
|
mode: ['default'],
|
|
@@ -388,6 +336,11 @@ const toolBarOptions = (mode, hasIconImage, hasIconPersonalize) => {
|
|
|
388
336
|
mode: ['default'],
|
|
389
337
|
width: 32,
|
|
390
338
|
},
|
|
339
|
+
{
|
|
340
|
+
type: 'listChecked',
|
|
341
|
+
mode: [],
|
|
342
|
+
width: 32,
|
|
343
|
+
},
|
|
391
344
|
{
|
|
392
345
|
type: 'line',
|
|
393
346
|
mode: ['default'],
|
|
@@ -418,12 +371,18 @@ const toolBarOptions = (mode, hasIconImage, hasIconPersonalize) => {
|
|
|
418
371
|
mode: ['default'],
|
|
419
372
|
width: 32,
|
|
420
373
|
},
|
|
374
|
+
{
|
|
375
|
+
type: 'video',
|
|
376
|
+
mode: [],
|
|
377
|
+
width: 32,
|
|
378
|
+
},
|
|
421
379
|
{
|
|
422
380
|
type: 'emoji',
|
|
423
381
|
classInclude: 'ml-[8px]',
|
|
424
382
|
mode: ['default'],
|
|
425
383
|
width: 24,
|
|
426
384
|
},
|
|
385
|
+
{ type: 'table', width: 32, mode: [] },
|
|
427
386
|
].filter((item) => {
|
|
428
387
|
if (!item.mode?.includes(mode)) {
|
|
429
388
|
return false;
|
|
@@ -465,7 +424,7 @@ const iconList = () => {
|
|
|
465
424
|
},
|
|
466
425
|
{
|
|
467
426
|
key: 'redo',
|
|
468
|
-
icon: 'libs-ui-icon-
|
|
427
|
+
icon: 'libs-ui-icon-redo',
|
|
469
428
|
},
|
|
470
429
|
{
|
|
471
430
|
key: 'strike',
|
|
@@ -523,6 +482,18 @@ const iconList = () => {
|
|
|
523
482
|
key: 'emoji',
|
|
524
483
|
icon: 'libs-ui-icon-face-smile',
|
|
525
484
|
},
|
|
485
|
+
{
|
|
486
|
+
key: 'table',
|
|
487
|
+
icon: 'libs-ui-icon-table',
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
key: 'check',
|
|
491
|
+
icon: 'libs-ui-icon-task-list',
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
key: 'video',
|
|
495
|
+
icon: 'libs-ui-icon-video-outline',
|
|
496
|
+
},
|
|
526
497
|
];
|
|
527
498
|
};
|
|
528
499
|
const uploadImageConfigDefault = () => {
|
|
@@ -551,6 +522,142 @@ const linkDefault = () => {
|
|
|
551
522
|
},
|
|
552
523
|
};
|
|
553
524
|
};
|
|
525
|
+
const fontSizeWhiteList = () => [
|
|
526
|
+
'8px',
|
|
527
|
+
'9px',
|
|
528
|
+
'10px',
|
|
529
|
+
'11px',
|
|
530
|
+
'12px',
|
|
531
|
+
'13px',
|
|
532
|
+
'14px',
|
|
533
|
+
'15px',
|
|
534
|
+
'16px',
|
|
535
|
+
'17px',
|
|
536
|
+
'18px',
|
|
537
|
+
'19px',
|
|
538
|
+
'20px',
|
|
539
|
+
'21px',
|
|
540
|
+
'22px',
|
|
541
|
+
'23px',
|
|
542
|
+
'24px',
|
|
543
|
+
'25px',
|
|
544
|
+
'26px',
|
|
545
|
+
'27px',
|
|
546
|
+
'28px',
|
|
547
|
+
'29px',
|
|
548
|
+
'30px',
|
|
549
|
+
'31px',
|
|
550
|
+
'32px',
|
|
551
|
+
'33px',
|
|
552
|
+
'34px',
|
|
553
|
+
'35px',
|
|
554
|
+
'36px',
|
|
555
|
+
'37px',
|
|
556
|
+
'38px',
|
|
557
|
+
'39px',
|
|
558
|
+
'40px',
|
|
559
|
+
'41px',
|
|
560
|
+
'42px',
|
|
561
|
+
'43px',
|
|
562
|
+
'44px',
|
|
563
|
+
'45px',
|
|
564
|
+
'46px',
|
|
565
|
+
'47px',
|
|
566
|
+
'48px',
|
|
567
|
+
'49px',
|
|
568
|
+
'50px',
|
|
569
|
+
'51px',
|
|
570
|
+
'52px',
|
|
571
|
+
'53px',
|
|
572
|
+
'54px',
|
|
573
|
+
'55px',
|
|
574
|
+
'56px',
|
|
575
|
+
'57px',
|
|
576
|
+
'58px',
|
|
577
|
+
'59px',
|
|
578
|
+
'60px',
|
|
579
|
+
'61px',
|
|
580
|
+
'62px',
|
|
581
|
+
'63px',
|
|
582
|
+
'64px',
|
|
583
|
+
'65px',
|
|
584
|
+
'66px',
|
|
585
|
+
'67px',
|
|
586
|
+
'68px',
|
|
587
|
+
'69px',
|
|
588
|
+
'70px',
|
|
589
|
+
'71px',
|
|
590
|
+
'72px',
|
|
591
|
+
];
|
|
592
|
+
|
|
593
|
+
const Block = Quill.import('blots/block');
|
|
594
|
+
class QuillDivBlot extends Block {
|
|
595
|
+
static tagName = 'div';
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
const Embed = Quill.import('blots/embed');
|
|
599
|
+
class QuillMentionBlot extends Embed {
|
|
600
|
+
static blotName = 'mention';
|
|
601
|
+
static tagName = 'span';
|
|
602
|
+
static className = 'libs-ui-quill-mention';
|
|
603
|
+
static create(data) {
|
|
604
|
+
const node = super.create();
|
|
605
|
+
node.innerText += data.value;
|
|
606
|
+
node.setAttribute('id', data.id);
|
|
607
|
+
node.setAttribute('feId', data.feId);
|
|
608
|
+
node.setAttribute('value', data.value);
|
|
609
|
+
return node;
|
|
610
|
+
}
|
|
611
|
+
static value(domNode) {
|
|
612
|
+
return {
|
|
613
|
+
id: domNode.getAttribute('id'),
|
|
614
|
+
feId: domNode.getAttribute('feId'),
|
|
615
|
+
value: domNode.getAttribute('value'),
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
attach() {
|
|
619
|
+
super.attach();
|
|
620
|
+
if (!this.mounted) {
|
|
621
|
+
this.mounted = true;
|
|
622
|
+
this.clickHandler = this.getClickHandler;
|
|
623
|
+
this.domNode.addEventListener('click', this.clickHandler, false);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
getClickHandler(event) {
|
|
627
|
+
event.stopPropagation();
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
const ImageFormat = Quill.import('formats/image');
|
|
632
|
+
class CustomImageBlot extends ImageFormat {
|
|
633
|
+
static create(value) {
|
|
634
|
+
const node = super.create(value);
|
|
635
|
+
node.classList.add('libs-ui-quill-format-image');
|
|
636
|
+
return node;
|
|
637
|
+
}
|
|
638
|
+
formats() {
|
|
639
|
+
return {}; // Tránh Quill tự động thêm thẻ `<span>`
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
const parchment = Quill.import('parchment');
|
|
644
|
+
const pixelLevels = [1, 2, 3, 4, 5, 6, 7, 8];
|
|
645
|
+
const tabMultiplier = 3;
|
|
646
|
+
class IndentAttributor extends parchment.Attributor.Style {
|
|
647
|
+
constructor(formatName, styleProperty, attributorOptions) {
|
|
648
|
+
super(formatName, styleProperty, attributorOptions);
|
|
649
|
+
}
|
|
650
|
+
add(node, value) {
|
|
651
|
+
return super.add(node, `${+value * tabMultiplier}em`);
|
|
652
|
+
}
|
|
653
|
+
value(node) {
|
|
654
|
+
return parseFloat(super.value(node)) / tabMultiplier || undefined; // Don't return NaN
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
const CustomIndentStyleBlot = new IndentAttributor('indent', 'margin-left', {
|
|
658
|
+
scope: parchment.Scope.BLOCK,
|
|
659
|
+
whitelist: pixelLevels.map((value) => `${value * tabMultiplier}em`),
|
|
660
|
+
});
|
|
554
661
|
|
|
555
662
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
556
663
|
class LibsUiComponentsInputsQuillComponent {
|
|
@@ -709,73 +816,7 @@ class LibsUiComponentsInputsQuillComponent {
|
|
|
709
816
|
const icons = Quill.import('ui/icons');
|
|
710
817
|
const italic = Quill.import('formats/italic');
|
|
711
818
|
const bold = Quill.import('formats/bold');
|
|
712
|
-
size.whitelist =
|
|
713
|
-
'8px',
|
|
714
|
-
'9px',
|
|
715
|
-
'10px',
|
|
716
|
-
'11px',
|
|
717
|
-
'12px',
|
|
718
|
-
'13px',
|
|
719
|
-
'14px',
|
|
720
|
-
'15px',
|
|
721
|
-
'16px',
|
|
722
|
-
'17px',
|
|
723
|
-
'18px',
|
|
724
|
-
'19px',
|
|
725
|
-
'20px',
|
|
726
|
-
'21px',
|
|
727
|
-
'22px',
|
|
728
|
-
'23px',
|
|
729
|
-
'24px',
|
|
730
|
-
'25px',
|
|
731
|
-
'26px',
|
|
732
|
-
'27px',
|
|
733
|
-
'28px',
|
|
734
|
-
'29px',
|
|
735
|
-
'30px',
|
|
736
|
-
'31px',
|
|
737
|
-
'32px',
|
|
738
|
-
'33px',
|
|
739
|
-
'34px',
|
|
740
|
-
'35px',
|
|
741
|
-
'36px',
|
|
742
|
-
'37px',
|
|
743
|
-
'38px',
|
|
744
|
-
'39px',
|
|
745
|
-
'40px',
|
|
746
|
-
'41px',
|
|
747
|
-
'42px',
|
|
748
|
-
'43px',
|
|
749
|
-
'44px',
|
|
750
|
-
'45px',
|
|
751
|
-
'46px',
|
|
752
|
-
'47px',
|
|
753
|
-
'48px',
|
|
754
|
-
'49px',
|
|
755
|
-
'50px',
|
|
756
|
-
'51px',
|
|
757
|
-
'52px',
|
|
758
|
-
'53px',
|
|
759
|
-
'54px',
|
|
760
|
-
'55px',
|
|
761
|
-
'56px',
|
|
762
|
-
'57px',
|
|
763
|
-
'58px',
|
|
764
|
-
'59px',
|
|
765
|
-
'60px',
|
|
766
|
-
'61px',
|
|
767
|
-
'62px',
|
|
768
|
-
'63px',
|
|
769
|
-
'64px',
|
|
770
|
-
'65px',
|
|
771
|
-
'66px',
|
|
772
|
-
'67px',
|
|
773
|
-
'68px',
|
|
774
|
-
'69px',
|
|
775
|
-
'70px',
|
|
776
|
-
'71px',
|
|
777
|
-
'72px',
|
|
778
|
-
];
|
|
819
|
+
size.whitelist = fontSizeWhiteList();
|
|
779
820
|
italic.tagName = 'i';
|
|
780
821
|
bold.tagName = 'b';
|
|
781
822
|
Quill.register(bold, true);
|
|
@@ -788,7 +829,7 @@ class LibsUiComponentsInputsQuillComponent {
|
|
|
788
829
|
this.blotsRegister()?.forEach((item) => {
|
|
789
830
|
Quill.register(item.component, true);
|
|
790
831
|
});
|
|
791
|
-
Quill.register({ 'formats/indent':
|
|
832
|
+
Quill.register({ 'formats/indent': CustomIndentStyleBlot }, true);
|
|
792
833
|
fromEvent(this.quillEditorEl()?.nativeElement, 'contextmenu')
|
|
793
834
|
.pipe(takeUntil(this.onDestroy))
|
|
794
835
|
.subscribe((e) => this.outContextMenu.emit(e));
|
|
@@ -1381,7 +1422,7 @@ class LibsUiComponentsInputsQuillComponent {
|
|
|
1381
1422
|
clearTimeout(this.timeoutScrollToSelectionWithElementScrollHeightAuto());
|
|
1382
1423
|
}
|
|
1383
1424
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsInputsQuillComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1384
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LibsUiComponentsInputsQuillComponent, isStandalone: true, selector: "libs_ui-components-inputs-quill", inputs: { isShowToolBar: { classPropertyName: "isShowToolBar", publicName: "isShowToolBar", isSignal: true, isRequired: false, transformFunction: null }, isToolbarPositionFixed: { classPropertyName: "isToolbarPositionFixed", publicName: "isToolbarPositionFixed", isSignal: true, isRequired: false, transformFunction: null }, classIncludeToolbar: { classPropertyName: "classIncludeToolbar", publicName: "classIncludeToolbar", isSignal: true, isRequired: false, transformFunction: null }, stylesIncludeToolbar: { classPropertyName: "stylesIncludeToolbar", publicName: "stylesIncludeToolbar", isSignal: true, isRequired: false, transformFunction: null }, toolbarConfig: { classPropertyName: "toolbarConfig", publicName: "toolbarConfig", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null }, autoUpdateValueWhenTextChange: { classPropertyName: "autoUpdateValueWhenTextChange", publicName: "autoUpdateValueWhenTextChange", isSignal: true, isRequired: false, transformFunction: null }, fieldNameBind: { classPropertyName: "fieldNameBind", publicName: "fieldNameBind", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, showErrorLabel: { classPropertyName: "showErrorLabel", publicName: "showErrorLabel", isSignal: true, isRequired: false, transformFunction: null }, showErrorBorder: { classPropertyName: "showErrorBorder", publicName: "showErrorBorder", isSignal: true, isRequired: false, transformFunction: null }, onlyShowErrorBorderInContent: { classPropertyName: "onlyShowErrorBorderInContent", publicName: "onlyShowErrorBorderInContent", isSignal: true, isRequired: false, transformFunction: null }, classIncludeTemplate: { classPropertyName: "classIncludeTemplate", publicName: "classIncludeTemplate", isSignal: true, isRequired: false, transformFunction: null }, classInclude: { classPropertyName: "classInclude", publicName: "classInclude", isSignal: true, isRequired: false, transformFunction: null }, handlersExpand: { classPropertyName: "handlersExpand", publicName: "handlersExpand", isSignal: true, isRequired: false, transformFunction: null }, validRequired: { classPropertyName: "validRequired", publicName: "validRequired", isSignal: true, isRequired: false, transformFunction: null }, validMinLength: { classPropertyName: "validMinLength", publicName: "validMinLength", isSignal: true, isRequired: false, transformFunction: null }, validMaxLength: { classPropertyName: "validMaxLength", publicName: "validMaxLength", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, dataConfigMention: { classPropertyName: "dataConfigMention", publicName: "dataConfigMention", isSignal: true, isRequired: false, transformFunction: null }, blotsRegister: { classPropertyName: "blotsRegister", publicName: "blotsRegister", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, focusBottom: { classPropertyName: "focusBottom", publicName: "focusBottom", isSignal: true, isRequired: false, transformFunction: null }, blockUndoRedoKeyboard: { classPropertyName: "blockUndoRedoKeyboard", publicName: "blockUndoRedoKeyboard", isSignal: true, isRequired: false, transformFunction: null }, templateToolBarPersonalize: { classPropertyName: "templateToolBarPersonalize", publicName: "templateToolBarPersonalize", isSignal: true, isRequired: false, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null }, uploadImageConfig: { classPropertyName: "uploadImageConfig", publicName: "uploadImageConfig", isSignal: true, isRequired: false, transformFunction: null }, heightAuto: { classPropertyName: "heightAuto", publicName: "heightAuto", isSignal: true, isRequired: false, transformFunction: null }, elementScrollHeightAuto: { classPropertyName: "elementScrollHeightAuto", publicName: "elementScrollHeightAuto", isSignal: true, isRequired: false, transformFunction: null }, ignoreShowPopupEditLink: { classPropertyName: "ignoreShowPopupEditLink", publicName: "ignoreShowPopupEditLink", isSignal: true, isRequired: false, transformFunction: null }, ignoreCommunicateMicroEventPopup: { classPropertyName: "ignoreCommunicateMicroEventPopup", publicName: "ignoreCommunicateMicroEventPopup", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { item: "itemChange", outShowPopupEditLink: "outShowPopupEditLink", outMessageError: "outMessageError", outBlur: "outBlur", outFocus: "outFocus", outChange: "outChange", outFunctionsControl: "outFunctionsControl", outSelectionChange: "outSelectionChange", outTextChange: "outTextChange", outContextMenu: "outContextMenu" }, viewQueries: [{ propertyName: "wrapperEditorEl", first: true, predicate: ["wrapperEditor"], descendants: true, isSignal: true }, { propertyName: "editorEl", first: true, predicate: ["editor"], descendants: true, isSignal: true }, { propertyName: "quillOptionEl", first: true, predicate: ["quillOption"], descendants: true, isSignal: true }, { propertyName: "quillEditorEl", first: true, predicate: ["quillEditor"], descendants: true, isSignal: true }, { propertyName: "toolbarItemsEl", first: true, predicate: ["toolbarItems"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex flex-col w-full h-full\">\n @if (label(); as label) {\n <libs_ui-components-label\n [classInclude]=\"label.classInclude\"\n [required]=\"label.required\"\n [labelLeft]=\"label.labelLeft\" />\n }\n <div\n #wrapperEditor\n [attr.heightAuto]=\"heightAuto()\"\n [attr.isToolbarPositionFixed]=\"isToolbarPositionFixed()\"\n class=\"libs-ui-quill-wrapper w-full h-full relative flex flex-col\"\n [class.libs-ui-border-error-general]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\"\n [class.rounded-[4px]]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\">\n <div\n #editor\n class=\"libs-ui-quill\"\n [attr.showError]=\"messageError() && showErrorBorder() && onlyShowErrorBorderInContent()\"\n [class.!hidden]=\"!display()\">\n <div\n #quillOption\n [class.!top-[-9999px]]=\"!isShowToolBar()\"\n [class.!left-[-9999px]]=\"!isShowToolBar()\"\n [style]=\"stylesIncludeToolbar()\"\n [class.pointer-events-none]=\"readonly() || loadingUploadImage()\"\n class=\"{{ isToolbarPositionFixed() ? 'fixed !z-10 w-[510px] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] rounded-[4px] bg-[#ffffff] libs-ui-quill-toolbar-animation' : '' }} {{ classIncludeToolbar() }} h-[44px] shrink-0\"\n [class.bg-[#f8f9fa]]=\"!readonly() && !loadingUploadImage()\"\n [class.libs-ui-readonly-background]=\"readonly() || loadingUploadImage()\">\n <ng-container *ngTemplateOutlet=\"toolbar\"></ng-container>\n </div>\n <div\n #quillEditor\n LibsUiComponentsInputsMentionDirective\n [timeDelayInit]=\"timeDelayInit() + 50\"\n [mentionConfig]=\"dataConfigMention()\"\n [class.libs-ui-readonly-background]=\"readonly() || loadingUploadImage()\"\n [class.pointer-events-none]=\"loadingUploadImage()\"\n (outToggle)=\"handleToggleMention($event)\"\n (outInsertMention)=\"handlerInsertMention($event)\"></div>\n <ng-container\n #qlEditorScroll\n LibsUiComponentsScrollOverlayDirective\n [ignoreInit]=\"!qlEditorElement()\"\n [elementScroll]=\"qlEditorElement()\" />\n </div>\n @if (template(); as template) {\n <div [class]=\"classIncludeTemplate()\">\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>\n }\n @if (loadingUploadImage()) {\n <libs_ui-components-spinner [size]=\"'medium'\" />\n }\n </div>\n @if (messageError() && showErrorLabel()) {\n <div class=\"flex items-center leading-normal mt-[8px]\">\n <span class=\"text-[#ff5454] libs-ui-font-h7r\">{{ messageError() | translate }}</span>\n </div>\n }\n</div>\n\n<ng-template #toolbar>\n <div\n class=\"toolbar h-full w-full shrink-0\"\n #toolbarItems>\n @if (displaySkeleton()) {\n <libs_ui-components-skeleton\n class=\"w-full h-full\"\n [config]=\"{\n rows: [\n {\n item: { classIncludeItem: '!rounded-none' },\n },\n ],\n }\" />\n }\n <div class=\"ql-formats items-center px-[16px] py-[4px]\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"!option.display\"\n [class.flex]=\"option.display\">\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { option, $index, $last }\"></ng-container>\n </div>\n }\n <div class=\"relative\">\n @if (displayShowMoreToolbar()) {\n <libs_ui-components-buttons-button\n [type]=\"showMoreAction() ? 'button-secondary' : 'button-third'\"\n [iconOnlyType]=\"true\"\n [classInclude]=\"'!p-[1px] !h-[20px] ml-[8px]'\"\n [classIconLeft]=\"'libs-ui-icon-move-right rotate-90'\"\n (outClick)=\"handlerChangeShowMoreAction($event)\" />\n }\n <!-- Build toolbar khi click xem th\u00EAm-->\n <div\n [class.hidden]=\"!showMoreAction()\"\n class=\"absolute bg-[#ffffff] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] z-[1] flex items-center pl-[8px] pr-[16px] py-[4px] rounded-[8px] top-[31px] right-[0px]\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"option.display !== false\"\n [class.flex]=\"option.display === false\">\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { option, $index, $last }\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template\n #itemTemplate\n let-$index=\"$index\"\n let-$last=\"$last\"\n let-option=\"option\">\n @if (option.type === 'undo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_undo', zIndex: zIndex() }\"\n class=\"ql-undo\"></button>\n </div>\n }\n @if (option.type === 'redo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_redo', zIndex: zIndex() }\"\n class=\"ql-redo\"></button>\n </div>\n }\n @if (option.type === 'fontFamily') {\n <div\n class=\"relative w-[132px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigFont()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectFont($event)\">\n @if (fontSelected(); as fontSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px]\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelFontSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'header') {\n <div\n class=\"relative w-[138px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigHeader()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectHeader($event)\">\n @if (headerSelected(); as headerSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px] {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelHeaderSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'fontSize') {\n <div class=\"ql-picker {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-inputs-valid\n [dataType]=\"'int'\"\n [(item)]=\"size\"\n [fieldNameBind]=\"'value'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"72\"\n [minValueNumber]=\"8\"\n [readonly]=\"readonly() || loadingUploadImage()\"\n [classContainerInput]=\"'w-[72px] h-[32px]'\"\n (outValueChange)=\"handlerValueChange($event)\" />\n </div>\n }\n @if (option.type === 'color') {\n <div class=\"ql-color ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_text_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n [applyNow]=\"false\"\n (outColorChange)=\"setStyle('color', $event)\">\n <div class=\"libs-ui-icon-editor-color-text libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'background') {\n <div class=\"ql-background ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_background_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [applyNow]=\"false\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n (outColorChange)=\"setStyle('background', $event)\">\n <div class=\"libs-ui-icon-editor-color-background libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'bold') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_weight_bold', zIndex: zIndex() }\"\n class=\"ql-bold\"></button>\n </div>\n }\n @if (option.type === 'italic') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_style_italic', zIndex: zIndex() }\"\n class=\"ql-italic\"></button>\n </div>\n }\n @if (option.type === 'underline') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_decoration_underline', zIndex: zIndex() }\"\n class=\"ql-underline\"></button>\n </div>\n }\n @if (option.type === 'strikeThrough') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_line_through', zIndex: zIndex() }\"\n class=\"ql-strike\"></button>\n </div>\n }\n @if (option.type === 'adjust') {\n <div class=\"relative !flex items-center ql-align ql-picker ql-icon-picker !w-max {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_adjust', zIndex: zIndex() }\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [ignoreStopPropagationEvent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigAlign()\"\n [listHiddenInputSearch]=\"true\"\n [popoverCustomConfig]=\"{ ignoreArrow: true, classInclude: '!w-[32px] overflow-hidden !py-[4px]', position: { mode: 'start', distance: 0 }, paddingLeftItem: false }\"\n [listHasButtonUnSelectOption]=\"false\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectAlign($event)\">\n @if (alignSelected(); as alignSelected) {\n <div class=\"flex items-center cursor-pointer\">\n <i [class]=\"iconAlignSelectedComputed()\"></i>\n <i class=\"libs-ui-icon-move-right rotate-90 text-[#6a7383] text-[16px] ml-[4px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'indentIncrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_increase', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"+1\"></button>\n </div>\n }\n @if (option.type === 'indentDecrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_decrease', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"-1\"></button>\n </div>\n }\n @if (option.type === 'listBulleted') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_bulleted', zIndex: zIndex() }\"\n class=\"ql-list ql-bullet\"\n value=\"bullet\"></button>\n </div>\n }\n @if (option.type === 'listNumbered') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_numbered', zIndex: zIndex() }\"\n class=\"ql-list ql-ordered\"\n value=\"ordered\"></button>\n </div>\n }\n @if (option.type === 'personalize' && templateToolBarPersonalize(); as templateToolBarPersonalize) {\n <div class=\"flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <ng-container *ngTemplateOutlet=\"templateToolBarPersonalize\"></ng-container>\n </div>\n }\n @if (option.type === 'blockquote') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_quote', zIndex: zIndex() }\"\n class=\"ql-blockquote\"></button>\n </div>\n }\n @if (option.type === 'link') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_insert_link', zIndex: zIndex() }\"\n class=\"ql-link\"></button>\n </div>\n }\n @if (option.type === 'unLink') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_unlink', zIndex: zIndex() }\"\n class=\"ql-unLink\"></button>\n </div>\n }\n @if (option.type === 'image') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_image', zIndex: zIndex() }\"\n class=\"ql-image\"></button>\n </div>\n }\n @if (option.type === 'emoji') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <libs_ui-components-emoji\n [zIndex]=\"zIndex()\"\n [isNgContent]=\"true\"\n (outEventEmoji)=\"handlerAddEmoji($event)\">\n <button class=\"ql-emoji\"></button>\n </libs_ui-components-emoji>\n </div>\n }\n @if (option.type === 'line') {\n <div class=\"w-[1px] h-[16px] libs-ui-border-right-general\"></div>\n }\n</ng-template>\n\n<libs_ui-components-popover\n [mode]=\"'click'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [config]=\"{ template: viewLink, whiteTheme: true, ignoreArrow: true, zIndex: zIndex() }\"\n (outEvent)=\"handlerPopoverEvent($event)\"\n (outFunctionsControl)=\"handlerPopoverFunctionControl($event)\" />\n\n<ng-template #viewLink>\n <div class=\"flex justify-between items-center px-[16px] py-[8px] rounded-[8px]\">\n <div\n class=\"w-full min-w-0 libs-ui-font-h5r\"\n [type]=\"'text'\"\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: link().url, zIndex: zIndex() + 1 }\">\n {{ link().url }}\n </div>\n <div class=\"flex items-center ml-[16px]\">\n <libs_ui-components-buttons-button\n [type]=\"'button-link-primary'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-edit-line'\"\n [classInclude]=\"'!p-0'\"\n (outClick)=\"handlerEdit($event)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-link-custom'\"\n [buttonCustom]=\"{\n configStepColor: {\n text: '#071631',\n text_hover: '#ee2d41',\n text_active: '#ee2d41',\n text_disable: '071631',\n },\n rootColor: '#071631',\n }\"\n [classInclude]=\"'!p-0 ml-[12px]'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-link-broken'\"\n (outClick)=\"handlerUnlink($event)\" />\n </div>\n </div>\n</ng-template>\n", styles: ["@-webkit-keyframes animation-move{0%{transform:translateY(-12px)}to{transform:translateY(0)}}@keyframes animation-move{0%{transform:translateY(-12px)}to{transform:translateY(0)}}.libs-ui-quill{height:100%;width:100%;display:flex;flex-direction:column}.libs-ui-quill-toolbar-animation{animation:animation-move .4s ease}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill{height:auto}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill ::ng-deep .ql-container{height:auto}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill ::ng-deep .ql-container .ql-editor{position:relative!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=true] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:0px!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:solid 1px #e6e8ed!important;border-radius:0 0 4px 4px}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill ::ng-deep .ql-toolbar.ql-snow{border:solid 1px #e6e8ed!important;border-radius:4px 4px 0 0;border-bottom:unset!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill[showError=true] ::ng-deep .ql-container.ql-snow{border:solid 1px #ee2d41!important}:host ::ng-deep .toolbar,:host ::ng-deep .ql-formats{position:relative;width:100%}:host ::ng-deep .ql-toolbar.ql-snow .ql-formats{display:flex}:host ::ng-deep .ql-container.ql-snow{width:100%;height:100%;position:relative}:host ::ng-deep .ql-editor{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:400}:host ::ng-deep .ql-editor b{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:600}:host ::ng-deep .ql-toolbar.ql-snow{border:none;border-radius:8px;padding:0}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label{color:#071631;border:none!important;margin-top:5px}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label:hover{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label:hover .ql-stroke{stroke:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-item:hover{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label.ql-active{color:#071631}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke{stroke:#071631}:host ::ng-deep .ql-editor{height:100%;width:100%;position:absolute;line-height:1.42!important}:host ::ng-deep .ql-editor:before{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;color:#9ca2ad!important;font-size:12px}:host ::ng-deep .ql-editor img{height:auto;max-width:100%}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label{border:none!important}:host ::ng-deep .ql-snow .ql-picker.ql-bold{width:36px!important}:host ::ng-deep .ql-editor.ql-blank{font-size:11px!important;letter-spacing:.05px;font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;line-height:16px}:host ::ng-deep .ql-editor.ql-blank:before{font-style:normal!important;color:#9ca2ad!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label :hover{color:red!important}:host ::ng-deep .ql-formats{margin-right:12px!important}:host ::ng-deep .ql-formats .ql-size.ql-picker,:host ::ng-deep .ql-formats .ql-header.ql-picker,:host ::ng-deep .ql-formats .ql-font.ql-picker{border:solid 1px #e6e8ed!important;border-radius:4px}:host ::ng-deep .ql-formats .ql-align.ql-picker .ql-picker-label{width:24px}:host ::ng-deep .ql-formats .ql-align.ql-picker .ql-picker-label:hover{color:red!important}:host ::ng-deep .ql-formats .ql-header.ql-picker .ql-picker-label:before{font-size:12px}:host ::ng-deep .ql-picker-item:before{font-size:12px}:host ::ng-deep .ql-picker-label:before{font-size:12px}:host ::ng-deep .ql-snow.ql-toolbar button,:host ::ng-deep .ql-snow .ql-toolbar button{background:none;border:none;cursor:pointer;display:flex;align-items:center;float:none;padding:0;width:inherit}:host ::ng-deep ul{padding-left:1rem!important}:host ::ng-deep li{padding-left:0!important}:host ::ng-deep .ql-tooltip{display:none!important}.ql-picker-options{max-height:130px;overflow-y:auto}.ql-snow .ql-picker.ql-size{border:1px solid #e6e7ea;box-shadow:#00000005 0 1px 3px,#1b1f2326 0 0 0 1px;border-radius:2px}.ql-snow .ql-picker.ql-font{border:1px solid #e6e7ea!important;margin-right:8px;border-radius:4px}.ql-snow .ql-picker.ql-font .ql-picker-options:before{font-size:12px}.ql-snow .ql-picker.ql-font .ql-picker-label:before{font-size:12px}.ql-font-Arial{font-family:Arial}.ql-font-sans-serif{font-family:\"sans-serif\"}.ql-font-Helvetica{font-family:Helvetica}.libs-ui-quill-mention{font-weight:500!important;color:#7239ea;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:600}.ql-snow .ql-picker.ql-expanded .ql-picker-options{overflow:hidden}.ql-formats{margin-right:0!important}.ql-formats .ql-header{position:relative!important}.ql-formats .ql-header .ql-picker-options{position:absolute!important;top:-151px!important}.ql-formats .ql-font{position:relative!important}.ql-formats .ql-font .ql-picker-options{position:absolute!important;top:-93px!important}.ql-formats .ql-color{position:relative!important}.ql-formats .ql-color .ql-picker-options{position:absolute!important;top:-108px}.ql-formats .ql-background{position:relative!important}.ql-formats .ql-background .ql-picker-options{position:absolute!important;top:-108px}.ql-formats .ql-align{position:relative!important}.ql-formats .ql-align .ql-picker-label{padding:3px 4px!important}.ql-formats .ql-align .ql-picker-options{position:absolute!important;top:-106px}.ql-snow .ql-picker{font-size:12px!important;height:32px;float:none;width:auto}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: LibsUiComponentsInputsMentionDirective, selector: "[LibsUiComponentsInputsMentionDirective]", inputs: ["timeDelayInit", "mentionConfig", "mentionListTemplate"], outputs: ["outSearchTerm", "outItemSelected", "outToggle", "outInsertMention", "outFunctionControl"] }, { kind: "directive", type: LibsUiComponentsScrollOverlayDirective, selector: "[LibsUiComponentsScrollOverlayDirective]", inputs: ["debugMode", "ignoreInit", "classContainer", "options", "elementCheckScrollX", "elementCheckScrollY", "elementScroll"], outputs: ["outScroll", "outScrollX", "outScrollY", "outScrollTop", "outScrollBottom"] }, { kind: "component", type: LibsUiComponentsLabelComponent, selector: "libs_ui-components-label", inputs: ["iconPopoverClass", "classInclude", "labelLeft", "labelLeftClass", "labelLeftBehindToggleButton", "popover", "required", "buttonsLeft", "disableButtonsLeft", "buttonsRight", "disableButtonsRight", "labelRight", "labelRightClass", "labelRightRequired", "hasToggle", "toggleSize", "toggleActive", "toggleDisable", "description", "descriptionClass", "buttonsDescription", "disableButtonsDescription", "buttonsDescriptionContainerClass", "onlyShowCount", "zIndexPopover", "timerDestroyPopover", "count", "limitLength"], outputs: ["outClickButton", "outSwitchEvent", "outLabelRightClick", "outLabelLeftClick"] }, { kind: "component", type: LibsUiComponentsDropdownComponent, selector: "libs_ui-components-dropdown", inputs: ["useXssFilter", "popoverElementRefCustom", "classInclude", "ignoreStopPropagationEvent", "flagMouse", "flagMouseContent", "popoverCustomConfig", "isNgContent", "zIndex", "convertItemSelected", "getPopoverItemSelected", "httpRequestDetailItemById", "lengthKeys", "textDisplayWhenNoSelect", "textDisplayWhenMultiSelect", "classIncludeTextDisplayWhenNoSelect", "fieldLabel", "fieldGetLabel", "labelPopoverConfig", "labelPopoverFullWidth", "hasContentUnitRight", "listSearchNoDataTemplateRef", "fieldGetImage", "imageSize", "typeShape", "fieldGetIcon", "fieldGetTextAvatar", "fieldGetColorAvatar", "classAvatarInclude", "getLastTextAfterSpace", "linkImageError", "showError", "showBorderError", "disable", "readonly", "labelConfig", "disableLabel", "listSearchConfig", "isSearchOnline", "listHiddenInputSearch", "listSearchPadding", "listKeySearch", "listDividerClassInclude", "listConfig", "listButtonsOther", "listHasButtonUnSelectOption", "listClickExactly", "listBackgroundCustom", "listMaxItemShow", "listKeySelected", "listMultiKeySelected", "listKeysDisable", "listKeysHidden", "validRequired", "validMaxItemSelected", "changeValidUndefinedResetError", "allowSelectItemMultiple", "focusInputSearch", "onlyEmitDataWhenReset", "resetKeyWhenSelectAllKey", "listConfigHasDivider", "classIncludeIcon", "classIncludeContent", "listIgnoreClassDisableDefaultWhenUseKeysDisableItem", "tabKeyActive", "tabsConfig", "ignoreBorderBottom"], outputs: ["flagMouseChange", "flagMouseContentChange", "lengthKeysChange", "showBorderErrorChange", "listKeySelectedChange", "listMultiKeySelectedChange", "tabKeyActiveChange", "outSelectKey", "outSelectMultiKey", "outFunctionsControl", "outValidEvent", "outChangStageFlagMouse", "outDataChange", "outClickButtonOther", "outShowList", "outChangeTabKeyActive"] }, { kind: "component", type: LibsUiComponentsPopoverComponent, selector: "libs_ui-components-popover,[LibsUiComponentsPopoverDirective]", inputs: ["debugId", "flagMouse", "type", "mode", "config", "ignoreShowPopover", "elementRefCustom", "initEventInElementRefCustom", "classInclude", "ignoreHiddenPopoverContentWhenMouseLeave", "ignoreStopPropagationEvent", "ignoreCursorPointerModeLikeClick", "isAddContentToParentDocument", "ignoreClickOutside"], outputs: ["outEvent", "outChangStageFlagMouse", "outEventPopoverContent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsButtonsSelectColorComponent, selector: "libs_ui-components-buttons-select_color", inputs: ["zIndex", "customOptions", "externalContent", "direction", "button", "applyNow"], outputs: ["zIndexChange", "outColorChange", "outColorChangeMultipleType"] }, { kind: "component", type: LibsUiComponentsInputsValidComponent, selector: "libs_ui-components-inputs-valid", inputs: ["item", "labelConfig", "emitEmptyInDataTypeNumber", "ignoreBlockInputMaxValue", "fieldNameBind", "showCount", "typeComponentSelectItem", "valueComponentSelectItem", "disableComponentSelectItem", "tagInput", "dataType", "typeInput", "modeInput", "resetAutoCompletePassword", "textAreaEnterNotNewLine", "fixedFloat", "acceptNegativeValue", "valueUpDownNumber", "ignoreWidthInput100", "classIncludeInput", "classContainerInput", "readonly", "disable", "noBorder", "backgroundNone", "useColorModeExist", "placeholder", "keepPlaceholderOnly", "classContainerBottomInput", "autoRemoveEmoji", "defaultHeight", "maxHeightTextArea", "minHeightTextArea", "ignoreShowError", "borderError", "iconLeftClass", "popoverContentIconLeft", "iconRightClass", "popoverContentIconRight", "zIndexPopoverContent", "unitsLeft", "configUnitLeft", "keySelectedUnitLeft", "unitsRight", "configUnitRight", "keySelectedUnitRight", "maxValueNumber", "minValueNumber", "ignoreContentLeft", "ignoreContentRight", "isBaselineStyle", "valuePatternShowError", "validPattern", "validRequired", "validMinLength", "validMinValue", "validMaxValue", "validMaxLength", "functionValid", "maxLength", "positionMessageErrorStartInput", "classInclude", "resize", "templateLeftBottomInput", "templateRightBottomInput", "onlyAcceptNegativeValue", "autoAddZeroLessThan10InTypeInt", "maxLengthNumberCount", "classMessageErrorInclude", "ignoreStopPropagationEvent", "ignoreUnitRightClassReadOnly", "paddingRightCustomSpecific", "focusTimeOut", "debounceTimeValidate"], outputs: ["itemChange", "outValueChange", "outSelect", "outIconLeft", "outIconRight", "outClickButtonLabel", "outSwitchEventLabel", "outLabelRightClick", "outEnterInputEvent", "outHeightAreaChange", "outFunctionsControl", "outFocusAndBlur", "outChangeValueByButtonUpDown"] }, { kind: "component", type: LibsUiComponentsEmojiComponent, selector: "libs_ui-components-emoji", inputs: ["configPopover", "isNgContent", "zIndex", "modePopoverPosition", "classPopup", "classInclude", "classIconInclude"], outputs: ["outEventEmoji", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive", "isHandlerEnterDocumentClickButton"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsSpinnerComponent, selector: "libs_ui-components-spinner", inputs: ["type", "size"] }, { kind: "component", type: LibsUiComponentsSkeletonComponent, selector: "libs_ui-components-skeleton", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1425
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LibsUiComponentsInputsQuillComponent, isStandalone: true, selector: "libs_ui-components-inputs-quill", inputs: { isShowToolBar: { classPropertyName: "isShowToolBar", publicName: "isShowToolBar", isSignal: true, isRequired: false, transformFunction: null }, isToolbarPositionFixed: { classPropertyName: "isToolbarPositionFixed", publicName: "isToolbarPositionFixed", isSignal: true, isRequired: false, transformFunction: null }, classIncludeToolbar: { classPropertyName: "classIncludeToolbar", publicName: "classIncludeToolbar", isSignal: true, isRequired: false, transformFunction: null }, stylesIncludeToolbar: { classPropertyName: "stylesIncludeToolbar", publicName: "stylesIncludeToolbar", isSignal: true, isRequired: false, transformFunction: null }, toolbarConfig: { classPropertyName: "toolbarConfig", publicName: "toolbarConfig", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null }, autoUpdateValueWhenTextChange: { classPropertyName: "autoUpdateValueWhenTextChange", publicName: "autoUpdateValueWhenTextChange", isSignal: true, isRequired: false, transformFunction: null }, fieldNameBind: { classPropertyName: "fieldNameBind", publicName: "fieldNameBind", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, showErrorLabel: { classPropertyName: "showErrorLabel", publicName: "showErrorLabel", isSignal: true, isRequired: false, transformFunction: null }, showErrorBorder: { classPropertyName: "showErrorBorder", publicName: "showErrorBorder", isSignal: true, isRequired: false, transformFunction: null }, onlyShowErrorBorderInContent: { classPropertyName: "onlyShowErrorBorderInContent", publicName: "onlyShowErrorBorderInContent", isSignal: true, isRequired: false, transformFunction: null }, classIncludeTemplate: { classPropertyName: "classIncludeTemplate", publicName: "classIncludeTemplate", isSignal: true, isRequired: false, transformFunction: null }, classInclude: { classPropertyName: "classInclude", publicName: "classInclude", isSignal: true, isRequired: false, transformFunction: null }, handlersExpand: { classPropertyName: "handlersExpand", publicName: "handlersExpand", isSignal: true, isRequired: false, transformFunction: null }, validRequired: { classPropertyName: "validRequired", publicName: "validRequired", isSignal: true, isRequired: false, transformFunction: null }, validMinLength: { classPropertyName: "validMinLength", publicName: "validMinLength", isSignal: true, isRequired: false, transformFunction: null }, validMaxLength: { classPropertyName: "validMaxLength", publicName: "validMaxLength", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, dataConfigMention: { classPropertyName: "dataConfigMention", publicName: "dataConfigMention", isSignal: true, isRequired: false, transformFunction: null }, blotsRegister: { classPropertyName: "blotsRegister", publicName: "blotsRegister", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, focusBottom: { classPropertyName: "focusBottom", publicName: "focusBottom", isSignal: true, isRequired: false, transformFunction: null }, blockUndoRedoKeyboard: { classPropertyName: "blockUndoRedoKeyboard", publicName: "blockUndoRedoKeyboard", isSignal: true, isRequired: false, transformFunction: null }, templateToolBarPersonalize: { classPropertyName: "templateToolBarPersonalize", publicName: "templateToolBarPersonalize", isSignal: true, isRequired: false, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", isSignal: true, isRequired: false, transformFunction: null }, uploadImageConfig: { classPropertyName: "uploadImageConfig", publicName: "uploadImageConfig", isSignal: true, isRequired: false, transformFunction: null }, heightAuto: { classPropertyName: "heightAuto", publicName: "heightAuto", isSignal: true, isRequired: false, transformFunction: null }, elementScrollHeightAuto: { classPropertyName: "elementScrollHeightAuto", publicName: "elementScrollHeightAuto", isSignal: true, isRequired: false, transformFunction: null }, ignoreShowPopupEditLink: { classPropertyName: "ignoreShowPopupEditLink", publicName: "ignoreShowPopupEditLink", isSignal: true, isRequired: false, transformFunction: null }, ignoreCommunicateMicroEventPopup: { classPropertyName: "ignoreCommunicateMicroEventPopup", publicName: "ignoreCommunicateMicroEventPopup", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { item: "itemChange", outShowPopupEditLink: "outShowPopupEditLink", outMessageError: "outMessageError", outBlur: "outBlur", outFocus: "outFocus", outChange: "outChange", outFunctionsControl: "outFunctionsControl", outSelectionChange: "outSelectionChange", outTextChange: "outTextChange", outContextMenu: "outContextMenu" }, viewQueries: [{ propertyName: "wrapperEditorEl", first: true, predicate: ["wrapperEditor"], descendants: true, isSignal: true }, { propertyName: "editorEl", first: true, predicate: ["editor"], descendants: true, isSignal: true }, { propertyName: "quillOptionEl", first: true, predicate: ["quillOption"], descendants: true, isSignal: true }, { propertyName: "quillEditorEl", first: true, predicate: ["quillEditor"], descendants: true, isSignal: true }, { propertyName: "toolbarItemsEl", first: true, predicate: ["toolbarItems"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex flex-col w-full h-full\">\n @if (label(); as label) {\n <libs_ui-components-label\n [classInclude]=\"label.classInclude\"\n [required]=\"label.required\"\n [labelLeft]=\"label.labelLeft\" />\n }\n <div\n #wrapperEditor\n [attr.heightAuto]=\"heightAuto()\"\n [attr.isToolbarPositionFixed]=\"isToolbarPositionFixed()\"\n class=\"libs-ui-quill-wrapper w-full h-full relative flex flex-col\"\n [class.libs-ui-border-error-general]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\"\n [class.rounded-[4px]]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\">\n <div\n #editor\n class=\"libs-ui-quill\"\n [attr.showError]=\"messageError() && showErrorBorder() && onlyShowErrorBorderInContent()\"\n [class.!hidden]=\"!display()\">\n <div\n #quillOption\n [class.!top-[-9999px]]=\"!isShowToolBar()\"\n [class.!left-[-9999px]]=\"!isShowToolBar()\"\n [style]=\"stylesIncludeToolbar()\"\n [class.pointer-events-none]=\"readonly() || loadingUploadImage()\"\n class=\"{{ isToolbarPositionFixed() ? 'fixed !z-10 w-[510px] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] rounded-[4px] bg-[#ffffff] libs-ui-quill-toolbar-animation' : '' }} {{ classIncludeToolbar() }} h-[44px] shrink-0\"\n [class.bg-[#f8f9fa]]=\"!readonly() && !loadingUploadImage()\"\n [class.libs-ui-readonly-background]=\"readonly() || loadingUploadImage()\">\n <ng-container *ngTemplateOutlet=\"toolbar\"></ng-container>\n </div>\n <div\n #quillEditor\n LibsUiComponentsInputsMentionDirective\n [timeDelayInit]=\"timeDelayInit() + 50\"\n [mentionConfig]=\"dataConfigMention()\"\n [class.libs-ui-readonly-background]=\"readonly() || loadingUploadImage()\"\n [class.pointer-events-none]=\"loadingUploadImage()\"\n (outToggle)=\"handleToggleMention($event)\"\n (outInsertMention)=\"handlerInsertMention($event)\"></div>\n <ng-container\n #qlEditorScroll\n LibsUiComponentsScrollOverlayDirective\n [ignoreInit]=\"!qlEditorElement()\"\n [elementScroll]=\"qlEditorElement()\" />\n </div>\n @if (template(); as template) {\n <div [class]=\"classIncludeTemplate()\">\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>\n }\n @if (loadingUploadImage()) {\n <libs_ui-components-spinner [size]=\"'medium'\" />\n }\n </div>\n @if (messageError() && showErrorLabel()) {\n <div class=\"flex items-center leading-normal mt-[8px]\">\n <span class=\"text-[#ff5454] libs-ui-font-h7r\">{{ messageError() | translate }}</span>\n </div>\n }\n</div>\n\n<ng-template #toolbar>\n <div\n class=\"toolbar h-full w-full shrink-0\"\n #toolbarItems>\n @if (displaySkeleton()) {\n <libs_ui-components-skeleton\n class=\"w-full h-full\"\n [config]=\"{\n rows: [\n {\n item: { classIncludeItem: '!rounded-none' },\n },\n ],\n }\" />\n }\n <div class=\"ql-formats items-center px-[16px] py-[4px]\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"!option.display\"\n [class.flex]=\"option.display\">\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { option, $index, $last }\"></ng-container>\n </div>\n }\n <div class=\"relative\">\n @if (displayShowMoreToolbar()) {\n <libs_ui-components-buttons-button\n [type]=\"showMoreAction() ? 'button-secondary' : 'button-third'\"\n [iconOnlyType]=\"true\"\n [classInclude]=\"'!p-[1px] !h-[20px] ml-[8px]'\"\n [classIconLeft]=\"'libs-ui-icon-move-right rotate-90'\"\n (outClick)=\"handlerChangeShowMoreAction($event)\" />\n }\n <!-- Build toolbar khi click xem th\u00EAm-->\n <div\n [class.hidden]=\"!showMoreAction()\"\n class=\"absolute bg-[#ffffff] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] z-[1] flex items-center pl-[8px] pr-[16px] py-[4px] rounded-[8px] top-[31px] right-[0px]\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"option.display !== false\"\n [class.flex]=\"option.display === false\">\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { option, $index, $last }\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template\n #itemTemplate\n let-$index=\"$index\"\n let-$last=\"$last\"\n let-option=\"option\">\n @if (option.type === 'undo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_undo', zIndex: zIndex() }\"\n class=\"ql-undo\"></button>\n </div>\n }\n @if (option.type === 'redo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_redo', zIndex: zIndex() }\"\n class=\"ql-redo\"></button>\n </div>\n }\n @if (option.type === 'fontFamily') {\n <div\n class=\"relative w-[132px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigFont()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectFont($event)\">\n @if (fontSelected(); as fontSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px]\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelFontSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'header') {\n <div\n class=\"relative w-[138px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigHeader()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectHeader($event)\">\n @if (headerSelected(); as headerSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px] {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelHeaderSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'fontSize') {\n <div class=\"ql-picker {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-inputs-valid\n [dataType]=\"'int'\"\n [(item)]=\"size\"\n [fieldNameBind]=\"'value'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"72\"\n [minValueNumber]=\"8\"\n [readonly]=\"readonly() || loadingUploadImage()\"\n [classContainerInput]=\"'w-[72px] h-[32px]'\"\n (outValueChange)=\"handlerValueChange($event)\" />\n </div>\n }\n @if (option.type === 'color') {\n <div class=\"ql-color ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_text_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n [applyNow]=\"false\"\n (outColorChange)=\"setStyle('color', $event)\">\n <div class=\"libs-ui-icon-editor-color-text libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'background') {\n <div class=\"ql-background ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_background_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [applyNow]=\"false\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n (outColorChange)=\"setStyle('background', $event)\">\n <div class=\"libs-ui-icon-editor-color-background libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'bold') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_weight_bold', zIndex: zIndex() }\"\n class=\"ql-bold\"></button>\n </div>\n }\n @if (option.type === 'italic') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_style_italic', zIndex: zIndex() }\"\n class=\"ql-italic\"></button>\n </div>\n }\n @if (option.type === 'underline') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_decoration_underline', zIndex: zIndex() }\"\n class=\"ql-underline\"></button>\n </div>\n }\n @if (option.type === 'strikeThrough') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_line_through', zIndex: zIndex() }\"\n class=\"ql-strike\"></button>\n </div>\n }\n @if (option.type === 'adjust') {\n <div class=\"relative !flex items-center ql-align ql-picker ql-icon-picker !w-max {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_adjust', zIndex: zIndex() }\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [ignoreStopPropagationEvent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigAlign()\"\n [listHiddenInputSearch]=\"true\"\n [popoverCustomConfig]=\"{ ignoreArrow: true, classInclude: '!w-[32px] overflow-hidden !py-[4px]', position: { mode: 'start', distance: 0 }, paddingLeftItem: false }\"\n [listHasButtonUnSelectOption]=\"false\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectAlign($event)\">\n @if (alignSelected(); as alignSelected) {\n <div class=\"flex items-center cursor-pointer\">\n <i [class]=\"iconAlignSelectedComputed()\"></i>\n <i class=\"libs-ui-icon-move-right rotate-90 text-[#6a7383] text-[16px] ml-[4px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'indentIncrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_increase', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"+1\"></button>\n </div>\n }\n @if (option.type === 'indentDecrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_decrease', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"-1\"></button>\n </div>\n }\n @if (option.type === 'listBulleted') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_bulleted', zIndex: zIndex() }\"\n class=\"ql-list ql-bullet\"\n value=\"bullet\"></button>\n </div>\n }\n @if (option.type === 'listNumbered') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_numbered', zIndex: zIndex() }\"\n class=\"ql-list ql-ordered\"\n value=\"ordered\"></button>\n </div>\n }\n @if (option.type === 'personalize' && templateToolBarPersonalize(); as templateToolBarPersonalize) {\n <div class=\"flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <ng-container *ngTemplateOutlet=\"templateToolBarPersonalize\"></ng-container>\n </div>\n }\n @if (option.type === 'blockquote') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_quote', zIndex: zIndex() }\"\n class=\"ql-blockquote\"></button>\n </div>\n }\n @if (option.type === 'link') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_insert_link', zIndex: zIndex() }\"\n class=\"ql-link\"></button>\n </div>\n }\n @if (option.type === 'unLink') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_unlink', zIndex: zIndex() }\"\n class=\"ql-unLink\"></button>\n </div>\n }\n @if (option.type === 'image') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_image', zIndex: zIndex() }\"\n class=\"ql-image\"></button>\n </div>\n }\n @if (option.type === 'emoji') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <libs_ui-components-emoji\n [zIndex]=\"zIndex()\"\n [isNgContent]=\"true\"\n (outEventEmoji)=\"handlerAddEmoji($event)\">\n <button class=\"ql-emoji\"></button>\n </libs_ui-components-emoji>\n </div>\n }\n @if (option.type === 'line') {\n <div class=\"w-[1px] h-[16px] libs-ui-border-right-general\"></div>\n }\n</ng-template>\n\n<libs_ui-components-popover\n [mode]=\"'click'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [config]=\"{ template: viewLink, whiteTheme: true, ignoreArrow: true, zIndex: zIndex() }\"\n (outEvent)=\"handlerPopoverEvent($event)\"\n (outFunctionsControl)=\"handlerPopoverFunctionControl($event)\" />\n\n<ng-template #viewLink>\n <div class=\"flex justify-between items-center px-[16px] py-[8px] rounded-[8px]\">\n <div\n class=\"w-full min-w-0 libs-ui-font-h5r\"\n [type]=\"'text'\"\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: link().url, zIndex: zIndex() + 1 }\">\n {{ link().url }}\n </div>\n <div class=\"flex items-center ml-[16px]\">\n <libs_ui-components-buttons-button\n [type]=\"'button-link-primary'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-edit-line'\"\n [classInclude]=\"'!p-0'\"\n (outClick)=\"handlerEdit($event)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-link-custom'\"\n [buttonCustom]=\"{\n configStepColor: {\n text: '#071631',\n text_hover: '#ee2d41',\n text_active: '#ee2d41',\n text_disable: '071631',\n },\n rootColor: '#071631',\n }\"\n [classInclude]=\"'!p-0 ml-[12px]'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-link-broken'\"\n (outClick)=\"handlerUnlink($event)\" />\n </div>\n </div>\n</ng-template>\n", styles: ["@-webkit-keyframes animation-move{0%{transform:translateY(-12px)}to{transform:translateY(0)}}@keyframes animation-move{0%{transform:translateY(-12px)}to{transform:translateY(0)}}.libs-ui-quill{height:100%;width:100%;display:flex;flex-direction:column}.libs-ui-quill-toolbar-animation{animation:animation-move .4s ease}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill{height:auto}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill ::ng-deep .ql-container{height:auto}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill ::ng-deep .ql-container .ql-editor{position:relative!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=true] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:0px!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:solid 1px #e6e8ed!important;border-radius:0 0 4px 4px}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill ::ng-deep .ql-toolbar.ql-snow{border:solid 1px #e6e8ed!important;border-radius:4px 4px 0 0;border-bottom:unset!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill[showError=true] ::ng-deep .ql-container.ql-snow{border:solid 1px #ee2d41!important}:host ::ng-deep .toolbar,:host ::ng-deep .ql-formats{position:relative;width:100%}:host ::ng-deep .ql-toolbar.ql-snow .ql-formats{display:flex}:host ::ng-deep .ql-container.ql-snow{width:100%;height:100%;position:relative}:host ::ng-deep .ql-editor{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:400}:host ::ng-deep .ql-editor b{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:600}:host ::ng-deep .ql-toolbar.ql-snow{border:none;border-radius:8px;padding:0}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label{color:#071631;border:none!important;margin-top:5px}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label:hover{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label:hover .ql-stroke{stroke:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-item:hover{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label.ql-active{color:#071631}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke{stroke:#071631}:host ::ng-deep .ql-editor{height:100%;width:100%;position:absolute;line-height:1.42!important}:host ::ng-deep .ql-editor:before{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;color:#9ca2ad!important;font-size:12px}:host ::ng-deep .ql-editor img{height:auto;max-width:100%}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label{border:none!important}:host ::ng-deep .ql-snow .ql-picker.ql-bold{width:36px!important}:host ::ng-deep .ql-active span:before{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-editor.ql-blank{font-size:11px!important;letter-spacing:.05px;font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;line-height:16px}:host ::ng-deep .ql-editor.ql-blank:before{font-style:normal!important;color:#9ca2ad!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label :hover{color:red!important}:host ::ng-deep .ql-formats{margin-right:12px!important}:host ::ng-deep .ql-formats .ql-size.ql-picker,:host ::ng-deep .ql-formats .ql-header.ql-picker,:host ::ng-deep .ql-formats .ql-font.ql-picker{border:solid 1px #e6e8ed!important;border-radius:4px}:host ::ng-deep .ql-formats .ql-align.ql-picker .ql-picker-label{width:24px}:host ::ng-deep .ql-formats .ql-align.ql-picker .ql-picker-label:hover{color:red!important}:host ::ng-deep .ql-formats .ql-header.ql-picker .ql-picker-label:before{font-size:12px}:host ::ng-deep .ql-picker-item:before{font-size:12px}:host ::ng-deep .ql-picker-label:before{font-size:12px}:host ::ng-deep .ql-snow.ql-toolbar button,:host ::ng-deep .ql-snow .ql-toolbar button{background:none;border:none;cursor:pointer;display:flex;align-items:center;float:none;padding:0;width:inherit}:host ::ng-deep ul{padding-left:1rem!important}:host ::ng-deep li{padding-left:0!important}:host ::ng-deep .ql-tooltip{display:none!important}.ql-picker-options{max-height:130px;overflow-y:auto}.ql-snow .ql-picker.ql-size{border:1px solid #e6e7ea;box-shadow:#00000005 0 1px 3px,#1b1f2326 0 0 0 1px;border-radius:2px}.ql-snow .ql-picker.ql-font{border:1px solid #e6e7ea!important;margin-right:8px;border-radius:4px}.ql-snow .ql-picker.ql-font .ql-picker-options:before{font-size:12px}.ql-snow .ql-picker.ql-font .ql-picker-label:before{font-size:12px}.ql-font-Arial{font-family:Arial}.ql-font-sans-serif{font-family:\"sans-serif\"}.ql-font-Helvetica{font-family:Helvetica}.libs-ui-quill-mention{font-weight:500!important;color:#7239ea;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:600}.ql-snow .ql-picker.ql-expanded .ql-picker-options{overflow:hidden}.ql-formats{margin-right:0!important}.ql-formats .ql-header{position:relative!important}.ql-formats .ql-header .ql-picker-options{position:absolute!important;top:-151px!important}.ql-formats .ql-font{position:relative!important}.ql-formats .ql-font .ql-picker-options{position:absolute!important;top:-93px!important}.ql-formats .ql-color{position:relative!important}.ql-formats .ql-color .ql-picker-options{position:absolute!important;top:-108px}.ql-formats .ql-background{position:relative!important}.ql-formats .ql-background .ql-picker-options{position:absolute!important;top:-108px}.ql-formats .ql-align{position:relative!important}.ql-formats .ql-align .ql-picker-label{padding:3px 4px!important}.ql-formats .ql-align .ql-picker-options{position:absolute!important;top:-106px}.ql-snow .ql-picker{font-size:12px!important;height:32px;float:none;width:auto}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: LibsUiComponentsInputsMentionDirective, selector: "[LibsUiComponentsInputsMentionDirective]", inputs: ["timeDelayInit", "mentionConfig", "mentionListTemplate"], outputs: ["outSearchTerm", "outItemSelected", "outToggle", "outInsertMention", "outFunctionControl"] }, { kind: "directive", type: LibsUiComponentsScrollOverlayDirective, selector: "[LibsUiComponentsScrollOverlayDirective]", inputs: ["debugMode", "ignoreInit", "classContainer", "options", "elementCheckScrollX", "elementCheckScrollY", "elementScroll"], outputs: ["outScroll", "outScrollX", "outScrollY", "outScrollTop", "outScrollBottom"] }, { kind: "component", type: LibsUiComponentsLabelComponent, selector: "libs_ui-components-label", inputs: ["iconPopoverClass", "classInclude", "labelLeft", "labelLeftClass", "labelLeftBehindToggleButton", "popover", "required", "buttonsLeft", "disableButtonsLeft", "buttonsRight", "disableButtonsRight", "labelRight", "labelRightClass", "labelRightRequired", "hasToggle", "toggleSize", "toggleActive", "toggleDisable", "description", "descriptionClass", "buttonsDescription", "disableButtonsDescription", "buttonsDescriptionContainerClass", "onlyShowCount", "zIndexPopover", "timerDestroyPopover", "count", "limitLength"], outputs: ["outClickButton", "outSwitchEvent", "outLabelRightClick", "outLabelLeftClick"] }, { kind: "component", type: LibsUiComponentsDropdownComponent, selector: "libs_ui-components-dropdown", inputs: ["useXssFilter", "popoverElementRefCustom", "classInclude", "ignoreStopPropagationEvent", "flagMouse", "flagMouseContent", "popoverCustomConfig", "isNgContent", "zIndex", "convertItemSelected", "getPopoverItemSelected", "httpRequestDetailItemById", "lengthKeys", "textDisplayWhenNoSelect", "textDisplayWhenMultiSelect", "classIncludeTextDisplayWhenNoSelect", "fieldLabel", "fieldGetLabel", "labelPopoverConfig", "labelPopoverFullWidth", "hasContentUnitRight", "listSearchNoDataTemplateRef", "fieldGetImage", "imageSize", "typeShape", "fieldGetIcon", "fieldGetTextAvatar", "fieldGetColorAvatar", "classAvatarInclude", "getLastTextAfterSpace", "linkImageError", "showError", "showBorderError", "disable", "readonly", "labelConfig", "disableLabel", "listSearchConfig", "isSearchOnline", "listHiddenInputSearch", "listSearchPadding", "listKeySearch", "listDividerClassInclude", "listConfig", "listButtonsOther", "listHasButtonUnSelectOption", "listClickExactly", "listBackgroundCustom", "listMaxItemShow", "listKeySelected", "listMultiKeySelected", "listKeysDisable", "listKeysHidden", "validRequired", "validMaxItemSelected", "changeValidUndefinedResetError", "allowSelectItemMultiple", "focusInputSearch", "onlyEmitDataWhenReset", "resetKeyWhenSelectAllKey", "listConfigHasDivider", "classIncludeIcon", "classIncludeContent", "listIgnoreClassDisableDefaultWhenUseKeysDisableItem", "tabKeyActive", "tabsConfig", "ignoreBorderBottom"], outputs: ["flagMouseChange", "flagMouseContentChange", "lengthKeysChange", "showBorderErrorChange", "listKeySelectedChange", "listMultiKeySelectedChange", "tabKeyActiveChange", "outSelectKey", "outSelectMultiKey", "outFunctionsControl", "outValidEvent", "outChangStageFlagMouse", "outDataChange", "outClickButtonOther", "outShowList", "outChangeTabKeyActive"] }, { kind: "component", type: LibsUiComponentsPopoverComponent, selector: "libs_ui-components-popover,[LibsUiComponentsPopoverDirective]", inputs: ["debugId", "flagMouse", "type", "mode", "config", "ignoreShowPopover", "elementRefCustom", "initEventInElementRefCustom", "classInclude", "ignoreHiddenPopoverContentWhenMouseLeave", "ignoreStopPropagationEvent", "ignoreCursorPointerModeLikeClick", "isAddContentToParentDocument", "ignoreClickOutside"], outputs: ["outEvent", "outChangStageFlagMouse", "outEventPopoverContent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsButtonsSelectColorComponent, selector: "libs_ui-components-buttons-select_color", inputs: ["zIndex", "customOptions", "externalContent", "direction", "button", "applyNow"], outputs: ["zIndexChange", "outColorChange", "outColorChangeMultipleType"] }, { kind: "component", type: LibsUiComponentsInputsValidComponent, selector: "libs_ui-components-inputs-valid", inputs: ["item", "labelConfig", "emitEmptyInDataTypeNumber", "ignoreBlockInputMaxValue", "fieldNameBind", "showCount", "typeComponentSelectItem", "valueComponentSelectItem", "disableComponentSelectItem", "tagInput", "dataType", "typeInput", "modeInput", "resetAutoCompletePassword", "textAreaEnterNotNewLine", "fixedFloat", "acceptNegativeValue", "valueUpDownNumber", "ignoreWidthInput100", "classIncludeInput", "classContainerInput", "readonly", "disable", "noBorder", "backgroundNone", "useColorModeExist", "placeholder", "keepPlaceholderOnly", "classContainerBottomInput", "autoRemoveEmoji", "defaultHeight", "maxHeightTextArea", "minHeightTextArea", "ignoreShowError", "borderError", "iconLeftClass", "popoverContentIconLeft", "iconRightClass", "popoverContentIconRight", "zIndexPopoverContent", "unitsLeft", "configUnitLeft", "keySelectedUnitLeft", "unitsRight", "configUnitRight", "keySelectedUnitRight", "maxValueNumber", "minValueNumber", "ignoreContentLeft", "ignoreContentRight", "isBaselineStyle", "valuePatternShowError", "validPattern", "validRequired", "validMinLength", "validMinValue", "validMaxValue", "validMaxLength", "functionValid", "maxLength", "positionMessageErrorStartInput", "classInclude", "resize", "templateLeftBottomInput", "templateRightBottomInput", "onlyAcceptNegativeValue", "autoAddZeroLessThan10InTypeInt", "maxLengthNumberCount", "classMessageErrorInclude", "ignoreStopPropagationEvent", "ignoreUnitRightClassReadOnly", "paddingRightCustomSpecific", "focusTimeOut", "debounceTimeValidate"], outputs: ["itemChange", "outValueChange", "outSelect", "outIconLeft", "outIconRight", "outClickButtonLabel", "outSwitchEventLabel", "outLabelRightClick", "outEnterInputEvent", "outHeightAreaChange", "outFunctionsControl", "outFocusAndBlur", "outChangeValueByButtonUpDown"] }, { kind: "component", type: LibsUiComponentsEmojiComponent, selector: "libs_ui-components-emoji", inputs: ["configPopover", "isNgContent", "zIndex", "modePopoverPosition", "classPopup", "classInclude", "classIconInclude"], outputs: ["outEventEmoji", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive", "isHandlerEnterDocumentClickButton"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsSpinnerComponent, selector: "libs_ui-components-spinner", inputs: ["type", "size"] }, { kind: "component", type: LibsUiComponentsSkeletonComponent, selector: "libs_ui-components-skeleton", inputs: ["config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1385
1426
|
}
|
|
1386
1427
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsInputsQuillComponent, decorators: [{
|
|
1387
1428
|
type: Component,
|
|
@@ -1399,12 +1440,850 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
1399
1440
|
LibsUiComponentsButtonsButtonComponent,
|
|
1400
1441
|
LibsUiComponentsSpinnerComponent,
|
|
1401
1442
|
LibsUiComponentsSkeletonComponent,
|
|
1402
|
-
], template: "<div class=\"flex flex-col w-full h-full\">\n @if (label(); as label) {\n <libs_ui-components-label\n [classInclude]=\"label.classInclude\"\n [required]=\"label.required\"\n [labelLeft]=\"label.labelLeft\" />\n }\n <div\n #wrapperEditor\n [attr.heightAuto]=\"heightAuto()\"\n [attr.isToolbarPositionFixed]=\"isToolbarPositionFixed()\"\n class=\"libs-ui-quill-wrapper w-full h-full relative flex flex-col\"\n [class.libs-ui-border-error-general]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\"\n [class.rounded-[4px]]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\">\n <div\n #editor\n class=\"libs-ui-quill\"\n [attr.showError]=\"messageError() && showErrorBorder() && onlyShowErrorBorderInContent()\"\n [class.!hidden]=\"!display()\">\n <div\n #quillOption\n [class.!top-[-9999px]]=\"!isShowToolBar()\"\n [class.!left-[-9999px]]=\"!isShowToolBar()\"\n [style]=\"stylesIncludeToolbar()\"\n [class.pointer-events-none]=\"readonly() || loadingUploadImage()\"\n class=\"{{ isToolbarPositionFixed() ? 'fixed !z-10 w-[510px] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] rounded-[4px] bg-[#ffffff] libs-ui-quill-toolbar-animation' : '' }} {{ classIncludeToolbar() }} h-[44px] shrink-0\"\n [class.bg-[#f8f9fa]]=\"!readonly() && !loadingUploadImage()\"\n [class.libs-ui-readonly-background]=\"readonly() || loadingUploadImage()\">\n <ng-container *ngTemplateOutlet=\"toolbar\"></ng-container>\n </div>\n <div\n #quillEditor\n LibsUiComponentsInputsMentionDirective\n [timeDelayInit]=\"timeDelayInit() + 50\"\n [mentionConfig]=\"dataConfigMention()\"\n [class.libs-ui-readonly-background]=\"readonly() || loadingUploadImage()\"\n [class.pointer-events-none]=\"loadingUploadImage()\"\n (outToggle)=\"handleToggleMention($event)\"\n (outInsertMention)=\"handlerInsertMention($event)\"></div>\n <ng-container\n #qlEditorScroll\n LibsUiComponentsScrollOverlayDirective\n [ignoreInit]=\"!qlEditorElement()\"\n [elementScroll]=\"qlEditorElement()\" />\n </div>\n @if (template(); as template) {\n <div [class]=\"classIncludeTemplate()\">\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>\n }\n @if (loadingUploadImage()) {\n <libs_ui-components-spinner [size]=\"'medium'\" />\n }\n </div>\n @if (messageError() && showErrorLabel()) {\n <div class=\"flex items-center leading-normal mt-[8px]\">\n <span class=\"text-[#ff5454] libs-ui-font-h7r\">{{ messageError() | translate }}</span>\n </div>\n }\n</div>\n\n<ng-template #toolbar>\n <div\n class=\"toolbar h-full w-full shrink-0\"\n #toolbarItems>\n @if (displaySkeleton()) {\n <libs_ui-components-skeleton\n class=\"w-full h-full\"\n [config]=\"{\n rows: [\n {\n item: { classIncludeItem: '!rounded-none' },\n },\n ],\n }\" />\n }\n <div class=\"ql-formats items-center px-[16px] py-[4px]\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"!option.display\"\n [class.flex]=\"option.display\">\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { option, $index, $last }\"></ng-container>\n </div>\n }\n <div class=\"relative\">\n @if (displayShowMoreToolbar()) {\n <libs_ui-components-buttons-button\n [type]=\"showMoreAction() ? 'button-secondary' : 'button-third'\"\n [iconOnlyType]=\"true\"\n [classInclude]=\"'!p-[1px] !h-[20px] ml-[8px]'\"\n [classIconLeft]=\"'libs-ui-icon-move-right rotate-90'\"\n (outClick)=\"handlerChangeShowMoreAction($event)\" />\n }\n <!-- Build toolbar khi click xem th\u00EAm-->\n <div\n [class.hidden]=\"!showMoreAction()\"\n class=\"absolute bg-[#ffffff] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] z-[1] flex items-center pl-[8px] pr-[16px] py-[4px] rounded-[8px] top-[31px] right-[0px]\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"option.display !== false\"\n [class.flex]=\"option.display === false\">\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { option, $index, $last }\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template\n #itemTemplate\n let-$index=\"$index\"\n let-$last=\"$last\"\n let-option=\"option\">\n @if (option.type === 'undo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_undo', zIndex: zIndex() }\"\n class=\"ql-undo\"></button>\n </div>\n }\n @if (option.type === 'redo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_redo', zIndex: zIndex() }\"\n class=\"ql-redo\"></button>\n </div>\n }\n @if (option.type === 'fontFamily') {\n <div\n class=\"relative w-[132px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigFont()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectFont($event)\">\n @if (fontSelected(); as fontSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px]\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelFontSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'header') {\n <div\n class=\"relative w-[138px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigHeader()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectHeader($event)\">\n @if (headerSelected(); as headerSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px] {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelHeaderSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'fontSize') {\n <div class=\"ql-picker {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-inputs-valid\n [dataType]=\"'int'\"\n [(item)]=\"size\"\n [fieldNameBind]=\"'value'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"72\"\n [minValueNumber]=\"8\"\n [readonly]=\"readonly() || loadingUploadImage()\"\n [classContainerInput]=\"'w-[72px] h-[32px]'\"\n (outValueChange)=\"handlerValueChange($event)\" />\n </div>\n }\n @if (option.type === 'color') {\n <div class=\"ql-color ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_text_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n [applyNow]=\"false\"\n (outColorChange)=\"setStyle('color', $event)\">\n <div class=\"libs-ui-icon-editor-color-text libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'background') {\n <div class=\"ql-background ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_background_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [applyNow]=\"false\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n (outColorChange)=\"setStyle('background', $event)\">\n <div class=\"libs-ui-icon-editor-color-background libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'bold') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_weight_bold', zIndex: zIndex() }\"\n class=\"ql-bold\"></button>\n </div>\n }\n @if (option.type === 'italic') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_style_italic', zIndex: zIndex() }\"\n class=\"ql-italic\"></button>\n </div>\n }\n @if (option.type === 'underline') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_decoration_underline', zIndex: zIndex() }\"\n class=\"ql-underline\"></button>\n </div>\n }\n @if (option.type === 'strikeThrough') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_line_through', zIndex: zIndex() }\"\n class=\"ql-strike\"></button>\n </div>\n }\n @if (option.type === 'adjust') {\n <div class=\"relative !flex items-center ql-align ql-picker ql-icon-picker !w-max {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_adjust', zIndex: zIndex() }\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [ignoreStopPropagationEvent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigAlign()\"\n [listHiddenInputSearch]=\"true\"\n [popoverCustomConfig]=\"{ ignoreArrow: true, classInclude: '!w-[32px] overflow-hidden !py-[4px]', position: { mode: 'start', distance: 0 }, paddingLeftItem: false }\"\n [listHasButtonUnSelectOption]=\"false\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectAlign($event)\">\n @if (alignSelected(); as alignSelected) {\n <div class=\"flex items-center cursor-pointer\">\n <i [class]=\"iconAlignSelectedComputed()\"></i>\n <i class=\"libs-ui-icon-move-right rotate-90 text-[#6a7383] text-[16px] ml-[4px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'indentIncrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_increase', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"+1\"></button>\n </div>\n }\n @if (option.type === 'indentDecrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_decrease', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"-1\"></button>\n </div>\n }\n @if (option.type === 'listBulleted') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_bulleted', zIndex: zIndex() }\"\n class=\"ql-list ql-bullet\"\n value=\"bullet\"></button>\n </div>\n }\n @if (option.type === 'listNumbered') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_numbered', zIndex: zIndex() }\"\n class=\"ql-list ql-ordered\"\n value=\"ordered\"></button>\n </div>\n }\n @if (option.type === 'personalize' && templateToolBarPersonalize(); as templateToolBarPersonalize) {\n <div class=\"flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <ng-container *ngTemplateOutlet=\"templateToolBarPersonalize\"></ng-container>\n </div>\n }\n @if (option.type === 'blockquote') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_quote', zIndex: zIndex() }\"\n class=\"ql-blockquote\"></button>\n </div>\n }\n @if (option.type === 'link') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_insert_link', zIndex: zIndex() }\"\n class=\"ql-link\"></button>\n </div>\n }\n @if (option.type === 'unLink') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_unlink', zIndex: zIndex() }\"\n class=\"ql-unLink\"></button>\n </div>\n }\n @if (option.type === 'image') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_image', zIndex: zIndex() }\"\n class=\"ql-image\"></button>\n </div>\n }\n @if (option.type === 'emoji') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <libs_ui-components-emoji\n [zIndex]=\"zIndex()\"\n [isNgContent]=\"true\"\n (outEventEmoji)=\"handlerAddEmoji($event)\">\n <button class=\"ql-emoji\"></button>\n </libs_ui-components-emoji>\n </div>\n }\n @if (option.type === 'line') {\n <div class=\"w-[1px] h-[16px] libs-ui-border-right-general\"></div>\n }\n</ng-template>\n\n<libs_ui-components-popover\n [mode]=\"'click'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [config]=\"{ template: viewLink, whiteTheme: true, ignoreArrow: true, zIndex: zIndex() }\"\n (outEvent)=\"handlerPopoverEvent($event)\"\n (outFunctionsControl)=\"handlerPopoverFunctionControl($event)\" />\n\n<ng-template #viewLink>\n <div class=\"flex justify-between items-center px-[16px] py-[8px] rounded-[8px]\">\n <div\n class=\"w-full min-w-0 libs-ui-font-h5r\"\n [type]=\"'text'\"\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: link().url, zIndex: zIndex() + 1 }\">\n {{ link().url }}\n </div>\n <div class=\"flex items-center ml-[16px]\">\n <libs_ui-components-buttons-button\n [type]=\"'button-link-primary'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-edit-line'\"\n [classInclude]=\"'!p-0'\"\n (outClick)=\"handlerEdit($event)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-link-custom'\"\n [buttonCustom]=\"{\n configStepColor: {\n text: '#071631',\n text_hover: '#ee2d41',\n text_active: '#ee2d41',\n text_disable: '071631',\n },\n rootColor: '#071631',\n }\"\n [classInclude]=\"'!p-0 ml-[12px]'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-link-broken'\"\n (outClick)=\"handlerUnlink($event)\" />\n </div>\n </div>\n</ng-template>\n", styles: ["@-webkit-keyframes animation-move{0%{transform:translateY(-12px)}to{transform:translateY(0)}}@keyframes animation-move{0%{transform:translateY(-12px)}to{transform:translateY(0)}}.libs-ui-quill{height:100%;width:100%;display:flex;flex-direction:column}.libs-ui-quill-toolbar-animation{animation:animation-move .4s ease}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill{height:auto}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill ::ng-deep .ql-container{height:auto}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill ::ng-deep .ql-container .ql-editor{position:relative!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=true] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:0px!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:solid 1px #e6e8ed!important;border-radius:0 0 4px 4px}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill ::ng-deep .ql-toolbar.ql-snow{border:solid 1px #e6e8ed!important;border-radius:4px 4px 0 0;border-bottom:unset!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill[showError=true] ::ng-deep .ql-container.ql-snow{border:solid 1px #ee2d41!important}:host ::ng-deep .toolbar,:host ::ng-deep .ql-formats{position:relative;width:100%}:host ::ng-deep .ql-toolbar.ql-snow .ql-formats{display:flex}:host ::ng-deep .ql-container.ql-snow{width:100%;height:100%;position:relative}:host ::ng-deep .ql-editor{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:400}:host ::ng-deep .ql-editor b{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:600}:host ::ng-deep .ql-toolbar.ql-snow{border:none;border-radius:8px;padding:0}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label{color:#071631;border:none!important;margin-top:5px}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label:hover{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label:hover .ql-stroke{stroke:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-item:hover{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label.ql-active{color:#071631}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke{stroke:#071631}:host ::ng-deep .ql-editor{height:100%;width:100%;position:absolute;line-height:1.42!important}:host ::ng-deep .ql-editor:before{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;color:#9ca2ad!important;font-size:12px}:host ::ng-deep .ql-editor img{height:auto;max-width:100%}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label{border:none!important}:host ::ng-deep .ql-snow .ql-picker.ql-bold{width:36px!important}:host ::ng-deep .ql-editor.ql-blank{font-size:11px!important;letter-spacing:.05px;font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;line-height:16px}:host ::ng-deep .ql-editor.ql-blank:before{font-style:normal!important;color:#9ca2ad!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label :hover{color:red!important}:host ::ng-deep .ql-formats{margin-right:12px!important}:host ::ng-deep .ql-formats .ql-size.ql-picker,:host ::ng-deep .ql-formats .ql-header.ql-picker,:host ::ng-deep .ql-formats .ql-font.ql-picker{border:solid 1px #e6e8ed!important;border-radius:4px}:host ::ng-deep .ql-formats .ql-align.ql-picker .ql-picker-label{width:24px}:host ::ng-deep .ql-formats .ql-align.ql-picker .ql-picker-label:hover{color:red!important}:host ::ng-deep .ql-formats .ql-header.ql-picker .ql-picker-label:before{font-size:12px}:host ::ng-deep .ql-picker-item:before{font-size:12px}:host ::ng-deep .ql-picker-label:before{font-size:12px}:host ::ng-deep .ql-snow.ql-toolbar button,:host ::ng-deep .ql-snow .ql-toolbar button{background:none;border:none;cursor:pointer;display:flex;align-items:center;float:none;padding:0;width:inherit}:host ::ng-deep ul{padding-left:1rem!important}:host ::ng-deep li{padding-left:0!important}:host ::ng-deep .ql-tooltip{display:none!important}.ql-picker-options{max-height:130px;overflow-y:auto}.ql-snow .ql-picker.ql-size{border:1px solid #e6e7ea;box-shadow:#00000005 0 1px 3px,#1b1f2326 0 0 0 1px;border-radius:2px}.ql-snow .ql-picker.ql-font{border:1px solid #e6e7ea!important;margin-right:8px;border-radius:4px}.ql-snow .ql-picker.ql-font .ql-picker-options:before{font-size:12px}.ql-snow .ql-picker.ql-font .ql-picker-label:before{font-size:12px}.ql-font-Arial{font-family:Arial}.ql-font-sans-serif{font-family:\"sans-serif\"}.ql-font-Helvetica{font-family:Helvetica}.libs-ui-quill-mention{font-weight:500!important;color:#7239ea;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:600}.ql-snow .ql-picker.ql-expanded .ql-picker-options{overflow:hidden}.ql-formats{margin-right:0!important}.ql-formats .ql-header{position:relative!important}.ql-formats .ql-header .ql-picker-options{position:absolute!important;top:-151px!important}.ql-formats .ql-font{position:relative!important}.ql-formats .ql-font .ql-picker-options{position:absolute!important;top:-93px!important}.ql-formats .ql-color{position:relative!important}.ql-formats .ql-color .ql-picker-options{position:absolute!important;top:-108px}.ql-formats .ql-background{position:relative!important}.ql-formats .ql-background .ql-picker-options{position:absolute!important;top:-108px}.ql-formats .ql-align{position:relative!important}.ql-formats .ql-align .ql-picker-label{padding:3px 4px!important}.ql-formats .ql-align .ql-picker-options{position:absolute!important;top:-106px}.ql-snow .ql-picker{font-size:12px!important;height:32px;float:none;width:auto}\n"] }]
|
|
1443
|
+
], template: "<div class=\"flex flex-col w-full h-full\">\n @if (label(); as label) {\n <libs_ui-components-label\n [classInclude]=\"label.classInclude\"\n [required]=\"label.required\"\n [labelLeft]=\"label.labelLeft\" />\n }\n <div\n #wrapperEditor\n [attr.heightAuto]=\"heightAuto()\"\n [attr.isToolbarPositionFixed]=\"isToolbarPositionFixed()\"\n class=\"libs-ui-quill-wrapper w-full h-full relative flex flex-col\"\n [class.libs-ui-border-error-general]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\"\n [class.rounded-[4px]]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\">\n <div\n #editor\n class=\"libs-ui-quill\"\n [attr.showError]=\"messageError() && showErrorBorder() && onlyShowErrorBorderInContent()\"\n [class.!hidden]=\"!display()\">\n <div\n #quillOption\n [class.!top-[-9999px]]=\"!isShowToolBar()\"\n [class.!left-[-9999px]]=\"!isShowToolBar()\"\n [style]=\"stylesIncludeToolbar()\"\n [class.pointer-events-none]=\"readonly() || loadingUploadImage()\"\n class=\"{{ isToolbarPositionFixed() ? 'fixed !z-10 w-[510px] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] rounded-[4px] bg-[#ffffff] libs-ui-quill-toolbar-animation' : '' }} {{ classIncludeToolbar() }} h-[44px] shrink-0\"\n [class.bg-[#f8f9fa]]=\"!readonly() && !loadingUploadImage()\"\n [class.libs-ui-readonly-background]=\"readonly() || loadingUploadImage()\">\n <ng-container *ngTemplateOutlet=\"toolbar\"></ng-container>\n </div>\n <div\n #quillEditor\n LibsUiComponentsInputsMentionDirective\n [timeDelayInit]=\"timeDelayInit() + 50\"\n [mentionConfig]=\"dataConfigMention()\"\n [class.libs-ui-readonly-background]=\"readonly() || loadingUploadImage()\"\n [class.pointer-events-none]=\"loadingUploadImage()\"\n (outToggle)=\"handleToggleMention($event)\"\n (outInsertMention)=\"handlerInsertMention($event)\"></div>\n <ng-container\n #qlEditorScroll\n LibsUiComponentsScrollOverlayDirective\n [ignoreInit]=\"!qlEditorElement()\"\n [elementScroll]=\"qlEditorElement()\" />\n </div>\n @if (template(); as template) {\n <div [class]=\"classIncludeTemplate()\">\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>\n }\n @if (loadingUploadImage()) {\n <libs_ui-components-spinner [size]=\"'medium'\" />\n }\n </div>\n @if (messageError() && showErrorLabel()) {\n <div class=\"flex items-center leading-normal mt-[8px]\">\n <span class=\"text-[#ff5454] libs-ui-font-h7r\">{{ messageError() | translate }}</span>\n </div>\n }\n</div>\n\n<ng-template #toolbar>\n <div\n class=\"toolbar h-full w-full shrink-0\"\n #toolbarItems>\n @if (displaySkeleton()) {\n <libs_ui-components-skeleton\n class=\"w-full h-full\"\n [config]=\"{\n rows: [\n {\n item: { classIncludeItem: '!rounded-none' },\n },\n ],\n }\" />\n }\n <div class=\"ql-formats items-center px-[16px] py-[4px]\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"!option.display\"\n [class.flex]=\"option.display\">\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { option, $index, $last }\"></ng-container>\n </div>\n }\n <div class=\"relative\">\n @if (displayShowMoreToolbar()) {\n <libs_ui-components-buttons-button\n [type]=\"showMoreAction() ? 'button-secondary' : 'button-third'\"\n [iconOnlyType]=\"true\"\n [classInclude]=\"'!p-[1px] !h-[20px] ml-[8px]'\"\n [classIconLeft]=\"'libs-ui-icon-move-right rotate-90'\"\n (outClick)=\"handlerChangeShowMoreAction($event)\" />\n }\n <!-- Build toolbar khi click xem th\u00EAm-->\n <div\n [class.hidden]=\"!showMoreAction()\"\n class=\"absolute bg-[#ffffff] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] z-[1] flex items-center pl-[8px] pr-[16px] py-[4px] rounded-[8px] top-[31px] right-[0px]\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"option.display !== false\"\n [class.flex]=\"option.display === false\">\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { option, $index, $last }\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template\n #itemTemplate\n let-$index=\"$index\"\n let-$last=\"$last\"\n let-option=\"option\">\n @if (option.type === 'undo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_undo', zIndex: zIndex() }\"\n class=\"ql-undo\"></button>\n </div>\n }\n @if (option.type === 'redo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_redo', zIndex: zIndex() }\"\n class=\"ql-redo\"></button>\n </div>\n }\n @if (option.type === 'fontFamily') {\n <div\n class=\"relative w-[132px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigFont()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectFont($event)\">\n @if (fontSelected(); as fontSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px]\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelFontSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'header') {\n <div\n class=\"relative w-[138px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigHeader()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectHeader($event)\">\n @if (headerSelected(); as headerSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px] {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelHeaderSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'fontSize') {\n <div class=\"ql-picker {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-inputs-valid\n [dataType]=\"'int'\"\n [(item)]=\"size\"\n [fieldNameBind]=\"'value'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"72\"\n [minValueNumber]=\"8\"\n [readonly]=\"readonly() || loadingUploadImage()\"\n [classContainerInput]=\"'w-[72px] h-[32px]'\"\n (outValueChange)=\"handlerValueChange($event)\" />\n </div>\n }\n @if (option.type === 'color') {\n <div class=\"ql-color ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_text_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n [applyNow]=\"false\"\n (outColorChange)=\"setStyle('color', $event)\">\n <div class=\"libs-ui-icon-editor-color-text libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'background') {\n <div class=\"ql-background ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_background_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [applyNow]=\"false\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n (outColorChange)=\"setStyle('background', $event)\">\n <div class=\"libs-ui-icon-editor-color-background libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'bold') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_weight_bold', zIndex: zIndex() }\"\n class=\"ql-bold\"></button>\n </div>\n }\n @if (option.type === 'italic') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_style_italic', zIndex: zIndex() }\"\n class=\"ql-italic\"></button>\n </div>\n }\n @if (option.type === 'underline') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_decoration_underline', zIndex: zIndex() }\"\n class=\"ql-underline\"></button>\n </div>\n }\n @if (option.type === 'strikeThrough') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_line_through', zIndex: zIndex() }\"\n class=\"ql-strike\"></button>\n </div>\n }\n @if (option.type === 'adjust') {\n <div class=\"relative !flex items-center ql-align ql-picker ql-icon-picker !w-max {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_adjust', zIndex: zIndex() }\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [ignoreStopPropagationEvent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigAlign()\"\n [listHiddenInputSearch]=\"true\"\n [popoverCustomConfig]=\"{ ignoreArrow: true, classInclude: '!w-[32px] overflow-hidden !py-[4px]', position: { mode: 'start', distance: 0 }, paddingLeftItem: false }\"\n [listHasButtonUnSelectOption]=\"false\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectAlign($event)\">\n @if (alignSelected(); as alignSelected) {\n <div class=\"flex items-center cursor-pointer\">\n <i [class]=\"iconAlignSelectedComputed()\"></i>\n <i class=\"libs-ui-icon-move-right rotate-90 text-[#6a7383] text-[16px] ml-[4px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'indentIncrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_increase', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"+1\"></button>\n </div>\n }\n @if (option.type === 'indentDecrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_decrease', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"-1\"></button>\n </div>\n }\n @if (option.type === 'listBulleted') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_bulleted', zIndex: zIndex() }\"\n class=\"ql-list ql-bullet\"\n value=\"bullet\"></button>\n </div>\n }\n @if (option.type === 'listNumbered') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_numbered', zIndex: zIndex() }\"\n class=\"ql-list ql-ordered\"\n value=\"ordered\"></button>\n </div>\n }\n @if (option.type === 'personalize' && templateToolBarPersonalize(); as templateToolBarPersonalize) {\n <div class=\"flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <ng-container *ngTemplateOutlet=\"templateToolBarPersonalize\"></ng-container>\n </div>\n }\n @if (option.type === 'blockquote') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_quote', zIndex: zIndex() }\"\n class=\"ql-blockquote\"></button>\n </div>\n }\n @if (option.type === 'link') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_insert_link', zIndex: zIndex() }\"\n class=\"ql-link\"></button>\n </div>\n }\n @if (option.type === 'unLink') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_unlink', zIndex: zIndex() }\"\n class=\"ql-unLink\"></button>\n </div>\n }\n @if (option.type === 'image') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_image', zIndex: zIndex() }\"\n class=\"ql-image\"></button>\n </div>\n }\n @if (option.type === 'emoji') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <libs_ui-components-emoji\n [zIndex]=\"zIndex()\"\n [isNgContent]=\"true\"\n (outEventEmoji)=\"handlerAddEmoji($event)\">\n <button class=\"ql-emoji\"></button>\n </libs_ui-components-emoji>\n </div>\n }\n @if (option.type === 'line') {\n <div class=\"w-[1px] h-[16px] libs-ui-border-right-general\"></div>\n }\n</ng-template>\n\n<libs_ui-components-popover\n [mode]=\"'click'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [config]=\"{ template: viewLink, whiteTheme: true, ignoreArrow: true, zIndex: zIndex() }\"\n (outEvent)=\"handlerPopoverEvent($event)\"\n (outFunctionsControl)=\"handlerPopoverFunctionControl($event)\" />\n\n<ng-template #viewLink>\n <div class=\"flex justify-between items-center px-[16px] py-[8px] rounded-[8px]\">\n <div\n class=\"w-full min-w-0 libs-ui-font-h5r\"\n [type]=\"'text'\"\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: link().url, zIndex: zIndex() + 1 }\">\n {{ link().url }}\n </div>\n <div class=\"flex items-center ml-[16px]\">\n <libs_ui-components-buttons-button\n [type]=\"'button-link-primary'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-edit-line'\"\n [classInclude]=\"'!p-0'\"\n (outClick)=\"handlerEdit($event)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-link-custom'\"\n [buttonCustom]=\"{\n configStepColor: {\n text: '#071631',\n text_hover: '#ee2d41',\n text_active: '#ee2d41',\n text_disable: '071631',\n },\n rootColor: '#071631',\n }\"\n [classInclude]=\"'!p-0 ml-[12px]'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-link-broken'\"\n (outClick)=\"handlerUnlink($event)\" />\n </div>\n </div>\n</ng-template>\n", styles: ["@-webkit-keyframes animation-move{0%{transform:translateY(-12px)}to{transform:translateY(0)}}@keyframes animation-move{0%{transform:translateY(-12px)}to{transform:translateY(0)}}.libs-ui-quill{height:100%;width:100%;display:flex;flex-direction:column}.libs-ui-quill-toolbar-animation{animation:animation-move .4s ease}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill{height:auto}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill ::ng-deep .ql-container{height:auto}.libs-ui-quill-wrapper[heightAuto=true] .libs-ui-quill ::ng-deep .ql-container .ql-editor{position:relative!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=true] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:0px!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:solid 1px #e6e8ed!important;border-radius:0 0 4px 4px}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill ::ng-deep .ql-toolbar.ql-snow{border:solid 1px #e6e8ed!important;border-radius:4px 4px 0 0;border-bottom:unset!important}.libs-ui-quill-wrapper[isToolbarPositionFixed=false] .libs-ui-quill[showError=true] ::ng-deep .ql-container.ql-snow{border:solid 1px #ee2d41!important}:host ::ng-deep .toolbar,:host ::ng-deep .ql-formats{position:relative;width:100%}:host ::ng-deep .ql-toolbar.ql-snow .ql-formats{display:flex}:host ::ng-deep .ql-container.ql-snow{width:100%;height:100%;position:relative}:host ::ng-deep .ql-editor{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:400}:host ::ng-deep .ql-editor b{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:600}:host ::ng-deep .ql-toolbar.ql-snow{border:none;border-radius:8px;padding:0}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label{color:#071631;border:none!important;margin-top:5px}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label:hover{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker-label:hover .ql-stroke{stroke:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-item:hover{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label.ql-active{color:#071631}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label.ql-active .ql-stroke{stroke:#071631}:host ::ng-deep .ql-editor{height:100%;width:100%;position:absolute;line-height:1.42!important}:host ::ng-deep .ql-editor:before{font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;color:#9ca2ad!important;font-size:12px}:host ::ng-deep .ql-editor img{height:auto;max-width:100%}:host ::ng-deep .ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label{border:none!important}:host ::ng-deep .ql-snow .ql-picker.ql-bold{width:36px!important}:host ::ng-deep .ql-active span:before{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .ql-editor.ql-blank{font-size:11px!important;letter-spacing:.05px;font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;line-height:16px}:host ::ng-deep .ql-editor.ql-blank:before{font-style:normal!important;color:#9ca2ad!important}:host ::ng-deep .ql-snow.ql-toolbar .ql-picker-label :hover{color:red!important}:host ::ng-deep .ql-formats{margin-right:12px!important}:host ::ng-deep .ql-formats .ql-size.ql-picker,:host ::ng-deep .ql-formats .ql-header.ql-picker,:host ::ng-deep .ql-formats .ql-font.ql-picker{border:solid 1px #e6e8ed!important;border-radius:4px}:host ::ng-deep .ql-formats .ql-align.ql-picker .ql-picker-label{width:24px}:host ::ng-deep .ql-formats .ql-align.ql-picker .ql-picker-label:hover{color:red!important}:host ::ng-deep .ql-formats .ql-header.ql-picker .ql-picker-label:before{font-size:12px}:host ::ng-deep .ql-picker-item:before{font-size:12px}:host ::ng-deep .ql-picker-label:before{font-size:12px}:host ::ng-deep .ql-snow.ql-toolbar button,:host ::ng-deep .ql-snow .ql-toolbar button{background:none;border:none;cursor:pointer;display:flex;align-items:center;float:none;padding:0;width:inherit}:host ::ng-deep ul{padding-left:1rem!important}:host ::ng-deep li{padding-left:0!important}:host ::ng-deep .ql-tooltip{display:none!important}.ql-picker-options{max-height:130px;overflow-y:auto}.ql-snow .ql-picker.ql-size{border:1px solid #e6e7ea;box-shadow:#00000005 0 1px 3px,#1b1f2326 0 0 0 1px;border-radius:2px}.ql-snow .ql-picker.ql-font{border:1px solid #e6e7ea!important;margin-right:8px;border-radius:4px}.ql-snow .ql-picker.ql-font .ql-picker-options:before{font-size:12px}.ql-snow .ql-picker.ql-font .ql-picker-label:before{font-size:12px}.ql-font-Arial{font-family:Arial}.ql-font-sans-serif{font-family:\"sans-serif\"}.ql-font-Helvetica{font-family:Helvetica}.libs-ui-quill-mention{font-weight:500!important;color:#7239ea;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--libs-ui-font-family-name),\"Arial, Helvetica, sans-serif\"!important;font-weight:600}.ql-snow .ql-picker.ql-expanded .ql-picker-options{overflow:hidden}.ql-formats{margin-right:0!important}.ql-formats .ql-header{position:relative!important}.ql-formats .ql-header .ql-picker-options{position:absolute!important;top:-151px!important}.ql-formats .ql-font{position:relative!important}.ql-formats .ql-font .ql-picker-options{position:absolute!important;top:-93px!important}.ql-formats .ql-color{position:relative!important}.ql-formats .ql-color .ql-picker-options{position:absolute!important;top:-108px}.ql-formats .ql-background{position:relative!important}.ql-formats .ql-background .ql-picker-options{position:absolute!important;top:-108px}.ql-formats .ql-align{position:relative!important}.ql-formats .ql-align .ql-picker-label{padding:3px 4px!important}.ql-formats .ql-align .ql-picker-options{position:absolute!important;top:-106px}.ql-snow .ql-picker{font-size:12px!important;height:32px;float:none;width:auto}\n"] }]
|
|
1403
1444
|
}], ctorParameters: () => [] });
|
|
1404
1445
|
|
|
1446
|
+
//region Function Table
|
|
1447
|
+
const createTableSelector = (quill, anchorEl, translate) => {
|
|
1448
|
+
// Đóng popup cũ nếu còn tồn tại
|
|
1449
|
+
document.querySelectorAll('.manual-table-creator').forEach((el) => el.parentElement?.removeChild(el));
|
|
1450
|
+
const popup = document.createElement('div');
|
|
1451
|
+
popup.className = 'manual-table-creator';
|
|
1452
|
+
// Inline style để đảm bảo hiển thị ngay cả khi CSS component không áp dụng
|
|
1453
|
+
popup.style.position = 'absolute';
|
|
1454
|
+
popup.style.background = '#fff';
|
|
1455
|
+
popup.style.border = '1px solid #ddd';
|
|
1456
|
+
popup.style.borderRadius = '6px';
|
|
1457
|
+
popup.style.boxShadow = '0 6px 16px rgba(0,0,0,0.12)';
|
|
1458
|
+
popup.style.padding = '12px';
|
|
1459
|
+
popup.style.zIndex = '10000';
|
|
1460
|
+
popup.style.minWidth = '200px';
|
|
1461
|
+
setStylesElement(popup, {
|
|
1462
|
+
position: 'absolute',
|
|
1463
|
+
background: '#fff',
|
|
1464
|
+
border: '1px solid #ddd',
|
|
1465
|
+
borderRadius: '6px',
|
|
1466
|
+
boxShadow: '0 6px 16px rgba(0,0,0,0.12)',
|
|
1467
|
+
padding: '12px',
|
|
1468
|
+
zIndex: '10000',
|
|
1469
|
+
minWidth: '200px',
|
|
1470
|
+
});
|
|
1471
|
+
const info = document.createElement('div');
|
|
1472
|
+
info.textContent = translate.instant('i18n_select_cell');
|
|
1473
|
+
setStylesElement(info, {
|
|
1474
|
+
fontSize: '12px',
|
|
1475
|
+
color: '#333',
|
|
1476
|
+
marginBottom: '10px',
|
|
1477
|
+
textAlign: 'center',
|
|
1478
|
+
fontWeight: '600',
|
|
1479
|
+
});
|
|
1480
|
+
popup.appendChild(info);
|
|
1481
|
+
const grid = document.createElement('div');
|
|
1482
|
+
setStylesElement(grid, {
|
|
1483
|
+
display: 'grid',
|
|
1484
|
+
gridTemplateColumns: 'repeat(8, 18px)',
|
|
1485
|
+
gap: '4px',
|
|
1486
|
+
});
|
|
1487
|
+
const max = 8;
|
|
1488
|
+
for (let r = 1; r <= max; r++) {
|
|
1489
|
+
for (let c = 1; c <= max; c++) {
|
|
1490
|
+
const cell = document.createElement('div');
|
|
1491
|
+
cell.style.width = '18px';
|
|
1492
|
+
cell.style.height = '18px';
|
|
1493
|
+
cell.style.border = '1px solid #e5e7eb';
|
|
1494
|
+
cell.style.background = '#fff';
|
|
1495
|
+
cell.style.cursor = 'pointer';
|
|
1496
|
+
cell.addEventListener('mouseenter', () => {
|
|
1497
|
+
info.textContent = `${r} × ${c}`;
|
|
1498
|
+
Array.from(grid.children).forEach((el, idx) => {
|
|
1499
|
+
const rr = Math.floor(idx / max) + 1;
|
|
1500
|
+
const cc = (idx % max) + 1;
|
|
1501
|
+
el.style.background = rr <= r && cc <= c ? '#dbeafe' : '#fff';
|
|
1502
|
+
el.style.borderColor = rr <= r && cc <= c ? '#93c5fd' : '#e5e7eb';
|
|
1503
|
+
});
|
|
1504
|
+
});
|
|
1505
|
+
cell.addEventListener('click', () => {
|
|
1506
|
+
try {
|
|
1507
|
+
quill.focus();
|
|
1508
|
+
const tableModule = quill.getModule('table');
|
|
1509
|
+
if (tableModule && typeof tableModule.insertTable === 'function') {
|
|
1510
|
+
tableModule.insertTable(r, c);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
finally {
|
|
1514
|
+
if (document.body.contains(popup)) {
|
|
1515
|
+
document.body.removeChild(popup);
|
|
1516
|
+
}
|
|
1517
|
+
document.removeEventListener('click', onOutsideClick, true);
|
|
1518
|
+
}
|
|
1519
|
+
});
|
|
1520
|
+
grid.appendChild(cell);
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
popup.appendChild(grid);
|
|
1524
|
+
const placePopup = () => {
|
|
1525
|
+
const rect = anchorEl?.getBoundingClientRect();
|
|
1526
|
+
const top = rect ? rect.bottom + window.scrollY + 6 : 100;
|
|
1527
|
+
const left = rect ? rect.left + window.scrollX : 100;
|
|
1528
|
+
popup.style.top = `${top}px`;
|
|
1529
|
+
popup.style.left = `${left}px`;
|
|
1530
|
+
};
|
|
1531
|
+
const onOutsideClick = (ev) => {
|
|
1532
|
+
if (!popup.contains(ev.target)) {
|
|
1533
|
+
if (document.body.contains(popup)) {
|
|
1534
|
+
document.body.removeChild(popup);
|
|
1535
|
+
}
|
|
1536
|
+
document.removeEventListener('click', onOutsideClick, true);
|
|
1537
|
+
}
|
|
1538
|
+
};
|
|
1539
|
+
document.body.appendChild(popup);
|
|
1540
|
+
placePopup();
|
|
1541
|
+
setTimeout(() => document.addEventListener('click', onOutsideClick, true));
|
|
1542
|
+
};
|
|
1543
|
+
const createContextMenuOptionTable = (quill, translate) => {
|
|
1544
|
+
let lastContextIndex = null;
|
|
1545
|
+
const closeAnyMenu = () => {
|
|
1546
|
+
document.querySelectorAll('.manual-table-menu').forEach((el) => el.parentElement?.removeChild(el));
|
|
1547
|
+
};
|
|
1548
|
+
const runWithSelection = (fn) => {
|
|
1549
|
+
try {
|
|
1550
|
+
quill.focus();
|
|
1551
|
+
if (typeof lastContextIndex === 'number') {
|
|
1552
|
+
quill.setSelection(lastContextIndex, 0, 'silent');
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
catch {
|
|
1556
|
+
/* no-op: giữ yên nếu không thể set selection */
|
|
1557
|
+
}
|
|
1558
|
+
fn();
|
|
1559
|
+
};
|
|
1560
|
+
const createMenuItem = (label, onClick) => {
|
|
1561
|
+
const item = document.createElement('div');
|
|
1562
|
+
item.textContent = label;
|
|
1563
|
+
item.style.padding = '6px 12px';
|
|
1564
|
+
item.style.cursor = 'pointer';
|
|
1565
|
+
item.addEventListener('click', () => {
|
|
1566
|
+
runWithSelection(onClick);
|
|
1567
|
+
closeAnyMenu();
|
|
1568
|
+
});
|
|
1569
|
+
item.addEventListener('mouseenter', () => {
|
|
1570
|
+
item.style.background = '#f5f5f5';
|
|
1571
|
+
});
|
|
1572
|
+
item.addEventListener('mouseleave', () => {
|
|
1573
|
+
item.style.background = 'transparent';
|
|
1574
|
+
});
|
|
1575
|
+
return item;
|
|
1576
|
+
};
|
|
1577
|
+
const openContextMenu = (pageX, pageY) => {
|
|
1578
|
+
closeAnyMenu();
|
|
1579
|
+
const menu = document.createElement('div');
|
|
1580
|
+
menu.className = 'manual-table-menu';
|
|
1581
|
+
menu.style.position = 'absolute';
|
|
1582
|
+
menu.style.top = `${pageY}px`;
|
|
1583
|
+
menu.style.left = `${pageX}px`;
|
|
1584
|
+
menu.style.background = '#fff';
|
|
1585
|
+
menu.style.border = '1px solid #ccc';
|
|
1586
|
+
menu.style.borderRadius = '4px';
|
|
1587
|
+
menu.style.boxShadow = '0 4px 12px rgba(0,0,0,0.2)';
|
|
1588
|
+
menu.style.zIndex = '10001';
|
|
1589
|
+
menu.style.padding = '4px';
|
|
1590
|
+
menu.style.minWidth = '180px';
|
|
1591
|
+
const tableModule = quill.getModule('table');
|
|
1592
|
+
const safeCall = (method, ...args) => {
|
|
1593
|
+
if (tableModule && typeof tableModule[method] === 'function') {
|
|
1594
|
+
tableModule[method](...args);
|
|
1595
|
+
}
|
|
1596
|
+
};
|
|
1597
|
+
menu.appendChild(createMenuItem(translate.instant('i18n_add_new_row_above'), () => safeCall('insertRowAbove')));
|
|
1598
|
+
menu.appendChild(createMenuItem(translate.instant('i18n_add_new_row_below'), () => safeCall('insertRowBelow')));
|
|
1599
|
+
menu.appendChild(createMenuItem(translate.instant('i18n_add_new_column_left'), () => safeCall('insertColumnLeft')));
|
|
1600
|
+
menu.appendChild(createMenuItem(translate.instant('i18n_add_new_column_right'), () => safeCall('insertColumnRight')));
|
|
1601
|
+
const divider = document.createElement('div');
|
|
1602
|
+
divider.style.height = '1px';
|
|
1603
|
+
divider.style.background = '#eee';
|
|
1604
|
+
divider.style.margin = '4px 0';
|
|
1605
|
+
menu.appendChild(divider);
|
|
1606
|
+
menu.appendChild(createMenuItem(translate.instant('i18n_delete_row'), () => safeCall('deleteRow')));
|
|
1607
|
+
menu.appendChild(createMenuItem(translate.instant('i18n_delete_column'), () => safeCall('deleteColumn')));
|
|
1608
|
+
menu.appendChild(createMenuItem(translate.instant('i18n_delete_table'), () => safeCall('deleteTable')));
|
|
1609
|
+
document.body.appendChild(menu);
|
|
1610
|
+
const onOutside = (ev) => {
|
|
1611
|
+
if (!menu.contains(ev.target)) {
|
|
1612
|
+
closeAnyMenu();
|
|
1613
|
+
document.removeEventListener('click', onOutside, true);
|
|
1614
|
+
}
|
|
1615
|
+
};
|
|
1616
|
+
setTimeout(() => document.addEventListener('click', onOutside, true));
|
|
1617
|
+
const onScroll = () => {
|
|
1618
|
+
closeAnyMenu();
|
|
1619
|
+
window.removeEventListener('scroll', onScroll, true);
|
|
1620
|
+
window.removeEventListener('resize', onScroll, true);
|
|
1621
|
+
};
|
|
1622
|
+
window.addEventListener('scroll', onScroll, true);
|
|
1623
|
+
window.addEventListener('resize', onScroll, true);
|
|
1624
|
+
};
|
|
1625
|
+
fromEvent(quill.root, 'contextmenu').subscribe((ev) => {
|
|
1626
|
+
const target = ev.target;
|
|
1627
|
+
const isCell = !!target.closest('td,th,table,.ql-table');
|
|
1628
|
+
if (!isCell)
|
|
1629
|
+
return;
|
|
1630
|
+
ev.preventDefault();
|
|
1631
|
+
try {
|
|
1632
|
+
// Ưu tiên lấy index từ blot tương ứng node
|
|
1633
|
+
const QuillAny = Quill2x;
|
|
1634
|
+
const blot = QuillAny?.find?.(target);
|
|
1635
|
+
if (blot && typeof blot.offset === 'function') {
|
|
1636
|
+
lastContextIndex = blot.offset(quill.scroll);
|
|
1637
|
+
}
|
|
1638
|
+
else {
|
|
1639
|
+
// Fallback: đặt selection hiện tại nếu không xác định được
|
|
1640
|
+
const sel = quill.getSelection(true);
|
|
1641
|
+
lastContextIndex = sel ? sel.index : 0;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
catch {
|
|
1645
|
+
const sel = quill.getSelection(true);
|
|
1646
|
+
lastContextIndex = sel ? sel.index : 0;
|
|
1647
|
+
}
|
|
1648
|
+
quill.focus();
|
|
1649
|
+
openContextMenu(ev.pageX, ev.pageY);
|
|
1650
|
+
});
|
|
1651
|
+
};
|
|
1652
|
+
let register = false;
|
|
1653
|
+
const registerQuill2x = () => {
|
|
1654
|
+
if (register)
|
|
1655
|
+
return;
|
|
1656
|
+
register = true;
|
|
1657
|
+
const Quill = Quill2x;
|
|
1658
|
+
const size = Quill.import('attributors/style/size');
|
|
1659
|
+
const alignStyle = Quill.import('attributors/style/align');
|
|
1660
|
+
const italic = Quill.import('formats/italic');
|
|
1661
|
+
const bold = Quill.import('formats/bold');
|
|
1662
|
+
const icons = Quill.import('ui/icons');
|
|
1663
|
+
size.whitelist = fontSizeWhiteList();
|
|
1664
|
+
italic.tagName = 'i';
|
|
1665
|
+
bold.tagName = 'b';
|
|
1666
|
+
Quill.register(bold, true);
|
|
1667
|
+
Quill.register(italic, true);
|
|
1668
|
+
Quill.register(size, true);
|
|
1669
|
+
Quill.register(alignStyle, true);
|
|
1670
|
+
Quill.register(QuillMentionBlot, true);
|
|
1671
|
+
[...iconList()].forEach((element) => set(icons, element.key, `<span class="${element.icon} ${element.key === 'unLink' ? 'hover:text-[#ee2d41] ' : 'hover:text-[var(--libs-ui-color-light-1)]'} text-[16px] text-[#6a7383]"></span>`));
|
|
1672
|
+
};
|
|
1673
|
+
|
|
1674
|
+
class LibsUiComponentsInputsQuill2xComponent {
|
|
1675
|
+
//region Private
|
|
1676
|
+
quill;
|
|
1677
|
+
addEditLinkComponentRef = signal(undefined);
|
|
1678
|
+
uploadImageComponentRef = signal(undefined);
|
|
1679
|
+
handlers = signal({
|
|
1680
|
+
link: this.handleShowUploadLink.bind(this),
|
|
1681
|
+
undo: this.handleUndo.bind(this),
|
|
1682
|
+
redo: this.handleRedo.bind(this),
|
|
1683
|
+
table: this.handleTable.bind(this),
|
|
1684
|
+
image: this.handlerShowUploadImage.bind(this),
|
|
1685
|
+
});
|
|
1686
|
+
timerSetFontSize = signal(undefined);
|
|
1687
|
+
//endregion
|
|
1688
|
+
//region Protected
|
|
1689
|
+
containerToolbarClass = computed(() => this.quillCustomConfig()?.toolbar?.classCustomContainerToolbar || 'border-t border-l border-r border-[#e5e7eb] rounded-t-[4px]');
|
|
1690
|
+
containerEditorClass = computed(() => this.quillCustomConfig()?.editor?.classCustomContainerEditor || '!border !border-[#e5e7eb] !rounded-b-[4px]' + (this.quillCustomConfig()?.toolbar?.hidden ? ' rounded-t-[4px]' : ''));
|
|
1691
|
+
showButtonMoreToolbar = computed(() => this.toolbarOptionsConfig().some((item) => item.display === false));
|
|
1692
|
+
displaySkeletonToolbar = computed(() => this.toolbarOptionsConfig().every((item) => item.display === undefined));
|
|
1693
|
+
labelFontSelectedComputed = computed(() => get(this.fontSelected(), 'item.label') || 'Sans Serif');
|
|
1694
|
+
fontSelected = signal(undefined);
|
|
1695
|
+
listConfigFont = signal(listConfigFont());
|
|
1696
|
+
listConfigHeader = signal(listConfigHeader());
|
|
1697
|
+
headerSelected = signal(undefined);
|
|
1698
|
+
labelHeaderSelectedComputed = computed(() => get(this.headerSelected(), 'item.label') || 'Normal');
|
|
1699
|
+
listConfigAlign = signal(listConfigAlign());
|
|
1700
|
+
alignSelected = signal(undefined);
|
|
1701
|
+
iconAlignSelectedComputed = computed(() => get(this.alignSelected(), 'item.icon'));
|
|
1702
|
+
colorSelected = signal(false);
|
|
1703
|
+
backgroundSelected = signal(false);
|
|
1704
|
+
size = signal({ value: 14 });
|
|
1705
|
+
link = signal(linkDefault());
|
|
1706
|
+
showMoreAction = signal(false);
|
|
1707
|
+
toolbarOptionsConfig = signal([]);
|
|
1708
|
+
loadingUploadImage = signal(false);
|
|
1709
|
+
uploadImageConfig = input(uploadImageConfigDefault(), { transform: (value) => value || uploadImageConfigDefault() });
|
|
1710
|
+
//region Inputs
|
|
1711
|
+
placeholder = input('i18n_import_content', { transform: (value) => value || 'i18n_import_content' });
|
|
1712
|
+
blotsRegister = input();
|
|
1713
|
+
readonly = input(false, { transform: (value) => value ?? false });
|
|
1714
|
+
quillCustomConfig = input();
|
|
1715
|
+
label = input();
|
|
1716
|
+
item = model.required();
|
|
1717
|
+
fieldBind = input.required();
|
|
1718
|
+
autoUpdateValueWhenTextChange = input(true, { transform: (value) => value ?? true });
|
|
1719
|
+
templateToolBarPersonalize = input();
|
|
1720
|
+
zIndex = input(1250, { transform: (value) => value ?? 1250 });
|
|
1721
|
+
ignoreShowPopupEditLink = input();
|
|
1722
|
+
ignoreCommunicateMicroEventPopup = input();
|
|
1723
|
+
handlersExpand = input();
|
|
1724
|
+
//endregion
|
|
1725
|
+
//region Outputs
|
|
1726
|
+
outShowPopupEditLink = output();
|
|
1727
|
+
outMessageError = output();
|
|
1728
|
+
outBlur = output();
|
|
1729
|
+
outFocus = output();
|
|
1730
|
+
outChange = output();
|
|
1731
|
+
outSelectionChange = output();
|
|
1732
|
+
outTextChange = output();
|
|
1733
|
+
outContextMenu = output();
|
|
1734
|
+
outFunctionsControl = output();
|
|
1735
|
+
//endregion
|
|
1736
|
+
//region ViewChild
|
|
1737
|
+
htmlContainer = viewChild.required('htmlContainer');
|
|
1738
|
+
quillBodyContainer = viewChild.required('snowContainer');
|
|
1739
|
+
toolbarContainer = viewChild.required('toolbarContainer');
|
|
1740
|
+
inputSizeRef = viewChild.required('inputSizeRef');
|
|
1741
|
+
inputLinkRef = viewChild.required('inputLinkRef');
|
|
1742
|
+
//endregion
|
|
1743
|
+
//region Inject
|
|
1744
|
+
destroyRef = inject(DestroyRef);
|
|
1745
|
+
notificationService = inject(LibsUiNotificationService);
|
|
1746
|
+
translate = inject(TranslateService);
|
|
1747
|
+
cdr = inject(ChangeDetectorRef);
|
|
1748
|
+
dynamicComponentService = inject(LibsUiDynamicComponentService);
|
|
1749
|
+
//endregion
|
|
1750
|
+
ngOnInit() {
|
|
1751
|
+
const type = this.quillCustomConfig()?.toolbar?.type || 'default';
|
|
1752
|
+
const hasIconImage = this.uploadImageConfig().showIcon ?? false;
|
|
1753
|
+
const hasIconPersonalize = !!this.templateToolBarPersonalize();
|
|
1754
|
+
this.toolbarOptionsConfig.set(this.quillCustomConfig()?.toolbar?.options || [...toolBarOptions(type, hasIconImage, hasIconPersonalize)]);
|
|
1755
|
+
this.calculatorToolbar();
|
|
1756
|
+
registerQuill2x();
|
|
1757
|
+
this.blotsRegister()?.forEach((item) => {
|
|
1758
|
+
Quill2x.register(item.component, true);
|
|
1759
|
+
});
|
|
1760
|
+
this.updateHandlerFunction();
|
|
1761
|
+
const options = {
|
|
1762
|
+
theme: 'snow',
|
|
1763
|
+
placeholder: this.translate.instant(this.placeholder()),
|
|
1764
|
+
readOnly: this.readonly(),
|
|
1765
|
+
modules: {
|
|
1766
|
+
toolbar: {
|
|
1767
|
+
container: this.toolbarContainer().nativeElement,
|
|
1768
|
+
handlers: this.handlers(),
|
|
1769
|
+
},
|
|
1770
|
+
table: true,
|
|
1771
|
+
clipboard: {
|
|
1772
|
+
matchers: [[Node.TEXT_NODE, (node) => new Delta().insert(node.data)]],
|
|
1773
|
+
},
|
|
1774
|
+
keyboard: {
|
|
1775
|
+
bindings: {
|
|
1776
|
+
backspace: {
|
|
1777
|
+
key: UtilsKeyCodeConstant.BACKSPACE,
|
|
1778
|
+
handler: (range) => this.noPreventEmbedDeletion(range),
|
|
1779
|
+
},
|
|
1780
|
+
delete: {
|
|
1781
|
+
key: UtilsKeyCodeConstant.DELETE,
|
|
1782
|
+
handler: (range) => this.noPreventEmbedDeletion(range),
|
|
1783
|
+
},
|
|
1784
|
+
},
|
|
1785
|
+
},
|
|
1786
|
+
history: {
|
|
1787
|
+
delay: 2000,
|
|
1788
|
+
maxStack: 500,
|
|
1789
|
+
userOnly: true,
|
|
1790
|
+
},
|
|
1791
|
+
},
|
|
1792
|
+
};
|
|
1793
|
+
this.quill = new Quill2x(this.quillBodyContainer().nativeElement, options);
|
|
1794
|
+
fromEvent(this.quillBodyContainer()?.nativeElement, 'contextmenu')
|
|
1795
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
1796
|
+
.subscribe((e) => this.outContextMenu.emit(e));
|
|
1797
|
+
fromEvent(window, 'resize').pipe(takeUntilDestroyed(this.destroyRef)).subscribe(this.calculatorToolbar.bind(this));
|
|
1798
|
+
this.setContent(this.item()[this.fieldBind()]);
|
|
1799
|
+
this.outFunctionsControl.emit(this.FunctionsControl);
|
|
1800
|
+
createContextMenuOptionTable(this.quill, this.translate);
|
|
1801
|
+
this.setStyleForContent();
|
|
1802
|
+
this.handlerTextChange();
|
|
1803
|
+
this.handlerSelectionChange();
|
|
1804
|
+
this.handlerPaste();
|
|
1805
|
+
}
|
|
1806
|
+
get FunctionsControl() {
|
|
1807
|
+
return {
|
|
1808
|
+
quill: () => this.quill,
|
|
1809
|
+
};
|
|
1810
|
+
}
|
|
1811
|
+
//region handler Event HTML
|
|
1812
|
+
handlerChangeShowMoreAction(event) {
|
|
1813
|
+
event.stopPropagation();
|
|
1814
|
+
this.showMoreAction.update((showMoreAction) => !showMoreAction);
|
|
1815
|
+
}
|
|
1816
|
+
handleSelectFont(event) {
|
|
1817
|
+
this.fontSelected.set(event);
|
|
1818
|
+
this.quill?.format('font', event?.key);
|
|
1819
|
+
}
|
|
1820
|
+
handleSelectHeader(event) {
|
|
1821
|
+
this.headerSelected.set(event);
|
|
1822
|
+
this.quill?.format('header', event?.key);
|
|
1823
|
+
}
|
|
1824
|
+
handlerValueChangeFontSize(value) {
|
|
1825
|
+
clearTimeout(this.timerSetFontSize());
|
|
1826
|
+
this.timerSetFontSize.set(setTimeout(() => {
|
|
1827
|
+
this.size.update((item) => ({ ...item, value: value }));
|
|
1828
|
+
this.quill?.format('size', `${this.size().value}px`);
|
|
1829
|
+
this.quill?.blur();
|
|
1830
|
+
this.inputSizeRef()?.FunctionsControl?.focus?.();
|
|
1831
|
+
}, 400));
|
|
1832
|
+
}
|
|
1833
|
+
handleSelectAlign(event) {
|
|
1834
|
+
this.alignSelected.set(event);
|
|
1835
|
+
this.quill?.format('align', event?.key);
|
|
1836
|
+
}
|
|
1837
|
+
handlerSetFormat(type, data) {
|
|
1838
|
+
this.quill?.format(type, data);
|
|
1839
|
+
}
|
|
1840
|
+
handlerInsertEmoji(emoji) {
|
|
1841
|
+
this.insertText(emoji, undefined, true);
|
|
1842
|
+
}
|
|
1843
|
+
//endregion
|
|
1844
|
+
//region Private Method
|
|
1845
|
+
//region Quill Methods
|
|
1846
|
+
handleTable() {
|
|
1847
|
+
const button = this.htmlContainer().nativeElement.querySelector?.('button.ql-table');
|
|
1848
|
+
createTableSelector(this.quill, button, this.translate);
|
|
1849
|
+
}
|
|
1850
|
+
handleUndo() {
|
|
1851
|
+
this.quill?.history?.undo();
|
|
1852
|
+
}
|
|
1853
|
+
handleRedo() {
|
|
1854
|
+
this.quill?.history?.redo();
|
|
1855
|
+
}
|
|
1856
|
+
handlerShowUploadImage() {
|
|
1857
|
+
if (this.uploadImageConfig().modeCustom) {
|
|
1858
|
+
this.uploadImageComponentRef.set(this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsInputsQuillUploadImageComponent));
|
|
1859
|
+
const instance = this.uploadImageComponentRef()?.instance;
|
|
1860
|
+
this.uploadImageComponentRef()?.setInput('uploadImageConfig', this.uploadImageConfig());
|
|
1861
|
+
this.uploadImageComponentRef()?.setInput('ignoreCommunicateMicroEvent', this.ignoreCommunicateMicroEventPopup());
|
|
1862
|
+
instance?.outClose.subscribe((link) => {
|
|
1863
|
+
this.dynamicComponentService.remove(this.uploadImageComponentRef());
|
|
1864
|
+
if (link) {
|
|
1865
|
+
this.insertImage(link);
|
|
1866
|
+
}
|
|
1867
|
+
});
|
|
1868
|
+
this.dynamicComponentService.addToBody(this.uploadImageComponentRef());
|
|
1869
|
+
return;
|
|
1870
|
+
}
|
|
1871
|
+
const input = document.createElement('input');
|
|
1872
|
+
input.setAttribute('type', 'file');
|
|
1873
|
+
input.setAttribute('accept', 'image/*');
|
|
1874
|
+
input.click();
|
|
1875
|
+
input.onchange = async () => {
|
|
1876
|
+
await this.uploadImagesAndInsert(input?.files);
|
|
1877
|
+
};
|
|
1878
|
+
}
|
|
1879
|
+
async insertText(content, index, focusLast) {
|
|
1880
|
+
index = index ?? this.quill?.getSelection(true).index;
|
|
1881
|
+
if (!isNil(index)) {
|
|
1882
|
+
this.quill?.insertText(index, content, Quill2x.sources.USER);
|
|
1883
|
+
if (focusLast) {
|
|
1884
|
+
await lastValueFrom(timer(0));
|
|
1885
|
+
this.quill?.setSelection(index + content.length, 0, Quill2x.sources.USER);
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
handlerSelectionChange() {
|
|
1890
|
+
this.quill?.on('selection-change', (range, oldRange, source) => {
|
|
1891
|
+
if (this.readonly()) {
|
|
1892
|
+
return;
|
|
1893
|
+
}
|
|
1894
|
+
if (range === null && oldRange !== null) {
|
|
1895
|
+
this.outBlur.emit();
|
|
1896
|
+
return;
|
|
1897
|
+
}
|
|
1898
|
+
if (range !== null && oldRange === null) {
|
|
1899
|
+
this.outFocus.emit();
|
|
1900
|
+
return;
|
|
1901
|
+
}
|
|
1902
|
+
const format = this.quill?.getFormat();
|
|
1903
|
+
if (format) {
|
|
1904
|
+
this.setFontSizeSelected(format);
|
|
1905
|
+
this.setFontSelected(format);
|
|
1906
|
+
this.setColorSelected(format);
|
|
1907
|
+
}
|
|
1908
|
+
this.outSelectionChange.emit({
|
|
1909
|
+
quill: this.quill,
|
|
1910
|
+
range,
|
|
1911
|
+
oldRange,
|
|
1912
|
+
source,
|
|
1913
|
+
});
|
|
1914
|
+
if (range.length !== 0 || !format?.link || source !== 'user') {
|
|
1915
|
+
return;
|
|
1916
|
+
}
|
|
1917
|
+
const selection = document.getSelection();
|
|
1918
|
+
const anchorNode = selection?.anchorNode;
|
|
1919
|
+
let linkNode = anchorNode;
|
|
1920
|
+
while (linkNode && linkNode.tagName !== 'A') {
|
|
1921
|
+
linkNode = linkNode.parentNode;
|
|
1922
|
+
}
|
|
1923
|
+
if (!linkNode || linkNode.tagName !== 'A') {
|
|
1924
|
+
return;
|
|
1925
|
+
}
|
|
1926
|
+
const linkText = linkNode.innerText;
|
|
1927
|
+
const linksIndices = [];
|
|
1928
|
+
let indexReturn = -1;
|
|
1929
|
+
while (!isNil(indexReturn) && indexReturn < range.index) {
|
|
1930
|
+
const textContent = this.quill?.getText();
|
|
1931
|
+
const linkIndex = textContent?.indexOf(linkText, linksIndices.length > 0 ? linksIndices[linksIndices.length - 1] + linkText.length : 0);
|
|
1932
|
+
if (!isNil(linkIndex)) {
|
|
1933
|
+
if (linkIndex !== -1) {
|
|
1934
|
+
linksIndices.push(linkIndex);
|
|
1935
|
+
indexReturn = linkIndex + linkText.length;
|
|
1936
|
+
}
|
|
1937
|
+
if (linkIndex === -1) {
|
|
1938
|
+
indexReturn = undefined;
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
if (linksIndices && linksIndices.length) {
|
|
1943
|
+
const rangeIndex = linksIndices[linksIndices.length - 1];
|
|
1944
|
+
const countImage = this.adjustIndexForImages(rangeIndex);
|
|
1945
|
+
setTimeout(() => {
|
|
1946
|
+
this.link.set({
|
|
1947
|
+
title: linkText,
|
|
1948
|
+
url: linkNode.href,
|
|
1949
|
+
range: {
|
|
1950
|
+
index: rangeIndex + countImage,
|
|
1951
|
+
length: linkText.length,
|
|
1952
|
+
},
|
|
1953
|
+
});
|
|
1954
|
+
this.inputLinkRef().FunctionsControl?.showPopover(linkNode);
|
|
1955
|
+
});
|
|
1956
|
+
}
|
|
1957
|
+
});
|
|
1958
|
+
}
|
|
1959
|
+
handlerPaste() {
|
|
1960
|
+
set(this.quill, 'root.onpaste', async (event) => {
|
|
1961
|
+
if (!event || !event.clipboardData) {
|
|
1962
|
+
return;
|
|
1963
|
+
}
|
|
1964
|
+
const files = event.clipboardData.files;
|
|
1965
|
+
if (!files.length) {
|
|
1966
|
+
if (event.clipboardData.getData('text')) {
|
|
1967
|
+
this.scrollToSelectionWithElementScrollHeightAuto();
|
|
1968
|
+
}
|
|
1969
|
+
return;
|
|
1970
|
+
}
|
|
1971
|
+
event.preventDefault();
|
|
1972
|
+
await this.uploadImagesAndInsert(files);
|
|
1973
|
+
});
|
|
1974
|
+
}
|
|
1975
|
+
handlerTextChange() {
|
|
1976
|
+
this.quill?.on('text-change', (event) => {
|
|
1977
|
+
this.outTextChange.emit({
|
|
1978
|
+
quill: this.quill,
|
|
1979
|
+
delta: event,
|
|
1980
|
+
});
|
|
1981
|
+
setTimeout(() => {
|
|
1982
|
+
if (event?.ops[1]?.insert === '\n') {
|
|
1983
|
+
const range = { index: event?.ops[0].retain };
|
|
1984
|
+
const currentLeaf = this.quill?.getLeaf(range.index)[0];
|
|
1985
|
+
const nextLeaf = this.quill?.getLeaf(range.index + 1)[0];
|
|
1986
|
+
this.quill?.insertEmbed(range.index, 'break', true, 'user');
|
|
1987
|
+
if (nextLeaf === null || currentLeaf.parent !== nextLeaf.parent) {
|
|
1988
|
+
this.quill?.insertEmbed(range.index, 'break', true, 'user');
|
|
1989
|
+
}
|
|
1990
|
+
this.quill?.setSelection((range.index || 0) + 1, 0, Quill2x.sources.SILENT);
|
|
1991
|
+
}
|
|
1992
|
+
});
|
|
1993
|
+
if (!this.autoUpdateValueWhenTextChange()) {
|
|
1994
|
+
return;
|
|
1995
|
+
}
|
|
1996
|
+
// this.updateValueByRootQuillHtml();
|
|
1997
|
+
});
|
|
1998
|
+
}
|
|
1999
|
+
//endregion
|
|
2000
|
+
updateHandlerFunction() {
|
|
2001
|
+
const handlersExpand = this.handlersExpand();
|
|
2002
|
+
if (handlersExpand && handlersExpand.length) {
|
|
2003
|
+
handlersExpand.forEach((element) => {
|
|
2004
|
+
if (element.title && element.action) {
|
|
2005
|
+
this.handlers.update((item) => ({ ...item, [element.title]: element.action }));
|
|
2006
|
+
}
|
|
2007
|
+
});
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
noPreventEmbedDeletion(range) {
|
|
2011
|
+
if (!this.quill)
|
|
2012
|
+
return false;
|
|
2013
|
+
const delta = this.quill?.getContents(range.index, 1);
|
|
2014
|
+
if (delta?.ops.some((option) => this.blotsRegister()?.find((item) => get(option.insert, item.component['blotName']) && item.ignoreDelete))) {
|
|
2015
|
+
return false; // Ngăn không cho Quill xử lý xóa
|
|
2016
|
+
}
|
|
2017
|
+
return true;
|
|
2018
|
+
}
|
|
2019
|
+
setFontSizeSelected(format) {
|
|
2020
|
+
const fontSize = format?.size?.toString()?.replace('px', '');
|
|
2021
|
+
if (isNaN(parseFloat(fontSize))) {
|
|
2022
|
+
this.size.set({ value: 14 });
|
|
2023
|
+
return;
|
|
2024
|
+
}
|
|
2025
|
+
this.size.set({ value: parseFloat(fontSize) });
|
|
2026
|
+
}
|
|
2027
|
+
setFontSelected(format) {
|
|
2028
|
+
const font = listFont().find((item) => item.key === format.font);
|
|
2029
|
+
if (!font) {
|
|
2030
|
+
this.fontSelected.set({ key: '', item: listFont().find((item) => item.key === '') });
|
|
2031
|
+
return;
|
|
2032
|
+
}
|
|
2033
|
+
this.fontSelected.set({ key: format.font, item: font });
|
|
2034
|
+
}
|
|
2035
|
+
setColorSelected(format) {
|
|
2036
|
+
this.colorSelected.set(isTruthy(format?.color));
|
|
2037
|
+
this.backgroundSelected.set(isTruthy(format?.background));
|
|
2038
|
+
}
|
|
2039
|
+
async calculatorToolbar() {
|
|
2040
|
+
this.cdr.detectChanges();
|
|
2041
|
+
const toolbarWidth = this.toolbarContainer().nativeElement.offsetWidth || 0;
|
|
2042
|
+
let totalWidth = 84;
|
|
2043
|
+
this.toolbarOptionsConfig.update((configs) => {
|
|
2044
|
+
configs.forEach((item, index) => {
|
|
2045
|
+
item.display = true;
|
|
2046
|
+
totalWidth += item.width;
|
|
2047
|
+
if (item.type === 'line') {
|
|
2048
|
+
const nextItemWidth = totalWidth + this.toolbarOptionsConfig()[+index + 1].width;
|
|
2049
|
+
const preItem = this.toolbarOptionsConfig()[+index - 1];
|
|
2050
|
+
if (nextItemWidth > toolbarWidth && preItem.display === true) {
|
|
2051
|
+
item.display = undefined;
|
|
2052
|
+
return;
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
if (totalWidth > toolbarWidth) {
|
|
2056
|
+
item.display = false;
|
|
2057
|
+
return;
|
|
2058
|
+
}
|
|
2059
|
+
});
|
|
2060
|
+
return [...configs];
|
|
2061
|
+
});
|
|
2062
|
+
this.cdr.detectChanges();
|
|
2063
|
+
}
|
|
2064
|
+
setStyleForContent() {
|
|
2065
|
+
const styleArray = [
|
|
2066
|
+
{ selector: '.ql-font-Arial', style: 'font-family: Arial' },
|
|
2067
|
+
{ selector: '.ql-font-sans-serif', style: 'font-family: sans-serif' },
|
|
2068
|
+
{ selector: '.ql-font-serif', style: 'font-family: serif' },
|
|
2069
|
+
{ selector: '.ql-font-monospace', style: 'font-family: monospace' },
|
|
2070
|
+
{ selector: '.ql-font-Helvetica', style: 'font-family: Helvetica' },
|
|
2071
|
+
{ selector: '.libs-ui-quill-format-image', style: 'max-width: 100%; height: auto', overrideStyle: true },
|
|
2072
|
+
{ selector: '.libs-ui-quill-mention', style: 'font-weight: 600;-moz-osx-font-smoothing: grayscale;-webkit-font-smoothing: antialiased; color: #7239EA', overrideStyle: true },
|
|
2073
|
+
{ selector: 'blockquote', style: 'border-left: 4px solid #ccc; margin-bottom: 5px; margin-top: 5px; padding-left: 16px', overrideStyle: true },
|
|
2074
|
+
];
|
|
2075
|
+
this.blotsRegister()?.forEach((item) => {
|
|
2076
|
+
styleArray.push({ selector: `.${item.className}`, style: item.style, overrideStyle: true });
|
|
2077
|
+
});
|
|
2078
|
+
styleArray.forEach((item) => {
|
|
2079
|
+
const elements = this.quill?.root.querySelectorAll(item.selector);
|
|
2080
|
+
elements?.forEach((element) => {
|
|
2081
|
+
if (item.overrideStyle) {
|
|
2082
|
+
element.setAttribute('style', item.style);
|
|
2083
|
+
return;
|
|
2084
|
+
}
|
|
2085
|
+
// Fixbug issue: https://admin-cv.mobio.vn/issues/49092
|
|
2086
|
+
let styleExist = element.getAttribute('style');
|
|
2087
|
+
if (styleExist) {
|
|
2088
|
+
['font-family: Arial', 'font-family: sans-serif', 'font-family: serif', 'font-family: monospace', 'font-family: Helvetica'].forEach((font) => {
|
|
2089
|
+
styleExist = (styleExist?.includes(`${font};`) ? styleExist?.replace(`${font};`, '') : styleExist?.replace(font, ''));
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
element.setAttribute('style', styleExist ? `${styleExist}${styleExist[styleExist.length - 1] === ';' ? '' : ';'}${item.style};` : item.style);
|
|
2093
|
+
});
|
|
2094
|
+
});
|
|
2095
|
+
}
|
|
2096
|
+
async setContent(content) {
|
|
2097
|
+
if (!this.quill) {
|
|
2098
|
+
return;
|
|
2099
|
+
}
|
|
2100
|
+
const contentXssFilter = await xssFilter(this.removeUnwantedPart(content || ''));
|
|
2101
|
+
this.quill.clipboard.dangerouslyPasteHTML(contentXssFilter);
|
|
2102
|
+
}
|
|
2103
|
+
adjustIndexForImages(index) {
|
|
2104
|
+
const content = this.quill?.root;
|
|
2105
|
+
let imageCount = 0;
|
|
2106
|
+
let adjustedIndex = 0;
|
|
2107
|
+
const adjustTextIndex = (node) => {
|
|
2108
|
+
if (adjustedIndex > index) {
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
2111
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
2112
|
+
adjustedIndex += node.textContent?.length || 0;
|
|
2113
|
+
return;
|
|
2114
|
+
}
|
|
2115
|
+
if (node.nodeType === Node.ELEMENT_NODE && node.nodeName === 'IMG') {
|
|
2116
|
+
if (adjustedIndex <= index) {
|
|
2117
|
+
imageCount++;
|
|
2118
|
+
}
|
|
2119
|
+
return;
|
|
2120
|
+
}
|
|
2121
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
2122
|
+
Array.from(node.childNodes).forEach(adjustTextIndex);
|
|
2123
|
+
}
|
|
2124
|
+
};
|
|
2125
|
+
adjustTextIndex(content);
|
|
2126
|
+
return imageCount;
|
|
2127
|
+
}
|
|
2128
|
+
async uploadImagesAndInsert(files) {
|
|
2129
|
+
if (!files) {
|
|
2130
|
+
return;
|
|
2131
|
+
}
|
|
2132
|
+
const maxImageSize = this.uploadImageConfig()?.maxImageSize || 5 * 1024 * 1024;
|
|
2133
|
+
const images = Array.from(files).filter((file) => file && file.type.split('/')[0] === 'image' && (!this.uploadImageConfig().maxImageSize || file.size <= maxImageSize));
|
|
2134
|
+
if (!images.length) {
|
|
2135
|
+
this.notificationService.showCompTypeTextWarning(this.translate.instant('i18n_note_upload_image_volume', { value: getLabelBySizeFile(maxImageSize) }), { timeRemove: 8000 });
|
|
2136
|
+
return;
|
|
2137
|
+
}
|
|
2138
|
+
try {
|
|
2139
|
+
this.loadingUploadImage.set(true);
|
|
2140
|
+
const indexInsert = this.quill?.getSelection(true).index;
|
|
2141
|
+
const links = await this.uploadImageConfig().functionUploadImage?.(images);
|
|
2142
|
+
if (!links?.length) {
|
|
2143
|
+
return;
|
|
2144
|
+
}
|
|
2145
|
+
links.forEach((link) => {
|
|
2146
|
+
if (!link || (this.uploadImageConfig().onlyAcceptImageHttpsLink && (link instanceof ArrayBuffer || !new RegExp(patternUrl()).test(link)))) {
|
|
2147
|
+
return;
|
|
2148
|
+
}
|
|
2149
|
+
this.insertImage(link, indexInsert);
|
|
2150
|
+
});
|
|
2151
|
+
this.scrollToSelectionWithElementScrollHeightAuto(indexInsert);
|
|
2152
|
+
}
|
|
2153
|
+
catch (error) {
|
|
2154
|
+
console.error(error);
|
|
2155
|
+
}
|
|
2156
|
+
finally {
|
|
2157
|
+
this.loadingUploadImage.set(false);
|
|
2158
|
+
}
|
|
2159
|
+
return;
|
|
2160
|
+
}
|
|
2161
|
+
scrollToSelectionWithElementScrollHeightAuto(index) {
|
|
2162
|
+
// clearTimeout(this.timeoutScrollToSelectionWithElementScrollHeightAuto());
|
|
2163
|
+
// if (!this.elementScrollHeightAuto()) {
|
|
2164
|
+
// return;
|
|
2165
|
+
// }
|
|
2166
|
+
// this.timeoutScrollToSelectionWithElementScrollHeightAuto.set(
|
|
2167
|
+
// setTimeout(() => {
|
|
2168
|
+
// index = index ?? this.quill?.getSelection(true).index;
|
|
2169
|
+
// if (!isNil(index)) {
|
|
2170
|
+
// const bounds = this.quill?.getBounds(index, 1);
|
|
2171
|
+
// this.elementScrollHeightAuto()?.scrollTo(0, (bounds?.top || 0) - 20);
|
|
2172
|
+
// }
|
|
2173
|
+
// }, 100)
|
|
2174
|
+
// );
|
|
2175
|
+
}
|
|
2176
|
+
async insertImage(content, index) {
|
|
2177
|
+
const selection = index ?? this.quill?.getSelection(true).index;
|
|
2178
|
+
if (!isNil(selection)) {
|
|
2179
|
+
this.quill?.insertEmbed(selection, 'image', content);
|
|
2180
|
+
this.quill?.setSelection(selection + 1, 0);
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
handlerPopoverEvent(event) {
|
|
2184
|
+
setTimeout(() => {
|
|
2185
|
+
if (event === 'remove') {
|
|
2186
|
+
this.link.set(linkDefault());
|
|
2187
|
+
}
|
|
2188
|
+
}, 100);
|
|
2189
|
+
}
|
|
2190
|
+
async insertLink(text, url, index) {
|
|
2191
|
+
const selection = this.quill?.getSelection(true);
|
|
2192
|
+
const indexInsert = index ?? selection?.index;
|
|
2193
|
+
if (selection?.length) {
|
|
2194
|
+
this.quill?.deleteText(selection.index, selection.length, Quill.sources.USER);
|
|
2195
|
+
}
|
|
2196
|
+
if (!isNil(indexInsert)) {
|
|
2197
|
+
this.quill?.insertText(indexInsert, text, 'link', url);
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
handlerEditLink(event) {
|
|
2201
|
+
event.stopPropagation();
|
|
2202
|
+
const link = this.link();
|
|
2203
|
+
if (this.ignoreShowPopupEditLink()) {
|
|
2204
|
+
this.outShowPopupEditLink.emit({
|
|
2205
|
+
dataLink: link,
|
|
2206
|
+
callback: async (linkEdit) => {
|
|
2207
|
+
if (link instanceof Object && link.url) {
|
|
2208
|
+
this.quill?.deleteText(link.range.index, link.range.length, Quill.sources.USER);
|
|
2209
|
+
this.quill?.insertText(link.range.index, linkEdit.title, 'link', linkEdit.link);
|
|
2210
|
+
return;
|
|
2211
|
+
}
|
|
2212
|
+
this.insertLink(linkEdit.title, linkEdit.link);
|
|
2213
|
+
},
|
|
2214
|
+
});
|
|
2215
|
+
return;
|
|
2216
|
+
}
|
|
2217
|
+
this.handleShowUploadLink(link);
|
|
2218
|
+
this.inputLinkRef().FunctionsControl?.removePopoverOverlay();
|
|
2219
|
+
}
|
|
2220
|
+
handleShowUploadLink(event) {
|
|
2221
|
+
this.addEditLinkComponentRef.set(this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsInputsQuillLinkComponent));
|
|
2222
|
+
const instance = this.addEditLinkComponentRef()?.instance;
|
|
2223
|
+
const selection = this.quill?.getSelection();
|
|
2224
|
+
const textSelected = selection?.length ? this.quill?.getText(selection?.index, selection?.length) : '';
|
|
2225
|
+
const data = event;
|
|
2226
|
+
this.addEditLinkComponentRef()?.setInput('zIndex', this.zIndex());
|
|
2227
|
+
this.addEditLinkComponentRef()?.setInput('title', data?.title || textSelected);
|
|
2228
|
+
this.addEditLinkComponentRef()?.setInput('link', data?.url || '');
|
|
2229
|
+
this.addEditLinkComponentRef()?.setInput('ignoreCommunicateMicroEvent', this.ignoreCommunicateMicroEventPopup());
|
|
2230
|
+
instance?.outSaveLink.subscribe((item) => {
|
|
2231
|
+
if (data instanceof Object && data.url) {
|
|
2232
|
+
this.quill?.deleteText(data.range.index, data.range.length, Quill.sources.USER);
|
|
2233
|
+
this.quill?.insertText(data.range.index, item.title, 'link', item.link);
|
|
2234
|
+
return;
|
|
2235
|
+
}
|
|
2236
|
+
this.insertLink(item.title, item.link);
|
|
2237
|
+
});
|
|
2238
|
+
instance?.outClose.subscribe(() => this.dynamicComponentService.remove(this.addEditLinkComponentRef()));
|
|
2239
|
+
this.dynamicComponentService.addToBody(this.addEditLinkComponentRef());
|
|
2240
|
+
}
|
|
2241
|
+
handlerUnlink(event) {
|
|
2242
|
+
event.stopPropagation();
|
|
2243
|
+
const link = this.link();
|
|
2244
|
+
console.log('handlerUnlink', link);
|
|
2245
|
+
this.quill?.formatText(link.range.index, link.range.length, { link: false });
|
|
2246
|
+
this.inputLinkRef().FunctionsControl?.removePopoverOverlay();
|
|
2247
|
+
}
|
|
2248
|
+
handlerUnInsertLink() {
|
|
2249
|
+
console.log('handlerUnInsertLink');
|
|
2250
|
+
const selection = this.quill?.getSelection(true);
|
|
2251
|
+
if (!isNil(selection)) {
|
|
2252
|
+
this.quill?.formatText(selection, 'link', false);
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
removeUnwantedPart(html) {
|
|
2256
|
+
if (!html) {
|
|
2257
|
+
return '';
|
|
2258
|
+
}
|
|
2259
|
+
return html
|
|
2260
|
+
.replace(/^\s*<p><br><\/p>/, '')
|
|
2261
|
+
.replace(/<div><br><\/div>/gi, '')
|
|
2262
|
+
.replace(/[\u200B-\u200D\uFEFF]/g, '');
|
|
2263
|
+
}
|
|
2264
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsInputsQuill2xComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2265
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LibsUiComponentsInputsQuill2xComponent, isStandalone: true, selector: "libs_ui-components-inputs-quill2x", inputs: { uploadImageConfig: { classPropertyName: "uploadImageConfig", publicName: "uploadImageConfig", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, blotsRegister: { classPropertyName: "blotsRegister", publicName: "blotsRegister", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, quillCustomConfig: { classPropertyName: "quillCustomConfig", publicName: "quillCustomConfig", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, fieldBind: { classPropertyName: "fieldBind", publicName: "fieldBind", isSignal: true, isRequired: true, transformFunction: null }, autoUpdateValueWhenTextChange: { classPropertyName: "autoUpdateValueWhenTextChange", publicName: "autoUpdateValueWhenTextChange", isSignal: true, isRequired: false, transformFunction: null }, templateToolBarPersonalize: { classPropertyName: "templateToolBarPersonalize", publicName: "templateToolBarPersonalize", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, ignoreShowPopupEditLink: { classPropertyName: "ignoreShowPopupEditLink", publicName: "ignoreShowPopupEditLink", isSignal: true, isRequired: false, transformFunction: null }, ignoreCommunicateMicroEventPopup: { classPropertyName: "ignoreCommunicateMicroEventPopup", publicName: "ignoreCommunicateMicroEventPopup", isSignal: true, isRequired: false, transformFunction: null }, handlersExpand: { classPropertyName: "handlersExpand", publicName: "handlersExpand", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { item: "itemChange", outShowPopupEditLink: "outShowPopupEditLink", outMessageError: "outMessageError", outBlur: "outBlur", outFocus: "outFocus", outChange: "outChange", outSelectionChange: "outSelectionChange", outTextChange: "outTextChange", outContextMenu: "outContextMenu", outFunctionsControl: "outFunctionsControl" }, viewQueries: [{ propertyName: "htmlContainer", first: true, predicate: ["htmlContainer"], descendants: true, isSignal: true }, { propertyName: "quillBodyContainer", first: true, predicate: ["snowContainer"], descendants: true, isSignal: true }, { propertyName: "toolbarContainer", first: true, predicate: ["toolbarContainer"], descendants: true, isSignal: true }, { propertyName: "inputSizeRef", first: true, predicate: ["inputSizeRef"], descendants: true, isSignal: true }, { propertyName: "inputLinkRef", first: true, predicate: ["inputLinkRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #htmlContainer\n class=\"quill-container\">\n @if (label(); as label) {\n <libs_ui-components-label\n [classInclude]=\"label.classInclude\"\n [required]=\"label.required\"\n [labelLeft]=\"label.labelLeft\" />\n }\n <div\n #toolbarContainer\n class=\"relative h-[44px]\">\n <ng-container *ngTemplateOutlet=\"toolbarTemplate\" />\n </div>\n <div\n #snowContainer\n LibsUiComponentsScrollOverlayDirective\n [class]=\"containerEditorClass()\"></div>\n</div>\n\n<ng-template #toolbarTemplate>\n <div\n [class]=\"containerToolbarClass()\"\n #toolbarItems>\n @if (displaySkeletonToolbar()) {\n <libs_ui-components-skeleton\n class=\"w-full h-full\"\n [config]=\"{\n rows: [\n {\n item: { classIncludeItem: '!rounded-none' },\n },\n ],\n }\" />\n }\n <div class=\"ql-formats items-center px-[16px] py-[4px] !flex\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"!option.display\"\n [class.flex]=\"option.display\">\n <ng-container *ngTemplateOutlet=\"itemToolbarTemplate; context: { option, $index, $last }\" />\n </div>\n }\n <div class=\"relative\">\n @if (showButtonMoreToolbar()) {\n <libs_ui-components-buttons-button\n [type]=\"showMoreAction() ? 'button-secondary' : 'button-third'\"\n [iconOnlyType]=\"true\"\n [classInclude]=\"'!p-[1px] !h-[20px] ml-[8px]'\"\n [classIconLeft]=\"'libs-ui-icon-move-right rotate-90'\"\n (outClick)=\"handlerChangeShowMoreAction($event)\" />\n }\n <!-- Build toolbar khi click xem th\u00EAm-->\n <div\n [class.hidden]=\"!showMoreAction()\"\n class=\"absolute bg-[#ffffff] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] z-[1] flex items-center pl-[8px] pr-[16px] py-[4px] rounded-[8px] top-[31px] right-[0px]\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"option.display !== false\"\n [class.flex]=\"option.display === false\">\n <ng-container *ngTemplateOutlet=\"itemToolbarTemplate; context: { option, $index, $last }\" />\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template\n #itemToolbarTemplate\n let-$index=\"$index\"\n let-$last=\"$last\"\n let-option=\"option\">\n @if (option.type === 'undo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_undo', zIndex: zIndex() }\"\n class=\"ql-undo\"></button>\n </div>\n }\n @if (option.type === 'redo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_redo', zIndex: zIndex() }\"\n class=\"ql-redo\"></button>\n </div>\n }\n @if (option.type === 'fontFamily') {\n <div\n class=\"relative w-[132px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigFont()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectFont($event)\">\n @if (fontSelected(); as fontSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px]\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelFontSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'header') {\n <div\n class=\"relative w-[138px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigHeader()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectHeader($event)\">\n @if (headerSelected(); as headerSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px] {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelHeaderSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'fontSize') {\n <div class=\" {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-inputs-valid\n #inputSizeRef\n [dataType]=\"'int'\"\n [(item)]=\"size\"\n [fieldNameBind]=\"'value'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"72\"\n [minValueNumber]=\"8\"\n [readonly]=\"readonly() || loadingUploadImage()\"\n [classContainerInput]=\"'w-[72px] h-[32px]'\"\n (outValueChange)=\"handlerValueChangeFontSize($event)\" />\n </div>\n }\n @if (option.type === 'color') {\n <div class=\"ql-color ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_text_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n [applyNow]=\"false\"\n (outColorChange)=\"handlerSetFormat('color', $event)\">\n <div\n class=\"libs-ui-icon-editor-color-text libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"\n [class.text-[var(--libs-ui-color-light-1)]]=\"colorSelected()\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'background') {\n <div class=\"ql-background ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_background_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [applyNow]=\"false\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n (outColorChange)=\"handlerSetFormat('background', $event)\">\n <div\n class=\"libs-ui-icon-editor-color-background libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"\n [class.text-[var(--libs-ui-color-light-1)]]=\"backgroundSelected()\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'bold') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_weight_bold', zIndex: zIndex() }\"\n class=\"ql-bold\"></button>\n </div>\n }\n @if (option.type === 'italic') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_style_italic', zIndex: zIndex() }\"\n class=\"ql-italic\"></button>\n </div>\n }\n @if (option.type === 'underline') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_decoration_underline', zIndex: zIndex() }\"\n class=\"ql-underline\"></button>\n </div>\n }\n @if (option.type === 'strikeThrough') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_line_through', zIndex: zIndex() }\"\n class=\"ql-strike\"></button>\n </div>\n }\n @if (option.type === 'script.sub') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_script_sub', zIndex: zIndex() }\"\n class=\"ql-script\"\n value=\"sub\"></button>\n </div>\n }\n @if (option.type === 'script.super') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_script_super', zIndex: zIndex() }\"\n class=\"ql-script\"\n value=\"super\"></button>\n </div>\n }\n @if (option.type === 'adjust') {\n <div class=\"relative !flex items-center ql-align ql-picker ql-icon-picker !w-max {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_adjust', zIndex: zIndex() }\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [ignoreStopPropagationEvent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigAlign()\"\n [listHiddenInputSearch]=\"true\"\n [popoverCustomConfig]=\"{ ignoreArrow: true, classInclude: '!w-[32px] overflow-hidden !py-[4px]', position: { mode: 'start', distance: 0 }, paddingLeftItem: false }\"\n [listHasButtonUnSelectOption]=\"false\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"zIndex() + 1\"\n (outSelectKey)=\"handleSelectAlign($event)\">\n @if (alignSelected(); as alignSelected) {\n <div class=\"flex items-center cursor-pointer\">\n <i [class]=\"iconAlignSelectedComputed()\"></i>\n <i class=\"libs-ui-icon-move-right rotate-90 text-[#6a7383] text-[16px] ml-[4px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'indentIncrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_increase', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"+1\"></button>\n </div>\n }\n @if (option.type === 'indentDecrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_decrease', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"-1\"></button>\n </div>\n }\n @if (option.type === 'direction') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_direction', zIndex: zIndex() }\"\n class=\"ql-direction\"\n value=\"rtl\"></button>\n </div>\n }\n @if (option.type === 'listBulleted') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_bulleted', zIndex: zIndex() }\"\n class=\"ql-list ql-bullet\"\n value=\"bullet\"></button>\n </div>\n }\n @if (option.type === 'listNumbered') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_numbered', zIndex: zIndex() }\"\n class=\"ql-list ql-ordered\"\n value=\"ordered\"></button>\n </div>\n }\n @if (option.type === 'listChecked') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_numbered', zIndex: zIndex() }\"\n class=\"ql-list ql-check\"\n value=\"check\"></button>\n </div>\n }\n @if (option.type === 'personalize' && templateToolBarPersonalize(); as templateToolBarPersonalize) {\n <div class=\"flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <ng-container *ngTemplateOutlet=\"templateToolBarPersonalize\"></ng-container>\n </div>\n }\n @if (option.type === 'blockquote') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_quote', zIndex: zIndex() }\"\n class=\"ql-blockquote\"></button>\n </div>\n }\n @if (option.type === 'link') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_insert_link', zIndex: zIndex() }\"\n class=\"ql-link\"></button>\n </div>\n }\n @if (option.type === 'unLink') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_unlink', zIndex: zIndex() }\"\n class=\"ql-unLink\"\n (click)=\"handlerUnlink($event)\"></button>\n </div>\n }\n @if (option.type === 'image') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_image', zIndex: zIndex() }\"\n class=\"ql-image\"></button>\n </div>\n }\n @if (option.type === 'video') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_video', zIndex: zIndex() }\"\n class=\"ql-video\"></button>\n </div>\n }\n @if (option.type === 'emoji') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <libs_ui-components-emoji\n [zIndex]=\"zIndex()\"\n [isNgContent]=\"true\"\n (outEventEmoji)=\"handlerInsertEmoji($event)\">\n <button class=\"ql-emoji\"></button>\n </libs_ui-components-emoji>\n </div>\n }\n @if (option.type === 'table') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_table', zIndex: zIndex() }\"\n class=\"ql-table\"></button>\n </div>\n }\n @if (option.type === 'line') {\n <div class=\"w-[1px] h-[16px] libs-ui-border-right-general\"></div>\n }\n</ng-template>\n\n<libs_ui-components-popover\n #inputLinkRef\n [mode]=\"'click'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [config]=\"{ template: viewLink, whiteTheme: true, ignoreArrow: true, zIndex: zIndex() }\"\n (outEvent)=\"handlerPopoverEvent($event)\" />\n\n<ng-template #viewLink>\n <div class=\"flex justify-between items-center px-[16px] py-[8px] rounded-[8px]\">\n <div\n class=\"w-full min-w-0 libs-ui-font-h5r\"\n [type]=\"'text'\"\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: link().url, zIndex: zIndex() + 1 }\">\n {{ link().url }}\n </div>\n <div class=\"flex items-center ml-[16px]\">\n <libs_ui-components-buttons-button\n [type]=\"'button-link-primary'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-edit-line'\"\n [classInclude]=\"'!p-0'\"\n (outClick)=\"handlerEditLink($event)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-link-custom'\"\n [buttonCustom]=\"{\n configStepColor: {\n text: '#071631',\n text_hover: '#ee2d41',\n text_active: '#ee2d41',\n text_disable: '071631',\n },\n rootColor: '#071631',\n }\"\n [classInclude]=\"'!p-0 ml-[12px]'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-link-broken'\"\n (outClick)=\"handlerUnlink($event)\" />\n </div>\n </div>\n</ng-template>\n", styles: [":host ::ng-deep .quill-container{display:flex;flex-direction:column;width:100%}:host ::ng-deep .quill-container .ql-container{font-family:var(--libs-ui-font-family-name),\"Arial\"!important;font-weight:400}:host ::ng-deep .quill-container .ql-container .ql-editor{font-family:var(--libs-ui-font-family-name),\"Arial\"!important;font-weight:400}:host ::ng-deep .quill-container .ql-container .ql-editor ol li:before{content:\"\"!important}:host ::ng-deep .quill-container .ql-container .ql-blank:before{font-style:normal!important;font-size:12px!important;color:#9ca2ad!important;font-family:var(--libs-ui-font-family-name),arial!important}:host ::ng-deep .quill-container .ql-active span:before{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .quill-container .ql-active .ql-fill{fill:var(--libs-ui-color-light-1)!important}:host ::ng-deep .quill-container .ql-script :hover .ql-fill{fill:var(--libs-ui-color-light-1)!important}:host ::ng-deep .quill-container .ql-toolbar{padding:0!important;border:none!important}:host ::ng-deep .quill-container .ql-toolbar button{padding:0!important;height:16px!important;width:16px!important}:host ::ng-deep .quill-container .ql-tooltip{display:none!important}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LibsUiComponentsDropdownComponent, selector: "libs_ui-components-dropdown", inputs: ["useXssFilter", "popoverElementRefCustom", "classInclude", "ignoreStopPropagationEvent", "flagMouse", "flagMouseContent", "popoverCustomConfig", "isNgContent", "zIndex", "convertItemSelected", "getPopoverItemSelected", "httpRequestDetailItemById", "lengthKeys", "textDisplayWhenNoSelect", "textDisplayWhenMultiSelect", "classIncludeTextDisplayWhenNoSelect", "fieldLabel", "fieldGetLabel", "labelPopoverConfig", "labelPopoverFullWidth", "hasContentUnitRight", "listSearchNoDataTemplateRef", "fieldGetImage", "imageSize", "typeShape", "fieldGetIcon", "fieldGetTextAvatar", "fieldGetColorAvatar", "classAvatarInclude", "getLastTextAfterSpace", "linkImageError", "showError", "showBorderError", "disable", "readonly", "labelConfig", "disableLabel", "listSearchConfig", "isSearchOnline", "listHiddenInputSearch", "listSearchPadding", "listKeySearch", "listDividerClassInclude", "listConfig", "listButtonsOther", "listHasButtonUnSelectOption", "listClickExactly", "listBackgroundCustom", "listMaxItemShow", "listKeySelected", "listMultiKeySelected", "listKeysDisable", "listKeysHidden", "validRequired", "validMaxItemSelected", "changeValidUndefinedResetError", "allowSelectItemMultiple", "focusInputSearch", "onlyEmitDataWhenReset", "resetKeyWhenSelectAllKey", "listConfigHasDivider", "classIncludeIcon", "classIncludeContent", "listIgnoreClassDisableDefaultWhenUseKeysDisableItem", "tabKeyActive", "tabsConfig", "ignoreBorderBottom"], outputs: ["flagMouseChange", "flagMouseContentChange", "lengthKeysChange", "showBorderErrorChange", "listKeySelectedChange", "listMultiKeySelectedChange", "tabKeyActiveChange", "outSelectKey", "outSelectMultiKey", "outFunctionsControl", "outValidEvent", "outChangStageFlagMouse", "outDataChange", "outClickButtonOther", "outShowList", "outChangeTabKeyActive"] }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive", "isHandlerEnterDocumentClickButton"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsSkeletonComponent, selector: "libs_ui-components-skeleton", inputs: ["config"] }, { kind: "directive", type: LibsUiComponentsScrollOverlayDirective, selector: "[LibsUiComponentsScrollOverlayDirective]", inputs: ["debugMode", "ignoreInit", "classContainer", "options", "elementCheckScrollX", "elementCheckScrollY", "elementScroll"], outputs: ["outScroll", "outScrollX", "outScrollY", "outScrollTop", "outScrollBottom"] }, { kind: "component", type: LibsUiComponentsEmojiComponent, selector: "libs_ui-components-emoji", inputs: ["configPopover", "isNgContent", "zIndex", "modePopoverPosition", "classPopup", "classInclude", "classIconInclude"], outputs: ["outEventEmoji", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsPopoverComponent, selector: "libs_ui-components-popover,[LibsUiComponentsPopoverDirective]", inputs: ["debugId", "flagMouse", "type", "mode", "config", "ignoreShowPopover", "elementRefCustom", "initEventInElementRefCustom", "classInclude", "ignoreHiddenPopoverContentWhenMouseLeave", "ignoreStopPropagationEvent", "ignoreCursorPointerModeLikeClick", "isAddContentToParentDocument", "ignoreClickOutside"], outputs: ["outEvent", "outChangStageFlagMouse", "outEventPopoverContent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsInputsValidComponent, selector: "libs_ui-components-inputs-valid", inputs: ["item", "labelConfig", "emitEmptyInDataTypeNumber", "ignoreBlockInputMaxValue", "fieldNameBind", "showCount", "typeComponentSelectItem", "valueComponentSelectItem", "disableComponentSelectItem", "tagInput", "dataType", "typeInput", "modeInput", "resetAutoCompletePassword", "textAreaEnterNotNewLine", "fixedFloat", "acceptNegativeValue", "valueUpDownNumber", "ignoreWidthInput100", "classIncludeInput", "classContainerInput", "readonly", "disable", "noBorder", "backgroundNone", "useColorModeExist", "placeholder", "keepPlaceholderOnly", "classContainerBottomInput", "autoRemoveEmoji", "defaultHeight", "maxHeightTextArea", "minHeightTextArea", "ignoreShowError", "borderError", "iconLeftClass", "popoverContentIconLeft", "iconRightClass", "popoverContentIconRight", "zIndexPopoverContent", "unitsLeft", "configUnitLeft", "keySelectedUnitLeft", "unitsRight", "configUnitRight", "keySelectedUnitRight", "maxValueNumber", "minValueNumber", "ignoreContentLeft", "ignoreContentRight", "isBaselineStyle", "valuePatternShowError", "validPattern", "validRequired", "validMinLength", "validMinValue", "validMaxValue", "validMaxLength", "functionValid", "maxLength", "positionMessageErrorStartInput", "classInclude", "resize", "templateLeftBottomInput", "templateRightBottomInput", "onlyAcceptNegativeValue", "autoAddZeroLessThan10InTypeInt", "maxLengthNumberCount", "classMessageErrorInclude", "ignoreStopPropagationEvent", "ignoreUnitRightClassReadOnly", "paddingRightCustomSpecific", "focusTimeOut", "debounceTimeValidate"], outputs: ["itemChange", "outValueChange", "outSelect", "outIconLeft", "outIconRight", "outClickButtonLabel", "outSwitchEventLabel", "outLabelRightClick", "outEnterInputEvent", "outHeightAreaChange", "outFunctionsControl", "outFocusAndBlur", "outChangeValueByButtonUpDown"] }, { kind: "component", type: LibsUiComponentsButtonsSelectColorComponent, selector: "libs_ui-components-buttons-select_color", inputs: ["zIndex", "customOptions", "externalContent", "direction", "button", "applyNow"], outputs: ["zIndexChange", "outColorChange", "outColorChangeMultipleType"] }, { kind: "component", type: LibsUiComponentsLabelComponent, selector: "libs_ui-components-label", inputs: ["iconPopoverClass", "classInclude", "labelLeft", "labelLeftClass", "labelLeftBehindToggleButton", "popover", "required", "buttonsLeft", "disableButtonsLeft", "buttonsRight", "disableButtonsRight", "labelRight", "labelRightClass", "labelRightRequired", "hasToggle", "toggleSize", "toggleActive", "toggleDisable", "description", "descriptionClass", "buttonsDescription", "disableButtonsDescription", "buttonsDescriptionContainerClass", "onlyShowCount", "zIndexPopover", "timerDestroyPopover", "count", "limitLength"], outputs: ["outClickButton", "outSwitchEvent", "outLabelRightClick", "outLabelLeftClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2266
|
+
}
|
|
2267
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsInputsQuill2xComponent, decorators: [{
|
|
2268
|
+
type: Component,
|
|
2269
|
+
args: [{ selector: 'libs_ui-components-inputs-quill2x', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
2270
|
+
TranslateModule,
|
|
2271
|
+
NgTemplateOutlet,
|
|
2272
|
+
LibsUiComponentsDropdownComponent,
|
|
2273
|
+
LibsUiComponentsButtonsButtonComponent,
|
|
2274
|
+
LibsUiComponentsSkeletonComponent,
|
|
2275
|
+
LibsUiComponentsScrollOverlayDirective,
|
|
2276
|
+
LibsUiComponentsEmojiComponent,
|
|
2277
|
+
LibsUiComponentsPopoverComponent,
|
|
2278
|
+
LibsUiComponentsInputsValidComponent,
|
|
2279
|
+
LibsUiComponentsButtonsSelectColorComponent,
|
|
2280
|
+
LibsUiComponentsLabelComponent,
|
|
2281
|
+
], template: "<div\n #htmlContainer\n class=\"quill-container\">\n @if (label(); as label) {\n <libs_ui-components-label\n [classInclude]=\"label.classInclude\"\n [required]=\"label.required\"\n [labelLeft]=\"label.labelLeft\" />\n }\n <div\n #toolbarContainer\n class=\"relative h-[44px]\">\n <ng-container *ngTemplateOutlet=\"toolbarTemplate\" />\n </div>\n <div\n #snowContainer\n LibsUiComponentsScrollOverlayDirective\n [class]=\"containerEditorClass()\"></div>\n</div>\n\n<ng-template #toolbarTemplate>\n <div\n [class]=\"containerToolbarClass()\"\n #toolbarItems>\n @if (displaySkeletonToolbar()) {\n <libs_ui-components-skeleton\n class=\"w-full h-full\"\n [config]=\"{\n rows: [\n {\n item: { classIncludeItem: '!rounded-none' },\n },\n ],\n }\" />\n }\n <div class=\"ql-formats items-center px-[16px] py-[4px] !flex\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"!option.display\"\n [class.flex]=\"option.display\">\n <ng-container *ngTemplateOutlet=\"itemToolbarTemplate; context: { option, $index, $last }\" />\n </div>\n }\n <div class=\"relative\">\n @if (showButtonMoreToolbar()) {\n <libs_ui-components-buttons-button\n [type]=\"showMoreAction() ? 'button-secondary' : 'button-third'\"\n [iconOnlyType]=\"true\"\n [classInclude]=\"'!p-[1px] !h-[20px] ml-[8px]'\"\n [classIconLeft]=\"'libs-ui-icon-move-right rotate-90'\"\n (outClick)=\"handlerChangeShowMoreAction($event)\" />\n }\n <!-- Build toolbar khi click xem th\u00EAm-->\n <div\n [class.hidden]=\"!showMoreAction()\"\n class=\"absolute bg-[#ffffff] shadow-[0px_4px_16px_0px_rgba(0,20,51,0.10)] z-[1] flex items-center pl-[8px] pr-[16px] py-[4px] rounded-[8px] top-[31px] right-[0px]\">\n @for (option of toolbarOptionsConfig(); track option) {\n <div\n class=\"items-center\"\n [class.hidden]=\"option.display !== false\"\n [class.flex]=\"option.display === false\">\n <ng-container *ngTemplateOutlet=\"itemToolbarTemplate; context: { option, $index, $last }\" />\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template\n #itemToolbarTemplate\n let-$index=\"$index\"\n let-$last=\"$last\"\n let-option=\"option\">\n @if (option.type === 'undo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_undo', zIndex: zIndex() }\"\n class=\"ql-undo\"></button>\n </div>\n }\n @if (option.type === 'redo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_redo', zIndex: zIndex() }\"\n class=\"ql-redo\"></button>\n </div>\n }\n @if (option.type === 'fontFamily') {\n <div\n class=\"relative w-[132px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigFont()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectFont($event)\">\n @if (fontSelected(); as fontSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px]\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelFontSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'header') {\n <div\n class=\"relative w-[138px] h-full rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\"\n [class.bg-white]=\"!readonly() && !loadingUploadImage()\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigHeader()\"\n [listHasButtonUnSelectOption]=\"false\"\n [listHiddenInputSearch]=\"true\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"1250\"\n (outSelectKey)=\"handleSelectHeader($event)\">\n @if (headerSelected(); as headerSelected) {\n <div class=\"flex items-center cursor-pointer py-[7px] libs-ui-font-h5r pl-[16px] pr-[40px] {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover\n [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{ zIndex: zIndex() }\">\n {{ labelHeaderSelectedComputed() }}\n </libs_ui-components-popover>\n <i class=\"libs-ui-icon-move-right rotate-90 absolute right-[12px] text-[#6a7383] text-[16px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </div>\n }\n @if (option.type === 'fontSize') {\n <div class=\" {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-inputs-valid\n #inputSizeRef\n [dataType]=\"'int'\"\n [(item)]=\"size\"\n [fieldNameBind]=\"'value'\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"72\"\n [minValueNumber]=\"8\"\n [readonly]=\"readonly() || loadingUploadImage()\"\n [classContainerInput]=\"'w-[72px] h-[32px]'\"\n (outValueChange)=\"handlerValueChangeFontSize($event)\" />\n </div>\n }\n @if (option.type === 'color') {\n <div class=\"ql-color ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_text_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n [applyNow]=\"false\"\n (outColorChange)=\"handlerSetFormat('color', $event)\">\n <div\n class=\"libs-ui-icon-editor-color-text libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"\n [class.text-[var(--libs-ui-color-light-1)]]=\"colorSelected()\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'background') {\n <div class=\"ql-background ql-picker ql-color-picker !flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_background_color', zIndex: zIndex() }\">\n <libs_ui-components-buttons-select_color\n [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [applyNow]=\"false\"\n [customOptions]=\"{\n showAlpha: true,\n }\"\n (outColorChange)=\"handlerSetFormat('background', $event)\">\n <div\n class=\"libs-ui-icon-editor-color-background libs-ui-buttons-select-color text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]\"\n [class.text-[var(--libs-ui-color-light-1)]]=\"backgroundSelected()\"></div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'bold') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_weight_bold', zIndex: zIndex() }\"\n class=\"ql-bold\"></button>\n </div>\n }\n @if (option.type === 'italic') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_font_style_italic', zIndex: zIndex() }\"\n class=\"ql-italic\"></button>\n </div>\n }\n @if (option.type === 'underline') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_decoration_underline', zIndex: zIndex() }\"\n class=\"ql-underline\"></button>\n </div>\n }\n @if (option.type === 'strikeThrough') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_text_line_through', zIndex: zIndex() }\"\n class=\"ql-strike\"></button>\n </div>\n }\n @if (option.type === 'script.sub') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_script_sub', zIndex: zIndex() }\"\n class=\"ql-script\"\n value=\"sub\"></button>\n </div>\n }\n @if (option.type === 'script.super') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_script_super', zIndex: zIndex() }\"\n class=\"ql-script\"\n value=\"super\"></button>\n </div>\n }\n @if (option.type === 'adjust') {\n <div class=\"relative !flex items-center ql-align ql-picker ql-icon-picker !w-max {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-popover [config]=\"{ content: 'i18n_adjust', zIndex: zIndex() }\">\n <libs_ui-components-dropdown\n [isNgContent]=\"true\"\n [ignoreStopPropagationEvent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigAlign()\"\n [listHiddenInputSearch]=\"true\"\n [popoverCustomConfig]=\"{ ignoreArrow: true, classInclude: '!w-[32px] overflow-hidden !py-[4px]', position: { mode: 'start', distance: 0 }, paddingLeftItem: false }\"\n [listHasButtonUnSelectOption]=\"false\"\n [listMaxItemShow]=\"8\"\n [zIndex]=\"zIndex() + 1\"\n (outSelectKey)=\"handleSelectAlign($event)\">\n @if (alignSelected(); as alignSelected) {\n <div class=\"flex items-center cursor-pointer\">\n <i [class]=\"iconAlignSelectedComputed()\"></i>\n <i class=\"libs-ui-icon-move-right rotate-90 text-[#6a7383] text-[16px] ml-[4px]\"></i>\n </div>\n }\n </libs_ui-components-dropdown>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.type === 'indentIncrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_increase', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"+1\"></button>\n </div>\n }\n @if (option.type === 'indentDecrease') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_indent_decrease', zIndex: zIndex() }\"\n class=\"ql-indent\"\n value=\"-1\"></button>\n </div>\n }\n @if (option.type === 'direction') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_direction', zIndex: zIndex() }\"\n class=\"ql-direction\"\n value=\"rtl\"></button>\n </div>\n }\n @if (option.type === 'listBulleted') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_bulleted', zIndex: zIndex() }\"\n class=\"ql-list ql-bullet\"\n value=\"bullet\"></button>\n </div>\n }\n @if (option.type === 'listNumbered') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_numbered', zIndex: zIndex() }\"\n class=\"ql-list ql-ordered\"\n value=\"ordered\"></button>\n </div>\n }\n @if (option.type === 'listChecked') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_list_numbered', zIndex: zIndex() }\"\n class=\"ql-list ql-check\"\n value=\"check\"></button>\n </div>\n }\n @if (option.type === 'personalize' && templateToolBarPersonalize(); as templateToolBarPersonalize) {\n <div class=\"flex items-center {{ option.classInclude || 'mx-[8px]' }}\">\n <ng-container *ngTemplateOutlet=\"templateToolBarPersonalize\"></ng-container>\n </div>\n }\n @if (option.type === 'blockquote') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_quote', zIndex: zIndex() }\"\n class=\"ql-blockquote\"></button>\n </div>\n }\n @if (option.type === 'link') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_insert_link', zIndex: zIndex() }\"\n class=\"ql-link\"></button>\n </div>\n }\n @if (option.type === 'unLink') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_unlink', zIndex: zIndex() }\"\n class=\"ql-unLink\"\n (click)=\"handlerUnlink($event)\"></button>\n </div>\n }\n @if (option.type === 'image') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_image', zIndex: zIndex() }\"\n class=\"ql-image\"></button>\n </div>\n }\n @if (option.type === 'video') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_video', zIndex: zIndex() }\"\n class=\"ql-video\"></button>\n </div>\n }\n @if (option.type === 'emoji') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <libs_ui-components-emoji\n [zIndex]=\"zIndex()\"\n [isNgContent]=\"true\"\n (outEventEmoji)=\"handlerInsertEmoji($event)\">\n <button class=\"ql-emoji\"></button>\n </libs_ui-components-emoji>\n </div>\n }\n @if (option.type === 'table') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: 'i18n_table', zIndex: zIndex() }\"\n class=\"ql-table\"></button>\n </div>\n }\n @if (option.type === 'line') {\n <div class=\"w-[1px] h-[16px] libs-ui-border-right-general\"></div>\n }\n</ng-template>\n\n<libs_ui-components-popover\n #inputLinkRef\n [mode]=\"'click'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [config]=\"{ template: viewLink, whiteTheme: true, ignoreArrow: true, zIndex: zIndex() }\"\n (outEvent)=\"handlerPopoverEvent($event)\" />\n\n<ng-template #viewLink>\n <div class=\"flex justify-between items-center px-[16px] py-[8px] rounded-[8px]\">\n <div\n class=\"w-full min-w-0 libs-ui-font-h5r\"\n [type]=\"'text'\"\n LibsUiComponentsPopoverDirective\n [config]=\"{ content: link().url, zIndex: zIndex() + 1 }\">\n {{ link().url }}\n </div>\n <div class=\"flex items-center ml-[16px]\">\n <libs_ui-components-buttons-button\n [type]=\"'button-link-primary'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-edit-line'\"\n [classInclude]=\"'!p-0'\"\n (outClick)=\"handlerEditLink($event)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-link-custom'\"\n [buttonCustom]=\"{\n configStepColor: {\n text: '#071631',\n text_hover: '#ee2d41',\n text_active: '#ee2d41',\n text_disable: '071631',\n },\n rootColor: '#071631',\n }\"\n [classInclude]=\"'!p-0 ml-[12px]'\"\n [iconOnlyType]=\"true\"\n [classIconLeft]=\"'libs-ui-icon-link-broken'\"\n (outClick)=\"handlerUnlink($event)\" />\n </div>\n </div>\n</ng-template>\n", styles: [":host ::ng-deep .quill-container{display:flex;flex-direction:column;width:100%}:host ::ng-deep .quill-container .ql-container{font-family:var(--libs-ui-font-family-name),\"Arial\"!important;font-weight:400}:host ::ng-deep .quill-container .ql-container .ql-editor{font-family:var(--libs-ui-font-family-name),\"Arial\"!important;font-weight:400}:host ::ng-deep .quill-container .ql-container .ql-editor ol li:before{content:\"\"!important}:host ::ng-deep .quill-container .ql-container .ql-blank:before{font-style:normal!important;font-size:12px!important;color:#9ca2ad!important;font-family:var(--libs-ui-font-family-name),arial!important}:host ::ng-deep .quill-container .ql-active span:before{color:var(--libs-ui-color-light-1)!important}:host ::ng-deep .quill-container .ql-active .ql-fill{fill:var(--libs-ui-color-light-1)!important}:host ::ng-deep .quill-container .ql-script :hover .ql-fill{fill:var(--libs-ui-color-light-1)!important}:host ::ng-deep .quill-container .ql-toolbar{padding:0!important;border:none!important}:host ::ng-deep .quill-container .ql-toolbar button{padding:0!important;height:16px!important;width:16px!important}:host ::ng-deep .quill-container .ql-tooltip{display:none!important}\n"] }]
|
|
2282
|
+
}] });
|
|
2283
|
+
|
|
1405
2284
|
/**
|
|
1406
2285
|
* Generated bundle index. Do not edit.
|
|
1407
2286
|
*/
|
|
1408
2287
|
|
|
1409
|
-
export { LibsUiComponentsInputsQuillComponent };
|
|
2288
|
+
export { LibsUiComponentsInputsQuill2xComponent, LibsUiComponentsInputsQuillComponent };
|
|
1410
2289
|
//# sourceMappingURL=libs-ui-components-inputs-quill.mjs.map
|