@sdcorejs/angular 20.1.6 → 20.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +10 -0
  2. package/assets/scss/core/menu.scss +18 -0
  3. package/assets/scss/core/utilities/_misc.scss +15 -0
  4. package/assets/scss/sd-core.scss +1 -0
  5. package/components/anchor/index.d.ts +3 -1
  6. package/components/badge/index.d.ts +1 -0
  7. package/components/ckeditor-styles/index.d.ts +1 -1
  8. package/components/form-generic/index.d.ts +44 -33
  9. package/components/import-excel/index.d.ts +1 -0
  10. package/components/index.d.ts +6 -1
  11. package/components/mini-editor/index.d.ts +1 -1
  12. package/components/modal/index.d.ts +3 -2
  13. package/components/modal-resizable/index.d.ts +92 -0
  14. package/components/org-chart/index.d.ts +6 -0
  15. package/components/preview/index.d.ts +1 -0
  16. package/components/query-bar/index.d.ts +55 -17
  17. package/components/query-builder/index.d.ts +150 -98
  18. package/components/section/index.d.ts +3 -0
  19. package/components/tab-router/index.d.ts +19 -19
  20. package/components/table/index.d.ts +251 -109
  21. package/components/tree/index.d.ts +48 -30
  22. package/components/upload-file/index.d.ts +6 -3
  23. package/configurations/index.d.ts +1 -2
  24. package/fesm2022/sdcorejs-angular-components-anchor.mjs +37 -13
  25. package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
  26. package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +2 -2
  27. package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
  28. package/fesm2022/sdcorejs-angular-components-badge.mjs +15 -2
  29. package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
  30. package/fesm2022/sdcorejs-angular-components-button.mjs +2 -2
  31. package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
  32. package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs +1 -1
  33. package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs.map +1 -1
  34. package/fesm2022/sdcorejs-angular-components-code-editor.mjs +3 -3
  35. package/fesm2022/sdcorejs-angular-components-code-editor.mjs.map +1 -1
  36. package/fesm2022/sdcorejs-angular-components-data-state.mjs +3 -3
  37. package/fesm2022/sdcorejs-angular-components-data-state.mjs.map +1 -1
  38. package/fesm2022/sdcorejs-angular-components-editor.mjs +2 -2
  39. package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
  40. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +324 -192
  41. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  42. package/fesm2022/sdcorejs-angular-components-history.mjs +4 -4
  43. package/fesm2022/sdcorejs-angular-components-history.mjs.map +1 -1
  44. package/fesm2022/sdcorejs-angular-components-import-excel.mjs +13 -5
  45. package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
  46. package/fesm2022/sdcorejs-angular-components-inform.mjs +3 -3
  47. package/fesm2022/sdcorejs-angular-components-inform.mjs.map +1 -1
  48. package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs +164 -8
  49. package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs.map +1 -1
  50. package/fesm2022/sdcorejs-angular-components-modal.mjs +30 -18
  51. package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
  52. package/fesm2022/sdcorejs-angular-components-org-chart.mjs +60 -13
  53. package/fesm2022/sdcorejs-angular-components-org-chart.mjs.map +1 -1
  54. package/fesm2022/sdcorejs-angular-components-preview.mjs +27 -17
  55. package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
  56. package/fesm2022/sdcorejs-angular-components-query-bar.mjs +192 -30
  57. package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
  58. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +187 -127
  59. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  60. package/fesm2022/sdcorejs-angular-components-section.mjs +16 -2
  61. package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
  62. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +83 -24
  63. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
  64. package/fesm2022/sdcorejs-angular-components-splitter.mjs +57 -21
  65. package/fesm2022/sdcorejs-angular-components-splitter.mjs.map +1 -1
  66. package/fesm2022/sdcorejs-angular-components-stepper.mjs +2 -2
  67. package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
  68. package/fesm2022/sdcorejs-angular-components-tab-router.mjs +68 -20
  69. package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
  70. package/fesm2022/sdcorejs-angular-components-tab.mjs +3 -2
  71. package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
  72. package/fesm2022/sdcorejs-angular-components-table.mjs +542 -255
  73. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  74. package/fesm2022/sdcorejs-angular-components-tree.mjs +80 -17
  75. package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
  76. package/fesm2022/sdcorejs-angular-components-upload-file.mjs +48 -13
  77. package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
  78. package/fesm2022/sdcorejs-angular-components.mjs +6 -1
  79. package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
  80. package/fesm2022/sdcorejs-angular-configurations.mjs.map +1 -1
  81. package/fesm2022/sdcorejs-angular-directives.mjs +45 -8
  82. package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
  83. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +40 -29
  84. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  85. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +5 -5
  86. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
  87. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +67 -50
  88. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
  89. package/fesm2022/sdcorejs-angular-forms-chip.mjs +57 -43
  90. package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
  91. package/fesm2022/sdcorejs-angular-forms-date-range.mjs +232 -61
  92. package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
  93. package/fesm2022/sdcorejs-angular-forms-date.mjs +96 -24
  94. package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
  95. package/fesm2022/sdcorejs-angular-forms-datetime.mjs +131 -27
  96. package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
  97. package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs +40 -16
  98. package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs.map +1 -1
  99. package/fesm2022/sdcorejs-angular-forms-input-color.mjs +16 -5
  100. package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
  101. package/fesm2022/sdcorejs-angular-forms-input-number.mjs +24 -9
  102. package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
  103. package/fesm2022/sdcorejs-angular-forms-input.mjs +58 -10
  104. package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
  105. package/fesm2022/sdcorejs-angular-forms-models.mjs +227 -6
  106. package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
  107. package/fesm2022/sdcorejs-angular-forms-radio.mjs +4 -4
  108. package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
  109. package/fesm2022/sdcorejs-angular-forms-select.mjs +136 -38
  110. package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
  111. package/fesm2022/sdcorejs-angular-forms-switch.mjs +18 -3
  112. package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
  113. package/fesm2022/sdcorejs-angular-forms-textarea.mjs +51 -62
  114. package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
  115. package/fesm2022/sdcorejs-angular-forms-time-range.mjs +57 -12
  116. package/fesm2022/sdcorejs-angular-forms-time-range.mjs.map +1 -1
  117. package/fesm2022/sdcorejs-angular-forms-time.mjs +16 -5
  118. package/fesm2022/sdcorejs-angular-forms-time.mjs.map +1 -1
  119. package/fesm2022/sdcorejs-angular-forms-tree-select.mjs +100 -9
  120. package/fesm2022/sdcorejs-angular-forms-tree-select.mjs.map +1 -1
  121. package/fesm2022/sdcorejs-angular-forms.mjs +91 -46
  122. package/fesm2022/sdcorejs-angular-forms.mjs.map +1 -1
  123. package/fesm2022/sdcorejs-angular-handlers.mjs +18 -3
  124. package/fesm2022/sdcorejs-angular-handlers.mjs.map +1 -1
  125. package/fesm2022/sdcorejs-angular-i18n.mjs +490 -68
  126. package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
  127. package/fesm2022/sdcorejs-angular-interceptors.mjs +87 -29
  128. package/fesm2022/sdcorejs-angular-interceptors.mjs.map +1 -1
  129. package/fesm2022/sdcorejs-angular-modules-auth.mjs +25 -15
  130. package/fesm2022/sdcorejs-angular-modules-auth.mjs.map +1 -1
  131. package/fesm2022/sdcorejs-angular-modules-icon.mjs +2 -2
  132. package/fesm2022/sdcorejs-angular-modules-icon.mjs.map +1 -1
  133. package/fesm2022/sdcorejs-angular-modules-keycloak.mjs +32 -3
  134. package/fesm2022/sdcorejs-angular-modules-keycloak.mjs.map +1 -1
  135. package/fesm2022/sdcorejs-angular-modules-layout.mjs +332 -111
  136. package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
  137. package/fesm2022/sdcorejs-angular-modules-permission.mjs +177 -40
  138. package/fesm2022/sdcorejs-angular-modules-permission.mjs.map +1 -1
  139. package/fesm2022/sdcorejs-angular-pipes.mjs +62 -28
  140. package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
  141. package/fesm2022/sdcorejs-angular-services-api.mjs +123 -13
  142. package/fesm2022/sdcorejs-angular-services-api.mjs.map +1 -1
  143. package/fesm2022/sdcorejs-angular-services-cache.mjs +53 -3
  144. package/fesm2022/sdcorejs-angular-services-cache.mjs.map +1 -1
  145. package/fesm2022/sdcorejs-angular-services-confirm.mjs +25 -73
  146. package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
  147. package/fesm2022/sdcorejs-angular-services-excel.mjs +12 -10
  148. package/fesm2022/sdcorejs-angular-services-excel.mjs.map +1 -1
  149. package/fesm2022/sdcorejs-angular-services-loading.mjs +75 -84
  150. package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
  151. package/fesm2022/sdcorejs-angular-services-notify.mjs +46 -5
  152. package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
  153. package/fesm2022/sdcorejs-angular-services-storage.mjs +4 -0
  154. package/fesm2022/sdcorejs-angular-services-storage.mjs.map +1 -1
  155. package/fesm2022/sdcorejs-angular-services.mjs +0 -1
  156. package/fesm2022/sdcorejs-angular-services.mjs.map +1 -1
  157. package/fesm2022/sdcorejs-angular-utilities-extensions.mjs +225 -80
  158. package/fesm2022/sdcorejs-angular-utilities-extensions.mjs.map +1 -1
  159. package/fesm2022/sdcorejs-angular-utilities-models.mjs +1 -63
  160. package/fesm2022/sdcorejs-angular-utilities-models.mjs.map +1 -1
  161. package/fesm2022/sdcorejs-angular.mjs +17 -10
  162. package/fesm2022/sdcorejs-angular.mjs.map +1 -1
  163. package/forms/autocomplete/index.d.ts +5 -2
  164. package/forms/chip-calendar/index.d.ts +10 -0
  165. package/forms/date/index.d.ts +13 -2
  166. package/forms/date-range/index.d.ts +14 -2
  167. package/forms/datetime/index.d.ts +13 -2
  168. package/forms/entity-picker/index.d.ts +9 -3
  169. package/forms/index.d.ts +22 -13
  170. package/forms/input/index.d.ts +3 -0
  171. package/forms/input-color/index.d.ts +4 -0
  172. package/forms/input-number/index.d.ts +3 -0
  173. package/forms/models/index.d.ts +119 -4
  174. package/forms/select/index.d.ts +27 -4
  175. package/forms/switch/index.d.ts +7 -1
  176. package/forms/textarea/index.d.ts +5 -3
  177. package/forms/time-range/index.d.ts +22 -1
  178. package/forms/tree-select/index.d.ts +36 -5
  179. package/i18n/index.d.ts +95 -16
  180. package/index.d.ts +11 -2
  181. package/interceptors/index.d.ts +13 -3
  182. package/modules/auth/index.d.ts +1 -1
  183. package/modules/keycloak/index.d.ts +1 -0
  184. package/modules/layout/index.d.ts +94 -28
  185. package/modules/permission/index.d.ts +66 -4
  186. package/package.json +32 -25
  187. package/pipes/index.d.ts +27 -5
  188. package/services/api/index.d.ts +21 -1
  189. package/services/cache/index.d.ts +11 -1
  190. package/services/index.d.ts +0 -1
  191. package/services/notify/index.d.ts +1 -1
  192. package/utilities/extensions/index.d.ts +83 -61
  193. package/utilities/models/index.d.ts +2 -76
  194. package/components/base/index.d.ts +0 -11
  195. package/components/document-builder/index.d.ts +0 -252
  196. package/fesm2022/sdcorejs-angular-components-base.mjs +0 -23
  197. package/fesm2022/sdcorejs-angular-components-base.mjs.map +0 -1
  198. package/fesm2022/sdcorejs-angular-components-document-builder.mjs +0 -5038
  199. package/fesm2022/sdcorejs-angular-components-document-builder.mjs.map +0 -1
  200. package/fesm2022/sdcorejs-angular-models.mjs +0 -6
  201. package/fesm2022/sdcorejs-angular-models.mjs.map +0 -1
  202. package/fesm2022/sdcorejs-angular-services-docx.mjs +0 -291
  203. package/fesm2022/sdcorejs-angular-services-docx.mjs.map +0 -1
  204. package/fesm2022/sdcorejs-angular-services-license.mjs +0 -97
  205. package/fesm2022/sdcorejs-angular-services-license.mjs.map +0 -1
  206. package/models/index.d.ts +0 -2
  207. package/services/docx/index.d.ts +0 -27
  208. package/services/license/index.d.ts +0 -12
@@ -4,8 +4,8 @@ import * as i0 from '@angular/core';
4
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
- import { NgForm, FormGroup, FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
8
- import { MatCheckboxModule } from '@angular/material/checkbox';
7
+ import { NgForm, FormGroup, FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
8
+ import { MatPseudoCheckbox } from '@angular/material/core';
9
9
  import { MatFormFieldModule } from '@angular/material/form-field';
10
10
  import * as i3 from '@angular/material/input';
11
11
  import { MatInput, MatInputModule } from '@angular/material/input';
@@ -18,10 +18,10 @@ import { MatTooltipModule } from '@angular/material/tooltip';
18
18
  import { SdView } from '@sdcorejs/angular/components/view';
19
19
  import { SdItemDefDefDirective, SdViewDefDirective } from '@sdcorejs/angular/forms/directives';
20
20
  import { SdLabel } from '@sdcorejs/angular/forms/label';
21
- import { SD_FORM_CONFIGURATION, sdFormControlState, sdViewedTransform, sdViewedInline, SdFormControl, ɵsdFormControlConnector as _sdFormControlConnector, HandleSdCustomValidator, SdInlineErrorValidator } from '@sdcorejs/angular/forms/models';
22
- import { I18nService } from '@sdcorejs/angular/i18n';
21
+ import { SD_FORM_CONFIGURATION, ɵsdTimerScope as _sdTimerScope, sdFormControlState, sdViewedTransform, sdViewedInline, SdFormControl, ɵsdFormControlConnector as _sdFormControlConnector, HandleSdCustomValidator, SdInlineErrorValidator } from '@sdcorejs/angular/forms/models';
22
+ import { I18nService, SdTranslatePipe } from '@sdcorejs/angular/i18n';
23
23
  import { sdIsEmpty, sdSerializeDataValue } from '@sdcorejs/angular/utilities/data-state';
24
- import { Utilities, StringUtilities, ArrayUtilities } from '@sdcorejs/angular/utilities/extensions';
24
+ import { Utilities, StringUtilities, ArrayUtilities } from '@sdcorejs/utils/fns';
25
25
  import { timer, combineLatest } from 'rxjs';
26
26
  import { tap, map, startWith, debounce, switchMap } from 'rxjs/operators';
27
27
  import { SdIcon } from '@sdcorejs/angular/modules/icon';
@@ -42,6 +42,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
42
42
 
43
43
  class SdSelect {
44
44
  id = `I${Utilities.generateUuid()}`;
45
+ /** why: id ổn định của <mat-error> để control trỏ `aria-describedby` sang — thông báo lỗi
46
+ * phải đọc được từ chính control, không chỉ hiện ra màn hình. */
47
+ errorId = `${this.id}-error`;
45
48
  // ==========================================
46
49
  // 1. SIGNAL QUERIES & INJECTS
47
50
  // ==========================================
@@ -71,6 +74,9 @@ class SdSelect {
71
74
  #formConfiguration = inject(SD_FORM_CONFIGURATION, { optional: true });
72
75
  #el = inject(ElementRef);
73
76
  #i18n = inject(I18nService);
77
+ // why: focus/mở panel + focus ô search đều hoãn 100ms; handle phải bị clear khi destroy,
78
+ // nếu không callback vẫn chạm selectRef/matInputRef của view đã tháo.
79
+ #timers = _sdTimerScope();
74
80
  // ==========================================
75
81
  // 2. SIGNAL INPUTS & MODEL
76
82
  // ==========================================
@@ -124,8 +130,13 @@ class SdSelect {
124
130
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
125
131
  helperText = input(...(ngDevMode ? [undefined, { debugName: "helperText" }] : []));
126
132
  placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : []));
127
- valueField = input.required(...(ngDevMode ? [{ debugName: "valueField" }] : []));
128
- displayField = input.required(...(ngDevMode ? [{ debugName: "displayField" }] : []));
133
+ // why: KHÔNG dùng input.required. Component nhận `T extends object | string | number` và template
134
+ // nhánh riêng cho mảng primitive (`@else if (!_valueField && !_displayField)`), nhưng
135
+ // input.required làm nhánh đó không bao giờ tới được: `<sd-select [items]="['a','b']">` ném NG0950
136
+ // ngay lần render đầu vì template đọc valueField()/displayField() trước khi có giá trị.
137
+ // Mặc định '' (giống disabledField) → bỏ trống cả hai = item chính là value + label.
138
+ valueField = input('', ...(ngDevMode ? [{ debugName: "valueField" }] : []));
139
+ displayField = input('', ...(ngDevMode ? [{ debugName: "displayField" }] : []));
129
140
  disabledField = input('', ...(ngDevMode ? [{ debugName: "disabledField" }] : []));
130
141
  cacheChecksum = input(...(ngDevMode ? [undefined, { debugName: "cacheChecksum" }] : []));
131
142
  limit = input(50, ...(ngDevMode ? [{ debugName: "limit" }] : []));
@@ -139,6 +150,11 @@ class SdSelect {
139
150
  /** Display mode: `false` edit · `true` static view · `'inline'` view + click-to-edit (bare editor). */
140
151
  viewed = input(false, ...(ngDevMode ? [{ debugName: "viewed", transform: sdViewedTransform }] : [{ transform: sdViewedTransform }]));
141
152
  multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
153
+ /**
154
+ * Hiện option "Tất cả" đầu panel (chỉ multiple + items là mảng tĩnh/Signal — ẩn với
155
+ * SdSearch lazy vì dataset không xác định). Opt-in, default `false`.
156
+ */
157
+ showSelectAll = input(false, ...(ngDevMode ? [{ debugName: "showSelectAll", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
142
158
  /**
143
159
  * Whether the `viewed='inline'` text face shows a hover clear-× to empty the value.
144
160
  * Default `true`. Set `false` where the HOST owns removal (e.g. `<sd-query-bar>` chips,
@@ -159,8 +175,17 @@ class SdSelect {
159
175
  /**
160
176
  * Tổng hợp error message để hiển thị trong tooltip khi hideInlineError = true.
161
177
  */
178
+ // why: `required` và `inlineError` PHẢI được đọc VÔ ĐIỀU KIỆN. Connector cài/gỡ validator bằng
179
+ // `updateValueAndValidity({ emitEvent: false })` → `formControl.errors` đổi mà KHÔNG phát event
180
+ // nào → `#state` (sdFormControlState) không tick. Nếu computed chỉ phụ thuộc `#state` thì bật
181
+ // `[required]` (hoặc set `[inlineError]`) lúc RUNTIME sẽ giữ nguyên message cũ dưới OnPush:
182
+ // control invalid, viền đỏ, nhưng KHÔNG có chữ. Đọc trong nhánh `errors[...]` là không đủ — lần
183
+ // chạy "không lỗi" thoát sớm ở `if (!errors)` nên không đăng ký được dependency nào.
184
+ // `customValidator` thì an toàn: nó tới từ async validator, `setErrors` mặc định CÓ phát event.
162
185
  errorMessage = computed(() => {
163
186
  void this.#state();
187
+ void this.required();
188
+ const inlineError = this.inlineError();
164
189
  const errors = this.formControl.errors;
165
190
  if (!errors)
166
191
  return undefined;
@@ -169,7 +194,7 @@ class SdSelect {
169
194
  if (errors['customValidator'])
170
195
  return errors['customValidator'];
171
196
  if (errors['inlineError'])
172
- return this.inlineError();
197
+ return inlineError;
173
198
  return undefined;
174
199
  }, ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
175
200
  appearanceInput = input(undefined, ...(ngDevMode ? [{ debugName: "appearanceInput", alias: 'appearance' }] : [{ alias: 'appearance' }]));
@@ -187,10 +212,20 @@ class SdSelect {
187
212
  // 4. INTERNAL STATE & STREAMS
188
213
  // ==========================================
189
214
  formControl = new SdFormControl();
215
+ // why: validator đi qua connector (addValidators/removeValidators — additive) thay vì
216
+ // clearValidators()+clearAsyncValidators()+setValidators() như trước. `formControl` là public API,
217
+ // consumer hoàn toàn có thể tự gắn validator lên nó; cách cũ xoá SẠCH những validator đó mỗi lần
218
+ // required/[validator]/inlineError đổi. Connector chỉ thêm/gỡ đúng phần component sở hữu.
190
219
  #formConnector = _sdFormControlConnector({
191
220
  form: this.form,
192
221
  name: this.name,
193
222
  control: computed(() => this.formControl),
223
+ required: this.required,
224
+ validators: computed(() => (this.inlineError() ? [SdInlineErrorValidator] : null)),
225
+ asyncValidators: computed(() => {
226
+ const custom = this.validator();
227
+ return custom ? [HandleSdCustomValidator(custom)] : null;
228
+ }),
194
229
  });
195
230
  inputControl = new FormControl('');
196
231
  loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
@@ -240,6 +275,41 @@ class SdSelect {
240
275
  return false;
241
276
  }, ...(ngDevMode ? [{ debugName: "filtered" }] : []));
242
277
  delayTime = computed(() => (typeof this.actualItems() === 'function' ? 500 : 0), ...(ngDevMode ? [{ debugName: "delayTime" }] : []));
278
+ /**
279
+ * Scope của "Tất cả": item enabled khớp search text hiện tại, tính trên MẢNG NGUỒN
280
+ * `actualItems()`.
281
+ */
282
+ // why: KHÔNG đọc filteredItems — nó đã bị cắt theo `limit` paging nên tick all sẽ thiếu item;
283
+ // luật khớp search phải trùng với filter của allItems$ (aliasIncludes trên cả value + display).
284
+ selectAllScope = computed(() => {
285
+ const data = this.actualItems();
286
+ if (!Array.isArray(data))
287
+ return [];
288
+ const sText = this.searchText() || '';
289
+ return data.filter(item => {
290
+ if (item == null || this.itemDisabled(item))
291
+ return false;
292
+ return StringUtilities.aliasIncludes(this.itemValue(item), sText) || StringUtilities.aliasIncludes(this.itemDisplay(item), sText);
293
+ });
294
+ }, ...(ngDevMode ? [{ debugName: "selectAllScope" }] : []));
295
+ /** Row "Tất cả" chỉ render khi opt-in + multiple + items tĩnh + scope có item để thao tác. */
296
+ selectAllVisible = computed(() => this.showSelectAll() && this.multiple() && Array.isArray(this.actualItems()) && this.selectAllScope().length > 0, ...(ngDevMode ? [{ debugName: "selectAllVisible" }] : []));
297
+ /** Trạng thái checkbox "Tất cả", tính trên items ENABLED trong scope (item disabled bỏ qua). */
298
+ selectAllState = computed(() => {
299
+ const scope = this.selectAllScope();
300
+ const val = this.normalizedValue();
301
+ const selected = new Set((Array.isArray(val) ? val : []).map(v => String(v)));
302
+ if (!scope.length || !selected.size)
303
+ return 'unchecked';
304
+ let count = 0;
305
+ for (const item of scope) {
306
+ if (selected.has(String(this.itemValue(item))))
307
+ count++;
308
+ }
309
+ if (count === 0)
310
+ return 'unchecked';
311
+ return count === scope.length ? 'checked' : 'indeterminate';
312
+ }, ...(ngDevMode ? [{ debugName: "selectAllState" }] : []));
243
313
  // ==========================================
244
314
  // 5. GETTER & HELPERS
245
315
  // ==========================================
@@ -344,12 +414,6 @@ class SdSelect {
344
414
  else
345
415
  this.formControl.enable({ emitEvent: false });
346
416
  });
347
- effect(() => {
348
- const req = this.required();
349
- const val = this.validator();
350
- const inl = this.inlineError();
351
- untracked(() => this.#updateValidator(req, val, inl));
352
- });
353
417
  effect(() => {
354
418
  const actions = this.footerActions();
355
419
  const context = this.footerActionContext();
@@ -495,21 +559,6 @@ class SdSelect {
495
559
  this.#ref.markForCheck();
496
560
  });
497
561
  }
498
- #updateValidator = (req, val, inl) => {
499
- this.formControl.clearValidators();
500
- this.formControl.clearAsyncValidators();
501
- const validators = [];
502
- const asyncValidators = [];
503
- if (req)
504
- validators.push(Validators.required);
505
- if (val)
506
- asyncValidators.push(HandleSdCustomValidator(val));
507
- if (inl)
508
- validators.push(SdInlineErrorValidator);
509
- this.formControl.setValidators(validators.length ? validators : null);
510
- this.formControl.setAsyncValidators(asyncValidators.length ? asyncValidators : null);
511
- this.formControl.updateValueAndValidity({ emitEvent: false });
512
- };
513
562
  #loadSelectedItems = async (value, items) => {
514
563
  if (value === undefined || value === null || value === '')
515
564
  return [];
@@ -573,16 +622,61 @@ class SdSelect {
573
622
  onSelectionChange = (change) => {
574
623
  this.allSelected = !this.selectRef()?.options.some(e => !e.selected);
575
624
  const value = change?.value ?? '';
625
+ // why: KHÔNG dùng { emitEvent: false } khi mirror giá trị chọn sang formControl. formControl mang
626
+ // async [validator] (HandleSdCustomValidator). CVA của mat-select đã setValue (có event) trước khi
627
+ // (selectionChange) chạy; setValue im lặng ở đây HUỶ lần async đang pending đó rồi chạy lại im →
628
+ // setErrors lúc resolve cũng im → #state (sdFormControlState) không tick → errorMessage không
629
+ // recompute → viền đỏ nhưng KHÔNG có message.
630
+ // NHƯNG cũng KHÔNG được setValue vô điều kiện: control lúc này ĐÃ mang đúng giá trị (CVA vừa ghi),
631
+ // nên ghi lại sẽ phát valueChanges LẦN HAI trên chính control và trên FormGroup cha, đồng thời
632
+ // khởi động lại async [validator] hai lần cho mỗi lần chọn. Guard `!==` giữ đúng MỘT event:
633
+ // đi qua UI thì CVA lo, gọi trực tiếp (programmatic/test) thì nhánh setValue lo.
576
634
  if (this.multiple()) {
577
- this.formControl.setValue(value || [], { emitEvent: false });
578
- this.#onChange(value || []);
635
+ const next = value || [];
636
+ if (this.formControl.value !== next)
637
+ this.formControl.setValue(next);
638
+ this.#onChange(next);
579
639
  }
580
640
  else {
581
641
  this.clearSearch();
582
- this.formControl.setValue(value, { emitEvent: false });
642
+ if (this.formControl.value !== value)
643
+ this.formControl.setValue(value);
583
644
  this.#onChange(value);
584
645
  }
585
646
  };
647
+ /**
648
+ * Toggle "Tất cả" theo scope hiện tại (items enabled khớp search):
649
+ * - Đang `checked` → BỎ chọn các value trong scope (giữ value ngoài scope, kể cả item disabled đã chọn).
650
+ * - Ngược lại → CHỌN THÊM toàn bộ scope, union với selection hiện có (additive khi đang search).
651
+ */
652
+ // why: KHÔNG emit sdChange/sdSelection ở đây — giữ đúng semantics hiện hành: hai output đó chỉ
653
+ // bắn khi panel đóng với giá trị đổi (onOpenedChange so hash).
654
+ // why: setValue KHÔNG dùng { emitEvent: false } — cùng lý do như onSelectionChange: formControl
655
+ // mang async [validator], setValue im lặng sẽ huỷ lần async pending rồi chạy lại im → setErrors
656
+ // không phát event → #state không tick → errorMessage stale (viền đỏ mà không có message).
657
+ // Guard `!==` giữ đúng MỘT event: đây là đường programmatic nên nhánh setValue luôn chạy.
658
+ toggleSelectAll = () => {
659
+ const scope = this.selectAllScope();
660
+ if (!scope.length)
661
+ return;
662
+ const current = this.normalizedValue();
663
+ // why: normalizedValue có nhánh bọc scalar boolean thành mảng — với multiple thực tế value là
664
+ // (number | string)[], cast để khớp chữ ký #onChange.
665
+ const currentArr = Array.isArray(current) ? [...current] : [];
666
+ const scopeValues = scope.map(item => this.itemValue(item));
667
+ let next;
668
+ if (this.selectAllState() === 'checked') {
669
+ const scopeKeys = new Set(scopeValues.map(v => String(v)));
670
+ next = currentArr.filter(v => !scopeKeys.has(String(v)));
671
+ }
672
+ else {
673
+ const existing = new Set(currentArr.map(v => String(v)));
674
+ next = [...currentArr, ...scopeValues.filter(v => !existing.has(String(v)))];
675
+ }
676
+ if (this.formControl.value !== next)
677
+ this.formControl.setValue(next);
678
+ this.#onChange(next);
679
+ };
586
680
  reValidate = () => {
587
681
  this.formControl.updateValueAndValidity({ emitEvent: true });
588
682
  };
@@ -616,7 +710,9 @@ class SdSelect {
616
710
  focus = () => {
617
711
  this.focused.set(true);
618
712
  this.updatePanelWidth();
619
- setTimeout(() => {
713
+ // why: vẫn 100ms như cũ — chỉ scope handle theo DestroyRef. Mở panel trên mat-select đã
714
+ // destroy sẽ dựng overlay mồ côi không ai đóng.
715
+ this.#timers.schedule(() => {
620
716
  this.selectRef()?.focus();
621
717
  this.selectRef()?.open();
622
718
  }, 100);
@@ -647,7 +743,8 @@ class SdSelect {
647
743
  if (isOpened) {
648
744
  this.focused.set(true);
649
745
  this.clearSearch();
650
- setTimeout(() => this.matInputRef()?.focus(), 100);
746
+ // why: vẫn 100ms như cũ — chỉ scope handle theo DestroyRef.
747
+ this.#timers.schedule(() => this.matInputRef()?.focus(), 100);
651
748
  this.#hashedValue = Utilities.hash({ value: this.formControl.value });
652
749
  }
653
750
  else {
@@ -676,7 +773,7 @@ class SdSelect {
676
773
  }
677
774
  };
678
775
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
679
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", 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 <sd-icon name=\"close\"></sd-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 class=\"sd-form-field-label\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <sd-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\" name=\"info\"></sd-icon>\n }\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=\"\n _selTpl;\n context: { $implicit: selectedItems(), item: selectedItems(), items: selectedItems(), display: _display, multiple: true }\n \">\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 <sd-icon name=\"search\"></sd-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 _filteredItems = filteredItems();\n @if (_filteredItems) {\n @if (!_filteredItems.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 _filteredItems; 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 _filteredItems; 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 _visibleFooterActions = visibleFooterActions();\n @if (_visibleFooterActions.length) {\n <div class=\"sd-select-footer-actions\">\n @for (action of _visibleFooterActions; 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 <sd-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\" name=\"error\"></sd-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 <sd-icon name=\"close\"></sd-icon>\n </button>\n } @else {\n <sd-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix name=\"keyboard_arrow_down\"></sd-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 class=\"sd-form-field-label\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <sd-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\" name=\"info\"></sd-icon>\n }\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=\"\n _selTpl;\n context: {\n $implicit: selectedItems()[0],\n item: selectedItems()[0],\n items: selectedItems(),\n display: _display,\n multiple: false,\n }\n \">\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 <sd-icon name=\"search\"></sd-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 _filteredItems = filteredItems();\n @if (_filteredItems) {\n @if (!_filteredItems.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 _filteredItems; 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 _filteredItems; 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 _visibleFooterActions = visibleFooterActions();\n @if (_visibleFooterActions.length) {\n <div class=\"sd-select-footer-actions\">\n @for (action of _visibleFooterActions; 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 <sd-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\" name=\"error\"></sd-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 <sd-icon name=\"close\"></sd-icon>\n </button>\n } @else {\n <sd-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix name=\"keyboard_arrow_down\"></sd-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-primary-contrast{color:var(--sd-primary-contrast)!important}.bg-primary-contrast{background:var(--sd-primary-contrast)!important}.border-primary-contrast{border-color:var(--sd-primary-contrast)!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-secondary-contrast{color:var(--sd-secondary-contrast)!important}.bg-secondary-contrast{background:var(--sd-secondary-contrast)!important}.border-secondary-contrast{border-color:var(--sd-secondary-contrast)!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-info-contrast{color:var(--sd-info-contrast)!important}.bg-info-contrast{background:var(--sd-info-contrast)!important}.border-info-contrast{border-color:var(--sd-info-contrast)!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-success-contrast{color:var(--sd-success-contrast)!important}.bg-success-contrast{background:var(--sd-success-contrast)!important}.border-success-contrast{border-color:var(--sd-success-contrast)!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-warning-contrast{color:var(--sd-warning-contrast)!important}.bg-warning-contrast{background:var(--sd-warning-contrast)!important}.border-warning-contrast{border-color:var(--sd-warning-contrast)!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-error-contrast{color:var(--sd-error-contrast)!important}.bg-error-contrast{background:var(--sd-error-contrast)!important}.border-error-contrast{border-color:var(--sd-error-contrast)!important}.text-surface{color:var(--sd-surface)!important}.bg-surface{background:var(--sd-surface)!important}.border-surface{border-color:var(--sd-surface)!important}.text-surface-muted{color:var(--sd-surface-muted)!important}.bg-surface-muted{background:var(--sd-surface-muted)!important}.border-surface-muted{border-color:var(--sd-surface-muted)!important}.text-text{color:var(--sd-text)!important}.bg-text{background:var(--sd-text)!important}.border-text{border-color:var(--sd-text)!important}.text-text-secondary{color:var(--sd-text-secondary)!important}.bg-text-secondary{background:var(--sd-text-secondary)!important}.border-text-secondary{border-color:var(--sd-text-secondary)!important}.text-text-muted{color:var(--sd-text-muted)!important}.bg-text-muted{background:var(--sd-text-muted)!important}.border-text-muted{border-color:var(--sd-text-muted)!important}.text-border{color:var(--sd-border)!important}.bg-border{background:var(--sd-border)!important}.border-border{border-color:var(--sd-border)!important}.text-border-strong{color:var(--sd-border-strong)!important}.bg-border-strong{background:var(--sd-border-strong)!important}.border-border-strong{border-color:var(--sd-border-strong)!important}.text-disabled-bg{color:var(--sd-disabled-bg)!important}.bg-disabled-bg{background:var(--sd-disabled-bg)!important}.border-disabled-bg{border-color:var(--sd-disabled-bg)!important}.text-disabled-text{color:var(--sd-disabled-text)!important}.bg-disabled-text{background:var(--sd-disabled-text)!important}.border-disabled-text{border-color:var(--sd-disabled-text)!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}.text-secondary{color:var(--sd-text-secondary)!important}.text-muted{color:var(--sd-text-muted)!important}.text-body{color:var(--sd-text)!important}.bg-muted{background:var(--sd-surface-muted)!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-disabled-bg)}:host ::ng-deep .mat-mdc-form-field mat-select.mat-mdc-select-disabled .mat-mdc-select-value{color:var(--sd-disabled-text)!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-border);border-radius:4px;background-color:#fff}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper sd-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 sd-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: "component", type: SdIcon, selector: "sd-icon", inputs: ["name", "fontIcon", "color", "set", "fontSet", "size", "strokeWidth", "absoluteStrokeWidth", "ariaLabel"] }, { 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: MatSelectModule }, { kind: "component", type: i5.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: i5.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i6.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 });
776
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", 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: false, transformFunction: null }, displayField: { classPropertyName: "displayField", publicName: "displayField", isSignal: true, isRequired: false, 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 }, showSelectAll: { classPropertyName: "showSelectAll", publicName: "showSelectAll", 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@let _autoId = autoId();\n<!-- why: m\u1ED9t c\u1ED5ng gate duy nh\u1EA5t cho <mat-error>, aria-invalid v\u00E0 aria-describedby. -->\n@let _errorVisible = !!_errorMessage && formControl.touched;\n@let _showInlineError = !_hideInlineError && _errorVisible;\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 <sd-icon name=\"close\"></sd-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 <!-- why: div ch\u1EC9 l\u00E0 h\u1ED9p layout. aria-hidden=\"true\" c\u0169 \u1EA9n C\u1EA2 c\u00E2y con \u2014 label, <mat-select>,\n <mat-error>, n\u00FAt clear \u2014 kh\u1ECFi accessibility tree. role=\"presentation\" ch\u1EC9 v\u00F4 hi\u1EC7u ho\u00E1\n ch\u00EDnh div, KH\u00D4NG lan xu\u1ED1ng con; (click) l\u00E0 ti\u1EC7n \u00EDch chu\u1ED9t, b\u00E0n ph\u00EDm Tab th\u1EB3ng v\u00E0o\n <mat-select> v\u00E0 (focusin) \u0111\u00E3 lo ph\u1EA7n updatePanelWidth() t\u01B0\u01A1ng \u1EE9ng. -->\n <div\n class=\"d-flex align-items-center\"\n role=\"presentation\"\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 @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 class=\"sd-form-field-label\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <sd-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\" name=\"info\"></sd-icon>\n }\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=\"\n _selTpl;\n context: { $implicit: selectedItems(), item: selectedItems(), items: selectedItems(), display: _display, multiple: true }\n \">\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 <sd-icon name=\"search\" aria-hidden=\"true\"></sd-icon>\n <!-- why: B\u1ECE aria-hidden \u2014 \u0111\u00E2y l\u00E0 \u00F4 l\u1ECDc TH\u1EACT, ng\u01B0\u1EDDi d\u00F9ng focus v\u00E0 g\u00F5 v\u00E0o \u0111\u01B0\u1EE3c, n\u00EAn\n aria-hidden ch\u1EC9 l\u00E0m screen reader c\u00E2m. Panel kh\u00F4ng c\u00F3 <label> n\u00E0o, n\u00EAn ph\u1EA3i\n t\u1EF1 \u0111\u1EB7t t\u00EAn b\u1EB1ng aria-label, n\u1EBFu kh\u00F4ng AT ch\u1EC9 \u0111\u1ECDc \"edit text\" tr\u1ED1ng tr\u01A1n. -->\n <input\n [formControl]=\"inputControl\"\n matInput\n autocomplete=\"off\"\n class=\"c-search-input\"\n [attr.aria-label]=\"'core.form.select.search' | sdTranslate\"\n (keydown)=\"$event.stopPropagation()\" />\n </div>\n </div>\n }\n\n <!-- why: row \"T\u1EA5t c\u1EA3\" KH\u00D4NG ph\u1EA3i mat-option th\u1EADt \u2014 n\u1EBFu l\u00E0 option, gi\u00E1 tr\u1ECB c\u1EE7a n\u00F3 l\u1ECDt v\u00E0o\n formControl.value v\u00E0 keyboard navigation c\u1EE7a mat-select. Nh\u01B0ng n\u00F3 ph\u1EA3i TR\u00D4NG y h\u1EC7t m\u1ED9t\n option: d\u00F9ng ch\u00EDnh <mat-pseudo-checkbox> + .mdc-list-item__primary-text m\u00E0 mat-option\n render, n\u00EAn \u0103n c\u00F9ng scale/margin (rule .sd-multiple) v\u00E0 c\u00F9ng m\u00E0u theme (panel mang\n class mat-primary) \u2014 mat-checkbox MDC th\u1EADt th\u00EC l\u1EC7ch c\u1ED9t v\u00E0 \u0103n accent c\u1EE7a theme.\n V\u00EC pseudo-checkbox l\u00E0 decorative + aria-hidden, ch\u00EDnh div mang role/aria/keyboard. -->\n @if (selectAllVisible()) {\n @let _selectAllState = selectAllState();\n <div\n class=\"sd-select-all-row\"\n role=\"checkbox\"\n tabindex=\"0\"\n [attr.aria-checked]=\"_selectAllState === 'indeterminate' ? 'mixed' : _selectAllState === 'checked'\"\n [attr.data-autoid]=\"_autoId ? _autoId + '-select-all' : null\"\n (click)=\"toggleSelectAll()\"\n (keydown.enter)=\"toggleSelectAll(); $event.preventDefault()\"\n (keydown.space)=\"toggleSelectAll(); $event.preventDefault()\"\n (keydown)=\"$event.stopPropagation()\">\n <mat-pseudo-checkbox class=\"mat-mdc-option-pseudo-checkbox\" [state]=\"_selectAllState\" aria-hidden=\"true\"></mat-pseudo-checkbox>\n <span class=\"mdc-list-item__primary-text\">{{ 'core.form.select.selectAll' | sdTranslate }}</span>\n </div>\n }\n\n @let _filteredItems = filteredItems();\n @if (_filteredItems) {\n @if (!_filteredItems.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 _filteredItems; 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 _filteredItems; 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 _visibleFooterActions = visibleFooterActions();\n @if (_visibleFooterActions.length) {\n <div class=\"sd-select-footer-actions\">\n @for (action of _visibleFooterActions; track action) {\n <ng-container *ngTemplateOutlet=\"action.templateRef; context: footerActionContext()\"> </ng-container>\n }\n </div>\n }\n </mat-select>\n\n @if (_hideInlineError && _errorVisible) {\n <sd-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\" name=\"error\"></sd-icon>\n }\n @if (_hideInlineError && _errorVisible) {\n <span class=\"sd-visually-hidden\" matSuffix>{{ _errorMessage }}</span>\n }\n\n <!-- why: <mat-error> ph\u1EA3i c\u00F3 id \u1ED4N \u0110\u1ECANH. MatFormField t\u1EF1 n\u1ED1i id n\u00E0y v\u00E0o aria-describedby\n c\u1EE7a <mat-select> (v\u00E0 host binding c\u1EE7a MatSelect lo aria-invalid), nh\u01B0ng ch\u1EC9 khi id\n t\u1ED3n t\u1EA1i \u2014 id auto-gen c\u1EE7a Material \u0111\u1ED5i theo t\u1EEBng instance n\u00EAn test/AT kh\u00F4ng b\u00E1m \u0111\u01B0\u1EE3c. -->\n @if (_showInlineError) {\n <mat-error [id]=\"errorId\">{{ _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 <sd-icon name=\"close\"></sd-icon>\n </button>\n } @else {\n <sd-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix name=\"keyboard_arrow_down\"></sd-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 class=\"sd-form-field-label\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <sd-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\" name=\"info\"></sd-icon>\n }\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=\"\n _selTpl;\n context: {\n $implicit: selectedItems()[0],\n item: selectedItems()[0],\n items: selectedItems(),\n display: _display,\n multiple: false,\n }\n \">\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 <sd-icon name=\"search\" aria-hidden=\"true\"></sd-icon>\n <!-- why: B\u1ECE aria-hidden \u2014 \u0111\u00E2y l\u00E0 \u00F4 l\u1ECDc TH\u1EACT, ng\u01B0\u1EDDi d\u00F9ng focus v\u00E0 g\u00F5 v\u00E0o \u0111\u01B0\u1EE3c, n\u00EAn\n aria-hidden ch\u1EC9 l\u00E0m screen reader c\u00E2m. Panel kh\u00F4ng c\u00F3 <label> n\u00E0o, n\u00EAn ph\u1EA3i\n t\u1EF1 \u0111\u1EB7t t\u00EAn b\u1EB1ng aria-label, n\u1EBFu kh\u00F4ng AT ch\u1EC9 \u0111\u1ECDc \"edit text\" tr\u1ED1ng tr\u01A1n. -->\n <input\n [formControl]=\"inputControl\"\n matInput\n autocomplete=\"off\"\n class=\"c-search-input\"\n [attr.aria-label]=\"'core.form.select.search' | sdTranslate\"\n (keydown)=\"$event.stopPropagation()\" />\n </div>\n </div>\n }\n\n @let _filteredItems = filteredItems();\n @if (_filteredItems) {\n @if (!_filteredItems.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 _filteredItems; 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 _filteredItems; 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 _visibleFooterActions = visibleFooterActions();\n @if (_visibleFooterActions.length) {\n <div class=\"sd-select-footer-actions\">\n @for (action of _visibleFooterActions; track action) {\n <ng-container *ngTemplateOutlet=\"action.templateRef; context: footerActionContext()\"> </ng-container>\n }\n </div>\n }\n </mat-select>\n\n @if (_hideInlineError && _errorVisible) {\n <sd-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\" name=\"error\"></sd-icon>\n }\n @if (_hideInlineError && _errorVisible) {\n <span class=\"sd-visually-hidden\" matSuffix>{{ _errorMessage }}</span>\n }\n\n <!-- why: <mat-error> ph\u1EA3i c\u00F3 id \u1ED4N \u0110\u1ECANH. MatFormField t\u1EF1 n\u1ED1i id n\u00E0y v\u00E0o aria-describedby\n c\u1EE7a <mat-select> (v\u00E0 host binding c\u1EE7a MatSelect lo aria-invalid), nh\u01B0ng ch\u1EC9 khi id\n t\u1ED3n t\u1EA1i \u2014 id auto-gen c\u1EE7a Material \u0111\u1ED5i theo t\u1EEBng instance n\u00EAn test/AT kh\u00F4ng b\u00E1m \u0111\u01B0\u1EE3c. -->\n @if (_showInlineError) {\n <mat-error [id]=\"errorId\">{{ _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 <sd-icon name=\"close\"></sd-icon>\n </button>\n } @else {\n <sd-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix name=\"keyboard_arrow_down\"></sd-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-primary-contrast{color:var(--sd-primary-contrast)!important}.bg-primary-contrast{background:var(--sd-primary-contrast)!important}.border-primary-contrast{border-color:var(--sd-primary-contrast)!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-secondary-contrast{color:var(--sd-secondary-contrast)!important}.bg-secondary-contrast{background:var(--sd-secondary-contrast)!important}.border-secondary-contrast{border-color:var(--sd-secondary-contrast)!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-info-contrast{color:var(--sd-info-contrast)!important}.bg-info-contrast{background:var(--sd-info-contrast)!important}.border-info-contrast{border-color:var(--sd-info-contrast)!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-success-contrast{color:var(--sd-success-contrast)!important}.bg-success-contrast{background:var(--sd-success-contrast)!important}.border-success-contrast{border-color:var(--sd-success-contrast)!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-warning-contrast{color:var(--sd-warning-contrast)!important}.bg-warning-contrast{background:var(--sd-warning-contrast)!important}.border-warning-contrast{border-color:var(--sd-warning-contrast)!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-error-contrast{color:var(--sd-error-contrast)!important}.bg-error-contrast{background:var(--sd-error-contrast)!important}.border-error-contrast{border-color:var(--sd-error-contrast)!important}.text-surface{color:var(--sd-surface)!important}.bg-surface{background:var(--sd-surface)!important}.border-surface{border-color:var(--sd-surface)!important}.text-surface-muted{color:var(--sd-surface-muted)!important}.bg-surface-muted{background:var(--sd-surface-muted)!important}.border-surface-muted{border-color:var(--sd-surface-muted)!important}.text-text{color:var(--sd-text)!important}.bg-text{background:var(--sd-text)!important}.border-text{border-color:var(--sd-text)!important}.text-text-secondary{color:var(--sd-text-secondary)!important}.bg-text-secondary{background:var(--sd-text-secondary)!important}.border-text-secondary{border-color:var(--sd-text-secondary)!important}.text-text-muted{color:var(--sd-text-muted)!important}.bg-text-muted{background:var(--sd-text-muted)!important}.border-text-muted{border-color:var(--sd-text-muted)!important}.text-border{color:var(--sd-border)!important}.bg-border{background:var(--sd-border)!important}.border-border{border-color:var(--sd-border)!important}.text-border-strong{color:var(--sd-border-strong)!important}.bg-border-strong{background:var(--sd-border-strong)!important}.border-border-strong{border-color:var(--sd-border-strong)!important}.text-disabled-bg{color:var(--sd-disabled-bg)!important}.bg-disabled-bg{background:var(--sd-disabled-bg)!important}.border-disabled-bg{border-color:var(--sd-disabled-bg)!important}.text-disabled-text{color:var(--sd-disabled-text)!important}.bg-disabled-text{background:var(--sd-disabled-text)!important}.border-disabled-text{border-color:var(--sd-disabled-text)!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}.text-secondary{color:var(--sd-text-secondary)!important}.text-muted{color:var(--sd-text-muted)!important}.text-body{color:var(--sd-text)!important}.bg-muted{background:var(--sd-surface-muted)!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-disabled-bg)}:host ::ng-deep .mat-mdc-form-field mat-select.mat-mdc-select-disabled .mat-mdc-select-value{color:var(--sd-disabled-text)!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-border);border-radius:4px;background-color:#fff}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper sd-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-select-panel .sd-select-all-row{display:flex;align-items:center;justify-content:flex-start;min-height:36px;padding:8px 12px;cursor:pointer;-webkit-user-select:none;user-select:none;border-bottom:1px solid var(--mat-sys-outline-variant, #f2f2f2)}::ng-deep .sd-select-panel .sd-select-all-row:hover,::ng-deep .sd-select-panel .sd-select-all-row:focus-visible{background-color:var(--mat-option-hover-state-layer-color, rgba(0, 0, 0, .04));outline:none}::ng-deep .sd-select-panel .sd-select-all-row .mdc-list-item__primary-text{font-size:14px;white-space:normal}::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 sd-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: "component", type: SdIcon, selector: "sd-icon", inputs: ["name", "fontIcon", "color", "set", "fontSet", "size", "strokeWidth", "absoluteStrokeWidth", "ariaLabel"] }, { 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: MatSelectModule }, { kind: "component", type: i5.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: i5.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatPseudoCheckbox, selector: "mat-pseudo-checkbox", inputs: ["state", "disabled", "appearance"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i6.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"] }, { kind: "pipe", type: SdTranslatePipe, name: "sdTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
680
777
  }
681
778
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdSelect, decorators: [{
682
779
  type: Component,
@@ -689,13 +786,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
689
786
  MatTooltipModule,
690
787
  MatFormFieldModule,
691
788
  MatSelectModule,
692
- MatCheckboxModule,
789
+ MatPseudoCheckbox,
693
790
  MatProgressSpinnerModule,
694
791
  SdLabel,
695
792
  SdView,
696
793
  SdSelectFooterActionDirective,
697
- ], 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 <sd-icon name=\"close\"></sd-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 class=\"sd-form-field-label\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <sd-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\" name=\"info\"></sd-icon>\n }\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=\"\n _selTpl;\n context: { $implicit: selectedItems(), item: selectedItems(), items: selectedItems(), display: _display, multiple: true }\n \">\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 <sd-icon name=\"search\"></sd-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 _filteredItems = filteredItems();\n @if (_filteredItems) {\n @if (!_filteredItems.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 _filteredItems; 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 _filteredItems; 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 _visibleFooterActions = visibleFooterActions();\n @if (_visibleFooterActions.length) {\n <div class=\"sd-select-footer-actions\">\n @for (action of _visibleFooterActions; 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 <sd-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\" name=\"error\"></sd-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 <sd-icon name=\"close\"></sd-icon>\n </button>\n } @else {\n <sd-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix name=\"keyboard_arrow_down\"></sd-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 class=\"sd-form-field-label\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <sd-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\" name=\"info\"></sd-icon>\n }\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=\"\n _selTpl;\n context: {\n $implicit: selectedItems()[0],\n item: selectedItems()[0],\n items: selectedItems(),\n display: _display,\n multiple: false,\n }\n \">\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 <sd-icon name=\"search\"></sd-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 _filteredItems = filteredItems();\n @if (_filteredItems) {\n @if (!_filteredItems.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 _filteredItems; 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 _filteredItems; 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 _visibleFooterActions = visibleFooterActions();\n @if (_visibleFooterActions.length) {\n <div class=\"sd-select-footer-actions\">\n @for (action of _visibleFooterActions; 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 <sd-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\" name=\"error\"></sd-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 <sd-icon name=\"close\"></sd-icon>\n </button>\n } @else {\n <sd-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix name=\"keyboard_arrow_down\"></sd-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-primary-contrast{color:var(--sd-primary-contrast)!important}.bg-primary-contrast{background:var(--sd-primary-contrast)!important}.border-primary-contrast{border-color:var(--sd-primary-contrast)!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-secondary-contrast{color:var(--sd-secondary-contrast)!important}.bg-secondary-contrast{background:var(--sd-secondary-contrast)!important}.border-secondary-contrast{border-color:var(--sd-secondary-contrast)!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-info-contrast{color:var(--sd-info-contrast)!important}.bg-info-contrast{background:var(--sd-info-contrast)!important}.border-info-contrast{border-color:var(--sd-info-contrast)!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-success-contrast{color:var(--sd-success-contrast)!important}.bg-success-contrast{background:var(--sd-success-contrast)!important}.border-success-contrast{border-color:var(--sd-success-contrast)!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-warning-contrast{color:var(--sd-warning-contrast)!important}.bg-warning-contrast{background:var(--sd-warning-contrast)!important}.border-warning-contrast{border-color:var(--sd-warning-contrast)!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-error-contrast{color:var(--sd-error-contrast)!important}.bg-error-contrast{background:var(--sd-error-contrast)!important}.border-error-contrast{border-color:var(--sd-error-contrast)!important}.text-surface{color:var(--sd-surface)!important}.bg-surface{background:var(--sd-surface)!important}.border-surface{border-color:var(--sd-surface)!important}.text-surface-muted{color:var(--sd-surface-muted)!important}.bg-surface-muted{background:var(--sd-surface-muted)!important}.border-surface-muted{border-color:var(--sd-surface-muted)!important}.text-text{color:var(--sd-text)!important}.bg-text{background:var(--sd-text)!important}.border-text{border-color:var(--sd-text)!important}.text-text-secondary{color:var(--sd-text-secondary)!important}.bg-text-secondary{background:var(--sd-text-secondary)!important}.border-text-secondary{border-color:var(--sd-text-secondary)!important}.text-text-muted{color:var(--sd-text-muted)!important}.bg-text-muted{background:var(--sd-text-muted)!important}.border-text-muted{border-color:var(--sd-text-muted)!important}.text-border{color:var(--sd-border)!important}.bg-border{background:var(--sd-border)!important}.border-border{border-color:var(--sd-border)!important}.text-border-strong{color:var(--sd-border-strong)!important}.bg-border-strong{background:var(--sd-border-strong)!important}.border-border-strong{border-color:var(--sd-border-strong)!important}.text-disabled-bg{color:var(--sd-disabled-bg)!important}.bg-disabled-bg{background:var(--sd-disabled-bg)!important}.border-disabled-bg{border-color:var(--sd-disabled-bg)!important}.text-disabled-text{color:var(--sd-disabled-text)!important}.bg-disabled-text{background:var(--sd-disabled-text)!important}.border-disabled-text{border-color:var(--sd-disabled-text)!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}.text-secondary{color:var(--sd-text-secondary)!important}.text-muted{color:var(--sd-text-muted)!important}.text-body{color:var(--sd-text)!important}.bg-muted{background:var(--sd-surface-muted)!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-disabled-bg)}:host ::ng-deep .mat-mdc-form-field mat-select.mat-mdc-select-disabled .mat-mdc-select-value{color:var(--sd-disabled-text)!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-border);border-radius:4px;background-color:#fff}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper sd-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 sd-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"] }]
698
- }], ctorParameters: () => [], propDecorators: { matInputRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatInput), { isSignal: true }] }], selectRef: [{ type: i0.ViewChild, args: ['select', { isSignal: true }] }], sdLabelTemplate: [{ type: i0.ContentChild, args: ['sdLabel', { isSignal: true }] }], sdValueTemplate: [{ type: i0.ContentChild, args: ['sdValue', { isSignal: true }] }], sdSelectedTemplate: [{ type: i0.ContentChild, args: ['sdSelected', { isSignal: true }] }], itemDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdItemDefDefDirective), { isSignal: true }] }], sdViewDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdViewDefDirective), { isSignal: true }] }], footerActions: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdSelectFooterActionDirective), { isSignal: true }] }], autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], helperText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helperText", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], valueField: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueField", required: true }] }], displayField: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayField", required: true }] }], disabledField: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledField", required: false }] }], cacheChecksum: [{ type: i0.Input, args: [{ isSignal: true, alias: "cacheChecksum", required: false }] }], limit: [{ type: i0.Input, args: [{ isSignal: true, alias: "limit", required: false }] }], hyperlink: [{ type: i0.Input, args: [{ isSignal: true, alias: "hyperlink", required: false }] }], minWidthPanel: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidthPanel", required: false }] }], hideInlineError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideInlineError", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], viewed: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewed", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], validator: [{ type: i0.Input, args: [{ isSignal: true, alias: "validator", required: false }] }], inlineError: [{ type: i0.Input, args: [{ isSignal: true, alias: "inlineError", required: false }] }], appearanceInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], floatLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatLabel", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], valueModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: false }] }, { type: i0.Output, args: ["modelChange"] }], sdChange: [{ type: i0.Output, args: ["sdChange"] }], sdSelection: [{ type: i0.Output, args: ["sdSelection"] }] } });
794
+ SdTranslatePipe,
795
+ ], 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@let _autoId = autoId();\n<!-- why: m\u1ED9t c\u1ED5ng gate duy nh\u1EA5t cho <mat-error>, aria-invalid v\u00E0 aria-describedby. -->\n@let _errorVisible = !!_errorMessage && formControl.touched;\n@let _showInlineError = !_hideInlineError && _errorVisible;\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 <sd-icon name=\"close\"></sd-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 <!-- why: div ch\u1EC9 l\u00E0 h\u1ED9p layout. aria-hidden=\"true\" c\u0169 \u1EA9n C\u1EA2 c\u00E2y con \u2014 label, <mat-select>,\n <mat-error>, n\u00FAt clear \u2014 kh\u1ECFi accessibility tree. role=\"presentation\" ch\u1EC9 v\u00F4 hi\u1EC7u ho\u00E1\n ch\u00EDnh div, KH\u00D4NG lan xu\u1ED1ng con; (click) l\u00E0 ti\u1EC7n \u00EDch chu\u1ED9t, b\u00E0n ph\u00EDm Tab th\u1EB3ng v\u00E0o\n <mat-select> v\u00E0 (focusin) \u0111\u00E3 lo ph\u1EA7n updatePanelWidth() t\u01B0\u01A1ng \u1EE9ng. -->\n <div\n class=\"d-flex align-items-center\"\n role=\"presentation\"\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 @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 class=\"sd-form-field-label\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <sd-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\" name=\"info\"></sd-icon>\n }\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=\"\n _selTpl;\n context: { $implicit: selectedItems(), item: selectedItems(), items: selectedItems(), display: _display, multiple: true }\n \">\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 <sd-icon name=\"search\" aria-hidden=\"true\"></sd-icon>\n <!-- why: B\u1ECE aria-hidden \u2014 \u0111\u00E2y l\u00E0 \u00F4 l\u1ECDc TH\u1EACT, ng\u01B0\u1EDDi d\u00F9ng focus v\u00E0 g\u00F5 v\u00E0o \u0111\u01B0\u1EE3c, n\u00EAn\n aria-hidden ch\u1EC9 l\u00E0m screen reader c\u00E2m. Panel kh\u00F4ng c\u00F3 <label> n\u00E0o, n\u00EAn ph\u1EA3i\n t\u1EF1 \u0111\u1EB7t t\u00EAn b\u1EB1ng aria-label, n\u1EBFu kh\u00F4ng AT ch\u1EC9 \u0111\u1ECDc \"edit text\" tr\u1ED1ng tr\u01A1n. -->\n <input\n [formControl]=\"inputControl\"\n matInput\n autocomplete=\"off\"\n class=\"c-search-input\"\n [attr.aria-label]=\"'core.form.select.search' | sdTranslate\"\n (keydown)=\"$event.stopPropagation()\" />\n </div>\n </div>\n }\n\n <!-- why: row \"T\u1EA5t c\u1EA3\" KH\u00D4NG ph\u1EA3i mat-option th\u1EADt \u2014 n\u1EBFu l\u00E0 option, gi\u00E1 tr\u1ECB c\u1EE7a n\u00F3 l\u1ECDt v\u00E0o\n formControl.value v\u00E0 keyboard navigation c\u1EE7a mat-select. Nh\u01B0ng n\u00F3 ph\u1EA3i TR\u00D4NG y h\u1EC7t m\u1ED9t\n option: d\u00F9ng ch\u00EDnh <mat-pseudo-checkbox> + .mdc-list-item__primary-text m\u00E0 mat-option\n render, n\u00EAn \u0103n c\u00F9ng scale/margin (rule .sd-multiple) v\u00E0 c\u00F9ng m\u00E0u theme (panel mang\n class mat-primary) \u2014 mat-checkbox MDC th\u1EADt th\u00EC l\u1EC7ch c\u1ED9t v\u00E0 \u0103n accent c\u1EE7a theme.\n V\u00EC pseudo-checkbox l\u00E0 decorative + aria-hidden, ch\u00EDnh div mang role/aria/keyboard. -->\n @if (selectAllVisible()) {\n @let _selectAllState = selectAllState();\n <div\n class=\"sd-select-all-row\"\n role=\"checkbox\"\n tabindex=\"0\"\n [attr.aria-checked]=\"_selectAllState === 'indeterminate' ? 'mixed' : _selectAllState === 'checked'\"\n [attr.data-autoid]=\"_autoId ? _autoId + '-select-all' : null\"\n (click)=\"toggleSelectAll()\"\n (keydown.enter)=\"toggleSelectAll(); $event.preventDefault()\"\n (keydown.space)=\"toggleSelectAll(); $event.preventDefault()\"\n (keydown)=\"$event.stopPropagation()\">\n <mat-pseudo-checkbox class=\"mat-mdc-option-pseudo-checkbox\" [state]=\"_selectAllState\" aria-hidden=\"true\"></mat-pseudo-checkbox>\n <span class=\"mdc-list-item__primary-text\">{{ 'core.form.select.selectAll' | sdTranslate }}</span>\n </div>\n }\n\n @let _filteredItems = filteredItems();\n @if (_filteredItems) {\n @if (!_filteredItems.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 _filteredItems; 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 _filteredItems; 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 _visibleFooterActions = visibleFooterActions();\n @if (_visibleFooterActions.length) {\n <div class=\"sd-select-footer-actions\">\n @for (action of _visibleFooterActions; track action) {\n <ng-container *ngTemplateOutlet=\"action.templateRef; context: footerActionContext()\"> </ng-container>\n }\n </div>\n }\n </mat-select>\n\n @if (_hideInlineError && _errorVisible) {\n <sd-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\" name=\"error\"></sd-icon>\n }\n @if (_hideInlineError && _errorVisible) {\n <span class=\"sd-visually-hidden\" matSuffix>{{ _errorMessage }}</span>\n }\n\n <!-- why: <mat-error> ph\u1EA3i c\u00F3 id \u1ED4N \u0110\u1ECANH. MatFormField t\u1EF1 n\u1ED1i id n\u00E0y v\u00E0o aria-describedby\n c\u1EE7a <mat-select> (v\u00E0 host binding c\u1EE7a MatSelect lo aria-invalid), nh\u01B0ng ch\u1EC9 khi id\n t\u1ED3n t\u1EA1i \u2014 id auto-gen c\u1EE7a Material \u0111\u1ED5i theo t\u1EEBng instance n\u00EAn test/AT kh\u00F4ng b\u00E1m \u0111\u01B0\u1EE3c. -->\n @if (_showInlineError) {\n <mat-error [id]=\"errorId\">{{ _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 <sd-icon name=\"close\"></sd-icon>\n </button>\n } @else {\n <sd-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix name=\"keyboard_arrow_down\"></sd-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 class=\"sd-form-field-label\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <sd-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\" name=\"info\"></sd-icon>\n }\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=\"\n _selTpl;\n context: {\n $implicit: selectedItems()[0],\n item: selectedItems()[0],\n items: selectedItems(),\n display: _display,\n multiple: false,\n }\n \">\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 <sd-icon name=\"search\" aria-hidden=\"true\"></sd-icon>\n <!-- why: B\u1ECE aria-hidden \u2014 \u0111\u00E2y l\u00E0 \u00F4 l\u1ECDc TH\u1EACT, ng\u01B0\u1EDDi d\u00F9ng focus v\u00E0 g\u00F5 v\u00E0o \u0111\u01B0\u1EE3c, n\u00EAn\n aria-hidden ch\u1EC9 l\u00E0m screen reader c\u00E2m. Panel kh\u00F4ng c\u00F3 <label> n\u00E0o, n\u00EAn ph\u1EA3i\n t\u1EF1 \u0111\u1EB7t t\u00EAn b\u1EB1ng aria-label, n\u1EBFu kh\u00F4ng AT ch\u1EC9 \u0111\u1ECDc \"edit text\" tr\u1ED1ng tr\u01A1n. -->\n <input\n [formControl]=\"inputControl\"\n matInput\n autocomplete=\"off\"\n class=\"c-search-input\"\n [attr.aria-label]=\"'core.form.select.search' | sdTranslate\"\n (keydown)=\"$event.stopPropagation()\" />\n </div>\n </div>\n }\n\n @let _filteredItems = filteredItems();\n @if (_filteredItems) {\n @if (!_filteredItems.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 _filteredItems; 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 _filteredItems; 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 _visibleFooterActions = visibleFooterActions();\n @if (_visibleFooterActions.length) {\n <div class=\"sd-select-footer-actions\">\n @for (action of _visibleFooterActions; track action) {\n <ng-container *ngTemplateOutlet=\"action.templateRef; context: footerActionContext()\"> </ng-container>\n }\n </div>\n }\n </mat-select>\n\n @if (_hideInlineError && _errorVisible) {\n <sd-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\" name=\"error\"></sd-icon>\n }\n @if (_hideInlineError && _errorVisible) {\n <span class=\"sd-visually-hidden\" matSuffix>{{ _errorMessage }}</span>\n }\n\n <!-- why: <mat-error> ph\u1EA3i c\u00F3 id \u1ED4N \u0110\u1ECANH. MatFormField t\u1EF1 n\u1ED1i id n\u00E0y v\u00E0o aria-describedby\n c\u1EE7a <mat-select> (v\u00E0 host binding c\u1EE7a MatSelect lo aria-invalid), nh\u01B0ng ch\u1EC9 khi id\n t\u1ED3n t\u1EA1i \u2014 id auto-gen c\u1EE7a Material \u0111\u1ED5i theo t\u1EEBng instance n\u00EAn test/AT kh\u00F4ng b\u00E1m \u0111\u01B0\u1EE3c. -->\n @if (_showInlineError) {\n <mat-error [id]=\"errorId\">{{ _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 <sd-icon name=\"close\"></sd-icon>\n </button>\n } @else {\n <sd-icon class=\"cursor-pointer sd-suffix-icon\" matSuffix name=\"keyboard_arrow_down\"></sd-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-primary-contrast{color:var(--sd-primary-contrast)!important}.bg-primary-contrast{background:var(--sd-primary-contrast)!important}.border-primary-contrast{border-color:var(--sd-primary-contrast)!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-secondary-contrast{color:var(--sd-secondary-contrast)!important}.bg-secondary-contrast{background:var(--sd-secondary-contrast)!important}.border-secondary-contrast{border-color:var(--sd-secondary-contrast)!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-info-contrast{color:var(--sd-info-contrast)!important}.bg-info-contrast{background:var(--sd-info-contrast)!important}.border-info-contrast{border-color:var(--sd-info-contrast)!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-success-contrast{color:var(--sd-success-contrast)!important}.bg-success-contrast{background:var(--sd-success-contrast)!important}.border-success-contrast{border-color:var(--sd-success-contrast)!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-warning-contrast{color:var(--sd-warning-contrast)!important}.bg-warning-contrast{background:var(--sd-warning-contrast)!important}.border-warning-contrast{border-color:var(--sd-warning-contrast)!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-error-contrast{color:var(--sd-error-contrast)!important}.bg-error-contrast{background:var(--sd-error-contrast)!important}.border-error-contrast{border-color:var(--sd-error-contrast)!important}.text-surface{color:var(--sd-surface)!important}.bg-surface{background:var(--sd-surface)!important}.border-surface{border-color:var(--sd-surface)!important}.text-surface-muted{color:var(--sd-surface-muted)!important}.bg-surface-muted{background:var(--sd-surface-muted)!important}.border-surface-muted{border-color:var(--sd-surface-muted)!important}.text-text{color:var(--sd-text)!important}.bg-text{background:var(--sd-text)!important}.border-text{border-color:var(--sd-text)!important}.text-text-secondary{color:var(--sd-text-secondary)!important}.bg-text-secondary{background:var(--sd-text-secondary)!important}.border-text-secondary{border-color:var(--sd-text-secondary)!important}.text-text-muted{color:var(--sd-text-muted)!important}.bg-text-muted{background:var(--sd-text-muted)!important}.border-text-muted{border-color:var(--sd-text-muted)!important}.text-border{color:var(--sd-border)!important}.bg-border{background:var(--sd-border)!important}.border-border{border-color:var(--sd-border)!important}.text-border-strong{color:var(--sd-border-strong)!important}.bg-border-strong{background:var(--sd-border-strong)!important}.border-border-strong{border-color:var(--sd-border-strong)!important}.text-disabled-bg{color:var(--sd-disabled-bg)!important}.bg-disabled-bg{background:var(--sd-disabled-bg)!important}.border-disabled-bg{border-color:var(--sd-disabled-bg)!important}.text-disabled-text{color:var(--sd-disabled-text)!important}.bg-disabled-text{background:var(--sd-disabled-text)!important}.border-disabled-text{border-color:var(--sd-disabled-text)!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}.text-secondary{color:var(--sd-text-secondary)!important}.text-muted{color:var(--sd-text-muted)!important}.text-body{color:var(--sd-text)!important}.bg-muted{background:var(--sd-surface-muted)!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-disabled-bg)}:host ::ng-deep .mat-mdc-form-field mat-select.mat-mdc-select-disabled .mat-mdc-select-value{color:var(--sd-disabled-text)!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-border);border-radius:4px;background-color:#fff}::ng-deep .sd-select-panel .c-filter-input-container .filter-input-wrapper sd-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-select-panel .sd-select-all-row{display:flex;align-items:center;justify-content:flex-start;min-height:36px;padding:8px 12px;cursor:pointer;-webkit-user-select:none;user-select:none;border-bottom:1px solid var(--mat-sys-outline-variant, #f2f2f2)}::ng-deep .sd-select-panel .sd-select-all-row:hover,::ng-deep .sd-select-panel .sd-select-all-row:focus-visible{background-color:var(--mat-option-hover-state-layer-color, rgba(0, 0, 0, .04));outline:none}::ng-deep .sd-select-panel .sd-select-all-row .mdc-list-item__primary-text{font-size:14px;white-space:normal}::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 sd-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"] }]
796
+ }], ctorParameters: () => [], propDecorators: { matInputRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatInput), { isSignal: true }] }], selectRef: [{ type: i0.ViewChild, args: ['select', { isSignal: true }] }], sdLabelTemplate: [{ type: i0.ContentChild, args: ['sdLabel', { isSignal: true }] }], sdValueTemplate: [{ type: i0.ContentChild, args: ['sdValue', { isSignal: true }] }], sdSelectedTemplate: [{ type: i0.ContentChild, args: ['sdSelected', { isSignal: true }] }], itemDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdItemDefDefDirective), { isSignal: true }] }], sdViewDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdViewDefDirective), { isSignal: true }] }], footerActions: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SdSelectFooterActionDirective), { isSignal: true }] }], autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], helperText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helperText", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], valueField: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueField", required: false }] }], displayField: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayField", required: false }] }], disabledField: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledField", required: false }] }], cacheChecksum: [{ type: i0.Input, args: [{ isSignal: true, alias: "cacheChecksum", required: false }] }], limit: [{ type: i0.Input, args: [{ isSignal: true, alias: "limit", required: false }] }], hyperlink: [{ type: i0.Input, args: [{ isSignal: true, alias: "hyperlink", required: false }] }], minWidthPanel: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidthPanel", required: false }] }], hideInlineError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideInlineError", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], viewed: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewed", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], showSelectAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSelectAll", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], validator: [{ type: i0.Input, args: [{ isSignal: true, alias: "validator", required: false }] }], inlineError: [{ type: i0.Input, args: [{ isSignal: true, alias: "inlineError", required: false }] }], appearanceInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], floatLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatLabel", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], valueModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: false }] }, { type: i0.Output, args: ["modelChange"] }], sdChange: [{ type: i0.Output, args: ["sdChange"] }], sdSelection: [{ type: i0.Output, args: ["sdSelection"] }] } });
699
797
 
700
798
  /**
701
799
  * Generated bundle index. Do not edit.