@luoxiao123/angular-material-date-time-range-picker 21.1.1 → 21.1.3
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { model, output, ChangeDetectionStrategy, Component, input, computed, inject, signal, ViewChild, ElementRef, Injector, DestroyRef, effect, untracked, forwardRef, Input } from '@angular/core';
|
|
3
3
|
import { Subject, take, tap } from 'rxjs';
|
|
4
4
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
5
|
import * as i1 from '@angular/material/datepicker';
|
|
@@ -8,8 +8,8 @@ import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
|
|
8
8
|
import { TablerIconComponent, provideTablerIcons } from '@luoxiao123/angular-tabler-icons';
|
|
9
9
|
import { IconLayoutSidebarLeftCollapse, IconClock, IconX, IconCalendarDue, IconInfoCircle } from '@luoxiao123/angular-tabler-icons/icons';
|
|
10
10
|
import * as i2 from '@angular/forms';
|
|
11
|
-
import { FormsModule, ReactiveFormsModule,
|
|
12
|
-
import {
|
|
11
|
+
import { FormsModule, ReactiveFormsModule, NgControl } from '@angular/forms';
|
|
12
|
+
import { MatFormFieldControl } from '@angular/material/form-field';
|
|
13
13
|
import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogModule } from '@angular/material/dialog';
|
|
14
14
|
import { FocusMonitor } from '@angular/cdk/a11y';
|
|
15
15
|
import * as i3$1 from '@angular/common';
|
|
@@ -20,12 +20,9 @@ import * as i2$1 from '@angular/material/sidenav';
|
|
|
20
20
|
import { MatSidenavModule } from '@angular/material/sidenav';
|
|
21
21
|
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
|
22
22
|
import * as i1$1 from '@angular/cdk/bidi';
|
|
23
|
-
import { MatBottomSheet } from '@angular/material/bottom-sheet';
|
|
24
23
|
|
|
25
24
|
class Container {
|
|
26
25
|
constructor() {
|
|
27
|
-
this.#breakpoints = inject(BreakpointObserver);
|
|
28
|
-
this.isMobile = this.#breakpoints.isMatched([Breakpoints.Handset, Breakpoints.Tablet]);
|
|
29
26
|
this.hasHeader = model(true, ...(ngDevMode ? [{ debugName: "hasHeader" }] : []));
|
|
30
27
|
this.hasFooter = model(true, ...(ngDevMode ? [{ debugName: "hasFooter" }] : []));
|
|
31
28
|
this.headerTitle = model('', ...(ngDevMode ? [{ debugName: "headerTitle" }] : []));
|
|
@@ -48,7 +45,6 @@ class Container {
|
|
|
48
45
|
this.submit = output();
|
|
49
46
|
this.secondaryButton = output();
|
|
50
47
|
}
|
|
51
|
-
#breakpoints;
|
|
52
48
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: Container, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
53
49
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: Container, isStandalone: true, selector: "date-time-picker-container", inputs: { hasHeader: { classPropertyName: "hasHeader", publicName: "hasHeader", isSignal: true, isRequired: false, transformFunction: null }, hasFooter: { classPropertyName: "hasFooter", publicName: "hasFooter", isSignal: true, isRequired: false, transformFunction: null }, headerTitle: { classPropertyName: "headerTitle", publicName: "headerTitle", isSignal: true, isRequired: false, transformFunction: null }, headerExtraContent: { classPropertyName: "headerExtraContent", publicName: "headerExtraContent", isSignal: true, isRequired: false, transformFunction: null }, footerExtraContent: { classPropertyName: "footerExtraContent", publicName: "footerExtraContent", isSignal: true, isRequired: false, transformFunction: null }, hasDismiss: { classPropertyName: "hasDismiss", publicName: "hasDismiss", isSignal: true, isRequired: false, transformFunction: null }, hasSubmit: { classPropertyName: "hasSubmit", publicName: "hasSubmit", isSignal: true, isRequired: false, transformFunction: null }, submitTitle: { classPropertyName: "submitTitle", publicName: "submitTitle", isSignal: true, isRequired: false, transformFunction: null }, submitBg: { classPropertyName: "submitBg", publicName: "submitBg", isSignal: true, isRequired: false, transformFunction: null }, submitColor: { classPropertyName: "submitColor", publicName: "submitColor", isSignal: true, isRequired: false, transformFunction: null }, submitTitleColor: { classPropertyName: "submitTitleColor", publicName: "submitTitleColor", isSignal: true, isRequired: false, transformFunction: null }, disabledSubmit: { classPropertyName: "disabledSubmit", publicName: "disabledSubmit", isSignal: true, isRequired: false, transformFunction: null }, hasSecondaryButton: { classPropertyName: "hasSecondaryButton", publicName: "hasSecondaryButton", isSignal: true, isRequired: false, transformFunction: null }, secondaryButtonTitle: { classPropertyName: "secondaryButtonTitle", publicName: "secondaryButtonTitle", isSignal: true, isRequired: false, transformFunction: null }, secondaryButtonBg: { classPropertyName: "secondaryButtonBg", publicName: "secondaryButtonBg", isSignal: true, isRequired: false, transformFunction: null }, secondaryButtonColor: { classPropertyName: "secondaryButtonColor", publicName: "secondaryButtonColor", isSignal: true, isRequired: false, transformFunction: null }, secondaryButtonTitleColor: { classPropertyName: "secondaryButtonTitleColor", publicName: "secondaryButtonTitleColor", isSignal: true, isRequired: false, transformFunction: null }, disabledSecondaryButton: { classPropertyName: "disabledSecondaryButton", publicName: "disabledSecondaryButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { hasHeader: "hasHeaderChange", hasFooter: "hasFooterChange", headerTitle: "headerTitleChange", headerExtraContent: "headerExtraContentChange", footerExtraContent: "footerExtraContentChange", hasDismiss: "hasDismissChange", hasSubmit: "hasSubmitChange", submitTitle: "submitTitleChange", submitBg: "submitBgChange", submitColor: "submitColorChange", submitTitleColor: "submitTitleColorChange", disabledSubmit: "disabledSubmitChange", hasSecondaryButton: "hasSecondaryButtonChange", secondaryButtonTitle: "secondaryButtonTitleChange", secondaryButtonBg: "secondaryButtonBgChange", secondaryButtonColor: "secondaryButtonColorChange", secondaryButtonTitleColor: "secondaryButtonTitleColorChange", disabledSecondaryButton: "disabledSecondaryButtonChange", dismiss: "dismiss", submit: "submit", secondaryButton: "secondaryButton" }, providers: [provideTablerIcons({ IconInfoCircle, IconCalendarDue, IconX, IconClock, IconLayoutSidebarLeftCollapse })], ngImport: i0, template: "<aside class=\"container-wrapper\">\r\n @if (hasHeader()) {\r\n <header class=\"container-header\">\r\n <div class=\"container-header-start\">\r\n <i-tabler name=\"clock\" strokeWidth=\"2px\" size=\"18px\" class=\"container-header-icon\" />\r\n\r\n @if (headerTitle()) {\r\n <h2 class=\"container-header-title\">{{ headerTitle() }}</h2>\r\n }\r\n </div>\r\n\r\n @if (headerExtraContent()) {\r\n <div class=\"container-header-extra\">\r\n <ng-container *ngTemplateOutlet=\"headerExtraContent() ?? null\"></ng-container>\r\n </div>\r\n }\r\n\r\n <button (click)=\"dismiss.emit()\" type=\"button\" class=\"container-header-close\" [attr.aria-label]=\"'\u5173\u95ED'\" tabindex=\"0\">\r\n <i-tabler name=\"x\" strokeWidth=\"2.5px\" size=\"18px\" class=\"container-header-close-icon\" />\r\n </button>\r\n </header>\r\n }\r\n\r\n <main class=\"container-main\">\r\n <ng-content />\r\n </main>\r\n\r\n @if (hasFooter()) {\r\n <footer class=\"container-footer\">\r\n @if (footerExtraContent()) {\r\n <div class=\"container-footer-extra\">\r\n <ng-container *ngTemplateOutlet=\"footerExtraContent() ?? null\"></ng-container>\r\n </div>\r\n }\r\n\r\n <div class=\"container-footer-actions\">\r\n @if (hasDismiss()) {\r\n <button mat-stroked-button color=\"primary\" (click)=\"dismiss.emit()\" type=\"button\"> \u53D6\u6D88 </button>\r\n }\r\n\r\n @if (hasSecondaryButton()) {\r\n <button mat-stroked-button color=\"primary\" (click)=\"secondaryButton.emit()\" type=\"button\" [disabled]=\"disabledSecondaryButton()\">\r\n {{ secondaryButtonTitle() }}\r\n </button>\r\n }\r\n\r\n @if (hasSubmit()) {\r\n <button mat-raised-button color=\"primary\" (click)=\"submit.emit()\" type=\"button\" [disabled]=\"disabledSubmit()\">\r\n {{ submitTitle() }}\r\n </button>\r\n }\r\n </div>\r\n </footer>\r\n }\r\n</aside>\r\n", styles: ["@charset \"UTF-8\";:host{display:flex;height:100%}.container-wrapper{width:100%;height:100%;display:flex;flex-direction:column;justify-content:space-between;overflow:hidden}.container-header{width:100%;padding:12px 16px;display:flex;gap:12px;justify-content:space-between;align-items:center;background-color:var(--mat-sys-surface-container-low, #fafafa);border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));-webkit-user-select:none;user-select:none;flex-shrink:0;box-sizing:border-box}.container-header-start{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.container-header-icon{color:var(--mat-sys-primary, #1976d2);flex-shrink:0}.container-header-title{font-size:.9375rem;font-weight:500;line-height:1.35;color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87));margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.container-header-extra{display:flex;align-items:center;gap:8px;flex:1;padding:0 4px;font-size:.75rem}.container-header-close{width:32px;height:32px;padding:0;display:flex;align-items:center;justify-content:center;background:transparent;border:none;border-radius:4px;cursor:pointer;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));transition:background-color .2s ease;flex-shrink:0}.container-header-close:hover{background-color:var(--mat-sys-surface-container-highest, rgba(0, 0, 0, .08))}.container-header-close:focus-visible{outline:2px solid var(--mat-sys-primary, #1976d2);outline-offset:2px}.container-header-close-icon{display:flex;align-items:center;justify-content:center}.container-main{flex:1;width:100%;display:flex;overflow-y:auto;overflow-x:hidden;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12))}.container-footer{width:100%;padding:12px 16px;display:flex;gap:12px;justify-content:flex-end;align-items:center;background-color:var(--mat-sys-surface-container-low, #fafafa);border-top:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));-webkit-user-select:none;user-select:none;flex-shrink:0;box-sizing:border-box}.container-footer-extra{display:flex;align-items:center;gap:8px;margin-right:auto;font-size:.75rem;padding:0 4px}.container-footer-actions{display:flex;gap:8px;align-items:center;flex-shrink:0}\n", ":host{height:100%}\n"], dependencies: [{ kind: "component", type: TablerIconComponent, selector: "i-tabler, tabler-icon", inputs: ["name"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
54
50
|
}
|
|
@@ -95,20 +91,64 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
|
|
|
95
91
|
args: [{ selector: 'date-time-input', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatDatepickerModule, FormsModule, TablerIconComponent, CommonModule], template: "<div class=\"date-time-input-wrapper\">\r\n <label class=\"date-time-input-label\">{{ label() }}</label>\r\n\r\n <div class=\"date-time-input-container\">\r\n <!-- \u65E5\u671F\u90E8\u5206 -->\r\n <div class=\"date-time-input-date\">\r\n <input\r\n type=\"text\"\r\n matInput\r\n [ngModel]=\"dateObj()\"\r\n (ngModelChange)=\"onDateChange($event)\"\r\n [matDatepicker]=\"datePicker\"\r\n (click)=\"datePicker.open()\"\r\n (focus)=\"datePicker.open()\"\r\n placeholder=\"\u9009\u62E9\u65E5\u671F\"\r\n class=\"date-time-input-field\"\r\n />\r\n <mat-datepicker #datePicker></mat-datepicker>\r\n\r\n <button type=\"button\" class=\"date-time-input-icon-btn\" tabindex=\"-1\" aria-hidden=\"true\">\r\n <i-tabler name=\"calendar-due\" strokeWidth=\"2px\" size=\"16px\" />\r\n </button>\r\n </div>\r\n\r\n <!-- \u5206\u9694\u7B26 -->\r\n <div class=\"date-time-input-divider\"></div>\r\n\r\n <!-- \u65F6\u95F4\u90E8\u5206 -->\r\n <div class=\"date-time-input-time\">\r\n <!-- \u5C0F\u65F6 -->\r\n <select class=\"date-time-input-select date-time-input-select-hour\" [ngModel]=\"hourValue()\" (ngModelChange)=\"onHourChange($event)\" [attr.aria-label]=\"'\u5C0F\u65F6'\">\r\n <option [ngValue]=\"null\" disabled>--</option>\r\n @for (hour of hours(); track hour) {\r\n <option [ngValue]=\"hour\">{{ hour | number: '2.0-0' }}</option>\r\n }\r\n </select>\r\n\r\n <!-- \u5206\u9694\u7B26 -->\r\n <span class=\"date-time-input-separator\">:</span>\r\n\r\n <!-- \u5206\u949F -->\r\n <select class=\"date-time-input-select date-time-input-select-minute\" [ngModel]=\"minuteValue()\" (ngModelChange)=\"onMinuteChange($event)\" [attr.aria-label]=\"'\u5206\u949F'\">\r\n <option [ngValue]=\"null\" disabled>--</option>\r\n @for (minute of minutes(); track minute) {\r\n <option [ngValue]=\"minute\">{{ minute | number: '2.0-0' }}</option>\r\n }\r\n </select>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block}:host .date-time-input-wrapper{display:flex;flex-direction:column;gap:8px;padding:12px 16px}@media(max-width:767px){:host .date-time-input-wrapper{padding-bottom:0}}:host .date-time-input-label{font-size:.75rem;font-weight:500;text-transform:uppercase;letter-spacing:.5px;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}:host .date-time-input-container{display:flex;align-items:center;width:100%;max-width:100%;border:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));border-radius:4px;overflow:hidden;background-color:var(--mat-sys-surface-container-low, rgba(0, 0, 0, .02));transition:border-color .2s ease;box-sizing:border-box}:host .date-time-input-container:hover{border-color:var(--mat-divider-color, rgba(0, 0, 0, .24))}:host .date-time-input-container:focus-within{border-color:var(--mat-sys-primary, #1976d2);background-color:var(--mat-sys-surface, #fff)}:host .date-time-input-date{flex:1;display:flex;align-items:center;position:relative;padding:0 8px;min-width:0;overflow:hidden}:host .date-time-input-field{flex:1;height:36px;padding:0;border:none;background:transparent;color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87));font-size:.875rem;min-width:0;overflow:hidden;text-overflow:ellipsis}:host .date-time-input-field::placeholder{color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .4))}:host .date-time-input-field:focus{outline:none}:host .date-time-input-icon-btn{position:absolute;right:0;width:24px;height:24px;padding:0;display:flex;align-items:center;justify-content:center;background:transparent;border:none;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));pointer-events:none}:host .date-time-input-divider{width:1px;height:20px;background-color:var(--mat-divider-color, rgba(0, 0, 0, .12))}:host .date-time-input-time{flex:1;display:flex;min-width:0;align-items:center;gap:2px;padding:0 8px}:host .date-time-input-select{flex:1;height:36px;border:none;background:transparent;color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87));font-size:.875rem;font-weight:500;padding:0 2px;cursor:pointer;text-align:center}:host .date-time-input-select:focus{outline:none}:host .date-time-input-separator{color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));font-weight:500;padding:0 2px;-webkit-user-select:none;user-select:none}\n"] }]
|
|
96
92
|
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], dateValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateValue", required: false }] }], hourValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "hourValue", required: false }] }], minuteValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteValue", required: false }] }], hours: [{ type: i0.Input, args: [{ isSignal: true, alias: "hours", required: false }] }], minutes: [{ type: i0.Input, args: [{ isSignal: true, alias: "minutes", required: false }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }], hourChange: [{ type: i0.Output, args: ["hourChange"] }], minuteChange: [{ type: i0.Output, args: ["minuteChange"] }], timeChange: [{ type: i0.Output, args: ["timeChange"] }] } });
|
|
97
93
|
|
|
94
|
+
/**
|
|
95
|
+
* 格式化日期对象为字符串
|
|
96
|
+
*
|
|
97
|
+
* 将给定的 Date 对象格式化为包含日期和时间的字符串。
|
|
98
|
+
* 日期部分使用提供的 DateAdapter 和 MatDateFormats 进行格式化。
|
|
99
|
+
* 时间部分格式化为 HH:mm (24小时制)。
|
|
100
|
+
*
|
|
101
|
+
* @param date - 要格式化的 Date 对象
|
|
102
|
+
* @param dateAdapter - Angular Material 的 DateAdapter,用于处理日期部分的格式化
|
|
103
|
+
* @param dateFormats - Angular Material 的 MatDateFormats,包含日期格式配置
|
|
104
|
+
* @returns 格式化后的日期时间字符串,例如 "2024-01-24 14:30"
|
|
105
|
+
*/
|
|
106
|
+
function formatDate(date, dateAdapter, dateFormats) {
|
|
107
|
+
const datePart = dateAdapter.format(date, dateFormats.display.dateInput);
|
|
108
|
+
const hours = date.getHours().toString().padStart(2, '0');
|
|
109
|
+
const minutes = date.getMinutes().toString().padStart(2, '0');
|
|
110
|
+
return `${datePart} ${hours}:${minutes}`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const DEFAULT_TIME_RANGES = [
|
|
114
|
+
{ label: '最近5分钟', start: 'offset:-5minutes', end: 'offset:now' },
|
|
115
|
+
{ label: '最近15分钟', start: 'offset:-15minutes', end: 'offset:now' },
|
|
116
|
+
{ label: '最近30分钟', start: 'offset:-30minutes', end: 'offset:now' },
|
|
117
|
+
{ label: '最近1小时', start: 'offset:-1hours', end: 'offset:now' },
|
|
118
|
+
{ label: '最近3小时', start: 'offset:-3hours', end: 'offset:now' },
|
|
119
|
+
{ label: '最近6小时', start: 'offset:-6hours', end: 'offset:now' },
|
|
120
|
+
{ label: '最近12小时', start: 'offset:-12hours', end: 'offset:now' },
|
|
121
|
+
{ label: '最近24小时', start: 'offset:-24hours', end: 'offset:now' },
|
|
122
|
+
{ label: '最近2天', start: 'offset:-2days', end: 'offset:now' },
|
|
123
|
+
{ label: '最近7天', start: 'offset:-7days', end: 'offset:now' },
|
|
124
|
+
{ label: '最近30天', start: 'offset:-30days', end: 'offset:now' },
|
|
125
|
+
{ label: '最近90天', start: 'offset:-90days', end: 'offset:now' },
|
|
126
|
+
{ label: '最近6个月', start: 'offset:-6months', end: 'offset:now' },
|
|
127
|
+
{ label: '最近1年', start: 'offset:-1years', end: 'offset:now' },
|
|
128
|
+
{ label: '最近2年', start: 'offset:-2years', end: 'offset:now' },
|
|
129
|
+
{ label: '最近5年', start: 'offset:-5years', end: 'offset:now' },
|
|
130
|
+
{ label: '昨天', start: 'offset:-1days/start', end: 'offset:-1days/end' },
|
|
131
|
+
{ label: '前天', start: 'offset:-2days/start', end: 'offset:-2days/end' },
|
|
132
|
+
{ label: '上周同一天', start: 'offset:-7days/start', end: 'offset:-7days/end' },
|
|
133
|
+
{ label: '今天', start: 'offset:0days/start', end: 'offset:0days/end' },
|
|
134
|
+
{ label: '今天至今', start: 'offset:0days/start', end: 'offset:now' },
|
|
135
|
+
{ label: '本周至今', start: 'startof:week', end: 'offset:now' },
|
|
136
|
+
{ label: '本月至今', start: 'startof:month', end: 'offset:now' },
|
|
137
|
+
{ label: '今年至今', start: 'startof:year', end: 'offset:now' }
|
|
138
|
+
];
|
|
139
|
+
const FUTURE_TIME_RANGES = [
|
|
140
|
+
{ label: '未来1天', start: 'offset:now', end: 'offset:+1days' },
|
|
141
|
+
{ label: '未来1周', start: 'offset:now', end: 'offset:+1weeks' },
|
|
142
|
+
{ label: '未来1月', start: 'offset:now', end: 'offset:+1months' },
|
|
143
|
+
{ label: '未来3月', start: 'offset:now', end: 'offset:+3months' }
|
|
144
|
+
];
|
|
145
|
+
|
|
98
146
|
class DateSelector {
|
|
99
|
-
#cdr;
|
|
100
147
|
#dialogRef;
|
|
101
148
|
#data;
|
|
102
149
|
#selectionModel;
|
|
103
150
|
#breakpoints;
|
|
104
|
-
formatDate(date) {
|
|
105
|
-
const datePart = this._dateAdapter.format(date, this._dateFormats.display.dateInput);
|
|
106
|
-
const hours = date.getHours().toString().padStart(2, '0');
|
|
107
|
-
const minutes = date.getMinutes().toString().padStart(2, '0');
|
|
108
|
-
return `${datePart} ${hours}:${minutes}`;
|
|
109
|
-
}
|
|
110
151
|
constructor() {
|
|
111
|
-
this.#cdr = inject(ChangeDetectorRef);
|
|
112
152
|
this.#dialogRef = inject((MatDialogRef));
|
|
113
153
|
this.#data = inject(MAT_DIALOG_DATA);
|
|
114
154
|
this.#selectionModel = inject((MatRangeDateSelectionModel));
|
|
@@ -117,7 +157,6 @@ class DateSelector {
|
|
|
117
157
|
this._dateFormats = inject(MAT_DATE_FORMATS);
|
|
118
158
|
this.isMobile = signal(false, ...(ngDevMode ? [{ debugName: "isMobile" }] : []));
|
|
119
159
|
this.data = this.#data;
|
|
120
|
-
this.valueFormat = this.data?.valueFormat ?? 'yyyy-MM-dd HH:mm';
|
|
121
160
|
this.startDate = model('', ...(ngDevMode ? [{ debugName: "startDate" }] : []));
|
|
122
161
|
this.endDate = model('', ...(ngDevMode ? [{ debugName: "endDate" }] : []));
|
|
123
162
|
this.startHour = model(null, ...(ngDevMode ? [{ debugName: "startHour" }] : []));
|
|
@@ -129,71 +168,21 @@ class DateSelector {
|
|
|
129
168
|
const startStr = this.startDate();
|
|
130
169
|
if (!startStr)
|
|
131
170
|
return '';
|
|
132
|
-
return
|
|
171
|
+
return formatDate(new Date(startStr), this._dateAdapter, this._dateFormats);
|
|
133
172
|
}, ...(ngDevMode ? [{ debugName: "displayStart" }] : []));
|
|
134
173
|
this.displayEnd = computed(() => {
|
|
135
174
|
const endStr = this.endDate();
|
|
136
175
|
if (!endStr)
|
|
137
176
|
return '';
|
|
138
|
-
return
|
|
177
|
+
return formatDate(new Date(endStr), this._dateAdapter, this._dateFormats);
|
|
139
178
|
}, ...(ngDevMode ? [{ debugName: "displayEnd" }] : []));
|
|
140
|
-
this.
|
|
141
|
-
['最近5分钟', '-5minutes'],
|
|
142
|
-
['最近15分钟', '-15minutes'],
|
|
143
|
-
['最近30分钟', '-30minutes'],
|
|
144
|
-
['最近1小时', '-1hours'],
|
|
145
|
-
['最近3小时', '-3hours'],
|
|
146
|
-
['最近6小时', '-6hours'],
|
|
147
|
-
['最近12小时', '-12hours'],
|
|
148
|
-
['最近24小时', '-24hours'],
|
|
149
|
-
['最近2天', '-2days'],
|
|
150
|
-
['最近7天', '-7days'],
|
|
151
|
-
['最近30天', '-30days'],
|
|
152
|
-
['最近90天', '-90days'],
|
|
153
|
-
['最近6个月', '-6months'],
|
|
154
|
-
['最近1年', '-1years'],
|
|
155
|
-
['最近2年', '-2years'],
|
|
156
|
-
['最近5年', '-5years'],
|
|
157
|
-
['上周', '-1weeks'],
|
|
158
|
-
['上个月', '-1months'],
|
|
159
|
-
['去年', '-1years']
|
|
160
|
-
];
|
|
161
|
-
this.fixedDays = [
|
|
162
|
-
['昨天', '-1days/day'],
|
|
163
|
-
['前天', '-2days/day'],
|
|
164
|
-
['上周同一天', '-7days/day'],
|
|
165
|
-
['上周', '-1weeks/week'],
|
|
166
|
-
['上个月', '-1months/month'],
|
|
167
|
-
['去年', '-1years/year']
|
|
168
|
-
];
|
|
169
|
-
this.currentPeriods = [
|
|
170
|
-
['今天', 'today', 'today'],
|
|
171
|
-
['今天至今', 'today', 'now'],
|
|
172
|
-
['本周至今', 'thisweek', 'now'],
|
|
173
|
-
['本月至今', 'thismonth', 'now'],
|
|
174
|
-
['今年至今', 'thisyear', 'now']
|
|
175
|
-
];
|
|
176
|
-
this.timeRanges = signal([
|
|
177
|
-
...this.relativeDurations.map(([label, offset]) => ({
|
|
178
|
-
label,
|
|
179
|
-
start: `offset:${offset}`,
|
|
180
|
-
end: 'offset:now'
|
|
181
|
-
})),
|
|
182
|
-
...this.fixedDays.map(([label, point]) => ({
|
|
183
|
-
label,
|
|
184
|
-
start: `offset:${point}`,
|
|
185
|
-
end: `offset:${point}`
|
|
186
|
-
})),
|
|
187
|
-
...this.currentPeriods.map(([label, start, end]) => ({
|
|
188
|
-
label,
|
|
189
|
-
start: `offset:${start}`,
|
|
190
|
-
end: `offset:${end}`
|
|
191
|
-
}))
|
|
192
|
-
], ...(ngDevMode ? [{ debugName: "timeRanges" }] : []));
|
|
179
|
+
this.timeRanges = [...DEFAULT_TIME_RANGES];
|
|
193
180
|
this.selectedTimeRange = model(undefined, ...(ngDevMode ? [{ debugName: "selectedTimeRange" }] : []));
|
|
194
181
|
this.selectedDateRange = null;
|
|
195
182
|
this.now = new Date();
|
|
196
183
|
this.selectingStart = true;
|
|
184
|
+
this.hours = Array.from({ length: 24 }, (_, i) => i);
|
|
185
|
+
this.minutes = Array.from({ length: 60 }, (_, i) => i);
|
|
197
186
|
this.#breakpoints
|
|
198
187
|
.observe([Breakpoints.Handset, Breakpoints.Tablet])
|
|
199
188
|
.pipe(takeUntilDestroyed())
|
|
@@ -212,8 +201,8 @@ class DateSelector {
|
|
|
212
201
|
this.selectedDateRange = new DateRange(start, end);
|
|
213
202
|
this.#selectionModel.updateSelection(this.selectedDateRange, this);
|
|
214
203
|
// 初始化时间值
|
|
215
|
-
this.startDate.set(picker.start);
|
|
216
|
-
this.endDate.set(picker.end);
|
|
204
|
+
this.startDate.set(!isNaN(start.getTime()) ? start.toISOString() : String(picker.start));
|
|
205
|
+
this.endDate.set(!isNaN(end.getTime()) ? end.toISOString() : String(picker.end));
|
|
217
206
|
this.startHour.set(start.getHours());
|
|
218
207
|
this.startMinute.set(start.getMinutes());
|
|
219
208
|
this.endHour.set(end.getHours());
|
|
@@ -221,17 +210,11 @@ class DateSelector {
|
|
|
221
210
|
}
|
|
222
211
|
}
|
|
223
212
|
if (this.future()) {
|
|
224
|
-
|
|
225
|
-
{ label: '未来1天', start: 'offset:now', end: 'offset:+1days' },
|
|
226
|
-
{ label: '未来1周', start: 'offset:now', end: 'offset:+1weeks' },
|
|
227
|
-
{ label: '未来1月', start: 'offset:now', end: 'offset:+1months' },
|
|
228
|
-
{ label: '未来3月', start: 'offset:now', end: 'offset:+3months' }
|
|
229
|
-
];
|
|
230
|
-
this.timeRanges.update(ranges => [...ranges, ...futureOffsets]);
|
|
213
|
+
this.timeRanges = [...this.timeRanges, ...FUTURE_TIME_RANGES];
|
|
231
214
|
}
|
|
232
215
|
}
|
|
233
|
-
|
|
234
|
-
this.selectTimeRange(this.timeRanges
|
|
216
|
+
if (!this.data?.dateTimePicker) {
|
|
217
|
+
this.selectTimeRange(this.timeRanges[5]);
|
|
235
218
|
}
|
|
236
219
|
}
|
|
237
220
|
selectTimeRange(timeRange) {
|
|
@@ -252,46 +235,89 @@ class DateSelector {
|
|
|
252
235
|
const parseTime = (time) => {
|
|
253
236
|
if (!time)
|
|
254
237
|
return new Date(now);
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
return new Date(now);
|
|
259
|
-
const regex = /([+-]?)(\d+)(months?|days?|years?|weeks?|hours?|minutes?)/i;
|
|
260
|
-
const match = regex.exec(offset);
|
|
261
|
-
if (!match)
|
|
262
|
-
return new Date(now);
|
|
263
|
-
const sign = match[1] === '-' ? -1 : 1;
|
|
264
|
-
const value = parseInt(match[2], 10) * sign;
|
|
265
|
-
const unit = match[3].toLowerCase();
|
|
238
|
+
// 处理 startof: 前缀 (本周/本月/今年)
|
|
239
|
+
if (time.startsWith('startof:')) {
|
|
240
|
+
const unit = time.replace('startof:', '').trim().toLowerCase();
|
|
266
241
|
const result = new Date(now);
|
|
242
|
+
result.setHours(0, 0, 0, 0);
|
|
267
243
|
switch (unit) {
|
|
268
|
-
case 'minutes':
|
|
269
|
-
case 'minute':
|
|
270
|
-
result.setMinutes(result.getMinutes() + value);
|
|
271
|
-
break;
|
|
272
|
-
case 'hours':
|
|
273
|
-
case 'hour':
|
|
274
|
-
result.setHours(result.getHours() + value);
|
|
275
|
-
break;
|
|
276
|
-
case 'days':
|
|
277
|
-
case 'day':
|
|
278
|
-
result.setDate(result.getDate() + value);
|
|
279
|
-
break;
|
|
280
|
-
case 'weeks':
|
|
281
244
|
case 'week':
|
|
282
|
-
|
|
245
|
+
// 假设周一为一周的开始
|
|
246
|
+
const day = result.getDay() || 7; // 0是周日,改为7
|
|
247
|
+
if (day !== 1) {
|
|
248
|
+
result.setHours(-24 * (day - 1));
|
|
249
|
+
}
|
|
283
250
|
break;
|
|
284
|
-
case 'months':
|
|
285
251
|
case 'month':
|
|
286
|
-
result.
|
|
252
|
+
result.setDate(1);
|
|
287
253
|
break;
|
|
288
|
-
case 'years':
|
|
289
254
|
case 'year':
|
|
290
|
-
result.
|
|
255
|
+
result.setMonth(0, 1);
|
|
291
256
|
break;
|
|
292
257
|
}
|
|
293
258
|
return result;
|
|
294
259
|
}
|
|
260
|
+
// 处理 offset: 前缀
|
|
261
|
+
if (time.startsWith('offset:')) {
|
|
262
|
+
const offsetStr = time.replace('offset:', '').trim();
|
|
263
|
+
if (offsetStr === 'now')
|
|
264
|
+
return new Date(now);
|
|
265
|
+
// 检查是否有 /start 或 /end 后缀
|
|
266
|
+
let suffix = '';
|
|
267
|
+
let cleanOffset = offsetStr;
|
|
268
|
+
if (offsetStr.endsWith('/start')) {
|
|
269
|
+
suffix = 'start';
|
|
270
|
+
cleanOffset = offsetStr.replace('/start', '');
|
|
271
|
+
}
|
|
272
|
+
else if (offsetStr.endsWith('/end')) {
|
|
273
|
+
suffix = 'end';
|
|
274
|
+
cleanOffset = offsetStr.replace('/end', '');
|
|
275
|
+
}
|
|
276
|
+
const regex = /([+-]?)(\d+)(months?|days?|years?|weeks?|hours?|minutes?)/i;
|
|
277
|
+
const match = regex.exec(cleanOffset);
|
|
278
|
+
// 如果没有匹配到数字偏移量,但有后缀(例如 offset:0days/start),尝试解析
|
|
279
|
+
// 注意:上面的正则也能匹配 0days
|
|
280
|
+
const result = new Date(now);
|
|
281
|
+
if (match) {
|
|
282
|
+
const sign = match[1] === '-' ? -1 : 1;
|
|
283
|
+
const value = parseInt(match[2], 10) * sign;
|
|
284
|
+
const unit = match[3].toLowerCase();
|
|
285
|
+
switch (unit) {
|
|
286
|
+
case 'minutes':
|
|
287
|
+
case 'minute':
|
|
288
|
+
result.setMinutes(result.getMinutes() + value);
|
|
289
|
+
break;
|
|
290
|
+
case 'hours':
|
|
291
|
+
case 'hour':
|
|
292
|
+
result.setHours(result.getHours() + value);
|
|
293
|
+
break;
|
|
294
|
+
case 'days':
|
|
295
|
+
case 'day':
|
|
296
|
+
result.setDate(result.getDate() + value);
|
|
297
|
+
break;
|
|
298
|
+
case 'weeks':
|
|
299
|
+
case 'week':
|
|
300
|
+
result.setDate(result.getDate() + value * 7);
|
|
301
|
+
break;
|
|
302
|
+
case 'months':
|
|
303
|
+
case 'month':
|
|
304
|
+
result.setMonth(result.getMonth() + value);
|
|
305
|
+
break;
|
|
306
|
+
case 'years':
|
|
307
|
+
case 'year':
|
|
308
|
+
result.setFullYear(result.getFullYear() + value);
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
// 应用后缀修正
|
|
313
|
+
if (suffix === 'start') {
|
|
314
|
+
result.setHours(0, 0, 0, 0);
|
|
315
|
+
}
|
|
316
|
+
else if (suffix === 'end') {
|
|
317
|
+
result.setHours(23, 59, 59, 999);
|
|
318
|
+
}
|
|
319
|
+
return result;
|
|
320
|
+
}
|
|
295
321
|
return new Date(time);
|
|
296
322
|
};
|
|
297
323
|
const startDate = timeRange.start ? parseTime(timeRange.start) : null;
|
|
@@ -350,33 +376,79 @@ class DateSelector {
|
|
|
350
376
|
this.selectedDateRange = range;
|
|
351
377
|
this.startDate.set(start?.toISOString() ?? '');
|
|
352
378
|
this.endDate.set(end?.toISOString() ?? '');
|
|
379
|
+
if (start) {
|
|
380
|
+
this.startHour.set(start.getHours());
|
|
381
|
+
this.startMinute.set(start.getMinutes());
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
this.startHour.set(null);
|
|
385
|
+
this.startMinute.set(null);
|
|
386
|
+
}
|
|
387
|
+
if (end) {
|
|
388
|
+
this.endHour.set(end.getHours());
|
|
389
|
+
this.endMinute.set(end.getMinutes());
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
this.endHour.set(null);
|
|
393
|
+
this.endMinute.set(null);
|
|
394
|
+
}
|
|
353
395
|
}
|
|
354
396
|
rangeChanged(selectedDate) {
|
|
355
397
|
if (!selectedDate)
|
|
356
398
|
return;
|
|
357
|
-
// 创建一个新日期对象,保留日期部分,但使用当前时间作为时间部分
|
|
358
|
-
const now = new Date();
|
|
359
|
-
const dateWithCurrentTime = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate(), now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds());
|
|
360
399
|
if (this.selectingStart) {
|
|
361
|
-
|
|
400
|
+
// 正在选择开始日期
|
|
401
|
+
let h = 0, m = 0, s = 0, ms = 0;
|
|
402
|
+
// 尝试保留之前的开始时间
|
|
403
|
+
if (this.selectedDateRange?.start) {
|
|
404
|
+
h = this.selectedDateRange.start.getHours();
|
|
405
|
+
m = this.selectedDateRange.start.getMinutes();
|
|
406
|
+
s = this.selectedDateRange.start.getSeconds();
|
|
407
|
+
}
|
|
408
|
+
const newStart = new Date(selectedDate);
|
|
409
|
+
newStart.setHours(h, m, s, ms);
|
|
410
|
+
this.startDate.set(newStart.toISOString());
|
|
362
411
|
this.endDate.set('');
|
|
363
|
-
this.startHour.set(
|
|
364
|
-
this.startMinute.set(
|
|
412
|
+
this.startHour.set(newStart.getHours());
|
|
413
|
+
this.startMinute.set(newStart.getMinutes());
|
|
365
414
|
this.endHour.set(null);
|
|
366
415
|
this.endMinute.set(null);
|
|
367
416
|
this.selectedTimeRange.set(undefined);
|
|
368
|
-
this.selectedDateRange = new DateRange(
|
|
417
|
+
this.selectedDateRange = new DateRange(newStart, null);
|
|
369
418
|
this.#selectionModel.updateSelection(this.selectedDateRange, this);
|
|
370
419
|
this.selectingStart = false;
|
|
371
420
|
}
|
|
372
421
|
else {
|
|
422
|
+
// 正在选择结束日期
|
|
373
423
|
const start = this.#selectionModel.selection.start;
|
|
374
424
|
if (!start)
|
|
375
425
|
return;
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
426
|
+
const startDay = new Date(start.getFullYear(), start.getMonth(), start.getDate());
|
|
427
|
+
const selectedDay = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate());
|
|
428
|
+
let newStart;
|
|
429
|
+
let newEnd;
|
|
430
|
+
if (selectedDay.getTime() < startDay.getTime()) {
|
|
431
|
+
// 用户选了一个比 Start 更早的日期 -> 交换角色
|
|
432
|
+
// 新 Start (selectedDate) 设为 00:00
|
|
433
|
+
newStart = new Date(selectedDate);
|
|
434
|
+
newStart.setHours(0, 0, 0, 0);
|
|
435
|
+
// 新 End (旧 start) 设为 23:59
|
|
436
|
+
newEnd = new Date(start);
|
|
437
|
+
newEnd.setHours(23, 59, 59, 999);
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
// 正常顺序 (selectedDate >= start)
|
|
441
|
+
// Start 保持原样
|
|
442
|
+
newStart = new Date(start);
|
|
443
|
+
// End (selectedDate) 设为 23:59
|
|
444
|
+
newEnd = new Date(selectedDate);
|
|
445
|
+
newEnd.setHours(23, 59, 59, 999);
|
|
446
|
+
// 如果是同一天,确保 Start <= End
|
|
447
|
+
if (newStart.getTime() > newEnd.getTime()) {
|
|
448
|
+
newStart.setHours(0, 0, 0, 0);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
this.updateSelection(newStart, newEnd);
|
|
380
452
|
this.selectingStart = true;
|
|
381
453
|
}
|
|
382
454
|
}
|
|
@@ -392,13 +464,17 @@ class DateSelector {
|
|
|
392
464
|
this.endMinute.set(end.getMinutes());
|
|
393
465
|
}
|
|
394
466
|
submit() {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
const
|
|
467
|
+
if (!this.selectedDateRange?.start || !this.selectedDateRange?.end) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
const start = new Date(this.selectedDateRange.start);
|
|
471
|
+
const end = new Date(this.selectedDateRange.end);
|
|
472
|
+
if (isNaN(start.getTime()) || isNaN(end.getTime())) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
399
475
|
const result = {
|
|
400
|
-
start:
|
|
401
|
-
end:
|
|
476
|
+
start: start.toISOString(),
|
|
477
|
+
end: end.toISOString()
|
|
402
478
|
};
|
|
403
479
|
this.data = { ...this.data, dateTimePicker: result };
|
|
404
480
|
this.#dialogRef.close(this.data);
|
|
@@ -406,12 +482,6 @@ class DateSelector {
|
|
|
406
482
|
dismiss() {
|
|
407
483
|
this.#dialogRef.close(undefined);
|
|
408
484
|
}
|
|
409
|
-
getHours() {
|
|
410
|
-
return Array.from({ length: 24 }, (_, i) => i);
|
|
411
|
-
}
|
|
412
|
-
getMinutes() {
|
|
413
|
-
return Array.from({ length: 60 }, (_, i) => i);
|
|
414
|
-
}
|
|
415
485
|
updateStartTime() {
|
|
416
486
|
if (this.selectedDateRange?.start && this.startHour() !== null && this.startMinute() !== null) {
|
|
417
487
|
const startDate = new Date(this.selectedDateRange.start);
|
|
@@ -438,7 +508,7 @@ class DateSelector {
|
|
|
438
508
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: DateSelector, isStandalone: true, selector: "date-time-picker-selector", inputs: { startDate: { classPropertyName: "startDate", publicName: "startDate", isSignal: true, isRequired: false, transformFunction: null }, endDate: { classPropertyName: "endDate", publicName: "endDate", isSignal: true, isRequired: false, transformFunction: null }, startHour: { classPropertyName: "startHour", publicName: "startHour", isSignal: true, isRequired: false, transformFunction: null }, startMinute: { classPropertyName: "startMinute", publicName: "startMinute", isSignal: true, isRequired: false, transformFunction: null }, endHour: { classPropertyName: "endHour", publicName: "endHour", isSignal: true, isRequired: false, transformFunction: null }, endMinute: { classPropertyName: "endMinute", publicName: "endMinute", isSignal: true, isRequired: false, transformFunction: null }, future: { classPropertyName: "future", publicName: "future", isSignal: true, isRequired: false, transformFunction: null }, selectedTimeRange: { classPropertyName: "selectedTimeRange", publicName: "selectedTimeRange", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { startDate: "startDateChange", endDate: "endDateChange", startHour: "startHourChange", startMinute: "startMinuteChange", endHour: "endHourChange", endMinute: "endMinuteChange", future: "futureChange", selectedTimeRange: "selectedTimeRangeChange" }, providers: [
|
|
439
509
|
DefaultMatCalendarRangeStrategy,
|
|
440
510
|
MatRangeDateSelectionModel
|
|
441
|
-
], viewQueries: [{ propertyName: "sidenav", first: true, predicate: ["sidenav"], descendants: true }], ngImport: i0, template: "<date-time-picker-container\r\n headerTitle=\"\u65E5\u671F\u65F6\u95F4\u9009\u62E9\u5668\"\r\n submitTitle=\"\u5E94\u7528\"\r\n [disabledSubmit]=\"!selectedDateRange\"\r\n [footerExtraContent]=\"footerExtraContent\"\r\n (submit)=\"submit()\"\r\n (dismiss)=\"dismiss()\"\r\n>\r\n <mat-sidenav-container class=\"date-selector-sidenav-container\">\r\n <!-- \u5DE6\u4FA7\u5FEB\u6377\u9009\u62E9\u9762\u677F -->\r\n <mat-sidenav\r\n #sidenav\r\n [mode]=\"isMobile() ? 'over' : 'side'\"\r\n [opened]=\"!isMobile()\"\r\n class=\"date-selector-sidebar\"\r\n dir=\"rtl\"\r\n >\r\n <div class=\"date-selector-sidebar-inner\" dir=\"ltr\">\r\n <div class=\"date-selector-sidebar-header\">\r\n <span class=\"date-selector-sidebar-title\">\u5FEB\u6377\u9009\u62E9</span>\r\n @if (isMobile()) {\r\n <button mat-icon-button (click)=\"sidenav.close()\">\r\n <i-tabler name=\"layout-sidebar-left-collapse\" />\r\n </button>\r\n }\r\n </div>\r\n <ul class=\"date-selector-sidebar-list\">\r\n @for (timeRangeItem of timeRanges(); track timeRangeItem) {\r\n <li class=\"date-selector-sidebar-item\">\r\n <button\r\n type=\"button\"\r\n (click)=\"selectTimeRange(timeRangeItem); isMobile() && sidenav.close()\"\r\n [class.selected]=\"selectedTimeRange() && selectedTimeRange()?.start === timeRangeItem.start && selectedTimeRange()?.end === timeRangeItem.end\"\r\n class=\"date-selector-sidebar-btn\"\r\n >\r\n <span class=\"date-selector-sidebar-text\">{{ timeRangeItem.label }}</span>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n </mat-sidenav>\r\n <!-- \u5DE6\u4FA7\u5FEB\u6377\u9009\u62E9\u9762\u677F\u7ED3\u675F -->\r\n\r\n <mat-sidenav-content>\r\n @if (isMobile()) {\r\n <div class=\"date-selector-mobile-toolbar\">\r\n <button mat-button (click)=\"sidenav.open()\">\r\n <span>\u5FEB\u6377\u9009\u62E9</span>\r\n </button>\r\n </div>\r\n }\r\n\r\n <!-- \u4E3B\u8981\u5185\u5BB9\u533A\u57DF -->\r\n <div class=\"date-selector-main\">\r\n <div class=\"date-selector-content\">\r\n <!-- \u65E5\u5386\u5BB9\u5668 -->\r\n <section class=\"date-selector-calendar-section\">\r\n <div class=\"date-selector-calendar-wrapper\">\r\n <mat-calendar [maxDate]=\"!future() ? now : undefined\" [(selected)]=\"selectedDateRange\" (selectedChange)=\"rangeChanged($event)\" class=\"date-selector-calendar\" />\r\n </div>\r\n </section>\r\n <!-- \u65E5\u5386\u5BB9\u5668\u7ED3\u675F -->\r\n\r\n <!-- \u65F6\u95F4\u8BBE\u7F6E\u5BB9\u5668 -->\r\n <section class=\"date-selector-time-section\">\r\n <!-- \u5F00\u59CB\u548C\u7ED3\u675F\u8F93\u5165\u65E5\u671F -->\r\n <div class=\"date-selector-inputs\">\r\n <!-- \u4ECE\u65E5\u671F -->\r\n <date-time-input\r\n label=\"\u5F00\u59CB\u65E5\u671F\"\r\n [dateValue]=\"startDate()\"\r\n [hourValue]=\"startHour()\"\r\n (hourChange)=\"startHour.set($event)\"\r\n [minuteValue]=\"startMinute()\"\r\n (minuteChange)=\"startMinute.set($event)\"\r\n [hours]=\"getHours()\"\r\n [minutes]=\"getMinutes()\"\r\n (dateChange)=\"changeDatePart('start', $event)\"\r\n (timeChange)=\"updateStartTime()\"\r\n />\r\n\r\n <!-- \u7ED3\u675F\u65E5\u671F -->\r\n <date-time-input\r\n label=\"\u7ED3\u675F\u65E5\u671F\"\r\n [dateValue]=\"endDate()\"\r\n [hourValue]=\"endHour()\"\r\n (hourChange)=\"endHour.set($event)\"\r\n [minuteValue]=\"endMinute()\"\r\n (minuteChange)=\"endMinute.set($event)\"\r\n [hours]=\"getHours()\"\r\n [minutes]=\"getMinutes()\"\r\n (dateChange)=\"changeDatePart('end', $event)\"\r\n (timeChange)=\"updateEndTime()\"\r\n />\r\n </div>\r\n\r\n <div class=\"date-selector-hint-wrapper\">\r\n <div class=\"date-selector-hint\">\r\n <i-tabler name=\"info-circle\" strokeWidth=\"2px\" class=\"date-selector-hint-icon\"></i-tabler>\r\n <span class=\"date-selector-hint-text\">\u5982\u679C\u8981\u9009\u62E9\u4E00\u5929\uFF0C\u8BF7\u53CC\u51FB\u8BE5\u5929\u3002</span>\r\n </div>\r\n </div>\r\n\r\n </section>\r\n </div>\r\n </div>\r\n </mat-sidenav-content>\r\n </mat-sidenav-container>\r\n</date-time-picker-container>\r\n\r\n<ng-template #footerExtraContent>\r\n <div class=\"date-selector-footer-range\">\r\n <span class=\"date-selector-footer-label\">\u8303\u56F4\uFF1A</span>\r\n\r\n @if (startDate()) {\r\n <div class=\"date-selector-footer-value\">\r\n @if (startDate()) {\r\n <span class=\"date-selector-footer-date\">{{ displayStart() }}</span>\r\n }\r\n\r\n @if (startDate() && endDate()) {\r\n <span class=\"date-selector-footer-separator\">-</span>\r\n }\r\n\r\n @if (endDate()) {\r\n <span class=\"date-selector-footer-date\">{{ displayEnd() }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.date-selector-sidebar{width:12rem;height:100%;background-color:var(--mat-sys-surface-container, #fafafa);border-right:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));display:flex;flex-direction:column}.date-selector-sidebar-inner{width:100%;height:100%;display:flex;flex-direction:column;padding:0}.date-selector-sidebar-header{padding:12px 16px;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));background-color:var(--mat-sys-surface, #fff);position:sticky;top:0;z-index:1;display:flex;justify-content:space-between;align-items:center}.date-selector-sidebar-title{font-size:.75rem;font-weight:500;text-transform:uppercase;letter-spacing:.5px;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.date-selector-sidebar-list{list-style:none;margin:0;padding:4px 0;flex:1;overflow-y:auto;overflow-x:hidden}.date-selector-sidebar-item{margin:0;padding:0}.date-selector-sidebar-btn{width:100%;padding:8px 12px;background:transparent;border:none;cursor:pointer;font-size:.8125rem;font-weight:500;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));text-align:left;transition:all .2s ease;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.date-selector-sidebar-btn:hover{background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .08));color:var(--mat-sys-primary, #1976d2);padding-left:16px}.date-selector-sidebar-btn.selected{background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .16));color:var(--mat-sys-primary, #1976d2);font-weight:600;padding-left:16px}.date-selector-sidebar-btn:focus-visible{outline:2px solid var(--mat-sys-primary, #1976d2);outline-offset:-2px}.date-selector-sidebar-text{display:block}.date-selector-main{width:100%;height:100%;display:flex;background-color:var(--mat-sys-surface, #fff)}@media(max-width:767px){.date-selector-main{height:auto;flex:1}}.date-selector-content{width:100%;height:100%;display:flex;flex-direction:column}@media(min-width:768px){.date-selector-content{flex-direction:row}}.date-selector-calendar-section{width:100%;display:flex;align-items:center;justify-content:center;padding:16px;border-right:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));box-sizing:border-box}@media(min-width:768px){.date-selector-calendar-section{width:50%}}@media(max-width:767px){.date-selector-calendar-section{border-right:none;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));padding-top:0;padding-bottom:0}}.date-selector-calendar-wrapper{width:100%;display:flex;flex-direction:column;gap:16px}.date-selector-calendar{width:100%}.date-selector-hint{display:flex;align-items:flex-start;gap:8px;padding:12px 16px;background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .08));border:1px solid var(--mat-outline-variant, rgba(25, 118, 210, .16));border-radius:4px;align-items:center}.date-selector-hint-icon{flex-shrink:0;color:var(--mat-sys-primary, #1976d2);margin-top:2px}.date-selector-hint-text{font-size:.75rem;line-height:1.25;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.date-selector-hint-wrapper{padding:12px 16px}.date-selector-time-section{width:100%;display:flex;flex-direction:column}@media(min-width:768px){.date-selector-time-section{width:50%}}.date-selector-inputs{display:flex;flex-direction:column;padding:0}.date-selector-footer-range{display:flex;align-items:center;gap:8px;font-size:.75rem;margin-right:auto;padding:0 8px}.date-selector-footer-label{font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));display:none}@media(min-width:768px){.date-selector-footer-label{display:block}}.date-selector-footer-value{display:flex;flex-direction:column;gap:0;font-weight:600}@media(min-width:768px){.date-selector-footer-value{flex-direction:row;gap:8px;align-items:center}}.date-selector-footer-date{color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87));white-space:nowrap}.date-selector-footer-separator{color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));display:none}@media(min-width:768px){.date-selector-footer-separator{display:block}}.date-selector-sidenav-container{width:100%;height:100%;background-color:transparent}.date-selector-mobile-toolbar{padding:8px;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));display:flex;align-items:center}\n", ":host{display:block;height:100%}\n"], dependencies: [{ kind: "component", type: 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: "component", type: TablerIconComponent, selector: "i-tabler, tabler-icon", inputs: ["name"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "directive", type: i1$1.Dir, selector: "[dir]", inputs: ["dir"], outputs: ["dirChange"], exportAs: ["dir"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: Container, selector: "date-time-picker-container", inputs: ["hasHeader", "hasFooter", "headerTitle", "headerExtraContent", "footerExtraContent", "hasDismiss", "hasSubmit", "submitTitle", "submitBg", "submitColor", "submitTitleColor", "disabledSubmit", "hasSecondaryButton", "secondaryButtonTitle", "secondaryButtonBg", "secondaryButtonColor", "secondaryButtonTitleColor", "disabledSecondaryButton"], outputs: ["hasHeaderChange", "hasFooterChange", "headerTitleChange", "headerExtraContentChange", "footerExtraContentChange", "hasDismissChange", "hasSubmitChange", "submitTitleChange", "submitBgChange", "submitColorChange", "submitTitleColorChange", "disabledSubmitChange", "hasSecondaryButtonChange", "secondaryButtonTitleChange", "secondaryButtonBgChange", "secondaryButtonColorChange", "secondaryButtonTitleColorChange", "disabledSecondaryButtonChange", "dismiss", "submit", "secondaryButton"] }, { kind: "component", type: DateTimeInputComponent, selector: "date-time-input", inputs: ["label", "dateValue", "hourValue", "minuteValue", "hours", "minutes"], outputs: ["dateChange", "hourChange", "minuteChange", "timeChange"] }, { kind: "ngmodule", type: MatSidenavModule }, { kind: "component", type: i2$1.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i2$1.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i2$1.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
511
|
+
], viewQueries: [{ propertyName: "sidenav", first: true, predicate: ["sidenav"], descendants: true }], ngImport: i0, template: "<date-time-picker-container\r\n headerTitle=\"\u65E5\u671F\u65F6\u95F4\u9009\u62E9\u5668\"\r\n submitTitle=\"\u5E94\u7528\"\r\n [disabledSubmit]=\"!selectedDateRange\"\r\n [footerExtraContent]=\"footerExtraContent\"\r\n (submit)=\"submit()\"\r\n (dismiss)=\"dismiss()\"\r\n>\r\n <mat-sidenav-container class=\"date-selector-sidenav-container\">\r\n <!-- \u5DE6\u4FA7\u5FEB\u6377\u9009\u62E9\u9762\u677F -->\r\n <mat-sidenav #sidenav [mode]=\"isMobile() ? 'over' : 'side'\" [opened]=\"!isMobile()\" class=\"date-selector-sidebar\" dir=\"rtl\">\r\n <div class=\"date-selector-sidebar-inner\" dir=\"ltr\">\r\n <div class=\"date-selector-sidebar-header\">\r\n <span class=\"date-selector-sidebar-title\">\u5FEB\u6377\u9009\u62E9</span>\r\n @if (isMobile()) {\r\n <button mat-icon-button (click)=\"sidenav.close()\">\r\n <i-tabler name=\"layout-sidebar-left-collapse\" />\r\n </button>\r\n }\r\n </div>\r\n <ul class=\"date-selector-sidebar-list\">\r\n @for (timeRangeItem of timeRanges; track timeRangeItem) {\r\n <li class=\"date-selector-sidebar-item\">\r\n <button\r\n type=\"button\"\r\n (click)=\"selectTimeRange(timeRangeItem); isMobile() && sidenav.close()\"\r\n [class.selected]=\"selectedTimeRange() && selectedTimeRange()?.start === timeRangeItem.start && selectedTimeRange()?.end === timeRangeItem.end\"\r\n class=\"date-selector-sidebar-btn\"\r\n >\r\n <span class=\"date-selector-sidebar-text\">{{ timeRangeItem.label }}</span>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n </mat-sidenav>\r\n <!-- \u5DE6\u4FA7\u5FEB\u6377\u9009\u62E9\u9762\u677F\u7ED3\u675F -->\r\n\r\n <mat-sidenav-content>\r\n @if (isMobile()) {\r\n <div class=\"date-selector-mobile-toolbar\">\r\n <button mat-button (click)=\"sidenav.open()\">\r\n <span>\u5FEB\u6377\u9009\u62E9</span>\r\n </button>\r\n </div>\r\n }\r\n\r\n <!-- \u4E3B\u8981\u5185\u5BB9\u533A\u57DF -->\r\n <div class=\"date-selector-main\">\r\n <div class=\"date-selector-content\">\r\n <!-- \u65E5\u5386\u5BB9\u5668 -->\r\n <section class=\"date-selector-calendar-section\">\r\n <div class=\"date-selector-calendar-wrapper\">\r\n <mat-calendar [maxDate]=\"!future() ? now : undefined\" [(selected)]=\"selectedDateRange\" (selectedChange)=\"rangeChanged($event)\" class=\"date-selector-calendar\" />\r\n </div>\r\n </section>\r\n <!-- \u65E5\u5386\u5BB9\u5668\u7ED3\u675F -->\r\n\r\n <!-- \u65F6\u95F4\u8BBE\u7F6E\u5BB9\u5668 -->\r\n <section class=\"date-selector-time-section\">\r\n <!-- \u5F00\u59CB\u548C\u7ED3\u675F\u8F93\u5165\u65E5\u671F -->\r\n <div class=\"date-selector-inputs\">\r\n <!-- \u4ECE\u65E5\u671F -->\r\n <date-time-input\r\n label=\"\u5F00\u59CB\u65E5\u671F\"\r\n [dateValue]=\"startDate()\"\r\n [hourValue]=\"startHour()\"\r\n (hourChange)=\"startHour.set($event)\"\r\n [minuteValue]=\"startMinute()\"\r\n (minuteChange)=\"startMinute.set($event)\"\r\n [hours]=\"hours\"\r\n [minutes]=\"minutes\"\r\n (dateChange)=\"changeDatePart('start', $event)\"\r\n (timeChange)=\"updateStartTime()\"\r\n />\r\n\r\n <!-- \u7ED3\u675F\u65E5\u671F -->\r\n <date-time-input\r\n label=\"\u7ED3\u675F\u65E5\u671F\"\r\n [dateValue]=\"endDate()\"\r\n [hourValue]=\"endHour()\"\r\n (hourChange)=\"endHour.set($event)\"\r\n [minuteValue]=\"endMinute()\"\r\n (minuteChange)=\"endMinute.set($event)\"\r\n [hours]=\"hours\"\r\n [minutes]=\"minutes\"\r\n (dateChange)=\"changeDatePart('end', $event)\"\r\n (timeChange)=\"updateEndTime()\"\r\n />\r\n </div>\r\n\r\n <div class=\"date-selector-hint-wrapper\">\r\n <div class=\"date-selector-hint\">\r\n <i-tabler name=\"info-circle\" strokeWidth=\"2px\" class=\"date-selector-hint-icon\"></i-tabler>\r\n <span class=\"date-selector-hint-text\">\u5982\u679C\u8981\u9009\u62E9\u4E00\u5929\uFF0C\u8BF7\u53CC\u51FB\u8BE5\u5929\u3002</span>\r\n </div>\r\n </div>\r\n </section>\r\n </div>\r\n </div>\r\n </mat-sidenav-content>\r\n </mat-sidenav-container>\r\n</date-time-picker-container>\r\n\r\n<ng-template #footerExtraContent>\r\n <div class=\"date-selector-footer-range\">\r\n <span class=\"date-selector-footer-label\">\u8303\u56F4\uFF1A</span>\r\n\r\n @if (startDate()) {\r\n <div class=\"date-selector-footer-value\">\r\n @if (startDate()) {\r\n <span class=\"date-selector-footer-date\">{{ displayStart() }}</span>\r\n }\r\n\r\n @if (startDate() && endDate()) {\r\n <span class=\"date-selector-footer-separator\">-</span>\r\n }\r\n\r\n @if (endDate()) {\r\n <span class=\"date-selector-footer-date\">{{ displayEnd() }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.date-selector-sidebar{width:12rem;height:100%;background-color:var(--mat-sys-surface-container, #fafafa);border-right:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));display:flex;flex-direction:column}.date-selector-sidebar-inner{width:100%;height:100%;display:flex;flex-direction:column;padding:0}.date-selector-sidebar-header{padding:12px 16px;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));background-color:var(--mat-sys-surface, #fff);position:sticky;top:0;z-index:1;display:flex;justify-content:space-between;align-items:center}.date-selector-sidebar-title{font-size:.75rem;font-weight:500;text-transform:uppercase;letter-spacing:.5px;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.date-selector-sidebar-list{list-style:none;margin:0;padding:4px 0;flex:1;overflow-y:auto;overflow-x:hidden}.date-selector-sidebar-item{margin:0;padding:0}.date-selector-sidebar-btn{width:100%;padding:8px 12px;background:transparent;border:none;cursor:pointer;font-size:.8125rem;font-weight:500;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));text-align:left;transition:all .2s ease;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.date-selector-sidebar-btn:hover{background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .08));color:var(--mat-sys-primary, #1976d2);padding-left:16px}.date-selector-sidebar-btn.selected{background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .16));color:var(--mat-sys-primary, #1976d2);font-weight:600;padding-left:16px}.date-selector-sidebar-btn:focus-visible{outline:2px solid var(--mat-sys-primary, #1976d2);outline-offset:-2px}.date-selector-sidebar-text{display:block}.date-selector-main{width:100%;height:100%;display:flex;background-color:var(--mat-sys-surface, #fff)}@media(max-width:767px){.date-selector-main{height:auto;flex:1}}.date-selector-content{width:100%;height:100%;display:flex;flex-direction:column}@media(min-width:768px){.date-selector-content{flex-direction:row}}.date-selector-calendar-section{width:100%;display:flex;align-items:center;justify-content:center;padding:16px;border-right:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));box-sizing:border-box}@media(min-width:768px){.date-selector-calendar-section{width:50%}}@media(max-width:767px){.date-selector-calendar-section{border-right:none;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));padding-top:0;padding-bottom:0}}.date-selector-calendar-wrapper{width:100%;display:flex;flex-direction:column;gap:16px}.date-selector-calendar{width:100%}.date-selector-hint{display:flex;align-items:flex-start;gap:8px;padding:12px 16px;background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .08));border:1px solid var(--mat-outline-variant, rgba(25, 118, 210, .16));border-radius:4px;align-items:center}.date-selector-hint-icon{flex-shrink:0;color:var(--mat-sys-primary, #1976d2);margin-top:2px}.date-selector-hint-text{font-size:.75rem;line-height:1.25;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.date-selector-hint-wrapper{padding:12px 16px}.date-selector-time-section{width:100%;display:flex;flex-direction:column}@media(min-width:768px){.date-selector-time-section{width:50%}}.date-selector-inputs{display:flex;flex-direction:column;padding:0}.date-selector-footer-range{display:flex;align-items:center;gap:8px;font-size:.75rem;margin-right:auto;padding:0 8px}.date-selector-footer-label{font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));display:none}@media(min-width:768px){.date-selector-footer-label{display:block}}.date-selector-footer-value{display:flex;flex-direction:column;gap:0;font-weight:600}@media(min-width:768px){.date-selector-footer-value{flex-direction:row;gap:8px;align-items:center}}.date-selector-footer-date{color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87));white-space:nowrap}.date-selector-footer-separator{color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));display:none}@media(min-width:768px){.date-selector-footer-separator{display:block}}.date-selector-sidenav-container{width:100%;height:100%;background-color:transparent}.date-selector-mobile-toolbar{padding:8px;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));display:flex;align-items:center}\n", ":host{display:block;height:100%}\n"], dependencies: [{ kind: "component", type: 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: "component", type: TablerIconComponent, selector: "i-tabler, tabler-icon", inputs: ["name"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "directive", type: i1$1.Dir, selector: "[dir]", inputs: ["dir"], outputs: ["dirChange"], exportAs: ["dir"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: Container, selector: "date-time-picker-container", inputs: ["hasHeader", "hasFooter", "headerTitle", "headerExtraContent", "footerExtraContent", "hasDismiss", "hasSubmit", "submitTitle", "submitBg", "submitColor", "submitTitleColor", "disabledSubmit", "hasSecondaryButton", "secondaryButtonTitle", "secondaryButtonBg", "secondaryButtonColor", "secondaryButtonTitleColor", "disabledSecondaryButton"], outputs: ["hasHeaderChange", "hasFooterChange", "headerTitleChange", "headerExtraContentChange", "footerExtraContentChange", "hasDismissChange", "hasSubmitChange", "submitTitleChange", "submitBgChange", "submitColorChange", "submitTitleColorChange", "disabledSubmitChange", "hasSecondaryButtonChange", "secondaryButtonTitleChange", "secondaryButtonBgChange", "secondaryButtonColorChange", "secondaryButtonTitleColorChange", "disabledSecondaryButtonChange", "dismiss", "submit", "secondaryButton"] }, { kind: "component", type: DateTimeInputComponent, selector: "date-time-input", inputs: ["label", "dateValue", "hourValue", "minuteValue", "hours", "minutes"], outputs: ["dateChange", "hourChange", "minuteChange", "timeChange"] }, { kind: "ngmodule", type: MatSidenavModule }, { kind: "component", type: i2$1.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i2$1.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i2$1.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
442
512
|
}
|
|
443
513
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DateSelector, decorators: [{
|
|
444
514
|
type: Component,
|
|
@@ -455,7 +525,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
|
|
|
455
525
|
DateTimeInputComponent,
|
|
456
526
|
MatSidenavModule,
|
|
457
527
|
MatButtonModule
|
|
458
|
-
], template: "<date-time-picker-container\r\n headerTitle=\"\u65E5\u671F\u65F6\u95F4\u9009\u62E9\u5668\"\r\n submitTitle=\"\u5E94\u7528\"\r\n [disabledSubmit]=\"!selectedDateRange\"\r\n [footerExtraContent]=\"footerExtraContent\"\r\n (submit)=\"submit()\"\r\n (dismiss)=\"dismiss()\"\r\n>\r\n <mat-sidenav-container class=\"date-selector-sidenav-container\">\r\n <!-- \u5DE6\u4FA7\u5FEB\u6377\u9009\u62E9\u9762\u677F -->\r\n <mat-sidenav\r\n #sidenav\r\n [mode]=\"isMobile() ? 'over' : 'side'\"\r\n [opened]=\"!isMobile()\"\r\n class=\"date-selector-sidebar\"\r\n dir=\"rtl\"\r\n >\r\n <div class=\"date-selector-sidebar-inner\" dir=\"ltr\">\r\n <div class=\"date-selector-sidebar-header\">\r\n <span class=\"date-selector-sidebar-title\">\u5FEB\u6377\u9009\u62E9</span>\r\n @if (isMobile()) {\r\n <button mat-icon-button (click)=\"sidenav.close()\">\r\n <i-tabler name=\"layout-sidebar-left-collapse\" />\r\n </button>\r\n }\r\n </div>\r\n <ul class=\"date-selector-sidebar-list\">\r\n @for (timeRangeItem of timeRanges(); track timeRangeItem) {\r\n <li class=\"date-selector-sidebar-item\">\r\n <button\r\n type=\"button\"\r\n (click)=\"selectTimeRange(timeRangeItem); isMobile() && sidenav.close()\"\r\n [class.selected]=\"selectedTimeRange() && selectedTimeRange()?.start === timeRangeItem.start && selectedTimeRange()?.end === timeRangeItem.end\"\r\n class=\"date-selector-sidebar-btn\"\r\n >\r\n <span class=\"date-selector-sidebar-text\">{{ timeRangeItem.label }}</span>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n </mat-sidenav>\r\n <!-- \u5DE6\u4FA7\u5FEB\u6377\u9009\u62E9\u9762\u677F\u7ED3\u675F -->\r\n\r\n <mat-sidenav-content>\r\n @if (isMobile()) {\r\n <div class=\"date-selector-mobile-toolbar\">\r\n <button mat-button (click)=\"sidenav.open()\">\r\n <span>\u5FEB\u6377\u9009\u62E9</span>\r\n </button>\r\n </div>\r\n }\r\n\r\n <!-- \u4E3B\u8981\u5185\u5BB9\u533A\u57DF -->\r\n <div class=\"date-selector-main\">\r\n <div class=\"date-selector-content\">\r\n <!-- \u65E5\u5386\u5BB9\u5668 -->\r\n <section class=\"date-selector-calendar-section\">\r\n <div class=\"date-selector-calendar-wrapper\">\r\n <mat-calendar [maxDate]=\"!future() ? now : undefined\" [(selected)]=\"selectedDateRange\" (selectedChange)=\"rangeChanged($event)\" class=\"date-selector-calendar\" />\r\n </div>\r\n </section>\r\n <!-- \u65E5\u5386\u5BB9\u5668\u7ED3\u675F -->\r\n\r\n <!-- \u65F6\u95F4\u8BBE\u7F6E\u5BB9\u5668 -->\r\n <section class=\"date-selector-time-section\">\r\n <!-- \u5F00\u59CB\u548C\u7ED3\u675F\u8F93\u5165\u65E5\u671F -->\r\n <div class=\"date-selector-inputs\">\r\n <!-- \u4ECE\u65E5\u671F -->\r\n <date-time-input\r\n label=\"\u5F00\u59CB\u65E5\u671F\"\r\n [dateValue]=\"startDate()\"\r\n [hourValue]=\"startHour()\"\r\n (hourChange)=\"startHour.set($event)\"\r\n [minuteValue]=\"startMinute()\"\r\n (minuteChange)=\"startMinute.set($event)\"\r\n [hours]=\"getHours()\"\r\n [minutes]=\"getMinutes()\"\r\n (dateChange)=\"changeDatePart('start', $event)\"\r\n (timeChange)=\"updateStartTime()\"\r\n />\r\n\r\n <!-- \u7ED3\u675F\u65E5\u671F -->\r\n <date-time-input\r\n label=\"\u7ED3\u675F\u65E5\u671F\"\r\n [dateValue]=\"endDate()\"\r\n [hourValue]=\"endHour()\"\r\n (hourChange)=\"endHour.set($event)\"\r\n [minuteValue]=\"endMinute()\"\r\n (minuteChange)=\"endMinute.set($event)\"\r\n [hours]=\"getHours()\"\r\n [minutes]=\"getMinutes()\"\r\n (dateChange)=\"changeDatePart('end', $event)\"\r\n (timeChange)=\"updateEndTime()\"\r\n />\r\n </div>\r\n\r\n <div class=\"date-selector-hint-wrapper\">\r\n <div class=\"date-selector-hint\">\r\n <i-tabler name=\"info-circle\" strokeWidth=\"2px\" class=\"date-selector-hint-icon\"></i-tabler>\r\n <span class=\"date-selector-hint-text\">\u5982\u679C\u8981\u9009\u62E9\u4E00\u5929\uFF0C\u8BF7\u53CC\u51FB\u8BE5\u5929\u3002</span>\r\n </div>\r\n </div>\r\n\r\n </section>\r\n </div>\r\n </div>\r\n </mat-sidenav-content>\r\n </mat-sidenav-container>\r\n</date-time-picker-container>\r\n\r\n<ng-template #footerExtraContent>\r\n <div class=\"date-selector-footer-range\">\r\n <span class=\"date-selector-footer-label\">\u8303\u56F4\uFF1A</span>\r\n\r\n @if (startDate()) {\r\n <div class=\"date-selector-footer-value\">\r\n @if (startDate()) {\r\n <span class=\"date-selector-footer-date\">{{ displayStart() }}</span>\r\n }\r\n\r\n @if (startDate() && endDate()) {\r\n <span class=\"date-selector-footer-separator\">-</span>\r\n }\r\n\r\n @if (endDate()) {\r\n <span class=\"date-selector-footer-date\">{{ displayEnd() }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.date-selector-sidebar{width:12rem;height:100%;background-color:var(--mat-sys-surface-container, #fafafa);border-right:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));display:flex;flex-direction:column}.date-selector-sidebar-inner{width:100%;height:100%;display:flex;flex-direction:column;padding:0}.date-selector-sidebar-header{padding:12px 16px;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));background-color:var(--mat-sys-surface, #fff);position:sticky;top:0;z-index:1;display:flex;justify-content:space-between;align-items:center}.date-selector-sidebar-title{font-size:.75rem;font-weight:500;text-transform:uppercase;letter-spacing:.5px;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.date-selector-sidebar-list{list-style:none;margin:0;padding:4px 0;flex:1;overflow-y:auto;overflow-x:hidden}.date-selector-sidebar-item{margin:0;padding:0}.date-selector-sidebar-btn{width:100%;padding:8px 12px;background:transparent;border:none;cursor:pointer;font-size:.8125rem;font-weight:500;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));text-align:left;transition:all .2s ease;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.date-selector-sidebar-btn:hover{background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .08));color:var(--mat-sys-primary, #1976d2);padding-left:16px}.date-selector-sidebar-btn.selected{background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .16));color:var(--mat-sys-primary, #1976d2);font-weight:600;padding-left:16px}.date-selector-sidebar-btn:focus-visible{outline:2px solid var(--mat-sys-primary, #1976d2);outline-offset:-2px}.date-selector-sidebar-text{display:block}.date-selector-main{width:100%;height:100%;display:flex;background-color:var(--mat-sys-surface, #fff)}@media(max-width:767px){.date-selector-main{height:auto;flex:1}}.date-selector-content{width:100%;height:100%;display:flex;flex-direction:column}@media(min-width:768px){.date-selector-content{flex-direction:row}}.date-selector-calendar-section{width:100%;display:flex;align-items:center;justify-content:center;padding:16px;border-right:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));box-sizing:border-box}@media(min-width:768px){.date-selector-calendar-section{width:50%}}@media(max-width:767px){.date-selector-calendar-section{border-right:none;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));padding-top:0;padding-bottom:0}}.date-selector-calendar-wrapper{width:100%;display:flex;flex-direction:column;gap:16px}.date-selector-calendar{width:100%}.date-selector-hint{display:flex;align-items:flex-start;gap:8px;padding:12px 16px;background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .08));border:1px solid var(--mat-outline-variant, rgba(25, 118, 210, .16));border-radius:4px;align-items:center}.date-selector-hint-icon{flex-shrink:0;color:var(--mat-sys-primary, #1976d2);margin-top:2px}.date-selector-hint-text{font-size:.75rem;line-height:1.25;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.date-selector-hint-wrapper{padding:12px 16px}.date-selector-time-section{width:100%;display:flex;flex-direction:column}@media(min-width:768px){.date-selector-time-section{width:50%}}.date-selector-inputs{display:flex;flex-direction:column;padding:0}.date-selector-footer-range{display:flex;align-items:center;gap:8px;font-size:.75rem;margin-right:auto;padding:0 8px}.date-selector-footer-label{font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));display:none}@media(min-width:768px){.date-selector-footer-label{display:block}}.date-selector-footer-value{display:flex;flex-direction:column;gap:0;font-weight:600}@media(min-width:768px){.date-selector-footer-value{flex-direction:row;gap:8px;align-items:center}}.date-selector-footer-date{color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87));white-space:nowrap}.date-selector-footer-separator{color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));display:none}@media(min-width:768px){.date-selector-footer-separator{display:block}}.date-selector-sidenav-container{width:100%;height:100%;background-color:transparent}.date-selector-mobile-toolbar{padding:8px;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));display:flex;align-items:center}\n", ":host{display:block;height:100%}\n"] }]
|
|
528
|
+
], template: "<date-time-picker-container\r\n headerTitle=\"\u65E5\u671F\u65F6\u95F4\u9009\u62E9\u5668\"\r\n submitTitle=\"\u5E94\u7528\"\r\n [disabledSubmit]=\"!selectedDateRange\"\r\n [footerExtraContent]=\"footerExtraContent\"\r\n (submit)=\"submit()\"\r\n (dismiss)=\"dismiss()\"\r\n>\r\n <mat-sidenav-container class=\"date-selector-sidenav-container\">\r\n <!-- \u5DE6\u4FA7\u5FEB\u6377\u9009\u62E9\u9762\u677F -->\r\n <mat-sidenav #sidenav [mode]=\"isMobile() ? 'over' : 'side'\" [opened]=\"!isMobile()\" class=\"date-selector-sidebar\" dir=\"rtl\">\r\n <div class=\"date-selector-sidebar-inner\" dir=\"ltr\">\r\n <div class=\"date-selector-sidebar-header\">\r\n <span class=\"date-selector-sidebar-title\">\u5FEB\u6377\u9009\u62E9</span>\r\n @if (isMobile()) {\r\n <button mat-icon-button (click)=\"sidenav.close()\">\r\n <i-tabler name=\"layout-sidebar-left-collapse\" />\r\n </button>\r\n }\r\n </div>\r\n <ul class=\"date-selector-sidebar-list\">\r\n @for (timeRangeItem of timeRanges; track timeRangeItem) {\r\n <li class=\"date-selector-sidebar-item\">\r\n <button\r\n type=\"button\"\r\n (click)=\"selectTimeRange(timeRangeItem); isMobile() && sidenav.close()\"\r\n [class.selected]=\"selectedTimeRange() && selectedTimeRange()?.start === timeRangeItem.start && selectedTimeRange()?.end === timeRangeItem.end\"\r\n class=\"date-selector-sidebar-btn\"\r\n >\r\n <span class=\"date-selector-sidebar-text\">{{ timeRangeItem.label }}</span>\r\n </button>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n </mat-sidenav>\r\n <!-- \u5DE6\u4FA7\u5FEB\u6377\u9009\u62E9\u9762\u677F\u7ED3\u675F -->\r\n\r\n <mat-sidenav-content>\r\n @if (isMobile()) {\r\n <div class=\"date-selector-mobile-toolbar\">\r\n <button mat-button (click)=\"sidenav.open()\">\r\n <span>\u5FEB\u6377\u9009\u62E9</span>\r\n </button>\r\n </div>\r\n }\r\n\r\n <!-- \u4E3B\u8981\u5185\u5BB9\u533A\u57DF -->\r\n <div class=\"date-selector-main\">\r\n <div class=\"date-selector-content\">\r\n <!-- \u65E5\u5386\u5BB9\u5668 -->\r\n <section class=\"date-selector-calendar-section\">\r\n <div class=\"date-selector-calendar-wrapper\">\r\n <mat-calendar [maxDate]=\"!future() ? now : undefined\" [(selected)]=\"selectedDateRange\" (selectedChange)=\"rangeChanged($event)\" class=\"date-selector-calendar\" />\r\n </div>\r\n </section>\r\n <!-- \u65E5\u5386\u5BB9\u5668\u7ED3\u675F -->\r\n\r\n <!-- \u65F6\u95F4\u8BBE\u7F6E\u5BB9\u5668 -->\r\n <section class=\"date-selector-time-section\">\r\n <!-- \u5F00\u59CB\u548C\u7ED3\u675F\u8F93\u5165\u65E5\u671F -->\r\n <div class=\"date-selector-inputs\">\r\n <!-- \u4ECE\u65E5\u671F -->\r\n <date-time-input\r\n label=\"\u5F00\u59CB\u65E5\u671F\"\r\n [dateValue]=\"startDate()\"\r\n [hourValue]=\"startHour()\"\r\n (hourChange)=\"startHour.set($event)\"\r\n [minuteValue]=\"startMinute()\"\r\n (minuteChange)=\"startMinute.set($event)\"\r\n [hours]=\"hours\"\r\n [minutes]=\"minutes\"\r\n (dateChange)=\"changeDatePart('start', $event)\"\r\n (timeChange)=\"updateStartTime()\"\r\n />\r\n\r\n <!-- \u7ED3\u675F\u65E5\u671F -->\r\n <date-time-input\r\n label=\"\u7ED3\u675F\u65E5\u671F\"\r\n [dateValue]=\"endDate()\"\r\n [hourValue]=\"endHour()\"\r\n (hourChange)=\"endHour.set($event)\"\r\n [minuteValue]=\"endMinute()\"\r\n (minuteChange)=\"endMinute.set($event)\"\r\n [hours]=\"hours\"\r\n [minutes]=\"minutes\"\r\n (dateChange)=\"changeDatePart('end', $event)\"\r\n (timeChange)=\"updateEndTime()\"\r\n />\r\n </div>\r\n\r\n <div class=\"date-selector-hint-wrapper\">\r\n <div class=\"date-selector-hint\">\r\n <i-tabler name=\"info-circle\" strokeWidth=\"2px\" class=\"date-selector-hint-icon\"></i-tabler>\r\n <span class=\"date-selector-hint-text\">\u5982\u679C\u8981\u9009\u62E9\u4E00\u5929\uFF0C\u8BF7\u53CC\u51FB\u8BE5\u5929\u3002</span>\r\n </div>\r\n </div>\r\n </section>\r\n </div>\r\n </div>\r\n </mat-sidenav-content>\r\n </mat-sidenav-container>\r\n</date-time-picker-container>\r\n\r\n<ng-template #footerExtraContent>\r\n <div class=\"date-selector-footer-range\">\r\n <span class=\"date-selector-footer-label\">\u8303\u56F4\uFF1A</span>\r\n\r\n @if (startDate()) {\r\n <div class=\"date-selector-footer-value\">\r\n @if (startDate()) {\r\n <span class=\"date-selector-footer-date\">{{ displayStart() }}</span>\r\n }\r\n\r\n @if (startDate() && endDate()) {\r\n <span class=\"date-selector-footer-separator\">-</span>\r\n }\r\n\r\n @if (endDate()) {\r\n <span class=\"date-selector-footer-date\">{{ displayEnd() }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.date-selector-sidebar{width:12rem;height:100%;background-color:var(--mat-sys-surface-container, #fafafa);border-right:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));display:flex;flex-direction:column}.date-selector-sidebar-inner{width:100%;height:100%;display:flex;flex-direction:column;padding:0}.date-selector-sidebar-header{padding:12px 16px;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));background-color:var(--mat-sys-surface, #fff);position:sticky;top:0;z-index:1;display:flex;justify-content:space-between;align-items:center}.date-selector-sidebar-title{font-size:.75rem;font-weight:500;text-transform:uppercase;letter-spacing:.5px;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.date-selector-sidebar-list{list-style:none;margin:0;padding:4px 0;flex:1;overflow-y:auto;overflow-x:hidden}.date-selector-sidebar-item{margin:0;padding:0}.date-selector-sidebar-btn{width:100%;padding:8px 12px;background:transparent;border:none;cursor:pointer;font-size:.8125rem;font-weight:500;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));text-align:left;transition:all .2s ease;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.date-selector-sidebar-btn:hover{background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .08));color:var(--mat-sys-primary, #1976d2);padding-left:16px}.date-selector-sidebar-btn.selected{background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .16));color:var(--mat-sys-primary, #1976d2);font-weight:600;padding-left:16px}.date-selector-sidebar-btn:focus-visible{outline:2px solid var(--mat-sys-primary, #1976d2);outline-offset:-2px}.date-selector-sidebar-text{display:block}.date-selector-main{width:100%;height:100%;display:flex;background-color:var(--mat-sys-surface, #fff)}@media(max-width:767px){.date-selector-main{height:auto;flex:1}}.date-selector-content{width:100%;height:100%;display:flex;flex-direction:column}@media(min-width:768px){.date-selector-content{flex-direction:row}}.date-selector-calendar-section{width:100%;display:flex;align-items:center;justify-content:center;padding:16px;border-right:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));box-sizing:border-box}@media(min-width:768px){.date-selector-calendar-section{width:50%}}@media(max-width:767px){.date-selector-calendar-section{border-right:none;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));padding-top:0;padding-bottom:0}}.date-selector-calendar-wrapper{width:100%;display:flex;flex-direction:column;gap:16px}.date-selector-calendar{width:100%}.date-selector-hint{display:flex;align-items:flex-start;gap:8px;padding:12px 16px;background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .08));border:1px solid var(--mat-outline-variant, rgba(25, 118, 210, .16));border-radius:4px;align-items:center}.date-selector-hint-icon{flex-shrink:0;color:var(--mat-sys-primary, #1976d2);margin-top:2px}.date-selector-hint-text{font-size:.75rem;line-height:1.25;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.date-selector-hint-wrapper{padding:12px 16px}.date-selector-time-section{width:100%;display:flex;flex-direction:column}@media(min-width:768px){.date-selector-time-section{width:50%}}.date-selector-inputs{display:flex;flex-direction:column;padding:0}.date-selector-footer-range{display:flex;align-items:center;gap:8px;font-size:.75rem;margin-right:auto;padding:0 8px}.date-selector-footer-label{font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));display:none}@media(min-width:768px){.date-selector-footer-label{display:block}}.date-selector-footer-value{display:flex;flex-direction:column;gap:0;font-weight:600}@media(min-width:768px){.date-selector-footer-value{flex-direction:row;gap:8px;align-items:center}}.date-selector-footer-date{color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87));white-space:nowrap}.date-selector-footer-separator{color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));display:none}@media(min-width:768px){.date-selector-footer-separator{display:block}}.date-selector-sidenav-container{width:100%;height:100%;background-color:transparent}.date-selector-mobile-toolbar{padding:8px;border-bottom:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));display:flex;align-items:center}\n", ":host{display:block;height:100%}\n"] }]
|
|
459
529
|
}], ctorParameters: () => [], propDecorators: { sidenav: [{
|
|
460
530
|
type: ViewChild,
|
|
461
531
|
args: ['sidenav']
|
|
@@ -466,73 +536,60 @@ class DatePickerComponent {
|
|
|
466
536
|
#dialog;
|
|
467
537
|
#focusMonitor;
|
|
468
538
|
#elementRef;
|
|
469
|
-
#matFormField;
|
|
470
539
|
#injector;
|
|
471
540
|
// 内部值存储:{start: string, end: string} 或 null/undefined
|
|
472
541
|
#internalValue;
|
|
473
542
|
#errorStateSignal;
|
|
474
|
-
#shouldLabelFloatSignal;
|
|
475
543
|
#focusedSignal;
|
|
476
544
|
#id;
|
|
477
|
-
formatDate(date) {
|
|
478
|
-
const datePart = this._dateAdapter.format(date, this._dateFormats.display.dateInput);
|
|
479
|
-
const hours = date.getHours().toString().padStart(2, '0');
|
|
480
|
-
const minutes = date.getMinutes().toString().padStart(2, '0');
|
|
481
|
-
return `${datePart} ${hours}:${minutes}`;
|
|
482
|
-
}
|
|
483
545
|
constructor() {
|
|
484
546
|
this.#breakpoints = inject(BreakpointObserver);
|
|
485
547
|
this.#dialog = inject(MatDialog);
|
|
486
548
|
this.#focusMonitor = inject(FocusMonitor);
|
|
487
549
|
this.#elementRef = inject(ElementRef);
|
|
488
|
-
this.#matFormField = inject(MatFormField, { optional: true });
|
|
489
550
|
this.#injector = inject(Injector);
|
|
490
551
|
this._dateAdapter = inject(DateAdapter);
|
|
491
552
|
this._dateFormats = inject(MAT_DATE_FORMATS);
|
|
492
553
|
this.destroyRef = inject(DestroyRef);
|
|
493
|
-
this.ngControl =
|
|
554
|
+
this.ngControl = inject(NgControl, { optional: true, self: true });
|
|
494
555
|
this.required = false;
|
|
495
556
|
this.disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : {}), alias: 'disabled' });
|
|
496
557
|
this._formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_formDisabled" }] : []));
|
|
497
|
-
this.valueFormat = 'yyyy-MM-dd HH:mm';
|
|
498
558
|
this.placeholder = '';
|
|
499
559
|
this.future = input(false, ...(ngDevMode ? [{ debugName: "future" }] : []));
|
|
560
|
+
this.isTimestamp = input(false, ...(ngDevMode ? [{ debugName: "isTimestamp" }] : []));
|
|
500
561
|
this.selectedDateRange = model(...(ngDevMode ? [undefined, { debugName: "selectedDateRange" }] : []));
|
|
501
|
-
this.toggle = signal(false, ...(ngDevMode ? [{ debugName: "toggle" }] : []));
|
|
502
562
|
this.selectionChange = output();
|
|
503
563
|
// 内部值存储:{start: string, end: string} 或 null/undefined
|
|
504
564
|
this.#internalValue = signal(undefined, ...(ngDevMode ? [{ debugName: "#internalValue" }] : []));
|
|
505
565
|
// MatFormFieldControl 属性
|
|
506
566
|
this.stateChanges = new Subject();
|
|
507
567
|
this.#errorStateSignal = signal(false, ...(ngDevMode ? [{ debugName: "#errorStateSignal" }] : []));
|
|
508
|
-
this.#shouldLabelFloatSignal = signal(false, ...(ngDevMode ? [{ debugName: "#shouldLabelFloatSignal" }] : []));
|
|
509
568
|
this.#focusedSignal = signal(false, ...(ngDevMode ? [{ debugName: "#focusedSignal" }] : []));
|
|
510
569
|
this.#id = signal(`date-time-picker-${Math.random().toString(36).substr(2, 9)}`, ...(ngDevMode ? [{ debugName: "#id" }] : []));
|
|
511
570
|
this.displayStart = computed(() => {
|
|
512
571
|
const range = this.selectedDateRange();
|
|
513
572
|
if (!range?.start)
|
|
514
573
|
return '';
|
|
515
|
-
return
|
|
574
|
+
return formatDate(range.start, this._dateAdapter, this._dateFormats);
|
|
516
575
|
}, ...(ngDevMode ? [{ debugName: "displayStart" }] : []));
|
|
517
576
|
this.displayEnd = computed(() => {
|
|
518
577
|
const range = this.selectedDateRange();
|
|
519
578
|
if (!range?.end)
|
|
520
579
|
return '';
|
|
521
|
-
return
|
|
580
|
+
return formatDate(range.end, this._dateAdapter, this._dateFormats);
|
|
522
581
|
}, ...(ngDevMode ? [{ debugName: "displayEnd" }] : []));
|
|
523
582
|
this.ref = effect(() => {
|
|
524
|
-
|
|
583
|
+
this.selectedDateRange();
|
|
525
584
|
// 触发 MatFormField 更新
|
|
526
|
-
this.stateChanges.next();
|
|
527
|
-
this.#shouldLabelFloatSignal.set(!!dateRange);
|
|
528
|
-
// 通知 ControlValueAccessor(当通过 model 更新时)
|
|
529
|
-
if (dateRange && this.onChange) {
|
|
530
|
-
const value = this.#internalValue();
|
|
531
|
-
if (value) {
|
|
532
|
-
this.onChange(value);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
585
|
+
untracked(() => this.stateChanges.next());
|
|
535
586
|
}, ...(ngDevMode ? [{ debugName: "ref" }] : []));
|
|
587
|
+
if (this.ngControl) {
|
|
588
|
+
this.ngControl.valueAccessor = this;
|
|
589
|
+
this.ngControl.statusChanges?.pipe(takeUntilDestroyed()).subscribe(() => {
|
|
590
|
+
this.stateChanges.next();
|
|
591
|
+
});
|
|
592
|
+
}
|
|
536
593
|
// 监听 focus 事件
|
|
537
594
|
this.#focusMonitor
|
|
538
595
|
.monitor(this.#elementRef, true)
|
|
@@ -555,8 +612,7 @@ class DatePickerComponent {
|
|
|
555
612
|
const currentValue = this.#internalValue();
|
|
556
613
|
const data = {
|
|
557
614
|
dateTimePicker: currentValue ?? undefined,
|
|
558
|
-
future: this.future()
|
|
559
|
-
valueFormat: this.valueFormat
|
|
615
|
+
future: this.future()
|
|
560
616
|
};
|
|
561
617
|
const dialogRef = this.#dialog.open(DateSelector, {
|
|
562
618
|
width: isMobile ? '100%' : '850px',
|
|
@@ -568,22 +624,31 @@ class DatePickerComponent {
|
|
|
568
624
|
panelClass: 'date-time-picker-dialog',
|
|
569
625
|
injector: this.#injector
|
|
570
626
|
});
|
|
571
|
-
dialogRef
|
|
572
|
-
.afterOpened()
|
|
573
|
-
.pipe(take(1), takeUntilDestroyed(this.destroyRef), tap(() => this.toggle.update((status) => !status)))
|
|
574
|
-
.subscribe();
|
|
575
627
|
dialogRef
|
|
576
628
|
.afterClosed()
|
|
577
629
|
.pipe(take(1), takeUntilDestroyed(this.destroyRef), tap((result) => {
|
|
578
|
-
this.toggle.update((status) => !status);
|
|
579
630
|
if (result && result.dateTimePicker) {
|
|
631
|
+
const start = new Date(result.dateTimePicker.start);
|
|
632
|
+
const end = new Date(result.dateTimePicker.end);
|
|
633
|
+
let startVal;
|
|
634
|
+
let endVal;
|
|
635
|
+
if (this.isTimestamp()) {
|
|
636
|
+
start.setSeconds(0, 0);
|
|
637
|
+
end.setSeconds(0, 0);
|
|
638
|
+
startVal = start.getTime();
|
|
639
|
+
endVal = end.getTime();
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
startVal = formatDate(start, this._dateAdapter, this._dateFormats);
|
|
643
|
+
endVal = formatDate(end, this._dateAdapter, this._dateFormats);
|
|
644
|
+
}
|
|
580
645
|
const rangeValue = {
|
|
581
|
-
start:
|
|
582
|
-
end:
|
|
646
|
+
start: startVal,
|
|
647
|
+
end: endVal
|
|
583
648
|
};
|
|
584
649
|
this.#internalValue.set(rangeValue);
|
|
585
650
|
// 更新显示用的日期范围
|
|
586
|
-
this.selectedDateRange.set(new DateRange(
|
|
651
|
+
this.selectedDateRange.set(new DateRange(start, end));
|
|
587
652
|
// 发出用户手动选择的值
|
|
588
653
|
this.selectionChange.emit(rangeValue);
|
|
589
654
|
// 通知表单控件
|
|
@@ -635,16 +700,16 @@ class DatePickerComponent {
|
|
|
635
700
|
return !this.#internalValue();
|
|
636
701
|
}
|
|
637
702
|
get shouldPlaceholderFloat() {
|
|
638
|
-
return this
|
|
703
|
+
return this.shouldLabelFloat;
|
|
639
704
|
}
|
|
640
705
|
get focused() {
|
|
641
706
|
return this.#focusedSignal();
|
|
642
707
|
}
|
|
643
708
|
get errorState() {
|
|
644
|
-
return this.#errorStateSignal();
|
|
709
|
+
return this.#errorStateSignal() || (!!this.ngControl?.invalid && (!!this.ngControl?.touched || !!this.ngControl?.dirty));
|
|
645
710
|
}
|
|
646
711
|
get shouldLabelFloat() {
|
|
647
|
-
return this
|
|
712
|
+
return this.focused || !this.empty;
|
|
648
713
|
}
|
|
649
714
|
get id() {
|
|
650
715
|
return this.#id();
|
|
@@ -680,13 +745,8 @@ class DatePickerComponent {
|
|
|
680
745
|
this.stateChanges.next();
|
|
681
746
|
}
|
|
682
747
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
683
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: DatePickerComponent, isStandalone: true, selector: "date-time-picker", inputs: { required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null },
|
|
748
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: DatePickerComponent, isStandalone: true, selector: "date-time-picker", inputs: { required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: false, isRequired: false, transformFunction: null }, future: { classPropertyName: "future", publicName: "future", isSignal: true, isRequired: false, transformFunction: null }, isTimestamp: { classPropertyName: "isTimestamp", publicName: "isTimestamp", isSignal: true, isRequired: false, transformFunction: null }, selectedDateRange: { classPropertyName: "selectedDateRange", publicName: "selectedDateRange", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedDateRange: "selectedDateRangeChange", selectionChange: "selectionChange" }, providers: [
|
|
684
749
|
provideTablerIcons({ IconCalendarDue, IconX }),
|
|
685
|
-
{
|
|
686
|
-
provide: NG_VALUE_ACCESSOR,
|
|
687
|
-
useExisting: forwardRef(() => DatePickerComponent),
|
|
688
|
-
multi: true
|
|
689
|
-
},
|
|
690
750
|
{
|
|
691
751
|
provide: MatFormFieldControl,
|
|
692
752
|
useExisting: forwardRef(() => DatePickerComponent)
|
|
@@ -697,11 +757,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
|
|
|
697
757
|
type: Component,
|
|
698
758
|
args: [{ selector: 'date-time-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TablerIconComponent, MatDatepickerModule, MatDialogModule], providers: [
|
|
699
759
|
provideTablerIcons({ IconCalendarDue, IconX }),
|
|
700
|
-
{
|
|
701
|
-
provide: NG_VALUE_ACCESSOR,
|
|
702
|
-
useExisting: forwardRef(() => DatePickerComponent),
|
|
703
|
-
multi: true
|
|
704
|
-
},
|
|
705
760
|
{
|
|
706
761
|
provide: MatFormFieldControl,
|
|
707
762
|
useExisting: forwardRef(() => DatePickerComponent)
|
|
@@ -712,152 +767,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
|
|
|
712
767
|
args: ['dateRangeButton']
|
|
713
768
|
}], required: [{
|
|
714
769
|
type: Input
|
|
715
|
-
}], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }],
|
|
716
|
-
type: Input
|
|
717
|
-
}], dateTimePicker: [{
|
|
718
|
-
type: Input
|
|
719
|
-
}], placeholder: [{
|
|
770
|
+
}], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], placeholder: [{
|
|
720
771
|
type: Input
|
|
721
|
-
}], future: [{ type: i0.Input, args: [{ isSignal: true, alias: "future", required: false }] }], selectedDateRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedDateRange", required: false }] }, { type: i0.Output, args: ["selectedDateRangeChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }] } });
|
|
722
|
-
|
|
723
|
-
class SmartDialogService {
|
|
724
|
-
constructor() {
|
|
725
|
-
this.#dialog = inject(MatDialog);
|
|
726
|
-
this.#bottomSheet = inject(MatBottomSheet);
|
|
727
|
-
this.#breakpoints = inject(BreakpointObserver);
|
|
728
|
-
this.ref = null;
|
|
729
|
-
this.data = null;
|
|
730
|
-
}
|
|
731
|
-
#dialog;
|
|
732
|
-
#bottomSheet;
|
|
733
|
-
#breakpoints;
|
|
734
|
-
open(component, config = {}) {
|
|
735
|
-
const isMobile = this.#breakpoints.isMatched([
|
|
736
|
-
Breakpoints.Handset,
|
|
737
|
-
Breakpoints.Tablet
|
|
738
|
-
]);
|
|
739
|
-
const smartRef = new SmartDialogRef({});
|
|
740
|
-
this.data = config.data;
|
|
741
|
-
if (isMobile) {
|
|
742
|
-
this.ref = this.#bottomSheet.open(component, {
|
|
743
|
-
ariaLabel: 'Bottomsheet',
|
|
744
|
-
ariaModal: true,
|
|
745
|
-
autoFocus: false,
|
|
746
|
-
data: config.data,
|
|
747
|
-
panelClass: config.panelClass,
|
|
748
|
-
disableClose: config.disableClose
|
|
749
|
-
});
|
|
750
|
-
Promise.resolve().then(() => {
|
|
751
|
-
const hostElement = this.ref?.containerInstance?._elementRef?.nativeElement;
|
|
752
|
-
const container = hostElement?.closest('.mat-bottom-sheet-container');
|
|
753
|
-
if (container) {
|
|
754
|
-
if (config.width)
|
|
755
|
-
container.style.width = config.width;
|
|
756
|
-
if (config.height)
|
|
757
|
-
container.style.height = config.height;
|
|
758
|
-
if (config.maxWidth)
|
|
759
|
-
container.style.maxWidth = config.maxWidth;
|
|
760
|
-
container.style.minWidth = 'unset';
|
|
761
|
-
container.style.maxHeight = 'unset';
|
|
762
|
-
container.style.borderTopLeftRadius = '1rem';
|
|
763
|
-
container.style.borderTopRightRadius = '1rem';
|
|
764
|
-
}
|
|
765
|
-
if (hostElement) {
|
|
766
|
-
if (config.width)
|
|
767
|
-
hostElement.style.width = config.width;
|
|
768
|
-
if (config.maxWidth)
|
|
769
|
-
hostElement.style.maxWidth = config.maxWidth;
|
|
770
|
-
if (config.height)
|
|
771
|
-
hostElement.style.height = config.height;
|
|
772
|
-
}
|
|
773
|
-
});
|
|
774
|
-
smartRef.ref = this.ref;
|
|
775
|
-
}
|
|
776
|
-
else {
|
|
777
|
-
this.ref = this.#dialog.open(component, {
|
|
778
|
-
data: config.data,
|
|
779
|
-
ariaLabel: 'Dialog',
|
|
780
|
-
ariaModal: true,
|
|
781
|
-
autoFocus: false,
|
|
782
|
-
panelClass: config.panelClass,
|
|
783
|
-
disableClose: config.disableClose,
|
|
784
|
-
width: config.width,
|
|
785
|
-
height: config.height,
|
|
786
|
-
maxWidth: config.maxWidth,
|
|
787
|
-
});
|
|
788
|
-
const hostElement = this.ref._containerInstance?._elementRef?.nativeElement;
|
|
789
|
-
const container = hostElement?.closest('.mat-mdc-dialog-panel');
|
|
790
|
-
if (container) {
|
|
791
|
-
if (config.width)
|
|
792
|
-
container.style.width = config.width;
|
|
793
|
-
if (config.height)
|
|
794
|
-
container.style.height = config.height;
|
|
795
|
-
if (config.maxWidth) {
|
|
796
|
-
container.style.maxWidth = config.maxWidth;
|
|
797
|
-
}
|
|
798
|
-
else {
|
|
799
|
-
container.style.maxWidth = 'unset';
|
|
800
|
-
}
|
|
801
|
-
container.style.minWidth = 'unset';
|
|
802
|
-
container.style.maxHeight = 'unset';
|
|
803
|
-
}
|
|
804
|
-
smartRef.ref = this.ref;
|
|
805
|
-
}
|
|
806
|
-
return smartRef;
|
|
807
|
-
}
|
|
808
|
-
getData() {
|
|
809
|
-
return this.data;
|
|
810
|
-
}
|
|
811
|
-
close(result) {
|
|
812
|
-
if (!this.ref)
|
|
813
|
-
return;
|
|
814
|
-
if ('close' in this.ref) {
|
|
815
|
-
this.ref.close(result);
|
|
816
|
-
}
|
|
817
|
-
else {
|
|
818
|
-
this.ref.dismiss(result);
|
|
819
|
-
}
|
|
820
|
-
this.clear();
|
|
821
|
-
}
|
|
822
|
-
clear() {
|
|
823
|
-
this.ref = null;
|
|
824
|
-
this.data = null;
|
|
825
|
-
}
|
|
826
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: SmartDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
827
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: SmartDialogService, providedIn: 'root' }); }
|
|
828
|
-
}
|
|
829
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: SmartDialogService, decorators: [{
|
|
830
|
-
type: Injectable,
|
|
831
|
-
args: [{ providedIn: 'root' }]
|
|
832
|
-
}] });
|
|
833
|
-
class SmartDialogRef {
|
|
834
|
-
constructor(ref) {
|
|
835
|
-
this.ref = ref;
|
|
836
|
-
}
|
|
837
|
-
close(result) {
|
|
838
|
-
if ('close' in this.ref) {
|
|
839
|
-
this.ref.close(result);
|
|
840
|
-
}
|
|
841
|
-
else {
|
|
842
|
-
this.ref.dismiss(result);
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
afterOpened() {
|
|
846
|
-
return this.ref.afterOpened();
|
|
847
|
-
}
|
|
848
|
-
afterClosed() {
|
|
849
|
-
if ('afterClosed' in this.ref) {
|
|
850
|
-
return this.ref.afterClosed();
|
|
851
|
-
}
|
|
852
|
-
else {
|
|
853
|
-
return this.ref.afterDismissed();
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
}
|
|
772
|
+
}], future: [{ type: i0.Input, args: [{ isSignal: true, alias: "future", required: false }] }], isTimestamp: [{ type: i0.Input, args: [{ isSignal: true, alias: "isTimestamp", required: false }] }], selectedDateRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedDateRange", required: false }] }, { type: i0.Output, args: ["selectedDateRangeChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }] } });
|
|
857
773
|
|
|
858
774
|
/**
|
|
859
775
|
* Generated bundle index. Do not edit.
|
|
860
776
|
*/
|
|
861
777
|
|
|
862
|
-
export { DatePickerComponent, DateSelector,
|
|
778
|
+
export { DatePickerComponent, DateSelector, formatDate };
|
|
863
779
|
//# sourceMappingURL=luoxiao123-angular-material-date-time-range-picker.mjs.map
|