@sd-angular/core 19.0.0-beta.94 → 19.0.0-beta.96

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 (194) hide show
  1. package/README.md +10 -10
  2. package/components/anchor/src/components/anchor/anchor.component.d.ts +4 -1
  3. package/components/anchor/src/components/anchor-item/anchor-item.component.d.ts +2 -1
  4. package/components/anchor/src/components/anchor-vertical/anchor-vertical-list.component.d.ts +3 -1
  5. package/components/badge/src/badge.component.d.ts +3 -4
  6. package/components/button/src/button.component.d.ts +2 -2
  7. package/components/document-builder/src/components/header-footer-builder/header-footer-builder.component.d.ts +2 -2
  8. package/components/document-builder/src/document-builder.model.d.ts +2 -2
  9. package/components/editor/src/models/editor.model.d.ts +2 -2
  10. package/components/editor/src/plugins/image-upload/utils/validate.utils.d.ts +2 -2
  11. package/components/form-generic/src/components/form-builder/components/attribute-table/attribute-table.component.d.ts +4 -2
  12. package/components/form-generic/src/components/form-builder/components/attribute-template/attribute-template.component.d.ts +2 -2
  13. package/components/form-generic/src/components/form-builder/components/configure-validation/configure-validation.component.d.ts +2 -2
  14. package/components/form-generic/src/components/form-builder/components/group/attribute/group-attribute.component.d.ts +23 -0
  15. package/components/form-generic/src/components/form-builder/components/group/index.d.ts +1 -0
  16. package/components/form-generic/src/components/form-builder/components/index.d.ts +1 -0
  17. package/components/form-generic/src/components/form-builder/components/table/control/table-control.component.d.ts +3 -0
  18. package/components/form-generic/src/components/form-builder/form-builder.component.d.ts +61 -18
  19. package/components/form-generic/src/components/form-render/form-render.component.d.ts +2 -2
  20. package/components/form-generic/src/models/form-generic-component.model.d.ts +22 -2
  21. package/components/index.d.ts +1 -2
  22. package/components/modal/src/modal.component.d.ts +5 -3
  23. package/components/preview/index.d.ts +3 -0
  24. package/components/preview/src/preview-image/preview-image.component.d.ts +84 -24
  25. package/components/preview/src/preview-image/preview-image.types.d.ts +53 -0
  26. package/components/preview/src/preview-pdf/preview-pdf.component.d.ts +186 -0
  27. package/components/preview/src/preview-pdf/preview-pdf.types.d.ts +84 -0
  28. package/components/quick-action/src/quick-action.component.d.ts +5 -6
  29. package/components/section/src/section.component.d.ts +1 -2
  30. package/components/table/src/components/column-filter/column-filter.component.d.ts +3 -3
  31. package/components/table/src/table.component.d.ts +2 -2
  32. package/components/upload-file/src/upload-file.component.d.ts +4 -1
  33. package/configurations/src/sd-core.configuration.d.ts +2 -1
  34. package/fesm2022/sd-angular-core-components-anchor.mjs +19 -6
  35. package/fesm2022/sd-angular-core-components-anchor.mjs.map +1 -1
  36. package/fesm2022/sd-angular-core-components-button.mjs +1 -1
  37. package/fesm2022/sd-angular-core-components-button.mjs.map +1 -1
  38. package/fesm2022/sd-angular-core-components-code-editor.mjs +3 -3
  39. package/fesm2022/sd-angular-core-components-code-editor.mjs.map +1 -1
  40. package/fesm2022/sd-angular-core-components-document-builder.mjs +3 -3
  41. package/fesm2022/sd-angular-core-components-document-builder.mjs.map +1 -1
  42. package/fesm2022/sd-angular-core-components-editor.mjs +3 -3
  43. package/fesm2022/sd-angular-core-components-editor.mjs.map +1 -1
  44. package/fesm2022/sd-angular-core-components-form-generic.mjs +627 -317
  45. package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
  46. package/fesm2022/sd-angular-core-components-history.mjs +3 -3
  47. package/fesm2022/sd-angular-core-components-history.mjs.map +1 -1
  48. package/fesm2022/sd-angular-core-components-import-excel.mjs +5 -5
  49. package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
  50. package/fesm2022/sd-angular-core-components-modal.mjs +8 -3
  51. package/fesm2022/sd-angular-core-components-modal.mjs.map +1 -1
  52. package/fesm2022/sd-angular-core-components-preview.mjs +1963 -91
  53. package/fesm2022/sd-angular-core-components-preview.mjs.map +1 -1
  54. package/fesm2022/sd-angular-core-components-quick-action.mjs +8 -19
  55. package/fesm2022/sd-angular-core-components-quick-action.mjs.map +1 -1
  56. package/fesm2022/sd-angular-core-components-tab-router.mjs +31 -26
  57. package/fesm2022/sd-angular-core-components-tab-router.mjs.map +1 -1
  58. package/fesm2022/sd-angular-core-components-table.mjs +32 -29
  59. package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
  60. package/fesm2022/sd-angular-core-components-upload-file.mjs +12 -8
  61. package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
  62. package/fesm2022/sd-angular-core-components.mjs +1 -2
  63. package/fesm2022/sd-angular-core-components.mjs.map +1 -1
  64. package/fesm2022/sd-angular-core-configurations.mjs.map +1 -1
  65. package/fesm2022/sd-angular-core-directives.mjs +2 -2
  66. package/fesm2022/sd-angular-core-directives.mjs.map +1 -1
  67. package/fesm2022/sd-angular-core-forms-autocomplete.mjs +2 -2
  68. package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
  69. package/fesm2022/sd-angular-core-forms-checkbox.mjs +6 -13
  70. package/fesm2022/sd-angular-core-forms-checkbox.mjs.map +1 -1
  71. package/fesm2022/sd-angular-core-forms-chip-calendar.mjs +6 -5
  72. package/fesm2022/sd-angular-core-forms-chip-calendar.mjs.map +1 -1
  73. package/fesm2022/sd-angular-core-forms-chip.mjs +6 -12
  74. package/fesm2022/sd-angular-core-forms-chip.mjs.map +1 -1
  75. package/fesm2022/sd-angular-core-forms-date-range.mjs +33 -26
  76. package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
  77. package/fesm2022/sd-angular-core-forms-date.mjs +29 -19
  78. package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
  79. package/fesm2022/sd-angular-core-forms-datetime.mjs +98 -57
  80. package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
  81. package/fesm2022/sd-angular-core-forms-input-number.mjs +2 -2
  82. package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
  83. package/fesm2022/sd-angular-core-forms-input.mjs +25 -10
  84. package/fesm2022/sd-angular-core-forms-input.mjs.map +1 -1
  85. package/fesm2022/sd-angular-core-forms-radio.mjs +7 -15
  86. package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
  87. package/fesm2022/sd-angular-core-forms-select.mjs +4 -4
  88. package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
  89. package/fesm2022/sd-angular-core-forms-switch.mjs +6 -14
  90. package/fesm2022/sd-angular-core-forms-switch.mjs.map +1 -1
  91. package/fesm2022/sd-angular-core-forms-textarea.mjs +5 -5
  92. package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
  93. package/fesm2022/sd-angular-core-handlers.mjs +2 -2
  94. package/fesm2022/sd-angular-core-handlers.mjs.map +1 -1
  95. package/fesm2022/sd-angular-core-i18n.mjs +1610 -38
  96. package/fesm2022/sd-angular-core-i18n.mjs.map +1 -1
  97. package/fesm2022/sd-angular-core-interceptors.mjs +2 -2
  98. package/fesm2022/sd-angular-core-interceptors.mjs.map +1 -1
  99. package/fesm2022/sd-angular-core-models.mjs +6 -0
  100. package/fesm2022/sd-angular-core-models.mjs.map +1 -0
  101. package/fesm2022/sd-angular-core-modules-layout.mjs +87 -39
  102. package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
  103. package/fesm2022/sd-angular-core-services-confirm.mjs +2 -2
  104. package/fesm2022/sd-angular-core-services-confirm.mjs.map +1 -1
  105. package/fesm2022/sd-angular-core-services-docx.mjs +2 -2
  106. package/fesm2022/sd-angular-core-services-docx.mjs.map +1 -1
  107. package/fesm2022/sd-angular-core-services-excel.mjs +27 -23
  108. package/fesm2022/sd-angular-core-services-excel.mjs.map +1 -1
  109. package/fesm2022/sd-angular-core-services-notify.mjs +21 -21
  110. package/fesm2022/sd-angular-core-services-notify.mjs.map +1 -1
  111. package/fesm2022/sd-angular-core-utilities-extensions.mjs +74 -830
  112. package/fesm2022/sd-angular-core-utilities-extensions.mjs.map +1 -1
  113. package/fesm2022/sd-angular-core-utilities-models.mjs +36 -136
  114. package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
  115. package/fesm2022/sd-angular-core.mjs +0 -1
  116. package/fesm2022/sd-angular-core.mjs.map +1 -1
  117. package/forms/autocomplete/src/autocomplete.component.d.ts +1 -2
  118. package/forms/checkbox/src/checkbox.component.d.ts +3 -3
  119. package/forms/chip/src/chip.component.d.ts +4 -4
  120. package/forms/chip-calendar/src/chip-calendar.component.d.ts +4 -4
  121. package/forms/date/src/date.component.d.ts +3 -5
  122. package/forms/date-range/src/date-range.component.d.ts +3 -5
  123. package/forms/datetime/src/datetime.component.d.ts +2 -2
  124. package/forms/datetime/src/popup/sd-datetime-picker.component.d.ts +10 -11
  125. package/forms/input/src/input.component.d.ts +1 -2
  126. package/forms/input-number/src/input-number.component.d.ts +1 -2
  127. package/forms/radio/src/radio.component.d.ts +3 -3
  128. package/forms/select/src/select.component.d.ts +5 -5
  129. package/forms/switch/src/switch.component.d.ts +3 -3
  130. package/forms/textarea/src/textarea.component.d.ts +1 -2
  131. package/i18n/index.d.ts +5 -5
  132. package/i18n/src/en.d.ts +406 -2
  133. package/i18n/src/i18n.messages.d.ts +2 -0
  134. package/i18n/src/i18n.pipe.d.ts +9 -0
  135. package/i18n/src/i18n.service.d.ts +14 -0
  136. package/i18n/src/i18n.token.d.ts +1 -0
  137. package/i18n/src/i18n.types.d.ts +31 -0
  138. package/i18n/src/ja.d.ts +2 -0
  139. package/i18n/src/ko.d.ts +2 -0
  140. package/i18n/src/vi.d.ts +2 -312
  141. package/i18n/src/zh.d.ts +2 -0
  142. package/models/index.d.ts +1 -0
  143. package/models/src/language.model.d.ts +2 -0
  144. package/modules/layout/modules/home/components/home-page/home-page.component.d.ts +25 -0
  145. package/package.json +82 -89
  146. package/public-api.d.ts +0 -1
  147. package/sd-angular-core-19.0.0-beta.96.tgz +0 -0
  148. package/services/notify/index.d.ts +1 -1
  149. package/services/notify/src/components/toast/toast.component.d.ts +3 -3
  150. package/services/notify/src/components/toast-container.component.d.ts +3 -4
  151. package/services/notify/src/notify.model.d.ts +1 -1
  152. package/services/notify/src/notify.service.d.ts +5 -5
  153. package/utilities/extensions/src/array.extension.d.ts +1 -7
  154. package/utilities/extensions/src/color.extension.d.ts +5 -20
  155. package/utilities/extensions/src/date.extension.d.ts +1 -18
  156. package/utilities/extensions/src/number.extension.d.ts +1 -10
  157. package/utilities/extensions/src/string.extension.d.ts +30 -4
  158. package/utilities/extensions/src/utility.extension.d.ts +6 -0
  159. package/utilities/models/src/color.model.d.ts +4 -1
  160. package/utilities/models/src/empty.model.d.ts +3 -0
  161. package/utilities/models/src/filter.model.d.ts +12 -24
  162. package/utilities/models/src/maybe-async.model.d.ts +10 -4
  163. package/utilities/models/src/nested-key-of.model.d.ts +4 -5
  164. package/utilities/models/src/operator.model.d.ts +9 -4
  165. package/utilities/models/src/order.model.d.ts +4 -5
  166. package/utilities/models/src/paging.model.d.ts +8 -16
  167. package/utilities/models/src/pattern.model.d.ts +13 -0
  168. package/utilities/models/src/size.model.d.ts +4 -1
  169. package/components/anchor-v2/index.d.ts +0 -1
  170. package/components/anchor-v2/src/components/anchor-item-v2/anchor-item-v2.component.d.ts +0 -12
  171. package/components/anchor-v2/src/components/anchor-v2/anchor-v2.component.d.ts +0 -19
  172. package/components/anchor-v2/src/components/anchor-vertical-v2/anchor-vertical-list-v2.component.d.ts +0 -16
  173. package/components/anchor-v2/src/components/index.d.ts +0 -2
  174. package/components/anchor-v2/src/index.d.ts +0 -2
  175. package/components/anchor-v2/src/models/index.d.ts +0 -1
  176. package/components/anchor-v2/src/models/sd-anchor-v2.model.d.ts +0 -7
  177. package/components/workflow/index.d.ts +0 -2
  178. package/components/workflow/src/configurations/index.d.ts +0 -1
  179. package/components/workflow/src/configurations/workflow.configuration.d.ts +0 -10
  180. package/fesm2022/sd-angular-core-components-anchor-v2.mjs +0 -151
  181. package/fesm2022/sd-angular-core-components-anchor-v2.mjs.map +0 -1
  182. package/fesm2022/sd-angular-core-components-workflow.mjs +0 -17
  183. package/fesm2022/sd-angular-core-components-workflow.mjs.map +0 -1
  184. package/fesm2022/sd-angular-core-services-firebase.mjs +0 -38
  185. package/fesm2022/sd-angular-core-services-firebase.mjs.map +0 -1
  186. package/i18n/src/sd-i18n.messages.d.ts +0 -2
  187. package/i18n/src/sd-i18n.pipe.d.ts +0 -9
  188. package/i18n/src/sd-i18n.service.d.ts +0 -12
  189. package/i18n/src/sd-i18n.token.d.ts +0 -1
  190. package/i18n/src/sd-i18n.types.d.ts +0 -5
  191. package/sd-angular-core-19.0.0-beta.94.tgz +0 -0
  192. package/services/firebase/index.d.ts +0 -2
  193. package/services/firebase/src/firebase.model.d.ts +0 -8
  194. package/services/firebase/src/firebase.service.d.ts +0 -14
@@ -6,7 +6,8 @@ import * as i0 from '@angular/core';
6
6
  import { model, input, booleanAttribute, ChangeDetectionStrategy, Component, EventEmitter, signal, Output, viewChild, contentChild, inject, ChangeDetectorRef, ElementRef, Injector, computed, output, effect, untracked } from '@angular/core';
7
7
  import * as i2 from '@angular/forms';
8
8
  import { NgForm, FormGroup, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
9
- import { provideMomentDateAdapter } from '@angular/material-moment-adapter';
9
+ import { provideDateFnsAdapter } from '@angular/material-date-fns-adapter';
10
+ import { MAT_DATE_LOCALE } from '@angular/material/core';
10
11
  import { MatFormFieldModule } from '@angular/material/form-field';
11
12
  import * as i4 from '@angular/material/icon';
12
13
  import { MatIconModule } from '@angular/material/icon';
@@ -18,9 +19,10 @@ import { SdView } from '@sd-angular/core/components/view';
18
19
  import { SdViewDefDirective } from '@sd-angular/core/forms/directives';
19
20
  import { SdLabel } from '@sd-angular/core/forms/label';
20
21
  import { SD_FORM_CONFIGURATION, SdFormControl } from '@sd-angular/core/forms/models';
21
- import { SdTPipe, SdI18nService } from '@sd-angular/core/i18n';
22
- import { SdUtilities, DateUtilities } from '@sd-angular/core/utilities/extensions';
23
- import moment from 'moment';
22
+ import { TranslatePipe, I18nService } from '@sd-angular/core/i18n';
23
+ import { DateUtilities, SdUtilities } from '@sd-angular/core/utilities/extensions';
24
+ import { isValid, parse } from 'date-fns';
25
+ import { enUS } from 'date-fns/locale';
24
26
  import { Subscription } from 'rxjs';
25
27
  import * as uuid from 'uuid';
26
28
  import { MatButtonModule } from '@angular/material/button';
@@ -191,11 +193,11 @@ class SdTimeSpinner {
191
193
  event.target.select();
192
194
  }
193
195
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdTimeSpinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
194
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdTimeSpinner, isStandalone: true, selector: "sd-time-spinner", inputs: { hours: { classPropertyName: "hours", publicName: "hours", isSignal: true, isRequired: false, transformFunction: null }, minutes: { classPropertyName: "minutes", publicName: "minutes", isSignal: true, isRequired: false, transformFunction: null }, seconds: { classPropertyName: "seconds", publicName: "seconds", isSignal: true, isRequired: false, transformFunction: null }, showSeconds: { classPropertyName: "showSeconds", publicName: "showSeconds", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { hours: "hoursChange", minutes: "minutesChange", seconds: "secondsChange" }, ngImport: i0, template: "<div class=\"sd-time-spinner\" [class.disabled]=\"disabled()\">\r\n <!-- HOURS -->\r\n <div class=\"unit\">\r\n <button type=\"button\" class=\"step\" (click)=\"step('h', 1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.increase-hour' | sdT\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"18 15 12 9 6 15\"></polyline>\r\n </svg>\r\n </button>\r\n <input\r\n class=\"value\"\r\n type=\"text\"\r\n inputmode=\"numeric\"\r\n maxlength=\"2\"\r\n [value]=\"pad(hours())\"\r\n [disabled]=\"disabled()\"\r\n (input)=\"onInput('h', $event)\"\r\n (wheel)=\"onWheel('h', $event)\"\r\n (keydown)=\"onKeyDown('h', $event)\"\r\n (focus)=\"onFocus('h', $event)\"\r\n (blur)=\"onBlur('h', $event)\"\r\n [attr.aria-label]=\"'core.form.time-spinner.hour' | sdT\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('h', -1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.decrease-hour' | sdT\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <span class=\"sep\">:</span>\r\n\r\n <!-- MINUTES -->\r\n <div class=\"unit\">\r\n <button type=\"button\" class=\"step\" (click)=\"step('m', 1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.increase-minute' | sdT\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"18 15 12 9 6 15\"></polyline>\r\n </svg>\r\n </button>\r\n <input\r\n class=\"value\"\r\n type=\"text\"\r\n inputmode=\"numeric\"\r\n maxlength=\"2\"\r\n [value]=\"pad(minutes())\"\r\n [disabled]=\"disabled()\"\r\n (input)=\"onInput('m', $event)\"\r\n (wheel)=\"onWheel('m', $event)\"\r\n (keydown)=\"onKeyDown('m', $event)\"\r\n (focus)=\"onFocus('m', $event)\"\r\n (blur)=\"onBlur('m', $event)\"\r\n [attr.aria-label]=\"'core.form.time-spinner.minute' | sdT\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('m', -1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.decrease-minute' | sdT\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n @if (showSeconds()) {\r\n <span class=\"sep\">:</span>\r\n <!-- SECONDS -->\r\n <div class=\"unit\">\r\n <button type=\"button\" class=\"step\" (click)=\"step('s', 1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.increase-second' | sdT\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"18 15 12 9 6 15\"></polyline>\r\n </svg>\r\n </button>\r\n <input\r\n class=\"value\"\r\n type=\"text\"\r\n inputmode=\"numeric\"\r\n maxlength=\"2\"\r\n [value]=\"pad(seconds())\"\r\n [disabled]=\"disabled()\"\r\n (input)=\"onInput('s', $event)\"\r\n (wheel)=\"onWheel('s', $event)\"\r\n (keydown)=\"onKeyDown('s', $event)\"\r\n (focus)=\"onFocus('s', $event)\"\r\n (blur)=\"onBlur('s', $event)\"\r\n [attr.aria-label]=\"'core.form.time-spinner.second' | sdT\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('s', -1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.decrease-second' | sdT\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block}.sd-time-spinner{display:flex;align-items:center;justify-content:center;gap:4px;padding:6px 12px}.sd-time-spinner.disabled{opacity:.5;pointer-events:none}.sd-time-spinner .unit{display:flex;flex-direction:column;align-items:center;gap:2px}.sd-time-spinner .unit .step{width:32px;height:20px;padding:0;border:0;background:transparent;color:var(--sd-black300);border-radius:6px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background-color .15s ease,color .15s ease,transform .1s ease}.sd-time-spinner .unit .step svg{width:14px;height:14px;display:block}.sd-time-spinner .unit .step:hover{background:var(--sd-primary-light);color:var(--sd-primary)}.sd-time-spinner .unit .step:active{transform:scale(.92)}.sd-time-spinner .unit .value{width:44px;height:36px;padding:0;text-align:center;font-size:20px;font-weight:600;line-height:1;color:var(--sd-black500);font-variant-numeric:tabular-nums;background:transparent;border:1.5px solid transparent;border-radius:6px;outline:none;cursor:text;transition:border-color .15s ease,background-color .15s ease}.sd-time-spinner .unit .value:hover:not(:focus){background:var(--sd-black100)}.sd-time-spinner .unit .value:focus{border-color:var(--sd-primary);background:#fff}.sd-time-spinner .unit .value:disabled{color:var(--sd-black400);cursor:not-allowed}.sd-time-spinner .unit:hover .step{color:var(--sd-black400)}.sd-time-spinner .sep{font-size:20px;font-weight:600;color:var(--sd-black400);padding-bottom:2px;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: SdTPipe, name: "sdT" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
196
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdTimeSpinner, isStandalone: true, selector: "sd-time-spinner", inputs: { hours: { classPropertyName: "hours", publicName: "hours", isSignal: true, isRequired: false, transformFunction: null }, minutes: { classPropertyName: "minutes", publicName: "minutes", isSignal: true, isRequired: false, transformFunction: null }, seconds: { classPropertyName: "seconds", publicName: "seconds", isSignal: true, isRequired: false, transformFunction: null }, showSeconds: { classPropertyName: "showSeconds", publicName: "showSeconds", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { hours: "hoursChange", minutes: "minutesChange", seconds: "secondsChange" }, ngImport: i0, template: "<div class=\"sd-time-spinner\" [class.disabled]=\"disabled()\">\r\n <!-- HOURS -->\r\n <div class=\"unit\">\r\n <button type=\"button\" class=\"step\" (click)=\"step('h', 1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.increase-hour' | translate\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"18 15 12 9 6 15\"></polyline>\r\n </svg>\r\n </button>\r\n <input\r\n class=\"value\"\r\n type=\"text\"\r\n inputmode=\"numeric\"\r\n maxlength=\"2\"\r\n [value]=\"pad(hours())\"\r\n [disabled]=\"disabled()\"\r\n (input)=\"onInput('h', $event)\"\r\n (wheel)=\"onWheel('h', $event)\"\r\n (keydown)=\"onKeyDown('h', $event)\"\r\n (focus)=\"onFocus('h', $event)\"\r\n (blur)=\"onBlur('h', $event)\"\r\n [attr.aria-label]=\"'core.form.time-spinner.hour' | translate\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('h', -1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.decrease-hour' | translate\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <span class=\"sep\">:</span>\r\n\r\n <!-- MINUTES -->\r\n <div class=\"unit\">\r\n <button type=\"button\" class=\"step\" (click)=\"step('m', 1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.increase-minute' | translate\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"18 15 12 9 6 15\"></polyline>\r\n </svg>\r\n </button>\r\n <input\r\n class=\"value\"\r\n type=\"text\"\r\n inputmode=\"numeric\"\r\n maxlength=\"2\"\r\n [value]=\"pad(minutes())\"\r\n [disabled]=\"disabled()\"\r\n (input)=\"onInput('m', $event)\"\r\n (wheel)=\"onWheel('m', $event)\"\r\n (keydown)=\"onKeyDown('m', $event)\"\r\n (focus)=\"onFocus('m', $event)\"\r\n (blur)=\"onBlur('m', $event)\"\r\n [attr.aria-label]=\"'core.form.time-spinner.minute' | translate\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('m', -1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.decrease-minute' | translate\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n @if (showSeconds()) {\r\n <span class=\"sep\">:</span>\r\n <!-- SECONDS -->\r\n <div class=\"unit\">\r\n <button type=\"button\" class=\"step\" (click)=\"step('s', 1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.increase-second' | translate\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"18 15 12 9 6 15\"></polyline>\r\n </svg>\r\n </button>\r\n <input\r\n class=\"value\"\r\n type=\"text\"\r\n inputmode=\"numeric\"\r\n maxlength=\"2\"\r\n [value]=\"pad(seconds())\"\r\n [disabled]=\"disabled()\"\r\n (input)=\"onInput('s', $event)\"\r\n (wheel)=\"onWheel('s', $event)\"\r\n (keydown)=\"onKeyDown('s', $event)\"\r\n (focus)=\"onFocus('s', $event)\"\r\n (blur)=\"onBlur('s', $event)\"\r\n [attr.aria-label]=\"'core.form.time-spinner.second' | translate\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('s', -1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.decrease-second' | translate\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block}.sd-time-spinner{display:flex;align-items:center;justify-content:center;gap:4px;padding:6px 12px}.sd-time-spinner.disabled{opacity:.5;pointer-events:none}.sd-time-spinner .unit{display:flex;flex-direction:column;align-items:center;gap:2px}.sd-time-spinner .unit .step{width:32px;height:20px;padding:0;border:0;background:transparent;color:var(--sd-black300);border-radius:6px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background-color .15s ease,color .15s ease,transform .1s ease}.sd-time-spinner .unit .step svg{width:14px;height:14px;display:block}.sd-time-spinner .unit .step:hover{background:var(--sd-primary-light);color:var(--sd-primary)}.sd-time-spinner .unit .step:active{transform:scale(.92)}.sd-time-spinner .unit .value{width:44px;height:36px;padding:0;text-align:center;font-size:20px;font-weight:600;line-height:1;color:var(--sd-black500);font-variant-numeric:tabular-nums;background:transparent;border:1.5px solid transparent;border-radius:6px;outline:none;cursor:text;transition:border-color .15s ease,background-color .15s ease}.sd-time-spinner .unit .value:hover:not(:focus){background:var(--sd-black100)}.sd-time-spinner .unit .value:focus{border-color:var(--sd-primary);background:#fff}.sd-time-spinner .unit .value:disabled{color:var(--sd-black400);cursor:not-allowed}.sd-time-spinner .unit:hover .step{color:var(--sd-black400)}.sd-time-spinner .sep{font-size:20px;font-weight:600;color:var(--sd-black400);padding-bottom:2px;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
195
197
  }
196
198
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdTimeSpinner, decorators: [{
197
199
  type: Component,
198
- args: [{ selector: 'sd-time-spinner', standalone: true, imports: [CommonModule, SdTPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sd-time-spinner\" [class.disabled]=\"disabled()\">\r\n <!-- HOURS -->\r\n <div class=\"unit\">\r\n <button type=\"button\" class=\"step\" (click)=\"step('h', 1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.increase-hour' | sdT\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"18 15 12 9 6 15\"></polyline>\r\n </svg>\r\n </button>\r\n <input\r\n class=\"value\"\r\n type=\"text\"\r\n inputmode=\"numeric\"\r\n maxlength=\"2\"\r\n [value]=\"pad(hours())\"\r\n [disabled]=\"disabled()\"\r\n (input)=\"onInput('h', $event)\"\r\n (wheel)=\"onWheel('h', $event)\"\r\n (keydown)=\"onKeyDown('h', $event)\"\r\n (focus)=\"onFocus('h', $event)\"\r\n (blur)=\"onBlur('h', $event)\"\r\n [attr.aria-label]=\"'core.form.time-spinner.hour' | sdT\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('h', -1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.decrease-hour' | sdT\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <span class=\"sep\">:</span>\r\n\r\n <!-- MINUTES -->\r\n <div class=\"unit\">\r\n <button type=\"button\" class=\"step\" (click)=\"step('m', 1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.increase-minute' | sdT\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"18 15 12 9 6 15\"></polyline>\r\n </svg>\r\n </button>\r\n <input\r\n class=\"value\"\r\n type=\"text\"\r\n inputmode=\"numeric\"\r\n maxlength=\"2\"\r\n [value]=\"pad(minutes())\"\r\n [disabled]=\"disabled()\"\r\n (input)=\"onInput('m', $event)\"\r\n (wheel)=\"onWheel('m', $event)\"\r\n (keydown)=\"onKeyDown('m', $event)\"\r\n (focus)=\"onFocus('m', $event)\"\r\n (blur)=\"onBlur('m', $event)\"\r\n [attr.aria-label]=\"'core.form.time-spinner.minute' | sdT\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('m', -1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.decrease-minute' | sdT\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n @if (showSeconds()) {\r\n <span class=\"sep\">:</span>\r\n <!-- SECONDS -->\r\n <div class=\"unit\">\r\n <button type=\"button\" class=\"step\" (click)=\"step('s', 1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.increase-second' | sdT\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"18 15 12 9 6 15\"></polyline>\r\n </svg>\r\n </button>\r\n <input\r\n class=\"value\"\r\n type=\"text\"\r\n inputmode=\"numeric\"\r\n maxlength=\"2\"\r\n [value]=\"pad(seconds())\"\r\n [disabled]=\"disabled()\"\r\n (input)=\"onInput('s', $event)\"\r\n (wheel)=\"onWheel('s', $event)\"\r\n (keydown)=\"onKeyDown('s', $event)\"\r\n (focus)=\"onFocus('s', $event)\"\r\n (blur)=\"onBlur('s', $event)\"\r\n [attr.aria-label]=\"'core.form.time-spinner.second' | sdT\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('s', -1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.decrease-second' | sdT\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block}.sd-time-spinner{display:flex;align-items:center;justify-content:center;gap:4px;padding:6px 12px}.sd-time-spinner.disabled{opacity:.5;pointer-events:none}.sd-time-spinner .unit{display:flex;flex-direction:column;align-items:center;gap:2px}.sd-time-spinner .unit .step{width:32px;height:20px;padding:0;border:0;background:transparent;color:var(--sd-black300);border-radius:6px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background-color .15s ease,color .15s ease,transform .1s ease}.sd-time-spinner .unit .step svg{width:14px;height:14px;display:block}.sd-time-spinner .unit .step:hover{background:var(--sd-primary-light);color:var(--sd-primary)}.sd-time-spinner .unit .step:active{transform:scale(.92)}.sd-time-spinner .unit .value{width:44px;height:36px;padding:0;text-align:center;font-size:20px;font-weight:600;line-height:1;color:var(--sd-black500);font-variant-numeric:tabular-nums;background:transparent;border:1.5px solid transparent;border-radius:6px;outline:none;cursor:text;transition:border-color .15s ease,background-color .15s ease}.sd-time-spinner .unit .value:hover:not(:focus){background:var(--sd-black100)}.sd-time-spinner .unit .value:focus{border-color:var(--sd-primary);background:#fff}.sd-time-spinner .unit .value:disabled{color:var(--sd-black400);cursor:not-allowed}.sd-time-spinner .unit:hover .step{color:var(--sd-black400)}.sd-time-spinner .sep{font-size:20px;font-weight:600;color:var(--sd-black400);padding-bottom:2px;-webkit-user-select:none;user-select:none}\n"] }]
200
+ args: [{ selector: 'sd-time-spinner', standalone: true, imports: [CommonModule, TranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sd-time-spinner\" [class.disabled]=\"disabled()\">\r\n <!-- HOURS -->\r\n <div class=\"unit\">\r\n <button type=\"button\" class=\"step\" (click)=\"step('h', 1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.increase-hour' | translate\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"18 15 12 9 6 15\"></polyline>\r\n </svg>\r\n </button>\r\n <input\r\n class=\"value\"\r\n type=\"text\"\r\n inputmode=\"numeric\"\r\n maxlength=\"2\"\r\n [value]=\"pad(hours())\"\r\n [disabled]=\"disabled()\"\r\n (input)=\"onInput('h', $event)\"\r\n (wheel)=\"onWheel('h', $event)\"\r\n (keydown)=\"onKeyDown('h', $event)\"\r\n (focus)=\"onFocus('h', $event)\"\r\n (blur)=\"onBlur('h', $event)\"\r\n [attr.aria-label]=\"'core.form.time-spinner.hour' | translate\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('h', -1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.decrease-hour' | translate\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <span class=\"sep\">:</span>\r\n\r\n <!-- MINUTES -->\r\n <div class=\"unit\">\r\n <button type=\"button\" class=\"step\" (click)=\"step('m', 1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.increase-minute' | translate\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"18 15 12 9 6 15\"></polyline>\r\n </svg>\r\n </button>\r\n <input\r\n class=\"value\"\r\n type=\"text\"\r\n inputmode=\"numeric\"\r\n maxlength=\"2\"\r\n [value]=\"pad(minutes())\"\r\n [disabled]=\"disabled()\"\r\n (input)=\"onInput('m', $event)\"\r\n (wheel)=\"onWheel('m', $event)\"\r\n (keydown)=\"onKeyDown('m', $event)\"\r\n (focus)=\"onFocus('m', $event)\"\r\n (blur)=\"onBlur('m', $event)\"\r\n [attr.aria-label]=\"'core.form.time-spinner.minute' | translate\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('m', -1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.decrease-minute' | translate\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n @if (showSeconds()) {\r\n <span class=\"sep\">:</span>\r\n <!-- SECONDS -->\r\n <div class=\"unit\">\r\n <button type=\"button\" class=\"step\" (click)=\"step('s', 1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.increase-second' | translate\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"18 15 12 9 6 15\"></polyline>\r\n </svg>\r\n </button>\r\n <input\r\n class=\"value\"\r\n type=\"text\"\r\n inputmode=\"numeric\"\r\n maxlength=\"2\"\r\n [value]=\"pad(seconds())\"\r\n [disabled]=\"disabled()\"\r\n (input)=\"onInput('s', $event)\"\r\n (wheel)=\"onWheel('s', $event)\"\r\n (keydown)=\"onKeyDown('s', $event)\"\r\n (focus)=\"onFocus('s', $event)\"\r\n (blur)=\"onBlur('s', $event)\"\r\n [attr.aria-label]=\"'core.form.time-spinner.second' | translate\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('s', -1)\" tabindex=\"-1\" [attr.aria-label]=\"'core.form.time-spinner.decrease-second' | translate\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block}.sd-time-spinner{display:flex;align-items:center;justify-content:center;gap:4px;padding:6px 12px}.sd-time-spinner.disabled{opacity:.5;pointer-events:none}.sd-time-spinner .unit{display:flex;flex-direction:column;align-items:center;gap:2px}.sd-time-spinner .unit .step{width:32px;height:20px;padding:0;border:0;background:transparent;color:var(--sd-black300);border-radius:6px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background-color .15s ease,color .15s ease,transform .1s ease}.sd-time-spinner .unit .step svg{width:14px;height:14px;display:block}.sd-time-spinner .unit .step:hover{background:var(--sd-primary-light);color:var(--sd-primary)}.sd-time-spinner .unit .step:active{transform:scale(.92)}.sd-time-spinner .unit .value{width:44px;height:36px;padding:0;text-align:center;font-size:20px;font-weight:600;line-height:1;color:var(--sd-black500);font-variant-numeric:tabular-nums;background:transparent;border:1.5px solid transparent;border-radius:6px;outline:none;cursor:text;transition:border-color .15s ease,background-color .15s ease}.sd-time-spinner .unit .value:hover:not(:focus){background:var(--sd-black100)}.sd-time-spinner .unit .value:focus{border-color:var(--sd-primary);background:#fff}.sd-time-spinner .unit .value:disabled{color:var(--sd-black400);cursor:not-allowed}.sd-time-spinner .unit:hover .step{color:var(--sd-black400)}.sd-time-spinner .sep{font-size:20px;font-weight:600;color:var(--sd-black400);padding-bottom:2px;-webkit-user-select:none;user-select:none}\n"] }]
199
201
  }] });
200
202
 
201
203
  /**
@@ -208,9 +210,9 @@ class SdDatetimePicker {
208
210
  // ==========================================
209
211
  // INPUTS
210
212
  // ==========================================
211
- /** Giá trị khởi tạo của picker (Moment, có thể null). */
213
+ /** Giá trị khởi tạo của picker (native Date, có thể null). */
212
214
  initialValue = input(null);
213
- /** Min/max boundary (Moment hoặc Date). */
215
+ /** Min/max boundary (Date hoặc bất kỳ giá trị nào hợp lệ cho `new Date(...)`). */
214
216
  minDate = input(null);
215
217
  maxDate = input(null);
216
218
  /** Hiển thị thêm cột giây (mặc định ẩn — chỉ HH:MM). */
@@ -225,7 +227,8 @@ class SdDatetimePicker {
225
227
  // ==========================================
226
228
  // STATE — signals nội bộ
227
229
  // ==========================================
228
- selectedDate = signal(moment());
230
+ // date-fns là immutable — luôn cấp Date mới, không mutate.
231
+ selectedDate = signal(new Date());
229
232
  hours = signal(0);
230
233
  minutes = signal(0);
231
234
  seconds = signal(0);
@@ -236,11 +239,12 @@ class SdDatetimePicker {
236
239
  }
237
240
  #hydrateFromInput() {
238
241
  const init = this.initialValue();
239
- const m = init && moment.isMoment(init) ? init.clone() : moment();
240
- this.selectedDate.set(m);
241
- this.hours.set(m.hour());
242
- this.minutes.set(m.minute());
243
- this.seconds.set(m.second());
242
+ // Clone bằng new Date(getTime()) để không chia sẻ reference với caller.
243
+ const d = init instanceof Date && isValid(init) ? new Date(init.getTime()) : new Date();
244
+ this.selectedDate.set(d);
245
+ this.hours.set(d.getHours());
246
+ this.minutes.set(d.getMinutes());
247
+ this.seconds.set(d.getSeconds());
244
248
  }
245
249
  // ==========================================
246
250
  // EVENT HANDLERS
@@ -250,20 +254,17 @@ class SdDatetimePicker {
250
254
  if (!date)
251
255
  return;
252
256
  // Giữ nguyên giờ/phút/giây hiện tại, chỉ thay đổi ngày.
253
- const next = date.clone()
254
- .hour(this.hours())
255
- .minute(this.minutes())
256
- .second(this.seconds());
257
+ const next = new Date(date.getTime());
258
+ next.setHours(this.hours(), this.minutes(), this.seconds(), 0);
257
259
  this.selectedDate.set(next);
258
260
  }
259
261
  onConfirm() {
260
262
  if (this.disabled())
261
263
  return;
262
- const result = this.selectedDate().clone()
263
- .hour(this.hours())
264
- .minute(this.minutes())
265
- .second(this.showSeconds() ? this.seconds() : 0)
266
- .millisecond(0);
264
+ // Tạo Date mới từ selectedDate + hours/minutes/seconds hiện tại.
265
+ const base = this.selectedDate();
266
+ const result = new Date(base.getTime());
267
+ result.setHours(this.hours(), this.minutes(), this.showSeconds() ? this.seconds() : 0, 0);
267
268
  this.confirmed.emit(result);
268
269
  }
269
270
  onCancel() {
@@ -273,31 +274,37 @@ class SdDatetimePicker {
273
274
  onNow() {
274
275
  if (this.disabled())
275
276
  return;
276
- const now = moment();
277
+ const now = new Date();
277
278
  this.selectedDate.set(now);
278
- this.hours.set(now.hour());
279
- this.minutes.set(now.minute());
280
- this.seconds.set(now.second());
279
+ this.hours.set(now.getHours());
280
+ this.minutes.set(now.getMinutes());
281
+ this.seconds.set(now.getSeconds());
281
282
  }
282
- // Min/Max — chuyển về Moment cho MatCalendar
283
- get _minMoment() {
283
+ // Min/Max — chuyển về Date cho MatCalendar (date-fns adapter dùng native Date).
284
+ get _minDate() {
284
285
  const v = this.minDate();
285
- if (!v)
286
+ if (v === null || v === undefined)
286
287
  return null;
287
- return moment.isMoment(v) ? v : moment(v);
288
+ if (v instanceof Date)
289
+ return isValid(v) ? v : null;
290
+ const d = new Date(v);
291
+ return isValid(d) ? d : null;
288
292
  }
289
- get _maxMoment() {
293
+ get _maxDate() {
290
294
  const v = this.maxDate();
291
- if (!v)
295
+ if (v === null || v === undefined)
292
296
  return null;
293
- return moment.isMoment(v) ? v : moment(v);
297
+ if (v instanceof Date)
298
+ return isValid(v) ? v : null;
299
+ const d = new Date(v);
300
+ return isValid(d) ? d : null;
294
301
  }
295
302
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdDatetimePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
296
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: SdDatetimePicker, isStandalone: true, selector: "sd-datetime-picker", inputs: { initialValue: { classPropertyName: "initialValue", publicName: "initialValue", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, showSeconds: { classPropertyName: "showSeconds", publicName: "showSeconds", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled" }, ngImport: i0, template: "<div class=\"sd-datetime-picker\">\r\n <!-- Calendar -->\r\n <div class=\"picker-calendar\">\r\n <mat-calendar\r\n [selected]=\"selectedDate()\"\r\n [minDate]=\"_minMoment\"\r\n [maxDate]=\"_maxMoment\"\r\n (selectedChange)=\"onDateSelected($event)\">\r\n </mat-calendar>\r\n </div>\r\n\r\n <!-- Divider m\u1EA3nh -->\r\n <div class=\"picker-divider\"></div>\r\n\r\n <!-- Time Spinner -->\r\n <div class=\"picker-time\">\r\n <sd-time-spinner\r\n [(hours)]=\"hours\"\r\n [(minutes)]=\"minutes\"\r\n [(seconds)]=\"seconds\"\r\n [showSeconds]=\"showSeconds()\"\r\n [disabled]=\"disabled()\">\r\n </sd-time-spinner>\r\n </div>\r\n\r\n <!-- Footer: B\u00E2y gi\u1EDD | H\u1EE7y | X\u00E1c nh\u1EADn -->\r\n <div class=\"picker-footer\">\r\n <button type=\"button\" class=\"btn btn-ghost\" (click)=\"onNow()\" [disabled]=\"disabled()\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"9\"></circle>\r\n <polyline points=\"12 7 12 12 15 14\"></polyline>\r\n </svg>\r\n <span>{{ 'core.form.datetime.now' | sdT }}</span>\r\n </button>\r\n\r\n <div class=\"footer-actions\">\r\n <button type=\"button\" class=\"btn btn-text\" (click)=\"onCancel()\">{{ 'core.common.cancel' | sdT }}</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"onConfirm()\" [disabled]=\"disabled()\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg>\r\n <span>{{ 'core.form.datetime.confirm' | sdT }}</span>\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block;background:#fff;border-radius:12px;box-shadow:0 10px 24px #0000001f,0 2px 6px #0000000f;overflow:hidden;font-family:inherit}.sd-datetime-picker{display:flex;flex-direction:column;width:320px;animation:sd-picker-enter .18s ease-out}@keyframes sd-picker-enter{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.picker-calendar{padding:4px 8px 0}.picker-calendar ::ng-deep .mat-calendar{height:auto;width:100%}.picker-calendar ::ng-deep .mat-calendar-header{padding:4px 4px 0}.picker-calendar ::ng-deep .mat-calendar-content{padding:0 8px 8px}.picker-divider{height:1px;background:var(--sd-black200);margin:0 16px}.picker-time{padding:8px 0}.picker-footer{display:flex;align-items:center;justify-content:space-between;padding:8px 12px 12px;gap:8px;border-top:1px solid var(--sd-black100)}.picker-footer .footer-actions{display:flex;align-items:center;gap:6px}.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;padding:0 12px;border:0;border-radius:6px;font-size:13px;font-weight:500;line-height:1;cursor:pointer;transition:background-color .15s ease,color .15s ease,transform .1s ease;white-space:nowrap}.btn svg{width:14px;height:14px;flex-shrink:0}.btn:active:not(:disabled){transform:scale(.97)}.btn:disabled{opacity:.5;cursor:not-allowed}.btn.btn-ghost{background:transparent;color:var(--sd-black400)}.btn.btn-ghost:hover:not(:disabled){background:var(--sd-black100);color:var(--sd-primary)}.btn.btn-text{background:transparent;color:var(--sd-black500)}.btn.btn-text:hover:not(:disabled){background:var(--sd-black100)}.btn.btn-primary{background:var(--sd-primary);color:#fff;box-shadow:0 1px 2px #0000000d}.btn.btn-primary:hover:not(:disabled){background:var(--sd-primary-dark)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i1.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: SdTimeSpinner, selector: "sd-time-spinner", inputs: ["hours", "minutes", "seconds", "showSeconds", "disabled"], outputs: ["hoursChange", "minutesChange", "secondsChange"] }, { kind: "pipe", type: SdTPipe, name: "sdT" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
303
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: SdDatetimePicker, isStandalone: true, selector: "sd-datetime-picker", inputs: { initialValue: { classPropertyName: "initialValue", publicName: "initialValue", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, showSeconds: { classPropertyName: "showSeconds", publicName: "showSeconds", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled" }, ngImport: i0, template: "<div class=\"sd-datetime-picker\">\r\n <!-- Calendar -->\r\n <div class=\"picker-calendar\">\r\n <mat-calendar\r\n [selected]=\"selectedDate()\"\r\n [minDate]=\"_minDate\"\r\n [maxDate]=\"_maxDate\"\r\n (selectedChange)=\"onDateSelected($event)\">\r\n </mat-calendar>\r\n </div>\r\n\r\n <!-- Divider m\u1EA3nh -->\r\n <div class=\"picker-divider\"></div>\r\n\r\n <!-- Time Spinner -->\r\n <div class=\"picker-time\">\r\n <sd-time-spinner\r\n [(hours)]=\"hours\"\r\n [(minutes)]=\"minutes\"\r\n [(seconds)]=\"seconds\"\r\n [showSeconds]=\"showSeconds()\"\r\n [disabled]=\"disabled()\">\r\n </sd-time-spinner>\r\n </div>\r\n\r\n <!-- Footer: B\u00E2y gi\u1EDD | H\u1EE7y | X\u00E1c nh\u1EADn -->\r\n <div class=\"picker-footer\">\r\n <button type=\"button\" class=\"btn btn-ghost\" (click)=\"onNow()\" [disabled]=\"disabled()\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"9\"></circle>\r\n <polyline points=\"12 7 12 12 15 14\"></polyline>\r\n </svg>\r\n <span>{{ 'core.form.datetime.now' | translate }}</span>\r\n </button>\r\n\r\n <div class=\"footer-actions\">\r\n <button type=\"button\" class=\"btn btn-text\" (click)=\"onCancel()\">{{ 'core.common.cancel' | translate }}</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"onConfirm()\" [disabled]=\"disabled()\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg>\r\n <span>{{ 'core.form.datetime.confirm' | translate }}</span>\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block;background:#fff;border-radius:12px;box-shadow:0 10px 24px #0000001f,0 2px 6px #0000000f;overflow:hidden;font-family:inherit}.sd-datetime-picker{display:flex;flex-direction:column;width:320px;animation:sd-picker-enter .18s ease-out}@keyframes sd-picker-enter{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.picker-calendar{padding:4px 8px 0}.picker-calendar ::ng-deep .mat-calendar{height:auto;width:100%}.picker-calendar ::ng-deep .mat-calendar-header{padding:4px 4px 0}.picker-calendar ::ng-deep .mat-calendar-content{padding:0 8px 8px}.picker-divider{height:1px;background:var(--sd-black200);margin:0 16px}.picker-time{padding:8px 0}.picker-footer{display:flex;align-items:center;justify-content:space-between;padding:8px 12px 12px;gap:8px;border-top:1px solid var(--sd-black100)}.picker-footer .footer-actions{display:flex;align-items:center;gap:6px}.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;padding:0 12px;border:0;border-radius:6px;font-size:13px;font-weight:500;line-height:1;cursor:pointer;transition:background-color .15s ease,color .15s ease,transform .1s ease;white-space:nowrap}.btn svg{width:14px;height:14px;flex-shrink:0}.btn:active:not(:disabled){transform:scale(.97)}.btn:disabled{opacity:.5;cursor:not-allowed}.btn.btn-ghost{background:transparent;color:var(--sd-black400)}.btn.btn-ghost:hover:not(:disabled){background:var(--sd-black100);color:var(--sd-primary)}.btn.btn-text{background:transparent;color:var(--sd-black500)}.btn.btn-text:hover:not(:disabled){background:var(--sd-black100)}.btn.btn-primary{background:var(--sd-primary);color:#fff;box-shadow:0 1px 2px #0000000d}.btn.btn-primary:hover:not(:disabled){background:var(--sd-primary-dark)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i1.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: SdTimeSpinner, selector: "sd-time-spinner", inputs: ["hours", "minutes", "seconds", "showSeconds", "disabled"], outputs: ["hoursChange", "minutesChange", "secondsChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
297
304
  }
298
305
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdDatetimePicker, decorators: [{
299
306
  type: Component,
300
- args: [{ selector: 'sd-datetime-picker', standalone: true, imports: [CommonModule, MatDatepickerModule, MatButtonModule, SdTimeSpinner, SdTPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sd-datetime-picker\">\r\n <!-- Calendar -->\r\n <div class=\"picker-calendar\">\r\n <mat-calendar\r\n [selected]=\"selectedDate()\"\r\n [minDate]=\"_minMoment\"\r\n [maxDate]=\"_maxMoment\"\r\n (selectedChange)=\"onDateSelected($event)\">\r\n </mat-calendar>\r\n </div>\r\n\r\n <!-- Divider m\u1EA3nh -->\r\n <div class=\"picker-divider\"></div>\r\n\r\n <!-- Time Spinner -->\r\n <div class=\"picker-time\">\r\n <sd-time-spinner\r\n [(hours)]=\"hours\"\r\n [(minutes)]=\"minutes\"\r\n [(seconds)]=\"seconds\"\r\n [showSeconds]=\"showSeconds()\"\r\n [disabled]=\"disabled()\">\r\n </sd-time-spinner>\r\n </div>\r\n\r\n <!-- Footer: B\u00E2y gi\u1EDD | H\u1EE7y | X\u00E1c nh\u1EADn -->\r\n <div class=\"picker-footer\">\r\n <button type=\"button\" class=\"btn btn-ghost\" (click)=\"onNow()\" [disabled]=\"disabled()\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"9\"></circle>\r\n <polyline points=\"12 7 12 12 15 14\"></polyline>\r\n </svg>\r\n <span>{{ 'core.form.datetime.now' | sdT }}</span>\r\n </button>\r\n\r\n <div class=\"footer-actions\">\r\n <button type=\"button\" class=\"btn btn-text\" (click)=\"onCancel()\">{{ 'core.common.cancel' | sdT }}</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"onConfirm()\" [disabled]=\"disabled()\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg>\r\n <span>{{ 'core.form.datetime.confirm' | sdT }}</span>\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block;background:#fff;border-radius:12px;box-shadow:0 10px 24px #0000001f,0 2px 6px #0000000f;overflow:hidden;font-family:inherit}.sd-datetime-picker{display:flex;flex-direction:column;width:320px;animation:sd-picker-enter .18s ease-out}@keyframes sd-picker-enter{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.picker-calendar{padding:4px 8px 0}.picker-calendar ::ng-deep .mat-calendar{height:auto;width:100%}.picker-calendar ::ng-deep .mat-calendar-header{padding:4px 4px 0}.picker-calendar ::ng-deep .mat-calendar-content{padding:0 8px 8px}.picker-divider{height:1px;background:var(--sd-black200);margin:0 16px}.picker-time{padding:8px 0}.picker-footer{display:flex;align-items:center;justify-content:space-between;padding:8px 12px 12px;gap:8px;border-top:1px solid var(--sd-black100)}.picker-footer .footer-actions{display:flex;align-items:center;gap:6px}.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;padding:0 12px;border:0;border-radius:6px;font-size:13px;font-weight:500;line-height:1;cursor:pointer;transition:background-color .15s ease,color .15s ease,transform .1s ease;white-space:nowrap}.btn svg{width:14px;height:14px;flex-shrink:0}.btn:active:not(:disabled){transform:scale(.97)}.btn:disabled{opacity:.5;cursor:not-allowed}.btn.btn-ghost{background:transparent;color:var(--sd-black400)}.btn.btn-ghost:hover:not(:disabled){background:var(--sd-black100);color:var(--sd-primary)}.btn.btn-text{background:transparent;color:var(--sd-black500)}.btn.btn-text:hover:not(:disabled){background:var(--sd-black100)}.btn.btn-primary{background:var(--sd-primary);color:#fff;box-shadow:0 1px 2px #0000000d}.btn.btn-primary:hover:not(:disabled){background:var(--sd-primary-dark)}\n"] }]
307
+ args: [{ selector: 'sd-datetime-picker', standalone: true, imports: [CommonModule, MatDatepickerModule, MatButtonModule, SdTimeSpinner, TranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sd-datetime-picker\">\r\n <!-- Calendar -->\r\n <div class=\"picker-calendar\">\r\n <mat-calendar\r\n [selected]=\"selectedDate()\"\r\n [minDate]=\"_minDate\"\r\n [maxDate]=\"_maxDate\"\r\n (selectedChange)=\"onDateSelected($event)\">\r\n </mat-calendar>\r\n </div>\r\n\r\n <!-- Divider m\u1EA3nh -->\r\n <div class=\"picker-divider\"></div>\r\n\r\n <!-- Time Spinner -->\r\n <div class=\"picker-time\">\r\n <sd-time-spinner\r\n [(hours)]=\"hours\"\r\n [(minutes)]=\"minutes\"\r\n [(seconds)]=\"seconds\"\r\n [showSeconds]=\"showSeconds()\"\r\n [disabled]=\"disabled()\">\r\n </sd-time-spinner>\r\n </div>\r\n\r\n <!-- Footer: B\u00E2y gi\u1EDD | H\u1EE7y | X\u00E1c nh\u1EADn -->\r\n <div class=\"picker-footer\">\r\n <button type=\"button\" class=\"btn btn-ghost\" (click)=\"onNow()\" [disabled]=\"disabled()\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"9\"></circle>\r\n <polyline points=\"12 7 12 12 15 14\"></polyline>\r\n </svg>\r\n <span>{{ 'core.form.datetime.now' | translate }}</span>\r\n </button>\r\n\r\n <div class=\"footer-actions\">\r\n <button type=\"button\" class=\"btn btn-text\" (click)=\"onCancel()\">{{ 'core.common.cancel' | translate }}</button>\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"onConfirm()\" [disabled]=\"disabled()\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg>\r\n <span>{{ 'core.form.datetime.confirm' | translate }}</span>\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block;background:#fff;border-radius:12px;box-shadow:0 10px 24px #0000001f,0 2px 6px #0000000f;overflow:hidden;font-family:inherit}.sd-datetime-picker{display:flex;flex-direction:column;width:320px;animation:sd-picker-enter .18s ease-out}@keyframes sd-picker-enter{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.picker-calendar{padding:4px 8px 0}.picker-calendar ::ng-deep .mat-calendar{height:auto;width:100%}.picker-calendar ::ng-deep .mat-calendar-header{padding:4px 4px 0}.picker-calendar ::ng-deep .mat-calendar-content{padding:0 8px 8px}.picker-divider{height:1px;background:var(--sd-black200);margin:0 16px}.picker-time{padding:8px 0}.picker-footer{display:flex;align-items:center;justify-content:space-between;padding:8px 12px 12px;gap:8px;border-top:1px solid var(--sd-black100)}.picker-footer .footer-actions{display:flex;align-items:center;gap:6px}.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;padding:0 12px;border:0;border-radius:6px;font-size:13px;font-weight:500;line-height:1;cursor:pointer;transition:background-color .15s ease,color .15s ease,transform .1s ease;white-space:nowrap}.btn svg{width:14px;height:14px;flex-shrink:0}.btn:active:not(:disabled){transform:scale(.97)}.btn:disabled{opacity:.5;cursor:not-allowed}.btn.btn-ghost{background:transparent;color:var(--sd-black400)}.btn.btn-ghost:hover:not(:disabled){background:var(--sd-black100);color:var(--sd-primary)}.btn.btn-text{background:transparent;color:var(--sd-black500)}.btn.btn-text:hover:not(:disabled){background:var(--sd-black100)}.btn.btn-primary{background:var(--sd-primary);color:#fff;box-shadow:0 1px 2px #0000000d}.btn.btn-primary:hover:not(:disabled){background:var(--sd-primary-dark)}\n"] }]
301
308
  }], ctorParameters: () => [], propDecorators: { confirmed: [{
302
309
  type: Output
303
310
  }], cancelled: [{
@@ -307,19 +314,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
307
314
  /* eslint-disable @typescript-eslint/no-explicit-any */
308
315
  /* eslint-disable @angular-eslint/no-input-rename */
309
316
  /**
310
- * Format parse/display dùng cho MatDateAdapter (Moment).
311
- * Note: format input là `DD/MM/YYYY HH:mm` (không có giây mặc định) —
317
+ * Format parse/display dùng cho MatDateAdapter (date-fns).
318
+ * Note: format input là `dd/MM/yyyy HH:mm` (không có giây mặc định) —
312
319
  * giây chỉ được render khi `showSeconds` = true.
320
+ * Token date-fns dùng chữ thường: `yyyy` (năm), `dd` (ngày), `HH` (giờ 24h).
313
321
  */
314
322
  const SD_DATETIME_FORMATS = {
315
- parse: { dateInput: 'DD/MM/YYYY HH:mm' },
323
+ parse: { dateInput: 'dd/MM/yyyy HH:mm' },
316
324
  display: {
317
- dateInput: 'DD/MM/YYYY HH:mm',
318
- monthYearLabel: 'MMM YYYY',
319
- dateA11yLabel: 'LL',
320
- monthYearA11yLabel: 'MMMM YYYY',
325
+ dateInput: 'dd/MM/yyyy HH:mm',
326
+ monthYearLabel: 'MMM yyyy',
327
+ dateA11yLabel: 'PP',
328
+ monthYearA11yLabel: 'MMMM yyyy',
321
329
  },
322
330
  };
331
+ /**
332
+ * Thử parse `value` theo lần lượt nhiều format; trả về Date đầu tiên hợp lệ.
333
+ * date-fns không hỗ trợ multi-format parse như moment(value, [fmt1, fmt2], true).
334
+ */
335
+ function parseFirstValid(value, formats) {
336
+ for (const fmt of formats) {
337
+ const d = parse(value, fmt, new Date());
338
+ if (isValid(d))
339
+ return d;
340
+ }
341
+ return null;
342
+ }
323
343
  class SdDatetime {
324
344
  id = `I${uuid.v4()}`;
325
345
  // ==========================================
@@ -337,7 +357,7 @@ class SdDatetime {
337
357
  elementRef = inject(ElementRef);
338
358
  injector = inject(Injector);
339
359
  formConfig = inject(SD_FORM_CONFIGURATION, { optional: true });
340
- #i18n = inject(SdI18nService);
360
+ #i18n = inject(I18nService);
341
361
  // ==========================================
342
362
  // 3. SIGNAL INPUTS & MODEL
343
363
  // ==========================================
@@ -409,6 +429,18 @@ class SdDatetime {
409
429
  maxDateInput = input(undefined, { alias: 'maxDate' });
410
430
  resolvedMax = computed(() => this.#parseDateBoundary(this.maxInput() ?? this.maxDateInput()));
411
431
  valueModel = model(undefined, { alias: 'model' });
432
+ // viewed-mode: formControl.value là chuỗi display (dd/MM/yyyy HH:mm) nên DatePipe không parse được.
433
+ // Lấy thẳng từ valueModel (nguồn dữ liệu thật) rồi convert sang Date cho DatePipe.
434
+ viewedDate = computed(() => {
435
+ const v = this.valueModel();
436
+ if (v == null || !DateUtilities.isDate(v))
437
+ return null;
438
+ const iso = DateUtilities.toFormat(v, 'yyyy/MM/dd HH:mm:ss');
439
+ if (!iso)
440
+ return null;
441
+ const d = parse(iso, 'yyyy/MM/dd HH:mm:ss', new Date());
442
+ return isValid(d) ? d : null;
443
+ });
412
444
  // ==========================================
413
445
  // 4. SIGNAL OUTPUTS
414
446
  // ==========================================
@@ -511,7 +543,7 @@ class SdDatetime {
511
543
  const portal = new ComponentPortal(SdDatetimePicker, null, this.injector);
512
544
  const ref = this.#overlayRef.attach(portal);
513
545
  // Đẩy state hiện tại vào popup
514
- ref.setInput('initialValue', this.#currentValueAsMoment());
546
+ ref.setInput('initialValue', this.#currentValueAsDate());
515
547
  ref.setInput('minDate', this.resolvedMin());
516
548
  ref.setInput('maxDate', this.resolvedMax());
517
549
  ref.setInput('showSeconds', this.showSeconds());
@@ -539,7 +571,8 @@ class SdDatetime {
539
571
  }
540
572
  #onPickerConfirm(value) {
541
573
  const fmt = this.showSeconds() ? 'yyyy/MM/dd HH:mm:ss' : 'yyyy/MM/dd HH:mm:00';
542
- const stored = DateUtilities.toFormat(value.toDate(), fmt);
574
+ // value giờ là native Date (date-fns), không cần .toDate() như Moment.
575
+ const stored = DateUtilities.toFormat(value, fmt);
543
576
  if (this.#date !== stored) {
544
577
  this.valueModel.set(stored);
545
578
  this.sdChange.emit(stored);
@@ -549,13 +582,16 @@ class SdDatetime {
549
582
  #onPickerCancel() {
550
583
  this.#closeOverlay();
551
584
  }
552
- /** Lấy giá trị hiện tại dưới dạng Moment để truyền vào popup. */
553
- #currentValueAsMoment() {
585
+ /** Lấy giá trị hiện tại dưới dạng native Date để truyền vào popup. */
586
+ #currentValueAsDate() {
554
587
  const v = this.valueModel();
555
588
  if (!v || !DateUtilities.isDate(v))
556
589
  return null;
557
590
  const fmtted = DateUtilities.toFormat(v, 'yyyy/MM/dd HH:mm:ss');
558
- return fmtted ? moment(fmtted, 'YYYY/MM/DD HH:mm:ss') : null;
591
+ if (!fmtted)
592
+ return null;
593
+ const parsed = parse(fmtted, 'yyyy/MM/dd HH:mm:ss', new Date());
594
+ return isValid(parsed) ? parsed : null;
559
595
  }
560
596
  // ==========================================
561
597
  // 7. PARSE/VALIDATE HELPERS
@@ -639,12 +675,13 @@ class SdDatetime {
639
675
  formControl.setErrors({ ...formControl.errors, date: null });
640
676
  this.formControl.updateValueAndValidity();
641
677
  }, 0);
642
- // Đồng bộ ngược về model nếu hợp lệ
678
+ // Đồng bộ ngược về model nếu hợp lệ.
679
+ // date-fns không có multi-format strict parse như moment, dùng helper parseFirstValid.
643
680
  if (currentVal) {
644
- const parsed = moment(currentVal, ['DD/MM/YYYY HH:mm:ss', 'DD/MM/YYYY HH:mm'], true);
645
- if (parsed.isValid()) {
681
+ const parsed = parseFirstValid(currentVal, ['dd/MM/yyyy HH:mm:ss', 'dd/MM/yyyy HH:mm']);
682
+ if (parsed) {
646
683
  const fmt = this.showSeconds() ? 'yyyy/MM/dd HH:mm:ss' : 'yyyy/MM/dd HH:mm:00';
647
- const stored = DateUtilities.toFormat(parsed.toDate(), fmt);
684
+ const stored = DateUtilities.toFormat(parsed, fmt);
648
685
  if (this.#date !== stored) {
649
686
  this.valueModel.set(stored);
650
687
  this.sdChange.emit(stored);
@@ -666,13 +703,17 @@ class SdDatetime {
666
703
  };
667
704
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdDatetime, deps: [], target: i0.ɵɵFactoryTarget.Component });
668
705
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: SdDatetime, isStandalone: true, selector: "sd-datetime", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, helperText: { classPropertyName: "helperText", publicName: "helperText", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hideInlineError: { classPropertyName: "hideInlineError", publicName: "hideInlineError", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, viewed: { classPropertyName: "viewed", publicName: "viewed", isSignal: true, isRequired: false, transformFunction: null }, showSeconds: { classPropertyName: "showSeconds", publicName: "showSeconds", 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 }, appearanceInput: { classPropertyName: "appearanceInput", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, floatLabel: { classPropertyName: "floatLabel", publicName: "floatLabel", isSignal: true, isRequired: false, transformFunction: null }, minInput: { classPropertyName: "minInput", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, minDateInput: { classPropertyName: "minDateInput", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxInput: { classPropertyName: "maxInput", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, maxDateInput: { classPropertyName: "maxDateInput", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, valueModel: { classPropertyName: "valueModel", publicName: "model", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueModel: "modelChange", sdChange: "sdChange", sdFocus: "sdFocus" }, providers: [
669
- provideMomentDateAdapter(SD_DATETIME_FORMATS),
670
- ], queries: [{ propertyName: "sdLabelTemplate", first: true, predicate: ["sdLabel"], descendants: true, isSignal: true }, { propertyName: "sdValueTemplate", first: true, predicate: ["sdValue"], descendants: true, isSignal: true }, { propertyName: "sdViewDef", first: true, predicate: SdViewDefDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: "@let lbl = label();\r\n@let app = appearance();\r\n@let hideErr = hideInlineError();\r\n@let errMsg = errorTooltipMessage;\r\n@let viewDef = sdViewDef();\r\n@let hText = helperText();\r\n@let req = required();\r\n\r\n@let minD = resolvedMin();\r\n@let maxD = resolvedMax();\r\n\r\n@if (viewed()) {\r\n <sd-view\r\n [label]=\"lbl\"\r\n [labelTemplate]=\"sdLabelTemplate()\"\r\n [value]=\"formControl.value\"\r\n [display]=\"formControl.value | date: 'dd/MM/yyyy HH:mm'\"\r\n [hyperlink]=\"hyperlink()\"\r\n [valueTemplate]=\"sdValueTemplate()\">\r\n </sd-view>\r\n} @else {\r\n @if (!app) {\r\n <ng-content select=\"[sdLabel]\">\r\n @if (lbl) {\r\n <sd-label [label]=\"lbl\" [required]=\"req\"></sd-label>\r\n }\r\n </ng-content>\r\n }\r\n\r\n <div\r\n class=\"d-flex align-items-center\"\r\n [class.sd-view]=\"viewDef?.templateRef\"\r\n [class.c-focused]=\"isFocused\"\r\n [class.c-disabled]=\"formControl.disabled\"\r\n (click)=\"onClick()\"\r\n aria-hidden=\"true\">\r\n @if (viewDef?.templateRef && !isFocused && !pickerOpened()) {\r\n <ng-container *ngTemplateOutlet=\"viewDef!.templateRef; context: { value: formControl.value }\"> </ng-container>\r\n } @else {\r\n <mat-form-field\r\n class=\"c-form-field-datetime-input\"\r\n [class.sd-md]=\"size() === 'md'\"\r\n [class.sd-sm]=\"size() === 'sm'\"\r\n [class.hide-inline-error]=\"hideErr\"\r\n [appearance]=\"app || 'outline'\"\r\n [floatLabel]=\"floatLabel()\">\r\n @if (app && lbl) {\r\n <mat-label style=\"display: inline-block\">\r\n <div class=\"d-flex align-items-center gap-4\">\r\n <span>{{ lbl }}</span>\r\n @if (hText) {\r\n <mat-icon [matTooltip]=\"hText\" matTooltipPosition=\"below\">info_outline</mat-icon>\r\n }\r\n </div>\r\n </mat-label>\r\n }\r\n\r\n <input\r\n aria-hidden=\"true\"\r\n [attr.data-autoId]=\"autoId()\"\r\n [id]=\"id\"\r\n (blur)=\"onConfirmInput($event)\"\r\n (keyup.enter)=\"onConfirmInput($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [autocomplete]=\"id\"\r\n autocorrect=\"off\"\r\n [formControl]=\"formControl\"\r\n [required]=\"req\"\r\n [placeholder]=\"placeholder() || lbl || ''\"\r\n [min]=\"minD\"\r\n [max]=\"maxD\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n #input\r\n matInput />\r\n\r\n @if (hideErr && errMsg && formControl.touched) {\r\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"errMsg\" matTooltipPosition=\"above\"> error </mat-icon>\r\n }\r\n\r\n @if (!hideErr && errMsg && formControl.touched) {\r\n <mat-error>{{ errMsg }}</mat-error>\r\n }\r\n\r\n <span class=\"cursor-pointer sd-suffix-icon\" (click)=\"!formControl.disabled && open()\" matSuffix\r\n ><svg fill=\"currentColor\" viewBox=\"0 0 24 24\" fill=\"currentColor\" focusable=\"false\">\r\n <path\r\n d=\"M15,13H16.5V15.82L18.94,17.23L18.19,18.53L15,16.69V13M19,8H5V19H9.67C9.24,18.09 9,17.07 9,16A7,7 0 0,1 16,9C17.07,9 18.09,9.24 19,9.67V8M5,21C3.89,21 3,20.1 3,19V5C3,3.89 3.89,3 5,3H6V1H8V3H16V1H18V3H19A2,2 0 0,1 21,5V11.1C22.24,12.36 23,14.09 23,16A7,7 0 0,1 16,23C14.09,23 12.36,22.24 11.1,21H5M16,11.15A4.85,4.85 0 0,0 11.15,16C11.15,18.68 13.32,20.85 16,20.85A4.85,4.85 0 0,0 20.85,16C20.85,13.32 18.68,11.15 16,11.15Z\"></path></svg\r\n ></span>\r\n </mat-form-field>\r\n }\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-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{padding-top:5px;display:block}:host ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline.mat-form-field-disabled .mat-mdc-text-field-wrapper{background:var(--sd-black100)}:host ::ng-deep .mat-mdc-form-field input.mat-mdc-input-element:disabled{color:var(--sd-black400)!important}:host ::ng-deep .mat-mdc-form-field .mat-mdc-placeholder-required{color:var(--sd-error)}.sd-view:not(.c-focused):not(.c-disabled):hover{background-color:#ebecf0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1$1.DatePipe, name: "date" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { 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: MatFormFieldModule }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
706
+ // DateFnsAdapter inject MAT_DATE_LOCALE; cấp default en-US để parse/format hoạt động.
707
+ { provide: MAT_DATE_LOCALE, useValue: enUS },
708
+ provideDateFnsAdapter(SD_DATETIME_FORMATS),
709
+ ], queries: [{ propertyName: "sdLabelTemplate", first: true, predicate: ["sdLabel"], descendants: true, isSignal: true }, { propertyName: "sdValueTemplate", first: true, predicate: ["sdValue"], descendants: true, isSignal: true }, { propertyName: "sdViewDef", first: true, predicate: SdViewDefDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: "@let lbl = label();\r\n@let app = appearance();\r\n@let hideErr = hideInlineError();\r\n@let errMsg = errorTooltipMessage;\r\n@let viewDef = sdViewDef();\r\n@let hText = helperText();\r\n@let req = required();\r\n\r\n@let minD = resolvedMin();\r\n@let maxD = resolvedMax();\r\n\r\n@let vDate = viewedDate();\r\n@if (viewed()) {\r\n <sd-view\r\n [label]=\"lbl\"\r\n [labelTemplate]=\"sdLabelTemplate()\"\r\n [value]=\"vDate\"\r\n [display]=\"vDate | date: (showSeconds() ? 'dd/MM/yyyy HH:mm:ss' : 'dd/MM/yyyy HH:mm')\"\r\n [hyperlink]=\"hyperlink()\"\r\n [valueTemplate]=\"sdValueTemplate()\">\r\n </sd-view>\r\n} @else {\r\n @if (!app) {\r\n <ng-content select=\"[sdLabel]\">\r\n @if (lbl) {\r\n <sd-label [label]=\"lbl\" [required]=\"req\"></sd-label>\r\n }\r\n </ng-content>\r\n }\r\n\r\n <div\r\n class=\"d-flex align-items-center\"\r\n [class.sd-view]=\"viewDef?.templateRef\"\r\n [class.c-focused]=\"isFocused\"\r\n [class.c-disabled]=\"formControl.disabled\"\r\n (click)=\"onClick()\"\r\n aria-hidden=\"true\">\r\n @if (viewDef?.templateRef && !isFocused && !pickerOpened()) {\r\n <ng-container *ngTemplateOutlet=\"viewDef!.templateRef; context: { value: formControl.value }\"> </ng-container>\r\n } @else {\r\n <mat-form-field\r\n class=\"c-form-field-datetime-input\"\r\n [class.sd-md]=\"size() === 'md'\"\r\n [class.sd-sm]=\"size() === 'sm'\"\r\n [class.hide-inline-error]=\"hideErr\"\r\n [appearance]=\"app || 'outline'\"\r\n [floatLabel]=\"floatLabel()\">\r\n @if (app && lbl) {\r\n <mat-label style=\"display: inline-block\">\r\n <div class=\"d-flex align-items-center gap-4\">\r\n <span>{{ lbl }}</span>\r\n @if (hText) {\r\n <mat-icon [matTooltip]=\"hText\" matTooltipPosition=\"below\">info_outline</mat-icon>\r\n }\r\n </div>\r\n </mat-label>\r\n }\r\n\r\n <input\r\n aria-hidden=\"true\"\r\n [attr.data-autoId]=\"autoId()\"\r\n [id]=\"id\"\r\n (blur)=\"onConfirmInput($event)\"\r\n (keyup.enter)=\"onConfirmInput($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [autocomplete]=\"id\"\r\n autocorrect=\"off\"\r\n [formControl]=\"formControl\"\r\n [required]=\"req\"\r\n [placeholder]=\"placeholder() || lbl || ''\"\r\n [min]=\"minD\"\r\n [max]=\"maxD\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n #input\r\n matInput />\r\n\r\n @if (hideErr && errMsg && formControl.touched) {\r\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"errMsg\" matTooltipPosition=\"above\"> error </mat-icon>\r\n }\r\n\r\n @if (!hideErr && errMsg && formControl.touched) {\r\n <mat-error>{{ errMsg }}</mat-error>\r\n }\r\n\r\n <span class=\"cursor-pointer sd-suffix-icon\" (click)=\"!formControl.disabled && open()\" matSuffix\r\n ><svg fill=\"currentColor\" viewBox=\"0 0 24 24\" fill=\"currentColor\" focusable=\"false\">\r\n <path\r\n d=\"M15,13H16.5V15.82L18.94,17.23L18.19,18.53L15,16.69V13M19,8H5V19H9.67C9.24,18.09 9,17.07 9,16A7,7 0 0,1 16,9C17.07,9 18.09,9.24 19,9.67V8M5,21C3.89,21 3,20.1 3,19V5C3,3.89 3.89,3 5,3H6V1H8V3H16V1H18V3H19A2,2 0 0,1 21,5V11.1C22.24,12.36 23,14.09 23,16A7,7 0 0,1 16,23C14.09,23 12.36,22.24 11.1,21H5M16,11.15A4.85,4.85 0 0,0 11.15,16C11.15,18.68 13.32,20.85 16,20.85A4.85,4.85 0 0,0 20.85,16C20.85,13.32 18.68,11.15 16,11.15Z\"></path></svg\r\n ></span>\r\n </mat-form-field>\r\n }\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-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{padding-top:5px;display:block}:host ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline.mat-form-field-disabled .mat-mdc-text-field-wrapper{background:var(--sd-black100)}:host ::ng-deep .mat-mdc-form-field input.mat-mdc-input-element:disabled{color:var(--sd-black400)!important}:host ::ng-deep .mat-mdc-form-field .mat-mdc-placeholder-required{color:var(--sd-error)}.sd-view:not(.c-focused):not(.c-disabled):hover{background-color:#ebecf0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1$1.DatePipe, name: "date" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { 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: MatFormFieldModule }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
671
710
  }
672
711
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdDatetime, decorators: [{
673
712
  type: Component,
674
713
  args: [{ selector: 'sd-datetime', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
675
- provideMomentDateAdapter(SD_DATETIME_FORMATS),
714
+ // DateFnsAdapter inject MAT_DATE_LOCALE; cấp default en-US để parse/format hoạt động.
715
+ { provide: MAT_DATE_LOCALE, useValue: enUS },
716
+ provideDateFnsAdapter(SD_DATETIME_FORMATS),
676
717
  ], standalone: true, imports: [
677
718
  CommonModule,
678
719
  FormsModule,
@@ -683,7 +724,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
683
724
  MatFormFieldModule,
684
725
  SdLabel,
685
726
  SdView,
686
- ], template: "@let lbl = label();\r\n@let app = appearance();\r\n@let hideErr = hideInlineError();\r\n@let errMsg = errorTooltipMessage;\r\n@let viewDef = sdViewDef();\r\n@let hText = helperText();\r\n@let req = required();\r\n\r\n@let minD = resolvedMin();\r\n@let maxD = resolvedMax();\r\n\r\n@if (viewed()) {\r\n <sd-view\r\n [label]=\"lbl\"\r\n [labelTemplate]=\"sdLabelTemplate()\"\r\n [value]=\"formControl.value\"\r\n [display]=\"formControl.value | date: 'dd/MM/yyyy HH:mm'\"\r\n [hyperlink]=\"hyperlink()\"\r\n [valueTemplate]=\"sdValueTemplate()\">\r\n </sd-view>\r\n} @else {\r\n @if (!app) {\r\n <ng-content select=\"[sdLabel]\">\r\n @if (lbl) {\r\n <sd-label [label]=\"lbl\" [required]=\"req\"></sd-label>\r\n }\r\n </ng-content>\r\n }\r\n\r\n <div\r\n class=\"d-flex align-items-center\"\r\n [class.sd-view]=\"viewDef?.templateRef\"\r\n [class.c-focused]=\"isFocused\"\r\n [class.c-disabled]=\"formControl.disabled\"\r\n (click)=\"onClick()\"\r\n aria-hidden=\"true\">\r\n @if (viewDef?.templateRef && !isFocused && !pickerOpened()) {\r\n <ng-container *ngTemplateOutlet=\"viewDef!.templateRef; context: { value: formControl.value }\"> </ng-container>\r\n } @else {\r\n <mat-form-field\r\n class=\"c-form-field-datetime-input\"\r\n [class.sd-md]=\"size() === 'md'\"\r\n [class.sd-sm]=\"size() === 'sm'\"\r\n [class.hide-inline-error]=\"hideErr\"\r\n [appearance]=\"app || 'outline'\"\r\n [floatLabel]=\"floatLabel()\">\r\n @if (app && lbl) {\r\n <mat-label style=\"display: inline-block\">\r\n <div class=\"d-flex align-items-center gap-4\">\r\n <span>{{ lbl }}</span>\r\n @if (hText) {\r\n <mat-icon [matTooltip]=\"hText\" matTooltipPosition=\"below\">info_outline</mat-icon>\r\n }\r\n </div>\r\n </mat-label>\r\n }\r\n\r\n <input\r\n aria-hidden=\"true\"\r\n [attr.data-autoId]=\"autoId()\"\r\n [id]=\"id\"\r\n (blur)=\"onConfirmInput($event)\"\r\n (keyup.enter)=\"onConfirmInput($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [autocomplete]=\"id\"\r\n autocorrect=\"off\"\r\n [formControl]=\"formControl\"\r\n [required]=\"req\"\r\n [placeholder]=\"placeholder() || lbl || ''\"\r\n [min]=\"minD\"\r\n [max]=\"maxD\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n #input\r\n matInput />\r\n\r\n @if (hideErr && errMsg && formControl.touched) {\r\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"errMsg\" matTooltipPosition=\"above\"> error </mat-icon>\r\n }\r\n\r\n @if (!hideErr && errMsg && formControl.touched) {\r\n <mat-error>{{ errMsg }}</mat-error>\r\n }\r\n\r\n <span class=\"cursor-pointer sd-suffix-icon\" (click)=\"!formControl.disabled && open()\" matSuffix\r\n ><svg fill=\"currentColor\" viewBox=\"0 0 24 24\" fill=\"currentColor\" focusable=\"false\">\r\n <path\r\n d=\"M15,13H16.5V15.82L18.94,17.23L18.19,18.53L15,16.69V13M19,8H5V19H9.67C9.24,18.09 9,17.07 9,16A7,7 0 0,1 16,9C17.07,9 18.09,9.24 19,9.67V8M5,21C3.89,21 3,20.1 3,19V5C3,3.89 3.89,3 5,3H6V1H8V3H16V1H18V3H19A2,2 0 0,1 21,5V11.1C22.24,12.36 23,14.09 23,16A7,7 0 0,1 16,23C14.09,23 12.36,22.24 11.1,21H5M16,11.15A4.85,4.85 0 0,0 11.15,16C11.15,18.68 13.32,20.85 16,20.85A4.85,4.85 0 0,0 20.85,16C20.85,13.32 18.68,11.15 16,11.15Z\"></path></svg\r\n ></span>\r\n </mat-form-field>\r\n }\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-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{padding-top:5px;display:block}:host ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline.mat-form-field-disabled .mat-mdc-text-field-wrapper{background:var(--sd-black100)}:host ::ng-deep .mat-mdc-form-field input.mat-mdc-input-element:disabled{color:var(--sd-black400)!important}:host ::ng-deep .mat-mdc-form-field .mat-mdc-placeholder-required{color:var(--sd-error)}.sd-view:not(.c-focused):not(.c-disabled):hover{background-color:#ebecf0}\n"] }]
727
+ ], template: "@let lbl = label();\r\n@let app = appearance();\r\n@let hideErr = hideInlineError();\r\n@let errMsg = errorTooltipMessage;\r\n@let viewDef = sdViewDef();\r\n@let hText = helperText();\r\n@let req = required();\r\n\r\n@let minD = resolvedMin();\r\n@let maxD = resolvedMax();\r\n\r\n@let vDate = viewedDate();\r\n@if (viewed()) {\r\n <sd-view\r\n [label]=\"lbl\"\r\n [labelTemplate]=\"sdLabelTemplate()\"\r\n [value]=\"vDate\"\r\n [display]=\"vDate | date: (showSeconds() ? 'dd/MM/yyyy HH:mm:ss' : 'dd/MM/yyyy HH:mm')\"\r\n [hyperlink]=\"hyperlink()\"\r\n [valueTemplate]=\"sdValueTemplate()\">\r\n </sd-view>\r\n} @else {\r\n @if (!app) {\r\n <ng-content select=\"[sdLabel]\">\r\n @if (lbl) {\r\n <sd-label [label]=\"lbl\" [required]=\"req\"></sd-label>\r\n }\r\n </ng-content>\r\n }\r\n\r\n <div\r\n class=\"d-flex align-items-center\"\r\n [class.sd-view]=\"viewDef?.templateRef\"\r\n [class.c-focused]=\"isFocused\"\r\n [class.c-disabled]=\"formControl.disabled\"\r\n (click)=\"onClick()\"\r\n aria-hidden=\"true\">\r\n @if (viewDef?.templateRef && !isFocused && !pickerOpened()) {\r\n <ng-container *ngTemplateOutlet=\"viewDef!.templateRef; context: { value: formControl.value }\"> </ng-container>\r\n } @else {\r\n <mat-form-field\r\n class=\"c-form-field-datetime-input\"\r\n [class.sd-md]=\"size() === 'md'\"\r\n [class.sd-sm]=\"size() === 'sm'\"\r\n [class.hide-inline-error]=\"hideErr\"\r\n [appearance]=\"app || 'outline'\"\r\n [floatLabel]=\"floatLabel()\">\r\n @if (app && lbl) {\r\n <mat-label style=\"display: inline-block\">\r\n <div class=\"d-flex align-items-center gap-4\">\r\n <span>{{ lbl }}</span>\r\n @if (hText) {\r\n <mat-icon [matTooltip]=\"hText\" matTooltipPosition=\"below\">info_outline</mat-icon>\r\n }\r\n </div>\r\n </mat-label>\r\n }\r\n\r\n <input\r\n aria-hidden=\"true\"\r\n [attr.data-autoId]=\"autoId()\"\r\n [id]=\"id\"\r\n (blur)=\"onConfirmInput($event)\"\r\n (keyup.enter)=\"onConfirmInput($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [autocomplete]=\"id\"\r\n autocorrect=\"off\"\r\n [formControl]=\"formControl\"\r\n [required]=\"req\"\r\n [placeholder]=\"placeholder() || lbl || ''\"\r\n [min]=\"minD\"\r\n [max]=\"maxD\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n #input\r\n matInput />\r\n\r\n @if (hideErr && errMsg && formControl.touched) {\r\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"errMsg\" matTooltipPosition=\"above\"> error </mat-icon>\r\n }\r\n\r\n @if (!hideErr && errMsg && formControl.touched) {\r\n <mat-error>{{ errMsg }}</mat-error>\r\n }\r\n\r\n <span class=\"cursor-pointer sd-suffix-icon\" (click)=\"!formControl.disabled && open()\" matSuffix\r\n ><svg fill=\"currentColor\" viewBox=\"0 0 24 24\" fill=\"currentColor\" focusable=\"false\">\r\n <path\r\n d=\"M15,13H16.5V15.82L18.94,17.23L18.19,18.53L15,16.69V13M19,8H5V19H9.67C9.24,18.09 9,17.07 9,16A7,7 0 0,1 16,9C17.07,9 18.09,9.24 19,9.67V8M5,21C3.89,21 3,20.1 3,19V5C3,3.89 3.89,3 5,3H6V1H8V3H16V1H18V3H19A2,2 0 0,1 21,5V11.1C22.24,12.36 23,14.09 23,16A7,7 0 0,1 16,23C14.09,23 12.36,22.24 11.1,21H5M16,11.15A4.85,4.85 0 0,0 11.15,16C11.15,18.68 13.32,20.85 16,20.85A4.85,4.85 0 0,0 20.85,16C20.85,13.32 18.68,11.15 16,11.15Z\"></path></svg\r\n ></span>\r\n </mat-form-field>\r\n }\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-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{padding-top:5px;display:block}:host ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline.mat-form-field-disabled .mat-mdc-text-field-wrapper{background:var(--sd-black100)}:host ::ng-deep .mat-mdc-form-field input.mat-mdc-input-element:disabled{color:var(--sd-black400)!important}:host ::ng-deep .mat-mdc-form-field .mat-mdc-placeholder-required{color:var(--sd-error)}.sd-view:not(.c-focused):not(.c-disabled):hover{background-color:#ebecf0}\n"] }]
687
728
  }], ctorParameters: () => [] });
688
729
 
689
730
  /**