@sdcorejs/angular 19.0.4 → 19.0.6

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 (44) hide show
  1. package/assets/{scss/README.md → STYLE-GUIDE.md} +3 -0
  2. package/components/index.d.ts +2 -0
  3. package/components/org-chart/index.d.ts +3 -0
  4. package/components/org-chart/src/org-chart-item-def.directive.d.ts +9 -0
  5. package/components/org-chart/src/org-chart.component.d.ts +26 -0
  6. package/components/org-chart/src/org-chart.model.d.ts +32 -0
  7. package/components/query-bar/src/query-bar.component.d.ts +15 -2
  8. package/components/query-bar/src/query-bar.model.d.ts +22 -0
  9. package/components/query-builder/src/query-builder.component.d.ts +23 -6
  10. package/components/query-builder/src/query-builder.model.d.ts +71 -23
  11. package/components/section/src/section.component.d.ts +4 -1
  12. package/components/splitter/src/splitter.component.d.ts +8 -2
  13. package/components/splitter/src/splitter.models.d.ts +13 -0
  14. package/components/table/src/services/table-filter/table-filter.model.d.ts +2 -0
  15. package/components/tree/index.d.ts +3 -0
  16. package/components/tree/src/tree-item-def.directive.d.ts +9 -0
  17. package/components/tree/src/tree.component.d.ts +102 -0
  18. package/components/tree/src/tree.model.d.ts +142 -0
  19. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +2 -2
  20. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  21. package/fesm2022/sdcorejs-angular-components-org-chart.mjs +110 -0
  22. package/fesm2022/sdcorejs-angular-components-org-chart.mjs.map +1 -0
  23. package/fesm2022/sdcorejs-angular-components-query-bar.mjs +37 -8
  24. package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
  25. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +257 -59
  26. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  27. package/fesm2022/sdcorejs-angular-components-section.mjs +7 -4
  28. package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
  29. package/fesm2022/sdcorejs-angular-components-splitter.mjs +23 -12
  30. package/fesm2022/sdcorejs-angular-components-splitter.mjs.map +1 -1
  31. package/fesm2022/sdcorejs-angular-components-table.mjs +6 -2
  32. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  33. package/fesm2022/sdcorejs-angular-components-tree.mjs +526 -0
  34. package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -0
  35. package/fesm2022/sdcorejs-angular-components.mjs +2 -0
  36. package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
  37. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +2 -2
  38. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  39. package/fesm2022/sdcorejs-angular-forms-select.mjs +65 -6
  40. package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
  41. package/forms/select/index.d.ts +1 -0
  42. package/forms/select/src/select-footer-action.directive.d.ts +11 -0
  43. package/forms/select/src/select.component.d.ts +17 -1
  44. package/package.json +10 -2
@@ -1,7 +1,7 @@
1
1
  import * as i1 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { viewChild, contentChild, computed, inject, ChangeDetectorRef, ElementRef, input, booleanAttribute, model, output, signal, isSignal, DestroyRef, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
4
+ import { inject, TemplateRef, input, Directive, viewChild, contentChild, contentChildren, computed, ChangeDetectorRef, ElementRef, booleanAttribute, model, output, signal, isSignal, DestroyRef, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
5
5
  import { toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
6
  import * as i2 from '@angular/forms';
7
7
  import { NgForm, FormGroup, FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
@@ -27,6 +27,20 @@ import { Utilities, StringUtilities, ArrayUtilities } from '@sdcorejs/angular/ut
27
27
  import { timer, combineLatest } from 'rxjs';
28
28
  import { tap, map, startWith, debounce, switchMap } from 'rxjs/operators';
29
29
 
30
+ class SdSelectFooterActionDirective {
31
+ templateRef = inject((TemplateRef));
32
+ when = input('always');
33
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdSelectFooterActionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
34
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.21", type: SdSelectFooterActionDirective, isStandalone: true, selector: "ng-template[sdSelectFooterAction]", inputs: { when: { classPropertyName: "when", publicName: "when", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
35
+ }
36
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdSelectFooterActionDirective, decorators: [{
37
+ type: Directive,
38
+ args: [{
39
+ selector: 'ng-template[sdSelectFooterAction]',
40
+ standalone: true,
41
+ }]
42
+ }] });
43
+
30
44
  /* eslint-disable @angular-eslint/no-input-rename */
31
45
  /* eslint-disable @typescript-eslint/no-explicit-any */
32
46
  class SdSelect {
@@ -38,8 +52,17 @@ class SdSelect {
38
52
  selectRef = viewChild('select');
39
53
  sdLabelTemplate = contentChild('sdLabel');
40
54
  sdValueTemplate = contentChild('sdValue');
55
+ /**
56
+ * Custom render for the SELECTED value shown in the editable trigger (`<mat-select-trigger>`).
57
+ * Distinct from `#sdValue`/`sdViewDef` which only drive the read-only `viewed`/`inline` face.
58
+ * Context: `{ $implicit, item, items: selectedItems(), display, multiple }` — `item`/`$implicit`
59
+ * is the single selected item object (single mode) or the selected-item array (multiple mode).
60
+ * Falls back to the plain `display` text when not projected, so existing usages are unaffected.
61
+ */
62
+ sdSelectedTemplate = contentChild('sdSelected');
41
63
  itemDef = contentChild(SdItemDefDefDirective);
42
64
  sdViewDef = contentChild(SdViewDefDirective);
65
+ footerActions = contentChildren(SdSelectFooterActionDirective);
43
66
  /**
44
67
  * View display template. `sdViewDef` is now just a custom override of the view rendering —
45
68
  * it replaces the projected `#sdValue` template when present (fed into `<sd-view>`'s
@@ -178,6 +201,9 @@ class SdSelect {
178
201
  selectedItems = signal([]);
179
202
  display = signal('');
180
203
  calculatedPanelWidth = signal('auto');
204
+ searchText = signal('');
205
+ footerActionContext = computed(() => ({ searchText: this.searchText() }));
206
+ visibleFooterActions = computed(() => this.footerActions().filter(action => this.shouldRenderFooterAction(action)));
181
207
  normalizedValue = computed(() => {
182
208
  const val = this.valueModel();
183
209
  if (this.multiple() && val !== undefined && val !== null && !Array.isArray(val)) {
@@ -215,6 +241,16 @@ class SdSelect {
215
241
  return false;
216
242
  return Boolean(Utilities.getNestedValue(item, path));
217
243
  };
244
+ shouldRenderFooterAction(action) {
245
+ const when = action.when();
246
+ if (when === 'always')
247
+ return true;
248
+ if (when === 'empty')
249
+ return this.searchText().length > 0 && this.filteredItems().length === 0;
250
+ if (when === 'has-result')
251
+ return this.filteredItems().length > 0;
252
+ return false;
253
+ }
218
254
  setNestedValue = (obj, path, value) => {
219
255
  if (!path)
220
256
  return;
@@ -329,7 +365,7 @@ class SdSelect {
329
365
  return items.filter(e => e !== null && e !== undefined);
330
366
  return items;
331
367
  }));
332
- const search$ = this.inputControl.valueChanges.pipe(startWith(''), tap(() => {
368
+ const search$ = this.inputControl.valueChanges.pipe(startWith(''), tap(searchText => this.searchText.set(searchText?.toString() || '')), tap(() => {
333
369
  if (typeof this.actualItems() === 'function' && this.focused()) {
334
370
  this.loading.set(true);
335
371
  this.#ref.markForCheck();
@@ -395,7 +431,29 @@ class SdSelect {
395
431
  });
396
432
  });
397
433
  }));
398
- const filteredItems$ = allItems$.pipe(map(allItems => ArrayUtilities.paging(allItems, this.limit())));
434
+ const filteredItems$ = allItems$.pipe(map(allItems => {
435
+ const limit = this.limit();
436
+ const val = this.valueModel();
437
+ if (!this.multiple() || !Array.isArray(val) || val.length === 0) {
438
+ return ArrayUtilities.paging(allItems, limit);
439
+ }
440
+ // multiple mode: keep ALL selected items (for checkmarks) + limit unselected items
441
+ // why: if selected.length >= limit, paging would show only selected items → user can't pick new ones
442
+ const vField = this.valueField();
443
+ const selectedSet = new Set(val.map(String));
444
+ const selected = [];
445
+ const unselected = [];
446
+ for (const item of allItems) {
447
+ const itemVal = vField ? String(this.itemValue(item) ?? '') : String(item ?? '');
448
+ if (selectedSet.has(itemVal)) {
449
+ selected.push(item);
450
+ }
451
+ else {
452
+ unselected.push(item);
453
+ }
454
+ }
455
+ return [...selected, ...ArrayUtilities.paging(unselected, limit)];
456
+ }));
399
457
  const display$ = selectedItems$.pipe(map(items => items?.map(item => (this.displayField() ? this.itemDisplay(item) : item))?.join(', ') || ''));
400
458
  filteredItems$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe(val => {
401
459
  this.filteredItems.set(val || []);
@@ -589,7 +647,7 @@ class SdSelect {
589
647
  }
590
648
  };
591
649
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
592
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdSelect, isStandalone: true, selector: "sd-select", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, helperText: { classPropertyName: "helperText", publicName: "helperText", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: true, transformFunction: null }, displayField: { classPropertyName: "displayField", publicName: "displayField", isSignal: true, isRequired: true, transformFunction: null }, disabledField: { classPropertyName: "disabledField", publicName: "disabledField", isSignal: true, isRequired: false, transformFunction: null }, cacheChecksum: { classPropertyName: "cacheChecksum", publicName: "cacheChecksum", isSignal: true, isRequired: false, transformFunction: null }, limit: { classPropertyName: "limit", publicName: "limit", isSignal: true, isRequired: false, transformFunction: null }, hyperlink: { classPropertyName: "hyperlink", publicName: "hyperlink", isSignal: true, isRequired: false, transformFunction: null }, minWidthPanel: { classPropertyName: "minWidthPanel", publicName: "minWidthPanel", isSignal: true, isRequired: false, transformFunction: null }, hideInlineError: { classPropertyName: "hideInlineError", publicName: "hideInlineError", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, viewed: { classPropertyName: "viewed", publicName: "viewed", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, validator: { classPropertyName: "validator", publicName: "validator", isSignal: true, isRequired: false, transformFunction: null }, inlineError: { classPropertyName: "inlineError", publicName: "inlineError", isSignal: true, isRequired: false, transformFunction: null }, appearanceInput: { classPropertyName: "appearanceInput", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, floatLabel: { classPropertyName: "floatLabel", publicName: "floatLabel", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, valueModel: { classPropertyName: "valueModel", publicName: "model", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueModel: "modelChange", sdChange: "sdChange", sdSelection: "sdSelection" }, host: { properties: { "class.sd-bare": "isInline()", "class.sd-viewed": "isViewed() || isInline()", "class.sd-has-label": "!!label()" } }, queries: [{ propertyName: "sdLabelTemplate", first: true, predicate: ["sdLabel"], descendants: true, isSignal: true }, { propertyName: "sdValueTemplate", first: true, predicate: ["sdValue"], descendants: true, isSignal: true }, { propertyName: "itemDef", first: true, predicate: SdItemDefDefDirective, descendants: true, isSignal: true }, { propertyName: "sdViewDef", first: true, predicate: SdViewDefDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "matInputRef", first: true, predicate: MatInput, descendants: true, isSignal: true }, { propertyName: "selectRef", first: true, predicate: ["select"], descendants: true, isSignal: true }], ngImport: i0, template: "@let _label = label();\n@let _appearance = appearance();\n@let _hideInlineError = hideInlineError();\n@let _errorMessage = errorMessage();\n@let _helperText = helperText();\n@let _multiple = multiple();\n@let _required = required();\n@let _normalizedValue = $any(normalizedValue());\n@let _focused = $any(focused());\n@let _isInline = isInline();\n@let _bare = _isInline;\n@let _hasValue = _multiple ? !!_normalizedValue?.length : _normalizedValue !== undefined && _normalizedValue !== null;\n@let _display = display();\n@let _size = size();\n@let _floatLabel = floatLabel();\n@let _valueField = valueField();\n@let _displayField = displayField();\n\n@if (isViewed()) {\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"_normalizedValue\"\n [display]=\"_display\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\"\n [selectedItems]=\"selectedItems()\">\n </sd-view>\n} @else {\n @if (_isInline) {\n <!-- why: inline \u2014 sd-view text l\u00E0 \"m\u1EB7t\" + trigger; editor v\u1EABn render b\u00EAn d\u01B0\u1EDBi (chrome \u1EA9n qua\n .sd-inline-editor) \u0111\u1EC3 m\u1EDF panel. Text gi\u1EEF nguy\u00EAn, ch\u1EC9 \u0111\u1ED5i khi commit gi\u00E1 tr\u1ECB m\u1EDBi. -->\n <span class=\"sd-inline-view\" role=\"button\" tabindex=\"0\" (click)=\"enterInlineEdit()\" (keydown.enter)=\"enterInlineEdit()\">\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"_normalizedValue\"\n [display]=\"_display\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\"\n [selectedItems]=\"selectedItems()\">\n </sd-view>\n\n <!-- why: clear-\u00D7 ch\u1EC9 hi\u1EC7n khi hover (CSS), \u0111\u1EB7t CU\u1ED0I face + clear($event) stopPropagation \u2192\n xo\u00E1 gi\u00E1 tr\u1ECB m\u00E0 KH\u00D4NG m\u1EDF panel; tr\u00E1nh bug c\u0169 (\u00D7 s\u00E1t trigger b\u1ECB b\u1EA5m nh\u1EA7m l\u00FAc \u0111\u00F3ng panel). -->\n @if (clearable() && _hasValue && !_required && !formControl.disabled) {\n <button type=\"button\" class=\"sd-inline-clear\" (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </span>\n }\n\n @if (!_appearance) {\n <ng-content select=\"[sdLabel]\">\n @if (_label) {\n <sd-label [label]=\"_label\" [required]=\"_required\"></sd-label>\n }\n </ng-content>\n }\n\n <div\n class=\"d-flex align-items-center\"\n [class.sd-inline-editor]=\"_isInline\"\n [class.c-focused]=\"_focused\"\n [class.c-disabled]=\"formControl.disabled\"\n (click)=\"onClick()\"\n (mouseenter)=\"updatePanelWidth()\"\n (focusin)=\"updatePanelWidth()\"\n aria-hidden=\"true\">\n @if (_multiple) {\n <mat-form-field\n [class.sd-md]=\"_size === 'md'\"\n [class.sd-sm]=\"_size === 'sm'\"\n [class.hide-inline-error]=\"_hideInlineError\"\n [appearance]=\"_appearance!\"\n [floatLabel]=\"_floatLabel\">\n @if (_appearance && _label) {\n <mat-label style=\"display: inline-block\">\n <div style=\"display: flex; align-items: center; gap: 4px\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <mat-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\">info_outline</mat-icon>\n }\n </div>\n </mat-label>\n }\n\n <mat-select\n #select\n multiple\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder() || _label || ''\"\n (selectionChange)=\"onSelectionChange($event)\"\n disableOptionCentering=\"true\"\n [panelWidth]=\"calculatedPanelWidth()\"\n [panelClass]=\"['sd-select-panel', 'sd-multiple']\"\n [class.sd-selected]=\"!_required && _normalizedValue?.length\"\n [required]=\"_required\"\n (openedChange)=\"onOpenedChange($event)\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-invalid]=\"dataInvalid()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-loading]=\"dataLoading()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [matTooltipDisabled]=\"!formControl.disabled || !_normalizedValue?.length\"\n [matTooltip]=\"tooltip() || ''\">\n <mat-select-trigger>\n <div class=\"sd-trigger-text\" [matTooltip]=\"_display || ''\" matTooltipPosition=\"above\">\n {{ _display }}\n </div>\n </mat-select-trigger>\n\n @if (filtered()) {\n <div class=\"c-filter-input-container\">\n <div class=\"filter-input-wrapper\">\n <mat-icon>search</mat-icon>\n <input\n [formControl]=\"inputControl\"\n aria-hidden=\"true\"\n matInput\n autocomplete=\"off\"\n class=\"c-search-input\"\n (keydown)=\"$event.stopPropagation()\" />\n </div>\n </div>\n }\n\n @let asyncItems = filteredItems();\n @if (asyncItems) {\n @if (!asyncItems.length && !loading()) {\n <mat-option class=\"sd-empty\" disabled>\n <img class=\"sd-image-data-empty\" alt=\"empty-image\" style=\"width: 95px\" />\n </mat-option>\n } @else {\n @let iDefTpl = itemDef()?.templateRef;\n @if (_valueField && _displayField) {\n @for (item of asyncItems; track itemValue(item)) {\n <mat-option [value]=\"itemValue(item)\" [disabled]=\"itemDisabled(item)\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ itemDisplay(item) }}\n }\n </div>\n </mat-option>\n }\n } @else if (!_valueField && !_displayField) {\n @for (item of asyncItems; track item) {\n <mat-option [value]=\"item\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ item }}\n }\n </div>\n </mat-option>\n }\n }\n }\n }\n\n @if (loading()) {\n <mat-option disabled class=\"sd-loading-option\">\n <mat-spinner diameter=\"24\"></mat-spinner>\n </mat-option>\n }\n </mat-select>\n\n @if (_hideInlineError && _errorMessage && formControl.touched) {\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\"> error </mat-icon>\n }\n\n @if (!_hideInlineError && _errorMessage && formControl.touched) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n @if (_normalizedValue?.length && !_required && !formControl.disabled && !_bare) {\n <button type=\"button\" class=\"sd-clear-btn\" matSuffix (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n } @else {\n <mat-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix>keyboard_arrow_down</mat-icon>\n }\n </mat-form-field>\n } @else {\n <mat-form-field\n [class.sd-md]=\"_size === 'md'\"\n [class.sd-sm]=\"_size === 'sm'\"\n [class.hide-inline-error]=\"_hideInlineError\"\n [appearance]=\"_appearance!\"\n [floatLabel]=\"_floatLabel\">\n @if (_appearance && _label) {\n <mat-label style=\"display: inline-block\">\n <div style=\"display: flex; align-items: center; gap: 4px\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <mat-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\">info_outline</mat-icon>\n }\n </div>\n </mat-label>\n }\n\n <mat-select\n #select\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder() || _label || ''\"\n (selectionChange)=\"onSelectionChange($event)\"\n disableOptionCentering=\"true\"\n [panelWidth]=\"calculatedPanelWidth()\"\n [panelClass]=\"'sd-select-panel'\"\n [class.sd-selected]=\"!_required && _normalizedValue !== undefined && _normalizedValue !== null\"\n [required]=\"_required\"\n (openedChange)=\"onOpenedChange($event)\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-invalid]=\"dataInvalid()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-loading]=\"dataLoading()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [matTooltipDisabled]=\"!formControl.disabled || !_normalizedValue?.length\"\n [matTooltip]=\"tooltip() || ''\">\n <mat-select-trigger>\n {{ _display }}\n </mat-select-trigger>\n\n @if (filtered()) {\n <div class=\"c-filter-input-container\">\n <div class=\"filter-input-wrapper\">\n <mat-icon>search</mat-icon>\n <input\n [formControl]=\"inputControl\"\n aria-hidden=\"true\"\n matInput\n autocomplete=\"off\"\n class=\"c-search-input\"\n (keydown)=\"$event.stopPropagation()\" />\n </div>\n </div>\n }\n\n @let asyncItems = filteredItems();\n @if (asyncItems) {\n @if (!asyncItems.length && !loading()) {\n <mat-option class=\"sd-empty\" disabled>\n <img class=\"sd-image-data-empty\" alt=\"empty-image\" style=\"width: 95px\" />\n </mat-option>\n } @else {\n @let iDefTpl = itemDef()?.templateRef;\n\n @if (_valueField && _displayField) {\n @for (item of asyncItems; track itemValue(item)) {\n <mat-option [value]=\"itemValue(item)\" [disabled]=\"itemDisabled(item)\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ itemDisplay(item) }}\n }\n </div>\n </mat-option>\n }\n } @else if (!_valueField && !_displayField) {\n @for (item of asyncItems; track item) {\n <mat-option [value]=\"item\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ item }}\n }\n </div>\n </mat-option>\n }\n }\n }\n }\n\n @if (loading()) {\n <mat-option disabled class=\"sd-loading-option\">\n <mat-spinner diameter=\"24\"></mat-spinner>\n </mat-option>\n }\n </mat-select>\n\n @if (_hideInlineError && _errorMessage && formControl.touched) {\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\"> error </mat-icon>\n }\n\n @if (!_hideInlineError && _errorMessage && formControl.touched) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n @if (_normalizedValue !== undefined && _normalizedValue !== null && !_required && !formControl.disabled && !_bare) {\n <button type=\"button\" class=\"sd-clear-btn\" matSuffix (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n } @else {\n <mat-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix>keyboard_arrow_down</mat-icon>\n }\n </mat-form-field>\n }\n </div>\n}\n", styles: ["@charset \"UTF-8\";.text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{display:block;max-width:100%}:host(.sd-has-label){padding-top:4px}:host(.sd-viewed){padding-top:0}::ng-deep .sd-loading-option{min-height:50px!important}::ng-deep .sd-loading-option .mat-pseudo-checkbox{display:none!important}::ng-deep .sd-loading-option .mdc-list-item__primary-text{width:100%;display:flex;justify-content:center;align-items:center}.sd-trigger-text{display:block;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .mat-mdc-select-value{max-width:100%;overflow:hidden;width:0;min-width:100%}:host ::ng-deep .sd-selected .mat-mdc-select-arrow{display:none}:host ::ng-deep .mat-mdc-select-arrow{display:none!important}:host ::ng-deep .custom-arrow{pointer-events:none;position:absolute;right:1rem;top:50%;transform:translateY(-50%);display:flex;align-items:center}:host ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline.mat-form-field-disabled .mat-mdc-text-field-wrapper{background:var(--sd-black100)}:host ::ng-deep .mat-mdc-form-field mat-select.mat-mdc-select-disabled .mat-mdc-select-value{color:var(--sd-black400)!important}:host ::ng-deep .mat-mdc-form-field .mat-mdc-placeholder-required{color:var(--sd-error)}::ng-deep .sd-select-panel .mat-mdc-option.sd-empty .mat-pseudo-checkbox{display:none}::ng-deep .sd-select-panel .mat-mdc-option{min-height:36px!important;padding:8px 12px!important}::ng-deep .sd-select-panel .c-filter-input-container{position:sticky;top:0;background-color:#fff;box-shadow:0 1px #f2f2f2;padding:8px;margin-bottom:8px;z-index:1000}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper{display:flex;align-items:center;padding:4px 8px;border:1px solid var(--sd-black200);border-radius:4px;background-color:#fff}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper .mat-icon{color:#dadada}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper .c-search-input{background-color:#fff;border:none;outline:none;flex:1;padding:4px}::ng-deep .sd-multiline-tooltip{white-space:pre-line}::ng-deep .mat-mdc-select-panel.sd-select-panel{padding:0}::ng-deep .mat-mdc-select-panel.sd-select-panel .mat-mdc-option.mdc-list-item--disabled.sd-empty .mdc-list-item__primary-text{opacity:.8;width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:16px}::ng-deep .sd-select-panel.sd-multiple .mat-pseudo-checkbox{transform:scale(.75);margin-right:8px!important}::ng-deep .sd-select-panel.sd-multiple .mdc-list-item__primary-text{font-size:14px;white-space:normal}::ng-deep .mat-mdc-select-panel.sd-select-panel{max-width:90vw!important}::ng-deep .mat-mdc-select-panel.sd-select-panel .mat-mdc-option .mdc-list-item__primary-text{white-space:normal;word-break:break-word;line-height:1.4}:host(.sd-bare){display:inline-flex;align-items:center}:host(.sd-bare){position:relative}.sd-inline-view{cursor:pointer;display:inline-flex;align-items:center;width:100%;padding:1px 6px;border-radius:4px;background-color:#0000000a;transition:background-color .15s ease}.sd-inline-view:hover{background-color:#00000014}.sd-inline-view .sd-inline-clear{display:none;align-items:center;margin-left:4px;padding:0;border:0;background:transparent;cursor:pointer;line-height:0;color:var(--sd-text-secondary, #6b7280);transition:color .15s ease}.sd-inline-view .sd-inline-clear mat-icon{font-size:16px;width:16px;height:16px}.sd-inline-view .sd-inline-clear:hover{color:var(--sd-error, #b32626)}.sd-inline-view:hover .sd-inline-clear{display:inline-flex}.sd-inline-editor{position:absolute;inset:0;opacity:0;pointer-events:none}.sd-inline-editor ::ng-deep *{pointer-events:none!important}:host(.sd-bare) ::ng-deep .mat-mdc-form-field{width:auto}:host(.sd-bare) ::ng-deep .mat-mdc-text-field-wrapper{padding:0;background:transparent}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-flex{padding:0;align-items:center}:host(.sd-bare) ::ng-deep .mdc-notched-outline{display:none}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}:host(.sd-bare) ::ng-deep .mat-mdc-select-arrow-wrapper{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i6.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: SdLabel, selector: "sd-label", inputs: ["label", "description", "required", "helperText"] }, { kind: "component", type: SdView, selector: "sd-view", inputs: ["label", "value", "display", "hyperlink", "labelTemplate", "valueTemplate", "selectedItems"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
650
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdSelect, isStandalone: true, selector: "sd-select", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, helperText: { classPropertyName: "helperText", publicName: "helperText", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: true, transformFunction: null }, displayField: { classPropertyName: "displayField", publicName: "displayField", isSignal: true, isRequired: true, transformFunction: null }, disabledField: { classPropertyName: "disabledField", publicName: "disabledField", isSignal: true, isRequired: false, transformFunction: null }, cacheChecksum: { classPropertyName: "cacheChecksum", publicName: "cacheChecksum", isSignal: true, isRequired: false, transformFunction: null }, limit: { classPropertyName: "limit", publicName: "limit", isSignal: true, isRequired: false, transformFunction: null }, hyperlink: { classPropertyName: "hyperlink", publicName: "hyperlink", isSignal: true, isRequired: false, transformFunction: null }, minWidthPanel: { classPropertyName: "minWidthPanel", publicName: "minWidthPanel", isSignal: true, isRequired: false, transformFunction: null }, hideInlineError: { classPropertyName: "hideInlineError", publicName: "hideInlineError", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, viewed: { classPropertyName: "viewed", publicName: "viewed", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, validator: { classPropertyName: "validator", publicName: "validator", isSignal: true, isRequired: false, transformFunction: null }, inlineError: { classPropertyName: "inlineError", publicName: "inlineError", isSignal: true, isRequired: false, transformFunction: null }, appearanceInput: { classPropertyName: "appearanceInput", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, floatLabel: { classPropertyName: "floatLabel", publicName: "floatLabel", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, valueModel: { classPropertyName: "valueModel", publicName: "model", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueModel: "modelChange", sdChange: "sdChange", sdSelection: "sdSelection" }, host: { properties: { "class.sd-bare": "isInline()", "class.sd-viewed": "isViewed() || isInline()", "class.sd-has-label": "!!label()" } }, queries: [{ propertyName: "sdLabelTemplate", first: true, predicate: ["sdLabel"], descendants: true, isSignal: true }, { propertyName: "sdValueTemplate", first: true, predicate: ["sdValue"], descendants: true, isSignal: true }, { propertyName: "sdSelectedTemplate", first: true, predicate: ["sdSelected"], descendants: true, isSignal: true }, { propertyName: "itemDef", first: true, predicate: SdItemDefDefDirective, descendants: true, isSignal: true }, { propertyName: "sdViewDef", first: true, predicate: SdViewDefDirective, descendants: true, isSignal: true }, { propertyName: "footerActions", predicate: SdSelectFooterActionDirective, isSignal: true }], viewQueries: [{ propertyName: "matInputRef", first: true, predicate: MatInput, descendants: true, isSignal: true }, { propertyName: "selectRef", first: true, predicate: ["select"], descendants: true, isSignal: true }], ngImport: i0, template: "@let _label = label();\n@let _appearance = appearance();\n@let _hideInlineError = hideInlineError();\n@let _errorMessage = errorMessage();\n@let _helperText = helperText();\n@let _multiple = multiple();\n@let _required = required();\n@let _normalizedValue = $any(normalizedValue());\n@let _focused = $any(focused());\n@let _isInline = isInline();\n@let _bare = _isInline;\n@let _hasValue = _multiple ? !!_normalizedValue?.length : _normalizedValue !== undefined && _normalizedValue !== null;\n@let _display = display();\n@let _size = size();\n@let _floatLabel = floatLabel();\n@let _valueField = valueField();\n@let _displayField = displayField();\n\n@if (isViewed()) {\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"_normalizedValue\"\n [display]=\"_display\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\"\n [selectedItems]=\"selectedItems()\">\n </sd-view>\n} @else {\n @if (_isInline) {\n <!-- why: inline \u2014 sd-view text l\u00E0 \"m\u1EB7t\" + trigger; editor v\u1EABn render b\u00EAn d\u01B0\u1EDBi (chrome \u1EA9n qua\n .sd-inline-editor) \u0111\u1EC3 m\u1EDF panel. Text gi\u1EEF nguy\u00EAn, ch\u1EC9 \u0111\u1ED5i khi commit gi\u00E1 tr\u1ECB m\u1EDBi. -->\n <span class=\"sd-inline-view\" role=\"button\" tabindex=\"0\" (click)=\"enterInlineEdit()\" (keydown.enter)=\"enterInlineEdit()\">\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"_normalizedValue\"\n [display]=\"_display\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\"\n [selectedItems]=\"selectedItems()\">\n </sd-view>\n\n <!-- why: clear-\u00D7 ch\u1EC9 hi\u1EC7n khi hover (CSS), \u0111\u1EB7t CU\u1ED0I face + clear($event) stopPropagation \u2192\n xo\u00E1 gi\u00E1 tr\u1ECB m\u00E0 KH\u00D4NG m\u1EDF panel; tr\u00E1nh bug c\u0169 (\u00D7 s\u00E1t trigger b\u1ECB b\u1EA5m nh\u1EA7m l\u00FAc \u0111\u00F3ng panel). -->\n @if (clearable() && _hasValue && !_required && !formControl.disabled) {\n <button type=\"button\" class=\"sd-inline-clear\" (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </span>\n }\n\n @if (!_appearance) {\n <ng-content select=\"[sdLabel]\">\n @if (_label) {\n <sd-label [label]=\"_label\" [required]=\"_required\"></sd-label>\n }\n </ng-content>\n }\n\n <div\n class=\"d-flex align-items-center\"\n [class.sd-inline-editor]=\"_isInline\"\n [class.c-focused]=\"_focused\"\n [class.c-disabled]=\"formControl.disabled\"\n (click)=\"onClick()\"\n (mouseenter)=\"updatePanelWidth()\"\n (focusin)=\"updatePanelWidth()\"\n aria-hidden=\"true\">\n @if (_multiple) {\n <mat-form-field\n [class.sd-md]=\"_size === 'md'\"\n [class.sd-sm]=\"_size === 'sm'\"\n [class.hide-inline-error]=\"_hideInlineError\"\n [appearance]=\"_appearance!\"\n [floatLabel]=\"_floatLabel\">\n @if (_appearance && _label) {\n <mat-label style=\"display: inline-block\">\n <div style=\"display: flex; align-items: center; gap: 4px\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <mat-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\">info_outline</mat-icon>\n }\n </div>\n </mat-label>\n }\n\n <mat-select\n #select\n multiple\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder() || _label || ''\"\n (selectionChange)=\"onSelectionChange($event)\"\n disableOptionCentering=\"true\"\n [panelWidth]=\"calculatedPanelWidth()\"\n [panelClass]=\"['sd-select-panel', 'sd-multiple']\"\n [class.sd-selected]=\"!_required && _normalizedValue?.length\"\n [required]=\"_required\"\n (openedChange)=\"onOpenedChange($event)\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-invalid]=\"dataInvalid()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-loading]=\"dataLoading()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [matTooltipDisabled]=\"!formControl.disabled || !_normalizedValue?.length\"\n [matTooltip]=\"tooltip() || ''\">\n <mat-select-trigger>\n @if (sdSelectedTemplate(); as _selTpl) {\n <ng-container\n *ngTemplateOutlet=\"_selTpl; context: { $implicit: selectedItems(), item: selectedItems(), items: selectedItems(), display: _display, multiple: true }\">\n </ng-container>\n } @else {\n <div class=\"sd-trigger-text\" [matTooltip]=\"_display || ''\" matTooltipPosition=\"above\">\n {{ _display }}\n </div>\n }\n </mat-select-trigger>\n\n @if (filtered()) {\n <div class=\"c-filter-input-container\">\n <div class=\"filter-input-wrapper\">\n <mat-icon>search</mat-icon>\n <input\n [formControl]=\"inputControl\"\n aria-hidden=\"true\"\n matInput\n autocomplete=\"off\"\n class=\"c-search-input\"\n (keydown)=\"$event.stopPropagation()\" />\n </div>\n </div>\n }\n\n @let asyncItems = filteredItems();\n @if (asyncItems) {\n @if (!asyncItems.length && !loading()) {\n <mat-option class=\"sd-empty\" disabled>\n <img class=\"sd-image-data-empty\" alt=\"empty-image\" style=\"width: 95px\" />\n </mat-option>\n } @else {\n @let iDefTpl = itemDef()?.templateRef;\n @if (_valueField && _displayField) {\n @for (item of asyncItems; track itemValue(item)) {\n <mat-option [value]=\"itemValue(item)\" [disabled]=\"itemDisabled(item)\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ itemDisplay(item) }}\n }\n </div>\n </mat-option>\n }\n } @else if (!_valueField && !_displayField) {\n @for (item of asyncItems; track item) {\n <mat-option [value]=\"item\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ item }}\n }\n </div>\n </mat-option>\n }\n }\n }\n }\n\n @if (loading()) {\n <mat-option disabled class=\"sd-loading-option\">\n <mat-spinner diameter=\"24\"></mat-spinner>\n </mat-option>\n }\n\n @let renderedFooterActions = visibleFooterActions();\n @if (renderedFooterActions.length) {\n <div class=\"sd-select-footer-actions\">\n @for (action of renderedFooterActions; track action) {\n <ng-container *ngTemplateOutlet=\"action.templateRef; context: footerActionContext()\"> </ng-container>\n }\n </div>\n }\n </mat-select>\n\n @if (_hideInlineError && _errorMessage && formControl.touched) {\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\"> error </mat-icon>\n }\n\n @if (!_hideInlineError && _errorMessage && formControl.touched) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n @if (_normalizedValue?.length && !_required && !formControl.disabled && !_bare) {\n <button type=\"button\" class=\"sd-clear-btn\" matSuffix (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n } @else {\n <mat-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix>keyboard_arrow_down</mat-icon>\n }\n </mat-form-field>\n } @else {\n <mat-form-field\n [class.sd-md]=\"_size === 'md'\"\n [class.sd-sm]=\"_size === 'sm'\"\n [class.hide-inline-error]=\"_hideInlineError\"\n [appearance]=\"_appearance!\"\n [floatLabel]=\"_floatLabel\">\n @if (_appearance && _label) {\n <mat-label style=\"display: inline-block\">\n <div style=\"display: flex; align-items: center; gap: 4px\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <mat-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\">info_outline</mat-icon>\n }\n </div>\n </mat-label>\n }\n\n <mat-select\n #select\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder() || _label || ''\"\n (selectionChange)=\"onSelectionChange($event)\"\n disableOptionCentering=\"true\"\n [panelWidth]=\"calculatedPanelWidth()\"\n [panelClass]=\"'sd-select-panel'\"\n [class.sd-selected]=\"!_required && _normalizedValue !== undefined && _normalizedValue !== null\"\n [required]=\"_required\"\n (openedChange)=\"onOpenedChange($event)\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-invalid]=\"dataInvalid()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-loading]=\"dataLoading()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [matTooltipDisabled]=\"!formControl.disabled || !_normalizedValue?.length\"\n [matTooltip]=\"tooltip() || ''\">\n <mat-select-trigger>\n @if (sdSelectedTemplate(); as _selTpl) {\n <ng-container\n *ngTemplateOutlet=\"_selTpl; context: { $implicit: selectedItems()[0], item: selectedItems()[0], items: selectedItems(), display: _display, multiple: false }\">\n </ng-container>\n } @else {\n {{ _display }}\n }\n </mat-select-trigger>\n\n @if (filtered()) {\n <div class=\"c-filter-input-container\">\n <div class=\"filter-input-wrapper\">\n <mat-icon>search</mat-icon>\n <input\n [formControl]=\"inputControl\"\n aria-hidden=\"true\"\n matInput\n autocomplete=\"off\"\n class=\"c-search-input\"\n (keydown)=\"$event.stopPropagation()\" />\n </div>\n </div>\n }\n\n @let asyncItems = filteredItems();\n @if (asyncItems) {\n @if (!asyncItems.length && !loading()) {\n <mat-option class=\"sd-empty\" disabled>\n <img class=\"sd-image-data-empty\" alt=\"empty-image\" style=\"width: 95px\" />\n </mat-option>\n } @else {\n @let iDefTpl = itemDef()?.templateRef;\n\n @if (_valueField && _displayField) {\n @for (item of asyncItems; track itemValue(item)) {\n <mat-option [value]=\"itemValue(item)\" [disabled]=\"itemDisabled(item)\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ itemDisplay(item) }}\n }\n </div>\n </mat-option>\n }\n } @else if (!_valueField && !_displayField) {\n @for (item of asyncItems; track item) {\n <mat-option [value]=\"item\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ item }}\n }\n </div>\n </mat-option>\n }\n }\n }\n }\n\n @if (loading()) {\n <mat-option disabled class=\"sd-loading-option\">\n <mat-spinner diameter=\"24\"></mat-spinner>\n </mat-option>\n }\n\n @let renderedFooterActions = visibleFooterActions();\n @if (renderedFooterActions.length) {\n <div class=\"sd-select-footer-actions\">\n @for (action of renderedFooterActions; track action) {\n <ng-container *ngTemplateOutlet=\"action.templateRef; context: footerActionContext()\"> </ng-container>\n }\n </div>\n }\n </mat-select>\n\n @if (_hideInlineError && _errorMessage && formControl.touched) {\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\"> error </mat-icon>\n }\n\n @if (!_hideInlineError && _errorMessage && formControl.touched) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n @if (_normalizedValue !== undefined && _normalizedValue !== null && !_required && !formControl.disabled && !_bare) {\n <button type=\"button\" class=\"sd-clear-btn\" matSuffix (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n } @else {\n <mat-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix>keyboard_arrow_down</mat-icon>\n }\n </mat-form-field>\n }\n </div>\n}\n", styles: ["@charset \"UTF-8\";.text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{display:block;max-width:100%}:host(.sd-has-label){padding-top:4px}:host(.sd-viewed){padding-top:0}::ng-deep .sd-loading-option{min-height:50px!important}::ng-deep .sd-loading-option .mat-pseudo-checkbox{display:none!important}::ng-deep .sd-loading-option .mdc-list-item__primary-text{width:100%;display:flex;justify-content:center;align-items:center}.sd-trigger-text{display:block;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .mat-mdc-select-value{max-width:100%;overflow:hidden;width:0;min-width:100%}:host ::ng-deep .sd-selected .mat-mdc-select-arrow{display:none}:host ::ng-deep .mat-mdc-select-arrow{display:none!important}:host ::ng-deep .custom-arrow{pointer-events:none;position:absolute;right:1rem;top:50%;transform:translateY(-50%);display:flex;align-items:center}:host ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline.mat-form-field-disabled .mat-mdc-text-field-wrapper{background:var(--sd-black100)}:host ::ng-deep .mat-mdc-form-field mat-select.mat-mdc-select-disabled .mat-mdc-select-value{color:var(--sd-black400)!important}:host ::ng-deep .mat-mdc-form-field .mat-mdc-placeholder-required{color:var(--sd-error)}::ng-deep .sd-select-panel .mat-mdc-option.sd-empty .mat-pseudo-checkbox{display:none}::ng-deep .sd-select-panel .mat-mdc-option{min-height:36px!important;padding:8px 12px!important}::ng-deep .sd-select-panel .c-filter-input-container{position:sticky;top:0;background-color:#fff;box-shadow:0 1px #f2f2f2;padding:8px;margin-bottom:8px;z-index:1000}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper{display:flex;align-items:center;padding:4px 8px;border:1px solid var(--sd-black200);border-radius:4px;background-color:#fff}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper .mat-icon{color:#dadada}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper .c-search-input{background-color:#fff;border:none;outline:none;flex:1;padding:4px}::ng-deep .sd-select-panel .sd-select-footer-actions{position:sticky;bottom:0;z-index:1000;display:flex;flex-direction:column;gap:4px;border-top:1px solid #f2f2f2;background-color:#fff}::ng-deep .sd-multiline-tooltip{white-space:pre-line}::ng-deep .mat-mdc-select-panel.sd-select-panel{padding:0}::ng-deep .mat-mdc-select-panel.sd-select-panel .mat-mdc-option.mdc-list-item--disabled.sd-empty .mdc-list-item__primary-text{opacity:.8;width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:16px}::ng-deep .sd-select-panel .mat-pseudo-checkbox-minimal{transform:scale(.7);transform-origin:center right}::ng-deep .sd-select-panel.sd-multiple .mat-pseudo-checkbox{transform:scale(.75);margin-right:8px!important}::ng-deep .sd-select-panel.sd-multiple .mdc-list-item__primary-text{font-size:14px;white-space:normal}::ng-deep .mat-mdc-select-panel.sd-select-panel{max-width:90vw!important}::ng-deep .mat-mdc-select-panel.sd-select-panel .mat-mdc-option .mdc-list-item__primary-text{white-space:normal;word-break:break-word;line-height:1.4}:host(.sd-bare){display:inline-flex;align-items:center}:host(.sd-bare){position:relative}.sd-inline-view{cursor:pointer;display:inline-flex;align-items:center;width:100%;padding:1px 6px;border-radius:4px;background-color:#0000000a;transition:background-color .15s ease}.sd-inline-view:hover{background-color:#00000014}.sd-inline-view .sd-inline-clear{display:none;align-items:center;margin-left:4px;padding:0;border:0;background:transparent;cursor:pointer;line-height:0;color:var(--sd-text-secondary, #6b7280);transition:color .15s ease}.sd-inline-view .sd-inline-clear mat-icon{font-size:16px;width:16px;height:16px}.sd-inline-view .sd-inline-clear:hover{color:var(--sd-error, #b32626)}.sd-inline-view:hover .sd-inline-clear{display:inline-flex}.sd-inline-editor{position:absolute;inset:0;opacity:0;pointer-events:none}.sd-inline-editor ::ng-deep *{pointer-events:none!important}:host(.sd-bare) ::ng-deep .mat-mdc-form-field{width:auto}:host(.sd-bare) ::ng-deep .mat-mdc-text-field-wrapper{padding:0;background:transparent}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-flex{padding:0;align-items:center}:host(.sd-bare) ::ng-deep .mdc-notched-outline{display:none}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}:host(.sd-bare) ::ng-deep .mat-mdc-select-arrow-wrapper{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i6.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: SdLabel, selector: "sd-label", inputs: ["label", "description", "required", "helperText"] }, { kind: "component", type: SdView, selector: "sd-view", inputs: ["label", "value", "display", "hyperlink", "labelTemplate", "valueTemplate", "selectedItems"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
593
651
  }
594
652
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdSelect, decorators: [{
595
653
  type: Component,
@@ -606,12 +664,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
606
664
  MatProgressSpinnerModule,
607
665
  SdLabel,
608
666
  SdView,
609
- ], template: "@let _label = label();\n@let _appearance = appearance();\n@let _hideInlineError = hideInlineError();\n@let _errorMessage = errorMessage();\n@let _helperText = helperText();\n@let _multiple = multiple();\n@let _required = required();\n@let _normalizedValue = $any(normalizedValue());\n@let _focused = $any(focused());\n@let _isInline = isInline();\n@let _bare = _isInline;\n@let _hasValue = _multiple ? !!_normalizedValue?.length : _normalizedValue !== undefined && _normalizedValue !== null;\n@let _display = display();\n@let _size = size();\n@let _floatLabel = floatLabel();\n@let _valueField = valueField();\n@let _displayField = displayField();\n\n@if (isViewed()) {\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"_normalizedValue\"\n [display]=\"_display\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\"\n [selectedItems]=\"selectedItems()\">\n </sd-view>\n} @else {\n @if (_isInline) {\n <!-- why: inline \u2014 sd-view text l\u00E0 \"m\u1EB7t\" + trigger; editor v\u1EABn render b\u00EAn d\u01B0\u1EDBi (chrome \u1EA9n qua\n .sd-inline-editor) \u0111\u1EC3 m\u1EDF panel. Text gi\u1EEF nguy\u00EAn, ch\u1EC9 \u0111\u1ED5i khi commit gi\u00E1 tr\u1ECB m\u1EDBi. -->\n <span class=\"sd-inline-view\" role=\"button\" tabindex=\"0\" (click)=\"enterInlineEdit()\" (keydown.enter)=\"enterInlineEdit()\">\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"_normalizedValue\"\n [display]=\"_display\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\"\n [selectedItems]=\"selectedItems()\">\n </sd-view>\n\n <!-- why: clear-\u00D7 ch\u1EC9 hi\u1EC7n khi hover (CSS), \u0111\u1EB7t CU\u1ED0I face + clear($event) stopPropagation \u2192\n xo\u00E1 gi\u00E1 tr\u1ECB m\u00E0 KH\u00D4NG m\u1EDF panel; tr\u00E1nh bug c\u0169 (\u00D7 s\u00E1t trigger b\u1ECB b\u1EA5m nh\u1EA7m l\u00FAc \u0111\u00F3ng panel). -->\n @if (clearable() && _hasValue && !_required && !formControl.disabled) {\n <button type=\"button\" class=\"sd-inline-clear\" (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </span>\n }\n\n @if (!_appearance) {\n <ng-content select=\"[sdLabel]\">\n @if (_label) {\n <sd-label [label]=\"_label\" [required]=\"_required\"></sd-label>\n }\n </ng-content>\n }\n\n <div\n class=\"d-flex align-items-center\"\n [class.sd-inline-editor]=\"_isInline\"\n [class.c-focused]=\"_focused\"\n [class.c-disabled]=\"formControl.disabled\"\n (click)=\"onClick()\"\n (mouseenter)=\"updatePanelWidth()\"\n (focusin)=\"updatePanelWidth()\"\n aria-hidden=\"true\">\n @if (_multiple) {\n <mat-form-field\n [class.sd-md]=\"_size === 'md'\"\n [class.sd-sm]=\"_size === 'sm'\"\n [class.hide-inline-error]=\"_hideInlineError\"\n [appearance]=\"_appearance!\"\n [floatLabel]=\"_floatLabel\">\n @if (_appearance && _label) {\n <mat-label style=\"display: inline-block\">\n <div style=\"display: flex; align-items: center; gap: 4px\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <mat-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\">info_outline</mat-icon>\n }\n </div>\n </mat-label>\n }\n\n <mat-select\n #select\n multiple\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder() || _label || ''\"\n (selectionChange)=\"onSelectionChange($event)\"\n disableOptionCentering=\"true\"\n [panelWidth]=\"calculatedPanelWidth()\"\n [panelClass]=\"['sd-select-panel', 'sd-multiple']\"\n [class.sd-selected]=\"!_required && _normalizedValue?.length\"\n [required]=\"_required\"\n (openedChange)=\"onOpenedChange($event)\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-invalid]=\"dataInvalid()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-loading]=\"dataLoading()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [matTooltipDisabled]=\"!formControl.disabled || !_normalizedValue?.length\"\n [matTooltip]=\"tooltip() || ''\">\n <mat-select-trigger>\n <div class=\"sd-trigger-text\" [matTooltip]=\"_display || ''\" matTooltipPosition=\"above\">\n {{ _display }}\n </div>\n </mat-select-trigger>\n\n @if (filtered()) {\n <div class=\"c-filter-input-container\">\n <div class=\"filter-input-wrapper\">\n <mat-icon>search</mat-icon>\n <input\n [formControl]=\"inputControl\"\n aria-hidden=\"true\"\n matInput\n autocomplete=\"off\"\n class=\"c-search-input\"\n (keydown)=\"$event.stopPropagation()\" />\n </div>\n </div>\n }\n\n @let asyncItems = filteredItems();\n @if (asyncItems) {\n @if (!asyncItems.length && !loading()) {\n <mat-option class=\"sd-empty\" disabled>\n <img class=\"sd-image-data-empty\" alt=\"empty-image\" style=\"width: 95px\" />\n </mat-option>\n } @else {\n @let iDefTpl = itemDef()?.templateRef;\n @if (_valueField && _displayField) {\n @for (item of asyncItems; track itemValue(item)) {\n <mat-option [value]=\"itemValue(item)\" [disabled]=\"itemDisabled(item)\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ itemDisplay(item) }}\n }\n </div>\n </mat-option>\n }\n } @else if (!_valueField && !_displayField) {\n @for (item of asyncItems; track item) {\n <mat-option [value]=\"item\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ item }}\n }\n </div>\n </mat-option>\n }\n }\n }\n }\n\n @if (loading()) {\n <mat-option disabled class=\"sd-loading-option\">\n <mat-spinner diameter=\"24\"></mat-spinner>\n </mat-option>\n }\n </mat-select>\n\n @if (_hideInlineError && _errorMessage && formControl.touched) {\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\"> error </mat-icon>\n }\n\n @if (!_hideInlineError && _errorMessage && formControl.touched) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n @if (_normalizedValue?.length && !_required && !formControl.disabled && !_bare) {\n <button type=\"button\" class=\"sd-clear-btn\" matSuffix (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n } @else {\n <mat-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix>keyboard_arrow_down</mat-icon>\n }\n </mat-form-field>\n } @else {\n <mat-form-field\n [class.sd-md]=\"_size === 'md'\"\n [class.sd-sm]=\"_size === 'sm'\"\n [class.hide-inline-error]=\"_hideInlineError\"\n [appearance]=\"_appearance!\"\n [floatLabel]=\"_floatLabel\">\n @if (_appearance && _label) {\n <mat-label style=\"display: inline-block\">\n <div style=\"display: flex; align-items: center; gap: 4px\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <mat-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\">info_outline</mat-icon>\n }\n </div>\n </mat-label>\n }\n\n <mat-select\n #select\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder() || _label || ''\"\n (selectionChange)=\"onSelectionChange($event)\"\n disableOptionCentering=\"true\"\n [panelWidth]=\"calculatedPanelWidth()\"\n [panelClass]=\"'sd-select-panel'\"\n [class.sd-selected]=\"!_required && _normalizedValue !== undefined && _normalizedValue !== null\"\n [required]=\"_required\"\n (openedChange)=\"onOpenedChange($event)\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-invalid]=\"dataInvalid()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-loading]=\"dataLoading()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [matTooltipDisabled]=\"!formControl.disabled || !_normalizedValue?.length\"\n [matTooltip]=\"tooltip() || ''\">\n <mat-select-trigger>\n {{ _display }}\n </mat-select-trigger>\n\n @if (filtered()) {\n <div class=\"c-filter-input-container\">\n <div class=\"filter-input-wrapper\">\n <mat-icon>search</mat-icon>\n <input\n [formControl]=\"inputControl\"\n aria-hidden=\"true\"\n matInput\n autocomplete=\"off\"\n class=\"c-search-input\"\n (keydown)=\"$event.stopPropagation()\" />\n </div>\n </div>\n }\n\n @let asyncItems = filteredItems();\n @if (asyncItems) {\n @if (!asyncItems.length && !loading()) {\n <mat-option class=\"sd-empty\" disabled>\n <img class=\"sd-image-data-empty\" alt=\"empty-image\" style=\"width: 95px\" />\n </mat-option>\n } @else {\n @let iDefTpl = itemDef()?.templateRef;\n\n @if (_valueField && _displayField) {\n @for (item of asyncItems; track itemValue(item)) {\n <mat-option [value]=\"itemValue(item)\" [disabled]=\"itemDisabled(item)\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ itemDisplay(item) }}\n }\n </div>\n </mat-option>\n }\n } @else if (!_valueField && !_displayField) {\n @for (item of asyncItems; track item) {\n <mat-option [value]=\"item\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ item }}\n }\n </div>\n </mat-option>\n }\n }\n }\n }\n\n @if (loading()) {\n <mat-option disabled class=\"sd-loading-option\">\n <mat-spinner diameter=\"24\"></mat-spinner>\n </mat-option>\n }\n </mat-select>\n\n @if (_hideInlineError && _errorMessage && formControl.touched) {\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\"> error </mat-icon>\n }\n\n @if (!_hideInlineError && _errorMessage && formControl.touched) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n @if (_normalizedValue !== undefined && _normalizedValue !== null && !_required && !formControl.disabled && !_bare) {\n <button type=\"button\" class=\"sd-clear-btn\" matSuffix (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n } @else {\n <mat-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix>keyboard_arrow_down</mat-icon>\n }\n </mat-form-field>\n }\n </div>\n}\n", styles: ["@charset \"UTF-8\";.text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{display:block;max-width:100%}:host(.sd-has-label){padding-top:4px}:host(.sd-viewed){padding-top:0}::ng-deep .sd-loading-option{min-height:50px!important}::ng-deep .sd-loading-option .mat-pseudo-checkbox{display:none!important}::ng-deep .sd-loading-option .mdc-list-item__primary-text{width:100%;display:flex;justify-content:center;align-items:center}.sd-trigger-text{display:block;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .mat-mdc-select-value{max-width:100%;overflow:hidden;width:0;min-width:100%}:host ::ng-deep .sd-selected .mat-mdc-select-arrow{display:none}:host ::ng-deep .mat-mdc-select-arrow{display:none!important}:host ::ng-deep .custom-arrow{pointer-events:none;position:absolute;right:1rem;top:50%;transform:translateY(-50%);display:flex;align-items:center}:host ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline.mat-form-field-disabled .mat-mdc-text-field-wrapper{background:var(--sd-black100)}:host ::ng-deep .mat-mdc-form-field mat-select.mat-mdc-select-disabled .mat-mdc-select-value{color:var(--sd-black400)!important}:host ::ng-deep .mat-mdc-form-field .mat-mdc-placeholder-required{color:var(--sd-error)}::ng-deep .sd-select-panel .mat-mdc-option.sd-empty .mat-pseudo-checkbox{display:none}::ng-deep .sd-select-panel .mat-mdc-option{min-height:36px!important;padding:8px 12px!important}::ng-deep .sd-select-panel .c-filter-input-container{position:sticky;top:0;background-color:#fff;box-shadow:0 1px #f2f2f2;padding:8px;margin-bottom:8px;z-index:1000}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper{display:flex;align-items:center;padding:4px 8px;border:1px solid var(--sd-black200);border-radius:4px;background-color:#fff}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper .mat-icon{color:#dadada}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper .c-search-input{background-color:#fff;border:none;outline:none;flex:1;padding:4px}::ng-deep .sd-multiline-tooltip{white-space:pre-line}::ng-deep .mat-mdc-select-panel.sd-select-panel{padding:0}::ng-deep .mat-mdc-select-panel.sd-select-panel .mat-mdc-option.mdc-list-item--disabled.sd-empty .mdc-list-item__primary-text{opacity:.8;width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:16px}::ng-deep .sd-select-panel.sd-multiple .mat-pseudo-checkbox{transform:scale(.75);margin-right:8px!important}::ng-deep .sd-select-panel.sd-multiple .mdc-list-item__primary-text{font-size:14px;white-space:normal}::ng-deep .mat-mdc-select-panel.sd-select-panel{max-width:90vw!important}::ng-deep .mat-mdc-select-panel.sd-select-panel .mat-mdc-option .mdc-list-item__primary-text{white-space:normal;word-break:break-word;line-height:1.4}:host(.sd-bare){display:inline-flex;align-items:center}:host(.sd-bare){position:relative}.sd-inline-view{cursor:pointer;display:inline-flex;align-items:center;width:100%;padding:1px 6px;border-radius:4px;background-color:#0000000a;transition:background-color .15s ease}.sd-inline-view:hover{background-color:#00000014}.sd-inline-view .sd-inline-clear{display:none;align-items:center;margin-left:4px;padding:0;border:0;background:transparent;cursor:pointer;line-height:0;color:var(--sd-text-secondary, #6b7280);transition:color .15s ease}.sd-inline-view .sd-inline-clear mat-icon{font-size:16px;width:16px;height:16px}.sd-inline-view .sd-inline-clear:hover{color:var(--sd-error, #b32626)}.sd-inline-view:hover .sd-inline-clear{display:inline-flex}.sd-inline-editor{position:absolute;inset:0;opacity:0;pointer-events:none}.sd-inline-editor ::ng-deep *{pointer-events:none!important}:host(.sd-bare) ::ng-deep .mat-mdc-form-field{width:auto}:host(.sd-bare) ::ng-deep .mat-mdc-text-field-wrapper{padding:0;background:transparent}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-flex{padding:0;align-items:center}:host(.sd-bare) ::ng-deep .mdc-notched-outline{display:none}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}:host(.sd-bare) ::ng-deep .mat-mdc-select-arrow-wrapper{display:none}\n"] }]
667
+ SdSelectFooterActionDirective,
668
+ ], template: "@let _label = label();\n@let _appearance = appearance();\n@let _hideInlineError = hideInlineError();\n@let _errorMessage = errorMessage();\n@let _helperText = helperText();\n@let _multiple = multiple();\n@let _required = required();\n@let _normalizedValue = $any(normalizedValue());\n@let _focused = $any(focused());\n@let _isInline = isInline();\n@let _bare = _isInline;\n@let _hasValue = _multiple ? !!_normalizedValue?.length : _normalizedValue !== undefined && _normalizedValue !== null;\n@let _display = display();\n@let _size = size();\n@let _floatLabel = floatLabel();\n@let _valueField = valueField();\n@let _displayField = displayField();\n\n@if (isViewed()) {\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"_normalizedValue\"\n [display]=\"_display\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\"\n [selectedItems]=\"selectedItems()\">\n </sd-view>\n} @else {\n @if (_isInline) {\n <!-- why: inline \u2014 sd-view text l\u00E0 \"m\u1EB7t\" + trigger; editor v\u1EABn render b\u00EAn d\u01B0\u1EDBi (chrome \u1EA9n qua\n .sd-inline-editor) \u0111\u1EC3 m\u1EDF panel. Text gi\u1EEF nguy\u00EAn, ch\u1EC9 \u0111\u1ED5i khi commit gi\u00E1 tr\u1ECB m\u1EDBi. -->\n <span class=\"sd-inline-view\" role=\"button\" tabindex=\"0\" (click)=\"enterInlineEdit()\" (keydown.enter)=\"enterInlineEdit()\">\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"_normalizedValue\"\n [display]=\"_display\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\"\n [selectedItems]=\"selectedItems()\">\n </sd-view>\n\n <!-- why: clear-\u00D7 ch\u1EC9 hi\u1EC7n khi hover (CSS), \u0111\u1EB7t CU\u1ED0I face + clear($event) stopPropagation \u2192\n xo\u00E1 gi\u00E1 tr\u1ECB m\u00E0 KH\u00D4NG m\u1EDF panel; tr\u00E1nh bug c\u0169 (\u00D7 s\u00E1t trigger b\u1ECB b\u1EA5m nh\u1EA7m l\u00FAc \u0111\u00F3ng panel). -->\n @if (clearable() && _hasValue && !_required && !formControl.disabled) {\n <button type=\"button\" class=\"sd-inline-clear\" (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </span>\n }\n\n @if (!_appearance) {\n <ng-content select=\"[sdLabel]\">\n @if (_label) {\n <sd-label [label]=\"_label\" [required]=\"_required\"></sd-label>\n }\n </ng-content>\n }\n\n <div\n class=\"d-flex align-items-center\"\n [class.sd-inline-editor]=\"_isInline\"\n [class.c-focused]=\"_focused\"\n [class.c-disabled]=\"formControl.disabled\"\n (click)=\"onClick()\"\n (mouseenter)=\"updatePanelWidth()\"\n (focusin)=\"updatePanelWidth()\"\n aria-hidden=\"true\">\n @if (_multiple) {\n <mat-form-field\n [class.sd-md]=\"_size === 'md'\"\n [class.sd-sm]=\"_size === 'sm'\"\n [class.hide-inline-error]=\"_hideInlineError\"\n [appearance]=\"_appearance!\"\n [floatLabel]=\"_floatLabel\">\n @if (_appearance && _label) {\n <mat-label style=\"display: inline-block\">\n <div style=\"display: flex; align-items: center; gap: 4px\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <mat-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\">info_outline</mat-icon>\n }\n </div>\n </mat-label>\n }\n\n <mat-select\n #select\n multiple\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder() || _label || ''\"\n (selectionChange)=\"onSelectionChange($event)\"\n disableOptionCentering=\"true\"\n [panelWidth]=\"calculatedPanelWidth()\"\n [panelClass]=\"['sd-select-panel', 'sd-multiple']\"\n [class.sd-selected]=\"!_required && _normalizedValue?.length\"\n [required]=\"_required\"\n (openedChange)=\"onOpenedChange($event)\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-invalid]=\"dataInvalid()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-loading]=\"dataLoading()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [matTooltipDisabled]=\"!formControl.disabled || !_normalizedValue?.length\"\n [matTooltip]=\"tooltip() || ''\">\n <mat-select-trigger>\n @if (sdSelectedTemplate(); as _selTpl) {\n <ng-container\n *ngTemplateOutlet=\"_selTpl; context: { $implicit: selectedItems(), item: selectedItems(), items: selectedItems(), display: _display, multiple: true }\">\n </ng-container>\n } @else {\n <div class=\"sd-trigger-text\" [matTooltip]=\"_display || ''\" matTooltipPosition=\"above\">\n {{ _display }}\n </div>\n }\n </mat-select-trigger>\n\n @if (filtered()) {\n <div class=\"c-filter-input-container\">\n <div class=\"filter-input-wrapper\">\n <mat-icon>search</mat-icon>\n <input\n [formControl]=\"inputControl\"\n aria-hidden=\"true\"\n matInput\n autocomplete=\"off\"\n class=\"c-search-input\"\n (keydown)=\"$event.stopPropagation()\" />\n </div>\n </div>\n }\n\n @let asyncItems = filteredItems();\n @if (asyncItems) {\n @if (!asyncItems.length && !loading()) {\n <mat-option class=\"sd-empty\" disabled>\n <img class=\"sd-image-data-empty\" alt=\"empty-image\" style=\"width: 95px\" />\n </mat-option>\n } @else {\n @let iDefTpl = itemDef()?.templateRef;\n @if (_valueField && _displayField) {\n @for (item of asyncItems; track itemValue(item)) {\n <mat-option [value]=\"itemValue(item)\" [disabled]=\"itemDisabled(item)\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ itemDisplay(item) }}\n }\n </div>\n </mat-option>\n }\n } @else if (!_valueField && !_displayField) {\n @for (item of asyncItems; track item) {\n <mat-option [value]=\"item\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ item }}\n }\n </div>\n </mat-option>\n }\n }\n }\n }\n\n @if (loading()) {\n <mat-option disabled class=\"sd-loading-option\">\n <mat-spinner diameter=\"24\"></mat-spinner>\n </mat-option>\n }\n\n @let renderedFooterActions = visibleFooterActions();\n @if (renderedFooterActions.length) {\n <div class=\"sd-select-footer-actions\">\n @for (action of renderedFooterActions; track action) {\n <ng-container *ngTemplateOutlet=\"action.templateRef; context: footerActionContext()\"> </ng-container>\n }\n </div>\n }\n </mat-select>\n\n @if (_hideInlineError && _errorMessage && formControl.touched) {\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\"> error </mat-icon>\n }\n\n @if (!_hideInlineError && _errorMessage && formControl.touched) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n @if (_normalizedValue?.length && !_required && !formControl.disabled && !_bare) {\n <button type=\"button\" class=\"sd-clear-btn\" matSuffix (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n } @else {\n <mat-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix>keyboard_arrow_down</mat-icon>\n }\n </mat-form-field>\n } @else {\n <mat-form-field\n [class.sd-md]=\"_size === 'md'\"\n [class.sd-sm]=\"_size === 'sm'\"\n [class.hide-inline-error]=\"_hideInlineError\"\n [appearance]=\"_appearance!\"\n [floatLabel]=\"_floatLabel\">\n @if (_appearance && _label) {\n <mat-label style=\"display: inline-block\">\n <div style=\"display: flex; align-items: center; gap: 4px\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <mat-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\">info_outline</mat-icon>\n }\n </div>\n </mat-label>\n }\n\n <mat-select\n #select\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder() || _label || ''\"\n (selectionChange)=\"onSelectionChange($event)\"\n disableOptionCentering=\"true\"\n [panelWidth]=\"calculatedPanelWidth()\"\n [panelClass]=\"'sd-select-panel'\"\n [class.sd-selected]=\"!_required && _normalizedValue !== undefined && _normalizedValue !== null\"\n [required]=\"_required\"\n (openedChange)=\"onOpenedChange($event)\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-invalid]=\"dataInvalid()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-loading]=\"dataLoading()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n matTooltipClass=\"sd-multiline-tooltip\"\n [matTooltipDisabled]=\"!formControl.disabled || !_normalizedValue?.length\"\n [matTooltip]=\"tooltip() || ''\">\n <mat-select-trigger>\n @if (sdSelectedTemplate(); as _selTpl) {\n <ng-container\n *ngTemplateOutlet=\"_selTpl; context: { $implicit: selectedItems()[0], item: selectedItems()[0], items: selectedItems(), display: _display, multiple: false }\">\n </ng-container>\n } @else {\n {{ _display }}\n }\n </mat-select-trigger>\n\n @if (filtered()) {\n <div class=\"c-filter-input-container\">\n <div class=\"filter-input-wrapper\">\n <mat-icon>search</mat-icon>\n <input\n [formControl]=\"inputControl\"\n aria-hidden=\"true\"\n matInput\n autocomplete=\"off\"\n class=\"c-search-input\"\n (keydown)=\"$event.stopPropagation()\" />\n </div>\n </div>\n }\n\n @let asyncItems = filteredItems();\n @if (asyncItems) {\n @if (!asyncItems.length && !loading()) {\n <mat-option class=\"sd-empty\" disabled>\n <img class=\"sd-image-data-empty\" alt=\"empty-image\" style=\"width: 95px\" />\n </mat-option>\n } @else {\n @let iDefTpl = itemDef()?.templateRef;\n\n @if (_valueField && _displayField) {\n @for (item of asyncItems; track itemValue(item)) {\n <mat-option [value]=\"itemValue(item)\" [disabled]=\"itemDisabled(item)\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ itemDisplay(item) }}\n }\n </div>\n </mat-option>\n }\n } @else if (!_valueField && !_displayField) {\n @for (item of asyncItems; track item) {\n <mat-option [value]=\"item\">\n <div>\n @if (iDefTpl) {\n <ng-container *ngTemplateOutlet=\"iDefTpl ?? null; context: { item: item }\"> </ng-container>\n } @else {\n {{ item }}\n }\n </div>\n </mat-option>\n }\n }\n }\n }\n\n @if (loading()) {\n <mat-option disabled class=\"sd-loading-option\">\n <mat-spinner diameter=\"24\"></mat-spinner>\n </mat-option>\n }\n\n @let renderedFooterActions = visibleFooterActions();\n @if (renderedFooterActions.length) {\n <div class=\"sd-select-footer-actions\">\n @for (action of renderedFooterActions; track action) {\n <ng-container *ngTemplateOutlet=\"action.templateRef; context: footerActionContext()\"> </ng-container>\n }\n </div>\n }\n </mat-select>\n\n @if (_hideInlineError && _errorMessage && formControl.touched) {\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\"> error </mat-icon>\n }\n\n @if (!_hideInlineError && _errorMessage && formControl.touched) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n @if (_normalizedValue !== undefined && _normalizedValue !== null && !_required && !formControl.disabled && !_bare) {\n <button type=\"button\" class=\"sd-clear-btn\" matSuffix (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n } @else {\n <mat-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix>keyboard_arrow_down</mat-icon>\n }\n </mat-form-field>\n }\n </div>\n}\n", styles: ["@charset \"UTF-8\";.text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{display:block;max-width:100%}:host(.sd-has-label){padding-top:4px}:host(.sd-viewed){padding-top:0}::ng-deep .sd-loading-option{min-height:50px!important}::ng-deep .sd-loading-option .mat-pseudo-checkbox{display:none!important}::ng-deep .sd-loading-option .mdc-list-item__primary-text{width:100%;display:flex;justify-content:center;align-items:center}.sd-trigger-text{display:block;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host ::ng-deep .mat-mdc-select-value{max-width:100%;overflow:hidden;width:0;min-width:100%}:host ::ng-deep .sd-selected .mat-mdc-select-arrow{display:none}:host ::ng-deep .mat-mdc-select-arrow{display:none!important}:host ::ng-deep .custom-arrow{pointer-events:none;position:absolute;right:1rem;top:50%;transform:translateY(-50%);display:flex;align-items:center}:host ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline.mat-form-field-disabled .mat-mdc-text-field-wrapper{background:var(--sd-black100)}:host ::ng-deep .mat-mdc-form-field mat-select.mat-mdc-select-disabled .mat-mdc-select-value{color:var(--sd-black400)!important}:host ::ng-deep .mat-mdc-form-field .mat-mdc-placeholder-required{color:var(--sd-error)}::ng-deep .sd-select-panel .mat-mdc-option.sd-empty .mat-pseudo-checkbox{display:none}::ng-deep .sd-select-panel .mat-mdc-option{min-height:36px!important;padding:8px 12px!important}::ng-deep .sd-select-panel .c-filter-input-container{position:sticky;top:0;background-color:#fff;box-shadow:0 1px #f2f2f2;padding:8px;margin-bottom:8px;z-index:1000}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper{display:flex;align-items:center;padding:4px 8px;border:1px solid var(--sd-black200);border-radius:4px;background-color:#fff}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper .mat-icon{color:#dadada}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper .c-search-input{background-color:#fff;border:none;outline:none;flex:1;padding:4px}::ng-deep .sd-select-panel .sd-select-footer-actions{position:sticky;bottom:0;z-index:1000;display:flex;flex-direction:column;gap:4px;border-top:1px solid #f2f2f2;background-color:#fff}::ng-deep .sd-multiline-tooltip{white-space:pre-line}::ng-deep .mat-mdc-select-panel.sd-select-panel{padding:0}::ng-deep .mat-mdc-select-panel.sd-select-panel .mat-mdc-option.mdc-list-item--disabled.sd-empty .mdc-list-item__primary-text{opacity:.8;width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:16px}::ng-deep .sd-select-panel .mat-pseudo-checkbox-minimal{transform:scale(.7);transform-origin:center right}::ng-deep .sd-select-panel.sd-multiple .mat-pseudo-checkbox{transform:scale(.75);margin-right:8px!important}::ng-deep .sd-select-panel.sd-multiple .mdc-list-item__primary-text{font-size:14px;white-space:normal}::ng-deep .mat-mdc-select-panel.sd-select-panel{max-width:90vw!important}::ng-deep .mat-mdc-select-panel.sd-select-panel .mat-mdc-option .mdc-list-item__primary-text{white-space:normal;word-break:break-word;line-height:1.4}:host(.sd-bare){display:inline-flex;align-items:center}:host(.sd-bare){position:relative}.sd-inline-view{cursor:pointer;display:inline-flex;align-items:center;width:100%;padding:1px 6px;border-radius:4px;background-color:#0000000a;transition:background-color .15s ease}.sd-inline-view:hover{background-color:#00000014}.sd-inline-view .sd-inline-clear{display:none;align-items:center;margin-left:4px;padding:0;border:0;background:transparent;cursor:pointer;line-height:0;color:var(--sd-text-secondary, #6b7280);transition:color .15s ease}.sd-inline-view .sd-inline-clear mat-icon{font-size:16px;width:16px;height:16px}.sd-inline-view .sd-inline-clear:hover{color:var(--sd-error, #b32626)}.sd-inline-view:hover .sd-inline-clear{display:inline-flex}.sd-inline-editor{position:absolute;inset:0;opacity:0;pointer-events:none}.sd-inline-editor ::ng-deep *{pointer-events:none!important}:host(.sd-bare) ::ng-deep .mat-mdc-form-field{width:auto}:host(.sd-bare) ::ng-deep .mat-mdc-text-field-wrapper{padding:0;background:transparent}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-flex{padding:0;align-items:center}:host(.sd-bare) ::ng-deep .mdc-notched-outline{display:none}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}:host(.sd-bare) ::ng-deep .mat-mdc-select-arrow-wrapper{display:none}\n"] }]
610
669
  }], ctorParameters: () => [] });
611
670
 
612
671
  /**
613
672
  * Generated bundle index. Do not edit.
614
673
  */
615
674
 
616
- export { SdSelect };
675
+ export { SdSelect, SdSelectFooterActionDirective };
617
676
  //# sourceMappingURL=sdcorejs-angular-forms-select.mjs.map