@luoxiao123/angular-material-date-time-range-picker 21.0.1 → 21.1.2

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,30 +1,28 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, model, output, ChangeDetectionStrategy, Component, input, ChangeDetectorRef, signal, ElementRef, DestroyRef, effect, forwardRef, Input, ViewChild, Injectable } from '@angular/core';
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
- import { NgTemplateOutlet, DecimalPipe, DatePipe } from '@angular/common';
5
4
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
- import * as i1$1 from '@angular/material/datepicker';
5
+ import * as i1 from '@angular/material/datepicker';
7
6
  import { MatDatepickerModule, MatRangeDateSelectionModel, DateRange, MatCalendar, DefaultMatCalendarRangeStrategy } from '@angular/material/datepicker';
8
7
  import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
9
8
  import { TablerIconComponent, provideTablerIcons } from '@luoxiao123/angular-tabler-icons';
10
- import { IconClock, IconX, IconCalendarDue, IconInfoCircle } from '@luoxiao123/angular-tabler-icons/icons';
9
+ import { IconLayoutSidebarLeftCollapse, IconClock, IconX, IconCalendarDue, IconInfoCircle } from '@luoxiao123/angular-tabler-icons/icons';
11
10
  import * as i2 from '@angular/forms';
12
- import { FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
13
- import { MatFormField, MatFormFieldControl } from '@angular/material/form-field';
11
+ import { FormsModule, ReactiveFormsModule, NgControl } from '@angular/forms';
12
+ import { MatFormFieldControl } from '@angular/material/form-field';
14
13
  import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogModule } from '@angular/material/dialog';
15
14
  import { FocusMonitor } from '@angular/cdk/a11y';
16
- import { MatCheckbox } from '@angular/material/checkbox';
17
- import { MatTimepickerModule } from '@angular/material/timepicker';
18
- import { MatNativeDateModule, provideNativeDateAdapter } from '@angular/material/core';
19
- import * as i1 from '@angular/material/button';
15
+ import * as i3$1 from '@angular/common';
16
+ import { NgTemplateOutlet, CommonModule } from '@angular/common';
17
+ import * as i3 from '@angular/material/button';
20
18
  import { MatButtonModule } from '@angular/material/button';
21
- import * as i1$2 from '@angular/cdk/bidi';
22
- import { MatBottomSheet } from '@angular/material/bottom-sheet';
19
+ import * as i2$1 from '@angular/material/sidenav';
20
+ import { MatSidenavModule } from '@angular/material/sidenav';
21
+ import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
22
+ import * as i1$1 from '@angular/cdk/bidi';
23
23
 
24
24
  class Container {
25
25
  constructor() {
26
- this.#breakpoints = inject(BreakpointObserver);
27
- this.isMobile = this.#breakpoints.isMatched([Breakpoints.Handset, Breakpoints.Tablet]);
28
26
  this.hasHeader = model(true, ...(ngDevMode ? [{ debugName: "hasHeader" }] : []));
29
27
  this.hasFooter = model(true, ...(ngDevMode ? [{ debugName: "hasFooter" }] : []));
30
28
  this.headerTitle = model('', ...(ngDevMode ? [{ debugName: "headerTitle" }] : []));
@@ -47,13 +45,12 @@ class Container {
47
45
  this.submit = output();
48
46
  this.secondaryButton = output();
49
47
  }
50
- #breakpoints;
51
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: Container, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
52
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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 })], 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: i1.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 }); }
48
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: Container, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
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 }); }
53
50
  }
54
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: Container, decorators: [{
51
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: Container, decorators: [{
55
52
  type: Component,
56
- args: [{ selector: 'date-time-picker-container', changeDetection: ChangeDetectionStrategy.OnPush, imports: [TablerIconComponent, NgTemplateOutlet, MatButtonModule], providers: [provideTablerIcons({ IconInfoCircle, IconCalendarDue, IconX, IconClock })], 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"] }]
53
+ args: [{ selector: 'date-time-picker-container', changeDetection: ChangeDetectionStrategy.OnPush, imports: [TablerIconComponent, NgTemplateOutlet, MatButtonModule], providers: [provideTablerIcons({ IconInfoCircle, IconCalendarDue, IconX, IconClock, IconLayoutSidebarLeftCollapse })], 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"] }]
57
54
  }], propDecorators: { hasHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasHeader", required: false }] }, { type: i0.Output, args: ["hasHeaderChange"] }], hasFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasFooter", required: false }] }, { type: i0.Output, args: ["hasFooterChange"] }], headerTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerTitle", required: false }] }, { type: i0.Output, args: ["headerTitleChange"] }], headerExtraContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerExtraContent", required: false }] }, { type: i0.Output, args: ["headerExtraContentChange"] }], footerExtraContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerExtraContent", required: false }] }, { type: i0.Output, args: ["footerExtraContentChange"] }], hasDismiss: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasDismiss", required: false }] }, { type: i0.Output, args: ["hasDismissChange"] }], hasSubmit: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasSubmit", required: false }] }, { type: i0.Output, args: ["hasSubmitChange"] }], submitTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitTitle", required: false }] }, { type: i0.Output, args: ["submitTitleChange"] }], submitBg: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitBg", required: false }] }, { type: i0.Output, args: ["submitBgChange"] }], submitColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitColor", required: false }] }, { type: i0.Output, args: ["submitColorChange"] }], submitTitleColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitTitleColor", required: false }] }, { type: i0.Output, args: ["submitTitleColorChange"] }], disabledSubmit: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledSubmit", required: false }] }, { type: i0.Output, args: ["disabledSubmitChange"] }], hasSecondaryButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasSecondaryButton", required: false }] }, { type: i0.Output, args: ["hasSecondaryButtonChange"] }], secondaryButtonTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryButtonTitle", required: false }] }, { type: i0.Output, args: ["secondaryButtonTitleChange"] }], secondaryButtonBg: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryButtonBg", required: false }] }, { type: i0.Output, args: ["secondaryButtonBgChange"] }], secondaryButtonColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryButtonColor", required: false }] }, { type: i0.Output, args: ["secondaryButtonColorChange"] }], secondaryButtonTitleColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryButtonTitleColor", required: false }] }, { type: i0.Output, args: ["secondaryButtonTitleColorChange"] }], disabledSecondaryButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledSecondaryButton", required: false }] }, { type: i0.Output, args: ["disabledSecondaryButtonChange"] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }], submit: [{ type: i0.Output, args: ["submit"] }], secondaryButton: [{ type: i0.Output, args: ["secondaryButton"] }] } });
58
55
 
59
56
  class DateTimeInputComponent {
@@ -68,9 +65,15 @@ class DateTimeInputComponent {
68
65
  this.hourChange = output();
69
66
  this.minuteChange = output();
70
67
  this.timeChange = output();
68
+ this.dateObj = computed(() => {
69
+ const val = this.dateValue();
70
+ return val ? new Date(val) : null;
71
+ }, ...(ngDevMode ? [{ debugName: "dateObj" }] : []));
71
72
  }
72
73
  onDateChange(value) {
73
- this.dateChange.emit(value);
74
+ if (value) {
75
+ this.dateChange.emit(value.toISOString());
76
+ }
74
77
  }
75
78
  onHourChange(value) {
76
79
  this.hourChange.emit(value);
@@ -80,24 +83,68 @@ class DateTimeInputComponent {
80
83
  this.minuteChange.emit(value);
81
84
  this.timeChange.emit();
82
85
  }
83
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DateTimeInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
84
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: DateTimeInputComponent, isStandalone: true, selector: "date-time-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, dateValue: { classPropertyName: "dateValue", publicName: "dateValue", isSignal: true, isRequired: false, transformFunction: null }, hourValue: { classPropertyName: "hourValue", publicName: "hourValue", isSignal: true, isRequired: false, transformFunction: null }, minuteValue: { classPropertyName: "minuteValue", publicName: "minuteValue", isSignal: true, isRequired: false, transformFunction: null }, hours: { classPropertyName: "hours", publicName: "hours", isSignal: true, isRequired: false, transformFunction: null }, minutes: { classPropertyName: "minutes", publicName: "minutes", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateChange: "dateChange", hourChange: "hourChange", minuteChange: "minuteChange", timeChange: "timeChange" }, ngImport: i0, 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]=\"dateValue()\"\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 [value]=\"null\" disabled>--</option>\r\n @for (hour of hours(); track hour) {\r\n <option [value]=\"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 [value]=\"null\" disabled>--</option>\r\n @for (minute of minutes(); track minute) {\r\n <option [value]=\"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}: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"], dependencies: [{ kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i1$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i1$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TablerIconComponent, selector: "i-tabler, tabler-icon", inputs: ["name"] }, { kind: "pipe", type: DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
86
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DateTimeInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
87
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: DateTimeInputComponent, isStandalone: true, selector: "date-time-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, dateValue: { classPropertyName: "dateValue", publicName: "dateValue", isSignal: true, isRequired: false, transformFunction: null }, hourValue: { classPropertyName: "hourValue", publicName: "hourValue", isSignal: true, isRequired: false, transformFunction: null }, minuteValue: { classPropertyName: "minuteValue", publicName: "minuteValue", isSignal: true, isRequired: false, transformFunction: null }, hours: { classPropertyName: "hours", publicName: "hours", isSignal: true, isRequired: false, transformFunction: null }, minutes: { classPropertyName: "minutes", publicName: "minutes", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateChange: "dateChange", hourChange: "hourChange", minuteChange: "minuteChange", timeChange: "timeChange" }, ngImport: i0, 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"], dependencies: [{ kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TablerIconComponent, selector: "i-tabler, tabler-icon", inputs: ["name"] }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i3$1.DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
85
88
  }
86
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DateTimeInputComponent, decorators: [{
89
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DateTimeInputComponent, decorators: [{
87
90
  type: Component,
88
- args: [{ selector: 'date-time-input', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatDatepickerModule, FormsModule, TablerIconComponent, DecimalPipe], 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]=\"dateValue()\"\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 [value]=\"null\" disabled>--</option>\r\n @for (hour of hours(); track hour) {\r\n <option [value]=\"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 [value]=\"null\" disabled>--</option>\r\n @for (minute of minutes(); track minute) {\r\n <option [value]=\"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}: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"] }]
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"] }]
89
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"] }] } });
90
93
 
94
+ function formatDate(date, dateAdapter, dateFormats) {
95
+ const datePart = dateAdapter.format(date, dateFormats.display.dateInput);
96
+ const hours = date.getHours().toString().padStart(2, '0');
97
+ const minutes = date.getMinutes().toString().padStart(2, '0');
98
+ return `${datePart} ${hours}:${minutes}`;
99
+ }
100
+
101
+ const DEFAULT_TIME_RANGES = [
102
+ { label: '最近5分钟', start: 'offset:-5minutes', end: 'offset:now' },
103
+ { label: '最近15分钟', start: 'offset:-15minutes', end: 'offset:now' },
104
+ { label: '最近30分钟', start: 'offset:-30minutes', end: 'offset:now' },
105
+ { label: '最近1小时', start: 'offset:-1hours', end: 'offset:now' },
106
+ { label: '最近3小时', start: 'offset:-3hours', end: 'offset:now' },
107
+ { label: '最近6小时', start: 'offset:-6hours', end: 'offset:now' },
108
+ { label: '最近12小时', start: 'offset:-12hours', end: 'offset:now' },
109
+ { label: '最近24小时', start: 'offset:-24hours', end: 'offset:now' },
110
+ { label: '最近2天', start: 'offset:-2days', end: 'offset:now' },
111
+ { label: '最近7天', start: 'offset:-7days', end: 'offset:now' },
112
+ { label: '最近30天', start: 'offset:-30days', end: 'offset:now' },
113
+ { label: '最近90天', start: 'offset:-90days', end: 'offset:now' },
114
+ { label: '最近6个月', start: 'offset:-6months', end: 'offset:now' },
115
+ { label: '最近1年', start: 'offset:-1years', end: 'offset:now' },
116
+ { label: '最近2年', start: 'offset:-2years', end: 'offset:now' },
117
+ { label: '最近5年', start: 'offset:-5years', end: 'offset:now' },
118
+ { label: '昨天', start: 'offset:-1days/start', end: 'offset:-1days/end' },
119
+ { label: '前天', start: 'offset:-2days/start', end: 'offset:-2days/end' },
120
+ { label: '上周同一天', start: 'offset:-7days/start', end: 'offset:-7days/end' },
121
+ { label: '今天', start: 'offset:0days/start', end: 'offset:0days/end' },
122
+ { label: '今天至今', start: 'offset:0days/start', end: 'offset:now' },
123
+ { label: '本周至今', start: 'startof:week', end: 'offset:now' },
124
+ { label: '本月至今', start: 'startof:month', end: 'offset:now' },
125
+ { label: '今年至今', start: 'startof:year', end: 'offset:now' }
126
+ ];
127
+ const FUTURE_TIME_RANGES = [
128
+ { label: '未来1天', start: 'offset:now', end: 'offset:+1days' },
129
+ { label: '未来1周', start: 'offset:now', end: 'offset:+1weeks' },
130
+ { label: '未来1月', start: 'offset:now', end: 'offset:+1months' },
131
+ { label: '未来3月', start: 'offset:now', end: 'offset:+3months' }
132
+ ];
133
+
91
134
  class DateSelector {
135
+ #dialogRef;
136
+ #data;
137
+ #selectionModel;
138
+ #breakpoints;
92
139
  constructor() {
93
- this.#cdr = inject(ChangeDetectorRef);
94
140
  this.#dialogRef = inject((MatDialogRef));
95
141
  this.#data = inject(MAT_DIALOG_DATA);
96
142
  this.#selectionModel = inject((MatRangeDateSelectionModel));
143
+ this.#breakpoints = inject(BreakpointObserver);
144
+ this._dateAdapter = inject(DateAdapter);
145
+ this._dateFormats = inject(MAT_DATE_FORMATS);
146
+ this.isMobile = signal(false, ...(ngDevMode ? [{ debugName: "isMobile" }] : []));
97
147
  this.data = this.#data;
98
- // 从 data 中获取格式,如果没有则使用默认值
99
- this.dateFormat = this.data?.dateFormat ?? 'yyyy年M月d日 HH:mm';
100
- this.valueFormat = this.data?.valueFormat ?? 'yyyy-MM-dd HH:mm:ss';
101
148
  this.startDate = model('', ...(ngDevMode ? [{ debugName: "startDate" }] : []));
102
149
  this.endDate = model('', ...(ngDevMode ? [{ debugName: "endDate" }] : []));
103
150
  this.startHour = model(null, ...(ngDevMode ? [{ debugName: "startHour" }] : []));
@@ -105,117 +152,57 @@ class DateSelector {
105
152
  this.endHour = model(null, ...(ngDevMode ? [{ debugName: "endHour" }] : []));
106
153
  this.endMinute = model(null, ...(ngDevMode ? [{ debugName: "endMinute" }] : []));
107
154
  this.future = model(false, ...(ngDevMode ? [{ debugName: "future" }] : []));
108
- this.optionalFeatures = model(true, ...(ngDevMode ? [{ debugName: "optionalFeatures" }] : []));
109
- this.relativeDurations = [
110
- ['最近5分钟', '-5minutes'],
111
- ['最近15分钟', '-15minutes'],
112
- ['最近30分钟', '-30minutes'],
113
- ['最近1小时', '-1hours'],
114
- ['最近3小时', '-3hours'],
115
- ['最近6小时', '-6hours'],
116
- ['最近12小时', '-12hours'],
117
- ['最近24小时', '-24hours'],
118
- ['最近2天', '-2days'],
119
- ['最近7天', '-7days'],
120
- ['最近30天', '-30days'],
121
- ['最近90天', '-90days'],
122
- ['最近6个月', '-6months'],
123
- ['最近1年', '-1years'],
124
- ['最近2年', '-2years'],
125
- ['最近5年', '-5years'],
126
- ['上周', '-1weeks'],
127
- ['上个月', '-1months'],
128
- ['去年', '-1years']
129
- ];
130
- this.fixedDays = [
131
- ['昨天', '-1days/day'],
132
- ['前天', '-2days/day'],
133
- ['上周同一天', '-7days/day'],
134
- ['上周', '-1weeks/week'],
135
- ['上个月', '-1months/month'],
136
- ['去年', '-1years/year']
137
- ];
138
- this.currentPeriods = [
139
- ['今天', 'today', 'today'],
140
- ['今天至今', 'today', 'now'],
141
- ['本周至今', 'thisweek', 'now'],
142
- ['本月至今', 'thismonth', 'now'],
143
- ['今年至今', 'thisyear', 'now']
144
- ];
145
- this.timeRanges = signal([
146
- ...this.relativeDurations.map(([label, offset]) => ({
147
- label,
148
- start: `offset:${offset}`,
149
- end: 'offset:now'
150
- })),
151
- ...this.fixedDays.map(([label, point]) => ({
152
- label,
153
- start: `offset:${point}`,
154
- end: `offset:${point}`
155
- })),
156
- ...this.currentPeriods.map(([label, start, end]) => ({
157
- label,
158
- start: `offset:${start}`,
159
- end: `offset:${end}`
160
- }))
161
- ], ...(ngDevMode ? [{ debugName: "timeRanges" }] : []));
155
+ this.displayStart = computed(() => {
156
+ const startStr = this.startDate();
157
+ if (!startStr)
158
+ return '';
159
+ return formatDate(new Date(startStr), this._dateAdapter, this._dateFormats);
160
+ }, ...(ngDevMode ? [{ debugName: "displayStart" }] : []));
161
+ this.displayEnd = computed(() => {
162
+ const endStr = this.endDate();
163
+ if (!endStr)
164
+ return '';
165
+ return formatDate(new Date(endStr), this._dateAdapter, this._dateFormats);
166
+ }, ...(ngDevMode ? [{ debugName: "displayEnd" }] : []));
167
+ this.timeRanges = [...DEFAULT_TIME_RANGES];
162
168
  this.selectedTimeRange = model(undefined, ...(ngDevMode ? [{ debugName: "selectedTimeRange" }] : []));
163
- this.allDays = model(true, ...(ngDevMode ? [{ debugName: "allDays" }] : []));
164
- this.weekdays = model([
165
- { label: '六', data: 'Saturday', value: 0, selected: false },
166
- { label: '日', data: 'Sunday', value: 1, selected: false },
167
- { label: '一', data: 'Monday', value: 2, selected: false },
168
- { label: '二', data: 'Tuesday', value: 3, selected: false },
169
- { label: '三', data: 'Wednesday', value: 4, selected: false },
170
- { label: '四', data: 'Thursday', value: 5, selected: false },
171
- { label: '五', data: 'Friday', value: 6, selected: false }
172
- ], ...(ngDevMode ? [{ debugName: "weekdays" }] : []));
173
- this.allHours = model(true, ...(ngDevMode ? [{ debugName: "allHours" }] : []));
174
- this.hourTypes = signal([
175
- { label: '全部', value: 0, selected: false },
176
- { label: '忙碌时间', value: 1, selected: false },
177
- { label: '自定义', value: 2, selected: true }
178
- ], ...(ngDevMode ? [{ debugName: "hourTypes" }] : []));
179
169
  this.selectedDateRange = null;
180
170
  this.now = new Date();
181
171
  this.selectingStart = true;
172
+ this.hours = Array.from({ length: 24 }, (_, i) => i);
173
+ this.minutes = Array.from({ length: 60 }, (_, i) => i);
174
+ this.#breakpoints
175
+ .observe([Breakpoints.Handset, Breakpoints.Tablet])
176
+ .pipe(takeUntilDestroyed())
177
+ .subscribe(result => {
178
+ this.isMobile.set(result.matches);
179
+ });
182
180
  }
183
- #cdr;
184
- #dialogRef;
185
- #data;
186
- #selectionModel;
187
181
  ngOnInit() {
188
182
  if (this.data) {
189
- this.optionalFeatures.set(this.data.optionalFeatures);
190
183
  this.future.set(this.data.future);
191
184
  const picker = this.data.dateTimePicker;
192
185
  if (picker) {
193
186
  if (picker.start && picker.end) {
194
- this.selectedDateRange = {
195
- start: new Date(picker.start),
196
- end: new Date(picker.end)
197
- };
187
+ const start = new Date(picker.start);
188
+ const end = new Date(picker.end);
189
+ this.selectedDateRange = new DateRange(start, end);
190
+ this.#selectionModel.updateSelection(this.selectedDateRange, this);
198
191
  // 初始化时间值
199
- const startDate = new Date(picker.start);
200
- const endDate = new Date(picker.end);
201
- this.startHour.set(startDate.getHours());
202
- this.startMinute.set(startDate.getMinutes());
203
- this.endHour.set(endDate.getHours());
204
- this.endMinute.set(endDate.getMinutes());
192
+ this.startDate.set(picker.start);
193
+ this.endDate.set(picker.end);
194
+ this.startHour.set(start.getHours());
195
+ this.startMinute.set(start.getMinutes());
196
+ this.endHour.set(end.getHours());
197
+ this.endMinute.set(end.getMinutes());
205
198
  }
206
199
  }
207
200
  if (this.future()) {
208
- const futureOffsets = [
209
- { label: '未来1天', start: 'offset:now', end: 'offset:+1days' },
210
- { label: '未来1周', start: 'offset:now', end: 'offset:+1weeks' },
211
- { label: '未来1月', start: 'offset:now', end: 'offset:+1months' },
212
- { label: '未来3月', start: 'offset:now', end: 'offset:+3months' }
213
- ];
214
- this.timeRanges.update(ranges => [...ranges, ...futureOffsets]);
201
+ this.timeRanges = [...this.timeRanges, ...FUTURE_TIME_RANGES];
215
202
  }
216
203
  }
217
- else {
218
- this.selectTimeRange(this.timeRanges()[5]);
204
+ if (!this.data?.dateTimePicker) {
205
+ this.selectTimeRange(this.timeRanges[5]);
219
206
  }
220
207
  }
221
208
  selectTimeRange(timeRange) {
@@ -236,46 +223,89 @@ class DateSelector {
236
223
  const parseTime = (time) => {
237
224
  if (!time)
238
225
  return new Date(now);
239
- if (time.startsWith('offset:')) {
240
- const offset = time.replace('offset:', '').trim();
241
- if (offset === 'now')
242
- return new Date(now);
243
- const regex = /([+-]?)(\d+)(months?|days?|years?|weeks?|hours?|minutes?)/i;
244
- const match = regex.exec(offset);
245
- if (!match)
246
- return new Date(now);
247
- const sign = match[1] === '-' ? -1 : 1;
248
- const value = parseInt(match[2], 10) * sign;
249
- const unit = match[3].toLowerCase();
226
+ // 处理 startof: 前缀 (本周/本月/今年)
227
+ if (time.startsWith('startof:')) {
228
+ const unit = time.replace('startof:', '').trim().toLowerCase();
250
229
  const result = new Date(now);
230
+ result.setHours(0, 0, 0, 0);
251
231
  switch (unit) {
252
- case 'minutes':
253
- case 'minute':
254
- result.setMinutes(result.getMinutes() + value);
255
- break;
256
- case 'hours':
257
- case 'hour':
258
- result.setHours(result.getHours() + value);
259
- break;
260
- case 'days':
261
- case 'day':
262
- result.setDate(result.getDate() + value);
263
- break;
264
- case 'weeks':
265
232
  case 'week':
266
- result.setDate(result.getDate() + value * 7);
233
+ // 假设周一为一周的开始
234
+ const day = result.getDay() || 7; // 0是周日,改为7
235
+ if (day !== 1) {
236
+ result.setHours(-24 * (day - 1));
237
+ }
267
238
  break;
268
- case 'months':
269
239
  case 'month':
270
- result.setMonth(result.getMonth() + value);
240
+ result.setDate(1);
271
241
  break;
272
- case 'years':
273
242
  case 'year':
274
- result.setFullYear(result.getFullYear() + value);
243
+ result.setMonth(0, 1);
275
244
  break;
276
245
  }
277
246
  return result;
278
247
  }
248
+ // 处理 offset: 前缀
249
+ if (time.startsWith('offset:')) {
250
+ const offsetStr = time.replace('offset:', '').trim();
251
+ if (offsetStr === 'now')
252
+ return new Date(now);
253
+ // 检查是否有 /start 或 /end 后缀
254
+ let suffix = '';
255
+ let cleanOffset = offsetStr;
256
+ if (offsetStr.endsWith('/start')) {
257
+ suffix = 'start';
258
+ cleanOffset = offsetStr.replace('/start', '');
259
+ }
260
+ else if (offsetStr.endsWith('/end')) {
261
+ suffix = 'end';
262
+ cleanOffset = offsetStr.replace('/end', '');
263
+ }
264
+ const regex = /([+-]?)(\d+)(months?|days?|years?|weeks?|hours?|minutes?)/i;
265
+ const match = regex.exec(cleanOffset);
266
+ // 如果没有匹配到数字偏移量,但有后缀(例如 offset:0days/start),尝试解析
267
+ // 注意:上面的正则也能匹配 0days
268
+ const result = new Date(now);
269
+ if (match) {
270
+ const sign = match[1] === '-' ? -1 : 1;
271
+ const value = parseInt(match[2], 10) * sign;
272
+ const unit = match[3].toLowerCase();
273
+ switch (unit) {
274
+ case 'minutes':
275
+ case 'minute':
276
+ result.setMinutes(result.getMinutes() + value);
277
+ break;
278
+ case 'hours':
279
+ case 'hour':
280
+ result.setHours(result.getHours() + value);
281
+ break;
282
+ case 'days':
283
+ case 'day':
284
+ result.setDate(result.getDate() + value);
285
+ break;
286
+ case 'weeks':
287
+ case 'week':
288
+ result.setDate(result.getDate() + value * 7);
289
+ break;
290
+ case 'months':
291
+ case 'month':
292
+ result.setMonth(result.getMonth() + value);
293
+ break;
294
+ case 'years':
295
+ case 'year':
296
+ result.setFullYear(result.getFullYear() + value);
297
+ break;
298
+ }
299
+ }
300
+ // 应用后缀修正
301
+ if (suffix === 'start') {
302
+ result.setHours(0, 0, 0, 0);
303
+ }
304
+ else if (suffix === 'end') {
305
+ result.setHours(23, 59, 59, 999);
306
+ }
307
+ return result;
308
+ }
279
309
  return new Date(time);
280
310
  };
281
311
  const startDate = timeRange.start ? parseTime(timeRange.start) : null;
@@ -334,30 +364,79 @@ class DateSelector {
334
364
  this.selectedDateRange = range;
335
365
  this.startDate.set(start?.toISOString() ?? '');
336
366
  this.endDate.set(end?.toISOString() ?? '');
367
+ if (start) {
368
+ this.startHour.set(start.getHours());
369
+ this.startMinute.set(start.getMinutes());
370
+ }
371
+ else {
372
+ this.startHour.set(null);
373
+ this.startMinute.set(null);
374
+ }
375
+ if (end) {
376
+ this.endHour.set(end.getHours());
377
+ this.endMinute.set(end.getMinutes());
378
+ }
379
+ else {
380
+ this.endHour.set(null);
381
+ this.endMinute.set(null);
382
+ }
337
383
  }
338
384
  rangeChanged(selectedDate) {
339
385
  if (!selectedDate)
340
386
  return;
341
387
  if (this.selectingStart) {
342
- this.startDate.set(selectedDate.toISOString());
388
+ // 正在选择开始日期
389
+ let h = 0, m = 0, s = 0, ms = 0;
390
+ // 尝试保留之前的开始时间
391
+ if (this.selectedDateRange?.start) {
392
+ h = this.selectedDateRange.start.getHours();
393
+ m = this.selectedDateRange.start.getMinutes();
394
+ s = this.selectedDateRange.start.getSeconds();
395
+ }
396
+ const newStart = new Date(selectedDate);
397
+ newStart.setHours(h, m, s, ms);
398
+ this.startDate.set(newStart.toISOString());
343
399
  this.endDate.set('');
344
- this.startHour.set(selectedDate.getHours());
345
- this.startMinute.set(selectedDate.getMinutes());
400
+ this.startHour.set(newStart.getHours());
401
+ this.startMinute.set(newStart.getMinutes());
346
402
  this.endHour.set(null);
347
403
  this.endMinute.set(null);
348
404
  this.selectedTimeRange.set(undefined);
349
- this.selectedDateRange = null;
350
- this.#selectionModel.updateSelection(new DateRange(selectedDate, null), this);
405
+ this.selectedDateRange = new DateRange(newStart, null);
406
+ this.#selectionModel.updateSelection(this.selectedDateRange, this);
351
407
  this.selectingStart = false;
352
408
  }
353
409
  else {
410
+ // 正在选择结束日期
354
411
  const start = this.#selectionModel.selection.start;
355
412
  if (!start)
356
413
  return;
357
- const range = start.toDateString() === selectedDate.toDateString()
358
- ? new DateRange(start, start)
359
- : new DateRange(start < selectedDate ? start : selectedDate, start < selectedDate ? selectedDate : start);
360
- this.updateSelection(range.start, range.end);
414
+ const startDay = new Date(start.getFullYear(), start.getMonth(), start.getDate());
415
+ const selectedDay = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate());
416
+ let newStart;
417
+ let newEnd;
418
+ if (selectedDay.getTime() < startDay.getTime()) {
419
+ // 用户选了一个比 Start 更早的日期 -> 交换角色
420
+ // 新 Start (selectedDate) 设为 00:00
421
+ newStart = new Date(selectedDate);
422
+ newStart.setHours(0, 0, 0, 0);
423
+ // 新 End (旧 start) 设为 23:59
424
+ newEnd = new Date(start);
425
+ newEnd.setHours(23, 59, 59, 999);
426
+ }
427
+ else {
428
+ // 正常顺序 (selectedDate >= start)
429
+ // Start 保持原样
430
+ newStart = new Date(start);
431
+ // End (selectedDate) 设为 23:59
432
+ newEnd = new Date(selectedDate);
433
+ newEnd.setHours(23, 59, 59, 999);
434
+ // 如果是同一天,确保 Start <= End
435
+ if (newStart.getTime() > newEnd.getTime()) {
436
+ newStart.setHours(0, 0, 0, 0);
437
+ }
438
+ }
439
+ this.updateSelection(newStart, newEnd);
361
440
  this.selectingStart = true;
362
441
  }
363
442
  }
@@ -373,13 +452,17 @@ class DateSelector {
373
452
  this.endMinute.set(end.getMinutes());
374
453
  }
375
454
  submit() {
376
- const start = new Date(this.selectedDateRange?.start ?? '');
377
- const end = new Date(this.selectedDateRange?.end ?? '');
378
- const startISO = start.toISOString();
379
- const endISO = end.toISOString();
455
+ if (!this.selectedDateRange?.start || !this.selectedDateRange?.end) {
456
+ return;
457
+ }
458
+ const start = new Date(this.selectedDateRange.start);
459
+ const end = new Date(this.selectedDateRange.end);
460
+ if (isNaN(start.getTime()) || isNaN(end.getTime())) {
461
+ return;
462
+ }
380
463
  const result = {
381
- start: startISO,
382
- end: endISO
464
+ start: start.toISOString(),
465
+ end: end.toISOString()
383
466
  };
384
467
  this.data = { ...this.data, dateTimePicker: result };
385
468
  this.#dialogRef.close(this.data);
@@ -387,12 +470,6 @@ class DateSelector {
387
470
  dismiss() {
388
471
  this.#dialogRef.close(undefined);
389
472
  }
390
- getHours() {
391
- return Array.from({ length: 24 }, (_, i) => i);
392
- }
393
- getMinutes() {
394
- return Array.from({ length: 60 }, (_, i) => i);
395
- }
396
473
  updateStartTime() {
397
474
  if (this.selectedDateRange?.start && this.startHour() !== null && this.startMinute() !== null) {
398
475
  const startDate = new Date(this.selectedDateRange.start);
@@ -415,36 +492,42 @@ class DateSelector {
415
492
  this.endDate.set(endDate.toISOString());
416
493
  }
417
494
  }
418
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DateSelector, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
419
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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 }, optionalFeatures: { classPropertyName: "optionalFeatures", publicName: "optionalFeatures", isSignal: true, isRequired: false, transformFunction: null }, selectedTimeRange: { classPropertyName: "selectedTimeRange", publicName: "selectedTimeRange", isSignal: true, isRequired: false, transformFunction: null }, allDays: { classPropertyName: "allDays", publicName: "allDays", isSignal: true, isRequired: false, transformFunction: null }, weekdays: { classPropertyName: "weekdays", publicName: "weekdays", isSignal: true, isRequired: false, transformFunction: null }, allHours: { classPropertyName: "allHours", publicName: "allHours", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { startDate: "startDateChange", endDate: "endDateChange", startHour: "startHourChange", startMinute: "startMinuteChange", endHour: "endHourChange", endMinute: "endMinuteChange", future: "futureChange", optionalFeatures: "optionalFeaturesChange", selectedTimeRange: "selectedTimeRangeChange", allDays: "allDaysChange", weekdays: "weekdaysChange", allHours: "allHoursChange" }, providers: [provideNativeDateAdapter(), DefaultMatCalendarRangeStrategy, MatRangeDateSelectionModel], 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 <!-- \u5DE6\u4FA7\u5FEB\u6377\u9009\u62E9\u9762\u677F -->\r\n <aside 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 </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)\"\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 </aside>\r\n <!-- \u5DE6\u4FA7\u5FEB\u6377\u9009\u62E9\u9762\u677F\u7ED3\u675F -->\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\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 <!-- \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 [minuteValue]=\"startMinute()\"\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 [minuteValue]=\"endMinute()\"\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 @if (optionalFeatures()) {\r\n <!-- \u81EA\u5B9A\u4E49\u9009\u9879 -->\r\n <div class=\"date-selector-options\">\r\n <!-- \u81EA\u5B9A\u4E49\u5929\u6570 -->\r\n <div class=\"date-selector-option-group\">\r\n <mat-checkbox [(ngModel)]=\"allDays\" class=\"date-selector-option-checkbox\">\r\n <span class=\"date-selector-option-label\">\u6240\u6709\u5929</span>\r\n </mat-checkbox>\r\n\r\n @if (!allDays()) {\r\n <div class=\"date-selector-weekdays\">\r\n @for (day of weekdays(); track day.value) {\r\n <button type=\"button\" (click)=\"day.selected = !day.selected\" [class.selected]=\"day.selected\" class=\"date-selector-weekday-btn\">\r\n {{ day.label }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- \u81EA\u5B9A\u4E49\u5C0F\u65F6 -->\r\n <div class=\"date-selector-option-group\">\r\n <mat-checkbox [(ngModel)]=\"allHours\" class=\"date-selector-option-checkbox\">\r\n <span class=\"date-selector-option-label\">\u6240\u6709\u5C0F\u65F6</span>\r\n </mat-checkbox>\r\n </div>\r\n </div>\r\n }\r\n </section>\r\n </div>\r\n </div>\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 (selectedDateRange) {\r\n <div class=\"date-selector-footer-value\">\r\n @if (selectedDateRange.start) {\r\n <span class=\"date-selector-footer-date\">{{ selectedDateRange.start | date: dateFormat }}</span>\r\n }\r\n\r\n @if (selectedDateRange.start && selectedDateRange.end) {\r\n <span class=\"date-selector-footer-separator\">-</span>\r\n }\r\n\r\n @if (selectedDateRange.end) {\r\n <span class=\"date-selector-footer-date\">{{ selectedDateRange.end | date: dateFormat }}</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%;display:none;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}@media(min-width:1024px){.date-selector-sidebar{display:flex}}.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}.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{flex:1;width:100%;height:100%;display:flex;background-color:var(--mat-sys-surface, #fff)}@media(min-width:1024px){.date-selector-main{width:calc(100% - 12rem)}}.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%;min-height: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))}}.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-time-section{width:100%;display:flex;flex-direction:column;overflow-y:auto;overflow-x:hidden}@media(min-width:768px){.date-selector-time-section{width:50%}}.date-selector-inputs{display:flex;flex-direction:column;padding:0}.date-selector-options{display:flex;flex-direction:column;gap:0;padding:12px 16px;border-top:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));background-color:var(--mat-sys-surface-container, #fafafa)}.date-selector-option-group{display:flex;flex-direction:column;gap:8px}.date-selector-option-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));margin-left:4px}.date-selector-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin-top:4px}.date-selector-weekday-btn{padding:8px 4px;background-color:var(--mat-sys-surface, #fff);border:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));border-radius:4px;cursor:pointer;font-size:.75rem;font-weight:500;line-height:1.25;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));text-align:center;white-space:nowrap;transition:all .2s ease}.date-selector-weekday-btn:hover{border-color:var(--mat-sys-primary, #1976d2);background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .08))}.date-selector-weekday-btn.selected{background-color:var(--mat-sys-primary, #1976d2);border-color:var(--mat-sys-primary, #1976d2);color:var(--mat-sys-on-primary, white);font-weight:600}.date-selector-weekday-btn:focus-visible{outline:2px solid var(--mat-sys-primary, #1976d2);outline-offset:2px}.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}}\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$2.Dir, selector: "[dir]", inputs: ["dir"], outputs: ["dirChange"], exportAs: ["dir"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatTimepickerModule }, { 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: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
495
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DateSelector, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
496
+ 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: [
497
+ DefaultMatCalendarRangeStrategy,
498
+ MatRangeDateSelectionModel
499
+ ], 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 }); }
420
500
  }
421
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DateSelector, decorators: [{
501
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DateSelector, decorators: [{
422
502
  type: Component,
423
- args: [{ selector: 'date-time-picker-selector', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [provideNativeDateAdapter(), DefaultMatCalendarRangeStrategy, MatRangeDateSelectionModel], imports: [
503
+ args: [{ selector: 'date-time-picker-selector', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
504
+ DefaultMatCalendarRangeStrategy,
505
+ MatRangeDateSelectionModel
506
+ ], imports: [
424
507
  MatCalendar,
425
508
  TablerIconComponent,
426
509
  MatDatepickerModule,
427
- MatNativeDateModule,
428
510
  ReactiveFormsModule,
429
511
  FormsModule,
430
- MatCheckbox,
431
- DatePipe,
432
- MatTimepickerModule,
433
512
  Container,
434
- DateTimeInputComponent
435
- ], 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 <!-- \u5DE6\u4FA7\u5FEB\u6377\u9009\u62E9\u9762\u677F -->\r\n <aside 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 </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)\"\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 </aside>\r\n <!-- \u5DE6\u4FA7\u5FEB\u6377\u9009\u62E9\u9762\u677F\u7ED3\u675F -->\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\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 <!-- \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 [minuteValue]=\"startMinute()\"\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 [minuteValue]=\"endMinute()\"\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 @if (optionalFeatures()) {\r\n <!-- \u81EA\u5B9A\u4E49\u9009\u9879 -->\r\n <div class=\"date-selector-options\">\r\n <!-- \u81EA\u5B9A\u4E49\u5929\u6570 -->\r\n <div class=\"date-selector-option-group\">\r\n <mat-checkbox [(ngModel)]=\"allDays\" class=\"date-selector-option-checkbox\">\r\n <span class=\"date-selector-option-label\">\u6240\u6709\u5929</span>\r\n </mat-checkbox>\r\n\r\n @if (!allDays()) {\r\n <div class=\"date-selector-weekdays\">\r\n @for (day of weekdays(); track day.value) {\r\n <button type=\"button\" (click)=\"day.selected = !day.selected\" [class.selected]=\"day.selected\" class=\"date-selector-weekday-btn\">\r\n {{ day.label }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- \u81EA\u5B9A\u4E49\u5C0F\u65F6 -->\r\n <div class=\"date-selector-option-group\">\r\n <mat-checkbox [(ngModel)]=\"allHours\" class=\"date-selector-option-checkbox\">\r\n <span class=\"date-selector-option-label\">\u6240\u6709\u5C0F\u65F6</span>\r\n </mat-checkbox>\r\n </div>\r\n </div>\r\n }\r\n </section>\r\n </div>\r\n </div>\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 (selectedDateRange) {\r\n <div class=\"date-selector-footer-value\">\r\n @if (selectedDateRange.start) {\r\n <span class=\"date-selector-footer-date\">{{ selectedDateRange.start | date: dateFormat }}</span>\r\n }\r\n\r\n @if (selectedDateRange.start && selectedDateRange.end) {\r\n <span class=\"date-selector-footer-separator\">-</span>\r\n }\r\n\r\n @if (selectedDateRange.end) {\r\n <span class=\"date-selector-footer-date\">{{ selectedDateRange.end | date: dateFormat }}</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%;display:none;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}@media(min-width:1024px){.date-selector-sidebar{display:flex}}.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}.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{flex:1;width:100%;height:100%;display:flex;background-color:var(--mat-sys-surface, #fff)}@media(min-width:1024px){.date-selector-main{width:calc(100% - 12rem)}}.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%;min-height: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))}}.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-time-section{width:100%;display:flex;flex-direction:column;overflow-y:auto;overflow-x:hidden}@media(min-width:768px){.date-selector-time-section{width:50%}}.date-selector-inputs{display:flex;flex-direction:column;padding:0}.date-selector-options{display:flex;flex-direction:column;gap:0;padding:12px 16px;border-top:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));background-color:var(--mat-sys-surface-container, #fafafa)}.date-selector-option-group{display:flex;flex-direction:column;gap:8px}.date-selector-option-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));margin-left:4px}.date-selector-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin-top:4px}.date-selector-weekday-btn{padding:8px 4px;background-color:var(--mat-sys-surface, #fff);border:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));border-radius:4px;cursor:pointer;font-size:.75rem;font-weight:500;line-height:1.25;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));text-align:center;white-space:nowrap;transition:all .2s ease}.date-selector-weekday-btn:hover{border-color:var(--mat-sys-primary, #1976d2);background-color:var(--mat-sys-primary-container, rgba(25, 118, 210, .08))}.date-selector-weekday-btn.selected{background-color:var(--mat-sys-primary, #1976d2);border-color:var(--mat-sys-primary, #1976d2);color:var(--mat-sys-on-primary, white);font-weight:600}.date-selector-weekday-btn:focus-visible{outline:2px solid var(--mat-sys-primary, #1976d2);outline-offset:2px}.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}}\n", ":host{display:block;height:100%}\n"] }]
436
- }], propDecorators: { startDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "startDate", required: false }] }, { type: i0.Output, args: ["startDateChange"] }], endDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "endDate", required: false }] }, { type: i0.Output, args: ["endDateChange"] }], startHour: [{ type: i0.Input, args: [{ isSignal: true, alias: "startHour", required: false }] }, { type: i0.Output, args: ["startHourChange"] }], startMinute: [{ type: i0.Input, args: [{ isSignal: true, alias: "startMinute", required: false }] }, { type: i0.Output, args: ["startMinuteChange"] }], endHour: [{ type: i0.Input, args: [{ isSignal: true, alias: "endHour", required: false }] }, { type: i0.Output, args: ["endHourChange"] }], endMinute: [{ type: i0.Input, args: [{ isSignal: true, alias: "endMinute", required: false }] }, { type: i0.Output, args: ["endMinuteChange"] }], future: [{ type: i0.Input, args: [{ isSignal: true, alias: "future", required: false }] }, { type: i0.Output, args: ["futureChange"] }], optionalFeatures: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalFeatures", required: false }] }, { type: i0.Output, args: ["optionalFeaturesChange"] }], selectedTimeRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedTimeRange", required: false }] }, { type: i0.Output, args: ["selectedTimeRangeChange"] }], allDays: [{ type: i0.Input, args: [{ isSignal: true, alias: "allDays", required: false }] }, { type: i0.Output, args: ["allDaysChange"] }], weekdays: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekdays", required: false }] }, { type: i0.Output, args: ["weekdaysChange"] }], allHours: [{ type: i0.Input, args: [{ isSignal: true, alias: "allHours", required: false }] }, { type: i0.Output, args: ["allHoursChange"] }] } });
513
+ DateTimeInputComponent,
514
+ MatSidenavModule,
515
+ MatButtonModule
516
+ ], 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"] }]
517
+ }], ctorParameters: () => [], propDecorators: { sidenav: [{
518
+ type: ViewChild,
519
+ args: ['sidenav']
520
+ }], startDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "startDate", required: false }] }, { type: i0.Output, args: ["startDateChange"] }], endDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "endDate", required: false }] }, { type: i0.Output, args: ["endDateChange"] }], startHour: [{ type: i0.Input, args: [{ isSignal: true, alias: "startHour", required: false }] }, { type: i0.Output, args: ["startHourChange"] }], startMinute: [{ type: i0.Input, args: [{ isSignal: true, alias: "startMinute", required: false }] }, { type: i0.Output, args: ["startMinuteChange"] }], endHour: [{ type: i0.Input, args: [{ isSignal: true, alias: "endHour", required: false }] }, { type: i0.Output, args: ["endHourChange"] }], endMinute: [{ type: i0.Input, args: [{ isSignal: true, alias: "endMinute", required: false }] }, { type: i0.Output, args: ["endMinuteChange"] }], future: [{ type: i0.Input, args: [{ isSignal: true, alias: "future", required: false }] }, { type: i0.Output, args: ["futureChange"] }], selectedTimeRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedTimeRange", required: false }] }, { type: i0.Output, args: ["selectedTimeRangeChange"] }] } });
437
521
 
438
522
  class DatePickerComponent {
439
523
  #breakpoints;
440
524
  #dialog;
441
525
  #focusMonitor;
442
526
  #elementRef;
443
- #matFormField;
527
+ #injector;
444
528
  // 内部值存储:{start: string, end: string} 或 null/undefined
445
529
  #internalValue;
446
530
  #errorStateSignal;
447
- #shouldLabelFloatSignal;
448
531
  #focusedSignal;
449
532
  #id;
450
533
  constructor() {
@@ -452,40 +535,48 @@ class DatePickerComponent {
452
535
  this.#dialog = inject(MatDialog);
453
536
  this.#focusMonitor = inject(FocusMonitor);
454
537
  this.#elementRef = inject(ElementRef);
455
- this.#matFormField = inject(MatFormField, { optional: true });
538
+ this.#injector = inject(Injector);
539
+ this._dateAdapter = inject(DateAdapter);
540
+ this._dateFormats = inject(MAT_DATE_FORMATS);
456
541
  this.destroyRef = inject(DestroyRef);
457
- this.ngControl = null;
542
+ this.ngControl = inject(NgControl, { optional: true, self: true });
458
543
  this.required = false;
459
- this.disabled = false;
460
- this.dateFormat = 'yyyy年M月d日 HH:mm';
461
- this.valueFormat = 'yyyy-MM-dd HH:mm:ss';
544
+ this.disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : {}), alias: 'disabled' });
545
+ this._formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_formDisabled" }] : []));
462
546
  this.placeholder = '';
463
- this.optionalFeatures = input(true, ...(ngDevMode ? [{ debugName: "optionalFeatures" }] : []));
464
547
  this.future = input(false, ...(ngDevMode ? [{ debugName: "future" }] : []));
465
548
  this.selectedDateRange = model(...(ngDevMode ? [undefined, { debugName: "selectedDateRange" }] : []));
466
- this.toggle = signal(false, ...(ngDevMode ? [{ debugName: "toggle" }] : []));
467
549
  this.selectionChange = output();
468
550
  // 内部值存储:{start: string, end: string} 或 null/undefined
469
551
  this.#internalValue = signal(undefined, ...(ngDevMode ? [{ debugName: "#internalValue" }] : []));
470
552
  // MatFormFieldControl 属性
471
553
  this.stateChanges = new Subject();
472
554
  this.#errorStateSignal = signal(false, ...(ngDevMode ? [{ debugName: "#errorStateSignal" }] : []));
473
- this.#shouldLabelFloatSignal = signal(false, ...(ngDevMode ? [{ debugName: "#shouldLabelFloatSignal" }] : []));
474
555
  this.#focusedSignal = signal(false, ...(ngDevMode ? [{ debugName: "#focusedSignal" }] : []));
475
556
  this.#id = signal(`date-time-picker-${Math.random().toString(36).substr(2, 9)}`, ...(ngDevMode ? [{ debugName: "#id" }] : []));
557
+ this.displayStart = computed(() => {
558
+ const range = this.selectedDateRange();
559
+ if (!range?.start)
560
+ return '';
561
+ return formatDate(range.start, this._dateAdapter, this._dateFormats);
562
+ }, ...(ngDevMode ? [{ debugName: "displayStart" }] : []));
563
+ this.displayEnd = computed(() => {
564
+ const range = this.selectedDateRange();
565
+ if (!range?.end)
566
+ return '';
567
+ return formatDate(range.end, this._dateAdapter, this._dateFormats);
568
+ }, ...(ngDevMode ? [{ debugName: "displayEnd" }] : []));
476
569
  this.ref = effect(() => {
477
- const dateRange = this.selectedDateRange();
570
+ this.selectedDateRange();
478
571
  // 触发 MatFormField 更新
479
- this.stateChanges.next();
480
- this.#shouldLabelFloatSignal.set(!!dateRange);
481
- // 通知 ControlValueAccessor(当通过 model 更新时)
482
- if (dateRange && this.onChange) {
483
- const value = this.#internalValue();
484
- if (value) {
485
- this.onChange(value);
486
- }
487
- }
572
+ untracked(() => this.stateChanges.next());
488
573
  }, ...(ngDevMode ? [{ debugName: "ref" }] : []));
574
+ if (this.ngControl) {
575
+ this.ngControl.valueAccessor = this;
576
+ this.ngControl.statusChanges?.pipe(takeUntilDestroyed()).subscribe(() => {
577
+ this.stateChanges.next();
578
+ });
579
+ }
489
580
  // 监听 focus 事件
490
581
  this.#focusMonitor
491
582
  .monitor(this.#elementRef, true)
@@ -498,16 +589,17 @@ class DatePickerComponent {
498
589
  this.onTouched?.();
499
590
  }
500
591
  });
592
+ effect(() => {
593
+ this.disabledInput();
594
+ untracked(() => this.stateChanges.next());
595
+ });
501
596
  }
502
597
  openDateDialogSelector() {
503
598
  const isMobile = this.#breakpoints.isMatched([Breakpoints.Handset, Breakpoints.Tablet]);
504
599
  const currentValue = this.#internalValue();
505
600
  const data = {
506
- optionalFeatures: this.optionalFeatures(),
507
601
  dateTimePicker: currentValue ?? undefined,
508
- future: this.future(),
509
- dateFormat: this.dateFormat,
510
- valueFormat: this.valueFormat
602
+ future: this.future()
511
603
  };
512
604
  const dialogRef = this.#dialog.open(DateSelector, {
513
605
  width: isMobile ? '100%' : '850px',
@@ -516,24 +608,24 @@ class DatePickerComponent {
516
608
  maxHeight: '100vh',
517
609
  data,
518
610
  disableClose: false,
519
- panelClass: 'date-time-picker-dialog'
611
+ panelClass: 'date-time-picker-dialog',
612
+ injector: this.#injector
520
613
  });
521
- dialogRef
522
- .afterOpened()
523
- .pipe(take(1), takeUntilDestroyed(this.destroyRef), tap(() => this.toggle.update((status) => !status)))
524
- .subscribe();
525
614
  dialogRef
526
615
  .afterClosed()
527
616
  .pipe(take(1), takeUntilDestroyed(this.destroyRef), tap((result) => {
528
- this.toggle.update((status) => !status);
529
617
  if (result && result.dateTimePicker) {
618
+ const start = new Date(result.dateTimePicker.start);
619
+ const end = new Date(result.dateTimePicker.end);
620
+ const startStr = formatDate(start, this._dateAdapter, this._dateFormats);
621
+ const endStr = formatDate(end, this._dateAdapter, this._dateFormats);
530
622
  const rangeValue = {
531
- start: result.dateTimePicker.start,
532
- end: result.dateTimePicker.end
623
+ start: startStr,
624
+ end: endStr
533
625
  };
534
626
  this.#internalValue.set(rangeValue);
535
627
  // 更新显示用的日期范围
536
- this.selectedDateRange.set(new DateRange(new Date(result.dateTimePicker.start), new Date(result.dateTimePicker.end)));
628
+ this.selectedDateRange.set(new DateRange(start, end));
537
629
  // 发出用户手动选择的值
538
630
  this.selectionChange.emit(rangeValue);
539
631
  // 通知表单控件
@@ -574,23 +666,27 @@ class DatePickerComponent {
574
666
  this.onTouched = fn;
575
667
  }
576
668
  setDisabledState(isDisabled) {
577
- // 可以根据需要在这里处理禁用状态
669
+ this._formDisabled.set(isDisabled);
670
+ this.stateChanges.next();
671
+ }
672
+ get disabled() {
673
+ return this.disabledInput() || this._formDisabled();
578
674
  }
579
675
  // MatFormFieldControl 实现
580
676
  get empty() {
581
677
  return !this.#internalValue();
582
678
  }
583
679
  get shouldPlaceholderFloat() {
584
- return this.#shouldLabelFloatSignal();
680
+ return this.shouldLabelFloat;
585
681
  }
586
682
  get focused() {
587
683
  return this.#focusedSignal();
588
684
  }
589
685
  get errorState() {
590
- return this.#errorStateSignal();
686
+ return this.#errorStateSignal() || (!!this.ngControl?.invalid && (!!this.ngControl?.touched || !!this.ngControl?.dirty));
591
687
  }
592
688
  get shouldLabelFloat() {
593
- return this.#shouldLabelFloatSignal();
689
+ return this.focused || !this.empty;
594
690
  }
595
691
  get id() {
596
692
  return this.#id();
@@ -616,189 +712,45 @@ class DatePickerComponent {
616
712
  this.dateRangeButton?.nativeElement.focus();
617
713
  }
618
714
  }
619
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
620
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: DatePickerComponent, isStandalone: true, selector: "date-time-picker", inputs: { required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null }, dateFormat: { classPropertyName: "dateFormat", publicName: "dateFormat", isSignal: false, isRequired: false, transformFunction: null }, valueFormat: { classPropertyName: "valueFormat", publicName: "valueFormat", isSignal: false, isRequired: false, transformFunction: null }, dateTimePicker: { classPropertyName: "dateTimePicker", publicName: "dateTimePicker", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: false, isRequired: false, transformFunction: null }, optionalFeatures: { classPropertyName: "optionalFeatures", publicName: "optionalFeatures", isSignal: true, isRequired: false, transformFunction: null }, future: { classPropertyName: "future", publicName: "future", isSignal: true, isRequired: false, transformFunction: null }, selectedDateRange: { classPropertyName: "selectedDateRange", publicName: "selectedDateRange", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedDateRange: "selectedDateRangeChange", selectionChange: "selectionChange" }, providers: [
715
+ clear(event) {
716
+ event?.stopPropagation();
717
+ this.selectedDateRange.set(undefined);
718
+ this.#internalValue.set(null);
719
+ this.onChange?.(null);
720
+ this.onTouched?.();
721
+ this.selectionChange.emit(undefined);
722
+ this.stateChanges.next();
723
+ }
724
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
725
+ 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 }, selectedDateRange: { classPropertyName: "selectedDateRange", publicName: "selectedDateRange", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedDateRange: "selectedDateRangeChange", selectionChange: "selectionChange" }, providers: [
621
726
  provideTablerIcons({ IconCalendarDue, IconX }),
622
- {
623
- provide: NG_VALUE_ACCESSOR,
624
- useExisting: forwardRef(() => DatePickerComponent),
625
- multi: true
626
- },
627
727
  {
628
728
  provide: MatFormFieldControl,
629
729
  useExisting: forwardRef(() => DatePickerComponent)
630
730
  }
631
- ], viewQueries: [{ propertyName: "dateRangeButton", first: true, predicate: ["dateRangeButton"], descendants: true }], ngImport: i0, template: "<div\r\n #dateRangeButton\r\n [attr.id]=\"id\"\r\n [attr.aria-label]=\"'\u9009\u62E9\u65E5\u671F\u65F6\u95F4\u8303\u56F4'\"\r\n [attr.aria-disabled]=\"disabled\"\r\n (click)=\"!disabled && openDateDialogSelector()\"\r\n (keydown.enter)=\"!disabled && openDateDialogSelector()\"\r\n (keydown.space)=\"!disabled && openDateDialogSelector()\"\r\n tabindex=\"0\"\r\n [attr.role]=\"'button'\"\r\n class=\"date-range-container\"\r\n>\r\n @if (selectedDateRange()) {\r\n <div class=\"date-range-content\">\r\n <div class=\"date-range-primary\">\r\n {{ selectedDateRange()?.start | date: dateFormat }}\r\n </div>\r\n <div class=\"date-range-secondary\">\r\n {{ selectedDateRange()?.end | date: dateFormat }}\r\n </div>\r\n </div>\r\n } @else if (placeholder) {\r\n <span class=\"date-range-placeholder\">{{ placeholder }}</span>\r\n } @else {\r\n <div class=\"date-range-content\"></div>\r\n }\r\n\r\n <div class=\"date-range-actions\">\r\n <i-tabler name=\"calendar-due\" strokeWidth=\"2px\" size=\"18px\" class=\"date-range-icon\" />\r\n\r\n @if (selectedDateRange()) {\r\n <button\r\n (click)=\"selectedDateRange.set(undefined); $event.stopPropagation()\"\r\n type=\"button\"\r\n class=\"date-range-clear-btn\"\r\n [attr.aria-label]=\"'\u6E05\u9664\u65E5\u671F\u9009\u62E9'\"\r\n tabindex=\"0\"\r\n (keydown.enter)=\"selectedDateRange.set(undefined); $event.stopPropagation()\"\r\n (keydown.space)=\"selectedDateRange.set(undefined); $event.stopPropagation()\"\r\n [attr.role]=\"'button'\"\r\n >\r\n <i-tabler name=\"x\" strokeWidth=\"2.5px\" size=\"18px\" class=\"date-range-icon\" />\r\n </button>\r\n }\r\n </div>\r\n</div>\r\n", styles: [":host{display:block}:host .date-range-container{display:flex;align-items:center;gap:12px;padding:8px 12px;border:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));border-radius:4px;background-color:var(--mat-sys-surface-container-lowest);cursor:pointer;transition:border-color .2s ease}:host .date-range-container:hover{border-color:var(--mat-divider-color, rgba(0, 0, 0, .24))}:host .date-range-container:focus-within{border-color:var(--mat-sys-primary, #1976d2);box-shadow:0 0 0 3px var(--mat-sys-primary-container, rgba(25, 118, 210, .1))}:host .date-range-container[aria-disabled=true]{cursor:not-allowed;opacity:.6;pointer-events:none}:host .date-range-content{flex:1;min-width:0}:host .date-range-primary{font-size:.875rem;font-weight:500;line-height:1.5;color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .date-range-secondary{font-size:.75rem;line-height:1.5;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .date-range-text,:host .date-range-text-muted{display:block}:host .date-range-placeholder{flex:1;font-size:.875rem;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .4))}:host .date-range-actions{display:flex;align-items:center;gap:4px;flex-shrink:0}:host .date-range-icon{color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));display:flex;align-items:center;justify-content:center}:host .date-range-clear-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s ease;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}:host .date-range-clear-btn:hover{background-color:var(--mat-sys-surface-variant, rgba(0, 0, 0, .08))}:host .date-range-clear-btn:focus-visible{outline:2px solid var(--mat-sys-primary, #1976d2);outline-offset:2px}:host(.mat-mdc-form-field) .date-range-container{border:none;border-radius:0;padding:0;box-shadow:none}:host(.mat-mdc-form-field) .date-range-container:hover,:host(.mat-mdc-form-field) .date-range-container:focus-within{border-color:transparent;box-shadow:none}:host-context(.mat-mdc-form-field) .date-range-container,:host([hide-default-styles]) .date-range-container{border:none!important;border-radius:0!important;padding:0!important;box-shadow:none!important;background-color:var(--mat-sys-surface, rgba(0, 0, 0, 0))}:host-context(.mat-mdc-form-field) .date-range-container:hover,:host-context(.mat-mdc-form-field) .date-range-container:focus-within,:host([hide-default-styles]) .date-range-container:hover,:host([hide-default-styles]) .date-range-container:focus-within{border-color:transparent!important;box-shadow:none!important}\n"], dependencies: [{ kind: "component", type: TablerIconComponent, selector: "i-tabler, tabler-icon", inputs: ["name"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
731
+ ], viewQueries: [{ propertyName: "dateRangeButton", first: true, predicate: ["dateRangeButton"], descendants: true }], ngImport: i0, template: "<div\r\n #dateRangeButton\r\n [attr.id]=\"id\"\r\n [attr.aria-label]=\"'\u9009\u62E9\u65E5\u671F\u65F6\u95F4\u8303\u56F4'\"\r\n [attr.aria-disabled]=\"disabled\"\r\n (click)=\"!disabled && openDateDialogSelector()\"\r\n (keydown.enter)=\"!disabled && openDateDialogSelector()\"\r\n (keydown.space)=\"!disabled && openDateDialogSelector()\"\r\n [tabindex]=\"disabled ? -1 : 0\"\r\n [attr.role]=\"'button'\"\r\n class=\"date-range-container\"\r\n>\r\n @if (selectedDateRange()) {\r\n <div class=\"date-range-content\">\r\n <span class=\"date-range-value\">{{ displayStart() }}</span>\r\n <span class=\"date-range-separator\"> ~ </span>\r\n <span class=\"date-range-value\">{{ displayEnd() }}</span>\r\n </div>\r\n } @else if (placeholder) {\r\n <span class=\"date-range-placeholder\">{{ placeholder }}</span>\r\n } @else {\r\n <div class=\"date-range-content\"></div>\r\n }\r\n\r\n <div class=\"date-range-actions\">\r\n @if (selectedDateRange() && !disabled) {\r\n <button\r\n (click)=\"clear($event)\"\r\n type=\"button\"\r\n class=\"date-range-clear-btn\"\r\n [attr.aria-label]=\"'\u6E05\u9664\u65E5\u671F\u9009\u62E9'\"\r\n [tabindex]=\"disabled ? -1 : 0\"\r\n [disabled]=\"disabled\"\r\n (keydown.enter)=\"clear($event)\"\r\n (keydown.space)=\"clear($event)\"\r\n [attr.role]=\"'button'\"\r\n >\r\n <i-tabler name=\"x\" strokeWidth=\"2.5px\" size=\"18px\" class=\"date-range-icon\" />\r\n </button>\r\n }\r\n\r\n <i-tabler name=\"calendar-due\" strokeWidth=\"2px\" size=\"18px\" class=\"date-range-icon\" />\r\n </div>\r\n</div>\r\n", styles: [":host{display:block}:host .date-range-container{display:flex;align-items:center;gap:12px;padding:8px 12px;border:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));border-radius:4px;background-color:var(--mat-sys-surface-container-lowest);cursor:pointer;transition:border-color .2s ease}:host .date-range-container:hover{border-color:var(--mat-divider-color, rgba(0, 0, 0, .24))}:host .date-range-container:focus-within{border-color:var(--mat-sys-primary, #1976d2);box-shadow:0 0 0 3px var(--mat-sys-primary-container, rgba(25, 118, 210, .1))}:host .date-range-container[aria-disabled=true]{cursor:not-allowed;opacity:.6;pointer-events:none}:host .date-range-content{flex:1;min-width:0;display:flex;align-items:center;height:24px}:host .date-range-value{font-size:.875rem;line-height:24px;color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87));white-space:nowrap}:host .date-range-separator{margin:0 4px;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));line-height:24px}:host .date-range-text,:host .date-range-text-muted{display:block}:host .date-range-placeholder{flex:1;font-size:.875rem;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .4))}:host .date-range-actions{display:flex;align-items:center;gap:4px;flex-shrink:0}:host .date-range-icon{color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));display:flex;align-items:center;justify-content:center}:host .date-range-clear-btn{display:none;align-items:center;justify-content:center;width:24px;height:24px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s ease;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}:host .date-range-clear-btn:hover{background-color:var(--mat-sys-surface-variant, rgba(0, 0, 0, .08))}:host .date-range-clear-btn:focus-visible{outline:2px solid var(--mat-sys-primary, #1976d2);outline-offset:2px}:host .date-range-container:hover .date-range-clear-btn{display:flex}:host(.mat-mdc-form-field) .date-range-container{border:none;border-radius:0;padding:0;box-shadow:none}:host(.mat-mdc-form-field) .date-range-container:hover,:host(.mat-mdc-form-field) .date-range-container:focus-within{border-color:transparent;box-shadow:none}:host-context(.mat-mdc-form-field) .date-range-container,:host([hide-default-styles]) .date-range-container{border:none!important;border-radius:0!important;padding:0!important;box-shadow:none!important;background-color:var(--mat-sys-surface, rgba(0, 0, 0, 0))}:host-context(.mat-mdc-form-field) .date-range-container:hover,:host-context(.mat-mdc-form-field) .date-range-container:focus-within,:host([hide-default-styles]) .date-range-container:hover,:host([hide-default-styles]) .date-range-container:focus-within{border-color:transparent!important;box-shadow:none!important}\n"], dependencies: [{ kind: "component", type: TablerIconComponent, selector: "i-tabler, tabler-icon", inputs: ["name"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "ngmodule", type: MatDialogModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
632
732
  }
633
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DatePickerComponent, decorators: [{
733
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DatePickerComponent, decorators: [{
634
734
  type: Component,
635
- args: [{ selector: 'date-time-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TablerIconComponent, MatDatepickerModule, DatePipe, MatDialogModule], providers: [
735
+ args: [{ selector: 'date-time-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TablerIconComponent, MatDatepickerModule, MatDialogModule], providers: [
636
736
  provideTablerIcons({ IconCalendarDue, IconX }),
637
- {
638
- provide: NG_VALUE_ACCESSOR,
639
- useExisting: forwardRef(() => DatePickerComponent),
640
- multi: true
641
- },
642
737
  {
643
738
  provide: MatFormFieldControl,
644
739
  useExisting: forwardRef(() => DatePickerComponent)
645
740
  }
646
- ], template: "<div\r\n #dateRangeButton\r\n [attr.id]=\"id\"\r\n [attr.aria-label]=\"'\u9009\u62E9\u65E5\u671F\u65F6\u95F4\u8303\u56F4'\"\r\n [attr.aria-disabled]=\"disabled\"\r\n (click)=\"!disabled && openDateDialogSelector()\"\r\n (keydown.enter)=\"!disabled && openDateDialogSelector()\"\r\n (keydown.space)=\"!disabled && openDateDialogSelector()\"\r\n tabindex=\"0\"\r\n [attr.role]=\"'button'\"\r\n class=\"date-range-container\"\r\n>\r\n @if (selectedDateRange()) {\r\n <div class=\"date-range-content\">\r\n <div class=\"date-range-primary\">\r\n {{ selectedDateRange()?.start | date: dateFormat }}\r\n </div>\r\n <div class=\"date-range-secondary\">\r\n {{ selectedDateRange()?.end | date: dateFormat }}\r\n </div>\r\n </div>\r\n } @else if (placeholder) {\r\n <span class=\"date-range-placeholder\">{{ placeholder }}</span>\r\n } @else {\r\n <div class=\"date-range-content\"></div>\r\n }\r\n\r\n <div class=\"date-range-actions\">\r\n <i-tabler name=\"calendar-due\" strokeWidth=\"2px\" size=\"18px\" class=\"date-range-icon\" />\r\n\r\n @if (selectedDateRange()) {\r\n <button\r\n (click)=\"selectedDateRange.set(undefined); $event.stopPropagation()\"\r\n type=\"button\"\r\n class=\"date-range-clear-btn\"\r\n [attr.aria-label]=\"'\u6E05\u9664\u65E5\u671F\u9009\u62E9'\"\r\n tabindex=\"0\"\r\n (keydown.enter)=\"selectedDateRange.set(undefined); $event.stopPropagation()\"\r\n (keydown.space)=\"selectedDateRange.set(undefined); $event.stopPropagation()\"\r\n [attr.role]=\"'button'\"\r\n >\r\n <i-tabler name=\"x\" strokeWidth=\"2.5px\" size=\"18px\" class=\"date-range-icon\" />\r\n </button>\r\n }\r\n </div>\r\n</div>\r\n", styles: [":host{display:block}:host .date-range-container{display:flex;align-items:center;gap:12px;padding:8px 12px;border:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));border-radius:4px;background-color:var(--mat-sys-surface-container-lowest);cursor:pointer;transition:border-color .2s ease}:host .date-range-container:hover{border-color:var(--mat-divider-color, rgba(0, 0, 0, .24))}:host .date-range-container:focus-within{border-color:var(--mat-sys-primary, #1976d2);box-shadow:0 0 0 3px var(--mat-sys-primary-container, rgba(25, 118, 210, .1))}:host .date-range-container[aria-disabled=true]{cursor:not-allowed;opacity:.6;pointer-events:none}:host .date-range-content{flex:1;min-width:0}:host .date-range-primary{font-size:.875rem;font-weight:500;line-height:1.5;color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .date-range-secondary{font-size:.75rem;line-height:1.5;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host .date-range-text,:host .date-range-text-muted{display:block}:host .date-range-placeholder{flex:1;font-size:.875rem;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .4))}:host .date-range-actions{display:flex;align-items:center;gap:4px;flex-shrink:0}:host .date-range-icon{color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));display:flex;align-items:center;justify-content:center}:host .date-range-clear-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s ease;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}:host .date-range-clear-btn:hover{background-color:var(--mat-sys-surface-variant, rgba(0, 0, 0, .08))}:host .date-range-clear-btn:focus-visible{outline:2px solid var(--mat-sys-primary, #1976d2);outline-offset:2px}:host(.mat-mdc-form-field) .date-range-container{border:none;border-radius:0;padding:0;box-shadow:none}:host(.mat-mdc-form-field) .date-range-container:hover,:host(.mat-mdc-form-field) .date-range-container:focus-within{border-color:transparent;box-shadow:none}:host-context(.mat-mdc-form-field) .date-range-container,:host([hide-default-styles]) .date-range-container{border:none!important;border-radius:0!important;padding:0!important;box-shadow:none!important;background-color:var(--mat-sys-surface, rgba(0, 0, 0, 0))}:host-context(.mat-mdc-form-field) .date-range-container:hover,:host-context(.mat-mdc-form-field) .date-range-container:focus-within,:host([hide-default-styles]) .date-range-container:hover,:host([hide-default-styles]) .date-range-container:focus-within{border-color:transparent!important;box-shadow:none!important}\n"] }]
741
+ ], template: "<div\r\n #dateRangeButton\r\n [attr.id]=\"id\"\r\n [attr.aria-label]=\"'\u9009\u62E9\u65E5\u671F\u65F6\u95F4\u8303\u56F4'\"\r\n [attr.aria-disabled]=\"disabled\"\r\n (click)=\"!disabled && openDateDialogSelector()\"\r\n (keydown.enter)=\"!disabled && openDateDialogSelector()\"\r\n (keydown.space)=\"!disabled && openDateDialogSelector()\"\r\n [tabindex]=\"disabled ? -1 : 0\"\r\n [attr.role]=\"'button'\"\r\n class=\"date-range-container\"\r\n>\r\n @if (selectedDateRange()) {\r\n <div class=\"date-range-content\">\r\n <span class=\"date-range-value\">{{ displayStart() }}</span>\r\n <span class=\"date-range-separator\"> ~ </span>\r\n <span class=\"date-range-value\">{{ displayEnd() }}</span>\r\n </div>\r\n } @else if (placeholder) {\r\n <span class=\"date-range-placeholder\">{{ placeholder }}</span>\r\n } @else {\r\n <div class=\"date-range-content\"></div>\r\n }\r\n\r\n <div class=\"date-range-actions\">\r\n @if (selectedDateRange() && !disabled) {\r\n <button\r\n (click)=\"clear($event)\"\r\n type=\"button\"\r\n class=\"date-range-clear-btn\"\r\n [attr.aria-label]=\"'\u6E05\u9664\u65E5\u671F\u9009\u62E9'\"\r\n [tabindex]=\"disabled ? -1 : 0\"\r\n [disabled]=\"disabled\"\r\n (keydown.enter)=\"clear($event)\"\r\n (keydown.space)=\"clear($event)\"\r\n [attr.role]=\"'button'\"\r\n >\r\n <i-tabler name=\"x\" strokeWidth=\"2.5px\" size=\"18px\" class=\"date-range-icon\" />\r\n </button>\r\n }\r\n\r\n <i-tabler name=\"calendar-due\" strokeWidth=\"2px\" size=\"18px\" class=\"date-range-icon\" />\r\n </div>\r\n</div>\r\n", styles: [":host{display:block}:host .date-range-container{display:flex;align-items:center;gap:12px;padding:8px 12px;border:1px solid var(--mat-divider-color, rgba(0, 0, 0, .12));border-radius:4px;background-color:var(--mat-sys-surface-container-lowest);cursor:pointer;transition:border-color .2s ease}:host .date-range-container:hover{border-color:var(--mat-divider-color, rgba(0, 0, 0, .24))}:host .date-range-container:focus-within{border-color:var(--mat-sys-primary, #1976d2);box-shadow:0 0 0 3px var(--mat-sys-primary-container, rgba(25, 118, 210, .1))}:host .date-range-container[aria-disabled=true]{cursor:not-allowed;opacity:.6;pointer-events:none}:host .date-range-content{flex:1;min-width:0;display:flex;align-items:center;height:24px}:host .date-range-value{font-size:.875rem;line-height:24px;color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87));white-space:nowrap}:host .date-range-separator{margin:0 4px;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));line-height:24px}:host .date-range-text,:host .date-range-text-muted{display:block}:host .date-range-placeholder{flex:1;font-size:.875rem;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .4))}:host .date-range-actions{display:flex;align-items:center;gap:4px;flex-shrink:0}:host .date-range-icon{color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));display:flex;align-items:center;justify-content:center}:host .date-range-clear-btn{display:none;align-items:center;justify-content:center;width:24px;height:24px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s ease;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}:host .date-range-clear-btn:hover{background-color:var(--mat-sys-surface-variant, rgba(0, 0, 0, .08))}:host .date-range-clear-btn:focus-visible{outline:2px solid var(--mat-sys-primary, #1976d2);outline-offset:2px}:host .date-range-container:hover .date-range-clear-btn{display:flex}:host(.mat-mdc-form-field) .date-range-container{border:none;border-radius:0;padding:0;box-shadow:none}:host(.mat-mdc-form-field) .date-range-container:hover,:host(.mat-mdc-form-field) .date-range-container:focus-within{border-color:transparent;box-shadow:none}:host-context(.mat-mdc-form-field) .date-range-container,:host([hide-default-styles]) .date-range-container{border:none!important;border-radius:0!important;padding:0!important;box-shadow:none!important;background-color:var(--mat-sys-surface, rgba(0, 0, 0, 0))}:host-context(.mat-mdc-form-field) .date-range-container:hover,:host-context(.mat-mdc-form-field) .date-range-container:focus-within,:host([hide-default-styles]) .date-range-container:hover,:host([hide-default-styles]) .date-range-container:focus-within{border-color:transparent!important;box-shadow:none!important}\n"] }]
647
742
  }], ctorParameters: () => [], propDecorators: { dateRangeButton: [{
648
743
  type: ViewChild,
649
744
  args: ['dateRangeButton']
650
745
  }], required: [{
651
746
  type: Input
652
- }], disabled: [{
747
+ }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], placeholder: [{
653
748
  type: Input
654
- }], dateFormat: [{
655
- type: Input
656
- }], valueFormat: [{
657
- type: Input
658
- }], dateTimePicker: [{
659
- type: Input
660
- }], placeholder: [{
661
- type: Input
662
- }], optionalFeatures: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalFeatures", required: false }] }], 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"] }] } });
663
-
664
- class SmartDialogService {
665
- constructor() {
666
- this.#dialog = inject(MatDialog);
667
- this.#bottomSheet = inject(MatBottomSheet);
668
- this.#breakpoints = inject(BreakpointObserver);
669
- this.ref = null;
670
- this.data = null;
671
- }
672
- #dialog;
673
- #bottomSheet;
674
- #breakpoints;
675
- open(component, config = {}) {
676
- const isMobile = this.#breakpoints.isMatched([
677
- Breakpoints.Handset,
678
- Breakpoints.Tablet
679
- ]);
680
- const smartRef = new SmartDialogRef({});
681
- this.data = config.data;
682
- if (isMobile) {
683
- this.ref = this.#bottomSheet.open(component, {
684
- ariaLabel: 'Bottomsheet',
685
- ariaModal: true,
686
- autoFocus: false,
687
- data: config.data,
688
- panelClass: config.panelClass,
689
- disableClose: config.disableClose
690
- });
691
- Promise.resolve().then(() => {
692
- const hostElement = this.ref?.containerInstance?._elementRef?.nativeElement;
693
- const container = hostElement?.closest('.mat-bottom-sheet-container');
694
- if (container) {
695
- if (config.width)
696
- container.style.width = config.width;
697
- if (config.height)
698
- container.style.height = config.height;
699
- if (config.maxWidth)
700
- container.style.maxWidth = config.maxWidth;
701
- container.style.minWidth = 'unset';
702
- container.style.maxHeight = 'unset';
703
- container.style.borderTopLeftRadius = '1rem';
704
- container.style.borderTopRightRadius = '1rem';
705
- }
706
- if (hostElement) {
707
- if (config.width)
708
- hostElement.style.width = config.width;
709
- if (config.maxWidth)
710
- hostElement.style.maxWidth = config.maxWidth;
711
- if (config.height)
712
- hostElement.style.height = config.height;
713
- }
714
- });
715
- smartRef.ref = this.ref;
716
- }
717
- else {
718
- this.ref = this.#dialog.open(component, {
719
- data: config.data,
720
- ariaLabel: 'Dialog',
721
- ariaModal: true,
722
- autoFocus: false,
723
- panelClass: config.panelClass,
724
- disableClose: config.disableClose,
725
- width: config.width,
726
- height: config.height,
727
- maxWidth: config.maxWidth,
728
- });
729
- const hostElement = this.ref._containerInstance?._elementRef?.nativeElement;
730
- const container = hostElement?.closest('.mat-mdc-dialog-panel');
731
- if (container) {
732
- if (config.width)
733
- container.style.width = config.width;
734
- if (config.height)
735
- container.style.height = config.height;
736
- if (config.maxWidth) {
737
- container.style.maxWidth = config.maxWidth;
738
- }
739
- else {
740
- container.style.maxWidth = 'unset';
741
- }
742
- container.style.minWidth = 'unset';
743
- container.style.maxHeight = 'unset';
744
- }
745
- smartRef.ref = this.ref;
746
- }
747
- return smartRef;
748
- }
749
- getData() {
750
- return this.data;
751
- }
752
- close(result) {
753
- if (!this.ref)
754
- return;
755
- if ('close' in this.ref) {
756
- this.ref.close(result);
757
- }
758
- else {
759
- this.ref.dismiss(result);
760
- }
761
- this.clear();
762
- }
763
- clear() {
764
- this.ref = null;
765
- this.data = null;
766
- }
767
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SmartDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
768
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SmartDialogService, providedIn: 'root' }); }
769
- }
770
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SmartDialogService, decorators: [{
771
- type: Injectable,
772
- args: [{ providedIn: 'root' }]
773
- }] });
774
- class SmartDialogRef {
775
- constructor(ref) {
776
- this.ref = ref;
777
- }
778
- close(result) {
779
- if ('close' in this.ref) {
780
- this.ref.close(result);
781
- }
782
- else {
783
- this.ref.dismiss(result);
784
- }
785
- }
786
- afterOpened() {
787
- return this.ref.afterOpened();
788
- }
789
- afterClosed() {
790
- if ('afterClosed' in this.ref) {
791
- return this.ref.afterClosed();
792
- }
793
- else {
794
- return this.ref.afterDismissed();
795
- }
796
- }
797
- }
749
+ }], 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"] }] } });
798
750
 
799
751
  /**
800
752
  * Generated bundle index. Do not edit.
801
753
  */
802
754
 
803
- export { DatePickerComponent, DateSelector, SmartDialogRef, SmartDialogService };
755
+ export { DatePickerComponent, DateSelector };
804
756
  //# sourceMappingURL=luoxiao123-angular-material-date-time-range-picker.mjs.map