@libs-ui/components-inputs-quill 0.2.10-6.2

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,1072 @@
1
+ import { NgTemplateOutlet } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { signal, input, output, Component, ChangeDetectionStrategy, computed, inject, model, viewChild, viewChildren } from '@angular/core';
4
+ import { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
5
+ import { LibsUiComponentsButtonsSelectColorComponent } from '@libs-ui/components-buttons-select-color';
6
+ import { LibsUiComponentsDropdownComponent } from '@libs-ui/components-dropdown';
7
+ import { LibsUiComponentsEmojiComponent } from '@libs-ui/components-inputs-emoji';
8
+ import { LibsUiComponentsInputsMentionDirective } from '@libs-ui/components-inputs-mention';
9
+ import { LibsUiComponentsInputsValidComponent } from '@libs-ui/components-inputs-valid';
10
+ import { LibsUiComponentsLabelComponent } from '@libs-ui/components-label';
11
+ import { LibsUiComponentsPopoverComponent } from '@libs-ui/components-popover';
12
+ import { LibsUiDynamicComponentService } from '@libs-ui/services-dynamic-component';
13
+ import { patternUrl, convertFileToBase64, get, set, isNil, xssFilter, ERROR_MESSAGE_EMPTY_VALID, ERROR_MESSAGE_MIN_LENGTH, ERROR_MESSAGE_MAX_LENGTH } from '@libs-ui/utils';
14
+ import * as i1 from '@ngx-translate/core';
15
+ import { TranslateService, TranslateModule } from '@ngx-translate/core';
16
+ import Quill from 'quill';
17
+ import { Subject, fromEvent, takeUntil } from 'rxjs';
18
+ import { LibsUiComponentsModalComponent } from '@libs-ui/components-modal';
19
+ import { returnListObject } from '@libs-ui/services-http-request';
20
+
21
+ const parchment = Quill.import('parchment');
22
+ const pixelLevels = [1, 2, 3, 4, 5, 6, 7, 8];
23
+ const tabMultiplier = 3;
24
+ class IndentAttributor extends parchment.Attributor.Style {
25
+ constructor(formatName, styleProperty, attributorOptions) {
26
+ super(formatName, styleProperty, attributorOptions);
27
+ }
28
+ add(node, value) {
29
+ return super.add(node, `${+value * tabMultiplier}em`);
30
+ }
31
+ value(node) {
32
+ return parseFloat(super.value(node)) / tabMultiplier || undefined; // Don't return NaN
33
+ }
34
+ }
35
+ const indentStyle = new IndentAttributor('indent', 'margin-left', {
36
+ scope: parchment.Scope.BLOCK,
37
+ whitelist: pixelLevels.map(value => `${value * tabMultiplier}em`),
38
+ });
39
+
40
+ class LibsUiComponentsInputsQuillLinkComponent {
41
+ dataLink = signal({ title: '', link: '' });
42
+ patternLink = signal(patternUrl());
43
+ inputValidFunctionControl = signal([]);
44
+ zIndex = input(1200);
45
+ title = input();
46
+ link = input();
47
+ outClose = output();
48
+ outSaveLink = output();
49
+ ngOnInit() {
50
+ const title = this.title();
51
+ const link = this.link();
52
+ if (title || link) {
53
+ this.dataLink.update(item => ({ ...item, title: title || '', link: link || '' }));
54
+ }
55
+ }
56
+ async handlerFunctionsControl(event) {
57
+ this.inputValidFunctionControl.update(items => [...items, event]);
58
+ }
59
+ async validate() {
60
+ let valid = true;
61
+ for (const control of this.inputValidFunctionControl()) {
62
+ if (!(await control.checkIsValid())) {
63
+ valid = false;
64
+ }
65
+ }
66
+ return valid;
67
+ }
68
+ async handlerEvent(event) {
69
+ if (event !== 'agree') {
70
+ this.outClose.emit();
71
+ return;
72
+ }
73
+ if (await this.validate()) {
74
+ this.outSaveLink.emit(this.dataLink());
75
+ this.outClose.emit();
76
+ }
77
+ }
78
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsQuillLinkComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
79
+ 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 }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { outClose: "outClose", outSaveLink: "outSaveLink" }, ngImport: i0, template: "<libs_ui-components-modal [title]=\"'i18n_insert_link'\"\n [mode]=\"'center'\"\n [height]=\"'auto'\"\n [width]=\"'598px'\"\n [headerConfig]=\"{ignoreHeaderTheme: true}\"\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(), valuePatternShowError: false}]\"\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 });
80
+ }
81
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsQuillLinkComponent, decorators: [{
82
+ type: Component,
83
+ args: [{ selector: 'libs_ui-components-inputs-quill-link', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
84
+ LibsUiComponentsModalComponent,
85
+ LibsUiComponentsInputsValidComponent
86
+ ], template: "<libs_ui-components-modal [title]=\"'i18n_insert_link'\"\n [mode]=\"'center'\"\n [height]=\"'auto'\"\n [width]=\"'598px'\"\n [headerConfig]=\"{ignoreHeaderTheme: true}\"\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(), valuePatternShowError: false}]\"\n [keySelectedUnitLeft]=\"'1'\"\n [unitsLeft]=\"[{id:'1',label:'URL'}]\"\n (outFunctionsControl)=\"handlerFunctionsControl($event)\" />\n </div>\n </div>\n</libs_ui-components-modal>\n" }]
87
+ }] });
88
+
89
+ const Embed = Quill.import("blots/embed");
90
+ class QuillMentionBlot extends Embed {
91
+ static create(data) {
92
+ const node = super.create();
93
+ node.innerText += data.value;
94
+ node.setAttribute('id', data.id);
95
+ node.setAttribute('feId', data.feId);
96
+ node.setAttribute('value', data.value);
97
+ return node;
98
+ }
99
+ static value(domNode) {
100
+ return {
101
+ id: domNode.getAttribute('id'),
102
+ feId: domNode.getAttribute('feId'),
103
+ value: domNode.getAttribute('value')
104
+ };
105
+ }
106
+ attach() {
107
+ super.attach();
108
+ if (!this.mounted) {
109
+ this.mounted = true;
110
+ this.clickHandler = this.getClickHandler;
111
+ this.domNode.addEventListener("click", this.clickHandler, false);
112
+ }
113
+ }
114
+ getClickHandler(event) {
115
+ event.stopPropagation();
116
+ }
117
+ }
118
+ QuillMentionBlot.blotName = "mention";
119
+ QuillMentionBlot.tagName = "span";
120
+ QuillMentionBlot.className = "libs-ui-quill-mention";
121
+
122
+ class LibsUiComponentsInputsQuillUploadImageComponent {
123
+ buttonFooter = signal([
124
+ {
125
+ type: 'button-third',
126
+ label: 'i18n_cancel',
127
+ action: async () => this.outClose.emit()
128
+ },
129
+ {
130
+ label: 'i18n_save',
131
+ action: () => this.handlerSaveImage()
132
+ }
133
+ ]);
134
+ disable = signal(false);
135
+ // private mediaFile =signal<IMediaFile | undefined>(undefined);
136
+ // private mediaUploadFunctionControl =signal<IMediaUploadBaseFunctionControlEvent | undefined>(undefined);
137
+ uploadImageConfig = input.required();
138
+ outClose = output();
139
+ // protected handlerFunctionsControl(event: IMediaUploadBaseFunctionControlEvent) {
140
+ // this.mediaUploadFunctionControl.set(event);
141
+ // }
142
+ // protected handlerChangeFile(event: IChangeFile) {
143
+ // this.mediaFile.set(event.files[0]);
144
+ // }
145
+ async handlerSaveImage() {
146
+ // if (!await this.mediaUploadFunctionControl()?.valid()) {
147
+ // return;
148
+ // }
149
+ // if (this.mediaFile?.origin_url) {
150
+ // this.moClose.emit(this.mediaFile.origin_url);
151
+ // return;
152
+ // }
153
+ // const body: IOptionsUploadMedia = {
154
+ // do_not_delete: true,
155
+ // file: this.mediaFile?.file,
156
+ // option: 'thumb',
157
+ // size: [{ 'width': '200', 'height': '200' }]
158
+ // };
159
+ // this.disable = true;
160
+ // try {
161
+ // const params = new HttpParamsRequest({ fromObject: { pem: BUILD_PEM_OBJECT({ isCheck: 0, action: DefineConstants.PERMISSION_ACTION_VIEW, pathCheck: '/other' }) } });
162
+ // const res = await this.mediaService.uploadImage(params, body);
163
+ // this.moClose.emit(res.data?.url);
164
+ // } catch (error) {
165
+ // console.log(error);
166
+ // this.pushMessageService.showCompTypeText('i18n_notification_manipulation_not_success', undefined, undefined, { timeRemove: 2000, type: 'error' });
167
+ // this.moClose.emit();
168
+ // } finally {
169
+ // this.disable = false;
170
+ // }
171
+ }
172
+ handlerEventModal(event) {
173
+ if (event === 'close') {
174
+ this.outClose.emit();
175
+ }
176
+ }
177
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsQuillUploadImageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
178
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: LibsUiComponentsInputsQuillUploadImageComponent, isStandalone: true, selector: "libs_ui-components-inputs-quill-upload_image", inputs: { uploadImageConfig: { classPropertyName: "uploadImageConfig", publicName: "uploadImageConfig", isSignal: true, isRequired: true, 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]=\"uploadImageConfig().zIndex || 1203\"\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 || 1048576\"\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 });
179
+ }
180
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsQuillUploadImageComponent, decorators: [{
181
+ type: Component,
182
+ args: [{ selector: 'libs_ui-components-inputs-quill-upload_image', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
183
+ LibsUiComponentsModalComponent
184
+ ], 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]=\"uploadImageConfig().zIndex || 1203\"\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 || 1048576\"\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" }]
185
+ }] });
186
+
187
+ const listDataAlign = () => {
188
+ return [
189
+ { key: '', icon: 'libs-ui-icon-align-left text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]' },
190
+ { key: 'right', icon: 'libs-ui-icon-align-right text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]' },
191
+ { key: 'center', icon: 'libs-ui-icon-align-center text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]' },
192
+ { key: 'justify', icon: 'libs-ui-icon-align-justify text-[#6a7383] text-[16px] hover:text-[var(--libs-ui-color-light-1)]' },
193
+ ];
194
+ };
195
+ const listFont = () => {
196
+ return [
197
+ { key: '', label: 'Sans Serif' },
198
+ { key: 'serif', label: 'Serif' },
199
+ { key: 'monospace', label: 'Monospace' },
200
+ ];
201
+ };
202
+ const listConfigAlign = () => {
203
+ return {
204
+ type: 'text',
205
+ autoSelectFirstItem: true,
206
+ httpRequestData: signal({
207
+ serviceOther: returnListObject(listDataAlign()),
208
+ functionName: 'list',
209
+ argumentsValue: []
210
+ }),
211
+ configTemplateText: signal({
212
+ fieldKey: 'key',
213
+ getClassItem: () => '!px-[8px] !py-[4px]',
214
+ getValue: item => `<i class='flex ${item.icon}'></i>`,
215
+ ignoreIconSelected: true
216
+ })
217
+ };
218
+ };
219
+ const listConfigFont = () => {
220
+ return {
221
+ type: 'text',
222
+ autoSelectFirstItem: true,
223
+ httpRequestData: signal({
224
+ serviceOther: returnListObject(listFont()),
225
+ functionName: 'list',
226
+ argumentsValue: []
227
+ }),
228
+ configTemplateText: signal({
229
+ fieldKey: 'key',
230
+ getValue: item => item.label,
231
+ ignoreIconSelected: true
232
+ })
233
+ };
234
+ };
235
+ const toolBarOptionDefault = () => {
236
+ return [
237
+ {
238
+ type: 'undo',
239
+ classInclude: 'mr-[8px]'
240
+ },
241
+ {
242
+ type: 'redo'
243
+ },
244
+ {
245
+ type: 'line'
246
+ },
247
+ {
248
+ type: 'fontFamily',
249
+ classInclude: 'ml-[8px] mr-[2px]'
250
+ },
251
+ {
252
+ type: 'fontSize',
253
+ classInclude: 'ml-[2px] mr-[8px]'
254
+ },
255
+ {
256
+ type: 'line'
257
+ },
258
+ {
259
+ type: 'color'
260
+ },
261
+ {
262
+ type: 'background'
263
+ },
264
+ {
265
+ type: 'line'
266
+ },
267
+ {
268
+ type: 'bold'
269
+ },
270
+ {
271
+ type: 'italic'
272
+ },
273
+ {
274
+ type: 'underline'
275
+ },
276
+ {
277
+ type: 'strikeThrough'
278
+ },
279
+ {
280
+ type: 'line'
281
+ },
282
+ {
283
+ type: 'adjust'
284
+ },
285
+ {
286
+ type: 'line'
287
+ },
288
+ {
289
+ type: 'indentIncrease'
290
+ },
291
+ {
292
+ type: 'indentDecrease'
293
+ },
294
+ {
295
+ type: 'listBulleted'
296
+ },
297
+ {
298
+ type: 'listNumbered'
299
+ },
300
+ {
301
+ type: 'line'
302
+ },
303
+ {
304
+ type: 'personalize'
305
+ },
306
+ {
307
+ type: 'blockquote'
308
+ },
309
+ {
310
+ type: 'link'
311
+ },
312
+ {
313
+ type: 'unLink'
314
+ },
315
+ {
316
+ type: 'image'
317
+ },
318
+ {
319
+ type: 'emoji',
320
+ classInclude: 'ml-[8px]'
321
+ }
322
+ ];
323
+ };
324
+ const iconList = () => {
325
+ return [
326
+ {
327
+ key: 'bold',
328
+ icon: 'libs-ui-icon-editor-bold',
329
+ },
330
+ {
331
+ key: 'italic',
332
+ icon: 'libs-ui-icon-editor-italic',
333
+ },
334
+ {
335
+ key: 'underline',
336
+ icon: 'libs-ui-icon-editor-underlined',
337
+ },
338
+ {
339
+ key: 'image',
340
+ icon: 'libs-ui-icon-image-solid'
341
+ },
342
+ {
343
+ key: 'link',
344
+ icon: 'libs-ui-icon-link'
345
+ },
346
+ {
347
+ key: 'undo',
348
+ icon: 'libs-ui-icon-undo'
349
+ },
350
+ {
351
+ key: 'redo',
352
+ icon: 'libs-ui-icon-undo scale-x-[-1]'
353
+ },
354
+ {
355
+ key: 'strike',
356
+ icon: 'libs-ui-icon-editor-strike-through'
357
+ },
358
+ {
359
+ key: 'blockquote',
360
+ icon: 'libs-ui-icon-quote'
361
+ },
362
+ {
363
+ key: 'ordered',
364
+ icon: 'libs-ui-icon-list-numbered'
365
+ },
366
+ {
367
+ key: 'bullet',
368
+ icon: 'libs-ui-icon-list-bulleted'
369
+ },
370
+ {
371
+ key: 'background',
372
+ icon: 'libs-ui-icon-editor-color-background'
373
+ },
374
+ {
375
+ key: 'color',
376
+ icon: 'libs-ui-icon-editor-color-text'
377
+ },
378
+ {
379
+ key: "indent.-1",
380
+ icon: 'libs-ui-icon-indent-decrease'
381
+ },
382
+ {
383
+ key: "indent.+1",
384
+ icon: 'libs-ui-icon-indent-increase'
385
+ },
386
+ {
387
+ key: "align.",
388
+ icon: 'align-quill libs-ui-icon-align-left'
389
+ },
390
+ {
391
+ key: "align.center",
392
+ icon: 'align-quill libs-ui-icon-align-center'
393
+ },
394
+ {
395
+ key: "align.right",
396
+ icon: 'align-quill libs-ui-icon-align-right'
397
+ },
398
+ {
399
+ key: "align.justify",
400
+ icon: 'align-quill libs-ui-icon-align-justify'
401
+ },
402
+ {
403
+ key: 'unLink',
404
+ icon: 'libs-ui-icon-link-broken'
405
+ },
406
+ {
407
+ key: 'emoji',
408
+ icon: 'libs-ui-icon-face-smile'
409
+ }
410
+ ];
411
+ };
412
+ const uploadImageConfigDefault = () => {
413
+ return {
414
+ modeCustom: true,
415
+ zIndex: 1202,
416
+ showIcon: true,
417
+ onlyAcceptImageHttpsLink: false,
418
+ functionUploadImage: async (links) => {
419
+ const data = [];
420
+ for (const element of links) {
421
+ data.push(await convertFileToBase64(element));
422
+ }
423
+ return data;
424
+ }
425
+ };
426
+ };
427
+ const linkDefault = () => {
428
+ return {
429
+ title: '',
430
+ url: '',
431
+ range: {
432
+ index: 0,
433
+ length: 0
434
+ }
435
+ };
436
+ };
437
+
438
+ class LibsUiComponentsInputsQuillComponent {
439
+ messageError = signal('');
440
+ display = signal(false);
441
+ listConfigAlign = signal(listConfigAlign());
442
+ alignSelected = signal(undefined);
443
+ iconAlignSelectedComputed = computed(() => get(this.alignSelected(), 'item.icon'));
444
+ listConfigFont = signal(listConfigFont());
445
+ fontSelected = signal(undefined);
446
+ labelFontSelectedComputed = computed(() => get(this.fontSelected(), 'item.label') || 'Sans Serif');
447
+ size = signal({ value: 14 });
448
+ itemHiddenExpand = signal([]);
449
+ itemHidden = signal([]);
450
+ showMoreAction = signal(false);
451
+ link = signal(linkDefault());
452
+ popoverFunctionControl = signal(undefined);
453
+ quill = signal(undefined);
454
+ handlers = signal({ undo: this.handleUndo.bind(this), redo: this.handleRedo.bind(this) });
455
+ showMention = signal(false);
456
+ addEditLinkComponentRef = signal(undefined);
457
+ uploadImageComponentRef = signal(undefined);
458
+ dynamicComponentService = inject(LibsUiDynamicComponentService);
459
+ translate = inject(TranslateService);
460
+ onDestroy = new Subject();
461
+ optionsToolbar = input(toolBarOptionDefault(), { transform: value => value || toolBarOptionDefault() });
462
+ showToolBar = input();
463
+ classIncludeToolbar = input('bottom-[-66px] left-[18px]');
464
+ placeholder = input('i18n_import_content', { transform: (value) => value || 'i18n_import_content' });
465
+ label = input();
466
+ item = model();
467
+ fieldNameBind = input('value');
468
+ readonly = input();
469
+ showErrorLabel = input(true);
470
+ showErrorBorder = input(false);
471
+ onlyShowErrorBorderInContent = input(false);
472
+ classIncludeTemplate = input();
473
+ classInclude = input();
474
+ handlersExpand = input();
475
+ validRequired = input();
476
+ validMinLength = input();
477
+ validMaxLength = input();
478
+ onlyShowContent = input(false);
479
+ zIndex = input(1201, { transform: (value) => value || 1201 });
480
+ dataConfigMention = input();
481
+ heightAuto = input();
482
+ autoFocus = input();
483
+ autoFocusBottom = input();
484
+ templateToolBarPersonalize = input();
485
+ template = input();
486
+ uploadImageConfig = input(uploadImageConfigDefault(), { transform: (value) => value || uploadImageConfigDefault() });
487
+ outMessageError = output();
488
+ outBlur = output();
489
+ outFocus = output();
490
+ outChange = output();
491
+ outFunctionsControl = output();
492
+ outSelectionChange = output();
493
+ wrapperEditorEl = viewChild('wrapperEditor');
494
+ editorEl = viewChild('editor');
495
+ quillOptionEl = viewChild('quillOption');
496
+ quillEditorEl = viewChild('quillEditor');
497
+ quillToolbarEl = viewChild('quillToolbar');
498
+ toolbarItemsEl = viewChild('toolbarItems');
499
+ itemsEl = viewChildren('item');
500
+ ngOnInit() {
501
+ this.outFunctionsControl.emit({
502
+ checkIsValid: this.validate.bind(this),
503
+ setContent: this.setContent.bind(this),
504
+ insertText: this.insertText.bind(this),
505
+ insertLink: this.insertLink.bind(this),
506
+ insertHtml: this.insertHtml.bind(this),
507
+ setFontSize: this.setFontSize.bind(this),
508
+ setColor: this.setColor.bind(this),
509
+ setBackground: this.setBackground.bind(this)
510
+ });
511
+ }
512
+ ngAfterViewInit() {
513
+ this.calculatorToolbar();
514
+ if (this.autoFocus()) {
515
+ this.display.set(true);
516
+ }
517
+ this.setHandlerFunction();
518
+ this.initQuill();
519
+ if (!this.autoFocus()) {
520
+ setTimeout(() => this.display.set(true), 200);
521
+ }
522
+ this.setClassIncludeAndReadOnly();
523
+ this.setContent(get(this.item(), this.fieldNameBind(), ''));
524
+ this.handlerTextChange();
525
+ this.handlerSelectionChange();
526
+ this.handlerPaste();
527
+ if (this.autoFocus()) {
528
+ this.quill()?.focus();
529
+ }
530
+ fromEvent(window, 'resize').pipe(takeUntil(this.onDestroy)).subscribe(this.calculatorToolbar.bind(this));
531
+ }
532
+ initQuill() {
533
+ const size = Quill.import('attributors/style/size');
534
+ const image = Quill.import('formats/image');
535
+ const parchment = Quill.import('parchment');
536
+ const alignStyle = Quill.import('attributors/style/align');
537
+ const icons = Quill.import('ui/icons');
538
+ const block = parchment.query('block');
539
+ const italic = Quill.import('formats/italic');
540
+ const bold = Quill.import('formats/bold');
541
+ 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'];
542
+ image.className = 'libs-ui-quill-format-image';
543
+ block.tagName = 'DIV';
544
+ italic.tagName = 'i';
545
+ bold.tagName = 'B';
546
+ Quill.register(bold, true);
547
+ Quill.register(italic, true);
548
+ Quill.register(size, true);
549
+ Quill.register(image, true);
550
+ Quill.register(block, true);
551
+ Quill.register(alignStyle, true);
552
+ Quill.register(QuillMentionBlot, true);
553
+ Quill.register({ 'formats/indent': indentStyle }, true);
554
+ iconList().forEach(element => set(icons, element.key, `<span class="${element.icon} hover:text-[var(--libs-ui-color-light-1)] text-[16px] text-[#6a7383]"></span>`));
555
+ this.quill.set(new Quill(this.quillEditorEl()?.nativeElement, {
556
+ modules: {
557
+ toolbar: {
558
+ container: this.onlyShowContent() && this.quillToolbarEl() ? this.quillToolbarEl()?.nativeElement : this.quillOptionEl()?.nativeElement,
559
+ handlers: this.handlers()
560
+ },
561
+ clipboard: {
562
+ matchVisual: false
563
+ },
564
+ history: {
565
+ delay: 1000,
566
+ maxStack: 100,
567
+ userOnly: false
568
+ },
569
+ keyboard: {
570
+ bindings: {
571
+ enter: {
572
+ key: 13,
573
+ handler: () => this.showMention() ? false : true
574
+ }
575
+ }
576
+ }
577
+ },
578
+ readOnly: this.readonly(),
579
+ placeholder: this.translate.instant(this.placeholder()),
580
+ theme: 'snow',
581
+ bounds: this.heightAuto() ? this.wrapperEditorEl()?.nativeElement : this.quillEditorEl()?.nativeElement,
582
+ scrollingContainer: this.heightAuto() ? this.wrapperEditorEl()?.nativeElement : null
583
+ }));
584
+ }
585
+ setHandlerFunction() {
586
+ if (this.uploadImageConfig().modeCustom) {
587
+ this.handlers.update(item => ({ ...item, image: this.handlerShowUploadImage.bind(this), emoji: () => { return; } }));
588
+ }
589
+ let link = false;
590
+ const handlersExpand = this.handlersExpand();
591
+ if (handlersExpand && handlersExpand.length) {
592
+ handlersExpand.forEach(element => {
593
+ if (element.title && element.action) {
594
+ if (element.title === 'link') {
595
+ link = true;
596
+ }
597
+ this.handlers.update(item => ({ ...item, [element.title]: element.action }));
598
+ }
599
+ });
600
+ }
601
+ if (!link) {
602
+ this.handlers.update(item => ({ ...item, link: this.handleShowUploadLink.bind(this), unLink: this.handlerUnInsertLink.bind(this) }));
603
+ }
604
+ }
605
+ setClassIncludeAndReadOnly() {
606
+ const editorEl = this.editorEl();
607
+ const classInclude = this.classInclude();
608
+ const readonly = this.readonly();
609
+ if (editorEl) {
610
+ if (classInclude || readonly) {
611
+ for (const elementNode of editorEl.nativeElement.lastElementChild.children) {
612
+ if (!elementNode.className.includes('ql-editor')) {
613
+ continue;
614
+ }
615
+ if (classInclude) {
616
+ elementNode.classList.add(classInclude);
617
+ }
618
+ if (readonly) {
619
+ elementNode.classList.add('!bg-[#f8f9fa]');
620
+ }
621
+ }
622
+ }
623
+ if (readonly) {
624
+ for (const elementNode of editorEl.nativeElement.children) {
625
+ if (elementNode.className.includes('ql-toolbar')) {
626
+ elementNode.classList.add('pointer-events-none');
627
+ }
628
+ }
629
+ }
630
+ }
631
+ }
632
+ adjustIndexForImages(index) {
633
+ const content = this.quill()?.root;
634
+ let imageCount = 0;
635
+ let adjustedIndex = 0;
636
+ const adjustTextIndex = (node) => {
637
+ if (adjustedIndex > index) {
638
+ return;
639
+ }
640
+ if (node.nodeType === Node.TEXT_NODE) {
641
+ adjustedIndex += node.textContent?.length || 0;
642
+ return;
643
+ }
644
+ if (node.nodeType === Node.ELEMENT_NODE && node.nodeName === 'IMG') {
645
+ if (adjustedIndex <= index) {
646
+ imageCount++;
647
+ }
648
+ return;
649
+ }
650
+ if (node.nodeType === Node.ELEMENT_NODE) {
651
+ Array.from(node.childNodes).forEach(adjustTextIndex);
652
+ }
653
+ };
654
+ adjustTextIndex(content);
655
+ return imageCount;
656
+ }
657
+ ;
658
+ handlerSelectionChange() {
659
+ this.quill()?.on('selection-change', (range, oldRange, source) => {
660
+ if (this.readonly()) {
661
+ return;
662
+ }
663
+ if (range === null && oldRange !== null) {
664
+ this.outBlur.emit();
665
+ return;
666
+ }
667
+ if (range !== null && oldRange === null) {
668
+ this.outFocus.emit();
669
+ return;
670
+ }
671
+ const format = this.quill()?.getFormat();
672
+ if (format) {
673
+ this.getFont(format);
674
+ this.getFontSize(format);
675
+ }
676
+ this.outSelectionChange.emit(range.length ? true : false);
677
+ if (range.length === 0 && format?.link && source === 'user') {
678
+ const selection = document.getSelection();
679
+ const anchorNode = selection?.anchorNode;
680
+ let linkNode = anchorNode;
681
+ while (linkNode && linkNode.tagName !== 'A') {
682
+ linkNode = linkNode.parentNode;
683
+ }
684
+ if (linkNode && linkNode.tagName === 'A') {
685
+ const linkText = linkNode.innerText;
686
+ const linksIndices = [];
687
+ let indexReturn = -1;
688
+ while (!isNil(indexReturn) && indexReturn < range.index) {
689
+ const textContent = this.quill()?.getText();
690
+ const linkIndex = textContent?.indexOf(linkText, linksIndices.length > 0 ? linksIndices[linksIndices.length - 1] + linkText.length : 0);
691
+ if (!isNil(linkIndex)) {
692
+ if (linkIndex !== -1) {
693
+ linksIndices.push(linkIndex);
694
+ indexReturn = linkIndex + linkText.length;
695
+ }
696
+ if (linkIndex === -1) {
697
+ indexReturn = undefined;
698
+ }
699
+ }
700
+ }
701
+ if (linksIndices && linksIndices.length) {
702
+ const rangeIndex = linksIndices[linksIndices.length - 1];
703
+ const countImage = this.adjustIndexForImages(rangeIndex);
704
+ setTimeout(() => {
705
+ this.link.set({
706
+ title: linkText,
707
+ url: linkNode.href,
708
+ range: {
709
+ index: rangeIndex + countImage,
710
+ length: linkText.length
711
+ }
712
+ });
713
+ this.popoverFunctionControl()?.showPopover(linkNode);
714
+ }, 250);
715
+ }
716
+ }
717
+ }
718
+ });
719
+ }
720
+ handlerPaste() {
721
+ set(this.quill, 'root.onpaste', async (event) => {
722
+ if (!event || !event.clipboardData) {
723
+ return;
724
+ }
725
+ const files = event.clipboardData.files;
726
+ if (!files.length) {
727
+ return;
728
+ }
729
+ event.preventDefault();
730
+ const images = [];
731
+ Array.from(files).forEach((file) => {
732
+ if (file && file.type.split('/')[0] === 'image') {
733
+ images.push(file);
734
+ }
735
+ });
736
+ const links = await this.uploadImageConfig().functionUploadImage?.(images);
737
+ if (links && links.length) {
738
+ links.forEach(link => {
739
+ if (!link || (this.uploadImageConfig().onlyAcceptImageHttpsLink && (link instanceof ArrayBuffer || !new RegExp(patternUrl()).test(link)))) {
740
+ return;
741
+ }
742
+ this.insertHtml('image', link);
743
+ });
744
+ }
745
+ });
746
+ }
747
+ handlerTextChange() {
748
+ this.quill()?.on('text-change', (event) => {
749
+ const html = this.quill()?.root.innerHTML;
750
+ setTimeout(() => {
751
+ if (event?.ops[1]?.insert === '\n') {
752
+ const range = { index: event?.ops[0].retain };
753
+ const currentLeaf = this.quill()?.getLeaf(range.index)[0];
754
+ const nextLeaf = this.quill()?.getLeaf(range.index + 1)[0];
755
+ this.quill()?.insertEmbed(range.index, 'break', true, 'user');
756
+ if (nextLeaf === null || currentLeaf.parent !== nextLeaf.parent) {
757
+ this.quill()?.insertEmbed(range.index, 'break', true, 'user');
758
+ }
759
+ this.setSelection((range.index || 0) + 1, 0, Quill.sources.SILENT);
760
+ }
761
+ });
762
+ if (html === '<div><br></div>' || html === '<div style="text-align: justify;"><br></div>' || !this.quill()?.getText()) {
763
+ set(this.item(), this.fieldNameBind(), '');
764
+ this.validate();
765
+ this.outChange.emit(get(this.item(), this.fieldNameBind()));
766
+ return;
767
+ }
768
+ this.convertInnerHTML();
769
+ this.validate();
770
+ this.outChange.emit(get(this.item(), this.fieldNameBind()));
771
+ });
772
+ }
773
+ handlerPopoverFunctionControl(event) {
774
+ this.popoverFunctionControl.set(event);
775
+ }
776
+ handlerPopoverEvent(event) {
777
+ if (event === 'remove') {
778
+ this.link.set(linkDefault());
779
+ }
780
+ }
781
+ handlerUnlink(event) {
782
+ event.stopPropagation();
783
+ const link = this.link();
784
+ this.quill()?.formatText(link.range.index, link.range.length, { link: false });
785
+ this.popoverFunctionControl()?.removePopoverOverlay();
786
+ }
787
+ handlerEdit(event) {
788
+ event.stopPropagation();
789
+ const link = this.link();
790
+ this.handleShowUploadLink(link);
791
+ this.popoverFunctionControl()?.removePopoverOverlay();
792
+ }
793
+ calculatorToolbar() {
794
+ this.itemHidden.set([]);
795
+ this.itemHiddenExpand.set([]);
796
+ setTimeout(() => {
797
+ const toolbarWidth = this.toolbarItemsEl()?.nativeElement.offsetWidth || 0;
798
+ let itemWidth = 28;
799
+ const hiddenItems = [];
800
+ const hiddenItemsExpand = [];
801
+ const itemsHasWidth = this.itemsEl().filter(item => item.nativeElement.offsetWidth);
802
+ for (let index = 0; index < itemsHasWidth.length; index++) {
803
+ const element = itemsHasWidth[index];
804
+ const id = element.nativeElement.id;
805
+ const trueIndex = Number(id.split('_')[1]);
806
+ const type = id.split('_')[0];
807
+ const width = element.nativeElement.offsetWidth || 0;
808
+ itemWidth += width;
809
+ if (type === 'line') {
810
+ const nextElement = itemsHasWidth[index + 1];
811
+ const nextWidth = nextElement?.nativeElement.offsetWidth || 0;
812
+ const nextItemWidth = itemWidth + nextWidth;
813
+ if (nextItemWidth > toolbarWidth) {
814
+ hiddenItemsExpand.push(trueIndex);
815
+ }
816
+ }
817
+ if (itemWidth > toolbarWidth) {
818
+ hiddenItems.push(trueIndex);
819
+ continue;
820
+ }
821
+ }
822
+ this.itemHidden.set(hiddenItems);
823
+ this.itemHiddenExpand.set(hiddenItemsExpand);
824
+ }, 500);
825
+ }
826
+ setStyle(type, data) {
827
+ this.quill()?.format(type, data);
828
+ }
829
+ getFontSize(format) {
830
+ const fontSize = format?.size?.toString()?.replace('px', '');
831
+ if (isNaN(parseFloat(fontSize))) {
832
+ this.size.set({ value: 14 });
833
+ return;
834
+ }
835
+ this.size.set({ value: parseFloat(fontSize) });
836
+ }
837
+ getFont(format) {
838
+ const font = listFont().find((item) => item.key === format.font);
839
+ if (!font) {
840
+ this.fontSelected.set({ key: '', item: listFont().find((item) => item.key === '') });
841
+ return;
842
+ }
843
+ this.fontSelected.set({ key: format.font, item: font });
844
+ }
845
+ handleUndo() {
846
+ this.quill()?.history?.undo();
847
+ }
848
+ handleRedo() {
849
+ this.quill()?.history?.redo();
850
+ }
851
+ async setContent(content) {
852
+ if (!content) {
853
+ setTimeout(() => set(this.quill, 'root.innerHTML', ''));
854
+ return;
855
+ }
856
+ const contentXssFilter = await xssFilter(content);
857
+ setTimeout(() => set(this.quill, 'root.innerHTML', contentXssFilter));
858
+ if (!this.autoFocusBottom()) {
859
+ return;
860
+ }
861
+ setTimeout(() => {
862
+ this.quill()?.blur();
863
+ const range = document.createRange();
864
+ const sel = window.getSelection();
865
+ const target = this.quillEditorEl()?.nativeElement.querySelector('[contenteditable="true"]');
866
+ const contentScroll = this.heightAuto() ? this.wrapperEditorEl()?.nativeElement : target;
867
+ range.selectNodeContents(target);
868
+ range.collapse(false);
869
+ sel?.removeAllRanges();
870
+ sel?.addRange(range);
871
+ target.focus();
872
+ contentScroll.scrollTop = contentScroll.scrollHeight;
873
+ }, 100);
874
+ }
875
+ handlerAddEmoji(emoji) {
876
+ const selection = this.quill()?.getSelection(true).index;
877
+ if (!isNil(selection)) {
878
+ this.quill()?.insertText(selection, emoji);
879
+ }
880
+ }
881
+ handleShowUploadLink(event) {
882
+ this.addEditLinkComponentRef.set(this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsInputsQuillLinkComponent));
883
+ const instance = this.addEditLinkComponentRef()?.instance;
884
+ const selection = this.quill()?.getSelection();
885
+ const textSelected = selection?.length ? this.quill()?.getText(selection?.index, selection?.length) : '';
886
+ const data = event;
887
+ this.addEditLinkComponentRef()?.setInput('zIndex', this.zIndex());
888
+ this.addEditLinkComponentRef()?.setInput('title', data?.title || textSelected);
889
+ this.addEditLinkComponentRef()?.setInput('link', data?.url || '');
890
+ instance?.outSaveLink.subscribe((item) => {
891
+ if (data instanceof Object && data.url) {
892
+ this.quill()?.deleteText(data.range.index, data.range.length, Quill.sources.USER);
893
+ this.quill()?.insertText(data.range.index, item.title, 'link', item.link);
894
+ return;
895
+ }
896
+ this.insertLink(item.title, item.link);
897
+ });
898
+ instance?.outClose.subscribe(() => this.dynamicComponentService.remove(this.addEditLinkComponentRef()));
899
+ this.dynamicComponentService.addToBody(this.addEditLinkComponentRef());
900
+ }
901
+ handlerUnInsertLink() {
902
+ const selection = this.quill()?.getSelection(true);
903
+ if (!isNil(selection)) {
904
+ this.quill()?.formatText(selection, 'link', false);
905
+ }
906
+ }
907
+ async validate() {
908
+ this.messageError.set('');
909
+ const validRequired = this.validRequired();
910
+ const item = this.item();
911
+ const fieldNameBind = this.fieldNameBind();
912
+ const value = get(item, fieldNameBind);
913
+ if (validRequired && validRequired.isRequired && (!fieldNameBind || !value || !value.trim())) {
914
+ this.messageError.set(validRequired.message || ERROR_MESSAGE_EMPTY_VALID);
915
+ this.outMessageError.emit(this.messageError());
916
+ return false;
917
+ }
918
+ const validMinLength = this.validMinLength();
919
+ if (validMinLength && fieldNameBind && value && value.trim().length < validMinLength.length) {
920
+ this.messageError.set(validMinLength.message || ERROR_MESSAGE_MIN_LENGTH);
921
+ this.outMessageError.emit(this.messageError());
922
+ return false;
923
+ }
924
+ const validMaxLength = this.validMaxLength();
925
+ if (validMaxLength && fieldNameBind && value && value.trim().length > this.validMaxLength.length) {
926
+ this.messageError.set(validMaxLength.message || ERROR_MESSAGE_MAX_LENGTH);
927
+ this.outMessageError.emit(this.messageError());
928
+ return false;
929
+ }
930
+ this.outMessageError.emit(this.messageError());
931
+ return true;
932
+ }
933
+ async insertHtml(tagName, content, index) {
934
+ const selection = (index || index === 0) ? index : this.quill()?.getSelection(true).index;
935
+ if (!isNil(selection)) {
936
+ this.quill()?.insertEmbed(selection, tagName, content);
937
+ this.setSelection(selection, content.length);
938
+ }
939
+ }
940
+ async insertText(content, index) {
941
+ const selection = (index || index === 0) ? index : this.quill()?.getSelection(true).index;
942
+ if (!isNil(selection)) {
943
+ this.quill()?.insertText(selection, content);
944
+ }
945
+ }
946
+ async insertLink(text, url, index) {
947
+ const selection = this.quill()?.getSelection(true);
948
+ const indexInsert = (index || index === 0) ? index : selection?.index;
949
+ if (selection?.length) {
950
+ this.quill()?.deleteText(selection.index, selection.length, Quill.sources.USER);
951
+ }
952
+ if (!isNil(indexInsert)) {
953
+ this.quill()?.insertText(indexInsert, text, 'link', url);
954
+ }
955
+ }
956
+ convertInnerHTML() {
957
+ this.setStyleForContent();
958
+ set(this.item(), this.fieldNameBind(), this.quill()?.root.innerHTML);
959
+ }
960
+ setStyleForContent() {
961
+ const styleArray = [
962
+ { selector: '.ql-font-Arial', style: 'font-family: Arial' },
963
+ { selector: '.ql-font-sans-serif', style: 'font-family: sans-serif' },
964
+ { selector: '.ql-font-serif', style: 'font-family: serif' },
965
+ { selector: '.ql-font-monospace', style: 'font-family: monospace' },
966
+ { selector: '.ql-font-Helvetica', style: 'font-family: Helvetica' },
967
+ { selector: '.libs-ui-quill-format-image', style: 'max-width: 100%; height: auto' },
968
+ { selector: '.libs-ui-quill-mention', style: 'font-weight: 600;-moz-osx-font-smoothing: grayscale;-webkit-font-smoothing: antialiased; color: #7239EA' },
969
+ { selector: 'blockquote', style: 'border-left: 4px solid #ccc; margin-bottom: 5px; margin-top: 5px; padding-left: 16px' }
970
+ ];
971
+ styleArray.forEach((item) => {
972
+ const elements = this.quill()?.root.querySelectorAll(item.selector);
973
+ elements?.forEach((element) => {
974
+ if (item.selector === '.libs-ui-quill-format-image' || item.selector === '.libs-ui-quill-mention' || item.selector === 'blockquote') {
975
+ element.setAttribute('style', item.style);
976
+ return;
977
+ }
978
+ // Fixbug issue: https://admin-cv.mobio.vn/issues/49092
979
+ let styleExist = element.getAttribute('style');
980
+ if (styleExist) {
981
+ ['font-family: Arial', 'font-family: sans-serif', 'font-family: serif', 'font-family: monospace', 'font-family: Helvetica'].forEach(font => {
982
+ styleExist = (styleExist?.includes(`${font};`) ? styleExist?.replace(`${font};`, '') : styleExist?.replace(font, ''));
983
+ });
984
+ }
985
+ element.setAttribute('style', styleExist ? `${styleExist}${styleExist[styleExist.length - 1] === ';' ? '' : ';'}${item.style};` : item.style);
986
+ });
987
+ });
988
+ }
989
+ handleToggleMention(show) {
990
+ this.showMention.set(show);
991
+ }
992
+ handlerShowUploadImage() {
993
+ this.uploadImageComponentRef.set(this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsInputsQuillUploadImageComponent));
994
+ const instance = this.uploadImageComponentRef()?.instance;
995
+ this.uploadImageComponentRef()?.setInput('uploadImageConfig', this.uploadImageConfig());
996
+ instance?.outClose.subscribe((event) => {
997
+ this.dynamicComponentService.remove(this.uploadImageComponentRef());
998
+ if (event) {
999
+ this.insertHtml('image', event);
1000
+ }
1001
+ });
1002
+ this.dynamicComponentService.addToBody(this.uploadImageComponentRef());
1003
+ }
1004
+ setSelection(index, length, sources) {
1005
+ this.quill()?.setSelection(index, length, sources);
1006
+ }
1007
+ insertMention(event) {
1008
+ const range = this.quill()?.getSelection();
1009
+ if (!range) {
1010
+ return;
1011
+ }
1012
+ const cursorPos = range.index;
1013
+ const startPosInsert = cursorPos - event.lengthKey;
1014
+ this.quill()?.deleteText(startPosInsert, event.lengthKey, Quill.sources.USER);
1015
+ this.quill()?.insertEmbed(startPosInsert, 'mention', event.data, Quill.sources.USER);
1016
+ this.quill()?.insertText(startPosInsert + 1, ' ', Quill.sources.USER);
1017
+ this.setSelection(startPosInsert + 2, 0, Quill.sources.USER);
1018
+ }
1019
+ handlerInsertMention(data) {
1020
+ this.insertMention(data);
1021
+ }
1022
+ async setFontSize(size) {
1023
+ this.quill()?.format('size', `${size}px`);
1024
+ }
1025
+ async setColor(color) {
1026
+ this.quill()?.format('color', color);
1027
+ }
1028
+ async setBackground(color) {
1029
+ this.quill()?.format('background', color);
1030
+ }
1031
+ handlerValueChange(value) {
1032
+ this.size.update(item => ({ ...item, value: value }));
1033
+ this.quill()?.format('size', `${this.size().value}px`);
1034
+ }
1035
+ handleSelectAlign(event) {
1036
+ this.alignSelected.set(event);
1037
+ this.setStyle('align', event?.key);
1038
+ }
1039
+ handleSelectFont(event) {
1040
+ this.fontSelected.set(event);
1041
+ this.setStyle('font', event?.key);
1042
+ }
1043
+ handlerChangeShowMoreAction(event) {
1044
+ event.stopPropagation();
1045
+ this.showMoreAction.update(item => !item);
1046
+ }
1047
+ ngOnDestroy() {
1048
+ this.onDestroy.next();
1049
+ this.onDestroy.complete();
1050
+ this.dynamicComponentService.remove(this.addEditLinkComponentRef());
1051
+ this.dynamicComponentService.remove(this.uploadImageComponentRef());
1052
+ }
1053
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsQuillComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1054
+ 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 }, showToolBar: { classPropertyName: "showToolBar", publicName: "showToolBar", isSignal: true, isRequired: false, transformFunction: null }, classIncludeToolbar: { classPropertyName: "classIncludeToolbar", publicName: "classIncludeToolbar", 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 }, 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 }, onlyShowContent: { classPropertyName: "onlyShowContent", publicName: "onlyShowContent", 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 }, heightAuto: { classPropertyName: "heightAuto", publicName: "heightAuto", 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 }, 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 } }, outputs: { item: "itemChange", outMessageError: "outMessageError", outBlur: "outBlur", outFocus: "outFocus", outChange: "outChange", outFunctionsControl: "outFunctionsControl", 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 }, { propertyName: "toolbarItemsEl", first: true, predicate: ["toolbarItems"], descendants: true, isSignal: true }, { propertyName: "itemsEl", predicate: ["item"], 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 [classInclude]=\"label.classInclude\"\n [required]=\"label.required\"\n [labelLeft]=\"label.labelLeft\" />\n }\n <div #wrapperEditor\n [attr.heightAuto]=\"heightAuto()\"\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]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\"\n [class.rounded-[4px]]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\">\n <div #editor\n class=\"libs-ui-quill\"\n [attr.showError]=\"messageError() && 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=\"toolbar\"></ng-container>\n </div>\n }\n <div #quillEditor\n LibsUiComponentsInputsMentionDirective\n [mentionConfig]=\"dataConfigMention()\"\n (outToggle)=\"handleToggleMention($event)\"\n (outInsertMention)=\"handlerInsertMention($event)\"></div>\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 (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@if (showToolBar()) {\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()\">\n <ng-container *ngTemplateOutlet=\"toolbar\"></ng-container>\n </div>\n}\n\n<ng-template #toolbar>\n <div class=\"toolbar\"\n #toolbarItems>\n <div class=\"ql-formats items-center\">\n @for (option of optionsToolbar(); track option) {\n <div #item\n [id]=\"option.type+'_'+$index\"\n class=\"items-center\"\n [class.hidden]=\"itemHidden().includes($index) || itemHiddenExpand().includes($index)\"\n [class.flex]=\"!itemHidden().includes($index)\">\n <ng-container *ngTemplateOutlet=\"itemTemplate;context:{option, $index, $last}\"></ng-container>\n </div>\n }\n <div class=\"relative\">\n @if (itemHidden().length) {\n <libs_ui-components-buttons-button [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 <div [class.hidden]=\"!showMoreAction()\"\n class=\"absolute bg-[#ffffff] top-[10px] shadow-md z-[1] flex items-center pl-[8px] pr-[16px] py-[4px] rounded-[8px] top-[31px] right-[0px]\">\n @for (option of optionsToolbar(); track option) {\n <div class=\"items-center\"\n [class.hidden]=\"!itemHidden().includes($index)\"\n [class.flex]=\"itemHidden().includes($index)\">\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\n<ng-template #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 LibsUiComponentsPopoverDirective\n [config]=\"{content: 'i18n_undo', zIndex: 1250}\"\n class=\"ql-undo\"></button>\n </div>\n }\n @if (option.type === 'redo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content: 'i18n_redo', zIndex: 1250}\"\n class=\"ql-redo\"></button>\n </div>\n }\n @if (option.type === 'fontFamily') {\n <div class=\"relative w-[117px] h-full bg-[#ffffff] rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\">\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] {{ option.classInclude || 'mx-[8px]' }}\">\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.type === 'fontSize') {\n <div class=\"ql-picker {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-inputs-valid [dataType]=\"'int'\"\n [(item)]=\"size\"\n [fieldNameBind]=\"'value'\"\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.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:1250}\">\n <libs_ui-components-buttons-select_color [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [applyNow]=\"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.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:1250}\">\n <libs_ui-components-buttons-select_color [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [applyNow]=\"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.type === 'bold') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_font_weight_bold', zIndex:1250}\"\n class=\"ql-bold\"></button>\n </div>\n }\n @if (option.type === 'italic') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_font_style_italic', zIndex:1250}\"\n class=\"ql-italic\"></button>\n </div>\n }\n @if (option.type === 'underline') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_text_decoration_underline', zIndex:1250}\"\n class=\"ql-underline\"></button>\n </div>\n }\n @if (option.type === 'strikeThrough') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_text_line_through', zIndex:1250}\"\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: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 !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 LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_indent_increase', zIndex:1250}\"\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 LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_indent_decrease', zIndex:1250}\"\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 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.type === 'listNumbered') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\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.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 LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_quote', zIndex:1250}\"\n class=\"ql-blockquote\"></button>\n </div>\n }\n @if (option.type === 'link') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_insert_link', zIndex:1250}\"\n class=\"ql-link\"></button>\n </div>\n }\n @if (option.type === 'unLink') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_unlink', zIndex:1250}\"\n class=\"ql-unLink\"></button>\n </div>\n }\n @if (option.type === 'image' && uploadImageConfig().showIcon) {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_image', zIndex:1250}\"\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 [zIndex]=\"1250\"\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 [mode]=\"'click'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [config]=\"{template: viewLink, whiteTheme: true, ignoreArrow: true}\"\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 class=\"w-full min-w-0 libs-ui-font-h5r\"\n [type]=\"'text'\"\n LibsUiComponentsPopoverDirective>{{ link().url }}</div>\n <div class=\"flex items-center ml-[16px]\">\n <libs_ui-components-buttons-button [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 [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]{overflow:auto}.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[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}: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}: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: ["mentionConfig", "mentionListTemplate"], outputs: ["outSearchTerm", "outItemSelected", "outToggle", "outInsertMention", "outFunctionControl"] }, { 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", "direction", "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"] }, { 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"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1055
+ }
1056
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsQuillComponent, decorators: [{
1057
+ type: Component,
1058
+ args: [{ selector: 'libs_ui-components-inputs-quill', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1059
+ TranslateModule, NgTemplateOutlet, LibsUiComponentsInputsMentionDirective,
1060
+ LibsUiComponentsLabelComponent, LibsUiComponentsDropdownComponent,
1061
+ LibsUiComponentsPopoverComponent, LibsUiComponentsButtonsSelectColorComponent,
1062
+ LibsUiComponentsInputsValidComponent, LibsUiComponentsEmojiComponent,
1063
+ LibsUiComponentsButtonsButtonComponent
1064
+ ], template: "<div class=\"flex flex-col w-full h-full\">\n @if (label(); as label) {\n <libs_ui-components-label [classInclude]=\"label.classInclude\"\n [required]=\"label.required\"\n [labelLeft]=\"label.labelLeft\" />\n }\n <div #wrapperEditor\n [attr.heightAuto]=\"heightAuto()\"\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]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\"\n [class.rounded-[4px]]=\"messageError() && showErrorBorder() && !onlyShowErrorBorderInContent()\">\n <div #editor\n class=\"libs-ui-quill\"\n [attr.showError]=\"messageError() && 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=\"toolbar\"></ng-container>\n </div>\n }\n <div #quillEditor\n LibsUiComponentsInputsMentionDirective\n [mentionConfig]=\"dataConfigMention()\"\n (outToggle)=\"handleToggleMention($event)\"\n (outInsertMention)=\"handlerInsertMention($event)\"></div>\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 (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@if (showToolBar()) {\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()\">\n <ng-container *ngTemplateOutlet=\"toolbar\"></ng-container>\n </div>\n}\n\n<ng-template #toolbar>\n <div class=\"toolbar\"\n #toolbarItems>\n <div class=\"ql-formats items-center\">\n @for (option of optionsToolbar(); track option) {\n <div #item\n [id]=\"option.type+'_'+$index\"\n class=\"items-center\"\n [class.hidden]=\"itemHidden().includes($index) || itemHiddenExpand().includes($index)\"\n [class.flex]=\"!itemHidden().includes($index)\">\n <ng-container *ngTemplateOutlet=\"itemTemplate;context:{option, $index, $last}\"></ng-container>\n </div>\n }\n <div class=\"relative\">\n @if (itemHidden().length) {\n <libs_ui-components-buttons-button [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 <div [class.hidden]=\"!showMoreAction()\"\n class=\"absolute bg-[#ffffff] top-[10px] shadow-md z-[1] flex items-center pl-[8px] pr-[16px] py-[4px] rounded-[8px] top-[31px] right-[0px]\">\n @for (option of optionsToolbar(); track option) {\n <div class=\"items-center\"\n [class.hidden]=\"!itemHidden().includes($index)\"\n [class.flex]=\"itemHidden().includes($index)\">\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\n<ng-template #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 LibsUiComponentsPopoverDirective\n [config]=\"{content: 'i18n_undo', zIndex: 1250}\"\n class=\"ql-undo\"></button>\n </div>\n }\n @if (option.type === 'redo') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content: 'i18n_redo', zIndex: 1250}\"\n class=\"ql-redo\"></button>\n </div>\n }\n @if (option.type === 'fontFamily') {\n <div class=\"relative w-[117px] h-full bg-[#ffffff] rounded-[4px] libs-ui-border-general {{ option.classInclude || 'mx-[8px]' }}\">\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] {{ option.classInclude || 'mx-[8px]' }}\">\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.type === 'fontSize') {\n <div class=\"ql-picker {{ option.classInclude || 'mx-[8px]' }}\">\n <libs_ui-components-inputs-valid [dataType]=\"'int'\"\n [(item)]=\"size\"\n [fieldNameBind]=\"'value'\"\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.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:1250}\">\n <libs_ui-components-buttons-select_color [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [applyNow]=\"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.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:1250}\">\n <libs_ui-components-buttons-select_color [zIndex]=\"zIndex()\"\n [direction]=\"'top'\"\n [externalContent]=\"true\"\n [applyNow]=\"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.type === 'bold') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_font_weight_bold', zIndex:1250}\"\n class=\"ql-bold\"></button>\n </div>\n }\n @if (option.type === 'italic') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_font_style_italic', zIndex:1250}\"\n class=\"ql-italic\"></button>\n </div>\n }\n @if (option.type === 'underline') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_text_decoration_underline', zIndex:1250}\"\n class=\"ql-underline\"></button>\n </div>\n }\n @if (option.type === 'strikeThrough') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_text_line_through', zIndex:1250}\"\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: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 !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 LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_indent_increase', zIndex:1250}\"\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 LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_indent_decrease', zIndex:1250}\"\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 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.type === 'listNumbered') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\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.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 LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_quote', zIndex:1250}\"\n class=\"ql-blockquote\"></button>\n </div>\n }\n @if (option.type === 'link') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_insert_link', zIndex:1250}\"\n class=\"ql-link\"></button>\n </div>\n }\n @if (option.type === 'unLink') {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_unlink', zIndex:1250}\"\n class=\"ql-unLink\"></button>\n </div>\n }\n @if (option.type === 'image' && uploadImageConfig().showIcon) {\n <div [class]=\"option.classInclude || 'mx-[8px]'\">\n <button LibsUiComponentsPopoverDirective\n [config]=\"{content:'i18n_image', zIndex:1250}\"\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 [zIndex]=\"1250\"\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 [mode]=\"'click'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [config]=\"{template: viewLink, whiteTheme: true, ignoreArrow: true}\"\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 class=\"w-full min-w-0 libs-ui-font-h5r\"\n [type]=\"'text'\"\n LibsUiComponentsPopoverDirective>{{ link().url }}</div>\n <div class=\"flex items-center ml-[16px]\">\n <libs_ui-components-buttons-button [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 [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]{overflow:auto}.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[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}: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}: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"] }]
1065
+ }] });
1066
+
1067
+ /**
1068
+ * Generated bundle index. Do not edit.
1069
+ */
1070
+
1071
+ export { LibsUiComponentsInputsQuillComponent };
1072
+ //# sourceMappingURL=libs-ui-components-inputs-quill.mjs.map