@sd-angular/core 19.0.44 → 19.0.45

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 (66) hide show
  1. package/README.md +4 -0
  2. package/assets/scss/core/form.scss +21 -40
  3. package/assets/scss/core/view.scss +24 -0
  4. package/assets/scss/sd-core.scss +1 -0
  5. package/assets/scss/themes/_material-tokens.scss +71 -0
  6. package/assets/scss/themes/default.scss +10 -0
  7. package/components/form-generic/src/components/form-builder/components/expression-builder/expression-builder.component.d.ts +1 -0
  8. package/components/form-generic/src/models/form-generic-expression.model.d.ts +10 -4
  9. package/components/form-generic/src/pipes/component-viewed.pipe.d.ts +1 -0
  10. package/components/import-excel/src/pipes/column-transform.pipe.d.ts +1 -0
  11. package/components/inform/src/inform.component.d.ts +12 -3
  12. package/components/table/src/services/table-export/table-export.service.d.ts +1 -1
  13. package/components/table/src/services/table-filter/table-filter.model.d.ts +7 -0
  14. package/components/table/src/services/table-local/table-local-sort.util.d.ts +8 -2
  15. package/components/table/src/services/table-local/table-local.util.d.ts +6 -1
  16. package/components/table/src/table.component.d.ts +1 -1
  17. package/components/timeline/pipes/view-date.pipe.d.ts +1 -0
  18. package/configurations/src/sd-core.configuration.d.ts +7 -0
  19. package/fesm2022/sd-angular-core-components-form-generic.mjs +44 -31
  20. package/fesm2022/sd-angular-core-components-form-generic.mjs.map +1 -1
  21. package/fesm2022/sd-angular-core-components-import-excel.mjs +19 -5
  22. package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
  23. package/fesm2022/sd-angular-core-components-inform.mjs +16 -2
  24. package/fesm2022/sd-angular-core-components-inform.mjs.map +1 -1
  25. package/fesm2022/sd-angular-core-components-section.mjs +2 -2
  26. package/fesm2022/sd-angular-core-components-section.mjs.map +1 -1
  27. package/fesm2022/sd-angular-core-components-table.mjs +174 -66
  28. package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
  29. package/fesm2022/sd-angular-core-components-timeline.mjs +4 -1
  30. package/fesm2022/sd-angular-core-components-timeline.mjs.map +1 -1
  31. package/fesm2022/sd-angular-core-components-view.mjs +2 -2
  32. package/fesm2022/sd-angular-core-components-view.mjs.map +1 -1
  33. package/fesm2022/sd-angular-core-configurations.mjs.map +1 -1
  34. package/fesm2022/sd-angular-core-forms-checkbox.mjs +2 -2
  35. package/fesm2022/sd-angular-core-forms-checkbox.mjs.map +1 -1
  36. package/fesm2022/sd-angular-core-forms-date-range.mjs +15 -2
  37. package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
  38. package/fesm2022/sd-angular-core-forms-date.mjs +11 -1
  39. package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
  40. package/fesm2022/sd-angular-core-forms-datetime.mjs +43 -9
  41. package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
  42. package/fesm2022/sd-angular-core-forms-models.mjs +6 -0
  43. package/fesm2022/sd-angular-core-forms-models.mjs.map +1 -1
  44. package/fesm2022/sd-angular-core-forms-radio.mjs +2 -2
  45. package/fesm2022/sd-angular-core-forms-radio.mjs.map +1 -1
  46. package/fesm2022/sd-angular-core-forms-switch.mjs +2 -2
  47. package/fesm2022/sd-angular-core-forms-switch.mjs.map +1 -1
  48. package/fesm2022/sd-angular-core-forms-textarea.mjs +2 -2
  49. package/fesm2022/sd-angular-core-forms-textarea.mjs.map +1 -1
  50. package/fesm2022/sd-angular-core-pipes.mjs +26 -10
  51. package/fesm2022/sd-angular-core-pipes.mjs.map +1 -1
  52. package/fesm2022/sd-angular-core-services-date-time.mjs +143 -0
  53. package/fesm2022/sd-angular-core-services-date-time.mjs.map +1 -0
  54. package/fesm2022/sd-angular-core-services.mjs +1 -0
  55. package/fesm2022/sd-angular-core-services.mjs.map +1 -1
  56. package/fesm2022/sd-angular-core-utilities-models.mjs.map +1 -1
  57. package/forms/datetime/src/datetime-time-zone.adapter.d.ts +15 -0
  58. package/forms/models/src/sd-strict-date-adapter.d.ts +3 -0
  59. package/package.json +10 -6
  60. package/pipes/src/time-different.pipe.d.ts +1 -0
  61. package/services/date-time/index.d.ts +1 -0
  62. package/services/date-time/src/date-time.service.d.ts +54 -0
  63. package/services/date-time/src/public-api.d.ts +1 -0
  64. package/services/index.d.ts +1 -0
  65. package/utilities/extensions/src/string.extension.d.ts +1 -0
  66. package/utilities/models/src/icon.model.d.ts +2 -0
@@ -20,6 +20,7 @@ import { SdLabel } from '@sd-angular/core/forms/label';
20
20
  import { SD_FORM_CONFIGURATION, sdFormControlState, sdViewedTransform, sdViewedInline, SdFormControl, SdInlineErrorValidator, provideSdStrictDateFnsAdapter } from '@sd-angular/core/forms/models';
21
21
  import { sdIsEmpty, sdSerializeDataValue } from '@sd-angular/core/utilities/data-state';
22
22
  import { I18nService } from '@sd-angular/core/i18n';
23
+ import { SdDateTimeService } from '@sd-angular/core/services/date-time';
23
24
  import { DateUtilities } from '@sd-angular/core/utilities/extensions';
24
25
  import { Utilities, BrowserUtilities } from '@sdcorejs/utils/fns';
25
26
  import { parse, isValid } from 'date-fns';
@@ -95,6 +96,8 @@ class SdDate {
95
96
  ref = inject(ChangeDetectorRef);
96
97
  formConfig = inject(SD_FORM_CONFIGURATION, { optional: true });
97
98
  #i18n = inject(I18nService);
99
+ // why: model values cross into the calendar day of ISdCoreConfiguration.timeZone here and nowhere else.
100
+ #dateTime = inject(SdDateTimeService);
98
101
  // ==========================================
99
102
  // 3. SIGNAL INPUTS & MODEL
100
103
  // ==========================================
@@ -216,7 +219,7 @@ class SdDate {
216
219
  if (!DateUtilities.isDate(val)) {
217
220
  val = null;
218
221
  }
219
- val = DateUtilities.toFormat(val, 'yyyy/MM/dd');
222
+ val = this.#dateTime.toFormat(val, 'yyyy/MM/dd');
220
223
  if (this.#date !== val) {
221
224
  this.#date = val;
222
225
  const dateObj = DateUtilities.isDate(this.#date)
@@ -262,6 +265,13 @@ class SdDate {
262
265
  }
263
266
  // Hàm private tái sử dụng cho parse Min/Max Date
264
267
  #parseDateBoundary(val) {
268
+ // why: under a zone the bound becomes a carrier of the zone's calendar day; local mode keeps its native parse.
269
+ if (this.#dateTime.timeZone !== 'local') {
270
+ if (val === 'TODAY')
271
+ return this.#dateTime.today();
272
+ const day = val && DateUtilities.isDate(val) ? this.#dateTime.toFormat(val, 'yyyy/MM/dd') : '';
273
+ return day ? parse(day, 'yyyy/MM/dd', new Date()) : null;
274
+ }
265
275
  if (val === 'TODAY')
266
276
  return new Date();
267
277
  if (val && DateUtilities.isDate(val))
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-forms-date.mjs","sources":["../../../projects/sd-angular/forms/date/src/date-input.util.ts","../../../projects/sd-angular/forms/date/src/date.component.ts","../../../projects/sd-angular/forms/date/src/date.component.html","../../../projects/sd-angular/forms/date/sd-angular-core-forms-date.ts"],"sourcesContent":["import { DateUtilities } from '@sd-angular/core/utilities/extensions';\nimport { isValid as isValidDate, parse as parseDate } from 'date-fns';\n\nexport const DATE_DISPLAY_FORMAT = 'dd/MM/yyyy';\nexport const DATE_DISPLAY_PATTERN = /^\\d{2}\\/\\d{2}\\/\\d{4}$/;\nexport const DATE_INPUT_MAX_DIGITS = 8;\n\n/** Chèn `/` vào chuỗi số người dùng đang gõ: `22081991` → `22/08/1991`. */\nexport function formatDateInput(value: string, addTrailingSeparator: boolean): string {\n const digits = value.replace(/\\D/g, '').slice(0, DATE_INPUT_MAX_DIGITS);\n let formatted = digits.slice(0, 2);\n\n if (digits.length > 2) formatted += `/${digits.slice(2, 4)}`;\n if (digits.length > 4) formatted += `/${digits.slice(4)}`;\n if (addTrailingSeparator && (digits.length === 2 || digits.length === 4)) formatted += '/';\n\n return formatted;\n}\n\n/** Chuỗi còn dở dang (đang gõ) — chưa đủ `dd/MM/yyyy` nhưng vẫn đúng khuôn. */\nexport function isPartialDateInput(value: string): boolean {\n return /^(?:\\d{0,2})(?:\\/\\d{0,2})?(?:\\/\\d{0,4})?$/.test(value);\n}\n\n/**\n * Chỉ nhận đúng `dd/MM/yyyy` ĐẦY ĐỦ và có thật trên lịch.\n *\n * WHY chặt tay như vậy: `date-fns.parse(value, 'dd/MM/yyyy')` rất dễ dãi — nó\n * nhận cả năm thiếu chữ số, nên `11/12/2` ra năm 0002 còn `11/12/20` ra năm\n * 0020. Nếu để lọt, người dùng mới gõ nửa chừng đã bị coi là nhập xong.\n */\nexport function parseDateInput(value: string): Date | null {\n if (!DATE_DISPLAY_PATTERN.test(value)) return null;\n\n const parsed = parseDate(value, DATE_DISPLAY_FORMAT, new Date());\n return isValidDate(parsed) && DateUtilities.toFormat(parsed, DATE_DISPLAY_FORMAT) === value ? parsed : null;\n}\n\n/** Giữ con trỏ đứng đúng chỗ sau khi chuỗi được chèn thêm `/`. */\nexport function getCaretPosition(value: string, selectionStart: number, formattedValue: string, addTrailingSeparator: boolean): number {\n const digitsBeforeCaret = value.slice(0, selectionStart).replace(/\\D/g, '').length;\n let formattedIndex = 0;\n let digitCount = 0;\n\n while (formattedIndex < formattedValue.length && digitCount < digitsBeforeCaret) {\n if (/\\d/.test(formattedValue[formattedIndex])) digitCount++;\n formattedIndex++;\n }\n\n if (addTrailingSeparator && digitCount === digitsBeforeCaret && formattedValue[formattedIndex] === '/') formattedIndex++;\n return formattedIndex;\n}\n\nexport function dateControlsEqual(left: Date | null, right: Date | null): boolean {\n return (\n left === right || (!!left && !!right && DateUtilities.toFormat(left, 'yyyy/MM/dd') === DateUtilities.toFormat(right, 'yyyy/MM/dd'))\n );\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @angular-eslint/no-input-rename */\nimport { CommonModule } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n inject,\n input,\n model,\n computed,\n effect,\n untracked,\n OnDestroy,\n OnInit,\n output,\n TemplateRef,\n viewChild,\n contentChild\n} from '@angular/core';\nimport { FormGroup, FormsModule, NgForm, ReactiveFormsModule, ValidatorFn, Validators } from '@angular/forms';\nimport { MAT_DATE_LOCALE } from '@angular/material/core';\nimport { MatDatepicker, MatDatepickerInputEvent, MatDatepickerModule } from '@angular/material/datepicker';\nimport { FloatLabelType, MatFormFieldAppearance, MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { SdView } from '@sd-angular/core/components/view';\nimport { SdLabelDefDirective, SdViewDefDirective } from '@sd-angular/core/forms/directives';\nimport { SdLabel } from '@sd-angular/core/forms/label';\nimport { ISdFormConfiguration, SD_FORM_CONFIGURATION, SdFormControl, SdInlineErrorValidator,\n provideSdStrictDateFnsAdapter, SdViewed, SdViewedInput, sdViewedInline, sdViewedTransform } from '@sd-angular/core/forms/models';\nimport { sdSerializeDataValue, sdIsEmpty } from '@sd-angular/core/utilities/data-state';\nimport { sdFormControlState } from '@sd-angular/core/forms/models';\nimport { I18nService } from '@sd-angular/core/i18n';\nimport { Size } from '@sdcorejs/utils/models';\nimport { DateUtilities } from '@sd-angular/core/utilities/extensions';\nimport { BrowserUtilities, Utilities } from '@sdcorejs/utils/fns';\nimport { parse as parseDate } from 'date-fns';\nimport { enUS as dfEnUS } from 'date-fns/locale';\nimport { Subscription } from 'rxjs';\n\nimport {\n DATE_DISPLAY_FORMAT,\n dateControlsEqual,\n formatDateInput,\n getCaretPosition,\n isPartialDateInput,\n parseDateInput,\n} from './date-input.util';\n\ntype SdDateKeyupEvent = Event | { target?: { value?: string | null } };\n\n@Component({\n selector: 'sd-date',\n templateUrl: './date.component.html',\n styleUrl: './date.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class.sd-bare]': 'isInline()', '[class.sd-viewed]': 'isViewed() || isInline()', '[class.sd-has-label]': '!!label()' },\n providers: [\n // DateFnsAdapter inject MAT_DATE_LOCALE; nếu undefined sẽ throw khi format/parse.\n // Provide locale en-US tại scope component để hành vi giống Moment cũ (English default).\n { provide: MAT_DATE_LOCALE, useValue: dfEnUS },\n // Adapter parse chặt: Material parse lại ô nhập sau mỗi phím gõ, adapter mặc\n // định nhận cả chuỗi dở dang nên `11/12/2` từng thành năm 0002.\n provideSdStrictDateFnsAdapter({\n parse: { dateInput: DATE_DISPLAY_FORMAT },\n display: {\n dateInput: DATE_DISPLAY_FORMAT,\n monthYearLabel: 'MMM yyyy',\n dateA11yLabel: 'PP',\n monthYearA11yLabel: 'MMMM yyyy',\n },\n }),\n ],\n standalone: true,\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n MatInputModule,\n MatIconModule,\n MatTooltipModule,\n MatFormFieldModule,\n MatDatepickerModule,\n SdLabel,\n SdView\n ],\n})\nexport class SdDate implements OnDestroy, OnInit {\n id = `I${Utilities.generateUuid()}`;\n\n // ==========================================\n // 1. SIGNAL QUERIES\n // ==========================================\n inputRef = viewChild<ElementRef<HTMLInputElement>>('input');\n datePicker = viewChild<MatDatepicker<Date>>(MatDatepicker);\n\n sdLabelTemplate = contentChild<TemplateRef<any>>('sdLabel');\n sdValueTemplate = contentChild<TemplateRef<any>>('sdValue');\n sdViewDef = contentChild(SdViewDefDirective);\n sdLabelDef = contentChild(SdLabelDefDirective);\n\n // ==========================================\n // 2. INJECTS\n // ==========================================\n private ref = inject(ChangeDetectorRef);\n private formConfig = inject(SD_FORM_CONFIGURATION, { optional: true });\n readonly #i18n = inject(I18nService);\n\n // ==========================================\n // 3. SIGNAL INPUTS & MODEL\n // ==========================================\n autoIdInput = input<string | undefined | null>(undefined, { alias: 'autoId' });\n autoId = computed(() => this.autoIdInput() ? `forms-date-${this.autoIdInput()}` : undefined);\n\n readonly #state = sdFormControlState(computed(() => this.formControl));\n readonly dataDisabled = computed(() => (this.#state().disabled ? 'true' : 'false'));\n readonly dataInvalid = computed(() => (this.#state().invalid ? 'true' : 'false'));\n readonly dataEmpty = computed(() => (sdIsEmpty(this.#state().value) ? 'true' : 'false'));\n readonly dataValue = computed(() => sdSerializeDataValue(this.#state().value));\n\n readonly dataRequired = computed(() => (this.required() ? 'true' : 'false'));\n readonly dataErrorMessage = computed(() => {\n void this.#state();\n const msg = this.errorMessage();\n return msg && msg.length > 0 ? msg : null;\n });\n\n name = input<string>(Utilities.generateUuid());\n\n size = input<Size>('md');\n // Ghi (TransformT): any (để không bị lỗi typing khi cha truyền vào)\n form = input<FormGroup | undefined, any>(undefined, {\n transform: (val: any): FormGroup | undefined => {\n if (!val) return undefined;\n // Nếu cha truyền vào NgForm (template-driven) -> Bóc lấy FormGroup bên trong\n if (val instanceof NgForm) return val.form;\n // Nếu cha truyền sẵn FormGroup (reactive) -> Lấy luôn\n if (val instanceof FormGroup) return val;\n // Fallback an toàn phòng trường hợp cha truyền 1 object chứa form\n if (val?.form instanceof FormGroup) return val.form;\n return undefined;\n },\n });\n label = input<string | undefined>();\n helperText = input<string | undefined>();\n placeholder = input<string | undefined>();\n \n hideInlineError = input(false, { transform: booleanAttribute });\n required = input(false, { transform: booleanAttribute });\n disabled = input(false, { transform: booleanAttribute });\n /** Display mode: `false` edit · `true` static view · `'inline'` view + click-to-edit (calendar). */\n viewed = input<SdViewed, SdViewedInput>(false, { transform: sdViewedTransform });\n /** In `viewed='inline'`, show a hover clear-× on the text face. Set `false` when the host owns removal (chips). */\n clearable = input(false, { transform: booleanAttribute });\n\n // Tri-state `viewed` — shared primitive. In `'inline'` the calendar editor is always mounted\n // (chrome hidden via CSS); the sd-view text face opens the calendar on click.\n readonly #viewedState = sdViewedInline(this.viewed, () => this.open(), this.disabled);\n /** `true` when `viewed === 'inline'`. */\n readonly isInline = this.#viewedState.isInline;\n /** `true` when `viewed === true` (static view, no editor). */\n readonly isViewed = this.#viewedState.isViewed;\n /** Open the calendar from the inline text face. No-op unless `viewed='inline'`. */\n enterInlineEdit = (): void => this.#viewedState.enterInlineEdit();\n /** View display template: `sdViewDef` overrides the projected `#sdValue` (unified). */\n readonly viewTemplate = computed<TemplateRef<any> | undefined>(() => this.sdViewDef()?.templateRef ?? this.sdValueTemplate());\n\n inlineError = input<string | undefined>();\n\n /**\n * Tổng hợp error message để hiển thị trong tooltip khi hideInlineError = true.\n */\n readonly errorMessage = computed<string | undefined>(() => {\n void this.#state();\n const errors = this.formControl.errors;\n if (!errors) return undefined;\n\n if (errors['required']) return this.#i18n.t('core.form.date.required');\n if (errors['matDatepickerMin']) { const d = this.resolvedMin(); return this.#i18n.t('core.form.date.min-date', { date: d ? new Date(d).toLocaleDateString('vi-VN') : '' }); }\n if (errors['matDatepickerMax']) { const d = this.resolvedMax(); return this.#i18n.t('core.form.date.max-date', { date: d ? new Date(d).toLocaleDateString('vi-VN') : '' }); }\n if (errors['matDatetimePickerParse']) return this.#i18n.t('core.form.date.parse-error', { text: errors['matDatetimePickerParse']?.text ?? '' });\n if (errors['date']) return errors['date'] as string;\n if (errors['customValidator']) return errors['customValidator'] as string;\n if (errors['inlineError']) return this.inlineError();\n return undefined;\n });\n\n hyperlink = input<string | null | undefined>();\n\n appearanceInput = input<MatFormFieldAppearance | undefined>(undefined, { alias: 'appearance' });\n appearance = computed(() => this.appearanceInput() ?? this.formConfig?.appearance ?? 'outline');\n\n floatLabel = input<FloatLabelType>('auto');\n\n // Xử lý thông minh Gom min/minDate và max/maxDate\n minInput = input<any>(undefined, { alias: 'min' });\n minDateInput = input<any>(undefined, { alias: 'minDate' });\n resolvedMin = computed(() => this.#parseDateBoundary(this.minInput() ?? this.minDateInput()));\n\n maxInput = input<any>(undefined, { alias: 'max' });\n maxDateInput = input<any>(undefined, { alias: 'maxDate' });\n resolvedMax = computed(() => this.#parseDateBoundary(this.maxInput() ?? this.maxDateInput()));\n\n valueModel = model<string | number | Date | undefined | null>(undefined, { alias: 'model' });\n\n // ==========================================\n // 4. SIGNAL OUTPUTS\n // ==========================================\n sdChange = output<any>();\n sdFocus = output<void>();\n\n // ==========================================\n // 5. INTERNAL STATE & STREAMS\n // ==========================================\n isMobileOrTablet = BrowserUtilities.isMobile();\n formControl = new SdFormControl();\n isFocused = false;\n isValid?: boolean;\n #hasInvalidInput = false;\n \n #date: string | undefined | null;\n #subscription = new Subscription();\n\n constructor() {\n // EFFECT 1: Sync model thay đổi từ bên ngoài (String/Date -> Date)\n // Material date-fns adapter dùng native Date làm internal type cho FormControl.\n effect(() => {\n let val = this.valueModel();\n untracked(() => {\n if (!DateUtilities.isDate(val)) {\n val = null;\n }\n val = DateUtilities.toFormat(val, 'yyyy/MM/dd');\n if (this.#date !== val) {\n this.#date = val;\n const dateObj = DateUtilities.isDate(this.#date)\n ? parseDate(DateUtilities.toFormat(this.#date, 'yyyy/MM/dd'), 'yyyy/MM/dd', new Date())\n : null;\n this.formControl.setValue(dateObj, { emitEvent: false });\n }\n });\n });\n\n // EFFECT 2: Sync Disable\n effect(() => {\n if (this.disabled()) this.formControl.disable({ emitEvent: false });\n else this.formControl.enable({ emitEvent: false });\n });\n\n // EFFECT 3: Update Validators\n effect(() => {\n const req = this.required();\n const inl = this.inlineError();\n\n untracked(() => {\n const validators: ValidatorFn[] = [];\n if (req) validators.push(Validators.required);\n if (inl) validators.push(SdInlineErrorValidator);\n \n this.formControl.setValidators(validators.length ? validators : null);\n this.formControl.updateValueAndValidity({ emitEvent: false });\n });\n });\n }\n\n ngOnInit() {\n this.#subscription.add(\n this.formControl.sdChanges.subscribe(() => {\n this.ref.markForCheck();\n })\n );\n const formGroup = this.form();\n formGroup?.addControl(this.name(), this.formControl);\n }\n\n ngOnDestroy() {\n const formGroup = this.form();\n formGroup?.removeControl(this.name());\n this.#subscription.unsubscribe();\n }\n\n // Hàm private tái sử dụng cho parse Min/Max Date\n #parseDateBoundary(val: any): Date | null {\n if (val === 'TODAY') return new Date();\n if (val && DateUtilities.isDate(val)) return new Date(val);\n return null;\n }\n\n onFocus = () => {\n this.isFocused = true;\n this.sdFocus.emit();\n };\n\n onBlur = () => {\n this.isFocused = false;\n\n const input = this.inputRef()?.nativeElement;\n const displayValue = input?.value ?? '';\n const parsedValue = this.#hasInvalidInput ? null : parseDateInput(displayValue);\n\n this.formControl.markAsTouched();\n this.isValid = false;\n this.#setDateError(false);\n this.#hasInvalidInput = false;\n\n if (parsedValue) {\n this.#setDateValue(parsedValue);\n return;\n }\n\n if (input && displayValue) input.value = '';\n this.#setDateValue(null);\n };\n\n onClick = () => {\n if (this.sdViewDef()?.templateRef) {\n if (!this.formControl.disabled && !this.isFocused) {\n this.focus();\n }\n }\n };\n\n blur = () => {\n this.inputRef()?.nativeElement?.blur();\n };\n\n focus = () => {\n this.isFocused = true;\n setTimeout(() => {\n this.inputRef()?.nativeElement?.focus();\n this.datePicker()?.open();\n }, 100);\n };\n\n /** Open the datepicker calendar programmatically (anchors to the field input). */\n open = () => {\n if (this.formControl.disabled) return;\n this.datePicker()?.open();\n };\n\n focusInputElement() {\n this.inputRef()?.nativeElement?.focus();\n }\n\n onKeyDown = (event: KeyboardEvent) => {\n const key = event.keyCode || event.charCode;\n const isShift = key === 16;\n\n if (event.ctrlKey && (key === 67 || key === 86)) return true;\n\n if (\n ((key >= 48 && key <= 57) ||\n key === 8 ||\n key <= 37 ||\n key <= 39 ||\n (key >= 96 && key <= 105) ||\n key === 191 ||\n key === 186 ||\n key === 59) &&\n !isShift\n ) {\n return true;\n }\n return false;\n };\n\n onInput = (event: Event) => {\n const input = event.target as HTMLInputElement | null;\n if (!input) return;\n\n const rawValue = input.value;\n const inputType = (event as InputEvent).inputType;\n const isDeleting = inputType?.startsWith('delete') ?? false;\n const addTrailingSeparator = !isDeleting;\n const hasInvalidCharacters = /[^\\d/]/.test(rawValue);\n const selectionStart = input.selectionStart ?? rawValue.length;\n const formattedValue = formatDateInput(rawValue, addTrailingSeparator);\n\n if (formattedValue !== rawValue) {\n input.value = formattedValue;\n const caretPosition = getCaretPosition(rawValue, selectionStart, formattedValue, addTrailingSeparator);\n input.setSelectionRange?.(caretPosition, caretPosition);\n }\n\n this.#hasInvalidInput = hasInvalidCharacters;\n this.#validateDateInput(formattedValue, hasInvalidCharacters);\n };\n\n /** Kept as a compatibility entry point for callers that used the old keyup handler. */\n onKeyup = (event: SdDateKeyupEvent) => {\n const target = event.target as { value?: string | null } | null | undefined;\n const value = target?.value ?? '';\n this.#validateDateInput(value, /[^\\d/]/.test(value));\n };\n\n #validateDateInput(value: string, hasInvalidCharacters: boolean): void {\n const parsedValue = parseDateInput(value);\n const invalid = !!value && (hasInvalidCharacters || (!parsedValue && !isPartialDateInput(value)));\n\n this.isValid = !!value && !parsedValue;\n if (invalid) {\n this.formControl.markAsDirty();\n this.#setDateError(true);\n } else {\n this.#setDateError(false);\n }\n }\n\n #setDateError(invalid: boolean): void {\n const errors = { ...(this.formControl.errors ?? {}) };\n if (invalid) errors['date'] = this.#i18n.t('core.form.date.invalid-format');\n else delete errors['date'];\n\n this.formControl.setErrors(Object.keys(errors).length > 0 ? errors : null);\n }\n\n #setDateValue(value: Date | null): void {\n const normalizedValue = value ? DateUtilities.toFormat(value, 'yyyy/MM/dd') : null;\n const modelChanged = this.#date !== normalizedValue;\n\n this.#date = normalizedValue;\n this.isValid = false;\n this.#setDateError(false);\n\n if (!dateControlsEqual(this.formControl.value as Date | null, value)) this.formControl.setValue(value);\n if (modelChanged) {\n this.valueModel.set(normalizedValue);\n this.sdChange.emit(normalizedValue);\n }\n }\n\n onChange = (event: MatDatepickerInputEvent<Date>) => {\n // event.value giờ là native Date (date-fns adapter), không cần .toDate() như Moment.\n this.inputRef()?.nativeElement?.focus();\n this.#hasInvalidInput = false;\n this.#setDateValue(event.value ?? null);\n };\n\n clear = ($event: any) => {\n $event?.stopPropagation();\n if (this.formControl.value) {\n this.#setDateValue(null);\n }\n };\n}\n","@let _label = label();\n@let _appearance = appearance();\n@let _hideInlineError = hideInlineError();\n@let _errorMessage = errorMessage();\n@let _helperText = helperText();\n@let _required = required();\n@let _isInline = isInline();\n@let _bare = _isInline;\n@let _hasValue = !!formControl.value;\n\n@let _resolvedMin = resolvedMin();\n@let _resolvedMax = resolvedMax();\n\n@if (isViewed()) {\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"formControl.value\"\n [display]=\"formControl.value | date: 'dd/MM/yyyy'\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\">\n </sd-view>\n} @else {\n @if (_isInline) {\n <!-- why: inline — sd-view là \"mặt\" + trigger; calendar editor render ẩn (.sd-inline-editor) chỉ để mở panel. -->\n <span class=\"sd-inline-view\" role=\"button\" tabindex=\"0\" (click)=\"enterInlineEdit()\" (keydown.enter)=\"enterInlineEdit()\">\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"formControl.value\"\n [display]=\"formControl.value | date: 'dd/MM/yyyy'\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\">\n </sd-view>\n @if (clearable() && _hasValue && !_required && !formControl.disabled) {\n <button type=\"button\" class=\"sd-inline-clear\" (click)=\"clear($event)\" title=\"Xóa\" aria-label=\"Xóa\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </span>\n }\n @if (!_appearance) {\n <ng-content select=\"[sdLabel]\">\n @if (_label) {\n <sd-label [label]=\"_label\" [required]=\"_required\"></sd-label>\n }\n </ng-content>\n }\n\n <div\n class=\"d-flex align-items-center\"\n [class.sd-inline-editor]=\"_isInline\"\n [class.c-focused]=\"isFocused\"\n [class.c-disabled]=\"formControl.disabled\"\n (click)=\"onClick()\"\n aria-hidden=\"true\">\n <mat-form-field\n class=\"c-form-field-date-input\"\n [class.sd-md]=\"size() === 'md'\"\n [class.sd-sm]=\"size() === 'sm'\"\n [class.hide-inline-error]=\"_hideInlineError\"\n [appearance]=\"_appearance!\"\n [floatLabel]=\"floatLabel()\">\n @if (_appearance && _label) {\n <mat-label style=\"display: inline-block\">\n <div style=\"display: flex; align-items: center; gap: 4px\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <mat-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\">info_outline</mat-icon>\n }\n </div>\n </mat-label>\n }\n\n <input\n aria-hidden=\"true\"\n [id]=\"id\"\n matInput\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (dateChange)=\"onChange($event)\"\n [autocomplete]=\"id\"\n autocorrect=\"off\"\n [formControl]=\"formControl\"\n [required]=\"_required\"\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeholder() || _label || ''\"\n [min]=\"_resolvedMin\"\n [max]=\"_resolvedMax\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-invalid]=\"dataInvalid()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n #input\n [maxLength]=\"10\" />\n\n <mat-datepicker #picker [touchUi]=\"isMobileOrTablet\"></mat-datepicker>\n\n @if (_hideInlineError && _errorMessage && formControl.touched) {\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\"> error </mat-icon>\n }\n\n @if (!_hideInlineError && _errorMessage && formControl.touched) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n @if (formControl.value && !_required && !formControl.disabled && !_bare) {\n <button\n type=\"button\"\n class=\"sd-clear-btn sd-hover\"\n matSuffix\n (click)=\"clear($event)\"\n title=\"Xóa\"\n aria-label=\"Xóa\">\n <mat-icon>close</mat-icon>\n </button>\n }\n\n <mat-icon fontSet=\"material-icons-outlined\" class=\"cursor-pointer sd-suffix-icon\" (click)=\"!formControl.disabled && picker.open()\" #btn matSuffix>today</mat-icon>\n </mat-form-field>\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["parseDate","isValidDate","dfEnUS"],"mappings":"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"}
1
+ {"version":3,"file":"sd-angular-core-forms-date.mjs","sources":["../../../projects/sd-angular/forms/date/src/date-input.util.ts","../../../projects/sd-angular/forms/date/src/date.component.ts","../../../projects/sd-angular/forms/date/src/date.component.html","../../../projects/sd-angular/forms/date/sd-angular-core-forms-date.ts"],"sourcesContent":["import { DateUtilities } from '@sd-angular/core/utilities/extensions';\nimport { isValid as isValidDate, parse as parseDate } from 'date-fns';\n\nexport const DATE_DISPLAY_FORMAT = 'dd/MM/yyyy';\nexport const DATE_DISPLAY_PATTERN = /^\\d{2}\\/\\d{2}\\/\\d{4}$/;\nexport const DATE_INPUT_MAX_DIGITS = 8;\n\n/** Chèn `/` vào chuỗi số người dùng đang gõ: `22081991` → `22/08/1991`. */\nexport function formatDateInput(value: string, addTrailingSeparator: boolean): string {\n const digits = value.replace(/\\D/g, '').slice(0, DATE_INPUT_MAX_DIGITS);\n let formatted = digits.slice(0, 2);\n\n if (digits.length > 2) formatted += `/${digits.slice(2, 4)}`;\n if (digits.length > 4) formatted += `/${digits.slice(4)}`;\n if (addTrailingSeparator && (digits.length === 2 || digits.length === 4)) formatted += '/';\n\n return formatted;\n}\n\n/** Chuỗi còn dở dang (đang gõ) — chưa đủ `dd/MM/yyyy` nhưng vẫn đúng khuôn. */\nexport function isPartialDateInput(value: string): boolean {\n return /^(?:\\d{0,2})(?:\\/\\d{0,2})?(?:\\/\\d{0,4})?$/.test(value);\n}\n\n/**\n * Chỉ nhận đúng `dd/MM/yyyy` ĐẦY ĐỦ và có thật trên lịch.\n *\n * WHY chặt tay như vậy: `date-fns.parse(value, 'dd/MM/yyyy')` rất dễ dãi — nó\n * nhận cả năm thiếu chữ số, nên `11/12/2` ra năm 0002 còn `11/12/20` ra năm\n * 0020. Nếu để lọt, người dùng mới gõ nửa chừng đã bị coi là nhập xong.\n */\nexport function parseDateInput(value: string): Date | null {\n if (!DATE_DISPLAY_PATTERN.test(value)) return null;\n\n const parsed = parseDate(value, DATE_DISPLAY_FORMAT, new Date());\n return isValidDate(parsed) && DateUtilities.toFormat(parsed, DATE_DISPLAY_FORMAT) === value ? parsed : null;\n}\n\n/** Giữ con trỏ đứng đúng chỗ sau khi chuỗi được chèn thêm `/`. */\nexport function getCaretPosition(value: string, selectionStart: number, formattedValue: string, addTrailingSeparator: boolean): number {\n const digitsBeforeCaret = value.slice(0, selectionStart).replace(/\\D/g, '').length;\n let formattedIndex = 0;\n let digitCount = 0;\n\n while (formattedIndex < formattedValue.length && digitCount < digitsBeforeCaret) {\n if (/\\d/.test(formattedValue[formattedIndex])) digitCount++;\n formattedIndex++;\n }\n\n if (addTrailingSeparator && digitCount === digitsBeforeCaret && formattedValue[formattedIndex] === '/') formattedIndex++;\n return formattedIndex;\n}\n\nexport function dateControlsEqual(left: Date | null, right: Date | null): boolean {\n return (\n left === right || (!!left && !!right && DateUtilities.toFormat(left, 'yyyy/MM/dd') === DateUtilities.toFormat(right, 'yyyy/MM/dd'))\n );\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @angular-eslint/no-input-rename */\nimport { CommonModule } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n inject,\n input,\n model,\n computed,\n effect,\n untracked,\n OnDestroy,\n OnInit,\n output,\n TemplateRef,\n viewChild,\n contentChild\n} from '@angular/core';\nimport { FormGroup, FormsModule, NgForm, ReactiveFormsModule, ValidatorFn, Validators } from '@angular/forms';\nimport { MAT_DATE_LOCALE } from '@angular/material/core';\nimport { MatDatepicker, MatDatepickerInputEvent, MatDatepickerModule } from '@angular/material/datepicker';\nimport { FloatLabelType, MatFormFieldAppearance, MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { SdView } from '@sd-angular/core/components/view';\nimport { SdLabelDefDirective, SdViewDefDirective } from '@sd-angular/core/forms/directives';\nimport { SdLabel } from '@sd-angular/core/forms/label';\nimport { ISdFormConfiguration, SD_FORM_CONFIGURATION, SdFormControl, SdInlineErrorValidator,\n provideSdStrictDateFnsAdapter, SdViewed, SdViewedInput, sdViewedInline, sdViewedTransform } from '@sd-angular/core/forms/models';\nimport { sdSerializeDataValue, sdIsEmpty } from '@sd-angular/core/utilities/data-state';\nimport { sdFormControlState } from '@sd-angular/core/forms/models';\nimport { I18nService } from '@sd-angular/core/i18n';\nimport { SdDateTimeService } from '@sd-angular/core/services/date-time';\nimport { Size } from '@sdcorejs/utils/models';\nimport { DateUtilities } from '@sd-angular/core/utilities/extensions';\nimport { BrowserUtilities, Utilities } from '@sdcorejs/utils/fns';\nimport { parse as parseDate } from 'date-fns';\nimport { enUS as dfEnUS } from 'date-fns/locale';\nimport { Subscription } from 'rxjs';\n\nimport {\n DATE_DISPLAY_FORMAT,\n dateControlsEqual,\n formatDateInput,\n getCaretPosition,\n isPartialDateInput,\n parseDateInput,\n} from './date-input.util';\n\ntype SdDateKeyupEvent = Event | { target?: { value?: string | null } };\n\n@Component({\n selector: 'sd-date',\n templateUrl: './date.component.html',\n styleUrl: './date.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class.sd-bare]': 'isInline()', '[class.sd-viewed]': 'isViewed() || isInline()', '[class.sd-has-label]': '!!label()' },\n providers: [\n // DateFnsAdapter inject MAT_DATE_LOCALE; nếu undefined sẽ throw khi format/parse.\n // Provide locale en-US tại scope component để hành vi giống Moment cũ (English default).\n { provide: MAT_DATE_LOCALE, useValue: dfEnUS },\n // Adapter parse chặt: Material parse lại ô nhập sau mỗi phím gõ, adapter mặc\n // định nhận cả chuỗi dở dang nên `11/12/2` từng thành năm 0002.\n provideSdStrictDateFnsAdapter({\n parse: { dateInput: DATE_DISPLAY_FORMAT },\n display: {\n dateInput: DATE_DISPLAY_FORMAT,\n monthYearLabel: 'MMM yyyy',\n dateA11yLabel: 'PP',\n monthYearA11yLabel: 'MMMM yyyy',\n },\n }),\n ],\n standalone: true,\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n MatInputModule,\n MatIconModule,\n MatTooltipModule,\n MatFormFieldModule,\n MatDatepickerModule,\n SdLabel,\n SdView\n ],\n})\nexport class SdDate implements OnDestroy, OnInit {\n id = `I${Utilities.generateUuid()}`;\n\n // ==========================================\n // 1. SIGNAL QUERIES\n // ==========================================\n inputRef = viewChild<ElementRef<HTMLInputElement>>('input');\n datePicker = viewChild<MatDatepicker<Date>>(MatDatepicker);\n\n sdLabelTemplate = contentChild<TemplateRef<any>>('sdLabel');\n sdValueTemplate = contentChild<TemplateRef<any>>('sdValue');\n sdViewDef = contentChild(SdViewDefDirective);\n sdLabelDef = contentChild(SdLabelDefDirective);\n\n // ==========================================\n // 2. INJECTS\n // ==========================================\n private ref = inject(ChangeDetectorRef);\n private formConfig = inject(SD_FORM_CONFIGURATION, { optional: true });\n readonly #i18n = inject(I18nService);\n // why: model values cross into the calendar day of ISdCoreConfiguration.timeZone here and nowhere else.\n readonly #dateTime = inject(SdDateTimeService);\n\n // ==========================================\n // 3. SIGNAL INPUTS & MODEL\n // ==========================================\n autoIdInput = input<string | undefined | null>(undefined, { alias: 'autoId' });\n autoId = computed(() => this.autoIdInput() ? `forms-date-${this.autoIdInput()}` : undefined);\n\n readonly #state = sdFormControlState(computed(() => this.formControl));\n readonly dataDisabled = computed(() => (this.#state().disabled ? 'true' : 'false'));\n readonly dataInvalid = computed(() => (this.#state().invalid ? 'true' : 'false'));\n readonly dataEmpty = computed(() => (sdIsEmpty(this.#state().value) ? 'true' : 'false'));\n readonly dataValue = computed(() => sdSerializeDataValue(this.#state().value));\n\n readonly dataRequired = computed(() => (this.required() ? 'true' : 'false'));\n readonly dataErrorMessage = computed(() => {\n void this.#state();\n const msg = this.errorMessage();\n return msg && msg.length > 0 ? msg : null;\n });\n\n name = input<string>(Utilities.generateUuid());\n\n size = input<Size>('md');\n // Ghi (TransformT): any (để không bị lỗi typing khi cha truyền vào)\n form = input<FormGroup | undefined, any>(undefined, {\n transform: (val: any): FormGroup | undefined => {\n if (!val) return undefined;\n // Nếu cha truyền vào NgForm (template-driven) -> Bóc lấy FormGroup bên trong\n if (val instanceof NgForm) return val.form;\n // Nếu cha truyền sẵn FormGroup (reactive) -> Lấy luôn\n if (val instanceof FormGroup) return val;\n // Fallback an toàn phòng trường hợp cha truyền 1 object chứa form\n if (val?.form instanceof FormGroup) return val.form;\n return undefined;\n },\n });\n label = input<string | undefined>();\n helperText = input<string | undefined>();\n placeholder = input<string | undefined>();\n \n hideInlineError = input(false, { transform: booleanAttribute });\n required = input(false, { transform: booleanAttribute });\n disabled = input(false, { transform: booleanAttribute });\n /** Display mode: `false` edit · `true` static view · `'inline'` view + click-to-edit (calendar). */\n viewed = input<SdViewed, SdViewedInput>(false, { transform: sdViewedTransform });\n /** In `viewed='inline'`, show a hover clear-× on the text face. Set `false` when the host owns removal (chips). */\n clearable = input(false, { transform: booleanAttribute });\n\n // Tri-state `viewed` — shared primitive. In `'inline'` the calendar editor is always mounted\n // (chrome hidden via CSS); the sd-view text face opens the calendar on click.\n readonly #viewedState = sdViewedInline(this.viewed, () => this.open(), this.disabled);\n /** `true` when `viewed === 'inline'`. */\n readonly isInline = this.#viewedState.isInline;\n /** `true` when `viewed === true` (static view, no editor). */\n readonly isViewed = this.#viewedState.isViewed;\n /** Open the calendar from the inline text face. No-op unless `viewed='inline'`. */\n enterInlineEdit = (): void => this.#viewedState.enterInlineEdit();\n /** View display template: `sdViewDef` overrides the projected `#sdValue` (unified). */\n readonly viewTemplate = computed<TemplateRef<any> | undefined>(() => this.sdViewDef()?.templateRef ?? this.sdValueTemplate());\n\n inlineError = input<string | undefined>();\n\n /**\n * Tổng hợp error message để hiển thị trong tooltip khi hideInlineError = true.\n */\n readonly errorMessage = computed<string | undefined>(() => {\n void this.#state();\n const errors = this.formControl.errors;\n if (!errors) return undefined;\n\n if (errors['required']) return this.#i18n.t('core.form.date.required');\n if (errors['matDatepickerMin']) { const d = this.resolvedMin(); return this.#i18n.t('core.form.date.min-date', { date: d ? new Date(d).toLocaleDateString('vi-VN') : '' }); }\n if (errors['matDatepickerMax']) { const d = this.resolvedMax(); return this.#i18n.t('core.form.date.max-date', { date: d ? new Date(d).toLocaleDateString('vi-VN') : '' }); }\n if (errors['matDatetimePickerParse']) return this.#i18n.t('core.form.date.parse-error', { text: errors['matDatetimePickerParse']?.text ?? '' });\n if (errors['date']) return errors['date'] as string;\n if (errors['customValidator']) return errors['customValidator'] as string;\n if (errors['inlineError']) return this.inlineError();\n return undefined;\n });\n\n hyperlink = input<string | null | undefined>();\n\n appearanceInput = input<MatFormFieldAppearance | undefined>(undefined, { alias: 'appearance' });\n appearance = computed(() => this.appearanceInput() ?? this.formConfig?.appearance ?? 'outline');\n\n floatLabel = input<FloatLabelType>('auto');\n\n // Xử lý thông minh Gom min/minDate và max/maxDate\n minInput = input<any>(undefined, { alias: 'min' });\n minDateInput = input<any>(undefined, { alias: 'minDate' });\n resolvedMin = computed(() => this.#parseDateBoundary(this.minInput() ?? this.minDateInput()));\n\n maxInput = input<any>(undefined, { alias: 'max' });\n maxDateInput = input<any>(undefined, { alias: 'maxDate' });\n resolvedMax = computed(() => this.#parseDateBoundary(this.maxInput() ?? this.maxDateInput()));\n\n valueModel = model<string | number | Date | undefined | null>(undefined, { alias: 'model' });\n\n // ==========================================\n // 4. SIGNAL OUTPUTS\n // ==========================================\n sdChange = output<any>();\n sdFocus = output<void>();\n\n // ==========================================\n // 5. INTERNAL STATE & STREAMS\n // ==========================================\n isMobileOrTablet = BrowserUtilities.isMobile();\n formControl = new SdFormControl();\n isFocused = false;\n isValid?: boolean;\n #hasInvalidInput = false;\n \n #date: string | undefined | null;\n #subscription = new Subscription();\n\n constructor() {\n // EFFECT 1: Sync model thay đổi từ bên ngoài (String/Date -> Date)\n // Material date-fns adapter dùng native Date làm internal type cho FormControl.\n effect(() => {\n let val = this.valueModel();\n untracked(() => {\n if (!DateUtilities.isDate(val)) {\n val = null;\n }\n val = this.#dateTime.toFormat(val, 'yyyy/MM/dd');\n if (this.#date !== val) {\n this.#date = val;\n const dateObj = DateUtilities.isDate(this.#date)\n ? parseDate(DateUtilities.toFormat(this.#date, 'yyyy/MM/dd'), 'yyyy/MM/dd', new Date())\n : null;\n this.formControl.setValue(dateObj, { emitEvent: false });\n }\n });\n });\n\n // EFFECT 2: Sync Disable\n effect(() => {\n if (this.disabled()) this.formControl.disable({ emitEvent: false });\n else this.formControl.enable({ emitEvent: false });\n });\n\n // EFFECT 3: Update Validators\n effect(() => {\n const req = this.required();\n const inl = this.inlineError();\n\n untracked(() => {\n const validators: ValidatorFn[] = [];\n if (req) validators.push(Validators.required);\n if (inl) validators.push(SdInlineErrorValidator);\n \n this.formControl.setValidators(validators.length ? validators : null);\n this.formControl.updateValueAndValidity({ emitEvent: false });\n });\n });\n }\n\n ngOnInit() {\n this.#subscription.add(\n this.formControl.sdChanges.subscribe(() => {\n this.ref.markForCheck();\n })\n );\n const formGroup = this.form();\n formGroup?.addControl(this.name(), this.formControl);\n }\n\n ngOnDestroy() {\n const formGroup = this.form();\n formGroup?.removeControl(this.name());\n this.#subscription.unsubscribe();\n }\n\n // Hàm private tái sử dụng cho parse Min/Max Date\n #parseDateBoundary(val: any): Date | null {\n // why: under a zone the bound becomes a carrier of the zone's calendar day; local mode keeps its native parse.\n if (this.#dateTime.timeZone !== 'local') {\n if (val === 'TODAY') return this.#dateTime.today();\n const day = val && DateUtilities.isDate(val) ? this.#dateTime.toFormat(val, 'yyyy/MM/dd') : '';\n return day ? parseDate(day, 'yyyy/MM/dd', new Date()) : null;\n }\n if (val === 'TODAY') return new Date();\n if (val && DateUtilities.isDate(val)) return new Date(val);\n return null;\n }\n\n onFocus = () => {\n this.isFocused = true;\n this.sdFocus.emit();\n };\n\n onBlur = () => {\n this.isFocused = false;\n\n const input = this.inputRef()?.nativeElement;\n const displayValue = input?.value ?? '';\n const parsedValue = this.#hasInvalidInput ? null : parseDateInput(displayValue);\n\n this.formControl.markAsTouched();\n this.isValid = false;\n this.#setDateError(false);\n this.#hasInvalidInput = false;\n\n if (parsedValue) {\n this.#setDateValue(parsedValue);\n return;\n }\n\n if (input && displayValue) input.value = '';\n this.#setDateValue(null);\n };\n\n onClick = () => {\n if (this.sdViewDef()?.templateRef) {\n if (!this.formControl.disabled && !this.isFocused) {\n this.focus();\n }\n }\n };\n\n blur = () => {\n this.inputRef()?.nativeElement?.blur();\n };\n\n focus = () => {\n this.isFocused = true;\n setTimeout(() => {\n this.inputRef()?.nativeElement?.focus();\n this.datePicker()?.open();\n }, 100);\n };\n\n /** Open the datepicker calendar programmatically (anchors to the field input). */\n open = () => {\n if (this.formControl.disabled) return;\n this.datePicker()?.open();\n };\n\n focusInputElement() {\n this.inputRef()?.nativeElement?.focus();\n }\n\n onKeyDown = (event: KeyboardEvent) => {\n const key = event.keyCode || event.charCode;\n const isShift = key === 16;\n\n if (event.ctrlKey && (key === 67 || key === 86)) return true;\n\n if (\n ((key >= 48 && key <= 57) ||\n key === 8 ||\n key <= 37 ||\n key <= 39 ||\n (key >= 96 && key <= 105) ||\n key === 191 ||\n key === 186 ||\n key === 59) &&\n !isShift\n ) {\n return true;\n }\n return false;\n };\n\n onInput = (event: Event) => {\n const input = event.target as HTMLInputElement | null;\n if (!input) return;\n\n const rawValue = input.value;\n const inputType = (event as InputEvent).inputType;\n const isDeleting = inputType?.startsWith('delete') ?? false;\n const addTrailingSeparator = !isDeleting;\n const hasInvalidCharacters = /[^\\d/]/.test(rawValue);\n const selectionStart = input.selectionStart ?? rawValue.length;\n const formattedValue = formatDateInput(rawValue, addTrailingSeparator);\n\n if (formattedValue !== rawValue) {\n input.value = formattedValue;\n const caretPosition = getCaretPosition(rawValue, selectionStart, formattedValue, addTrailingSeparator);\n input.setSelectionRange?.(caretPosition, caretPosition);\n }\n\n this.#hasInvalidInput = hasInvalidCharacters;\n this.#validateDateInput(formattedValue, hasInvalidCharacters);\n };\n\n /** Kept as a compatibility entry point for callers that used the old keyup handler. */\n onKeyup = (event: SdDateKeyupEvent) => {\n const target = event.target as { value?: string | null } | null | undefined;\n const value = target?.value ?? '';\n this.#validateDateInput(value, /[^\\d/]/.test(value));\n };\n\n #validateDateInput(value: string, hasInvalidCharacters: boolean): void {\n const parsedValue = parseDateInput(value);\n const invalid = !!value && (hasInvalidCharacters || (!parsedValue && !isPartialDateInput(value)));\n\n this.isValid = !!value && !parsedValue;\n if (invalid) {\n this.formControl.markAsDirty();\n this.#setDateError(true);\n } else {\n this.#setDateError(false);\n }\n }\n\n #setDateError(invalid: boolean): void {\n const errors = { ...(this.formControl.errors ?? {}) };\n if (invalid) errors['date'] = this.#i18n.t('core.form.date.invalid-format');\n else delete errors['date'];\n\n this.formControl.setErrors(Object.keys(errors).length > 0 ? errors : null);\n }\n\n #setDateValue(value: Date | null): void {\n const normalizedValue = value ? DateUtilities.toFormat(value, 'yyyy/MM/dd') : null;\n const modelChanged = this.#date !== normalizedValue;\n\n this.#date = normalizedValue;\n this.isValid = false;\n this.#setDateError(false);\n\n if (!dateControlsEqual(this.formControl.value as Date | null, value)) this.formControl.setValue(value);\n if (modelChanged) {\n this.valueModel.set(normalizedValue);\n this.sdChange.emit(normalizedValue);\n }\n }\n\n onChange = (event: MatDatepickerInputEvent<Date>) => {\n // event.value giờ là native Date (date-fns adapter), không cần .toDate() như Moment.\n this.inputRef()?.nativeElement?.focus();\n this.#hasInvalidInput = false;\n this.#setDateValue(event.value ?? null);\n };\n\n clear = ($event: any) => {\n $event?.stopPropagation();\n if (this.formControl.value) {\n this.#setDateValue(null);\n }\n };\n}\n","@let _label = label();\n@let _appearance = appearance();\n@let _hideInlineError = hideInlineError();\n@let _errorMessage = errorMessage();\n@let _helperText = helperText();\n@let _required = required();\n@let _isInline = isInline();\n@let _bare = _isInline;\n@let _hasValue = !!formControl.value;\n\n@let _resolvedMin = resolvedMin();\n@let _resolvedMax = resolvedMax();\n\n@if (isViewed()) {\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"formControl.value\"\n [display]=\"formControl.value | date: 'dd/MM/yyyy'\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\">\n </sd-view>\n} @else {\n @if (_isInline) {\n <!-- why: inline — sd-view là \"mặt\" + trigger; calendar editor render ẩn (.sd-inline-editor) chỉ để mở panel. -->\n <span class=\"sd-inline-view\" role=\"button\" tabindex=\"0\" (click)=\"enterInlineEdit()\" (keydown.enter)=\"enterInlineEdit()\">\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"formControl.value\"\n [display]=\"formControl.value | date: 'dd/MM/yyyy'\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\">\n </sd-view>\n @if (clearable() && _hasValue && !_required && !formControl.disabled) {\n <button type=\"button\" class=\"sd-inline-clear\" (click)=\"clear($event)\" title=\"Xóa\" aria-label=\"Xóa\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </span>\n }\n @if (!_appearance) {\n <ng-content select=\"[sdLabel]\">\n @if (_label) {\n <sd-label [label]=\"_label\" [required]=\"_required\"></sd-label>\n }\n </ng-content>\n }\n\n <div\n class=\"d-flex align-items-center\"\n [class.sd-inline-editor]=\"_isInline\"\n [class.c-focused]=\"isFocused\"\n [class.c-disabled]=\"formControl.disabled\"\n (click)=\"onClick()\"\n aria-hidden=\"true\">\n <mat-form-field\n class=\"c-form-field-date-input\"\n [class.sd-md]=\"size() === 'md'\"\n [class.sd-sm]=\"size() === 'sm'\"\n [class.hide-inline-error]=\"_hideInlineError\"\n [appearance]=\"_appearance!\"\n [floatLabel]=\"floatLabel()\">\n @if (_appearance && _label) {\n <mat-label style=\"display: inline-block\">\n <div style=\"display: flex; align-items: center; gap: 4px\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <mat-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\">info_outline</mat-icon>\n }\n </div>\n </mat-label>\n }\n\n <input\n aria-hidden=\"true\"\n [id]=\"id\"\n matInput\n (input)=\"onInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n (dateChange)=\"onChange($event)\"\n [autocomplete]=\"id\"\n autocorrect=\"off\"\n [formControl]=\"formControl\"\n [required]=\"_required\"\n [matDatepicker]=\"picker\"\n [placeholder]=\"placeholder() || _label || ''\"\n [min]=\"_resolvedMin\"\n [max]=\"_resolvedMax\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-invalid]=\"dataInvalid()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n #input\n [maxLength]=\"10\" />\n\n <mat-datepicker #picker [touchUi]=\"isMobileOrTablet\"></mat-datepicker>\n\n @if (_hideInlineError && _errorMessage && formControl.touched) {\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\"> error </mat-icon>\n }\n\n @if (!_hideInlineError && _errorMessage && formControl.touched) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n @if (formControl.value && !_required && !formControl.disabled && !_bare) {\n <button\n type=\"button\"\n class=\"sd-clear-btn sd-hover\"\n matSuffix\n (click)=\"clear($event)\"\n title=\"Xóa\"\n aria-label=\"Xóa\">\n <mat-icon>close</mat-icon>\n </button>\n }\n\n <mat-icon fontSet=\"material-icons-outlined\" class=\"cursor-pointer sd-suffix-icon\" (click)=\"!formControl.disabled && picker.open()\" #btn matSuffix>today</mat-icon>\n </mat-form-field>\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["parseDate","isValidDate","dfEnUS"],"mappings":"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"}
@@ -3,11 +3,11 @@ import { ComponentPortal } from '@angular/cdk/portal';
3
3
  import * as i1$1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i0 from '@angular/core';
6
- import { model, input, booleanAttribute, ChangeDetectionStrategy, Component, EventEmitter, signal, Output, viewChild, contentChild, inject, ChangeDetectorRef, ElementRef, Injector, computed, output, effect, untracked } from '@angular/core';
6
+ import { Injectable, model, input, booleanAttribute, ChangeDetectionStrategy, Component, EventEmitter, inject, signal, Output, viewChild, contentChild, 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 { provideDateFnsAdapter } from '@angular/material-date-fns-adapter';
10
- import { MAT_DATE_LOCALE } from '@angular/material/core';
9
+ import { DateFnsAdapter, provideDateFnsAdapter } from '@angular/material-date-fns-adapter';
10
+ import { MAT_DATE_LOCALE, DateAdapter } from '@angular/material/core';
11
11
  import { MatFormFieldModule } from '@angular/material/form-field';
12
12
  import * as i4 from '@angular/material/icon';
13
13
  import { MatIconModule } from '@angular/material/icon';
@@ -21,6 +21,7 @@ import { SdLabel } from '@sd-angular/core/forms/label';
21
21
  import { SD_FORM_CONFIGURATION, sdFormControlState, sdViewedTransform, sdViewedInline, SdFormControl, SdInlineErrorValidator } from '@sd-angular/core/forms/models';
22
22
  import { sdIsEmpty, sdSerializeDataValue } from '@sd-angular/core/utilities/data-state';
23
23
  import { TranslatePipe, I18nService } from '@sd-angular/core/i18n';
24
+ import { ɵsdInjectDateTime as _sdInjectDateTime, SdDateTimeService } from '@sd-angular/core/services/date-time';
24
25
  import { DateUtilities } from '@sd-angular/core/utilities/extensions';
25
26
  import { Utilities, BrowserUtilities } from '@sdcorejs/utils/fns';
26
27
  import { isValid, parse } from 'date-fns';
@@ -30,6 +31,25 @@ import { MatButtonModule } from '@angular/material/button';
30
31
  import * as i1 from '@angular/material/datepicker';
31
32
  import { MatDatepickerModule } from '@angular/material/datepicker';
32
33
 
34
+ /**
35
+ * `DateFnsAdapter` whose `today()` follows `ISdCoreConfiguration.timeZone`.
36
+ *
37
+ * The calendar of the sd-datetime popup marks today and opens on `today()`; a datetime carries a
38
+ * time, so this returns the current wall clock in the zone (not 00:00), like the popup's Now
39
+ * button. Without a zone it is the base adapter unchanged.
40
+ */
41
+ class SdDatetimeTimeZoneAdapter extends DateFnsAdapter {
42
+ #dateTime = _sdInjectDateTime();
43
+ today() {
44
+ return this.#dateTime && this.#dateTime.timeZone !== 'local' ? this.#dateTime.now() : super.today();
45
+ }
46
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdDatetimeTimeZoneAdapter, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
47
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdDatetimeTimeZoneAdapter });
48
+ }
49
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdDatetimeTimeZoneAdapter, decorators: [{
50
+ type: Injectable
51
+ }] });
52
+
33
53
  /**
34
54
  * Time spinner — UI chọn giờ/phút/(giây) compact, modern.
35
55
  *
@@ -228,8 +248,10 @@ class SdDatetimePicker {
228
248
  // ==========================================
229
249
  // STATE — signals nội bộ
230
250
  // ==========================================
251
+ // why: "bây giờ" là đồng hồ của ISdCoreConfiguration.timeZone (vật mang local), không phải của trình duyệt.
252
+ #dateTime = inject(SdDateTimeService);
231
253
  // date-fns là immutable — luôn cấp Date mới, không mutate.
232
- selectedDate = signal(new Date());
254
+ selectedDate = signal(this.#dateTime.now());
233
255
  hours = signal(0);
234
256
  minutes = signal(0);
235
257
  seconds = signal(0);
@@ -241,7 +263,7 @@ class SdDatetimePicker {
241
263
  #hydrateFromInput() {
242
264
  const init = this.initialValue();
243
265
  // Clone bằng new Date(getTime()) để không chia sẻ reference với caller.
244
- const d = init instanceof Date && isValid(init) ? new Date(init.getTime()) : new Date();
266
+ const d = init instanceof Date && isValid(init) ? new Date(init.getTime()) : this.#dateTime.now();
245
267
  this.selectedDate.set(d);
246
268
  this.hours.set(d.getHours());
247
269
  this.minutes.set(d.getMinutes());
@@ -275,7 +297,7 @@ class SdDatetimePicker {
275
297
  onNow() {
276
298
  if (this.disabled())
277
299
  return;
278
- const now = new Date();
300
+ const now = this.#dateTime.now();
279
301
  this.selectedDate.set(now);
280
302
  this.hours.set(now.getHours());
281
303
  this.minutes.set(now.getMinutes());
@@ -359,6 +381,8 @@ class SdDatetime {
359
381
  injector = inject(Injector);
360
382
  formConfig = inject(SD_FORM_CONFIGURATION, { optional: true });
361
383
  #i18n = inject(I18nService);
384
+ // why: model values cross into the wall-clock carrier of ISdCoreConfiguration.timeZone here and nowhere else.
385
+ #dateTime = inject(SdDateTimeService);
362
386
  // ==========================================
363
387
  // 3. SIGNAL INPUTS & MODEL
364
388
  // ==========================================
@@ -462,7 +486,7 @@ class SdDatetime {
462
486
  const v = this.valueModel();
463
487
  if (v == null || !DateUtilities.isDate(v))
464
488
  return null;
465
- const iso = DateUtilities.toFormat(v, 'yyyy/MM/dd HH:mm:ss');
489
+ const iso = this.#dateTime.toFormat(v, 'yyyy/MM/dd HH:mm:ss');
466
490
  if (!iso)
467
491
  return null;
468
492
  const d = parse(iso, 'yyyy/MM/dd HH:mm:ss', new Date());
@@ -493,7 +517,7 @@ class SdDatetime {
493
517
  if (!DateUtilities.isDate(val)) {
494
518
  val = null;
495
519
  }
496
- val = DateUtilities.toFormat(val, 'yyyy/MM/dd HH:mm');
520
+ val = this.#dateTime.toFormat(val, 'yyyy/MM/dd HH:mm');
497
521
  if (this.#date !== val) {
498
522
  this.#date = val;
499
523
  // Cập nhật formControl với chuỗi hiển thị dd/MM/yyyy HH:mm
@@ -614,7 +638,7 @@ class SdDatetime {
614
638
  const v = this.valueModel();
615
639
  if (!v || !DateUtilities.isDate(v))
616
640
  return null;
617
- const fmtted = DateUtilities.toFormat(v, 'yyyy/MM/dd HH:mm:ss');
641
+ const fmtted = this.#dateTime.toFormat(v, 'yyyy/MM/dd HH:mm:ss');
618
642
  if (!fmtted)
619
643
  return null;
620
644
  const parsed = parse(fmtted, 'yyyy/MM/dd HH:mm:ss', new Date());
@@ -624,6 +648,12 @@ class SdDatetime {
624
648
  // 7. PARSE/VALIDATE HELPERS
625
649
  // ==========================================
626
650
  #parseDateBoundary(val) {
651
+ // why: under a zone the bound becomes a carrier of the zone's wall clock; local mode keeps its native parse.
652
+ if (this.#dateTime.timeZone !== 'local') {
653
+ if (val === 'TODAY')
654
+ return this.#dateTime.now();
655
+ return val && DateUtilities.isDate(val) ? this.#dateTime.toWallClock(val) : null;
656
+ }
627
657
  if (val === 'TODAY')
628
658
  return new Date();
629
659
  if (val && DateUtilities.isDate(val))
@@ -730,6 +760,8 @@ class SdDatetime {
730
760
  // DateFnsAdapter inject MAT_DATE_LOCALE; cấp default en-US để parse/format hoạt động.
731
761
  { provide: MAT_DATE_LOCALE, useValue: enUS },
732
762
  provideDateFnsAdapter(SD_DATETIME_FORMATS),
763
+ // Phải đứng SAU provideDateFnsAdapter: lịch của popup lấy "hôm nay" theo ISdCoreConfiguration.timeZone.
764
+ { provide: DateAdapter, useClass: SdDatetimeTimeZoneAdapter },
733
765
  ], 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 _label = label();\n@let _appearance = appearance();\n@let _hideInlineError = hideInlineError();\n@let _errorMessage = errorMessage();\n@let _helperText = helperText();\n@let _required = required();\n@let _isInline = isInline();\n@let _bare = _isInline;\n@let _hasValue = !!formControl.value;\n\n@let _resolvedMin = resolvedMin();\n@let _resolvedMax = resolvedMax();\n\n@let _viewedDate = viewedDate();\n@if (isViewed()) {\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"_viewedDate\"\n [display]=\"_viewedDate | date: (showSeconds() ? 'dd/MM/yyyy HH:mm:ss' : 'dd/MM/yyyy HH:mm')\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\">\n </sd-view>\n} @else {\n @if (_isInline) {\n <!-- why: inline \u2014 sd-view l\u00E0 \"m\u1EB7t\" + trigger; datetime editor render \u1EA9n (.sd-inline-editor) ch\u1EC9 \u0111\u1EC3 m\u1EDF overlay. -->\n <span class=\"sd-inline-view\" role=\"button\" tabindex=\"0\" (click)=\"enterInlineEdit()\" (keydown.enter)=\"enterInlineEdit()\">\n <sd-view\n [label]=\"_label\"\n [labelTemplate]=\"sdLabelTemplate()\"\n [value]=\"_viewedDate\"\n [display]=\"_viewedDate | date: (showSeconds() ? 'dd/MM/yyyy HH:mm:ss' : 'dd/MM/yyyy HH:mm')\"\n [hyperlink]=\"hyperlink()\"\n [valueTemplate]=\"viewTemplate()\">\n </sd-view>\n @if (clearable() && _hasValue && !_required && !formControl.disabled) {\n <button type=\"button\" class=\"sd-inline-clear\" (click)=\"clear($event)\" title=\"X\u00F3a\" aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </span>\n }\n @if (!_appearance) {\n <ng-content select=\"[sdLabel]\">\n @if (_label) {\n <sd-label [label]=\"_label\" [required]=\"_required\"></sd-label>\n }\n </ng-content>\n }\n\n <div\n class=\"d-flex align-items-center\"\n [class.sd-inline-editor]=\"_isInline\"\n [class.c-focused]=\"isFocused\"\n [class.c-disabled]=\"formControl.disabled\"\n (click)=\"onClick()\"\n aria-hidden=\"true\">\n <mat-form-field\n class=\"c-form-field-datetime-input\"\n [class.sd-md]=\"size() === 'md'\"\n [class.sd-sm]=\"size() === 'sm'\"\n [class.hide-inline-error]=\"_hideInlineError\"\n [appearance]=\"_appearance || 'outline'\"\n [floatLabel]=\"floatLabel()\">\n @if (_appearance && _label) {\n <mat-label style=\"display: inline-block\">\n <div class=\"d-flex align-items-center gap-4\">\n <span>{{ _label }}</span>\n @if (_helperText) {\n <mat-icon [matTooltip]=\"_helperText\" matTooltipPosition=\"below\">info_outline</mat-icon>\n }\n </div>\n </mat-label>\n }\n\n <input\n aria-hidden=\"true\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-invalid]=\"dataInvalid()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.data-error-message]=\"dataErrorMessage()\"\n [id]=\"id\"\n (blur)=\"onConfirmInput($event)\"\n (keyup.enter)=\"onConfirmInput($event)\"\n (keydown)=\"onKeyDown($event)\"\n [autocomplete]=\"id\"\n autocorrect=\"off\"\n [formControl]=\"formControl\"\n [required]=\"_required\"\n [placeholder]=\"placeholder() || _label || ''\"\n [min]=\"_resolvedMin\"\n [max]=\"_resolvedMax\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n #input\n matInput />\n\n @if (_hideInlineError && _errorMessage && formControl.touched) {\n <mat-icon matSuffix class=\"sd-error-icon\" [matTooltip]=\"_errorMessage\" matTooltipPosition=\"above\"> error </mat-icon>\n }\n\n @if (!_hideInlineError && _errorMessage && formControl.touched) {\n <mat-error>{{ _errorMessage }}</mat-error>\n }\n\n @if (formControl.value && !_required && !formControl.disabled && !_bare) {\n <button\n type=\"button\"\n class=\"sd-clear-btn sd-hover\"\n matSuffix\n (click)=\"clear($event)\"\n title=\"X\u00F3a\"\n aria-label=\"X\u00F3a\">\n <mat-icon>close</mat-icon>\n </button>\n }\n\n <mat-icon\n class=\"cursor-pointer sd-suffix-icon\"\n fontSet=\"material-icons-outlined\"\n (click)=\"!formControl.disabled && open()\"\n matSuffix>today</mat-icon>\n </mat-form-field>\n </div>\n}\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-light{color:var(--sd-light)!important}.bg-light{background:var(--sd-light)!important}.border-light{border-color:var(--sd-light)!important}.text-dark{color:var(--sd-dark)!important}.bg-dark{background:var(--sd-dark)!important}.border-dark{border-color:var(--sd-dark)!important}.text-black500{color:var(--sd-black500)!important}.bg-black500{background:var(--sd-black500)!important}.border-black500{border-color:var(--sd-black500)!important}.text-black400{color:var(--sd-black400)!important}.bg-black400{background:var(--sd-black400)!important}.border-black400{border-color:var(--sd-black400)!important}.text-black300{color:var(--sd-black300)!important}.bg-black300{background:var(--sd-black300)!important}.border-black300{border-color:var(--sd-black300)!important}.text-black200{color:var(--sd-black200)!important}.bg-black200{background:var(--sd-black200)!important}.border-black200{border-color:var(--sd-black200)!important}.text-black100{color:var(--sd-black100)!important}.bg-black100{background:var(--sd-black100)!important}.border-black100{border-color:var(--sd-black100)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}:host{display:block}:host(.sd-has-label){padding-top:4px}:host(.sd-viewed){padding-top:0}:host ::ng-deep .mat-mdc-form-field.mat-form-field-appearance-outline.mat-form-field-disabled .mat-mdc-text-field-wrapper{background:var(--sd-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)}:host(.sd-bare){position:relative}.sd-inline-view{cursor:pointer;display:inline-flex;align-items:center;width:100%;padding:1px 6px;border-radius:4px;background-color:#0000000a;transition:background-color .15s ease}.sd-inline-view:hover{background-color:#00000014}.sd-inline-view .sd-inline-clear{display:none;align-items:center;margin-left:4px;padding:0;border:0;background:transparent;cursor:pointer;line-height:0;color:var(--sd-text-secondary, #6b7280);transition:color .15s ease}.sd-inline-view .sd-inline-clear mat-icon{font-size:16px;width:16px;height:16px}.sd-inline-view .sd-inline-clear:hover{color:var(--sd-error, #b32626)}.sd-inline-view:hover .sd-inline-clear{display:inline-flex}.sd-inline-editor{position:absolute;inset:0;opacity:0;pointer-events:none}.sd-inline-editor ::ng-deep *{pointer-events:none!important}:host(.sd-bare){display:inline-flex;align-items:center}:host(.sd-bare) ::ng-deep .mat-mdc-form-field{width:auto}:host(.sd-bare) ::ng-deep .mat-mdc-text-field-wrapper{padding:0;background:transparent}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-flex{padding:0;align-items:center}:host(.sd-bare) ::ng-deep .mdc-notched-outline{display:none}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}:host(.sd-bare) ::ng-deep .mat-mdc-form-field-infix{padding:0;min-height:0;width:auto;border:0;display:inline-flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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", "selectedItems"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
734
766
  }
735
767
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdDatetime, decorators: [{
@@ -738,6 +770,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
738
770
  // DateFnsAdapter inject MAT_DATE_LOCALE; cấp default en-US để parse/format hoạt động.
739
771
  { provide: MAT_DATE_LOCALE, useValue: enUS },
740
772
  provideDateFnsAdapter(SD_DATETIME_FORMATS),
773
+ // Phải đứng SAU provideDateFnsAdapter: lịch của popup lấy "hôm nay" theo ISdCoreConfiguration.timeZone.
774
+ { provide: DateAdapter, useClass: SdDatetimeTimeZoneAdapter },
741
775
  ], standalone: true, imports: [
742
776
  CommonModule,
743
777
  FormsModule,