angular-matecu 4.0.7 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/README.md +347 -130
  2. package/ng-package.json +7 -0
  3. package/package.json +6 -21
  4. package/src/lib/components/matecu-alert-box/matecu-alert-box.component.html +11 -0
  5. package/src/lib/components/matecu-alert-box/matecu-alert-box.component.scss +39 -0
  6. package/src/lib/components/matecu-alert-box/matecu-alert-box.component.spec.ts +25 -0
  7. package/src/lib/components/matecu-alert-box/matecu-alert-box.component.ts +60 -0
  8. package/src/lib/components/matecu-alert-dialog/matecu-alert-dialog.component.html +24 -0
  9. package/src/lib/components/matecu-alert-dialog/matecu-alert-dialog.component.scss +5 -0
  10. package/src/lib/components/matecu-alert-dialog/matecu-alert-dialog.component.spec.ts +25 -0
  11. package/src/lib/components/matecu-alert-dialog/matecu-alert-dialog.component.ts +53 -0
  12. package/src/lib/components/matecu-alert-snack-bar/matecu-alert-snack-bar.component.html +10 -0
  13. package/src/lib/components/matecu-alert-snack-bar/matecu-alert-snack-bar.component.scss +34 -0
  14. package/src/lib/components/matecu-alert-snack-bar/matecu-alert-snack-bar.component.spec.ts +25 -0
  15. package/src/lib/components/matecu-alert-snack-bar/matecu-alert-snack-bar.component.ts +45 -0
  16. package/src/lib/components/matecu-autocomplete/matecu-autocomplete.html +36 -0
  17. package/src/lib/components/matecu-autocomplete/matecu-autocomplete.scss +56 -0
  18. package/src/lib/components/matecu-autocomplete/matecu-autocomplete.spec.ts +23 -0
  19. package/src/lib/components/matecu-autocomplete/matecu-autocomplete.ts +336 -0
  20. package/src/lib/components/matecu-autocomplete-multiple/matecu-autocomplete-multiple.html +64 -0
  21. package/src/lib/components/matecu-autocomplete-multiple/matecu-autocomplete-multiple.scss +23 -0
  22. package/src/lib/components/matecu-autocomplete-multiple/matecu-autocomplete-multiple.spec.ts +23 -0
  23. package/src/lib/components/matecu-autocomplete-multiple/matecu-autocomplete-multiple.ts +314 -0
  24. package/src/lib/components/matecu-file-input/matecu-file-input-customization.md +284 -0
  25. package/src/lib/components/matecu-file-input/matecu-file-input.example.md +228 -0
  26. package/src/lib/components/matecu-file-input/matecu-file-input.html +128 -0
  27. package/src/lib/components/matecu-file-input/matecu-file-input.scss +461 -0
  28. package/src/lib/components/matecu-file-input/matecu-file-input.spec.ts +340 -0
  29. package/src/lib/components/matecu-file-input/matecu-file-input.ts +438 -0
  30. package/src/lib/components/matecu-spinner/matecu-spinner.component.css +15 -0
  31. package/src/lib/components/matecu-spinner/matecu-spinner.component.html +44 -0
  32. package/src/lib/components/matecu-spinner/matecu-spinner.component.spec.ts +25 -0
  33. package/src/lib/components/matecu-spinner/matecu-spinner.component.ts +54 -0
  34. package/src/lib/components/matecu-spinner/spinner-loader.component.scss +13 -0
  35. package/src/lib/components/matecu-topbar-action/matecu-topbar-action.component.html +1 -0
  36. package/src/lib/components/matecu-topbar-action/matecu-topbar-action.component.scss +19 -0
  37. package/src/lib/components/matecu-topbar-action/matecu-topbar-action.component.spec.ts +25 -0
  38. package/src/lib/components/matecu-topbar-action/matecu-topbar-action.component.ts +14 -0
  39. package/src/lib/components/matecu-topbar-body/matecu-topbar-body.component.html +1 -0
  40. package/src/lib/components/matecu-topbar-body/matecu-topbar-body.component.scss +14 -0
  41. package/src/lib/components/matecu-topbar-body/matecu-topbar-body.component.spec.ts +25 -0
  42. package/src/lib/components/matecu-topbar-body/matecu-topbar-body.component.ts +11 -0
  43. package/src/lib/components/matecu-topbar-fab/matecu-topbar-fab.component.html +3 -0
  44. package/src/lib/components/matecu-topbar-fab/matecu-topbar-fab.component.scss +19 -0
  45. package/src/lib/components/matecu-topbar-fab/matecu-topbar-fab.component.spec.ts +25 -0
  46. package/src/lib/components/matecu-topbar-fab/matecu-topbar-fab.component.ts +31 -0
  47. package/src/lib/components/matecu-topbar-header-column/matecu-topbar-header-column.component.html +1 -0
  48. package/src/lib/components/matecu-topbar-header-column/matecu-topbar-header-column.component.scss +8 -0
  49. package/src/lib/components/matecu-topbar-header-column/matecu-topbar-header-column.component.spec.ts +23 -0
  50. package/src/lib/components/matecu-topbar-header-column/matecu-topbar-header-column.component.ts +11 -0
  51. package/src/lib/components/matecu-topbar-header-row/matecu-topbar-header-row.component.html +9 -0
  52. package/src/lib/components/matecu-topbar-header-row/matecu-topbar-header-row.component.scss +34 -0
  53. package/src/lib/components/matecu-topbar-header-row/matecu-topbar-header-row.component.spec.ts +23 -0
  54. package/src/lib/components/matecu-topbar-header-row/matecu-topbar-header-row.component.ts +18 -0
  55. package/src/lib/components/matecu-topbar-layout/matecu-topbar-layout.component.html +7 -0
  56. package/src/lib/components/matecu-topbar-layout/matecu-topbar-layout.component.scss +49 -0
  57. package/src/lib/components/matecu-topbar-layout/matecu-topbar-layout.component.spec.ts +25 -0
  58. package/src/lib/components/matecu-topbar-layout/matecu-topbar-layout.component.ts +112 -0
  59. package/src/lib/components/matecu-topbar-search/matecu-topbar-search.component.html +20 -0
  60. package/src/lib/components/matecu-topbar-search/matecu-topbar-search.component.scss +90 -0
  61. package/src/lib/components/matecu-topbar-search/matecu-topbar-search.component.spec.ts +25 -0
  62. package/src/lib/components/matecu-topbar-search/matecu-topbar-search.component.ts +92 -0
  63. package/src/lib/components/matecu-topbar-title/matecu-topbar-title.component.html +1 -0
  64. package/src/lib/components/matecu-topbar-title/matecu-topbar-title.component.scss +91 -0
  65. package/src/lib/components/matecu-topbar-title/matecu-topbar-title.component.spec.ts +25 -0
  66. package/src/lib/components/matecu-topbar-title/matecu-topbar-title.component.ts +14 -0
  67. package/src/lib/modules/matecu-alert-box/matecu-alert-box.module.ts +16 -0
  68. package/src/lib/modules/matecu-spinner/matecu-spinner.module.ts +14 -0
  69. package/src/lib/modules/matecu-topbar-layout/matecu-topbar-layout.module.ts +45 -0
  70. package/src/lib/services/matecu-snack-bar.service.spec.ts +16 -0
  71. package/src/lib/services/matecu-snack-bar.service.ts +66 -0
  72. package/src/lib/services/matecu-spinner.service.spec.ts +16 -0
  73. package/src/lib/services/matecu-spinner.service.ts +39 -0
  74. package/src/lib/types/matecu-alert-dialog.ts +10 -0
  75. package/{lib/types/matecu-alert-snackbar.d.ts → src/lib/types/matecu-alert-snackbar.ts} +5 -4
  76. package/src/lib/types/matecu-altert-box-type.ts +6 -0
  77. package/src/lib/types/matecu-autocomplete.ts +5 -0
  78. package/{public-api.d.ts → src/public-api.ts} +14 -0
  79. package/tsconfig.lib.json +17 -0
  80. package/tsconfig.lib.prod.json +11 -0
  81. package/tsconfig.spec.json +15 -0
  82. package/CHANGELOG.md +0 -22
  83. package/esm2022/angular-matecu.mjs +0 -5
  84. package/esm2022/lib/components/matecu-alert-box/matecu-alert-box.component.mjs +0 -67
  85. package/esm2022/lib/components/matecu-alert-dialog/matecu-alert-dialog.component.mjs +0 -54
  86. package/esm2022/lib/components/matecu-alert-snack-bar/matecu-alert-snack-bar.component.mjs +0 -43
  87. package/esm2022/lib/components/matecu-spinner/matecu-spinner.component.mjs +0 -58
  88. package/esm2022/lib/components/matecu-topbar-action/matecu-topbar-action.component.mjs +0 -18
  89. package/esm2022/lib/components/matecu-topbar-body/matecu-topbar-body.component.mjs +0 -17
  90. package/esm2022/lib/components/matecu-topbar-fab/matecu-topbar-fab.component.mjs +0 -43
  91. package/esm2022/lib/components/matecu-topbar-header-column/matecu-topbar-header-column.component.mjs +0 -12
  92. package/esm2022/lib/components/matecu-topbar-header-row/matecu-topbar-header-row.component.mjs +0 -29
  93. package/esm2022/lib/components/matecu-topbar-layout/matecu-topbar-layout.component.mjs +0 -112
  94. package/esm2022/lib/components/matecu-topbar-search/matecu-topbar-search.component.mjs +0 -93
  95. package/esm2022/lib/components/matecu-topbar-title/matecu-topbar-title.component.mjs +0 -18
  96. package/esm2022/lib/modules/matecu-alert-box/matecu-alert-box.module.mjs +0 -24
  97. package/esm2022/lib/modules/matecu-spinner/matecu-spinner.module.mjs +0 -22
  98. package/esm2022/lib/modules/matecu-topbar-layout/matecu-topbar-layout.module.mjs +0 -83
  99. package/esm2022/lib/services/matecu-snack-bar.service.mjs +0 -66
  100. package/esm2022/lib/services/matecu-spinner.service.mjs +0 -44
  101. package/esm2022/lib/types/matecu-alert-dialog.mjs +0 -2
  102. package/esm2022/lib/types/matecu-alert-snackbar.mjs +0 -2
  103. package/esm2022/lib/types/matecu-altert-box-type.mjs +0 -8
  104. package/esm2022/public-api.mjs +0 -32
  105. package/fesm2022/angular-matecu.mjs +0 -735
  106. package/fesm2022/angular-matecu.mjs.map +0 -1
  107. package/index.d.ts +0 -5
  108. package/lib/components/matecu-alert-box/matecu-alert-box.component.d.ts +0 -19
  109. package/lib/components/matecu-alert-dialog/matecu-alert-dialog.component.d.ts +0 -22
  110. package/lib/components/matecu-alert-snack-bar/matecu-alert-snack-bar.component.d.ts +0 -20
  111. package/lib/components/matecu-spinner/matecu-spinner.component.d.ts +0 -20
  112. package/lib/components/matecu-topbar-action/matecu-topbar-action.component.d.ts +0 -9
  113. package/lib/components/matecu-topbar-body/matecu-topbar-body.component.d.ts +0 -6
  114. package/lib/components/matecu-topbar-fab/matecu-topbar-fab.component.d.ts +0 -12
  115. package/lib/components/matecu-topbar-header-column/matecu-topbar-header-column.component.d.ts +0 -5
  116. package/lib/components/matecu-topbar-header-row/matecu-topbar-header-row.component.d.ts +0 -8
  117. package/lib/components/matecu-topbar-layout/matecu-topbar-layout.component.d.ts +0 -27
  118. package/lib/components/matecu-topbar-search/matecu-topbar-search.component.d.ts +0 -27
  119. package/lib/components/matecu-topbar-title/matecu-topbar-title.component.d.ts +0 -9
  120. package/lib/modules/matecu-alert-box/matecu-alert-box.module.d.ts +0 -14
  121. package/lib/modules/matecu-spinner/matecu-spinner.module.d.ts +0 -8
  122. package/lib/modules/matecu-topbar-layout/matecu-topbar-layout.module.d.ts +0 -19
  123. package/lib/services/matecu-snack-bar.service.d.ts +0 -17
  124. package/lib/services/matecu-spinner.service.d.ts +0 -15
  125. package/lib/types/matecu-alert-dialog.d.ts +0 -9
  126. package/lib/types/matecu-altert-box-type.d.ts +0 -6
@@ -0,0 +1,336 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import {
3
+ Component,
4
+ Input,
5
+ Output,
6
+ EventEmitter,
7
+ OnChanges,
8
+ SimpleChanges,
9
+ OnInit,
10
+ OnDestroy,
11
+ ElementRef,
12
+ DoCheck,
13
+ Injector,
14
+ } from '@angular/core';
15
+ import {
16
+ ControlValueAccessor,
17
+ FormsModule,
18
+ NG_VALUE_ACCESSOR,
19
+ ReactiveFormsModule,
20
+ NgControl,
21
+ } from '@angular/forms';
22
+ import { FormControl } from '@angular/forms';
23
+ import { MatAutocompleteModule } from '@angular/material/autocomplete';
24
+ import { MatDividerModule } from '@angular/material/divider';
25
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
26
+ import { MatFormFieldControl } from '@angular/material/form-field';
27
+ import { Observable, startWith, map, Subject, tap, combineLatest, debounceTime } from 'rxjs';
28
+ import { coerceBooleanProperty } from '@angular/cdk/coercion';
29
+ import { FocusMonitor } from '@angular/cdk/a11y';
30
+ import {
31
+ MatecuAutocompleteFilterFn,
32
+ MatecuAutocompleteOption,
33
+ } from '../../types/matecu-autocomplete';
34
+
35
+ @Component({
36
+ selector: 'matecu-autocomplete',
37
+ standalone: true,
38
+ imports: [
39
+ CommonModule,
40
+ MatAutocompleteModule,
41
+ MatDividerModule,
42
+ FormsModule,
43
+ ReactiveFormsModule,
44
+ MatProgressSpinnerModule,
45
+ ],
46
+ templateUrl: './matecu-autocomplete.html',
47
+ styleUrls: ['./matecu-autocomplete.scss'],
48
+ providers: [
49
+ {
50
+ provide: NG_VALUE_ACCESSOR,
51
+ useExisting: MatecuAutocomplete,
52
+ multi: true,
53
+ },
54
+ {
55
+ provide: MatFormFieldControl,
56
+ useExisting: MatecuAutocomplete,
57
+ },
58
+ ],
59
+ })
60
+ export class MatecuAutocomplete
61
+ implements
62
+ ControlValueAccessor,
63
+ MatFormFieldControl<string>,
64
+ OnChanges,
65
+ OnInit,
66
+ OnDestroy,
67
+ DoCheck
68
+ {
69
+ @Input() options: MatecuAutocompleteOption[] = [];
70
+ @Input() allowCreate = false;
71
+ @Input() loading = false;
72
+ @Input() readonly = false;
73
+ @Input() filterFn: MatecuAutocompleteFilterFn = this.createFilterFn();
74
+ @Input() searchChangeDebounceTime = 300;
75
+ // MatFormFieldControl inputs
76
+ @Input()
77
+ get placeholder(): string {
78
+ return this._placeholder;
79
+ }
80
+ set placeholder(value: string) {
81
+ this._placeholder = value;
82
+ this.stateChanges.next();
83
+ }
84
+ private _placeholder = '';
85
+
86
+ @Input()
87
+ get required(): boolean {
88
+ return this._required;
89
+ }
90
+ set required(value: boolean) {
91
+ this._required = coerceBooleanProperty(value);
92
+ this.stateChanges.next();
93
+ }
94
+ private _required = false;
95
+
96
+ @Input()
97
+ get disabled(): boolean {
98
+ return this._disabled;
99
+ }
100
+ set disabled(value: boolean) {
101
+ this._disabled = coerceBooleanProperty(value);
102
+ this.setDisabledState(this._disabled);
103
+ this.stateChanges.next();
104
+ }
105
+ private _disabled = false;
106
+
107
+ @Input()
108
+ get value(): string | null {
109
+ return this.internalValue;
110
+ }
111
+ set value(value: string | null) {
112
+ this.writeValue(value);
113
+ this.stateChanges.next();
114
+ }
115
+
116
+ @Output() searchChange = new EventEmitter<string>();
117
+ @Output() create = new EventEmitter<string>();
118
+ @Output() valueChange = new EventEmitter<string | null>();
119
+
120
+ // MatFormFieldControl properties
121
+ static nextId = 0;
122
+ readonly stateChanges = new Subject<void>();
123
+ readonly id = `matecu-autocomplete-${MatecuAutocomplete.nextId++}`;
124
+ ngControl: NgControl | null = null;
125
+ focused = false;
126
+ lastSearchText: string | null = null;
127
+ readonly controlType = 'matecu-autocomplete';
128
+ readonly autofilled = false;
129
+
130
+ inputControl = new FormControl<string | null>(null);
131
+ filteredOptions$!: Observable<MatecuAutocompleteOption[]>;
132
+
133
+ private internalValue: string | null = null;
134
+ private focusMonitor: FocusMonitor;
135
+ private elementRef: ElementRef<HTMLElement>;
136
+ private injector: Injector;
137
+ private optionMap = new Map<string, string>();
138
+
139
+ private onChange: any = () => {};
140
+ private onTouched: any = () => {};
141
+ get empty(): boolean {
142
+ const isEmpty = this.inputControl.value === '' || !this.inputControl.value;
143
+ return isEmpty;
144
+ }
145
+
146
+ get shouldLabelFloat(): boolean {
147
+ const shouldFloat = this.focused || !this.empty;
148
+ return shouldFloat;
149
+ }
150
+
151
+ get errorState(): boolean {
152
+ return !!(this.ngControl && this.ngControl.invalid && this.ngControl.touched);
153
+ }
154
+ get showCreateOption(): boolean {
155
+ const value = this.inputControl.value;
156
+
157
+ return (
158
+ this.allowCreate &&
159
+ typeof value === 'string' &&
160
+ this.internalValue !== value &&
161
+ this.options.some((option) => option[1].toLowerCase() === value.toLowerCase()) === false
162
+ );
163
+ }
164
+
165
+ constructor(focusMonitor: FocusMonitor, elementRef: ElementRef<HTMLElement>, injector: Injector) {
166
+ this.focusMonitor = focusMonitor;
167
+ this.elementRef = elementRef;
168
+ this.injector = injector;
169
+ }
170
+
171
+ ngOnInit() {
172
+ // Intentar obtener NgControl de forma segura
173
+ try {
174
+ this.ngControl = this.injector.get(NgControl, null);
175
+ } catch (error) {
176
+ // Ignorar si no se puede obtener NgControl
177
+ this.ngControl = null;
178
+ }
179
+
180
+ const value$ = this.inputControl.valueChanges.pipe(startWith(this.inputControl.value ?? ''));
181
+
182
+ this.filteredOptions$ = combineLatest([value$]).pipe(
183
+ map(([value]) => this.filter(value ?? '')),
184
+ );
185
+
186
+ this.inputControl.valueChanges
187
+ .pipe(
188
+ // Almacena el último valor valido para la búsqueda esto se utiliza para enviar una emición para crear un elemento
189
+ tap((value) => (this.lastSearchText = value ?? this.lastSearchText)),
190
+ // CUando se escribe algo se limpian los valores seleccionados para que el usuario pueda seleccionar una opción o crear una nueva
191
+ tap(() => this.clearValue()),
192
+ debounceTime(this.searchChangeDebounceTime),
193
+ )
194
+ .subscribe((value) => {
195
+ queueMicrotask(() => {
196
+ this.searchChange.emit(value ?? '');
197
+ });
198
+ });
199
+
200
+ this.focusMonitor.monitor(this.elementRef, true).subscribe((focused) => {
201
+ if (!!focused !== this.focused) {
202
+ this.focused = !!focused;
203
+ this.stateChanges.next();
204
+ }
205
+ });
206
+ }
207
+
208
+ ngOnDestroy() {
209
+ this.stateChanges.complete();
210
+ this.focusMonitor.stopMonitoring(this.elementRef);
211
+ }
212
+
213
+ ngDoCheck() {
214
+ if (this.ngControl) {
215
+ const newErrorState = !!(this.ngControl.invalid && this.ngControl.touched);
216
+ if (newErrorState !== this.errorState) {
217
+ this.stateChanges.next();
218
+ }
219
+ }
220
+ }
221
+
222
+ ngOnChanges(changes: SimpleChanges) {
223
+ if (changes['options']) {
224
+ this.rebuildOptionMap();
225
+ this.updateInputLabelFromValue();
226
+ this.stateChanges.next();
227
+ }
228
+
229
+ if (changes['placeholder'] || changes['required'] || changes['disabled']) {
230
+ this.stateChanges.next();
231
+ }
232
+ }
233
+
234
+ private filter(search: string): MatecuAutocompleteOption[] {
235
+ return this.options.filter((option) => this.filterFn(option[1], search));
236
+ }
237
+
238
+ private createFilterFn(): (v1: string, v2: string) => boolean {
239
+ return (v1: string, v2: string): boolean => {
240
+ return v1.toLowerCase().includes(v2.toLowerCase());
241
+ };
242
+ }
243
+
244
+ displayLabel = (value: string | null): string => {
245
+ if (value === null || value === undefined) return '';
246
+
247
+ if (!Array.isArray(this.options)) {
248
+ return '';
249
+ }
250
+ return this.optionMap.get(value) ?? '';
251
+ };
252
+
253
+ onOptionSelected(value: string) {
254
+ if (!value || this.readonly || this.disabled) {
255
+ return;
256
+ }
257
+ this.internalValue = value;
258
+ this.inputControl.setValue(value, { emitEvent: false });
259
+ this.onChange(value);
260
+ this.onTouched();
261
+ this.valueChange.emit(value);
262
+ }
263
+
264
+ onCreateClick() {
265
+ if (
266
+ !this.lastSearchText ||
267
+ this.lastSearchText.trim() === '' ||
268
+ this.options.some(
269
+ (option) => option[1].toLowerCase() === this.lastSearchText!.toLowerCase(),
270
+ ) ||
271
+ this.options.some((option) => option[1].toLowerCase() === this.lastSearchText!.toLowerCase())
272
+ ) {
273
+ return;
274
+ }
275
+ this.create.emit(this.lastSearchText);
276
+ }
277
+
278
+ private updateInputLabelFromValue() {
279
+ if (this.internalValue !== null) {
280
+ const label = this.displayLabel(this.internalValue);
281
+ this.inputControl.setValue(label, { emitEvent: false });
282
+ }
283
+ }
284
+
285
+ // ControlValueAccessor
286
+
287
+ writeValue(value: string | null): void {
288
+ this.internalValue = value;
289
+ this.updateInputLabelFromValue();
290
+ this.stateChanges.next();
291
+ }
292
+
293
+ registerOnChange(fn: any): void {
294
+ this.onChange = fn;
295
+ }
296
+
297
+ registerOnTouched(fn: any): void {
298
+ this.onTouched = fn;
299
+ }
300
+
301
+ setDisabledState(isDisabled: boolean): void {
302
+ this._disabled = isDisabled;
303
+ isDisabled ? this.inputControl.disable() : this.inputControl.enable();
304
+ this.stateChanges.next();
305
+ }
306
+
307
+ // MatFormFieldControl methods
308
+ focus(options?: FocusOptions): void {
309
+ this.elementRef.nativeElement.querySelector('input')?.focus(options);
310
+ }
311
+
312
+ onContainerClick(): void {
313
+ this.focus();
314
+ }
315
+
316
+ setDescribedByIds(ids: string[]): void {
317
+ const input = this.elementRef.nativeElement.querySelector('input');
318
+ if (input) {
319
+ input.setAttribute('aria-describedby', ids.join(' '));
320
+ }
321
+ }
322
+ private rebuildOptionMap() {
323
+ this.optionMap.clear();
324
+
325
+ for (const [value, label] of this.options ?? []) {
326
+ this.optionMap.set(value, label);
327
+ }
328
+ }
329
+
330
+ private clearValue() {
331
+ this.internalValue = null;
332
+ this.onChange(null);
333
+ this.onTouched();
334
+ this.valueChange.emit(null);
335
+ }
336
+ }
@@ -0,0 +1,64 @@
1
+ @if (loading) {
2
+
3
+ <mat-progress-spinner matSuffix diameter="20" mode="indeterminate">
4
+ </mat-progress-spinner>
5
+ }
6
+ <mat-chip-grid #chipGrid class="chip-list">
7
+
8
+ @for (item of selectedItems(); track item.value) {
9
+
10
+ <mat-chip-row [removable]="!disabled && !readonly" (removed)="remove(item.value)"
11
+ [matTooltip]="showTooltip ? item.label : ''" matTooltipPosition="above">
12
+
13
+
14
+
15
+ {{ item.label }}
16
+ @if (!disabled && !readonly) {
17
+
18
+ <button matChipRemove aria-label="Remove {{item.label}}">
19
+ <mat-icon>cancel</mat-icon>
20
+ </button>
21
+ }
22
+
23
+ </mat-chip-row>
24
+ }
25
+
26
+ <input type="text" matInput [formControl]="searchControl" [matAutocomplete]="auto" (keydown)="onKeyDown($event)"
27
+ [placeholder]="placeholder" />
28
+
29
+ </mat-chip-grid>
30
+
31
+
32
+ <mat-autocomplete #auto="matAutocomplete" (optionSelected)="selectOption($event.option.value)"
33
+ class="autocomplete-large-panel" [displayWith]="displayLabel">
34
+
35
+ @if (!readonly && !disabled && (enableSelectAll || control.value.length > 0)) {
36
+ <mat-option>
37
+ <div style="display: flex; gap: 10px; align-items: center; justify-content: center; ">
38
+
39
+ @if (enableSelectAll) {
40
+ <div>
41
+ <button mat-icon-button (click)="selectAll()" [matTooltip]="selectAllLabel">
42
+ <mat-icon>select_all</mat-icon>
43
+ </button>
44
+ </div>
45
+
46
+ }
47
+ @if (control.value.length > 0) {
48
+ <div>
49
+
50
+ <button mat-icon-button (click)="clearAll()" [matTooltip]="clearAllLabel">
51
+ <mat-icon>clear_all</mat-icon>
52
+ </button>
53
+ </div>
54
+ }
55
+ </div>
56
+ </mat-option>
57
+ }
58
+
59
+ @for (option of filteredOptions(); track $index) {
60
+ <mat-option [value]="option">
61
+ {{ option[1] }}
62
+ </mat-option>
63
+ }
64
+ </mat-autocomplete>
@@ -0,0 +1,23 @@
1
+ :host {
2
+ display: inline-block;
3
+ position: relative;
4
+ width: 100%;
5
+
6
+ input {
7
+ outline: none;
8
+ border: none;
9
+ background-color: transparent;
10
+ width: 100%;
11
+ }
12
+ .clear-all-box {
13
+ width: 100%;
14
+ display: flex;
15
+ justify-content: flex-end;
16
+ align-items: center;
17
+ }
18
+ mat-option {
19
+ span {
20
+ display: block;
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { MatecuAutocompleteMultiple } from './matecu-autocomplete-multiple';
4
+
5
+ describe('MatecuAutocompleteMultiple', () => {
6
+ let component: MatecuAutocompleteMultiple;
7
+ let fixture: ComponentFixture<MatecuAutocompleteMultiple>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [MatecuAutocompleteMultiple]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(MatecuAutocompleteMultiple);
16
+ component = fixture.componentInstance;
17
+ await fixture.whenStable();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });