@libs-ui/components-inputs-quill 0.2.75

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.
@@ -0,0 +1,841 @@
1
+ import { NgTemplateOutlet } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { signal, input, output, Component, ChangeDetectionStrategy, computed, inject, viewChild } from '@angular/core';
4
+ import { LibsUiComponentsButtonsSelectColorComponent } from '@libs-ui/components-buttons-select-color';
5
+ import { LibsUiComponentsDropdownComponent } from '@libs-ui/components-dropdown';
6
+ import { LibsUiComponentsEmojiComponent } from '@libs-ui/components-inputs-emoji';
7
+ import { LibsUiComponentsInputsValidComponent } from '@libs-ui/components-inputs-valid';
8
+ import { LibsUiComponentsLabelComponent } from '@libs-ui/components-label';
9
+ import { LibsUiComponentsPopoverComponent } from '@libs-ui/components-popover';
10
+ import { LibsUiDynamicComponentService } from '@libs-ui/services-dynamic-component';
11
+ import { PATTERN_URL, get, set, xssFilter, isNil, ERROR_MESSAGE_EMPTY_VALID, ERROR_MESSAGE_MIN_LENGTH, ERROR_MESSAGE_MAX_LENGTH } from '@libs-ui/utils';
12
+ import * as i1 from '@ngx-translate/core';
13
+ import { TranslateService, TranslateModule } from '@ngx-translate/core';
14
+ import Quill from 'quill';
15
+ import { Subject, fromEvent, takeUntil } from 'rxjs';
16
+ import { LibsUiComponentsModalComponent } from '@libs-ui/components-modal';
17
+ import { returnListObject } from '@libs-ui/services-http-request';
18
+
19
+ class LibsUiComponentsInputsQuillCustomUploadImageComponent {
20
+ buttonFooter = signal([{
21
+ label: 'i18n_save',
22
+ action: () => this.handlerSaveImage()
23
+ },
24
+ {
25
+ type: 'button-third',
26
+ label: 'i18n_cancel',
27
+ action: async () => this.outClose.emit()
28
+ }]);
29
+ disable = signal(false);
30
+ // private mediaFile =signal<IMediaFile | undefined>(undefined);
31
+ // private mediaUploadFunctionControl =signal<IMediaUploadBaseFunctionControlEvent | undefined>(undefined);
32
+ zIndex = input(1202, { transform: (value) => value ? value + 1 : 1202 });
33
+ maxImageSize = input(1048576, { transform: (value) => value ?? 1048576 });
34
+ labelConfig = input();
35
+ outClose = output();
36
+ // protected handlerFunctionsControl(event: IMediaUploadBaseFunctionControlEvent) {
37
+ // this.mediaUploadFunctionControl.set(event);
38
+ // }
39
+ // protected handlerChangeFile(event: IChangeFile) {
40
+ // this.mediaFile.set(event.files[0]);
41
+ // }
42
+ async handlerSaveImage() {
43
+ // if (!await this.mediaUploadFunctionControl()?.valid()) {
44
+ // return;
45
+ // }
46
+ // if (this.mediaFile?.origin_url) {
47
+ // this.moClose.emit(this.mediaFile.origin_url);
48
+ // return;
49
+ // }
50
+ // const body: IOptionsUploadMedia = {
51
+ // do_not_delete: true,
52
+ // file: this.mediaFile?.file,
53
+ // option: 'thumb',
54
+ // size: [{ 'width': '200', 'height': '200' }]
55
+ // };
56
+ // this.disable = true;
57
+ // try {
58
+ // const params = new HttpParamsRequest({ fromObject: { pem: BUILD_PEM_OBJECT({ isCheck: 0, action: DefineConstants.PERMISSION_ACTION_VIEW, pathCheck: '/other' }) } });
59
+ // const res = await this.mediaService.uploadImage(params, body);
60
+ // this.moClose.emit(res.data?.url);
61
+ // } catch (error) {
62
+ // console.log(error);
63
+ // this.pushMessageService.showCompTypeText('i18n_notification_manipulation_not_success', undefined, undefined, { timeRemove: 2000, type: 'error' });
64
+ // this.moClose.emit();
65
+ // } finally {
66
+ // this.disable = false;
67
+ // }
68
+ }
69
+ handlerEventModal(event) {
70
+ if (event === 'close') {
71
+ this.outClose.emit();
72
+ }
73
+ }
74
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsQuillCustomUploadImageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
75
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: LibsUiComponentsInputsQuillCustomUploadImageComponent, isStandalone: true, selector: "libs_ui-components-inputs-quill-custom_upload_image", inputs: { zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, maxImageSize: { classPropertyName: "maxImageSize", publicName: "maxImageSize", isSignal: true, isRequired: false, transformFunction: null }, labelConfig: { classPropertyName: "labelConfig", publicName: "labelConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { outClose: "outClose" }, ngImport: i0, template: "<libs_ui-components-modal [title]=\"'i18n_download_image'\"\n [mode]=\"'center'\"\n [width]=\"'598px'\"\n [headerConfig]=\"{ignoreHeaderTheme:true}\"\n [maxHeight]=\"'calc(100% - 100px)'\"\n [height]=\"'auto'\"\n [zIndex]=\"zIndex()\"\n [disable]=\"disable()\"\n [buttonsFooter]=\"buttonFooter()\"\n (outEvent)=\"handlerEventModal($event)\">\n <div class=\"libs-ui-modal-body-custom\">\n <!-- <mo-libs-shared-components-media-upload [zIndex]=\"zIndex+1\"\n [labelConfig]=\"labelConfig\"\n [multiple]=\"false\"\n [fileType]=\"'image'\"\n [doNotDelete]=\"true\"\n [maxImageSize]=\"maxImageSize\"\n [limitFile]=\"10\"\n [validRequired]=\"{isRequired: true}\"\n (moChangeFile)=\"handlerChangeFile($event)\"\n (moFunctionsControl)=\"handlerFunctionsControl($event)\">\n </mo-libs-shared-components-media-upload> -->\n </div>\n</libs_ui-components-modal>\n", dependencies: [{ kind: "component", type: LibsUiComponentsModalComponent, selector: "libs_ui-components-modal", inputs: ["show", "mode", "isBackdropTransparent", "isBackgroundTransparentModal", "isSizeBackdropByWidthHeightInput", "hasShadowBoxWhenHiddenBackDropTransparent", "classIncludeModalWrapper", "zIndex", "width", "height", "maxWidth", "maxHeight", "minWidth", "isFullScreen", "disable", "ignoreCommunicateMicroEvent", "headerConfig", "bodyConfig", "footerConfig", "buttonsFooter", "title", "titleUseXssFilter", "titleUseTooltip", "titleUseInnerText"], outputs: ["showChange", "widthChange", "heightChange", "maxWidthChange", "maxHeightChange", "minWidthChange", "disableChange", "buttonsFooterChange", "outScrollContent", "outEvent", "outFunctionControl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
76
+ }
77
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsQuillCustomUploadImageComponent, decorators: [{
78
+ type: Component,
79
+ args: [{ selector: 'libs_ui-components-inputs-quill-custom_upload_image', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
80
+ LibsUiComponentsModalComponent
81
+ ], template: "<libs_ui-components-modal [title]=\"'i18n_download_image'\"\n [mode]=\"'center'\"\n [width]=\"'598px'\"\n [headerConfig]=\"{ignoreHeaderTheme:true}\"\n [maxHeight]=\"'calc(100% - 100px)'\"\n [height]=\"'auto'\"\n [zIndex]=\"zIndex()\"\n [disable]=\"disable()\"\n [buttonsFooter]=\"buttonFooter()\"\n (outEvent)=\"handlerEventModal($event)\">\n <div class=\"libs-ui-modal-body-custom\">\n <!-- <mo-libs-shared-components-media-upload [zIndex]=\"zIndex+1\"\n [labelConfig]=\"labelConfig\"\n [multiple]=\"false\"\n [fileType]=\"'image'\"\n [doNotDelete]=\"true\"\n [maxImageSize]=\"maxImageSize\"\n [limitFile]=\"10\"\n [validRequired]=\"{isRequired: true}\"\n (moChangeFile)=\"handlerChangeFile($event)\"\n (moFunctionsControl)=\"handlerFunctionsControl($event)\">\n </mo-libs-shared-components-media-upload> -->\n </div>\n</libs_ui-components-modal>\n" }]
82
+ }] });
83
+
84
+ const parchment = Quill.import('parchment');
85
+ const pixelLevels = [1, 2, 3, 4, 5, 6, 7, 8];
86
+ const tabMultiplier = 3;
87
+ class IndentAttributor extends parchment.Attributor.Style {
88
+ constructor(formatName, styleProperty, attributorOptions) {
89
+ super(formatName, styleProperty, attributorOptions);
90
+ }
91
+ add(node, value) {
92
+ return super.add(node, `${+value * tabMultiplier}em`);
93
+ }
94
+ value(node) {
95
+ return parseFloat(super.value(node)) / tabMultiplier || undefined; // Don't return NaN
96
+ }
97
+ }
98
+ const indentStyle = new IndentAttributor('indent', 'margin-left', {
99
+ scope: parchment.Scope.BLOCK,
100
+ whitelist: pixelLevels.map(value => `${value * tabMultiplier}em`),
101
+ });
102
+
103
+ class LibsUiComponentsInputsQuillLinkComponent {
104
+ dataLink = signal({ title: '', link: '' });
105
+ patternLink = signal(PATTERN_URL());
106
+ inputValidFunctionControl = signal([]);
107
+ zIndex = input(1200, { transform: (value) => value ? value + 1 : 1200 });
108
+ textSelected = input();
109
+ outClose = output();
110
+ outSaveLink = output();
111
+ ngOnInit() {
112
+ const textSelected = this.textSelected();
113
+ if (textSelected) {
114
+ this.dataLink.update(item => ({ ...item, title: textSelected }));
115
+ }
116
+ }
117
+ async handlerFunctionsControl(event) {
118
+ this.inputValidFunctionControl.update(items => [...items, event]);
119
+ }
120
+ async validate() {
121
+ let valid = true;
122
+ for (const control of this.inputValidFunctionControl()) {
123
+ if (!(await control.checkIsValid())) {
124
+ valid = false;
125
+ }
126
+ }
127
+ return valid;
128
+ }
129
+ async handlerEvent(event) {
130
+ if (event !== 'agree') {
131
+ this.outClose.emit();
132
+ return;
133
+ }
134
+ if (await this.validate()) {
135
+ this.outSaveLink.emit(this.dataLink());
136
+ this.outClose.emit();
137
+ }
138
+ }
139
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsQuillLinkComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
140
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: LibsUiComponentsInputsQuillLinkComponent, isStandalone: true, selector: "libs_ui-components-inputs-quill-link", inputs: { zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, textSelected: { classPropertyName: "textSelected", publicName: "textSelected", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { outClose: "outClose", outSaveLink: "outSaveLink" }, ngImport: i0, template: "<libs_ui-components-modal [title]=\"'i18n_insert_link'\"\n [height]=\"'auto'\"\n [width]=\"'598px'\"\n [zIndex]=\"zIndex()\"\n (outEvent)=\"handlerEvent($event)\">\n <div class=\"libs-ui-modal-body-custom\">\n <libs_ui-components-inputs-valid [labelConfig]=\"{labelLeft: 'i18n_content', required: true}\"\n [(item)]=\"dataLink\"\n [fieldNameBind]=\"'title'\"\n [placeholder]=\"'i18n_import_content'\"\n [validRequired]=\"{isRequired:true}\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\" />\n <div class=\"mt-[16px]\">\n <libs_ui-components-inputs-valid [labelConfig]=\"{labelLeft: 'Link', required: true}\"\n [(item)]=\"dataLink\"\n [fieldNameBind]=\"'link'\"\n [placeholder]=\"'https:/\u2026'\"\n [validRequired]=\"{isRequired:true}\"\n [validPattern]=\"[{pattern:patternLink}]\"\n keySelectedUnitLeft=\"1\"\n [unitsLeft]=\"[{id:'1',label:'URL'}]\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\" />\n </div>\n </div>\n</libs_ui-components-modal>\n", dependencies: [{ kind: "component", type: LibsUiComponentsModalComponent, selector: "libs_ui-components-modal", inputs: ["show", "mode", "isBackdropTransparent", "isBackgroundTransparentModal", "isSizeBackdropByWidthHeightInput", "hasShadowBoxWhenHiddenBackDropTransparent", "classIncludeModalWrapper", "zIndex", "width", "height", "maxWidth", "maxHeight", "minWidth", "isFullScreen", "disable", "ignoreCommunicateMicroEvent", "headerConfig", "bodyConfig", "footerConfig", "buttonsFooter", "title", "titleUseXssFilter", "titleUseTooltip", "titleUseInnerText"], outputs: ["showChange", "widthChange", "heightChange", "maxWidthChange", "maxHeightChange", "minWidthChange", "disableChange", "buttonsFooterChange", "outScrollContent", "outEvent", "outFunctionControl"] }, { kind: "component", type: LibsUiComponentsInputsValidComponent, selector: "libs_ui-components-inputs-valid", inputs: ["item", "labelConfig", "emitEmptyInDataTypeNumber", "ignoreBlockInputMaxValue", "fieldNameBind", "showCount", "typeComponentSelectItem", "valueComponentSelectItem", "disableComponentSelectItem", "tagInput", "dataType", "resetAutoCompletePassword", "textAreaEnterNotNewLine", "hiddenContent", "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"], outputs: ["itemChange", "outValueChange", "outSelect", "outIconLeft", "outIconRight", "outClickButtonLabel", "outSwitchEventLabel", "outLabelRightClick", "outEnterInputEvent", "outHeightAreaChange", "outFunctionsControl", "outFocusAndBlur", "outChangeValueByButtonUpDown"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
141
+ }
142
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsQuillLinkComponent, decorators: [{
143
+ type: Component,
144
+ args: [{ selector: 'libs_ui-components-inputs-quill-link', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
145
+ LibsUiComponentsModalComponent,
146
+ LibsUiComponentsInputsValidComponent
147
+ ], template: "<libs_ui-components-modal [title]=\"'i18n_insert_link'\"\n [height]=\"'auto'\"\n [width]=\"'598px'\"\n [zIndex]=\"zIndex()\"\n (outEvent)=\"handlerEvent($event)\">\n <div class=\"libs-ui-modal-body-custom\">\n <libs_ui-components-inputs-valid [labelConfig]=\"{labelLeft: 'i18n_content', required: true}\"\n [(item)]=\"dataLink\"\n [fieldNameBind]=\"'title'\"\n [placeholder]=\"'i18n_import_content'\"\n [validRequired]=\"{isRequired:true}\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\" />\n <div class=\"mt-[16px]\">\n <libs_ui-components-inputs-valid [labelConfig]=\"{labelLeft: 'Link', required: true}\"\n [(item)]=\"dataLink\"\n [fieldNameBind]=\"'link'\"\n [placeholder]=\"'https:/\u2026'\"\n [validRequired]=\"{isRequired:true}\"\n [validPattern]=\"[{pattern:patternLink}]\"\n keySelectedUnitLeft=\"1\"\n [unitsLeft]=\"[{id:'1',label:'URL'}]\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\" />\n </div>\n </div>\n</libs_ui-components-modal>\n" }]
148
+ }] });
149
+
150
+ const Embed = Quill.import("blots/embed");
151
+ class QuillMentionBlot extends Embed {
152
+ static create(data) {
153
+ const node = super.create();
154
+ node.innerText += data.value;
155
+ node.setAttribute('id', data.id);
156
+ node.setAttribute('feId', data.feId);
157
+ node.setAttribute('value', data.value);
158
+ return node;
159
+ }
160
+ static value(domNode) {
161
+ return {
162
+ id: domNode.getAttribute('id'),
163
+ feId: domNode.getAttribute('feId'),
164
+ value: domNode.getAttribute('value')
165
+ };
166
+ }
167
+ attach() {
168
+ super.attach();
169
+ if (!this.mounted) {
170
+ this.mounted = true;
171
+ this.clickHandler = this.getClickHandler;
172
+ this.domNode.addEventListener("click", this.clickHandler, false);
173
+ }
174
+ }
175
+ getClickHandler(event) {
176
+ event.stopPropagation();
177
+ }
178
+ }
179
+ QuillMentionBlot.blotName = "mention";
180
+ QuillMentionBlot.tagName = "span";
181
+ QuillMentionBlot.className = "libs-ui-quill-mention";
182
+
183
+ const listDataAlign = () => {
184
+ return [
185
+ { key: '', icon: 'libs-ui-align-left text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]' },
186
+ { key: 'right', icon: 'libs-ui-align-right text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]' },
187
+ { key: 'center', icon: 'libs-ui-align-center text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]' },
188
+ { key: 'justify', icon: 'libs-ui-align-justify text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]' },
189
+ ];
190
+ };
191
+ const listFont = () => {
192
+ return [
193
+ { key: '', label: 'Sans Serif' },
194
+ { key: 'serif', label: 'Serif' },
195
+ { key: 'monospace', label: 'Monospace' },
196
+ ];
197
+ };
198
+ const listConfigAlign = () => {
199
+ return {
200
+ type: 'text',
201
+ autoSelectFirstItem: true,
202
+ httpRequestData: signal({
203
+ serviceOther: returnListObject(listDataAlign()),
204
+ functionName: 'list',
205
+ argumentsValue: []
206
+ }),
207
+ configTemplateText: signal({
208
+ fieldKey: 'key',
209
+ getValue: item => `<i class="${item.icon} ml-[6px]"></i>`,
210
+ ignoreIconSelected: true
211
+ })
212
+ };
213
+ };
214
+ const listConfigFont = () => {
215
+ return {
216
+ type: 'text',
217
+ autoSelectFirstItem: true,
218
+ httpRequestData: signal({
219
+ serviceOther: returnListObject(listFont()),
220
+ functionName: 'list',
221
+ argumentsValue: []
222
+ }),
223
+ configTemplateText: signal({
224
+ fieldKey: 'key',
225
+ getValue: item => item.label,
226
+ ignoreIconSelected: true
227
+ })
228
+ };
229
+ };
230
+ const toolBarOptionDefault = [
231
+ { undo: true, redo: true },
232
+ { fontFamily: true, fontSize: true, styleGapItem: 'gap-2' },
233
+ { color: true, background: true },
234
+ { bold: true, italic: true, underline: true, strikeThrough: true },
235
+ { adjust: true },
236
+ { indentIncrease: true, indentDecrease: true, listBulleted: true, listNumbered: true },
237
+ { personalize: true, blockquote: true, link: true, unLink: true, image: true, emoji: true }
238
+ ];
239
+ const iconList = [
240
+ {
241
+ key: 'bold',
242
+ icon: 'libs-ui-icon-editor-bold',
243
+ },
244
+ {
245
+ key: 'italic',
246
+ icon: 'libs-ui-icon-editor-italic',
247
+ },
248
+ {
249
+ key: 'underline',
250
+ icon: 'libs-ui-icon-editor-underlined',
251
+ },
252
+ {
253
+ key: 'image',
254
+ icon: 'libs-ui-icon-image-solid'
255
+ },
256
+ {
257
+ key: 'link',
258
+ icon: 'libs-ui-icon-link'
259
+ },
260
+ {
261
+ key: 'undo',
262
+ icon: 'libs-ui-icon-undo'
263
+ },
264
+ {
265
+ key: 'redo',
266
+ icon: 'libs-ui-icon-undo scale-x-[-1]'
267
+ },
268
+ {
269
+ key: 'strike',
270
+ icon: 'libs-ui-icon-editor-strike-through'
271
+ },
272
+ {
273
+ key: 'blockquote',
274
+ icon: 'libs-ui-icon-quote'
275
+ },
276
+ {
277
+ key: 'ordered',
278
+ icon: 'libs-ui-icon-list-numbered'
279
+ },
280
+ {
281
+ key: 'bullet',
282
+ icon: 'libs-ui-icon-list-bulleted'
283
+ },
284
+ {
285
+ key: 'background',
286
+ icon: 'libs-ui-icon-editor-color-background'
287
+ },
288
+ {
289
+ key: 'color',
290
+ icon: 'libs-ui-icon-editor-color-text'
291
+ },
292
+ {
293
+ key: "indent['-1']",
294
+ icon: 'libs-ui-icon-indent-decrease'
295
+ },
296
+ {
297
+ key: "indent['+1']",
298
+ icon: 'libs-ui-icon-indent-increase'
299
+ },
300
+ {
301
+ key: "align['']",
302
+ icon: 'align-quill libs-ui-icon-align-left'
303
+ },
304
+ {
305
+ key: "align['center']",
306
+ icon: 'align-quill libs-ui-icon-align-center'
307
+ },
308
+ {
309
+ key: "align['right']",
310
+ icon: 'align-quill libs-ui-icon-align-right'
311
+ },
312
+ {
313
+ key: "align['justify']",
314
+ icon: 'align-quill libs-ui-icon-align-justify'
315
+ },
316
+ {
317
+ key: 'unLink',
318
+ icon: 'libs-ui-icon-link-broken'
319
+ },
320
+ {
321
+ key: 'emoji',
322
+ icon: 'libs-ui-icon-face-smile'
323
+ }
324
+ ];
325
+
326
+ class LibsUiComponentsInputsQuillComponent {
327
+ quill = signal(undefined);
328
+ messageErr = signal('');
329
+ display = signal(false);
330
+ handlers = signal({ undo: this.handleUndo, redo: this.handleRedo });
331
+ listConfigAlign = signal(listConfigAlign());
332
+ alignSelected = signal(undefined);
333
+ iconAlignSelectedComputed = computed(() => get(this.alignSelected(), 'item.icon'));
334
+ listConfigFont = signal(listConfigFont());
335
+ fontSelected = signal(undefined);
336
+ labelFontSelectedComputed = computed(() => get(this.fontSelected(), 'item.label') || 'Sans Serif');
337
+ size = signal({ value: 14 });
338
+ headingKeySelected = signal(undefined);
339
+ addLinkComponentRef = signal(undefined);
340
+ mediaUploadComponentRef = signal(undefined);
341
+ showMention = signal(false);
342
+ dynamicComponentService = inject(LibsUiDynamicComponentService);
343
+ translate = inject(TranslateService);
344
+ onDestroy = new Subject();
345
+ optionsToolbar = input(toolBarOptionDefault, { transform: value => value || toolBarOptionDefault });
346
+ placeholder = input('i18n_import_content', { transform: (value) => value || 'i18n_import_content' });
347
+ labelConfig = input();
348
+ item = input();
349
+ fieldNameBind = input('value');
350
+ readonly = input(false);
351
+ typeOutPutContent = input('style');
352
+ ignoreShowErrorLabel = input(false);
353
+ showErrorBorder = input(false);
354
+ template = input();
355
+ classIncludeTemplate = input();
356
+ classInclude = input();
357
+ handlerClickHeader = input();
358
+ validRequired = input();
359
+ validMinLength = input();
360
+ validMaxLength = input();
361
+ onlyShowContent = input(false);
362
+ zIndex = input(1201, { transform: (value) => value || 1201 });
363
+ // readonly dataConfigMention: IMentionsConfig | undefined;
364
+ notAllowUploadImage = input();
365
+ isHeightAuto = input();
366
+ customUploadImage = input({ modeCustom: true, zIndex: 1202 }, { transform: (value) => value || { modeCustom: true, zIndex: 1202 } });
367
+ autoFocus = input();
368
+ autoFocusBottom = input();
369
+ isShowToolBar = input();
370
+ classIncludeToolbar = input('bottom-[-66px] left-[18px]');
371
+ templateToolBarPersonalize = input();
372
+ onlyShowErrorBorderInContent = input(false);
373
+ functionUploadImage = input(); // cần truyền nếu cho phép tải ảnh lên, yêu cầu tải xong ảnh phải gọi hàm insertImage để thêm ảnh vào content
374
+ outLabelError = output();
375
+ outBlur = output();
376
+ outFocus = output();
377
+ outChange = output();
378
+ outFunctionsControl = output();
379
+ outImagePaste = output();
380
+ outSelectionChange = output();
381
+ wrapperEditorEl = viewChild('wrapperEditor');
382
+ editorEl = viewChild('editor');
383
+ quillOptionEl = viewChild('quillOption');
384
+ quillEditorEl = viewChild('quillEditor');
385
+ quillToolbarEl = viewChild('quillToolbar');
386
+ ngOnInit() {
387
+ this.outFunctionsControl.emit({
388
+ setContent: this.setContent.bind(this),
389
+ checkIsValid: this.validate.bind(this),
390
+ insertContent: this.handleAddContentText.bind(this),
391
+ insertLink: this.handleAddLinkQuill.bind(this),
392
+ insertImage: this.insertImage.bind(this),
393
+ setFontSize: this.setFontSize.bind(this),
394
+ setColor: this.setColor.bind(this),
395
+ setBackground: this.setBackground.bind(this)
396
+ });
397
+ }
398
+ ngAfterViewInit() {
399
+ if (this.autoFocus()) {
400
+ this.display.set(true);
401
+ }
402
+ if (this.customUploadImage().modeCustom) {
403
+ this.handlers.update(item => ({ ...item, image: this.handlerShowUploadImage.bind(this), emoji: this.handlerAddEmoji.bind(this) }));
404
+ }
405
+ let handlerClickLink = false;
406
+ const handlerClickHeader = this.handlerClickHeader();
407
+ if (handlerClickHeader && handlerClickHeader.length) {
408
+ handlerClickHeader.forEach(element => {
409
+ if (element.title && element.action) {
410
+ if (element.title === 'link') {
411
+ handlerClickLink = true;
412
+ }
413
+ this.handlers.update(item => ({ ...item, [element.title]: element.action }));
414
+ }
415
+ });
416
+ }
417
+ if (!handlerClickLink) {
418
+ this.handlers.update(item => ({ ...item, link: this.handleShowUploadLink.bind(this), unLink: this.handlerUnInsertLink.bind(this) }));
419
+ }
420
+ const size = Quill.import('attributors/style/size');
421
+ const image = Quill.import('formats/image');
422
+ const parchment = Quill.import('parchment');
423
+ const alignStyle = Quill.import('attributors/style/align');
424
+ const icons = Quill.import('ui/icons');
425
+ const block = parchment.query('block');
426
+ const italic = Quill.import('formats/italic');
427
+ const bold = Quill.import('formats/bold');
428
+ size.whitelist = ['8px', '9px', '10px', '11px', '12px', '13px', '14px', '15px', '16px', '17px', '18px', '19px', '20px', '21px', '22px', '23px', '24px', '25px', '26px', '27px', '28px', '29px', '30px', '31px', '32px', '33px', '34px', '35px', '36px', '37px', '38px', '39px', '40px', '41px', '42px', '43px', '44px', '45px', '46px', '47px', '48px', '49px', '50px', '51px', '52px', '53px', '54px', '55px', '56px', '57px', '58px', '59px', '60px', '61px', '62px', '63px', '64px', '65px', '66px', '67px', '68px', '69px', '70px', '71px', '72px'];
429
+ image.className = 'libs-ui-quill-format-image';
430
+ block.tagName = 'DIV';
431
+ italic.tagName = 'i';
432
+ bold.tagName = 'B';
433
+ Quill.register(bold, true);
434
+ Quill.register(italic, true);
435
+ Quill.register(size, true);
436
+ Quill.register(image, true);
437
+ Quill.register(block, true);
438
+ Quill.register(alignStyle, true);
439
+ Quill.register(QuillMentionBlot, true);
440
+ Quill.register({ 'formats/indent': indentStyle }, true);
441
+ iconList.forEach(element => {
442
+ set(icons, element.key, `<span class="${element.icon} hover:text-[var(--libs-ui-color-light-1)] text-[16px] text-[#6a7383]"></span>`);
443
+ });
444
+ this.quill.set(new Quill(this.quillEditorEl()?.nativeElement, {
445
+ modules: {
446
+ toolbar: {
447
+ container: this.onlyShowContent() && this.quillToolbarEl() ? this.quillToolbarEl()?.nativeElement : this.quillOptionEl()?.nativeElement,
448
+ handlers: this.handlers()
449
+ },
450
+ clipboard: {
451
+ matchVisual: false
452
+ },
453
+ history: {
454
+ delay: 1000,
455
+ maxStack: 100,
456
+ userOnly: false
457
+ },
458
+ keyboard: {
459
+ bindings: {
460
+ enter: {
461
+ key: 13,
462
+ handler: () => this.showMention() ? false : true
463
+ }
464
+ }
465
+ }
466
+ },
467
+ readOnly: this.readonly(),
468
+ placeholder: this.translate.instant(this.placeholder()),
469
+ theme: 'snow',
470
+ bounds: this.isHeightAuto() ? this.wrapperEditorEl()?.nativeElement : this.quillEditorEl()?.nativeElement,
471
+ scrollingContainer: this.isHeightAuto() ? this.wrapperEditorEl()?.nativeElement : null
472
+ }));
473
+ if (!this.autoFocus()) {
474
+ setTimeout(() => this.display.set(true), 200);
475
+ }
476
+ const editorEl = this.editorEl();
477
+ const classInclude = this.classInclude();
478
+ const readonly = this.readonly();
479
+ if (editorEl) {
480
+ if (classInclude || readonly) {
481
+ for (const elementNode of editorEl.nativeElement.lastElementChild.children) {
482
+ if (!elementNode.className.includes('ql-editor')) {
483
+ continue;
484
+ }
485
+ if (classInclude) {
486
+ elementNode.classList.add(classInclude);
487
+ }
488
+ if (readonly) {
489
+ elementNode.classList.add('!bg-[#f8f9fa]');
490
+ }
491
+ }
492
+ }
493
+ if (readonly) {
494
+ for (const elementNode of editorEl.nativeElement.children) {
495
+ if (elementNode.className.includes('ql-toolbar')) {
496
+ elementNode.classList.add('pointer-events-none');
497
+ }
498
+ }
499
+ }
500
+ }
501
+ this.setContent(get(this.item(), this.fieldNameBind(), ''));
502
+ this.quill()?.on('text-change', (event) => {
503
+ const html = this.quill()?.root.innerHTML;
504
+ setTimeout(() => {
505
+ if (event?.ops[1]?.insert === '\n') {
506
+ const range = { index: event?.ops[0].retain };
507
+ const currentLeaf = this.quill()?.getLeaf(range.index)[0];
508
+ const nextLeaf = this.quill()?.getLeaf(range.index + 1)[0];
509
+ this.quill()?.insertEmbed(range.index, 'break', true, 'user');
510
+ if (nextLeaf === null || currentLeaf.parent !== nextLeaf.parent) {
511
+ this.quill()?.insertEmbed(range.index, 'break', true, 'user');
512
+ }
513
+ this.setSelection((range.index || 0) + 1, 0, Quill.sources.SILENT);
514
+ }
515
+ });
516
+ if (html === '<div><br></div>' || html === '<div style="text-align: justify;"><br></div>' || !this.quill()?.getText()) {
517
+ set(this.item(), this.fieldNameBind(), '');
518
+ this.validate();
519
+ this.outChange.emit(get(this.item(), this.fieldNameBind()));
520
+ return;
521
+ }
522
+ this.convertInnerHTML();
523
+ this.validate();
524
+ this.outChange.emit(get(this.item(), this.fieldNameBind()));
525
+ });
526
+ this.quill()?.on('selection-change', (range, oldRange) => {
527
+ if (this.readonly()) {
528
+ return;
529
+ }
530
+ if (range === null && oldRange !== null) {
531
+ this.outBlur.emit();
532
+ return;
533
+ }
534
+ if (range !== null && oldRange === null) {
535
+ this.outFocus.emit();
536
+ return;
537
+ }
538
+ const format = this.quill()?.getFormat();
539
+ if (format) {
540
+ this.getFont(format);
541
+ this.getFontSize(format);
542
+ this.getHeading(format);
543
+ }
544
+ this.outSelectionChange.emit(range && range.length ? true : false);
545
+ });
546
+ set(this.quill(), 'root.onpaste', (event) => {
547
+ if (!event || !event.clipboardData) {
548
+ return;
549
+ }
550
+ const files = event.clipboardData.files;
551
+ if (!files.length) {
552
+ return;
553
+ }
554
+ event.preventDefault();
555
+ const images = [];
556
+ Array.from(files).forEach((file) => {
557
+ if (file && file.type.split('/')[0] === 'image') {
558
+ images.push(file);
559
+ }
560
+ });
561
+ if (this.notAllowUploadImage()) {
562
+ this.outImagePaste.emit(images);
563
+ return;
564
+ }
565
+ this.functionUploadImage()?.(images);
566
+ });
567
+ if (this.autoFocus()) {
568
+ this.quill()?.focus();
569
+ }
570
+ const alignPicker = document.getElementsByClassName('align-quill');
571
+ Array.from(alignPicker).forEach(picker => {
572
+ picker.innerHTML = '<i class="absolute -top-[2px] left-[16px] libs-ui-icon-move-right rotate-90 text-[6a7383] text-[16px] pl-[4px] pt-[4px]"></i>';
573
+ });
574
+ const alignPickerOptions = document.getElementById('ql-picker-options-3');
575
+ if (alignPickerOptions?.className) {
576
+ alignPickerOptions.className = 'ql-picker-options overflow-hidden';
577
+ }
578
+ fromEvent(this.quillEditorEl()?.nativeElement.querySelector('.ql-tooltip'), 'mousedown').pipe(takeUntil(this.onDestroy)).subscribe(event => event.stopPropagation());
579
+ }
580
+ setStyle(type, data) {
581
+ this.quill()?.format(type, data);
582
+ }
583
+ getFontSize(format) {
584
+ const fontSize = format?.size?.toString()?.replace('px', '');
585
+ if (isNaN(parseFloat(fontSize))) {
586
+ this.size.set({ value: 14 });
587
+ return;
588
+ }
589
+ this.size.set({ value: parseFloat(fontSize) });
590
+ }
591
+ getFont(format) {
592
+ const font = listFont().find((item) => item.key === format.font);
593
+ if (!font) {
594
+ this.fontSelected.set({ key: '', item: listFont().find((item) => item.key === '') });
595
+ return;
596
+ }
597
+ this.fontSelected.set({ key: format.font, item: font });
598
+ }
599
+ getHeading(format) {
600
+ if (!format.header || format.header instanceof Array) {
601
+ return;
602
+ }
603
+ this.headingKeySelected = format.header;
604
+ }
605
+ handleUndo() {
606
+ this.quill()?.history?.undo();
607
+ }
608
+ handleRedo() {
609
+ this.quill()?.history?.redo();
610
+ }
611
+ async setContent(content) {
612
+ if (!content) {
613
+ setTimeout(() => set(this.quill(), 'root.innerHTML', ''));
614
+ return;
615
+ }
616
+ const contentXssFilter = await xssFilter(content);
617
+ setTimeout(() => set(this.quill(), 'root.innerHTML', contentXssFilter));
618
+ if (!this.autoFocusBottom()) {
619
+ return;
620
+ }
621
+ setTimeout(() => {
622
+ this.quill()?.blur();
623
+ const range = document.createRange();
624
+ const sel = window.getSelection();
625
+ const target = this.quillEditorEl()?.nativeElement.querySelector('[contenteditable="true"]');
626
+ const contentScroll = this.isHeightAuto() ? this.wrapperEditorEl()?.nativeElement : target;
627
+ range.selectNodeContents(target);
628
+ range.collapse(false);
629
+ sel?.removeAllRanges();
630
+ sel?.addRange(range);
631
+ target.focus();
632
+ contentScroll.scrollTop = contentScroll.scrollHeight;
633
+ }, 100);
634
+ }
635
+ handlerAddEmoji(emoji) {
636
+ const selection = this.quill()?.getSelection(true).index;
637
+ if (!isNil(selection)) {
638
+ this.quill()?.insertText(selection, emoji);
639
+ }
640
+ }
641
+ handleShowUploadLink() {
642
+ this.addLinkComponentRef.set(this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsInputsQuillLinkComponent));
643
+ const instance = this.addLinkComponentRef()?.instance;
644
+ const selection = this.quill()?.getSelection();
645
+ const textSelected = selection?.length ? this.quill()?.getText(selection?.index, selection?.length) : '';
646
+ if (instance) {
647
+ instance.zIndex = this.zIndex;
648
+ instance.textSelected = signal(textSelected);
649
+ instance.outSaveLink.subscribe((item) => {
650
+ this.handleAddLinkQuill(item.title, item.link);
651
+ });
652
+ instance.outClose.subscribe(() => this.dynamicComponentService.remove(this.addLinkComponentRef()));
653
+ }
654
+ this.dynamicComponentService.addToBody(this.addLinkComponentRef());
655
+ }
656
+ handlerUnInsertLink() {
657
+ const selection = this.quill()?.getSelection(true);
658
+ if (!isNil(selection)) {
659
+ this.quill()?.formatText(selection, 'link', false);
660
+ }
661
+ }
662
+ async validate() {
663
+ this.messageErr.set('');
664
+ const validRequired = this.validRequired();
665
+ const item = this.item();
666
+ const fieldNameBind = this.fieldNameBind();
667
+ const value = get(item, fieldNameBind);
668
+ if (validRequired && validRequired.isRequired && (!fieldNameBind || !value || !value.trim())) {
669
+ this.messageErr.set(validRequired.message || ERROR_MESSAGE_EMPTY_VALID);
670
+ this.outLabelError.emit(this.messageErr());
671
+ return false;
672
+ }
673
+ const validMinLength = this.validMinLength();
674
+ if (validMinLength && fieldNameBind && value && value.trim().length < validMinLength.length) {
675
+ this.messageErr.set(validMinLength.message || ERROR_MESSAGE_MIN_LENGTH);
676
+ this.outLabelError.emit(this.messageErr());
677
+ return false;
678
+ }
679
+ const validMaxLength = this.validMaxLength();
680
+ if (validMaxLength && fieldNameBind && value && value.trim().length > this.validMaxLength.length) {
681
+ this.messageErr.set(validMaxLength.message || ERROR_MESSAGE_MAX_LENGTH);
682
+ this.outLabelError.emit(this.messageErr());
683
+ return false;
684
+ }
685
+ this.outLabelError.emit(this.messageErr());
686
+ return true;
687
+ }
688
+ handleAddContentHTML(tagName, content, index) {
689
+ const selection = (index || index === 0) ? index : this.quill()?.getSelection(true).index;
690
+ if (!isNil(selection)) {
691
+ this.quill()?.insertEmbed(selection, tagName, content);
692
+ this.setSelection(selection, content.length);
693
+ }
694
+ }
695
+ async handleAddContentText(content, index) {
696
+ const selection = (index || index === 0) ? index : this.quill()?.getSelection(true).index;
697
+ if (!isNil(selection)) {
698
+ this.quill()?.insertText(selection, content);
699
+ }
700
+ }
701
+ async handleAddLinkQuill(text, url, index) {
702
+ const selection = this.quill()?.getSelection(true);
703
+ const indexInsert = (index || index === 0) ? index : selection?.index;
704
+ if (selection?.length) {
705
+ this.quill()?.deleteText(selection.index, selection.length, Quill.sources.USER);
706
+ }
707
+ if (!isNil(indexInsert)) {
708
+ this.quill()?.insertText(indexInsert, text, 'link', url);
709
+ }
710
+ }
711
+ convertInnerHTML() {
712
+ this.setStyleForContent();
713
+ set(this.item(), this.fieldNameBind(), this.quill()?.root.innerHTML);
714
+ }
715
+ setStyleForContent() {
716
+ const styleArray = [
717
+ { selector: '.ql-font-Arial', style: 'font-family: Arial' },
718
+ { selector: '.ql-font-sans-serif', style: 'font-family: sans-serif' },
719
+ { selector: '.ql-font-serif', style: 'font-family: serif' },
720
+ { selector: '.ql-font-monospace', style: 'font-family: monospace' },
721
+ { selector: '.ql-font-Helvetica', style: 'font-family: Helvetica' },
722
+ { selector: '.libs-ui-quill-format-image', style: 'max-width: 100%; height: auto' },
723
+ { selector: '.libs-ui-quill-mention', style: 'font-weight: 600;-moz-osx-font-smoothing: grayscale;-webkit-font-smoothing: antialiased; color: #7239EA' },
724
+ { selector: 'blockquote', style: 'border-left: 4px solid #ccc; margin-bottom: 5px; margin-top: 5px; padding-left: 16px' }
725
+ ];
726
+ styleArray.forEach((item) => {
727
+ const elements = this.quill()?.root.querySelectorAll(item.selector);
728
+ elements?.forEach((element) => {
729
+ if (item.selector === '.libs-ui-quill-format-image' || item.selector === '.libs-ui-quill-mention' || item.selector === 'blockquote') {
730
+ element.setAttribute('style', item.style);
731
+ return;
732
+ }
733
+ // Fixbug issue: https://admin-cv.mobio.vn/issues/49092
734
+ let styleExist = element.getAttribute('style');
735
+ if (styleExist) {
736
+ ['font-family: Arial', 'font-family: sans-serif', 'font-family: serif', 'font-family: monospace', 'font-family: Helvetica'].forEach(font => {
737
+ styleExist = (styleExist?.includes(`${font};`) ? styleExist?.replace(`${font};`, '') : styleExist?.replace(font, ''));
738
+ });
739
+ }
740
+ element.setAttribute('style', styleExist ? `${styleExist}${styleExist[styleExist.length - 1] === ';' ? '' : ';'}${item.style};` : item.style);
741
+ });
742
+ });
743
+ }
744
+ handleToggleMention(show) {
745
+ this.showMention.set(show);
746
+ }
747
+ async insertImage(image) {
748
+ const sel = window.getSelection();
749
+ if (!sel) {
750
+ return;
751
+ }
752
+ const range = sel.getRangeAt(0);
753
+ if (!this.quill()?.root.contains(range.commonAncestorContainer)) {
754
+ return;
755
+ }
756
+ const selection = this.quill()?.getSelection(true);
757
+ if (!isNil(selection?.index)) {
758
+ this.quill()?.clipboard.dangerouslyPasteHTML(selection.index, image.outerHTML);
759
+ }
760
+ image.remove();
761
+ }
762
+ handlerShowUploadImage() {
763
+ this.mediaUploadComponentRef.set(this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsInputsQuillCustomUploadImageComponent));
764
+ const instance = this.mediaUploadComponentRef()?.instance;
765
+ if (instance) {
766
+ instance.zIndex = input(this.customUploadImage().zIndex || 1203, { transform: value => value });
767
+ instance.maxImageSize = input(this.customUploadImage().maxImageSize || 1048576, { transform: value => value });
768
+ instance.labelConfig = input(this.customUploadImage().labelConfig);
769
+ instance.outClose.subscribe((event) => {
770
+ this.dynamicComponentService.remove(this.mediaUploadComponentRef());
771
+ if (event) {
772
+ this.handleAddContentHTML('image', event);
773
+ }
774
+ });
775
+ }
776
+ this.dynamicComponentService.addToBody(this.mediaUploadComponentRef());
777
+ }
778
+ setSelection(index, length, sources) {
779
+ this.quill()?.setSelection(index, length, sources);
780
+ }
781
+ // private insertMention(event: IMentionInsert) {
782
+ // const range = this.quill()?.getSelection();
783
+ // if (!range) {
784
+ // return;
785
+ // }
786
+ // const cursorPos = range.index;
787
+ // const startPosInsert = cursorPos - event.lengthKey;
788
+ // this.quill()?.deleteText(startPosInsert, event.lengthKey, Quill.sources.USER);
789
+ // this.quill()?.insertEmbed(startPosInsert, 'mention', event.data, Quill.sources.USER);
790
+ // this.quill()?.insertText(startPosInsert + 1, ' ', Quill.sources.USER);
791
+ // this.setSelection(startPosInsert + 2, 0, Quill.sources.USER);
792
+ // }
793
+ // protected handlerInsertMention(data: IMentionInsert) {
794
+ // this.insertMention(data);
795
+ // }
796
+ async setFontSize(size) {
797
+ this.quill()?.format('size', `${size}px`);
798
+ }
799
+ async setColor(color) {
800
+ this.quill()?.format('color', color);
801
+ }
802
+ async setBackground(color) {
803
+ this.quill()?.format('background', color);
804
+ }
805
+ handlerValueChange(value) {
806
+ this.size.update(item => ({ ...item, value: value }));
807
+ this.quill()?.format('size', `${this.size().value}px`);
808
+ }
809
+ handleSelectAlign(event) {
810
+ this.alignSelected.set(event);
811
+ this.setStyle('align', event?.key);
812
+ }
813
+ handleSelectFont(event) {
814
+ this.fontSelected.set(event);
815
+ this.setStyle('font', event?.key);
816
+ }
817
+ ngOnDestroy() {
818
+ this.onDestroy.next();
819
+ this.onDestroy.complete();
820
+ this.dynamicComponentService.remove(this.addLinkComponentRef());
821
+ this.dynamicComponentService.remove(this.mediaUploadComponentRef());
822
+ }
823
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsQuillComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
824
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: LibsUiComponentsInputsQuillComponent, isStandalone: true, selector: "libs_ui-components-inputs-quill", inputs: { optionsToolbar: { classPropertyName: "optionsToolbar", publicName: "optionsToolbar", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, labelConfig: { classPropertyName: "labelConfig", publicName: "labelConfig", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", 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 }, typeOutPutContent: { classPropertyName: "typeOutPutContent", publicName: "typeOutPutContent", isSignal: true, isRequired: false, transformFunction: null }, ignoreShowErrorLabel: { classPropertyName: "ignoreShowErrorLabel", publicName: "ignoreShowErrorLabel", isSignal: true, isRequired: false, transformFunction: null }, showErrorBorder: { classPropertyName: "showErrorBorder", publicName: "showErrorBorder", isSignal: true, isRequired: false, transformFunction: null }, template: { classPropertyName: "template", publicName: "template", 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 }, handlerClickHeader: { classPropertyName: "handlerClickHeader", publicName: "handlerClickHeader", 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 }, onlyShowContent: { classPropertyName: "onlyShowContent", publicName: "onlyShowContent", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, notAllowUploadImage: { classPropertyName: "notAllowUploadImage", publicName: "notAllowUploadImage", isSignal: true, isRequired: false, transformFunction: null }, isHeightAuto: { classPropertyName: "isHeightAuto", publicName: "isHeightAuto", isSignal: true, isRequired: false, transformFunction: null }, customUploadImage: { classPropertyName: "customUploadImage", publicName: "customUploadImage", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, autoFocusBottom: { classPropertyName: "autoFocusBottom", publicName: "autoFocusBottom", isSignal: true, isRequired: false, transformFunction: null }, isShowToolBar: { classPropertyName: "isShowToolBar", publicName: "isShowToolBar", isSignal: true, isRequired: false, transformFunction: null }, classIncludeToolbar: { classPropertyName: "classIncludeToolbar", publicName: "classIncludeToolbar", isSignal: true, isRequired: false, transformFunction: null }, templateToolBarPersonalize: { classPropertyName: "templateToolBarPersonalize", publicName: "templateToolBarPersonalize", isSignal: true, isRequired: false, transformFunction: null }, onlyShowErrorBorderInContent: { classPropertyName: "onlyShowErrorBorderInContent", publicName: "onlyShowErrorBorderInContent", isSignal: true, isRequired: false, transformFunction: null }, functionUploadImage: { classPropertyName: "functionUploadImage", publicName: "functionUploadImage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { outLabelError: "outLabelError", outBlur: "outBlur", outFocus: "outFocus", outChange: "outChange", outFunctionsControl: "outFunctionsControl", outImagePaste: "outImagePaste", outSelectionChange: "outSelectionChange" }, 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: "quillToolbarEl", first: true, predicate: ["quillToolbar"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex flex-col w-full h-full\">\n @if (labelConfig(); as labelConfig) {\n <libs_ui-components-label [classInclude]=\"labelConfig.classInclude\"\n [required]=\"labelConfig.required\"\n [labelLeft]=\"labelConfig.labelLeft\" />\n }\n <div #wrapperEditor\n [attr.isHeightAuto]=\"isHeightAuto()\"\n [attr.hiddenToolBar]=\"onlyShowContent()\"\n class=\"libs-ui-quill-wrapper w-full h-full relative flex flex-col\"\n [class.libs-ui-border-error-general]=\"messageErr() && showErrorBorder() && !onlyShowErrorBorderInContent()\"\n [class.rounded-[4px]]=\"messageErr() && showErrorBorder() && !onlyShowErrorBorderInContent()\">\n <div #editor\n class=\"libs-ui-quill\"\n [attr.showError]=\"messageErr() && showErrorBorder() && onlyShowErrorBorderInContent()\"\n [class.!hidden]=\"!display()\">\n @if (!onlyShowContent()) {\n <div #quillOption\n class=\"'ql-toolbar ql-snow bg-[#f8f9fa] {{ classIncludeToolbar() }}\">\n <ng-container *ngTemplateOutlet=\"toolbarRef\"></ng-container>\n </div>\n }\n <div #quillEditor></div>\n <!-- MoLibsCoreUIMentionConfig\n [mentionConfig]=\"dataConfigMention\"\n (moToggle)=\"handleToggleMention($event)\"\n (moInsertMention)=\"handlerInsertMention($event)\" -->\n </div>\n @if (template(); as template) {\n <div [class]=\"classIncludeTemplate()\">\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>\n }\n </div>\n @if (messageErr() && !ignoreShowErrorLabel()) {\n <div class=\"flex items-center leading-normal mt-[8px]\">\n <span class=\"text-[#ff5454] libs-ui-font-h7r\"> {{ messageErr() | translate }}</span>\n </div>\n }\n</div>\n<div #quillToolbar\n [class]=\"'ql-snow absolute px-[8px] py-[4px] p-0 w-[500px] rounded-[4px] bg-[#ffffff] libs-ui-quill-toolbar-animation ' + classIncludeToolbar() + (isShowToolBar() ? ' block' : ' hidden')\">\n <ng-container *ngTemplateOutlet=\"toolbarRef\"></ng-container>\n</div>\n\n<ng-template #toolbarRef>\n <div class=\"toolbar\">\n <div class=\"ql-formats items-center\">\n @for (option of optionsToolbar(); track $index) {\n <div class=\"flex items-center h-[32px] {{ option.styleGapItem ? option.styleGapItem : 'gap-4' }}\">\n @if (option.undo) {\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content: 'i18n_undo', zIndex: 1250}\"\n class=\"ql-undo\"></button>\n }\n @if (option.redo) {\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content: 'i18n_redo', zIndex: 1250}\"\n class=\"ql-redo\"></button>\n }\n @if (option.fontFamily) {\n <div class=\"relative w-[117px] h-full bg-[#ffffff] rounded-[4px] libs-ui-border-general\">\n <libs_ui-components-dropdown [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-[8px] libs-ui-font-h5r pl-[16px] pr-[40px]\">\n <libs_ui-components-popover [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{zIndex:1250}\">\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.fontSize) {\n <div class=\"ql-picker\">\n <libs_ui-components-inputs-valid [dataType]=\"'int'\"\n [(item)]=\"size\"\n [fieldNameBind]=\"'value'\"\n [defaultHeight]=\"32\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"72\"\n [minValueNumber]=\"8\"\n [readonly]=\"readonly()\"\n [classContainerInput]=\"'w-[72px] h-[32px]'\"\n (outValueChange)=\"handlerValueChange($event)\" />\n </div>\n }\n @if (option.color) {\n <div class=\"ql-color ql-picker ql-color-picker !flex items-center\">\n <libs_ui-components-popover [config]=\"{content:'i18n_text_color', zIndex:1250}\">\n <libs_ui-components-buttons-select_color [zIndex]=\"zIndex()\"\n [externalContent]=\"true\"\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)]\">\n </div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.background) {\n <div class=\"ql-background ql-picker ql-color-picker !flex items-center\">\n <libs_ui-components-popover [config]=\"{content:'i18n_background_color', zIndex:1250}\">\n <libs_ui-components-buttons-select_color [zIndex]=\"zIndex()\"\n [externalContent]=\"true\"\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)]\">\n </div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.bold) {\n <div class=\"flex items-center\">\n <libs_ui-components-popover [config]=\"{content:'i18n_font_weight_bold', zIndex:1250}\">\n <button class=\"ql-bold\"></button>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.italic) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_font_style_italic', zIndex:1250}\"\n class=\"ql-italic\"></button>\n </div>\n }\n @if (option.underline) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_text_decoration_underline', zIndex:1250}\"\n class=\"ql-underline\"></button>\n </div>\n }\n @if (option.strikeThrough) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_text_line_through', zIndex:1250}\"\n class=\"ql-strike\"></button>\n </div>\n }\n @if (option.adjust) {\n <div class=\"relative !flex items-center ql-align ql-picker ql-icon-picker !w-max\">\n <libs_ui-components-popover [config]=\"{content:'i18n_adjust', zIndex:1250}\">\n <libs_ui-components-dropdown [isNgContent]=\"true\"\n [ignoreStopPropagationEvent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigAlign()\"\n [listHiddenInputSearch]=\"true\"\n [popoverCustomConfig]=\"{ignoreArrow: true, classInclude: 'w-[32px] overflow-hidden', 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.indentIncrease) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_indent_increase', zIndex:1250}\"\n class=\"ql-indent\"\n value=\"+1\"></button>\n </div>\n }\n @if (option.indentDecrease) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_indent_decrease', zIndex:1250}\"\n class=\"ql-indent\"\n value=\"-1\"></button>\n </div>\n }\n @if (option.listBulleted) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_list_bulleted', zIndex:1250}\"\n class=\"ql-list ql-bullet\"\n value=\"bullet\"></button>\n </div>\n }\n @if (option.listNumbered) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_list_numbered', zIndex:1250}\"\n class=\"ql-list ql-ordered\"\n value=\"ordered\"></button>\n </div>\n }\n @if (option.personalize && templateToolBarPersonalize(); as templateToolBarPersonalize) {\n <div class=\"flex items-center\">\n <ng-container *ngTemplateOutlet=\"templateToolBarPersonalize\"></ng-container>\n </div>\n }\n @if (option.blockquote) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_quote', zIndex:1250}\"\n class=\"ql-blockquote\"></button>\n </div>\n }\n @if (option.link) {\n <div class=\"flex items-center\">\n <libs_ui-components-popover [config]=\"{content:'i18n_insert_link', zIndex:1250}\">\n <button class=\"ql-link\"></button>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.unLink) {\n <div class=\"flex items-center\">\n <libs_ui-components-popover [config]=\"{content:'i18n_unlink', zIndex:1250}\">\n <button class=\"ql-unLink\"></button>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.image && customUploadImage().showIconUploadImage) {\n <div class=\"flex items-center\">\n <libs_ui-components-popover [config]=\"{content:'i18n_image', zIndex:1250}\">\n <button class=\"ql-image\"></button>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.emoji) {\n <div class=\"flex items-center\">\n <libs_ui-components-emoji [zIndex]=\"1250\"\n [isNgContent]=\"true\"\n (outEventEmoji)=\"handlerAddEmoji($event)\">\n <button class=\"ql-emoji\"></button>\n </libs_ui-components-emoji>\n </div>\n }\n </div>\n @if (!$last) {\n <div class=\"w-[1px] h-[16px] libs-ui-border-right-general mx-[8px]\"></div>\n }\n }\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[isHeightAuto=true]{overflow:auto}.libs-ui-quill-wrapper[isHeightAuto=true] .libs-ui-quill{height:auto}.libs-ui-quill-wrapper[isHeightAuto=true] .libs-ui-quill ::ng-deep .ql-container{height:auto}.libs-ui-quill-wrapper[isHeightAuto=true] .libs-ui-quill ::ng-deep .ql-container .ql-editor{position:relative!important}.libs-ui-quill-wrapper[hiddenToolBar=true] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:0px!important}.libs-ui-quill-wrapper[hiddenToolBar=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[hiddenToolBar=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[hiddenToolBar=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;flex-wrap:wrap}: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:4px 16px}: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}.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: "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", "fieldGetLabel", "labelPopoverConfig", "labelPopoverFullWidth", "hasContentUnitRight", "listSearchNoDataTemplateRef", "fieldGetImage", "imageSize", "typeShape", "fieldGetIcon", "fieldGetTextAvatar", "fieldGetColorAvatar", "classAvatarInclude", "getLastTextAfterSpace", "linkImageError", "showError", "showBorderError", "disable", "readonly", "labelConfig", "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", "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", "button", "applyNow"], outputs: ["zIndexChange", "outColorChange"] }, { kind: "component", type: LibsUiComponentsInputsValidComponent, selector: "libs_ui-components-inputs-valid", inputs: ["item", "labelConfig", "emitEmptyInDataTypeNumber", "ignoreBlockInputMaxValue", "fieldNameBind", "showCount", "typeComponentSelectItem", "valueComponentSelectItem", "disableComponentSelectItem", "tagInput", "dataType", "resetAutoCompletePassword", "textAreaEnterNotNewLine", "hiddenContent", "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"], 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", "moFunctionsControl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
825
+ }
826
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsQuillComponent, decorators: [{
827
+ type: Component,
828
+ args: [{ selector: 'libs_ui-components-inputs-quill', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
829
+ TranslateModule, NgTemplateOutlet,
830
+ LibsUiComponentsLabelComponent, LibsUiComponentsDropdownComponent,
831
+ LibsUiComponentsPopoverComponent, LibsUiComponentsButtonsSelectColorComponent,
832
+ LibsUiComponentsInputsValidComponent, LibsUiComponentsEmojiComponent
833
+ ], template: "<div class=\"flex flex-col w-full h-full\">\n @if (labelConfig(); as labelConfig) {\n <libs_ui-components-label [classInclude]=\"labelConfig.classInclude\"\n [required]=\"labelConfig.required\"\n [labelLeft]=\"labelConfig.labelLeft\" />\n }\n <div #wrapperEditor\n [attr.isHeightAuto]=\"isHeightAuto()\"\n [attr.hiddenToolBar]=\"onlyShowContent()\"\n class=\"libs-ui-quill-wrapper w-full h-full relative flex flex-col\"\n [class.libs-ui-border-error-general]=\"messageErr() && showErrorBorder() && !onlyShowErrorBorderInContent()\"\n [class.rounded-[4px]]=\"messageErr() && showErrorBorder() && !onlyShowErrorBorderInContent()\">\n <div #editor\n class=\"libs-ui-quill\"\n [attr.showError]=\"messageErr() && showErrorBorder() && onlyShowErrorBorderInContent()\"\n [class.!hidden]=\"!display()\">\n @if (!onlyShowContent()) {\n <div #quillOption\n class=\"'ql-toolbar ql-snow bg-[#f8f9fa] {{ classIncludeToolbar() }}\">\n <ng-container *ngTemplateOutlet=\"toolbarRef\"></ng-container>\n </div>\n }\n <div #quillEditor></div>\n <!-- MoLibsCoreUIMentionConfig\n [mentionConfig]=\"dataConfigMention\"\n (moToggle)=\"handleToggleMention($event)\"\n (moInsertMention)=\"handlerInsertMention($event)\" -->\n </div>\n @if (template(); as template) {\n <div [class]=\"classIncludeTemplate()\">\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>\n }\n </div>\n @if (messageErr() && !ignoreShowErrorLabel()) {\n <div class=\"flex items-center leading-normal mt-[8px]\">\n <span class=\"text-[#ff5454] libs-ui-font-h7r\"> {{ messageErr() | translate }}</span>\n </div>\n }\n</div>\n<div #quillToolbar\n [class]=\"'ql-snow absolute px-[8px] py-[4px] p-0 w-[500px] rounded-[4px] bg-[#ffffff] libs-ui-quill-toolbar-animation ' + classIncludeToolbar() + (isShowToolBar() ? ' block' : ' hidden')\">\n <ng-container *ngTemplateOutlet=\"toolbarRef\"></ng-container>\n</div>\n\n<ng-template #toolbarRef>\n <div class=\"toolbar\">\n <div class=\"ql-formats items-center\">\n @for (option of optionsToolbar(); track $index) {\n <div class=\"flex items-center h-[32px] {{ option.styleGapItem ? option.styleGapItem : 'gap-4' }}\">\n @if (option.undo) {\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content: 'i18n_undo', zIndex: 1250}\"\n class=\"ql-undo\"></button>\n }\n @if (option.redo) {\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content: 'i18n_redo', zIndex: 1250}\"\n class=\"ql-redo\"></button>\n }\n @if (option.fontFamily) {\n <div class=\"relative w-[117px] h-full bg-[#ffffff] rounded-[4px] libs-ui-border-general\">\n <libs_ui-components-dropdown [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-[8px] libs-ui-font-h5r pl-[16px] pr-[40px]\">\n <libs_ui-components-popover [type]=\"'text'\"\n [ignoreStopPropagationEvent]=\"true\"\n [config]=\"{zIndex:1250}\">\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.fontSize) {\n <div class=\"ql-picker\">\n <libs_ui-components-inputs-valid [dataType]=\"'int'\"\n [(item)]=\"size\"\n [fieldNameBind]=\"'value'\"\n [defaultHeight]=\"32\"\n [valueUpDownNumber]=\"1\"\n [maxValueNumber]=\"72\"\n [minValueNumber]=\"8\"\n [readonly]=\"readonly()\"\n [classContainerInput]=\"'w-[72px] h-[32px]'\"\n (outValueChange)=\"handlerValueChange($event)\" />\n </div>\n }\n @if (option.color) {\n <div class=\"ql-color ql-picker ql-color-picker !flex items-center\">\n <libs_ui-components-popover [config]=\"{content:'i18n_text_color', zIndex:1250}\">\n <libs_ui-components-buttons-select_color [zIndex]=\"zIndex()\"\n [externalContent]=\"true\"\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)]\">\n </div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.background) {\n <div class=\"ql-background ql-picker ql-color-picker !flex items-center\">\n <libs_ui-components-popover [config]=\"{content:'i18n_background_color', zIndex:1250}\">\n <libs_ui-components-buttons-select_color [zIndex]=\"zIndex()\"\n [externalContent]=\"true\"\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)]\">\n </div>\n </libs_ui-components-buttons-select_color>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.bold) {\n <div class=\"flex items-center\">\n <libs_ui-components-popover [config]=\"{content:'i18n_font_weight_bold', zIndex:1250}\">\n <button class=\"ql-bold\"></button>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.italic) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_font_style_italic', zIndex:1250}\"\n class=\"ql-italic\"></button>\n </div>\n }\n @if (option.underline) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_text_decoration_underline', zIndex:1250}\"\n class=\"ql-underline\"></button>\n </div>\n }\n @if (option.strikeThrough) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_text_line_through', zIndex:1250}\"\n class=\"ql-strike\"></button>\n </div>\n }\n @if (option.adjust) {\n <div class=\"relative !flex items-center ql-align ql-picker ql-icon-picker !w-max\">\n <libs_ui-components-popover [config]=\"{content:'i18n_adjust', zIndex:1250}\">\n <libs_ui-components-dropdown [isNgContent]=\"true\"\n [ignoreStopPropagationEvent]=\"true\"\n [labelPopoverFullWidth]=\"true\"\n [listConfig]=\"listConfigAlign()\"\n [listHiddenInputSearch]=\"true\"\n [popoverCustomConfig]=\"{ignoreArrow: true, classInclude: 'w-[32px] overflow-hidden', 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.indentIncrease) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_indent_increase', zIndex:1250}\"\n class=\"ql-indent\"\n value=\"+1\"></button>\n </div>\n }\n @if (option.indentDecrease) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_indent_decrease', zIndex:1250}\"\n class=\"ql-indent\"\n value=\"-1\"></button>\n </div>\n }\n @if (option.listBulleted) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_list_bulleted', zIndex:1250}\"\n class=\"ql-list ql-bullet\"\n value=\"bullet\"></button>\n </div>\n }\n @if (option.listNumbered) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_list_numbered', zIndex:1250}\"\n class=\"ql-list ql-ordered\"\n value=\"ordered\"></button>\n </div>\n }\n @if (option.personalize && templateToolBarPersonalize(); as templateToolBarPersonalize) {\n <div class=\"flex items-center\">\n <ng-container *ngTemplateOutlet=\"templateToolBarPersonalize\"></ng-container>\n </div>\n }\n @if (option.blockquote) {\n <div class=\"flex items-center\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_quote', zIndex:1250}\"\n class=\"ql-blockquote\"></button>\n </div>\n }\n @if (option.link) {\n <div class=\"flex items-center\">\n <libs_ui-components-popover [config]=\"{content:'i18n_insert_link', zIndex:1250}\">\n <button class=\"ql-link\"></button>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.unLink) {\n <div class=\"flex items-center\">\n <libs_ui-components-popover [config]=\"{content:'i18n_unlink', zIndex:1250}\">\n <button class=\"ql-unLink\"></button>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.image && customUploadImage().showIconUploadImage) {\n <div class=\"flex items-center\">\n <libs_ui-components-popover [config]=\"{content:'i18n_image', zIndex:1250}\">\n <button class=\"ql-image\"></button>\n </libs_ui-components-popover>\n </div>\n }\n @if (option.emoji) {\n <div class=\"flex items-center\">\n <libs_ui-components-emoji [zIndex]=\"1250\"\n [isNgContent]=\"true\"\n (outEventEmoji)=\"handlerAddEmoji($event)\">\n <button class=\"ql-emoji\"></button>\n </libs_ui-components-emoji>\n </div>\n }\n </div>\n @if (!$last) {\n <div class=\"w-[1px] h-[16px] libs-ui-border-right-general mx-[8px]\"></div>\n }\n }\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[isHeightAuto=true]{overflow:auto}.libs-ui-quill-wrapper[isHeightAuto=true] .libs-ui-quill{height:auto}.libs-ui-quill-wrapper[isHeightAuto=true] .libs-ui-quill ::ng-deep .ql-container{height:auto}.libs-ui-quill-wrapper[isHeightAuto=true] .libs-ui-quill ::ng-deep .ql-container .ql-editor{position:relative!important}.libs-ui-quill-wrapper[hiddenToolBar=true] .libs-ui-quill ::ng-deep .ql-container.ql-snow{border:0px!important}.libs-ui-quill-wrapper[hiddenToolBar=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[hiddenToolBar=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[hiddenToolBar=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;flex-wrap:wrap}: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:4px 16px}: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}.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"] }]
834
+ }] });
835
+
836
+ /**
837
+ * Generated bundle index. Do not edit.
838
+ */
839
+
840
+ export { LibsUiComponentsInputsQuillComponent };
841
+ //# sourceMappingURL=libs-ui-components-inputs-quill.mjs.map