@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
@@ -16,9 +16,9 @@ import { SdView } from '@sdcorejs/angular/components/view';
16
16
  import { SdInlineText } from '@sdcorejs/angular/forms/inline-text';
17
17
  import { SdSuffixDefDirective, SdViewDefDirective } from '@sdcorejs/angular/forms/directives';
18
18
  import { SdLabel } from '@sdcorejs/angular/forms/label';
19
- import { sdFormControlState, SD_FORM_CONFIGURATION, sdViewedTransform, SdFormControl, SdInlineErrorValidator, HandleSdCustomValidator, ɵsdFormControlConnector as _sdFormControlConnector, sdViewedInline } from '@sdcorejs/angular/forms/models';
19
+ import { sdFormControlState, SD_FORM_CONFIGURATION, ɵsdTimerScope as _sdTimerScope, sdViewedTransform, SdFormControl, SdInlineErrorValidator, HandleSdCustomValidator, ɵsdFormControlConnector as _sdFormControlConnector, sdViewedInline } from '@sdcorejs/angular/forms/models';
20
20
  import { sdIsEmpty, sdSerializeDataValue } from '@sdcorejs/angular/utilities/data-state';
21
- import { I18nService, TranslatePipe } from '@sdcorejs/angular/i18n';
21
+ import { I18nService, SdTranslatePipe } from '@sdcorejs/angular/i18n';
22
22
  import { VALIDATION_PATTERNS } from '@sdcorejs/utils/constants';
23
23
  import { Subscription } from 'rxjs';
24
24
  import { SdIcon } from '@sdcorejs/angular/modules/icon';
@@ -176,6 +176,9 @@ const LEGACY_PATTERN_ALIAS = {
176
176
  };
177
177
  class SdInput {
178
178
  id = `I${Utilities.generateUuid()}`;
179
+ /** why: id ổn định của <mat-error> để `<input>` trỏ `aria-describedby` sang — thông báo lỗi
180
+ * phải đọc được từ chính control, không chỉ hiện ra màn hình. */
181
+ errorId = `${this.id}-error`;
179
182
  // ==========================================
180
183
  // 1. SIGNAL QUERIES (Thay thế @ViewChild / @ContentChild)
181
184
  // ==========================================
@@ -225,6 +228,9 @@ class SdInput {
225
228
  #ref = inject(ChangeDetectorRef);
226
229
  #formConfig = inject(SD_FORM_CONFIGURATION, { optional: true });
227
230
  #i18n = inject(I18nService);
231
+ // why: focus bị hoãn 100ms; handle phải bị clear khi destroy, nếu không timer vẫn chạy
232
+ // trên view đã tháo (đổi route nhanh là đủ tái hiện).
233
+ #timers = _sdTimerScope();
228
234
  appearanceInput = input(undefined, ...(ngDevMode ? [{ debugName: "appearanceInput", alias: 'appearance' }] : [{ alias: 'appearance' }]));
229
235
  appearance = computed(() => this.appearanceInput() ?? this.#formConfig?.appearance ?? 'outline', ...(ngDevMode ? [{ debugName: "appearance" }] : []));
230
236
  floatLabel = input('auto', ...(ngDevMode ? [{ debugName: "floatLabel" }] : []));
@@ -321,6 +327,14 @@ class SdInput {
321
327
  errorMessage = computed(() => {
322
328
  // Subscribe to form-state changes so the computed re-evaluates correctly.
323
329
  void this.#state();
330
+ // why: `#state` KHÔNG đủ. Connector cài/gỡ validator bằng `updateValueAndValidity({
331
+ // emitEvent: false })` → `formControl.errors` đổi mà không phát event nào → `#state` không
332
+ // tick. Nên phải đọc VÔ ĐIỀU KIỆN cả `required` lẫn danh sách validator do component sở hữu
333
+ // (`#validators` gói min/max/pattern/mask/inlineError, mảng mới mỗi lần đổi) làm dependency.
334
+ // Không có 2 dòng này thì bật `[required]` lúc RUNTIME cho ra control invalid + viền đỏ nhưng
335
+ // message giữ nguyên giá trị cũ dưới OnPush.
336
+ void this.required();
337
+ void this.#validators();
324
338
  const errors = this.formControl.errors;
325
339
  if (!errors)
326
340
  return undefined;
@@ -414,7 +428,20 @@ class SdInput {
414
428
  /** Shared reactive form policy consumed by template-facing state below. */
415
429
  connectorState = this.#formConnector.state;
416
430
  isReadonly = computed(() => this.connectorState().readonly, ...(ngDevMode ? [{ debugName: "isReadonly" }] : []));
417
- visibleErrorMessage = computed(() => this.connectorState().validationError, ...(ngDevMode ? [{ debugName: "visibleErrorMessage" }] : []));
431
+ // why: KHÔNG lấy `connectorState().validationError`. Cổng hiển thị của connector
432
+ // `snapshot.invalid` — snapshot đó do sdFormControlState memo hoá và chỉ đổi khi control PHÁT
433
+ // event. Connector lại cài validator im lặng (`emitEvent: false`), nên bật `[required]` lúc
434
+ // runtime làm control invalid thật mà snapshot vẫn "valid" → message bị nuốt (viền đỏ, không
435
+ // chữ). Đọc trực tiếp `formControl` cho trạng thái tươi, vẫn giữ nguyên luật interaction-gated
436
+ // (chỉ hiện sau khi người dùng đã chạm/sửa) như connector.
437
+ visibleErrorMessage = computed(() => {
438
+ const message = this.errorMessage();
439
+ if (!message)
440
+ return undefined;
441
+ void this.#state();
442
+ const control = this.formControl;
443
+ return control.invalid && (control.touched || control.dirty) ? message : undefined;
444
+ }, ...(ngDevMode ? [{ debugName: "visibleErrorMessage" }] : []));
418
445
  // Tri-state `viewed` — shared primitive. Input has NO panel; in `'inline'` the input is rendered
419
446
  // borderless/transparent (looks like text), always editable — clicking/focusing it edits directly.
420
447
  #viewedState = sdViewedInline(computed(() => this.connectorState().viewed), () => this.#focusActiveInput(), this.disabled);
@@ -480,7 +507,14 @@ class SdInput {
480
507
  const max = this.maxlength();
481
508
  return !!(max && max > 0 && this.getCurrentLength() > max);
482
509
  };
510
+ // why: clear() phải để formControl phát event (xem comment ở clear()), nhưng nó ĐÃ tự
511
+ // set model + emit sdChange(null) rồi. Không chặn thì #onChange chạy thêm một vòng với
512
+ // `null ?? ''` → consumer nhận thừa một sdChange('') trước sdChange(null) và model bị
513
+ // nhảy '' → null. Cờ chỉ sống trong đúng lời gọi setValue đồng bộ của clear().
514
+ #isClearing = false;
483
515
  #onChange = () => {
516
+ if (this.#isClearing)
517
+ return;
484
518
  const value = this.formControl.value ?? '';
485
519
  this.valueModel.set(value);
486
520
  this.sdChange.emit(value);
@@ -543,7 +577,21 @@ class SdInput {
543
577
  return;
544
578
  // why: clear là thao tác chủ động → model về null (không phải '' hay undefined).
545
579
  // undefined chỉ dành cho trạng thái pristine chưa từng nhập.
546
- this.formControl.setValue(null, { emitEvent: false });
580
+ // why: KHÔNG dùng { emitEvent: false } cho formControl. Control này mang required /
581
+ // pattern / mask validator và cả async validator ([validator] → HandleSdCustomValidator).
582
+ // Chặn event thì AbstractControl.events không phát → #state (sdFormControlState) không
583
+ // tick → errorMessage / dataEmpty / dataValue / visibleErrorMessage giữ nguyên giá trị
584
+ // cũ → xoá xong field rỗng nhưng lỗi required KHÔNG hiện (chỉ còn viền đỏ). Đây đúng là
585
+ // lỗi đã sửa ở #onChange của sd-input-number, chỉ sót nhánh clear().
586
+ // displayControl thì VẪN giữ emitEvent:false — valueChanges của nó có subscriber
587
+ // (#onMaskedDisplayChange) sẽ parse ngược và ghi đè lại formControl.
588
+ this.#isClearing = true;
589
+ try {
590
+ this.formControl.setValue(null);
591
+ }
592
+ finally {
593
+ this.#isClearing = false;
594
+ }
547
595
  this.displayControl.setValue('', { emitEvent: false });
548
596
  this.maskStatus.set('empty');
549
597
  this.valueModel.set(null);
@@ -594,12 +642,12 @@ class SdInput {
594
642
  };
595
643
  focus = () => {
596
644
  this.isFocused = true;
597
- setTimeout(() => {
598
- this.#focusActiveInput();
599
- }, 100);
645
+ // why: vẫn 100ms như cũ (chờ Material dựng xong input mới focus) chỉ khác là handle
646
+ // được scope theo DestroyRef nên không còn chạy sau destroy.
647
+ this.#timers.schedule(() => this.#focusActiveInput(), 100);
600
648
  };
601
649
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
602
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdInput, isStandalone: true, selector: "sd-input", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", 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 }, 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 }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, mask: { classPropertyName: "mask", publicName: "mask", isSignal: true, isRequired: false, transformFunction: null }, hideInlineError: { classPropertyName: "hideInlineError", publicName: "hideInlineError", isSignal: true, isRequired: false, transformFunction: null }, blurOnEnter: { classPropertyName: "blurOnEnter", publicName: "blurOnEnter", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", 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 }, minlength: { classPropertyName: "minlength", publicName: "minlength", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null }, pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: false, transformFunction: null }, patternErrorMessage: { classPropertyName: "patternErrorMessage", publicName: "patternErrorMessage", 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 }, hyperlink: { classPropertyName: "hyperlink", publicName: "hyperlink", isSignal: true, isRequired: false, transformFunction: null }, valueModel: { classPropertyName: "valueModel", publicName: "model", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueModel: "modelChange", sdChange: "sdChange", sdFocus: "sdFocus", sdBlur: "sdBlur", keyupEnter: "keyupEnter", cleared: "cleared", sdFocusForceBlur: "sdFocusForceBlur" }, host: { properties: { "class.sd-has-label": "!!label()", "class.sd-viewed": "isViewed() || isInline()" } }, queries: [{ propertyName: "sdLabelTemplate", first: true, predicate: ["sdLabel"], descendants: true, isSignal: true }, { propertyName: "sdValueTemplate", first: true, predicate: ["sdValue"], descendants: true, isSignal: true }, { propertyName: "sdSuffixDef", first: true, predicate: SdSuffixDefDirective, descendants: true, isSignal: true }, { propertyName: "sdViewDef", first: true, predicate: SdViewDefDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "control", first: true, predicate: ["control"], descendants: true, isSignal: true }, { propertyName: "inlineRef", first: true, predicate: SdInlineText, descendants: true, isSignal: true }], ngImport: i0, template: "@let _label = label();\n@let _appearance = appearance();\n@let _hideInlineError = hideInlineError();\n@let _helperText = helperText();\n@let _maxLength = maxlength();\n@let _errorMessage = visibleErrorMessage();\n@let _required = required();\n@let _isInline = isInline();\n\n@if (isViewed()) {\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"formControl.value\"\n [display]=\"displayValue()\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\">\n </sd-view>\n} @else if (_isInline) {\n <sd-inline-text\n [control]=\"activeControl()\"\n [placeholder]=\"placeholder() || _label || ''\"\n [clearable]=\"clearable() && !_required\"\n [autoId]=\"autoId()\"\n [state]=\"connectorState().invalid ? 'error' : 'auto'\"\n (sdFocus)=\"onFocus()\"\n (sdBlur)=\"onBlur()\"\n (keyupEnter)=\"onKeyupEnter()\"\n (cleared)=\"cleared.emit()\">\n </sd-inline-text>\n} @else {\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 sd-input-container\"\n [class.c-focused]=\"isFocused\"\n [class.c-disabled]=\"formControl.disabled\"\n (click)=\"onClick()\"\n aria-hidden=\"true\">\n <div class=\"sd-input-field-wrap\">\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 <input\n aria-hidden=\"true\"\n [id]=\"id\"\n [formControl]=\"activeControl()\"\n [type]=\"effectiveType()\"\n #control\n matInput\n [placeholder]=\"placeholder() || _label || ''\"\n (keyup.enter)=\"onKeyupEnter()\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n [required]=\"_required\"\n [readonly]=\"isReadonly()\"\n [autocomplete]=\"id\"\n autocorrect=\"off\"\n [step]=\"1\"\n [attr.inputmode]=\"inputMode()\"\n [attr.maxlength]=\"maxDisplayLength()\"\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-required]=\"dataRequired()\"\n [attr.data-maxlength]=\"dataMaxLength()\"\n [attr.data-minlength]=\"dataMinLength()\"\n [attr.data-pattern]=\"dataPattern()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd($event)\" />\n\n @if (!_hideInlineError && _errorMessage) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n <!-- why: n\u00FAt clear render TR\u01AF\u1EDAC error icon. Clear hover-gated (visibility:hidden) v\u1EABn\n chi\u1EBFm ch\u1ED7 trong layout \u2192 n\u1EBFu \u0111\u1EE9ng sau s\u1EBD \u0111\u1EA9y error icon \"t\u1EE5t v\u00E0o trong\". \u0110\u1EE9ng tr\u01B0\u1EDBc\n th\u00EC error icon n\u1EB1m s\u00E1t m\u00E9p ph\u1EA3i, clear gi\u1EEF slot v\u00F4 h\u00ECnh b\u00EAn tr\u00E1i. -->\n @if (showClear()) {\n <button type=\"button\" class=\"sd-clear-btn sd-hover\" matSuffix (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <sd-icon name=\"close\"></sd-icon>\n </button>\n }\n\n @if (_hideInlineError && _errorMessage) {\n <sd-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\" name=\"error\"></sd-icon>\n }\n\n @if (sdSuffixDef()?.templateRef; as suffixRef) {\n <ng-container matSuffix>\n <ng-container *ngTemplateOutlet=\"suffixRef\"></ng-container>\n </ng-container>\n }\n <!-- <ng-container matSuffix>\n <ng-content select=\"[sdSuffix]\"></ng-content>\n </ng-container> -->\n </mat-form-field>\n\n @if (_maxLength && !_hideInlineError && !formControl.disabled) {\n <div\n class=\"sd-maxlength-counter\"\n [class.sd-maxlength-counter--visible]=\"isFocused\"\n [class.sd-maxlength-counter--exceeded]=\"isMaxlengthExceeded()\"\n [attr.title]=\"isMaxlengthExceeded() ? ('core.form.input.exceeded' | translate) : null\">\n {{ getCurrentLength() }}/{{ _maxLength }}\n </div>\n }\n </div>\n </div>\n}\n", styles: [".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}:host(.sd-has-label){padding-top:4px}:host(.sd-viewed){padding-top:0}: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 input.mat-mdc-input-element:disabled{color:var(--sd-disabled-text)!important}:host ::ng-deep .mat-mdc-form-field .mat-mdc-placeholder-required{color:var(--sd-error)}.sd-input-field-wrap{position:relative;flex:1;min-width:0}.sd-maxlength-counter{position:absolute;right:4px;top:calc(100% - 16px);opacity:0;font-size:10px;line-height:1.1;color:#00000061;pointer-events:none;transition:opacity .12s ease;z-index:1}.sd-maxlength-counter--exceeded{color:var(--sd-error);font-weight:600}:host ::ng-deep .sd-input-container.c-focused .sd-maxlength-counter,:host ::ng-deep .sd-input-container:hover .sd-maxlength-counter,:host ::ng-deep .sd-input-container .sd-maxlength-counter.sd-maxlength-counter--visible{opacity:1}.sd-md:hover .btn-copy{visibility:visible}\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: MatFormFieldModule }, { 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: MatInputModule }, { kind: "directive", type: i4.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: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { 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: "component", type: SdInlineText, selector: "sd-inline-text", inputs: ["value", "control", "placeholder", "disabled", "clearable", "state", "chrome", "autoId", "autofocus", "minSize"], outputs: ["valueChange", "cleared", "keyupEnter", "keydownEscape", "sdFocus", "sdBlur", "sdKeydown", "sdPaste", "sdCompositionStart", "sdCompositionEnd"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
650
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdInput, isStandalone: true, selector: "sd-input", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", 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 }, 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 }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, mask: { classPropertyName: "mask", publicName: "mask", isSignal: true, isRequired: false, transformFunction: null }, hideInlineError: { classPropertyName: "hideInlineError", publicName: "hideInlineError", isSignal: true, isRequired: false, transformFunction: null }, blurOnEnter: { classPropertyName: "blurOnEnter", publicName: "blurOnEnter", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", 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 }, minlength: { classPropertyName: "minlength", publicName: "minlength", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null }, pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: false, transformFunction: null }, patternErrorMessage: { classPropertyName: "patternErrorMessage", publicName: "patternErrorMessage", 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 }, hyperlink: { classPropertyName: "hyperlink", publicName: "hyperlink", isSignal: true, isRequired: false, transformFunction: null }, valueModel: { classPropertyName: "valueModel", publicName: "model", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueModel: "modelChange", sdChange: "sdChange", sdFocus: "sdFocus", sdBlur: "sdBlur", keyupEnter: "keyupEnter", cleared: "cleared", sdFocusForceBlur: "sdFocusForceBlur" }, host: { properties: { "class.sd-has-label": "!!label()", "class.sd-viewed": "isViewed() || isInline()" } }, queries: [{ propertyName: "sdLabelTemplate", first: true, predicate: ["sdLabel"], descendants: true, isSignal: true }, { propertyName: "sdValueTemplate", first: true, predicate: ["sdValue"], descendants: true, isSignal: true }, { propertyName: "sdSuffixDef", first: true, predicate: SdSuffixDefDirective, descendants: true, isSignal: true }, { propertyName: "sdViewDef", first: true, predicate: SdViewDefDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "control", first: true, predicate: ["control"], descendants: true, isSignal: true }, { propertyName: "inlineRef", first: true, predicate: SdInlineText, descendants: true, isSignal: true }], ngImport: i0, template: "@let _label = label();\r\n@let _appearance = appearance();\r\n@let _hideInlineError = hideInlineError();\r\n@let _helperText = helperText();\r\n@let _maxLength = maxlength();\r\n@let _errorMessage = visibleErrorMessage();\r\n@let _required = required();\r\n@let _isInline = isInline();\r\n<!-- why: c\u00F9ng M\u1ED8T c\u1ED5ng gate cho c\u1EA3 3 th\u1EE9 \u2014 hi\u1EC7n <mat-error>, b\u1EADt aria-invalid, v\u00E0 tr\u1ECF\r\n aria-describedby. Tr\u01B0\u1EDBc \u0111\u00E2y message hi\u1EC7n m\u00E0 control kh\u00F4ng h\u1EC1 b\u00E1o invalid, n\u00EAn screen\r\n reader \u0111\u1ECDc xong \u00F4 nh\u1EADp v\u1EABn kh\u00F4ng bi\u1EBFt l\u00E0 \u0111ang l\u1ED7i. -->\r\n@let _showInlineError = !_hideInlineError && !!_errorMessage;\r\n\r\n@if (isViewed()) {\r\n <sd-view\r\n [label]=\"_label\"\r\n [labelTemplate]=\"sdLabelTemplate()\"\r\n [value]=\"formControl.value\"\r\n [display]=\"displayValue()\"\r\n [hyperlink]=\"hyperlink()\"\r\n [valueTemplate]=\"viewTemplate()\">\r\n </sd-view>\r\n} @else if (_isInline) {\r\n <!-- why: nh\u00E1nh inline PH\u1EA2I project `sdSuffixDef` gi\u1ED1ng nh\u00E1nh mat-form-field. Tr\u01B0\u1EDBc \u0111\u00E2y ch\u1EC9\r\n <sd-inline-text> \u0111\u01B0\u1EE3c render, n\u00EAn <sd-input-color viewed=\"'inline'\"> m\u1EA5t lu\u00F4n swatch v\u00E0\r\n <input type=\"color\"> \u1EA9n \u2014 openPicker() g\u1ECDi \u0111\u01B0\u1EE3c nh\u01B0ng kh\u00F4ng c\u00F3 element n\u00E0o \u0111\u1EC3 click, t\u1EE9c\r\n l\u00E0 no-op c\u00E2m. <sd-inline-text> l\u00E0 inline-flex t\u1EF1 hug n\u1ED9i dung n\u00EAn ch\u1EC9 c\u1EA7n m\u1ED9t h\u00E0ng flex. -->\r\n <div class=\"sd-input-inline\">\r\n <sd-inline-text\r\n [control]=\"activeControl()\"\r\n [placeholder]=\"placeholder() || _label || ''\"\r\n [clearable]=\"clearable() && !_required\"\r\n [autoId]=\"autoId()\"\r\n [state]=\"connectorState().invalid ? 'error' : 'auto'\"\r\n (sdFocus)=\"onFocus()\"\r\n (sdBlur)=\"onBlur()\"\r\n (keyupEnter)=\"onKeyupEnter()\"\r\n (cleared)=\"cleared.emit()\">\r\n </sd-inline-text>\r\n\r\n @if (sdSuffixDef()?.templateRef; as suffixRef) {\r\n <span class=\"sd-input-inline__suffix\">\r\n <ng-container *ngTemplateOutlet=\"suffixRef\"></ng-container>\r\n </span>\r\n }\r\n </div>\r\n} @else {\r\n @if (!_appearance) {\r\n <ng-content select=\"[sdLabel]\">\r\n @if (_label) {\r\n <sd-label [label]=\"_label\" [required]=\"_required\"></sd-label>\r\n }\r\n </ng-content>\r\n }\r\n\r\n <!-- why: div n\u00E0y CH\u1EC8 l\u00E0 h\u1ED9p layout. N\u00F3 t\u1EEBng mang aria-hidden=\"true\" \u0111\u1EC3 d\u1EADp c\u1EA3nh b\u00E1o lint \u2014\r\n v\u00E0 aria-hidden \u1EA9n C\u1EA2 c\u00E2y con, n\u00EAn label, <input>, <mat-error> l\u1EABn n\u00FAt clear bi\u1EBFn m\u1EA5t\r\n kh\u1ECFi accessibility tree c\u00F9ng l\u00FAc. role=\"presentation\" ch\u1EC9 v\u00F4 hi\u1EC7u ho\u00E1 ch\u00EDnh div (KH\u00D4NG\r\n lan xu\u1ED1ng con), c\u00F2n (click) ch\u1EC9 l\u00E0 ti\u1EC7n \u00EDch chu\u1ED9t: b\u00E0n ph\u00EDm Tab th\u1EB3ng v\u00E0o <input> v\u00E0\r\n nh\u1EADn \u0111\u00FAng k\u1EBFt qu\u1EA3 \u0111\u00F3, n\u00EAn kh\u00F4ng c\u1EA7n th\u00EAm key handler. -->\r\n <div\r\n class=\"d-flex align-items-center sd-input-container\"\r\n role=\"presentation\"\r\n [class.c-focused]=\"isFocused\"\r\n [class.c-disabled]=\"formControl.disabled\"\r\n (click)=\"onClick()\">\r\n <div class=\"sd-input-field-wrap\">\r\n <mat-form-field\r\n [class.sd-md]=\"size() === 'md'\"\r\n [class.sd-sm]=\"size() === 'sm'\"\r\n [class.hide-inline-error]=\"_hideInlineError\"\r\n [appearance]=\"_appearance!\"\r\n [floatLabel]=\"floatLabel()\">\r\n @if (_appearance && _label) {\r\n <mat-label class=\"sd-form-field-label\">\r\n <span>{{ _label }}</span>\r\n @if (_helperText) {\r\n <sd-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\" name=\"info\"></sd-icon>\r\n }\r\n </mat-label>\r\n }\r\n\r\n <!-- why: B\u1ECE aria-hidden tr\u00EAn ch\u00EDnh <input>. Input v\u1EABn focus \u0111\u01B0\u1EE3c b\u1EB1ng Tab, n\u00EAn\r\n aria-hidden khi\u1EBFn screen reader \u0111\u1ECDc ra\u2026 kh\u00F4ng g\u00EC c\u1EA3 \u2014 t\u1EC7 h\u01A1n l\u00E0 kh\u00F4ng l\u00E0m g\u00EC. -->\r\n <input\r\n [id]=\"id\"\r\n [formControl]=\"activeControl()\"\r\n [type]=\"effectiveType()\"\r\n #control\r\n matInput\r\n [placeholder]=\"placeholder() || _label || ''\"\r\n (keyup.enter)=\"onKeyupEnter()\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n [required]=\"_required\"\r\n [readonly]=\"isReadonly()\"\r\n [autocomplete]=\"id\"\r\n autocorrect=\"off\"\r\n [step]=\"1\"\r\n [attr.inputmode]=\"inputMode()\"\r\n [attr.maxlength]=\"maxDisplayLength()\"\r\n [attr.data-autoId]=\"autoId()\"\r\n [attr.data-disabled]=\"dataDisabled()\"\r\n [attr.data-invalid]=\"dataInvalid()\"\r\n [attr.data-empty]=\"dataEmpty()\"\r\n [attr.data-value]=\"dataValue()\"\r\n [attr.data-required]=\"dataRequired()\"\r\n [attr.data-maxlength]=\"dataMaxLength()\"\r\n [attr.data-minlength]=\"dataMinLength()\"\r\n [attr.data-pattern]=\"dataPattern()\"\r\n [attr.data-error-message]=\"dataErrorMessage()\"\r\n [attr.aria-invalid]=\"_errorMessage ? 'true' : null\"\r\n [attr.aria-describedby]=\"_errorMessage ? errorId : null\"\r\n (compositionstart)=\"onCompositionStart()\"\r\n (compositionend)=\"onCompositionEnd($event)\" />\r\n\r\n @if (_showInlineError) {\r\n <mat-error [id]=\"errorId\">{{ _errorMessage }}</mat-error>\r\n }\r\n\r\n <!-- why: n\u00FAt clear render TR\u01AF\u1EDAC error icon. Clear hover-gated (visibility:hidden) v\u1EABn\r\n chi\u1EBFm ch\u1ED7 trong layout \u2192 n\u1EBFu \u0111\u1EE9ng sau s\u1EBD \u0111\u1EA9y error icon \"t\u1EE5t v\u00E0o trong\". \u0110\u1EE9ng tr\u01B0\u1EDBc\r\n th\u00EC error icon n\u1EB1m s\u00E1t m\u00E9p ph\u1EA3i, clear gi\u1EEF slot v\u00F4 h\u00ECnh b\u00EAn tr\u00E1i. -->\r\n @if (showClear()) {\r\n <button type=\"button\" class=\"sd-clear-btn sd-hover\" matSuffix (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\r\n <sd-icon name=\"close\"></sd-icon>\r\n </button>\r\n }\r\n\r\n @if (_hideInlineError && _errorMessage) {\r\n <sd-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\" name=\"error\"></sd-icon>\n }\r\n @if (_hideInlineError && _errorMessage) {\r\n <span class=\"sd-visually-hidden\" [id]=\"errorId\" matSuffix>{{ _errorMessage }}</span>\r\r\n }\r\n\r\n @if (sdSuffixDef()?.templateRef; as suffixRef) {\r\n <ng-container matSuffix>\r\n <ng-container *ngTemplateOutlet=\"suffixRef\"></ng-container>\r\n </ng-container>\r\n }\r\n <!-- <ng-container matSuffix>\r\n <ng-content select=\"[sdSuffix]\"></ng-content>\r\n </ng-container> -->\r\n </mat-form-field>\r\n\r\n @if (_maxLength && !_hideInlineError && !formControl.disabled) {\r\n <div\r\n class=\"sd-maxlength-counter\"\r\n [class.sd-maxlength-counter--visible]=\"isFocused\"\r\n [class.sd-maxlength-counter--exceeded]=\"isMaxlengthExceeded()\"\r\n [attr.title]=\"isMaxlengthExceeded() ? ('core.form.input.exceeded' | sdTranslate) : null\">\r\n {{ getCurrentLength() }}/{{ _maxLength }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n}\r\n", styles: [".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}.sd-input-inline{display:inline-flex;align-items:center;gap:4px;max-width:100%}.sd-input-inline__suffix{display:inline-flex;align-items:center;line-height:0}:host(.sd-has-label){padding-top:4px}:host(.sd-viewed){padding-top:0}: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 input.mat-mdc-input-element:disabled{color:var(--sd-disabled-text)!important}:host ::ng-deep .mat-mdc-form-field .mat-mdc-placeholder-required{color:var(--sd-error)}.sd-input-field-wrap{position:relative;flex:1;min-width:0}.sd-maxlength-counter{position:absolute;right:4px;top:calc(100% - 16px);opacity:0;font-size:10px;line-height:1.1;color:#00000061;pointer-events:none;transition:opacity .12s ease;z-index:1}.sd-maxlength-counter--exceeded{color:var(--sd-error);font-weight:600}:host ::ng-deep .sd-input-container.c-focused .sd-maxlength-counter,:host ::ng-deep .sd-input-container:hover .sd-maxlength-counter,:host ::ng-deep .sd-input-container .sd-maxlength-counter.sd-maxlength-counter--visible{opacity:1}.sd-md:hover .btn-copy{visibility:visible}\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: MatFormFieldModule }, { 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: MatInputModule }, { kind: "directive", type: i4.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: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { 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: "component", type: SdInlineText, selector: "sd-inline-text", inputs: ["value", "control", "placeholder", "disabled", "clearable", "state", "chrome", "autoId", "autofocus", "minSize"], outputs: ["valueChange", "cleared", "keyupEnter", "keydownEscape", "sdFocus", "sdBlur", "sdKeydown", "sdPaste", "sdCompositionStart", "sdCompositionEnd"] }, { kind: "pipe", type: SdTranslatePipe, name: "sdTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
603
651
  }
604
652
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdInput, decorators: [{
605
653
  type: Component,
@@ -615,8 +663,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
615
663
  SdLabel,
616
664
  SdView,
617
665
  SdInlineText,
618
- TranslatePipe,
619
- ], template: "@let _label = label();\n@let _appearance = appearance();\n@let _hideInlineError = hideInlineError();\n@let _helperText = helperText();\n@let _maxLength = maxlength();\n@let _errorMessage = visibleErrorMessage();\n@let _required = required();\n@let _isInline = isInline();\n\n@if (isViewed()) {\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"formControl.value\"\n [display]=\"displayValue()\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\">\n </sd-view>\n} @else if (_isInline) {\n <sd-inline-text\n [control]=\"activeControl()\"\n [placeholder]=\"placeholder() || _label || ''\"\n [clearable]=\"clearable() && !_required\"\n [autoId]=\"autoId()\"\n [state]=\"connectorState().invalid ? 'error' : 'auto'\"\n (sdFocus)=\"onFocus()\"\n (sdBlur)=\"onBlur()\"\n (keyupEnter)=\"onKeyupEnter()\"\n (cleared)=\"cleared.emit()\">\n </sd-inline-text>\n} @else {\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 sd-input-container\"\n [class.c-focused]=\"isFocused\"\n [class.c-disabled]=\"formControl.disabled\"\n (click)=\"onClick()\"\n aria-hidden=\"true\">\n <div class=\"sd-input-field-wrap\">\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 <input\n aria-hidden=\"true\"\n [id]=\"id\"\n [formControl]=\"activeControl()\"\n [type]=\"effectiveType()\"\n #control\n matInput\n [placeholder]=\"placeholder() || _label || ''\"\n (keyup.enter)=\"onKeyupEnter()\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n [required]=\"_required\"\n [readonly]=\"isReadonly()\"\n [autocomplete]=\"id\"\n autocorrect=\"off\"\n [step]=\"1\"\n [attr.inputmode]=\"inputMode()\"\n [attr.maxlength]=\"maxDisplayLength()\"\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-required]=\"dataRequired()\"\n [attr.data-maxlength]=\"dataMaxLength()\"\n [attr.data-minlength]=\"dataMinLength()\"\n [attr.data-pattern]=\"dataPattern()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n (compositionstart)=\"onCompositionStart()\"\n (compositionend)=\"onCompositionEnd($event)\" />\n\n @if (!_hideInlineError && _errorMessage) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n <!-- why: n\u00FAt clear render TR\u01AF\u1EDAC error icon. Clear hover-gated (visibility:hidden) v\u1EABn\n chi\u1EBFm ch\u1ED7 trong layout \u2192 n\u1EBFu \u0111\u1EE9ng sau s\u1EBD \u0111\u1EA9y error icon \"t\u1EE5t v\u00E0o trong\". \u0110\u1EE9ng tr\u01B0\u1EDBc\n th\u00EC error icon n\u1EB1m s\u00E1t m\u00E9p ph\u1EA3i, clear gi\u1EEF slot v\u00F4 h\u00ECnh b\u00EAn tr\u00E1i. -->\n @if (showClear()) {\n <button type=\"button\" class=\"sd-clear-btn sd-hover\" matSuffix (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <sd-icon name=\"close\"></sd-icon>\n </button>\n }\n\n @if (_hideInlineError && _errorMessage) {\n <sd-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\" name=\"error\"></sd-icon>\n }\n\n @if (sdSuffixDef()?.templateRef; as suffixRef) {\n <ng-container matSuffix>\n <ng-container *ngTemplateOutlet=\"suffixRef\"></ng-container>\n </ng-container>\n }\n <!-- <ng-container matSuffix>\n <ng-content select=\"[sdSuffix]\"></ng-content>\n </ng-container> -->\n </mat-form-field>\n\n @if (_maxLength && !_hideInlineError && !formControl.disabled) {\n <div\n class=\"sd-maxlength-counter\"\n [class.sd-maxlength-counter--visible]=\"isFocused\"\n [class.sd-maxlength-counter--exceeded]=\"isMaxlengthExceeded()\"\n [attr.title]=\"isMaxlengthExceeded() ? ('core.form.input.exceeded' | translate) : null\">\n {{ getCurrentLength() }}/{{ _maxLength }}\n </div>\n }\n </div>\n </div>\n}\n", styles: [".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}:host(.sd-has-label){padding-top:4px}:host(.sd-viewed){padding-top:0}: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 input.mat-mdc-input-element:disabled{color:var(--sd-disabled-text)!important}:host ::ng-deep .mat-mdc-form-field .mat-mdc-placeholder-required{color:var(--sd-error)}.sd-input-field-wrap{position:relative;flex:1;min-width:0}.sd-maxlength-counter{position:absolute;right:4px;top:calc(100% - 16px);opacity:0;font-size:10px;line-height:1.1;color:#00000061;pointer-events:none;transition:opacity .12s ease;z-index:1}.sd-maxlength-counter--exceeded{color:var(--sd-error);font-weight:600}:host ::ng-deep .sd-input-container.c-focused .sd-maxlength-counter,:host ::ng-deep .sd-input-container:hover .sd-maxlength-counter,:host ::ng-deep .sd-input-container .sd-maxlength-counter.sd-maxlength-counter--visible{opacity:1}.sd-md:hover .btn-copy{visibility:visible}\n"] }]
666
+ SdTranslatePipe,
667
+ ], template: "@let _label = label();\r\n@let _appearance = appearance();\r\n@let _hideInlineError = hideInlineError();\r\n@let _helperText = helperText();\r\n@let _maxLength = maxlength();\r\n@let _errorMessage = visibleErrorMessage();\r\n@let _required = required();\r\n@let _isInline = isInline();\r\n<!-- why: c\u00F9ng M\u1ED8T c\u1ED5ng gate cho c\u1EA3 3 th\u1EE9 \u2014 hi\u1EC7n <mat-error>, b\u1EADt aria-invalid, v\u00E0 tr\u1ECF\r\n aria-describedby. Tr\u01B0\u1EDBc \u0111\u00E2y message hi\u1EC7n m\u00E0 control kh\u00F4ng h\u1EC1 b\u00E1o invalid, n\u00EAn screen\r\n reader \u0111\u1ECDc xong \u00F4 nh\u1EADp v\u1EABn kh\u00F4ng bi\u1EBFt l\u00E0 \u0111ang l\u1ED7i. -->\r\n@let _showInlineError = !_hideInlineError && !!_errorMessage;\r\n\r\n@if (isViewed()) {\r\n <sd-view\r\n [label]=\"_label\"\r\n [labelTemplate]=\"sdLabelTemplate()\"\r\n [value]=\"formControl.value\"\r\n [display]=\"displayValue()\"\r\n [hyperlink]=\"hyperlink()\"\r\n [valueTemplate]=\"viewTemplate()\">\r\n </sd-view>\r\n} @else if (_isInline) {\r\n <!-- why: nh\u00E1nh inline PH\u1EA2I project `sdSuffixDef` gi\u1ED1ng nh\u00E1nh mat-form-field. Tr\u01B0\u1EDBc \u0111\u00E2y ch\u1EC9\r\n <sd-inline-text> \u0111\u01B0\u1EE3c render, n\u00EAn <sd-input-color viewed=\"'inline'\"> m\u1EA5t lu\u00F4n swatch v\u00E0\r\n <input type=\"color\"> \u1EA9n \u2014 openPicker() g\u1ECDi \u0111\u01B0\u1EE3c nh\u01B0ng kh\u00F4ng c\u00F3 element n\u00E0o \u0111\u1EC3 click, t\u1EE9c\r\n l\u00E0 no-op c\u00E2m. <sd-inline-text> l\u00E0 inline-flex t\u1EF1 hug n\u1ED9i dung n\u00EAn ch\u1EC9 c\u1EA7n m\u1ED9t h\u00E0ng flex. -->\r\n <div class=\"sd-input-inline\">\r\n <sd-inline-text\r\n [control]=\"activeControl()\"\r\n [placeholder]=\"placeholder() || _label || ''\"\r\n [clearable]=\"clearable() && !_required\"\r\n [autoId]=\"autoId()\"\r\n [state]=\"connectorState().invalid ? 'error' : 'auto'\"\r\n (sdFocus)=\"onFocus()\"\r\n (sdBlur)=\"onBlur()\"\r\n (keyupEnter)=\"onKeyupEnter()\"\r\n (cleared)=\"cleared.emit()\">\r\n </sd-inline-text>\r\n\r\n @if (sdSuffixDef()?.templateRef; as suffixRef) {\r\n <span class=\"sd-input-inline__suffix\">\r\n <ng-container *ngTemplateOutlet=\"suffixRef\"></ng-container>\r\n </span>\r\n }\r\n </div>\r\n} @else {\r\n @if (!_appearance) {\r\n <ng-content select=\"[sdLabel]\">\r\n @if (_label) {\r\n <sd-label [label]=\"_label\" [required]=\"_required\"></sd-label>\r\n }\r\n </ng-content>\r\n }\r\n\r\n <!-- why: div n\u00E0y CH\u1EC8 l\u00E0 h\u1ED9p layout. N\u00F3 t\u1EEBng mang aria-hidden=\"true\" \u0111\u1EC3 d\u1EADp c\u1EA3nh b\u00E1o lint \u2014\r\n v\u00E0 aria-hidden \u1EA9n C\u1EA2 c\u00E2y con, n\u00EAn label, <input>, <mat-error> l\u1EABn n\u00FAt clear bi\u1EBFn m\u1EA5t\r\n kh\u1ECFi accessibility tree c\u00F9ng l\u00FAc. role=\"presentation\" ch\u1EC9 v\u00F4 hi\u1EC7u ho\u00E1 ch\u00EDnh div (KH\u00D4NG\r\n lan xu\u1ED1ng con), c\u00F2n (click) ch\u1EC9 l\u00E0 ti\u1EC7n \u00EDch chu\u1ED9t: b\u00E0n ph\u00EDm Tab th\u1EB3ng v\u00E0o <input> v\u00E0\r\n nh\u1EADn \u0111\u00FAng k\u1EBFt qu\u1EA3 \u0111\u00F3, n\u00EAn kh\u00F4ng c\u1EA7n th\u00EAm key handler. -->\r\n <div\r\n class=\"d-flex align-items-center sd-input-container\"\r\n role=\"presentation\"\r\n [class.c-focused]=\"isFocused\"\r\n [class.c-disabled]=\"formControl.disabled\"\r\n (click)=\"onClick()\">\r\n <div class=\"sd-input-field-wrap\">\r\n <mat-form-field\r\n [class.sd-md]=\"size() === 'md'\"\r\n [class.sd-sm]=\"size() === 'sm'\"\r\n [class.hide-inline-error]=\"_hideInlineError\"\r\n [appearance]=\"_appearance!\"\r\n [floatLabel]=\"floatLabel()\">\r\n @if (_appearance && _label) {\r\n <mat-label class=\"sd-form-field-label\">\r\n <span>{{ _label }}</span>\r\n @if (_helperText) {\r\n <sd-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\" name=\"info\"></sd-icon>\r\n }\r\n </mat-label>\r\n }\r\n\r\n <!-- why: B\u1ECE aria-hidden tr\u00EAn ch\u00EDnh <input>. Input v\u1EABn focus \u0111\u01B0\u1EE3c b\u1EB1ng Tab, n\u00EAn\r\n aria-hidden khi\u1EBFn screen reader \u0111\u1ECDc ra\u2026 kh\u00F4ng g\u00EC c\u1EA3 \u2014 t\u1EC7 h\u01A1n l\u00E0 kh\u00F4ng l\u00E0m g\u00EC. -->\r\n <input\r\n [id]=\"id\"\r\n [formControl]=\"activeControl()\"\r\n [type]=\"effectiveType()\"\r\n #control\r\n matInput\r\n [placeholder]=\"placeholder() || _label || ''\"\r\n (keyup.enter)=\"onKeyupEnter()\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n [required]=\"_required\"\r\n [readonly]=\"isReadonly()\"\r\n [autocomplete]=\"id\"\r\n autocorrect=\"off\"\r\n [step]=\"1\"\r\n [attr.inputmode]=\"inputMode()\"\r\n [attr.maxlength]=\"maxDisplayLength()\"\r\n [attr.data-autoId]=\"autoId()\"\r\n [attr.data-disabled]=\"dataDisabled()\"\r\n [attr.data-invalid]=\"dataInvalid()\"\r\n [attr.data-empty]=\"dataEmpty()\"\r\n [attr.data-value]=\"dataValue()\"\r\n [attr.data-required]=\"dataRequired()\"\r\n [attr.data-maxlength]=\"dataMaxLength()\"\r\n [attr.data-minlength]=\"dataMinLength()\"\r\n [attr.data-pattern]=\"dataPattern()\"\r\n [attr.data-error-message]=\"dataErrorMessage()\"\r\n [attr.aria-invalid]=\"_errorMessage ? 'true' : null\"\r\n [attr.aria-describedby]=\"_errorMessage ? errorId : null\"\r\n (compositionstart)=\"onCompositionStart()\"\r\n (compositionend)=\"onCompositionEnd($event)\" />\r\n\r\n @if (_showInlineError) {\r\n <mat-error [id]=\"errorId\">{{ _errorMessage }}</mat-error>\r\n }\r\n\r\n <!-- why: n\u00FAt clear render TR\u01AF\u1EDAC error icon. Clear hover-gated (visibility:hidden) v\u1EABn\r\n chi\u1EBFm ch\u1ED7 trong layout \u2192 n\u1EBFu \u0111\u1EE9ng sau s\u1EBD \u0111\u1EA9y error icon \"t\u1EE5t v\u00E0o trong\". \u0110\u1EE9ng tr\u01B0\u1EDBc\r\n th\u00EC error icon n\u1EB1m s\u00E1t m\u00E9p ph\u1EA3i, clear gi\u1EEF slot v\u00F4 h\u00ECnh b\u00EAn tr\u00E1i. -->\r\n @if (showClear()) {\r\n <button type=\"button\" class=\"sd-clear-btn sd-hover\" matSuffix (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\r\n <sd-icon name=\"close\"></sd-icon>\r\n </button>\r\n }\r\n\r\n @if (_hideInlineError && _errorMessage) {\r\n <sd-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\" name=\"error\"></sd-icon>\n }\r\n @if (_hideInlineError && _errorMessage) {\r\n <span class=\"sd-visually-hidden\" [id]=\"errorId\" matSuffix>{{ _errorMessage }}</span>\r\r\n }\r\n\r\n @if (sdSuffixDef()?.templateRef; as suffixRef) {\r\n <ng-container matSuffix>\r\n <ng-container *ngTemplateOutlet=\"suffixRef\"></ng-container>\r\n </ng-container>\r\n }\r\n <!-- <ng-container matSuffix>\r\n <ng-content select=\"[sdSuffix]\"></ng-content>\r\n </ng-container> -->\r\n </mat-form-field>\r\n\r\n @if (_maxLength && !_hideInlineError && !formControl.disabled) {\r\n <div\r\n class=\"sd-maxlength-counter\"\r\n [class.sd-maxlength-counter--visible]=\"isFocused\"\r\n [class.sd-maxlength-counter--exceeded]=\"isMaxlengthExceeded()\"\r\n [attr.title]=\"isMaxlengthExceeded() ? ('core.form.input.exceeded' | sdTranslate) : null\">\r\n {{ getCurrentLength() }}/{{ _maxLength }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n}\r\n", styles: [".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}.sd-input-inline{display:inline-flex;align-items:center;gap:4px;max-width:100%}.sd-input-inline__suffix{display:inline-flex;align-items:center;line-height:0}:host(.sd-has-label){padding-top:4px}:host(.sd-viewed){padding-top:0}: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 input.mat-mdc-input-element:disabled{color:var(--sd-disabled-text)!important}:host ::ng-deep .mat-mdc-form-field .mat-mdc-placeholder-required{color:var(--sd-error)}.sd-input-field-wrap{position:relative;flex:1;min-width:0}.sd-maxlength-counter{position:absolute;right:4px;top:calc(100% - 16px);opacity:0;font-size:10px;line-height:1.1;color:#00000061;pointer-events:none;transition:opacity .12s ease;z-index:1}.sd-maxlength-counter--exceeded{color:var(--sd-error);font-weight:600}:host ::ng-deep .sd-input-container.c-focused .sd-maxlength-counter,:host ::ng-deep .sd-input-container:hover .sd-maxlength-counter,:host ::ng-deep .sd-input-container .sd-maxlength-counter.sd-maxlength-counter--visible{opacity:1}.sd-md:hover .btn-copy{visibility:visible}\n"] }]
620
668
  }], ctorParameters: () => [], propDecorators: { control: [{ type: i0.ViewChild, args: ['control', { isSignal: true }] }], inlineRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SdInlineText), { isSignal: true }] }], sdLabelTemplate: [{ type: i0.ContentChild, args: ['sdLabel', { isSignal: true }] }], sdValueTemplate: [{ type: i0.ContentChild, args: ['sdValue', { isSignal: true }] }], sdSuffixDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdSuffixDefDirective), { isSignal: true }] }], sdViewDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdViewDefDirective), { isSignal: true }] }], autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], appearanceInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], floatLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "floatLabel", 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 }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], mask: [{ type: i0.Input, args: [{ isSignal: true, alias: "mask", required: false }] }], hideInlineError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideInlineError", required: false }] }], blurOnEnter: [{ type: i0.Input, args: [{ isSignal: true, alias: "blurOnEnter", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], viewed: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewed", required: false }] }], minlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minlength", required: false }] }], maxlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxlength", required: false }] }], pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: false }] }], patternErrorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "patternErrorMessage", required: false }] }], validator: [{ type: i0.Input, args: [{ isSignal: true, alias: "validator", required: false }] }], inlineError: [{ type: i0.Input, args: [{ isSignal: true, alias: "inlineError", required: false }] }], hyperlink: [{ type: i0.Input, args: [{ isSignal: true, alias: "hyperlink", required: false }] }], valueModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: false }] }, { type: i0.Output, args: ["modelChange"] }], sdChange: [{ type: i0.Output, args: ["sdChange"] }], sdFocus: [{ type: i0.Output, args: ["sdFocus"] }], sdBlur: [{ type: i0.Output, args: ["sdBlur"] }], keyupEnter: [{ type: i0.Output, args: ["keyupEnter"] }], cleared: [{ type: i0.Output, args: ["cleared"] }], sdFocusForceBlur: [{
621
669
  type: Output
622
670
  }] } });