@sd-angular/core 19.0.0-beta.89 → 19.0.0-beta.91
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.
- package/assets/scss/README.md +524 -0
- package/assets/scss/core/bootstrap.scss +0 -125
- package/assets/scss/core/utilities/_base.scss +333 -0
- package/assets/scss/core/utilities/_border.scss +22 -0
- package/assets/scss/core/utilities/_display.scss +10 -0
- package/assets/scss/core/utilities/_elevation.scss +80 -0
- package/assets/scss/core/utilities/_flexbox.scss +54 -0
- package/assets/scss/core/utilities/_gap.scss +9 -0
- package/assets/scss/core/utilities/_grid.scss +142 -0
- package/assets/scss/core/utilities/_index.scss +17 -0
- package/assets/scss/core/utilities/_misc.scss +20 -0
- package/assets/scss/core/utilities/_overflow.scss +9 -0
- package/assets/scss/core/utilities/_position.scss +8 -0
- package/assets/scss/core/utilities/_sizing.scss +28 -0
- package/assets/scss/core/utilities/_spacing.scss +31 -0
- package/assets/scss/core/utilities/_typography.scss +99 -0
- package/assets/scss/sd-core.scss +4 -6
- package/components/anchor/index.d.ts +1 -2
- package/components/anchor/src/components/anchor-vertical/{anchor-list/anchor-list.component.d.ts → anchor-vertical-list.component.d.ts} +4 -4
- package/components/anchor/src/components/index.d.ts +1 -1
- package/components/anchor/src/index.d.ts +2 -0
- package/components/anchor/src/models/index.d.ts +1 -1
- package/components/anchor/src/models/{anchor.model.d.ts → sd-anchor.model.d.ts} +0 -5
- package/fesm2022/sd-angular-core-components-anchor.mjs +9 -9
- package/fesm2022/sd-angular-core-components-anchor.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-import-excel.mjs +2 -2
- package/fesm2022/sd-angular-core-components-import-excel.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-modal.mjs +2 -2
- package/fesm2022/sd-angular-core-components-modal.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-table.mjs +4 -4
- package/fesm2022/sd-angular-core-components-table.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-upload-file.mjs +4 -4
- package/fesm2022/sd-angular-core-components-upload-file.mjs.map +1 -1
- package/fesm2022/sd-angular-core-components-workflow.mjs +9 -9
- package/fesm2022/sd-angular-core-components-workflow.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs +2 -2
- package/fesm2022/sd-angular-core-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date-range.mjs +2 -2
- package/fesm2022/sd-angular-core-forms-date-range.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-date.mjs +2 -2
- package/fesm2022/sd-angular-core-forms-date.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-datetime.mjs +428 -70
- package/fesm2022/sd-angular-core-forms-datetime.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-input-number.mjs +13 -5
- package/fesm2022/sd-angular-core-forms-input-number.mjs.map +1 -1
- package/fesm2022/sd-angular-core-forms-select.mjs +2 -2
- package/fesm2022/sd-angular-core-forms-select.mjs.map +1 -1
- package/fesm2022/sd-angular-core-modules-layout.mjs +2 -2
- package/fesm2022/sd-angular-core-modules-layout.mjs.map +1 -1
- package/fesm2022/sd-angular-core-pipes.mjs +3 -4
- package/fesm2022/sd-angular-core-pipes.mjs.map +1 -1
- package/fesm2022/sd-angular-core-services-api.mjs +2 -1
- package/fesm2022/sd-angular-core-services-api.mjs.map +1 -1
- package/forms/datetime/src/datetime.component.d.ts +16 -6
- package/forms/datetime/src/popup/sd-datetime-picker.component.d.ts +38 -0
- package/forms/datetime/src/popup/sd-time-spinner.component.d.ts +41 -0
- package/forms/input-number/src/input-number.component.d.ts +2 -1
- package/package.json +52 -52
- package/pipes/src/format-number.pipe.d.ts +1 -1
- package/sd-angular-core-19.0.0-beta.91.tgz +0 -0
- package/services/api/src/api.model.d.ts +1 -0
- package/assets/img/1D UX System.zip +0 -0
- package/assets/img/Popup/Vector.png +0 -0
- package/assets/img/empty.png +0 -0
- package/assets/img/empty.svg +0 -27
- package/assets/img/file-types/eps/001-file.eps +0 -143
- package/assets/img/file-types/eps/002-file-1.eps +0 -136
- package/assets/img/file-types/eps/003-file-2.eps +0 -130
- package/assets/img/file-types/eps/004-file-3.eps +0 -127
- package/assets/img/file-types/eps/005-file-4.eps +0 -120
- package/assets/img/file-types/eps/006-file-5.eps +0 -133
- package/assets/img/file-types/eps/007-file-6.eps +0 -133
- package/assets/img/file-types/eps/008-file-7.eps +0 -144
- package/assets/img/file-types/eps/009-file-8.eps +0 -150
- package/assets/img/file-types/eps/010-file-9.eps +0 -155
- package/assets/img/file-types/eps/011-file-10.eps +0 -124
- package/assets/img/file-types/eps/012-file-11.eps +0 -147
- package/assets/img/file-types/eps/013-file-12.eps +0 -125
- package/assets/img/file-types/eps/014-file-13.eps +0 -129
- package/assets/img/file-types/eps/015-file-14.eps +0 -143
- package/assets/img/file-types/eps/016-file-15.eps +0 -130
- package/assets/img/file-types/eps/017-file-16.eps +0 -197
- package/assets/img/file-types/eps/018-file-17.eps +0 -146
- package/assets/img/file-types/eps/019-file-18.eps +0 -131
- package/assets/img/file-types/eps/020-file-19.eps +0 -137
- package/assets/img/file-types/eps/021-file-20.eps +0 -134
- package/assets/img/file-types/eps/022-file-21.eps +0 -130
- package/assets/img/file-types/eps/023-file-22.eps +0 -161
- package/assets/img/file-types/eps/024-file-23.eps +0 -144
- package/assets/img/file-types/eps/025-file-24.eps +0 -164
- package/assets/img/file-types/eps/026-file-25.eps +0 -135
- package/assets/img/file-types/eps/027-file-26.eps +0 -124
- package/assets/img/file-types/eps/028-file-27.eps +0 -120
- package/assets/img/file-types/eps/029-file-28.eps +0 -141
- package/assets/img/file-types/eps/030-file-29.eps +0 -130
- package/assets/img/file-types/eps/031-file-30.eps +0 -157
- package/assets/img/file-types/eps/032-file-31.eps +0 -139
- package/assets/img/file-types/eps/033-file-32.eps +0 -139
- package/assets/img/file-types/eps/034-file-33.eps +0 -189
- package/assets/img/file-types/eps/035-file-34.eps +0 -162
- package/assets/img/file-types/eps/036-file-35.eps +0 -142
- package/assets/img/file-types/eps/037-file-36.eps +0 -123
- package/assets/img/file-types/eps/038-file-37.eps +0 -127
- package/assets/img/file-types/eps/039-file-38.eps +0 -146
- package/assets/img/file-types/eps/040-file-39.eps +0 -126
- package/assets/img/file-types/eps/041-file-40.eps +0 -117
- package/assets/img/file-types/eps/042-file-41.eps +0 -156
- package/assets/img/file-types/eps/043-file-42.eps +0 -118
- package/assets/img/file-types/eps/044-file-43.eps +0 -172
- package/assets/img/file-types/eps/045-file-44.eps +0 -201
- package/assets/img/file-types/eps/046-file-45.eps +0 -94
- package/assets/img/file-types/eps/047-file-46.eps +0 -176
- package/assets/img/file-types/eps/048-file-47.eps +0 -238
- package/assets/img/file-types/eps/049-file-48.eps +0 -187
- package/assets/img/file-types/eps/050-file-49.eps +0 -137
- package/assets/img/file-types/license/license.pdf +0 -0
- package/assets/img/file-types/png/3ds.png +0 -0
- package/assets/img/file-types/png/ai.png +0 -0
- package/assets/img/file-types/png/asp.png +0 -0
- package/assets/img/file-types/png/avi.png +0 -0
- package/assets/img/file-types/png/bin.png +0 -0
- package/assets/img/file-types/png/com.png +0 -0
- package/assets/img/file-types/png/css.png +0 -0
- package/assets/img/file-types/png/csv.png +0 -0
- package/assets/img/file-types/png/dbf.png +0 -0
- package/assets/img/file-types/png/dll.png +0 -0
- package/assets/img/file-types/png/doc.png +0 -0
- package/assets/img/file-types/png/docx.png +0 -0
- package/assets/img/file-types/png/dwg.png +0 -0
- package/assets/img/file-types/png/eml.png +0 -0
- package/assets/img/file-types/png/eps.png +0 -0
- package/assets/img/file-types/png/exe.png +0 -0
- package/assets/img/file-types/png/file.png +0 -0
- package/assets/img/file-types/png/fla.png +0 -0
- package/assets/img/file-types/png/gif.png +0 -0
- package/assets/img/file-types/png/htm.png +0 -0
- package/assets/img/file-types/png/ico.png +0 -0
- package/assets/img/file-types/png/ini.png +0 -0
- package/assets/img/file-types/png/iso.png +0 -0
- package/assets/img/file-types/png/jar.png +0 -0
- package/assets/img/file-types/png/jpg.png +0 -0
- package/assets/img/file-types/png/js.png +0 -0
- package/assets/img/file-types/png/mkv.png +0 -0
- package/assets/img/file-types/png/mov.png +0 -0
- package/assets/img/file-types/png/mp3.png +0 -0
- package/assets/img/file-types/png/mp4.png +0 -0
- package/assets/img/file-types/png/nfo.png +0 -0
- package/assets/img/file-types/png/obj.png +0 -0
- package/assets/img/file-types/png/otf.png +0 -0
- package/assets/img/file-types/png/pdf.png +0 -0
- package/assets/img/file-types/png/pkg.png +0 -0
- package/assets/img/file-types/png/png.png +0 -0
- package/assets/img/file-types/png/ppt.png +0 -0
- package/assets/img/file-types/png/pptx.png +0 -0
- package/assets/img/file-types/png/psd.png +0 -0
- package/assets/img/file-types/png/rtf.png +0 -0
- package/assets/img/file-types/png/svg.png +0 -0
- package/assets/img/file-types/png/tiff.png +0 -0
- package/assets/img/file-types/png/ttf.png +0 -0
- package/assets/img/file-types/png/txt.png +0 -0
- package/assets/img/file-types/png/vcf.png +0 -0
- package/assets/img/file-types/png/wav.png +0 -0
- package/assets/img/file-types/png/wmv.png +0 -0
- package/assets/img/file-types/png/xls.png +0 -0
- package/assets/img/file-types/png/xlsx.png +0 -0
- package/assets/img/file-types/png/xml.png +0 -0
- package/assets/img/file-types/png/zip.png +0 -0
- package/assets/img/file-types/psd/001-file.psd +0 -0
- package/assets/img/file-types/psd/002-file-1.psd +0 -0
- package/assets/img/file-types/psd/003-file-2.psd +0 -0
- package/assets/img/file-types/psd/004-file-3.psd +0 -0
- package/assets/img/file-types/psd/005-file-4.psd +0 -0
- package/assets/img/file-types/psd/006-file-5.psd +0 -0
- package/assets/img/file-types/psd/007-file-6.psd +0 -0
- package/assets/img/file-types/psd/008-file-7.psd +0 -0
- package/assets/img/file-types/psd/009-file-8.psd +0 -0
- package/assets/img/file-types/psd/010-file-9.psd +0 -0
- package/assets/img/file-types/psd/011-file-10.psd +0 -0
- package/assets/img/file-types/psd/012-file-11.psd +0 -0
- package/assets/img/file-types/psd/013-file-12.psd +0 -0
- package/assets/img/file-types/psd/014-file-13.psd +0 -0
- package/assets/img/file-types/psd/015-file-14.psd +0 -0
- package/assets/img/file-types/psd/016-file-15.psd +0 -0
- package/assets/img/file-types/psd/017-file-16.psd +0 -0
- package/assets/img/file-types/psd/018-file-17.psd +0 -0
- package/assets/img/file-types/psd/019-file-18.psd +0 -0
- package/assets/img/file-types/psd/020-file-19.psd +0 -0
- package/assets/img/file-types/psd/021-file-20.psd +0 -0
- package/assets/img/file-types/psd/022-file-21.psd +0 -0
- package/assets/img/file-types/psd/023-file-22.psd +0 -0
- package/assets/img/file-types/psd/024-file-23.psd +0 -0
- package/assets/img/file-types/psd/025-file-24.psd +0 -0
- package/assets/img/file-types/psd/026-file-25.psd +0 -0
- package/assets/img/file-types/psd/027-file-26.psd +0 -0
- package/assets/img/file-types/psd/028-file-27.psd +0 -0
- package/assets/img/file-types/psd/029-file-28.psd +0 -0
- package/assets/img/file-types/psd/030-file-29.psd +0 -0
- package/assets/img/file-types/psd/031-file-30.psd +0 -0
- package/assets/img/file-types/psd/032-file-31.psd +0 -0
- package/assets/img/file-types/psd/033-file-32.psd +0 -0
- package/assets/img/file-types/psd/034-file-33.psd +0 -0
- package/assets/img/file-types/psd/035-file-34.psd +0 -0
- package/assets/img/file-types/psd/036-file-35.psd +0 -0
- package/assets/img/file-types/psd/037-file-36.psd +0 -0
- package/assets/img/file-types/psd/038-file-37.psd +0 -0
- package/assets/img/file-types/psd/039-file-38.psd +0 -0
- package/assets/img/file-types/psd/040-file-39.psd +0 -0
- package/assets/img/file-types/psd/041-file-40.psd +0 -0
- package/assets/img/file-types/psd/042-file-41.psd +0 -0
- package/assets/img/file-types/psd/043-file-42.psd +0 -0
- package/assets/img/file-types/psd/044-file-43.psd +0 -0
- package/assets/img/file-types/psd/045-file-44.psd +0 -0
- package/assets/img/file-types/psd/046-file-45.psd +0 -0
- package/assets/img/file-types/psd/047-file-46.psd +0 -0
- package/assets/img/file-types/psd/048-file-47.psd +0 -0
- package/assets/img/file-types/psd/049-file-48.psd +0 -0
- package/assets/img/file-types/psd/050-file-49.psd +0 -0
- package/assets/img/file-types/svg/001-file.svg +0 -1
- package/assets/img/file-types/svg/002-file-1.svg +0 -1
- package/assets/img/file-types/svg/003-file-2.svg +0 -1
- package/assets/img/file-types/svg/004-file-3.svg +0 -1
- package/assets/img/file-types/svg/005-file-4.svg +0 -1
- package/assets/img/file-types/svg/006-file-5.svg +0 -1
- package/assets/img/file-types/svg/007-file-6.svg +0 -1
- package/assets/img/file-types/svg/008-file-7.svg +0 -1
- package/assets/img/file-types/svg/009-file-8.svg +0 -1
- package/assets/img/file-types/svg/010-file-9.svg +0 -1
- package/assets/img/file-types/svg/011-file-10.svg +0 -1
- package/assets/img/file-types/svg/012-file-11.svg +0 -1
- package/assets/img/file-types/svg/013-file-12.svg +0 -1
- package/assets/img/file-types/svg/014-file-13.svg +0 -1
- package/assets/img/file-types/svg/015-file-14.svg +0 -1
- package/assets/img/file-types/svg/016-file-15.svg +0 -1
- package/assets/img/file-types/svg/017-file-16.svg +0 -1
- package/assets/img/file-types/svg/018-file-17.svg +0 -1
- package/assets/img/file-types/svg/019-file-18.svg +0 -1
- package/assets/img/file-types/svg/020-file-19.svg +0 -1
- package/assets/img/file-types/svg/021-file-20.svg +0 -1
- package/assets/img/file-types/svg/022-file-21.svg +0 -1
- package/assets/img/file-types/svg/023-file-22.svg +0 -1
- package/assets/img/file-types/svg/024-file-23.svg +0 -1
- package/assets/img/file-types/svg/025-file-24.svg +0 -1
- package/assets/img/file-types/svg/026-file-25.svg +0 -1
- package/assets/img/file-types/svg/027-file-26.svg +0 -1
- package/assets/img/file-types/svg/028-file-27.svg +0 -1
- package/assets/img/file-types/svg/029-file-28.svg +0 -1
- package/assets/img/file-types/svg/030-file-29.svg +0 -1
- package/assets/img/file-types/svg/031-file-30.svg +0 -1
- package/assets/img/file-types/svg/032-file-31.svg +0 -1
- package/assets/img/file-types/svg/033-file-32.svg +0 -1
- package/assets/img/file-types/svg/034-file-33.svg +0 -1
- package/assets/img/file-types/svg/035-file-34.svg +0 -1
- package/assets/img/file-types/svg/036-file-35.svg +0 -1
- package/assets/img/file-types/svg/037-file-36.svg +0 -1
- package/assets/img/file-types/svg/038-file-37.svg +0 -1
- package/assets/img/file-types/svg/039-file-38.svg +0 -1
- package/assets/img/file-types/svg/040-file-39.svg +0 -1
- package/assets/img/file-types/svg/041-file-40.svg +0 -1
- package/assets/img/file-types/svg/042-file-41.svg +0 -1
- package/assets/img/file-types/svg/043-file-42.svg +0 -1
- package/assets/img/file-types/svg/044-file-43.svg +0 -1
- package/assets/img/file-types/svg/045-file-44.svg +0 -1
- package/assets/img/file-types/svg/046-file-45.svg +0 -1
- package/assets/img/file-types/svg/047-file-46.svg +0 -1
- package/assets/img/file-types/svg/048-file-47.svg +0 -1
- package/assets/img/file-types/svg/049-file-48.svg +0 -1
- package/assets/img/file-types/svg/050-file-49.svg +0 -1
- package/assets/img/plus-search-zoom-white.png +0 -0
- package/assets/scss/core/cursor.scss +0 -3
- package/assets/scss/core/elevation.scss +0 -57
- package/assets/scss/core/grid.scss +0 -40
- package/assets/scss/core/print.scss +0 -47
- package/assets/scss/core/typography.scss +0 -121
- package/sd-angular-core-19.0.0-beta.89.tgz +0 -0
- /package/components/anchor/src/components/{main/main.component.d.ts → anchor/anchor.component.d.ts} +0 -0
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Overlay, OverlayConfig } from '@angular/cdk/overlay';
|
|
2
|
+
import { ComponentPortal } from '@angular/cdk/portal';
|
|
3
|
+
import * as i1$1 from '@angular/common';
|
|
2
4
|
import { CommonModule } from '@angular/common';
|
|
3
5
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { viewChild, contentChild, inject, ChangeDetectorRef,
|
|
6
|
+
import { model, input, booleanAttribute, ChangeDetectionStrategy, Component, EventEmitter, signal, Output, viewChild, contentChild, inject, ChangeDetectorRef, ElementRef, Injector, computed, output, effect, untracked } from '@angular/core';
|
|
5
7
|
import * as i2 from '@angular/forms';
|
|
6
8
|
import { NgForm, FormGroup, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
9
|
+
import { provideMomentDateAdapter } from '@angular/material-moment-adapter';
|
|
7
10
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
8
11
|
import * as i4 from '@angular/material/icon';
|
|
9
12
|
import { MatIconModule } from '@angular/material/icon';
|
|
@@ -11,9 +14,6 @@ import * as i3 from '@angular/material/input';
|
|
|
11
14
|
import { MatInputModule } from '@angular/material/input';
|
|
12
15
|
import * as i5 from '@angular/material/tooltip';
|
|
13
16
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
14
|
-
import { provideMomentDatetimeAdapter } from '@ng-matero/extensions-moment-adapter';
|
|
15
|
-
import * as i6 from '@ng-matero/extensions/datetimepicker';
|
|
16
|
-
import { MtxDatetimepicker, MtxDatetimepickerModule } from '@ng-matero/extensions/datetimepicker';
|
|
17
17
|
import { SdView } from '@sd-angular/core/components/view';
|
|
18
18
|
import { SdViewDefDirective } from '@sd-angular/core/forms/directives';
|
|
19
19
|
import { SdLabel } from '@sd-angular/core/forms/label';
|
|
@@ -22,16 +22,309 @@ import { SdUtilities, DateUtilities } from '@sd-angular/core/utilities/extension
|
|
|
22
22
|
import moment from 'moment';
|
|
23
23
|
import { Subscription } from 'rxjs';
|
|
24
24
|
import * as uuid from 'uuid';
|
|
25
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
26
|
+
import * as i1 from '@angular/material/datepicker';
|
|
27
|
+
import { MatDatepickerModule } from '@angular/material/datepicker';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Time spinner — UI chọn giờ/phút/(giây) compact, modern.
|
|
31
|
+
*
|
|
32
|
+
* - Format 24h
|
|
33
|
+
* - Mặc định hiển thị HH:MM, bật `showSeconds` để hiện thêm cột giây
|
|
34
|
+
* - Hỗ trợ: click ▲▼, gõ trực tiếp, lăn chuột, mũi tên bàn phím
|
|
35
|
+
* - Wrap vòng (23 → ▲ → 00)
|
|
36
|
+
*/
|
|
37
|
+
class SdTimeSpinner {
|
|
38
|
+
// Hai-chiều: cha có thể đọc/ghi từng đơn vị qua signal model.
|
|
39
|
+
hours = model(0);
|
|
40
|
+
minutes = model(0);
|
|
41
|
+
seconds = model(0);
|
|
42
|
+
showSeconds = input(false, { transform: booleanAttribute });
|
|
43
|
+
disabled = input(false, { transform: booleanAttribute });
|
|
44
|
+
// Cache hiển thị 2 chữ số — pad-left "0".
|
|
45
|
+
pad(n) {
|
|
46
|
+
return n < 10 ? `0${n}` : `${n}`;
|
|
47
|
+
}
|
|
48
|
+
// Bước nhảy ±1, wrap vòng quanh max.
|
|
49
|
+
step(unit, delta) {
|
|
50
|
+
if (this.disabled())
|
|
51
|
+
return;
|
|
52
|
+
if (unit === 'h') {
|
|
53
|
+
const next = (this.hours() + delta + 24) % 24;
|
|
54
|
+
this.hours.set(next);
|
|
55
|
+
}
|
|
56
|
+
else if (unit === 'm') {
|
|
57
|
+
const next = (this.minutes() + delta + 60) % 60;
|
|
58
|
+
this.minutes.set(next);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const next = (this.seconds() + delta + 60) % 60;
|
|
62
|
+
this.seconds.set(next);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Buffer tích lũy chữ số đang gõ cho từng đơn vị.
|
|
67
|
+
* Được reset khi: focus, commit (2 chữ số / auto-commit), blur.
|
|
68
|
+
*/
|
|
69
|
+
_buf = { h: '', m: '', s: '' };
|
|
70
|
+
_commitUnit(unit, num) {
|
|
71
|
+
if (unit === 'h')
|
|
72
|
+
this.hours.set(num);
|
|
73
|
+
else if (unit === 'm')
|
|
74
|
+
this.minutes.set(num);
|
|
75
|
+
else
|
|
76
|
+
this.seconds.set(num);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* onInput chỉ xử lý các trường hợp không qua keydown:
|
|
80
|
+
* paste, drag-drop, mobile soft-keyboard (không fire keydown).
|
|
81
|
+
*/
|
|
82
|
+
onInput(unit, event) {
|
|
83
|
+
if (this.disabled())
|
|
84
|
+
return;
|
|
85
|
+
const raw = event.target.value.replace(/[^0-9]/g, '');
|
|
86
|
+
if (!raw) {
|
|
87
|
+
this._buf[unit] = '';
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const max = unit === 'h' ? 23 : 59;
|
|
91
|
+
const num = Math.min(parseInt(raw.slice(-2), 10), max);
|
|
92
|
+
this._commitUnit(unit, num);
|
|
93
|
+
this._buf[unit] = '';
|
|
94
|
+
}
|
|
95
|
+
// Lăn chuột trên input — cuộn lên = tăng.
|
|
96
|
+
onWheel(unit, event) {
|
|
97
|
+
if (this.disabled())
|
|
98
|
+
return;
|
|
99
|
+
event.preventDefault();
|
|
100
|
+
this._buf[unit] = '';
|
|
101
|
+
this.step(unit, event.deltaY < 0 ? 1 : -1);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Xử lý gõ phím:
|
|
105
|
+
* - Chữ số: buffer 2 ký tự, auto-commit khi đủ hoặc chữ số đầu vượt ngưỡng
|
|
106
|
+
* - Arrow: ±1, reset buffer
|
|
107
|
+
* - Tab/Enter: commit buffer dở (nếu có)
|
|
108
|
+
*/
|
|
109
|
+
onKeyDown(unit, event) {
|
|
110
|
+
if (this.disabled())
|
|
111
|
+
return;
|
|
112
|
+
if (event.key === 'ArrowUp') {
|
|
113
|
+
event.preventDefault();
|
|
114
|
+
this._buf[unit] = '';
|
|
115
|
+
this.step(unit, 1);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (event.key === 'ArrowDown') {
|
|
119
|
+
event.preventDefault();
|
|
120
|
+
this._buf[unit] = '';
|
|
121
|
+
this.step(unit, -1);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (/^\d$/.test(event.key)) {
|
|
125
|
+
event.preventDefault(); // Ta tự kiểm soát hiển thị
|
|
126
|
+
const max = unit === 'h' ? 23 : 59;
|
|
127
|
+
// Chữ số đầu tối đa để còn có thể nhập chữ số 2 hợp lệ:
|
|
128
|
+
// giờ → max first digit = 2 (vd '3x' không hợp lệ vì max 23)
|
|
129
|
+
// phút/giây → max first digit = 5
|
|
130
|
+
const maxFirstDigit = unit === 'h' ? 2 : 5;
|
|
131
|
+
const buf = this._buf[unit] + event.key;
|
|
132
|
+
const el = event.target;
|
|
133
|
+
if (buf.length === 1) {
|
|
134
|
+
const d = parseInt(event.key, 10);
|
|
135
|
+
if (d > maxFirstDigit) {
|
|
136
|
+
// Chữ số đầu không thể là hàng chục hợp lệ → commit ngay dạng 0X
|
|
137
|
+
const num = Math.min(d, max);
|
|
138
|
+
this._commitUnit(unit, num);
|
|
139
|
+
el.value = this.pad(num);
|
|
140
|
+
this._buf[unit] = '';
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// Chờ chữ số thứ 2 — hiển thị ký tự đơn tạm thời
|
|
144
|
+
this._buf[unit] = event.key;
|
|
145
|
+
el.value = event.key;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
// Đã có 2 chữ số → commit
|
|
150
|
+
const num = Math.min(parseInt(buf, 10), max);
|
|
151
|
+
this._commitUnit(unit, num);
|
|
152
|
+
el.value = this.pad(num);
|
|
153
|
+
this._buf[unit] = '';
|
|
154
|
+
}
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (event.key === 'Backspace' || event.key === 'Delete') {
|
|
158
|
+
this._buf[unit] = '';
|
|
159
|
+
return; // browser tự xử lý xóa ký tự
|
|
160
|
+
}
|
|
161
|
+
if (event.key === 'Tab' || event.key === 'Enter') {
|
|
162
|
+
// Commit nếu còn buffer chữ số đơn
|
|
163
|
+
if (this._buf[unit]) {
|
|
164
|
+
const max = unit === 'h' ? 23 : 59;
|
|
165
|
+
const num = Math.min(parseInt(this._buf[unit], 10), max);
|
|
166
|
+
this._commitUnit(unit, num);
|
|
167
|
+
this._buf[unit] = '';
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Khi blur: commit buffer dở (nếu có) + chuẩn hóa hiển thị.
|
|
172
|
+
onBlur(unit, event) {
|
|
173
|
+
if (this._buf[unit]) {
|
|
174
|
+
const max = unit === 'h' ? 23 : 59;
|
|
175
|
+
const num = Math.min(parseInt(this._buf[unit], 10), max);
|
|
176
|
+
this._commitUnit(unit, num);
|
|
177
|
+
this._buf[unit] = '';
|
|
178
|
+
}
|
|
179
|
+
const el = event.target;
|
|
180
|
+
if (unit === 'h')
|
|
181
|
+
el.value = this.pad(this.hours());
|
|
182
|
+
else if (unit === 'm')
|
|
183
|
+
el.value = this.pad(this.minutes());
|
|
184
|
+
else
|
|
185
|
+
el.value = this.pad(this.seconds());
|
|
186
|
+
}
|
|
187
|
+
// Chọn toàn bộ text khi focus + reset buffer.
|
|
188
|
+
onFocus(unit, event) {
|
|
189
|
+
this._buf[unit] = '';
|
|
190
|
+
event.target.select();
|
|
191
|
+
}
|
|
192
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdTimeSpinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
193
|
+
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\" aria-label=\"T\u0103ng gi\u1EDD\">\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 aria-label=\"Gi\u1EDD\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('h', -1)\" tabindex=\"-1\" aria-label=\"Gi\u1EA3m gi\u1EDD\">\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\" aria-label=\"T\u0103ng ph\u00FAt\">\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 aria-label=\"Ph\u00FAt\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('m', -1)\" tabindex=\"-1\" aria-label=\"Gi\u1EA3m ph\u00FAt\">\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\" aria-label=\"T\u0103ng gi\u00E2y\">\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 aria-label=\"Gi\u00E2y\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('s', -1)\" tabindex=\"-1\" aria-label=\"Gi\u1EA3m gi\u00E2y\">\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 }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
194
|
+
}
|
|
195
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdTimeSpinner, decorators: [{
|
|
196
|
+
type: Component,
|
|
197
|
+
args: [{ selector: 'sd-time-spinner', standalone: true, imports: [CommonModule], 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\" aria-label=\"T\u0103ng gi\u1EDD\">\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 aria-label=\"Gi\u1EDD\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('h', -1)\" tabindex=\"-1\" aria-label=\"Gi\u1EA3m gi\u1EDD\">\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\" aria-label=\"T\u0103ng ph\u00FAt\">\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 aria-label=\"Ph\u00FAt\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('m', -1)\" tabindex=\"-1\" aria-label=\"Gi\u1EA3m ph\u00FAt\">\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\" aria-label=\"T\u0103ng gi\u00E2y\">\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 aria-label=\"Gi\u00E2y\" />\r\n <button type=\"button\" class=\"step\" (click)=\"step('s', -1)\" tabindex=\"-1\" aria-label=\"Gi\u1EA3m gi\u00E2y\">\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"] }]
|
|
198
|
+
}] });
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Datetime picker popup — Calendar (Angular Material) + Time Spinner + Footer.
|
|
202
|
+
*
|
|
203
|
+
* Component này được render trong CDK Overlay từ `sd-datetime`.
|
|
204
|
+
* Phát event `confirmed`/`cancelled` khi user thao tác trên footer.
|
|
205
|
+
*/
|
|
206
|
+
class SdDatetimePicker {
|
|
207
|
+
// ==========================================
|
|
208
|
+
// INPUTS
|
|
209
|
+
// ==========================================
|
|
210
|
+
/** Giá trị khởi tạo của picker (Moment, có thể null). */
|
|
211
|
+
initialValue = input(null);
|
|
212
|
+
/** Min/max boundary (Moment hoặc Date). */
|
|
213
|
+
minDate = input(null);
|
|
214
|
+
maxDate = input(null);
|
|
215
|
+
/** Hiển thị thêm cột giây (mặc định ẩn — chỉ HH:MM). */
|
|
216
|
+
showSeconds = input(false, { transform: booleanAttribute });
|
|
217
|
+
/** Disabled state. */
|
|
218
|
+
disabled = input(false, { transform: booleanAttribute });
|
|
219
|
+
// ==========================================
|
|
220
|
+
// OUTPUTS (legacy EventEmitter để tương thích Overlay subscription)
|
|
221
|
+
// ==========================================
|
|
222
|
+
confirmed = new EventEmitter();
|
|
223
|
+
cancelled = new EventEmitter();
|
|
224
|
+
// ==========================================
|
|
225
|
+
// STATE — signals nội bộ
|
|
226
|
+
// ==========================================
|
|
227
|
+
selectedDate = signal(moment());
|
|
228
|
+
hours = signal(0);
|
|
229
|
+
minutes = signal(0);
|
|
230
|
+
seconds = signal(0);
|
|
231
|
+
constructor() {
|
|
232
|
+
// Khởi tạo từ initialValue khi component được tạo.
|
|
233
|
+
// Effect không cần thiết vì input chỉ set một lần lúc mở popup.
|
|
234
|
+
queueMicrotask(() => this.#hydrateFromInput());
|
|
235
|
+
}
|
|
236
|
+
#hydrateFromInput() {
|
|
237
|
+
const init = this.initialValue();
|
|
238
|
+
const m = init && moment.isMoment(init) ? init.clone() : moment();
|
|
239
|
+
this.selectedDate.set(m);
|
|
240
|
+
this.hours.set(m.hour());
|
|
241
|
+
this.minutes.set(m.minute());
|
|
242
|
+
this.seconds.set(m.second());
|
|
243
|
+
}
|
|
244
|
+
// ==========================================
|
|
245
|
+
// EVENT HANDLERS
|
|
246
|
+
// ==========================================
|
|
247
|
+
/** Khi user chọn ngày trên MatCalendar. */
|
|
248
|
+
onDateSelected(date) {
|
|
249
|
+
if (!date)
|
|
250
|
+
return;
|
|
251
|
+
// Giữ nguyên giờ/phút/giây hiện tại, chỉ thay đổi ngày.
|
|
252
|
+
const next = date.clone()
|
|
253
|
+
.hour(this.hours())
|
|
254
|
+
.minute(this.minutes())
|
|
255
|
+
.second(this.seconds());
|
|
256
|
+
this.selectedDate.set(next);
|
|
257
|
+
}
|
|
258
|
+
onConfirm() {
|
|
259
|
+
if (this.disabled())
|
|
260
|
+
return;
|
|
261
|
+
const result = this.selectedDate().clone()
|
|
262
|
+
.hour(this.hours())
|
|
263
|
+
.minute(this.minutes())
|
|
264
|
+
.second(this.showSeconds() ? this.seconds() : 0)
|
|
265
|
+
.millisecond(0);
|
|
266
|
+
this.confirmed.emit(result);
|
|
267
|
+
}
|
|
268
|
+
onCancel() {
|
|
269
|
+
this.cancelled.emit();
|
|
270
|
+
}
|
|
271
|
+
/** Đặt nhanh thời gian "Bây giờ". */
|
|
272
|
+
onNow() {
|
|
273
|
+
if (this.disabled())
|
|
274
|
+
return;
|
|
275
|
+
const now = moment();
|
|
276
|
+
this.selectedDate.set(now);
|
|
277
|
+
this.hours.set(now.hour());
|
|
278
|
+
this.minutes.set(now.minute());
|
|
279
|
+
this.seconds.set(now.second());
|
|
280
|
+
}
|
|
281
|
+
// Min/Max — chuyển về Moment cho MatCalendar
|
|
282
|
+
get _minMoment() {
|
|
283
|
+
const v = this.minDate();
|
|
284
|
+
if (!v)
|
|
285
|
+
return null;
|
|
286
|
+
return moment.isMoment(v) ? v : moment(v);
|
|
287
|
+
}
|
|
288
|
+
get _maxMoment() {
|
|
289
|
+
const v = this.maxDate();
|
|
290
|
+
if (!v)
|
|
291
|
+
return null;
|
|
292
|
+
return moment.isMoment(v) ? v : moment(v);
|
|
293
|
+
}
|
|
294
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdDatetimePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
295
|
+
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>B\u00E2y gi\u1EDD</span>\r\n </button>\r\n\r\n <div class=\"footer-actions\">\r\n <button type=\"button\" class=\"btn btn-text\" (click)=\"onCancel()\">H\u1EE7y</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>X\u00E1c nh\u1EADn</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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
296
|
+
}
|
|
297
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdDatetimePicker, decorators: [{
|
|
298
|
+
type: Component,
|
|
299
|
+
args: [{ selector: 'sd-datetime-picker', standalone: true, imports: [CommonModule, MatDatepickerModule, MatButtonModule, SdTimeSpinner], 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>B\u00E2y gi\u1EDD</span>\r\n </button>\r\n\r\n <div class=\"footer-actions\">\r\n <button type=\"button\" class=\"btn btn-text\" (click)=\"onCancel()\">H\u1EE7y</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>X\u00E1c nh\u1EADn</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"] }]
|
|
300
|
+
}], ctorParameters: () => [], propDecorators: { confirmed: [{
|
|
301
|
+
type: Output
|
|
302
|
+
}], cancelled: [{
|
|
303
|
+
type: Output
|
|
304
|
+
}] } });
|
|
25
305
|
|
|
26
306
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
27
307
|
/* eslint-disable @angular-eslint/no-input-rename */
|
|
308
|
+
/**
|
|
309
|
+
* Format parse/display dùng cho MatDateAdapter (Moment).
|
|
310
|
+
* Note: format input là `DD/MM/YYYY HH:mm` (không có giây mặc định) —
|
|
311
|
+
* giây chỉ được render khi `showSeconds` = true.
|
|
312
|
+
*/
|
|
313
|
+
const SD_DATETIME_FORMATS = {
|
|
314
|
+
parse: { dateInput: 'DD/MM/YYYY HH:mm' },
|
|
315
|
+
display: {
|
|
316
|
+
dateInput: 'DD/MM/YYYY HH:mm',
|
|
317
|
+
monthYearLabel: 'MMM YYYY',
|
|
318
|
+
dateA11yLabel: 'LL',
|
|
319
|
+
monthYearA11yLabel: 'MMMM YYYY',
|
|
320
|
+
},
|
|
321
|
+
};
|
|
28
322
|
class SdDatetime {
|
|
29
323
|
id = `I${uuid.v4()}`;
|
|
30
324
|
// ==========================================
|
|
31
325
|
// 1. SIGNAL QUERIES
|
|
32
326
|
// ==========================================
|
|
33
327
|
inputRef = viewChild('input');
|
|
34
|
-
datetimePicker = viewChild(MtxDatetimepicker);
|
|
35
328
|
sdLabelTemplate = contentChild('sdLabel');
|
|
36
329
|
sdValueTemplate = contentChild('sdValue');
|
|
37
330
|
sdViewDef = contentChild(SdViewDefDirective);
|
|
@@ -39,6 +332,9 @@ class SdDatetime {
|
|
|
39
332
|
// 2. INJECTS
|
|
40
333
|
// ==========================================
|
|
41
334
|
ref = inject(ChangeDetectorRef);
|
|
335
|
+
overlay = inject(Overlay);
|
|
336
|
+
elementRef = inject(ElementRef);
|
|
337
|
+
injector = inject(Injector);
|
|
42
338
|
formConfig = inject(SD_FORM_CONFIGURATION, { optional: true });
|
|
43
339
|
// ==========================================
|
|
44
340
|
// 3. SIGNAL INPUTS & MODEL
|
|
@@ -71,10 +367,11 @@ class SdDatetime {
|
|
|
71
367
|
required = input(false, { transform: booleanAttribute });
|
|
72
368
|
disabled = input(false, { transform: booleanAttribute });
|
|
73
369
|
viewed = input(false, { transform: booleanAttribute });
|
|
370
|
+
/** Hiển thị thêm cột giây trong picker. Mặc định: chỉ HH:MM. */
|
|
371
|
+
showSeconds = input(false, { transform: booleanAttribute });
|
|
74
372
|
inlineError = input();
|
|
75
373
|
/**
|
|
76
374
|
* Tổng hợp error message để hiển thị trong tooltip khi hideInlineError = true.
|
|
77
|
-
* Dùng getter (không phải computed) vì formControl.errors không phải Angular signal.
|
|
78
375
|
*/
|
|
79
376
|
get errorTooltipMessage() {
|
|
80
377
|
const errors = this.formControl.errors;
|
|
@@ -90,8 +387,6 @@ class SdDatetime {
|
|
|
90
387
|
const d = this.resolvedMax();
|
|
91
388
|
return `Ngày lớn nhất: ${d ? new Date(d).toLocaleDateString('vi-VN') : ''}`;
|
|
92
389
|
}
|
|
93
|
-
if (errors['matDatetimePickerParse'])
|
|
94
|
-
return `Parse error: ${errors['matDatetimePickerParse']?.text}`;
|
|
95
390
|
if (errors['date'])
|
|
96
391
|
return errors['date'];
|
|
97
392
|
if (errors['customValidator'])
|
|
@@ -104,7 +399,7 @@ class SdDatetime {
|
|
|
104
399
|
appearanceInput = input(undefined, { alias: 'appearance' });
|
|
105
400
|
appearance = computed(() => this.appearanceInput() ?? this.formConfig?.appearance ?? 'outline');
|
|
106
401
|
floatLabel = input('auto');
|
|
107
|
-
//
|
|
402
|
+
// Min/max — chấp nhận 'TODAY', Date, hoặc string ISO
|
|
108
403
|
minInput = input(undefined, { alias: 'min' });
|
|
109
404
|
minDateInput = input(undefined, { alias: 'minDate' });
|
|
110
405
|
resolvedMin = computed(() => this.#parseDateBoundary(this.minInput() ?? this.minDateInput()));
|
|
@@ -118,16 +413,19 @@ class SdDatetime {
|
|
|
118
413
|
sdChange = output();
|
|
119
414
|
sdFocus = output();
|
|
120
415
|
// ==========================================
|
|
121
|
-
// 5. INTERNAL STATE
|
|
416
|
+
// 5. INTERNAL STATE
|
|
122
417
|
// ==========================================
|
|
123
418
|
isMobileOrTablet = SdUtilities.isMobile();
|
|
124
419
|
formControl = new SdFormControl();
|
|
125
420
|
isFocused = false;
|
|
126
421
|
isValid;
|
|
422
|
+
/** State popup — true khi đang mở. */
|
|
423
|
+
pickerOpened = signal(false);
|
|
127
424
|
#date;
|
|
128
425
|
#subscription = new Subscription();
|
|
426
|
+
#overlayRef = null;
|
|
129
427
|
constructor() {
|
|
130
|
-
// EFFECT 1: Sync model thay đổi từ bên ngoài
|
|
428
|
+
// EFFECT 1: Sync model thay đổi từ bên ngoài → cập nhật hiển thị
|
|
131
429
|
effect(() => {
|
|
132
430
|
let val = this.valueModel();
|
|
133
431
|
untracked(() => {
|
|
@@ -137,10 +435,12 @@ class SdDatetime {
|
|
|
137
435
|
val = DateUtilities.toFormat(val, 'yyyy/MM/dd HH:mm');
|
|
138
436
|
if (this.#date !== val) {
|
|
139
437
|
this.#date = val;
|
|
140
|
-
|
|
141
|
-
|
|
438
|
+
// Cập nhật formControl với chuỗi hiển thị dd/MM/yyyy HH:mm
|
|
439
|
+
const fmt = this.showSeconds() ? 'dd/MM/yyyy HH:mm:ss' : 'dd/MM/yyyy HH:mm';
|
|
440
|
+
const displayStr = DateUtilities.isDate(this.#date)
|
|
441
|
+
? DateUtilities.toFormat(this.#date, fmt)
|
|
142
442
|
: null;
|
|
143
|
-
this.formControl.setValue(
|
|
443
|
+
this.formControl.setValue(displayStr, { emitEvent: false });
|
|
144
444
|
}
|
|
145
445
|
});
|
|
146
446
|
});
|
|
@@ -177,8 +477,87 @@ class SdDatetime {
|
|
|
177
477
|
const formGroup = this.form();
|
|
178
478
|
formGroup?.removeControl(this.name());
|
|
179
479
|
this.#subscription.unsubscribe();
|
|
480
|
+
this.#closeOverlay();
|
|
180
481
|
}
|
|
181
|
-
//
|
|
482
|
+
// ==========================================
|
|
483
|
+
// 6. POPUP MANAGEMENT — CDK Overlay
|
|
484
|
+
// ==========================================
|
|
485
|
+
/** Mở popup chọn datetime, neo vào input. */
|
|
486
|
+
open() {
|
|
487
|
+
if (this.formControl.disabled || this.pickerOpened())
|
|
488
|
+
return;
|
|
489
|
+
const origin = this.elementRef.nativeElement;
|
|
490
|
+
const positionStrategy = this.overlay
|
|
491
|
+
.position()
|
|
492
|
+
.flexibleConnectedTo(origin)
|
|
493
|
+
.withPositions([
|
|
494
|
+
{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
|
|
495
|
+
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
|
|
496
|
+
{ originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },
|
|
497
|
+
{ originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },
|
|
498
|
+
])
|
|
499
|
+
.withFlexibleDimensions(false)
|
|
500
|
+
.withPush(true);
|
|
501
|
+
const overlayConfig = new OverlayConfig({
|
|
502
|
+
positionStrategy,
|
|
503
|
+
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
504
|
+
hasBackdrop: true,
|
|
505
|
+
backdropClass: 'sd-datetime-backdrop',
|
|
506
|
+
panelClass: 'sd-datetime-overlay-panel',
|
|
507
|
+
});
|
|
508
|
+
this.#overlayRef = this.overlay.create(overlayConfig);
|
|
509
|
+
const portal = new ComponentPortal(SdDatetimePicker, null, this.injector);
|
|
510
|
+
const ref = this.#overlayRef.attach(portal);
|
|
511
|
+
// Đẩy state hiện tại vào popup
|
|
512
|
+
ref.setInput('initialValue', this.#currentValueAsMoment());
|
|
513
|
+
ref.setInput('minDate', this.resolvedMin());
|
|
514
|
+
ref.setInput('maxDate', this.resolvedMax());
|
|
515
|
+
ref.setInput('showSeconds', this.showSeconds());
|
|
516
|
+
// Subscribe events từ popup
|
|
517
|
+
ref.instance.confirmed.subscribe((value) => this.#onPickerConfirm(value));
|
|
518
|
+
ref.instance.cancelled.subscribe(() => this.#onPickerCancel());
|
|
519
|
+
// Đóng khi click backdrop
|
|
520
|
+
this.#overlayRef.backdropClick().subscribe(() => this.#onPickerCancel());
|
|
521
|
+
this.pickerOpened.set(true);
|
|
522
|
+
this.ref.markForCheck();
|
|
523
|
+
}
|
|
524
|
+
/** Đóng popup (public — gọi từ template nếu cần). */
|
|
525
|
+
close() {
|
|
526
|
+
this.#closeOverlay();
|
|
527
|
+
}
|
|
528
|
+
#closeOverlay() {
|
|
529
|
+
if (this.#overlayRef) {
|
|
530
|
+
this.#overlayRef.dispose();
|
|
531
|
+
this.#overlayRef = null;
|
|
532
|
+
}
|
|
533
|
+
if (this.pickerOpened()) {
|
|
534
|
+
this.pickerOpened.set(false);
|
|
535
|
+
this.ref.markForCheck();
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
#onPickerConfirm(value) {
|
|
539
|
+
const fmt = this.showSeconds() ? 'yyyy/MM/dd HH:mm:ss' : 'yyyy/MM/dd HH:mm:00';
|
|
540
|
+
const stored = DateUtilities.toFormat(value.toDate(), fmt);
|
|
541
|
+
if (this.#date !== stored) {
|
|
542
|
+
this.valueModel.set(stored);
|
|
543
|
+
this.sdChange.emit(stored);
|
|
544
|
+
}
|
|
545
|
+
this.#closeOverlay();
|
|
546
|
+
}
|
|
547
|
+
#onPickerCancel() {
|
|
548
|
+
this.#closeOverlay();
|
|
549
|
+
}
|
|
550
|
+
/** Lấy giá trị hiện tại dưới dạng Moment để truyền vào popup. */
|
|
551
|
+
#currentValueAsMoment() {
|
|
552
|
+
const v = this.valueModel();
|
|
553
|
+
if (!v || !DateUtilities.isDate(v))
|
|
554
|
+
return null;
|
|
555
|
+
const fmtted = DateUtilities.toFormat(v, 'yyyy/MM/dd HH:mm:ss');
|
|
556
|
+
return fmtted ? moment(fmtted, 'YYYY/MM/DD HH:mm:ss') : null;
|
|
557
|
+
}
|
|
558
|
+
// ==========================================
|
|
559
|
+
// 7. PARSE/VALIDATE HELPERS
|
|
560
|
+
// ==========================================
|
|
182
561
|
#parseDateBoundary(val) {
|
|
183
562
|
if (val === 'TODAY')
|
|
184
563
|
return new Date();
|
|
@@ -189,6 +568,9 @@ class SdDatetime {
|
|
|
189
568
|
customInlineErrorValidator() {
|
|
190
569
|
return () => ({ inlineError: true });
|
|
191
570
|
}
|
|
571
|
+
// ==========================================
|
|
572
|
+
// 8. INPUT EVENT HANDLERS
|
|
573
|
+
// ==========================================
|
|
192
574
|
onFocus = () => {
|
|
193
575
|
this.isFocused = true;
|
|
194
576
|
this.sdFocus.emit();
|
|
@@ -210,7 +592,7 @@ class SdDatetime {
|
|
|
210
592
|
this.isFocused = true;
|
|
211
593
|
setTimeout(() => {
|
|
212
594
|
this.inputRef()?.nativeElement?.focus();
|
|
213
|
-
this.
|
|
595
|
+
this.open();
|
|
214
596
|
}, 100);
|
|
215
597
|
};
|
|
216
598
|
focusInputElement() {
|
|
@@ -234,6 +616,10 @@ class SdDatetime {
|
|
|
234
616
|
}
|
|
235
617
|
return false;
|
|
236
618
|
};
|
|
619
|
+
/**
|
|
620
|
+
* Khi user gõ trực tiếp vào input và rời focus → validate format dd/MM/yyyy HH:mm
|
|
621
|
+
* Hỗ trợ cả format có giây.
|
|
622
|
+
*/
|
|
237
623
|
onConfirmInput = (event) => {
|
|
238
624
|
const currentVal = event.target.value;
|
|
239
625
|
const formControl = this.formControl;
|
|
@@ -245,22 +631,27 @@ class SdDatetime {
|
|
|
245
631
|
formControl.markAsTouched();
|
|
246
632
|
formControl.setErrors({ ...formControl.errors, date: `Sai định dạng` });
|
|
247
633
|
}, 0);
|
|
634
|
+
return;
|
|
248
635
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
636
|
+
setTimeout(() => {
|
|
637
|
+
formControl.setErrors({ ...formControl.errors, date: null });
|
|
638
|
+
this.formControl.updateValueAndValidity();
|
|
639
|
+
}, 0);
|
|
640
|
+
// Đồng bộ ngược về model nếu hợp lệ
|
|
641
|
+
if (currentVal) {
|
|
642
|
+
const parsed = moment(currentVal, ['DD/MM/YYYY HH:mm:ss', 'DD/MM/YYYY HH:mm'], true);
|
|
643
|
+
if (parsed.isValid()) {
|
|
644
|
+
const fmt = this.showSeconds() ? 'yyyy/MM/dd HH:mm:ss' : 'yyyy/MM/dd HH:mm:00';
|
|
645
|
+
const stored = DateUtilities.toFormat(parsed.toDate(), fmt);
|
|
646
|
+
if (this.#date !== stored) {
|
|
647
|
+
this.valueModel.set(stored);
|
|
648
|
+
this.sdChange.emit(stored);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
254
651
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
// Giữ nguyên logic format cũ theo yêu cầu hệ thống
|
|
259
|
-
const value = DateUtilities.toFormat(event.value?.toDate(), 'yyyy/MM/dd HH:mm:ss');
|
|
260
|
-
this.inputRef()?.nativeElement?.focus();
|
|
261
|
-
if (this.#date !== value) {
|
|
262
|
-
this.valueModel.set(value);
|
|
263
|
-
this.sdChange.emit(value);
|
|
652
|
+
else if (this.valueModel()) {
|
|
653
|
+
this.valueModel.set(null);
|
|
654
|
+
this.sdChange.emit(null);
|
|
264
655
|
}
|
|
265
656
|
};
|
|
266
657
|
clear = ($event) => {
|
|
@@ -272,46 +663,14 @@ class SdDatetime {
|
|
|
272
663
|
}
|
|
273
664
|
};
|
|
274
665
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdDatetime, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
275
|
-
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 }, 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: [
|
|
276
|
-
|
|
277
|
-
parse: {
|
|
278
|
-
dateInput: 'DD/MM/YYYY',
|
|
279
|
-
timeInput: 'HH:mm',
|
|
280
|
-
datetimeInput: 'DD/MM/YYYY HH:mm',
|
|
281
|
-
},
|
|
282
|
-
display: {
|
|
283
|
-
dateInput: 'DD/MM/YYYY',
|
|
284
|
-
monthInput: 'MMMM',
|
|
285
|
-
timeInput: 'HH:mm',
|
|
286
|
-
datetimeInput: 'DD/MM/YYYY HH:mm',
|
|
287
|
-
monthYearLabel: 'MMM YYYY',
|
|
288
|
-
dateA11yLabel: 'LL',
|
|
289
|
-
monthYearA11yLabel: 'MMMM YYYY',
|
|
290
|
-
popupHeaderDateLabel: 'MMM DD, ddd',
|
|
291
|
-
},
|
|
292
|
-
}),
|
|
293
|
-
], 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 }, { propertyName: "datetimePicker", first: true, predicate: MtxDatetimepicker, 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 && !datetimePicker()?.opened) {\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 <mtx-datetimepicker #datetimePicker [type]=\"'datetime'\" [mode]=\"'auto'\"></mtx-datetimepicker>\r\n\r\n <input\r\n aria-hidden=\"true\"\r\n [attr.data-autoId]=\"autoId()\"\r\n [mtxDatetimepicker]=\"datetimePicker\"\r\n [id]=\"id\"\r\n (blur)=\"onConfirmInput($event)\"\r\n (keyup.enter)=\"onConfirmInput($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (dateChange)=\"onChange($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=\"pointer sd-suffix-icon\" (click)=\"!formControl.disabled && datetimePicker?.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.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.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: "ngmodule", type: MtxDatetimepickerModule }, { kind: "component", type: i6.MtxDatetimepicker, selector: "mtx-datetimepicker", inputs: ["multiYearSelector", "twelvehour", "showWeekNumbers", "startView", "mode", "timeInterval", "preventSameDateTimeSelection", "calendarHeaderComponent", "panelClass", "opened", "color", "startAt", "type", "touchUi", "timeInput", "timeInputAutoFocus", "disabled", "xPosition", "yPosition", "restoreFocus"], outputs: ["selectedChanged", "opened", "closed", "viewChanged"], exportAs: ["mtxDatetimepicker"] }, { kind: "directive", type: i6.MtxDatetimepickerInput, selector: "input[mtxDatetimepicker]", inputs: ["mtxDatetimepicker", "mtxDatetimepickerFilter", "value", "min", "max", "disabled"], outputs: ["dateChange", "dateInput"], exportAs: ["mtxDatetimepickerInput"] }, { 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 });
|
|
666
|
+
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: [
|
|
667
|
+
provideMomentDateAdapter(SD_DATETIME_FORMATS),
|
|
668
|
+
], 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 });
|
|
294
669
|
}
|
|
295
670
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: SdDatetime, decorators: [{
|
|
296
671
|
type: Component,
|
|
297
672
|
args: [{ selector: 'sd-datetime', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
298
|
-
|
|
299
|
-
parse: {
|
|
300
|
-
dateInput: 'DD/MM/YYYY',
|
|
301
|
-
timeInput: 'HH:mm',
|
|
302
|
-
datetimeInput: 'DD/MM/YYYY HH:mm',
|
|
303
|
-
},
|
|
304
|
-
display: {
|
|
305
|
-
dateInput: 'DD/MM/YYYY',
|
|
306
|
-
monthInput: 'MMMM',
|
|
307
|
-
timeInput: 'HH:mm',
|
|
308
|
-
datetimeInput: 'DD/MM/YYYY HH:mm',
|
|
309
|
-
monthYearLabel: 'MMM YYYY',
|
|
310
|
-
dateA11yLabel: 'LL',
|
|
311
|
-
monthYearA11yLabel: 'MMMM YYYY',
|
|
312
|
-
popupHeaderDateLabel: 'MMM DD, ddd',
|
|
313
|
-
},
|
|
314
|
-
}),
|
|
673
|
+
provideMomentDateAdapter(SD_DATETIME_FORMATS),
|
|
315
674
|
], standalone: true, imports: [
|
|
316
675
|
CommonModule,
|
|
317
676
|
FormsModule,
|
|
@@ -320,10 +679,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
|
|
|
320
679
|
MatIconModule,
|
|
321
680
|
MatTooltipModule,
|
|
322
681
|
MatFormFieldModule,
|
|
323
|
-
MtxDatetimepickerModule,
|
|
324
682
|
SdLabel,
|
|
325
|
-
SdView
|
|
326
|
-
], 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 && !
|
|
683
|
+
SdView,
|
|
684
|
+
], 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"] }]
|
|
327
685
|
}], ctorParameters: () => [] });
|
|
328
686
|
|
|
329
687
|
/**
|