@shival99/z-ui 1.3.9 → 1.3.11
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,6 +1,6 @@
|
|
|
1
1
|
import { DecimalPipe } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { Pipe, input, output, viewChild, computed, signal, inject, Injector, DestroyRef,
|
|
3
|
+
import { Pipe, input, output, viewChild, computed, signal, inject, Injector, DestroyRef, effect, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
4
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
5
|
import { NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
6
6
|
import { TranslatePipe } from '@ngx-translate/core';
|
|
@@ -395,9 +395,36 @@ const getDayState = (day) => {
|
|
|
395
395
|
}
|
|
396
396
|
return 'default';
|
|
397
397
|
};
|
|
398
|
-
const getMonthState = (monthIndex,
|
|
399
|
-
|
|
400
|
-
|
|
398
|
+
const getMonthState = (monthIndex, selectedMonthIndex, todayMonthIndex) => {
|
|
399
|
+
if (monthIndex === selectedMonthIndex) {
|
|
400
|
+
return 'selected';
|
|
401
|
+
}
|
|
402
|
+
// Only show current month when no value is selected
|
|
403
|
+
if (selectedMonthIndex === -1 && monthIndex === todayMonthIndex) {
|
|
404
|
+
return 'current';
|
|
405
|
+
}
|
|
406
|
+
return 'default';
|
|
407
|
+
};
|
|
408
|
+
const getQuarterState = (quarterIndex, selectedQuarterIndex, todayQuarterIndex) => {
|
|
409
|
+
if (quarterIndex === selectedQuarterIndex) {
|
|
410
|
+
return 'selected';
|
|
411
|
+
}
|
|
412
|
+
// Only show current quarter when no value is selected
|
|
413
|
+
if (selectedQuarterIndex === -1 && quarterIndex === todayQuarterIndex) {
|
|
414
|
+
return 'current';
|
|
415
|
+
}
|
|
416
|
+
return 'default';
|
|
417
|
+
};
|
|
418
|
+
const getYearState = (year, selectedYear, todayYear) => {
|
|
419
|
+
if (year === selectedYear) {
|
|
420
|
+
return 'selected';
|
|
421
|
+
}
|
|
422
|
+
// Only show current year when no value is selected
|
|
423
|
+
if (selectedYear === -1 && year === todayYear) {
|
|
424
|
+
return 'current';
|
|
425
|
+
}
|
|
426
|
+
return 'default';
|
|
427
|
+
};
|
|
401
428
|
|
|
402
429
|
const zCalendarVariants = cva([
|
|
403
430
|
'group flex w-fit items-center rounded-[6px] border border-input bg-white shadow-xs cursor-pointer',
|
|
@@ -456,7 +483,7 @@ const zCalendarMonthVariants = cva([
|
|
|
456
483
|
variants: {
|
|
457
484
|
state: {
|
|
458
485
|
default: 'hover:bg-primary/10 text-foreground',
|
|
459
|
-
current: 'bg-primary
|
|
486
|
+
current: 'bg-primary text-primary-foreground',
|
|
460
487
|
selected: 'bg-primary text-primary-foreground',
|
|
461
488
|
disabled: 'text-muted-foreground/50 cursor-not-allowed line-through',
|
|
462
489
|
},
|
|
@@ -473,7 +500,7 @@ const zCalendarYearVariants = cva([
|
|
|
473
500
|
variants: {
|
|
474
501
|
state: {
|
|
475
502
|
default: 'hover:bg-primary/10 text-foreground',
|
|
476
|
-
current: 'bg-primary
|
|
503
|
+
current: 'bg-primary text-primary-foreground',
|
|
477
504
|
selected: 'bg-primary text-primary-foreground',
|
|
478
505
|
disabled: 'text-muted-foreground/50 cursor-not-allowed line-through',
|
|
479
506
|
},
|
|
@@ -490,6 +517,7 @@ const zCalendarQuarterVariants = cva([
|
|
|
490
517
|
variants: {
|
|
491
518
|
state: {
|
|
492
519
|
default: 'hover:bg-primary/10 text-foreground',
|
|
520
|
+
current: 'bg-primary text-primary-foreground',
|
|
493
521
|
selected: 'bg-primary text-primary-foreground',
|
|
494
522
|
},
|
|
495
523
|
},
|
|
@@ -547,9 +575,121 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
547
575
|
}]
|
|
548
576
|
}] });
|
|
549
577
|
|
|
578
|
+
class ZIsEndHourDisabledPipe {
|
|
579
|
+
transform(hour, context) {
|
|
580
|
+
if (!context.isSameDay) {
|
|
581
|
+
return false;
|
|
582
|
+
}
|
|
583
|
+
let actualHour = hour;
|
|
584
|
+
let actualStartHour = context.startHour;
|
|
585
|
+
if (context.timeFormat === '12h') {
|
|
586
|
+
if (context.endPeriod === 'PM' && hour !== 12) {
|
|
587
|
+
actualHour = hour + 12;
|
|
588
|
+
}
|
|
589
|
+
if (context.endPeriod === 'AM' && hour === 12) {
|
|
590
|
+
actualHour = 0;
|
|
591
|
+
}
|
|
592
|
+
if (context.startPeriod === 'PM' && context.startHour !== 12) {
|
|
593
|
+
actualStartHour = context.startHour + 12;
|
|
594
|
+
}
|
|
595
|
+
if (context.startPeriod === 'AM' && context.startHour === 12) {
|
|
596
|
+
actualStartHour = 0;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
return actualHour < actualStartHour;
|
|
600
|
+
}
|
|
601
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndHourDisabledPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
602
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndHourDisabledPipe, isStandalone: true, name: "zIsEndHourDisabled" });
|
|
603
|
+
}
|
|
604
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndHourDisabledPipe, decorators: [{
|
|
605
|
+
type: Pipe,
|
|
606
|
+
args: [{
|
|
607
|
+
name: 'zIsEndHourDisabled',
|
|
608
|
+
standalone: true,
|
|
609
|
+
pure: true,
|
|
610
|
+
}]
|
|
611
|
+
}] });
|
|
612
|
+
class ZIsEndMinuteDisabledPipe {
|
|
613
|
+
transform(minute, context) {
|
|
614
|
+
if (!context.isSameDay) {
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
let actualStartHour = context.startHour;
|
|
618
|
+
let actualEndHour = context.endHour;
|
|
619
|
+
if (context.timeFormat === '12h') {
|
|
620
|
+
if (context.startPeriod === 'PM' && context.startHour !== 12) {
|
|
621
|
+
actualStartHour = context.startHour + 12;
|
|
622
|
+
}
|
|
623
|
+
if (context.startPeriod === 'AM' && context.startHour === 12) {
|
|
624
|
+
actualStartHour = 0;
|
|
625
|
+
}
|
|
626
|
+
if (context.endPeriod === 'PM' && context.endHour !== 12) {
|
|
627
|
+
actualEndHour = context.endHour + 12;
|
|
628
|
+
}
|
|
629
|
+
if (context.endPeriod === 'AM' && context.endHour === 12) {
|
|
630
|
+
actualEndHour = 0;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
if (actualEndHour !== actualStartHour) {
|
|
634
|
+
return false;
|
|
635
|
+
}
|
|
636
|
+
return minute < context.startMinute;
|
|
637
|
+
}
|
|
638
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndMinuteDisabledPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
639
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndMinuteDisabledPipe, isStandalone: true, name: "zIsEndMinuteDisabled" });
|
|
640
|
+
}
|
|
641
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndMinuteDisabledPipe, decorators: [{
|
|
642
|
+
type: Pipe,
|
|
643
|
+
args: [{
|
|
644
|
+
name: 'zIsEndMinuteDisabled',
|
|
645
|
+
standalone: true,
|
|
646
|
+
pure: true,
|
|
647
|
+
}]
|
|
648
|
+
}] });
|
|
649
|
+
class ZIsEndSecondDisabledPipe {
|
|
650
|
+
transform(second, context) {
|
|
651
|
+
if (!context.isSameDay) {
|
|
652
|
+
return false;
|
|
653
|
+
}
|
|
654
|
+
let actualStartHour = context.startHour;
|
|
655
|
+
let actualEndHour = context.endHour;
|
|
656
|
+
if (context.timeFormat === '12h') {
|
|
657
|
+
if (context.startPeriod === 'PM' && context.startHour !== 12) {
|
|
658
|
+
actualStartHour = context.startHour + 12;
|
|
659
|
+
}
|
|
660
|
+
if (context.startPeriod === 'AM' && context.startHour === 12) {
|
|
661
|
+
actualStartHour = 0;
|
|
662
|
+
}
|
|
663
|
+
if (context.endPeriod === 'PM' && context.endHour !== 12) {
|
|
664
|
+
actualEndHour = context.endHour + 12;
|
|
665
|
+
}
|
|
666
|
+
if (context.endPeriod === 'AM' && context.endHour === 12) {
|
|
667
|
+
actualEndHour = 0;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
if (actualEndHour !== actualStartHour) {
|
|
671
|
+
return false;
|
|
672
|
+
}
|
|
673
|
+
if (context.endMinute !== context.startMinute) {
|
|
674
|
+
return false;
|
|
675
|
+
}
|
|
676
|
+
return second <= context.startSecond;
|
|
677
|
+
}
|
|
678
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndSecondDisabledPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
679
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndSecondDisabledPipe, isStandalone: true, name: "zIsEndSecondDisabled" });
|
|
680
|
+
}
|
|
681
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndSecondDisabledPipe, decorators: [{
|
|
682
|
+
type: Pipe,
|
|
683
|
+
args: [{
|
|
684
|
+
name: 'zIsEndSecondDisabled',
|
|
685
|
+
standalone: true,
|
|
686
|
+
pure: true,
|
|
687
|
+
}]
|
|
688
|
+
}] });
|
|
689
|
+
|
|
550
690
|
class ZMonthClassesPipe {
|
|
551
|
-
transform(monthIndex,
|
|
552
|
-
const state = getMonthState(monthIndex,
|
|
691
|
+
transform(monthIndex, selectedMonthIndex, todayMonthIndex) {
|
|
692
|
+
const state = getMonthState(monthIndex, selectedMonthIndex, todayMonthIndex);
|
|
553
693
|
return zCalendarMonthVariants({ state });
|
|
554
694
|
}
|
|
555
695
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZMonthClassesPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
@@ -564,9 +704,130 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
564
704
|
}]
|
|
565
705
|
}] });
|
|
566
706
|
|
|
707
|
+
class ZIsStartMonthDisabledPipe {
|
|
708
|
+
transform(monthIndex, context) {
|
|
709
|
+
if (context.disabledDateFn) {
|
|
710
|
+
const monthDate = new Date(context.currentYear, monthIndex, 1);
|
|
711
|
+
if (context.disabledDateFn(monthDate)) {
|
|
712
|
+
return true;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
if (!context.isRangeMode) {
|
|
716
|
+
return false;
|
|
717
|
+
}
|
|
718
|
+
if (context.currentYear > context.endYear) {
|
|
719
|
+
return true;
|
|
720
|
+
}
|
|
721
|
+
if (context.currentYear === context.endYear && monthIndex > context.endMonthIndex) {
|
|
722
|
+
return true;
|
|
723
|
+
}
|
|
724
|
+
return false;
|
|
725
|
+
}
|
|
726
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsStartMonthDisabledPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
727
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.6", ngImport: i0, type: ZIsStartMonthDisabledPipe, isStandalone: true, name: "zIsStartMonthDisabled" });
|
|
728
|
+
}
|
|
729
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsStartMonthDisabledPipe, decorators: [{
|
|
730
|
+
type: Pipe,
|
|
731
|
+
args: [{
|
|
732
|
+
name: 'zIsStartMonthDisabled',
|
|
733
|
+
standalone: true,
|
|
734
|
+
pure: true,
|
|
735
|
+
}]
|
|
736
|
+
}] });
|
|
737
|
+
class ZIsEndMonthDisabledPipe {
|
|
738
|
+
transform(monthIndex, context) {
|
|
739
|
+
if (context.disabledDateFn) {
|
|
740
|
+
const monthDate = new Date(context.endYear, monthIndex, 1);
|
|
741
|
+
if (context.disabledDateFn(monthDate)) {
|
|
742
|
+
return true;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
if (!context.isRangeMode) {
|
|
746
|
+
return false;
|
|
747
|
+
}
|
|
748
|
+
if (context.endYear < context.startYear) {
|
|
749
|
+
return true;
|
|
750
|
+
}
|
|
751
|
+
if (context.endYear === context.startYear && monthIndex < context.startMonthIndex) {
|
|
752
|
+
return true;
|
|
753
|
+
}
|
|
754
|
+
return false;
|
|
755
|
+
}
|
|
756
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndMonthDisabledPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
757
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndMonthDisabledPipe, isStandalone: true, name: "zIsEndMonthDisabled" });
|
|
758
|
+
}
|
|
759
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndMonthDisabledPipe, decorators: [{
|
|
760
|
+
type: Pipe,
|
|
761
|
+
args: [{
|
|
762
|
+
name: 'zIsEndMonthDisabled',
|
|
763
|
+
standalone: true,
|
|
764
|
+
pure: true,
|
|
765
|
+
}]
|
|
766
|
+
}] });
|
|
767
|
+
class ZIsStartYearDisabledPipe {
|
|
768
|
+
transform(year, context) {
|
|
769
|
+
if (context.disabledDateFn) {
|
|
770
|
+
const yearDate = new Date(year, 0, 1);
|
|
771
|
+
if (context.disabledDateFn(yearDate)) {
|
|
772
|
+
return true;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
if (!context.isRangeMode) {
|
|
776
|
+
return false;
|
|
777
|
+
}
|
|
778
|
+
if (year > context.endYear) {
|
|
779
|
+
return true;
|
|
780
|
+
}
|
|
781
|
+
if (year === context.endYear && context.startMonthIndex >= context.endMonthIndex) {
|
|
782
|
+
return true;
|
|
783
|
+
}
|
|
784
|
+
return false;
|
|
785
|
+
}
|
|
786
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsStartYearDisabledPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
787
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.6", ngImport: i0, type: ZIsStartYearDisabledPipe, isStandalone: true, name: "zIsStartYearDisabled" });
|
|
788
|
+
}
|
|
789
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsStartYearDisabledPipe, decorators: [{
|
|
790
|
+
type: Pipe,
|
|
791
|
+
args: [{
|
|
792
|
+
name: 'zIsStartYearDisabled',
|
|
793
|
+
standalone: true,
|
|
794
|
+
pure: true,
|
|
795
|
+
}]
|
|
796
|
+
}] });
|
|
797
|
+
class ZIsEndYearDisabledPipe {
|
|
798
|
+
transform(year, context) {
|
|
799
|
+
if (context.disabledDateFn) {
|
|
800
|
+
const yearDate = new Date(year, 0, 1);
|
|
801
|
+
if (context.disabledDateFn(yearDate)) {
|
|
802
|
+
return true;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
if (!context.isRangeMode) {
|
|
806
|
+
return false;
|
|
807
|
+
}
|
|
808
|
+
if (year < context.startYear) {
|
|
809
|
+
return true;
|
|
810
|
+
}
|
|
811
|
+
if (year === context.startYear && context.endMonthIndex <= context.startMonthIndex) {
|
|
812
|
+
return true;
|
|
813
|
+
}
|
|
814
|
+
return false;
|
|
815
|
+
}
|
|
816
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndYearDisabledPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
817
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndYearDisabledPipe, isStandalone: true, name: "zIsEndYearDisabled" });
|
|
818
|
+
}
|
|
819
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsEndYearDisabledPipe, decorators: [{
|
|
820
|
+
type: Pipe,
|
|
821
|
+
args: [{
|
|
822
|
+
name: 'zIsEndYearDisabled',
|
|
823
|
+
standalone: true,
|
|
824
|
+
pure: true,
|
|
825
|
+
}]
|
|
826
|
+
}] });
|
|
827
|
+
|
|
567
828
|
class ZQuarterClassesPipe {
|
|
568
|
-
transform(quarterIndex,
|
|
569
|
-
const state = getQuarterState(quarterIndex,
|
|
829
|
+
transform(quarterIndex, selectedQuarterIndex, todayQuarterIndex) {
|
|
830
|
+
const state = getQuarterState(quarterIndex, selectedQuarterIndex, todayQuarterIndex);
|
|
570
831
|
return zCalendarQuarterVariants({ state });
|
|
571
832
|
}
|
|
572
833
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZQuarterClassesPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
@@ -581,9 +842,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
581
842
|
}]
|
|
582
843
|
}] });
|
|
583
844
|
|
|
845
|
+
class ZIsTimeSelectedPipe {
|
|
846
|
+
transform(value, selectedValue) {
|
|
847
|
+
return value === selectedValue;
|
|
848
|
+
}
|
|
849
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsTimeSelectedPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
850
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.6", ngImport: i0, type: ZIsTimeSelectedPipe, isStandalone: true, name: "zIsTimeSelected" });
|
|
851
|
+
}
|
|
852
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZIsTimeSelectedPipe, decorators: [{
|
|
853
|
+
type: Pipe,
|
|
854
|
+
args: [{
|
|
855
|
+
name: 'zIsTimeSelected',
|
|
856
|
+
standalone: true,
|
|
857
|
+
pure: true,
|
|
858
|
+
}]
|
|
859
|
+
}] });
|
|
860
|
+
|
|
584
861
|
class ZYearClassesPipe {
|
|
585
|
-
transform(year,
|
|
586
|
-
const state = getYearState(year,
|
|
862
|
+
transform(year, selectedYear, todayYear) {
|
|
863
|
+
const state = getYearState(year, selectedYear, todayYear);
|
|
587
864
|
return zCalendarYearVariants({ state });
|
|
588
865
|
}
|
|
589
866
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZYearClassesPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
@@ -644,17 +921,17 @@ class ZCalendarComponent {
|
|
|
644
921
|
minuteOptions = Array.from({ length: 60 }, (_, i) => i);
|
|
645
922
|
secondOptions = Array.from({ length: 60 }, (_, i) => i);
|
|
646
923
|
formattedHour = computed(() => {
|
|
647
|
-
const h = this.
|
|
924
|
+
const h = this.hour();
|
|
648
925
|
if (this.zTimeFormat() === '12h') {
|
|
649
926
|
const h12 = h % 12 || 12;
|
|
650
927
|
return formatTimeValue(h12);
|
|
651
928
|
}
|
|
652
929
|
return formatTimeValue(h);
|
|
653
930
|
}, ...(ngDevMode ? [{ debugName: "formattedHour" }] : []));
|
|
654
|
-
formattedMinute = computed(() => formatTimeValue(this.
|
|
655
|
-
formattedSecond = computed(() => formatTimeValue(this.
|
|
931
|
+
formattedMinute = computed(() => formatTimeValue(this.minute()), ...(ngDevMode ? [{ debugName: "formattedMinute" }] : []));
|
|
932
|
+
formattedSecond = computed(() => formatTimeValue(this.second()), ...(ngDevMode ? [{ debugName: "formattedSecond" }] : []));
|
|
656
933
|
displayHour = computed(() => {
|
|
657
|
-
const h = this.
|
|
934
|
+
const h = this.hour();
|
|
658
935
|
if (this.zTimeFormat() === '12h') {
|
|
659
936
|
return h % 12 || 12;
|
|
660
937
|
}
|
|
@@ -671,15 +948,8 @@ class ZCalendarComponent {
|
|
|
671
948
|
_selectedDate = signal(null, ...(ngDevMode ? [{ debugName: "_selectedDate" }] : []));
|
|
672
949
|
_rangeStart = signal(null, ...(ngDevMode ? [{ debugName: "_rangeStart" }] : []));
|
|
673
950
|
_rangeEnd = signal(null, ...(ngDevMode ? [{ debugName: "_rangeEnd" }] : []));
|
|
674
|
-
_hoveredDate = signal(null, ...(ngDevMode ? [{ debugName: "_hoveredDate" }] : []));
|
|
675
951
|
_currentMonth = signal(getToday(), ...(ngDevMode ? [{ debugName: "_currentMonth" }] : []));
|
|
676
952
|
_endMonth = signal(addMonths(getToday(), 1), ...(ngDevMode ? [{ debugName: "_endMonth" }] : []));
|
|
677
|
-
_currentView = signal('day', ...(ngDevMode ? [{ debugName: "_currentView" }] : []));
|
|
678
|
-
_endView = signal('day', ...(ngDevMode ? [{ debugName: "_endView" }] : []));
|
|
679
|
-
_hour = signal(0, ...(ngDevMode ? [{ debugName: "_hour" }] : []));
|
|
680
|
-
_minute = signal(0, ...(ngDevMode ? [{ debugName: "_minute" }] : []));
|
|
681
|
-
_second = signal(0, ...(ngDevMode ? [{ debugName: "_second" }] : []));
|
|
682
|
-
_period = signal('AM', ...(ngDevMode ? [{ debugName: "_period" }] : []));
|
|
683
953
|
_hourEnd = signal(0, ...(ngDevMode ? [{ debugName: "_hourEnd" }] : []));
|
|
684
954
|
_minuteEnd = signal(0, ...(ngDevMode ? [{ debugName: "_minuteEnd" }] : []));
|
|
685
955
|
_secondEnd = signal(0, ...(ngDevMode ? [{ debugName: "_secondEnd" }] : []));
|
|
@@ -689,38 +959,40 @@ class ZCalendarComponent {
|
|
|
689
959
|
_dirty = signal(false, ...(ngDevMode ? [{ debugName: "_dirty" }] : []));
|
|
690
960
|
_formControl = signal(null, ...(ngDevMode ? [{ debugName: "_formControl" }] : []));
|
|
691
961
|
_formStateVersion = signal(0, ...(ngDevMode ? [{ debugName: "_formStateVersion" }] : []));
|
|
692
|
-
_inputDisplayValue = signal('', ...(ngDevMode ? [{ debugName: "_inputDisplayValue" }] : []));
|
|
693
962
|
_backupSelectedDate = signal(null, ...(ngDevMode ? [{ debugName: "_backupSelectedDate" }] : []));
|
|
694
963
|
_backupRangeStart = signal(null, ...(ngDevMode ? [{ debugName: "_backupRangeStart" }] : []));
|
|
695
964
|
_backupRangeEnd = signal(null, ...(ngDevMode ? [{ debugName: "_backupRangeEnd" }] : []));
|
|
696
|
-
_activePresetKey = signal(null, ...(ngDevMode ? [{ debugName: "_activePresetKey" }] : []));
|
|
697
|
-
_hasViewChanged = signal(false, ...(ngDevMode ? [{ debugName: "_hasViewChanged" }] : []));
|
|
698
|
-
_hasEndViewChanged = signal(false, ...(ngDevMode ? [{ debugName: "_hasEndViewChanged" }] : []));
|
|
699
965
|
_appliedViaOk = signal(false, ...(ngDevMode ? [{ debugName: "_appliedViaOk" }] : []));
|
|
700
966
|
_skipBlurHandler = signal(false, ...(ngDevMode ? [{ debugName: "_skipBlurHandler" }] : []));
|
|
701
967
|
_injector = inject(Injector);
|
|
702
968
|
_destroyRef = inject(DestroyRef);
|
|
703
|
-
_cdr = inject(ChangeDetectorRef);
|
|
704
969
|
_zTranslate = inject(ZTranslateService);
|
|
705
970
|
_onChange = () => void 0;
|
|
706
971
|
_onTouched = () => void 0;
|
|
707
972
|
_ngControl = null;
|
|
708
973
|
isOpen = computed(() => this._popoverControl()?.isVisible() ?? false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
709
|
-
hoveredDate =
|
|
710
|
-
currentView =
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
974
|
+
hoveredDate = signal(null, ...(ngDevMode ? [{ debugName: "hoveredDate" }] : []));
|
|
975
|
+
currentView = signal('day', ...(ngDevMode ? [{ debugName: "currentView" }] : []));
|
|
976
|
+
endView = signal('day', ...(ngDevMode ? [{ debugName: "endView" }] : []));
|
|
977
|
+
hour = signal(0, ...(ngDevMode ? [{ debugName: "hour" }] : []));
|
|
978
|
+
minute = signal(0, ...(ngDevMode ? [{ debugName: "minute" }] : []));
|
|
979
|
+
second = signal(0, ...(ngDevMode ? [{ debugName: "second" }] : []));
|
|
980
|
+
period = signal('AM', ...(ngDevMode ? [{ debugName: "period" }] : []));
|
|
981
|
+
inputDisplayValue = signal('', ...(ngDevMode ? [{ debugName: "inputDisplayValue" }] : []));
|
|
982
|
+
activePresetKey = signal(null, ...(ngDevMode ? [{ debugName: "activePresetKey" }] : []));
|
|
983
|
+
hasViewChanged = signal(false, ...(ngDevMode ? [{ debugName: "hasViewChanged" }] : []));
|
|
984
|
+
hasEndViewChanged = signal(false, ...(ngDevMode ? [{ debugName: "hasEndViewChanged" }] : []));
|
|
985
|
+
timeDropdownOpen = signal(false, ...(ngDevMode ? [{ debugName: "timeDropdownOpen" }] : []));
|
|
986
|
+
timeDropdownEndOpen = signal(false, ...(ngDevMode ? [{ debugName: "timeDropdownEndOpen" }] : []));
|
|
719
987
|
quarterNames = ['Q1', 'Q2', 'Q3', 'Q4'];
|
|
720
|
-
|
|
988
|
+
todayQuarterIndex = computed(() => {
|
|
989
|
+
const today = new Date();
|
|
990
|
+
return Math.floor(today.getMonth() / 3);
|
|
991
|
+
}, ...(ngDevMode ? [{ debugName: "todayQuarterIndex" }] : []));
|
|
992
|
+
selectedQuarterIndex = computed(() => {
|
|
721
993
|
const date = this._selectedDate();
|
|
722
994
|
return date ? Math.floor(date.getMonth() / 3) : -1;
|
|
723
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
995
|
+
}, ...(ngDevMode ? [{ debugName: "selectedQuarterIndex" }] : []));
|
|
724
996
|
isSameDayRange = computed(() => {
|
|
725
997
|
if (!this.isRangeMode()) {
|
|
726
998
|
return false;
|
|
@@ -768,6 +1040,55 @@ class ZCalendarComponent {
|
|
|
768
1040
|
currentMonth = computed(() => this._currentMonth(), ...(ngDevMode ? [{ debugName: "currentMonth" }] : []));
|
|
769
1041
|
currentYear = computed(() => this._currentMonth().getFullYear(), ...(ngDevMode ? [{ debugName: "currentYear" }] : []));
|
|
770
1042
|
currentMonthIndex = computed(() => this._currentMonth().getMonth(), ...(ngDevMode ? [{ debugName: "currentMonthIndex" }] : []));
|
|
1043
|
+
todayMonthIndex = computed(() => new Date().getMonth(), ...(ngDevMode ? [{ debugName: "todayMonthIndex" }] : []));
|
|
1044
|
+
todayYear = computed(() => new Date().getFullYear(), ...(ngDevMode ? [{ debugName: "todayYear" }] : []));
|
|
1045
|
+
selectedMonthIndex = computed(() => {
|
|
1046
|
+
const date = this._selectedDate();
|
|
1047
|
+
return date ? date.getMonth() : -1;
|
|
1048
|
+
}, ...(ngDevMode ? [{ debugName: "selectedMonthIndex" }] : []));
|
|
1049
|
+
selectedYear = computed(() => {
|
|
1050
|
+
const date = this._selectedDate();
|
|
1051
|
+
return date ? date.getFullYear() : -1;
|
|
1052
|
+
}, ...(ngDevMode ? [{ debugName: "selectedYear" }] : []));
|
|
1053
|
+
endTimeContext = computed(() => ({
|
|
1054
|
+
isSameDay: this.isSameDayRange(),
|
|
1055
|
+
startHour: this.hour(),
|
|
1056
|
+
startMinute: this.minute(),
|
|
1057
|
+
startSecond: this.second(),
|
|
1058
|
+
endHour: this._hourEnd(),
|
|
1059
|
+
endMinute: this._minuteEnd(),
|
|
1060
|
+
timeFormat: this.zTimeFormat(),
|
|
1061
|
+
startPeriod: this.period(),
|
|
1062
|
+
endPeriod: this._periodEnd(),
|
|
1063
|
+
}), ...(ngDevMode ? [{ debugName: "endTimeContext" }] : []));
|
|
1064
|
+
startMonthDisabledContext = computed(() => ({
|
|
1065
|
+
currentYear: this._currentMonth().getFullYear(),
|
|
1066
|
+
endYear: this._endMonth().getFullYear(),
|
|
1067
|
+
endMonthIndex: this._endMonth().getMonth(),
|
|
1068
|
+
isRangeMode: this.isRangeMode(),
|
|
1069
|
+
disabledDateFn: this.zDisabledDate(),
|
|
1070
|
+
}), ...(ngDevMode ? [{ debugName: "startMonthDisabledContext" }] : []));
|
|
1071
|
+
endMonthDisabledContext = computed(() => ({
|
|
1072
|
+
startYear: this._currentMonth().getFullYear(),
|
|
1073
|
+
startMonthIndex: this._currentMonth().getMonth(),
|
|
1074
|
+
endYear: this._endMonth().getFullYear(),
|
|
1075
|
+
isRangeMode: this.isRangeMode(),
|
|
1076
|
+
disabledDateFn: this.zDisabledDate(),
|
|
1077
|
+
}), ...(ngDevMode ? [{ debugName: "endMonthDisabledContext" }] : []));
|
|
1078
|
+
startYearDisabledContext = computed(() => ({
|
|
1079
|
+
endYear: this._endMonth().getFullYear(),
|
|
1080
|
+
startMonthIndex: this._currentMonth().getMonth(),
|
|
1081
|
+
endMonthIndex: this._endMonth().getMonth(),
|
|
1082
|
+
isRangeMode: this.isRangeMode(),
|
|
1083
|
+
disabledDateFn: this.zDisabledDate(),
|
|
1084
|
+
}), ...(ngDevMode ? [{ debugName: "startYearDisabledContext" }] : []));
|
|
1085
|
+
endYearDisabledContext = computed(() => ({
|
|
1086
|
+
startYear: this._currentMonth().getFullYear(),
|
|
1087
|
+
startMonthIndex: this._currentMonth().getMonth(),
|
|
1088
|
+
endMonthIndex: this._endMonth().getMonth(),
|
|
1089
|
+
isRangeMode: this.isRangeMode(),
|
|
1090
|
+
disabledDateFn: this.zDisabledDate(),
|
|
1091
|
+
}), ...(ngDevMode ? [{ debugName: "endYearDisabledContext" }] : []));
|
|
771
1092
|
currentMonthName = computed(() => {
|
|
772
1093
|
const month = this._currentMonth();
|
|
773
1094
|
return month.toLocaleDateString(this.zLocale(), { month: 'long' });
|
|
@@ -788,7 +1109,7 @@ class ZCalendarComponent {
|
|
|
788
1109
|
selectedDate: this._selectedDate(),
|
|
789
1110
|
rangeStart: this._rangeStart(),
|
|
790
1111
|
rangeEnd: this._rangeEnd(),
|
|
791
|
-
hoveredDate: this.
|
|
1112
|
+
hoveredDate: this.hoveredDate(),
|
|
792
1113
|
minDate: this.zMinDate(),
|
|
793
1114
|
maxDate: this.zMaxDate(),
|
|
794
1115
|
disabledDate: this.zDisabledDate(),
|
|
@@ -808,7 +1129,7 @@ class ZCalendarComponent {
|
|
|
808
1129
|
selectedDate: this._selectedDate(),
|
|
809
1130
|
rangeStart: this._rangeStart(),
|
|
810
1131
|
rangeEnd: this._rangeEnd(),
|
|
811
|
-
hoveredDate: this.
|
|
1132
|
+
hoveredDate: this.hoveredDate(),
|
|
812
1133
|
minDate: this.zMinDate(),
|
|
813
1134
|
maxDate: this.zMaxDate(),
|
|
814
1135
|
disabledDate: this.zDisabledDate(),
|
|
@@ -817,111 +1138,20 @@ class ZCalendarComponent {
|
|
|
817
1138
|
formattedHourEnd = computed(() => formatTimeValue(this.zTimeFormat() === '12h' ? this._hourEnd() % 12 || 12 : this._hourEnd()), ...(ngDevMode ? [{ debugName: "formattedHourEnd" }] : []));
|
|
818
1139
|
formattedMinuteEnd = computed(() => formatTimeValue(this._minuteEnd()), ...(ngDevMode ? [{ debugName: "formattedMinuteEnd" }] : []));
|
|
819
1140
|
formattedSecondEnd = computed(() => formatTimeValue(this._secondEnd()), ...(ngDevMode ? [{ debugName: "formattedSecondEnd" }] : []));
|
|
1141
|
+
minuteEnd = computed(() => this._minuteEnd(), ...(ngDevMode ? [{ debugName: "minuteEnd" }] : []));
|
|
1142
|
+
secondEnd = computed(() => this._secondEnd(), ...(ngDevMode ? [{ debugName: "secondEnd" }] : []));
|
|
820
1143
|
periodEnd = computed(() => this._periodEnd(), ...(ngDevMode ? [{ debugName: "periodEnd" }] : []));
|
|
821
|
-
endView = this._endView.asReadonly();
|
|
822
1144
|
endYearRange = computed(() => {
|
|
823
1145
|
const currentYear = this._endMonth().getFullYear();
|
|
824
1146
|
return getYearRange(currentYear);
|
|
825
1147
|
}, ...(ngDevMode ? [{ debugName: "endYearRange" }] : []));
|
|
826
|
-
isStartMonthDisabled(monthIndex) {
|
|
827
|
-
const disabledDateFn = this.zDisabledDate();
|
|
828
|
-
if (disabledDateFn) {
|
|
829
|
-
const year = this._currentMonth().getFullYear();
|
|
830
|
-
const monthDate = new Date(year, monthIndex, 1);
|
|
831
|
-
if (disabledDateFn(monthDate)) {
|
|
832
|
-
return true;
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
if (!this.isRangeMode()) {
|
|
836
|
-
return false;
|
|
837
|
-
}
|
|
838
|
-
const startYear = this._currentMonth().getFullYear();
|
|
839
|
-
const endMonth = this._endMonth();
|
|
840
|
-
const endYear = endMonth.getFullYear();
|
|
841
|
-
const endMonthIndex = endMonth.getMonth();
|
|
842
|
-
if (startYear > endYear) {
|
|
843
|
-
return true;
|
|
844
|
-
}
|
|
845
|
-
if (startYear === endYear && monthIndex > endMonthIndex) {
|
|
846
|
-
return true;
|
|
847
|
-
}
|
|
848
|
-
return false;
|
|
849
|
-
}
|
|
850
|
-
isEndMonthDisabled(monthIndex) {
|
|
851
|
-
const disabledDateFn = this.zDisabledDate();
|
|
852
|
-
if (disabledDateFn) {
|
|
853
|
-
const year = this._endMonth().getFullYear();
|
|
854
|
-
const monthDate = new Date(year, monthIndex, 1);
|
|
855
|
-
if (disabledDateFn(monthDate)) {
|
|
856
|
-
return true;
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
if (!this.isRangeMode()) {
|
|
860
|
-
return false;
|
|
861
|
-
}
|
|
862
|
-
const startMonth = this._currentMonth();
|
|
863
|
-
const startYear = startMonth.getFullYear();
|
|
864
|
-
const startMonthIndex = startMonth.getMonth();
|
|
865
|
-
const endYear = this._endMonth().getFullYear();
|
|
866
|
-
if (endYear < startYear) {
|
|
867
|
-
return true;
|
|
868
|
-
}
|
|
869
|
-
if (endYear === startYear && monthIndex < startMonthIndex) {
|
|
870
|
-
return true;
|
|
871
|
-
}
|
|
872
|
-
return false;
|
|
873
|
-
}
|
|
874
|
-
isStartYearDisabled(year) {
|
|
875
|
-
const disabledDateFn = this.zDisabledDate();
|
|
876
|
-
if (disabledDateFn) {
|
|
877
|
-
const yearDate = new Date(year, 0, 1);
|
|
878
|
-
if (disabledDateFn(yearDate)) {
|
|
879
|
-
return true;
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
if (!this.isRangeMode()) {
|
|
883
|
-
return false;
|
|
884
|
-
}
|
|
885
|
-
const endYear = this._endMonth().getFullYear();
|
|
886
|
-
const startMonthIndex = this._currentMonth().getMonth();
|
|
887
|
-
const endMonthIndex = this._endMonth().getMonth();
|
|
888
|
-
if (year > endYear) {
|
|
889
|
-
return true;
|
|
890
|
-
}
|
|
891
|
-
if (year === endYear && startMonthIndex >= endMonthIndex) {
|
|
892
|
-
return true;
|
|
893
|
-
}
|
|
894
|
-
return false;
|
|
895
|
-
}
|
|
896
|
-
isEndYearDisabled(year) {
|
|
897
|
-
const disabledDateFn = this.zDisabledDate();
|
|
898
|
-
if (disabledDateFn) {
|
|
899
|
-
const yearDate = new Date(year, 0, 1);
|
|
900
|
-
if (disabledDateFn(yearDate)) {
|
|
901
|
-
return true;
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
if (!this.isRangeMode()) {
|
|
905
|
-
return false;
|
|
906
|
-
}
|
|
907
|
-
const startYear = this._currentMonth().getFullYear();
|
|
908
|
-
const startMonthIndex = this._currentMonth().getMonth();
|
|
909
|
-
const endMonthIndex = this._endMonth().getMonth();
|
|
910
|
-
if (year < startYear) {
|
|
911
|
-
return true;
|
|
912
|
-
}
|
|
913
|
-
if (year === startYear && endMonthIndex <= startMonthIndex) {
|
|
914
|
-
return true;
|
|
915
|
-
}
|
|
916
|
-
return false;
|
|
917
|
-
}
|
|
918
1148
|
canNavigateStartNext = computed(() => {
|
|
919
1149
|
if (!this.isRangeMode()) {
|
|
920
1150
|
return true;
|
|
921
1151
|
}
|
|
922
1152
|
const current = this._currentMonth();
|
|
923
1153
|
const end = this._endMonth();
|
|
924
|
-
const view = this.
|
|
1154
|
+
const view = this.currentView();
|
|
925
1155
|
if (view === 'day') {
|
|
926
1156
|
const startNext = addMonths(current, 1);
|
|
927
1157
|
return (startNext.getFullYear() < end.getFullYear() ||
|
|
@@ -944,7 +1174,7 @@ class ZCalendarComponent {
|
|
|
944
1174
|
}
|
|
945
1175
|
const start = this._currentMonth();
|
|
946
1176
|
const end = this._endMonth();
|
|
947
|
-
const view = this.
|
|
1177
|
+
const view = this.endView();
|
|
948
1178
|
if (view === 'day') {
|
|
949
1179
|
const endPrev = addMonths(end, -1);
|
|
950
1180
|
return (endPrev.getFullYear() > start.getFullYear() ||
|
|
@@ -975,7 +1205,7 @@ class ZCalendarComponent {
|
|
|
975
1205
|
timeParts.push('ss');
|
|
976
1206
|
}
|
|
977
1207
|
const timeFormat = timeParts.join(':');
|
|
978
|
-
const periodSuffix = this.zTimeFormat() === '12h' ? ` ${this.
|
|
1208
|
+
const periodSuffix = this.zTimeFormat() === '12h' ? ` ${this.period()}` : '';
|
|
979
1209
|
format = this.isTimeMode() ? timeFormat + periodSuffix : `${this.zFormat()} ${timeFormat}${periodSuffix}`;
|
|
980
1210
|
}
|
|
981
1211
|
if (this.isRangeMode()) {
|
|
@@ -1030,7 +1260,7 @@ class ZCalendarComponent {
|
|
|
1030
1260
|
timeParts.push('ss');
|
|
1031
1261
|
}
|
|
1032
1262
|
const timeFormat = timeParts.join(':');
|
|
1033
|
-
const periodSuffix = this.zTimeFormat() === '12h' ? ` ${this.
|
|
1263
|
+
const periodSuffix = this.zTimeFormat() === '12h' ? ` ${this.period()}` : '';
|
|
1034
1264
|
format = this.isTimeMode() ? timeFormat + periodSuffix : `${this.zFormat()} ${timeFormat}${periodSuffix}`;
|
|
1035
1265
|
}
|
|
1036
1266
|
return format;
|
|
@@ -1132,9 +1362,9 @@ class ZCalendarComponent {
|
|
|
1132
1362
|
effect(() => {
|
|
1133
1363
|
const date = this._selectedDate();
|
|
1134
1364
|
if (date && this.zShowTime()) {
|
|
1135
|
-
this.
|
|
1136
|
-
this.
|
|
1137
|
-
this.
|
|
1365
|
+
this.hour.set(date.getHours());
|
|
1366
|
+
this.minute.set(date.getMinutes());
|
|
1367
|
+
this.second.set(date.getSeconds());
|
|
1138
1368
|
}
|
|
1139
1369
|
});
|
|
1140
1370
|
}
|
|
@@ -1151,14 +1381,13 @@ class ZCalendarComponent {
|
|
|
1151
1381
|
.pipe(takeUntilDestroyed(this._destroyRef))
|
|
1152
1382
|
.subscribe(() => {
|
|
1153
1383
|
this._formStateVersion.update(v => v + 1);
|
|
1154
|
-
this._cdr.markForCheck();
|
|
1155
1384
|
});
|
|
1156
1385
|
}
|
|
1157
1386
|
catch {
|
|
1158
1387
|
this._ngControl = null;
|
|
1159
1388
|
}
|
|
1160
1389
|
});
|
|
1161
|
-
|
|
1390
|
+
this._emitControl();
|
|
1162
1391
|
}
|
|
1163
1392
|
writeValue(value) {
|
|
1164
1393
|
if (value === null || value === undefined) {
|
|
@@ -1177,11 +1406,8 @@ class ZCalendarComponent {
|
|
|
1177
1406
|
this._currentMonth.set(range.start);
|
|
1178
1407
|
this._endMonth.set(isSameMonth(range.start, range.end) ? addMonths(range.end, 1) : range.end);
|
|
1179
1408
|
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
1183
|
-
this._cdr.markForCheck();
|
|
1184
|
-
});
|
|
1409
|
+
this._inputDisplayStart.set(this.displayValueStart());
|
|
1410
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
1185
1411
|
}
|
|
1186
1412
|
return;
|
|
1187
1413
|
}
|
|
@@ -1247,12 +1473,12 @@ class ZCalendarComponent {
|
|
|
1247
1473
|
this._selectedDate.set(null);
|
|
1248
1474
|
this._rangeStart.set(null);
|
|
1249
1475
|
this._rangeEnd.set(null);
|
|
1250
|
-
this.
|
|
1251
|
-
this.
|
|
1252
|
-
this.
|
|
1476
|
+
this.hour.set(0);
|
|
1477
|
+
this.minute.set(0);
|
|
1478
|
+
this.second.set(0);
|
|
1253
1479
|
this._touched.set(false);
|
|
1254
1480
|
this._dirty.set(false);
|
|
1255
|
-
this.
|
|
1481
|
+
this.inputDisplayValue.set('');
|
|
1256
1482
|
const emitValue = this._getEmitValue();
|
|
1257
1483
|
this._onChange(emitValue);
|
|
1258
1484
|
if (this._ngControl?.control) {
|
|
@@ -1285,33 +1511,32 @@ class ZCalendarComponent {
|
|
|
1285
1511
|
onPopoverShow() {
|
|
1286
1512
|
this._backupIfNeeded();
|
|
1287
1513
|
this._appliedViaOk.set(false);
|
|
1288
|
-
this.
|
|
1289
|
-
this.
|
|
1514
|
+
this.hasViewChanged.set(false);
|
|
1515
|
+
this.hasEndViewChanged.set(false);
|
|
1290
1516
|
if (this.isMonthMode()) {
|
|
1291
|
-
this.
|
|
1517
|
+
this.currentView.set('month');
|
|
1292
1518
|
this._initializeTimeIfNeeded();
|
|
1293
1519
|
return;
|
|
1294
1520
|
}
|
|
1295
1521
|
if (this.isYearMode()) {
|
|
1296
|
-
this.
|
|
1522
|
+
this.currentView.set('year');
|
|
1297
1523
|
this._initializeTimeIfNeeded();
|
|
1298
1524
|
return;
|
|
1299
1525
|
}
|
|
1300
1526
|
if (this.isQuarterMode()) {
|
|
1301
|
-
this.
|
|
1527
|
+
this.currentView.set('quarter');
|
|
1302
1528
|
this._initializeTimeIfNeeded();
|
|
1303
1529
|
return;
|
|
1304
1530
|
}
|
|
1305
|
-
this.
|
|
1531
|
+
this.currentView.set('day');
|
|
1306
1532
|
this._initializeTimeIfNeeded();
|
|
1307
1533
|
if (this.isRangeMode()) {
|
|
1308
|
-
this.
|
|
1534
|
+
this.endView.set('day');
|
|
1309
1535
|
this._inputDisplayStart.set(this.displayValueStart());
|
|
1310
1536
|
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
1311
1537
|
}
|
|
1312
|
-
this._scrollToTimeOnOpen();
|
|
1313
1538
|
if (!this.isRangeMode()) {
|
|
1314
|
-
this.
|
|
1539
|
+
this.activePresetKey.set(null);
|
|
1315
1540
|
const selected = this._selectedDate();
|
|
1316
1541
|
if (selected) {
|
|
1317
1542
|
this._currentMonth.set(selected);
|
|
@@ -1325,15 +1550,15 @@ class ZCalendarComponent {
|
|
|
1325
1550
|
if (start && end) {
|
|
1326
1551
|
this._currentMonth.set(start);
|
|
1327
1552
|
this._endMonth.set(isSameMonth(start, end) ? addMonths(end, 1) : end);
|
|
1328
|
-
this.
|
|
1553
|
+
this.activePresetKey.set(this._detectMatchingPreset(start, end));
|
|
1329
1554
|
return;
|
|
1330
1555
|
}
|
|
1331
1556
|
if (this.zQuickSelect()) {
|
|
1332
|
-
this.
|
|
1557
|
+
this.activePresetKey.set(null);
|
|
1333
1558
|
this._resetCalendarsToDefault();
|
|
1334
1559
|
return;
|
|
1335
1560
|
}
|
|
1336
|
-
this.
|
|
1561
|
+
this.activePresetKey.set(null);
|
|
1337
1562
|
this._resetCalendarsToDefault();
|
|
1338
1563
|
}
|
|
1339
1564
|
_initializeTimeIfNeeded() {
|
|
@@ -1362,8 +1587,8 @@ class ZCalendarComponent {
|
|
|
1362
1587
|
const today = getToday();
|
|
1363
1588
|
this._currentMonth.set(today);
|
|
1364
1589
|
this._endMonth.set(addMonths(today, 1));
|
|
1365
|
-
this.
|
|
1366
|
-
this.
|
|
1590
|
+
this.currentView.set('day');
|
|
1591
|
+
this.endView.set('day');
|
|
1367
1592
|
}
|
|
1368
1593
|
_backupIfNeeded() {
|
|
1369
1594
|
this._backupSelectedDate.set(this._selectedDate());
|
|
@@ -1371,7 +1596,7 @@ class ZCalendarComponent {
|
|
|
1371
1596
|
this._backupRangeEnd.set(this._rangeEnd());
|
|
1372
1597
|
}
|
|
1373
1598
|
onPopoverHide() {
|
|
1374
|
-
this.
|
|
1599
|
+
this.hoveredDate.set(null);
|
|
1375
1600
|
const needsConfirmation = this.showOkButton() || this.showCancelButton();
|
|
1376
1601
|
if (needsConfirmation && !this._appliedViaOk()) {
|
|
1377
1602
|
this._restoreFromBackup();
|
|
@@ -1387,7 +1612,7 @@ class ZCalendarComponent {
|
|
|
1387
1612
|
this._touched.set(true);
|
|
1388
1613
|
}
|
|
1389
1614
|
this._onTouched();
|
|
1390
|
-
this.
|
|
1615
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
1391
1616
|
if (this.isRangeMode()) {
|
|
1392
1617
|
this._inputDisplayStart.set(this.displayValueStart());
|
|
1393
1618
|
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
@@ -1416,7 +1641,7 @@ class ZCalendarComponent {
|
|
|
1416
1641
|
if (backup) {
|
|
1417
1642
|
this._syncTimeSignals(backup);
|
|
1418
1643
|
}
|
|
1419
|
-
this.
|
|
1644
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
1420
1645
|
}
|
|
1421
1646
|
onPopoverControl(control) {
|
|
1422
1647
|
this._popoverControl.set(control);
|
|
@@ -1438,7 +1663,7 @@ class ZCalendarComponent {
|
|
|
1438
1663
|
onInputChange(event) {
|
|
1439
1664
|
const input = event.target;
|
|
1440
1665
|
const { value } = input;
|
|
1441
|
-
this.
|
|
1666
|
+
this.inputDisplayValue.set(value);
|
|
1442
1667
|
const trimmedValue = value.trim();
|
|
1443
1668
|
if (!trimmedValue) {
|
|
1444
1669
|
return;
|
|
@@ -1469,7 +1694,6 @@ class ZCalendarComponent {
|
|
|
1469
1694
|
this._selectedDate.set(date);
|
|
1470
1695
|
this._currentMonth.set(date);
|
|
1471
1696
|
this._syncTimeSignals(date);
|
|
1472
|
-
this._scrollToCurrentTime();
|
|
1473
1697
|
}
|
|
1474
1698
|
}
|
|
1475
1699
|
_getExpectedFormatLength(format) {
|
|
@@ -1500,7 +1724,6 @@ class ZCalendarComponent {
|
|
|
1500
1724
|
this._rangeStart.set(date);
|
|
1501
1725
|
this._currentMonth.set(date);
|
|
1502
1726
|
this._syncTimeSignals(date);
|
|
1503
|
-
this._scrollToCurrentTime();
|
|
1504
1727
|
}
|
|
1505
1728
|
onEndInputChange(event) {
|
|
1506
1729
|
const input = event.target;
|
|
@@ -1527,7 +1750,6 @@ class ZCalendarComponent {
|
|
|
1527
1750
|
this._rangeEnd.set(date);
|
|
1528
1751
|
this._endMonth.set(date);
|
|
1529
1752
|
this._syncEndTimeSignals(date);
|
|
1530
|
-
this._scrollToEndTime();
|
|
1531
1753
|
}
|
|
1532
1754
|
onStartInputEnter(event) {
|
|
1533
1755
|
event.preventDefault();
|
|
@@ -1606,7 +1828,7 @@ class ZCalendarComponent {
|
|
|
1606
1828
|
if (!currentValue) {
|
|
1607
1829
|
this._selectedDate.set(null);
|
|
1608
1830
|
this._backupSelectedDate.set(null);
|
|
1609
|
-
this.
|
|
1831
|
+
this.inputDisplayValue.set('');
|
|
1610
1832
|
this._applyValue();
|
|
1611
1833
|
return;
|
|
1612
1834
|
}
|
|
@@ -1616,13 +1838,13 @@ class ZCalendarComponent {
|
|
|
1616
1838
|
this._currentMonth.set(parsed);
|
|
1617
1839
|
this._syncTimeSignals(parsed);
|
|
1618
1840
|
this._backupSelectedDate.set(parsed);
|
|
1619
|
-
this.
|
|
1841
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
1620
1842
|
this._applyValue();
|
|
1621
1843
|
return;
|
|
1622
1844
|
}
|
|
1623
1845
|
const backup = this._backupSelectedDate();
|
|
1624
1846
|
this._selectedDate.set(backup);
|
|
1625
|
-
this.
|
|
1847
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
1626
1848
|
}
|
|
1627
1849
|
onInputEnter(event) {
|
|
1628
1850
|
event.preventDefault();
|
|
@@ -1692,7 +1914,7 @@ class ZCalendarComponent {
|
|
|
1692
1914
|
this._cancelAndRestore();
|
|
1693
1915
|
return;
|
|
1694
1916
|
}
|
|
1695
|
-
if (this.
|
|
1917
|
+
if (this.currentView() !== 'day') {
|
|
1696
1918
|
return;
|
|
1697
1919
|
}
|
|
1698
1920
|
if (key === 'Enter') {
|
|
@@ -1722,12 +1944,12 @@ class ZCalendarComponent {
|
|
|
1722
1944
|
}
|
|
1723
1945
|
onDayHover(day) {
|
|
1724
1946
|
if (this.isRangeMode() && this._rangeStart() && !this._rangeEnd()) {
|
|
1725
|
-
this.
|
|
1947
|
+
this.hoveredDate.set(day.date);
|
|
1726
1948
|
}
|
|
1727
1949
|
}
|
|
1728
1950
|
onDayLeave() {
|
|
1729
1951
|
if (this.isRangeMode()) {
|
|
1730
|
-
this.
|
|
1952
|
+
this.hoveredDate.set(null);
|
|
1731
1953
|
}
|
|
1732
1954
|
}
|
|
1733
1955
|
onMonthClick(monthIndex) {
|
|
@@ -1742,15 +1964,15 @@ class ZCalendarComponent {
|
|
|
1742
1964
|
}
|
|
1743
1965
|
}
|
|
1744
1966
|
this._currentMonth.set(newMonth);
|
|
1745
|
-
this.
|
|
1746
|
-
this.
|
|
1967
|
+
this.hasViewChanged.set(true);
|
|
1968
|
+
this.currentView.set('day');
|
|
1747
1969
|
}
|
|
1748
1970
|
onYearClick(year) {
|
|
1749
1971
|
const currentDate = this._currentMonth();
|
|
1750
1972
|
if (this.isYearMode()) {
|
|
1751
1973
|
this._selectedDate.set(setYear(new Date(year, 0, 1), year));
|
|
1752
1974
|
this._dirty.set(true);
|
|
1753
|
-
this.
|
|
1975
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
1754
1976
|
this._applyValue();
|
|
1755
1977
|
this.close();
|
|
1756
1978
|
return;
|
|
@@ -1763,8 +1985,8 @@ class ZCalendarComponent {
|
|
|
1763
1985
|
}
|
|
1764
1986
|
}
|
|
1765
1987
|
this._currentMonth.set(setYear(currentDate, newYear));
|
|
1766
|
-
this.
|
|
1767
|
-
this.
|
|
1988
|
+
this.hasViewChanged.set(true);
|
|
1989
|
+
this.currentView.set(this.isQuarterMode() ? 'quarter' : 'month');
|
|
1768
1990
|
}
|
|
1769
1991
|
onQuarterClick(quarterIndex) {
|
|
1770
1992
|
const currentYear = this._currentMonth().getFullYear();
|
|
@@ -1772,7 +1994,7 @@ class ZCalendarComponent {
|
|
|
1772
1994
|
const date = new Date(currentYear, firstMonthOfQuarter, 1);
|
|
1773
1995
|
this._selectedDate.set(date);
|
|
1774
1996
|
this._dirty.set(true);
|
|
1775
|
-
this.
|
|
1997
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
1776
1998
|
this._applyValue();
|
|
1777
1999
|
this.close();
|
|
1778
2000
|
}
|
|
@@ -1781,7 +2003,7 @@ class ZCalendarComponent {
|
|
|
1781
2003
|
const currentYear = this._currentMonth().getFullYear();
|
|
1782
2004
|
this._selectedDate.set(new Date(currentYear, monthIndex, 1));
|
|
1783
2005
|
this._dirty.set(true);
|
|
1784
|
-
this.
|
|
2006
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
1785
2007
|
this._applyValue();
|
|
1786
2008
|
this.close();
|
|
1787
2009
|
return;
|
|
@@ -1789,7 +2011,7 @@ class ZCalendarComponent {
|
|
|
1789
2011
|
this.onMonthClick(monthIndex);
|
|
1790
2012
|
}
|
|
1791
2013
|
onQuickSelect(preset) {
|
|
1792
|
-
this.
|
|
2014
|
+
this.activePresetKey.set(preset.key);
|
|
1793
2015
|
if (preset.key === 'custom') {
|
|
1794
2016
|
this._rangeStart.set(null);
|
|
1795
2017
|
this._rangeEnd.set(null);
|
|
@@ -1834,16 +2056,15 @@ class ZCalendarComponent {
|
|
|
1834
2056
|
const today = getToday();
|
|
1835
2057
|
this._currentMonth.set(today);
|
|
1836
2058
|
if (this.zShowTime() || this.isTimeMode()) {
|
|
1837
|
-
this.
|
|
1838
|
-
this.
|
|
1839
|
-
this.
|
|
1840
|
-
this.
|
|
1841
|
-
this._scrollToCurrentTime();
|
|
2059
|
+
this.hour.set(now.getHours());
|
|
2060
|
+
this.minute.set(now.getMinutes());
|
|
2061
|
+
this.second.set(now.getSeconds());
|
|
2062
|
+
this.period.set(now.getHours() >= 12 ? 'PM' : 'AM');
|
|
1842
2063
|
}
|
|
1843
2064
|
if (this.isMonthMode()) {
|
|
1844
2065
|
this._selectedDate.set(new Date(now.getFullYear(), now.getMonth(), 1));
|
|
1845
2066
|
this._dirty.set(true);
|
|
1846
|
-
this.
|
|
2067
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
1847
2068
|
this._applyValue();
|
|
1848
2069
|
this.close();
|
|
1849
2070
|
return;
|
|
@@ -1851,7 +2072,7 @@ class ZCalendarComponent {
|
|
|
1851
2072
|
if (this.isYearMode()) {
|
|
1852
2073
|
this._selectedDate.set(new Date(now.getFullYear(), 0, 1));
|
|
1853
2074
|
this._dirty.set(true);
|
|
1854
|
-
this.
|
|
2075
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
1855
2076
|
this._applyValue();
|
|
1856
2077
|
this.close();
|
|
1857
2078
|
return;
|
|
@@ -1860,7 +2081,7 @@ class ZCalendarComponent {
|
|
|
1860
2081
|
const currentQuarter = Math.floor(now.getMonth() / 3);
|
|
1861
2082
|
this._selectedDate.set(new Date(now.getFullYear(), currentQuarter * 3, 1));
|
|
1862
2083
|
this._dirty.set(true);
|
|
1863
|
-
this.
|
|
2084
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
1864
2085
|
this._applyValue();
|
|
1865
2086
|
this.close();
|
|
1866
2087
|
return;
|
|
@@ -1868,7 +2089,7 @@ class ZCalendarComponent {
|
|
|
1868
2089
|
if (this.isTimeMode()) {
|
|
1869
2090
|
this._selectedDate.set(now);
|
|
1870
2091
|
this._dirty.set(true);
|
|
1871
|
-
this.
|
|
2092
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
1872
2093
|
if (!this.showOkButton()) {
|
|
1873
2094
|
this._applyValue();
|
|
1874
2095
|
this.close();
|
|
@@ -1895,7 +2116,7 @@ class ZCalendarComponent {
|
|
|
1895
2116
|
const selectedDate = this.zShowTime() ? now : today;
|
|
1896
2117
|
this._selectedDate.set(selectedDate);
|
|
1897
2118
|
this._dirty.set(true);
|
|
1898
|
-
this.
|
|
2119
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
1899
2120
|
if (!this.showOkButton()) {
|
|
1900
2121
|
this._applyValue();
|
|
1901
2122
|
this.close();
|
|
@@ -1907,9 +2128,9 @@ class ZCalendarComponent {
|
|
|
1907
2128
|
this._selectedDate.set(null);
|
|
1908
2129
|
this._rangeStart.set(null);
|
|
1909
2130
|
this._rangeEnd.set(null);
|
|
1910
|
-
this.
|
|
1911
|
-
this.
|
|
1912
|
-
this.
|
|
2131
|
+
this.hour.set(0);
|
|
2132
|
+
this.minute.set(0);
|
|
2133
|
+
this.second.set(0);
|
|
1913
2134
|
this._dirty.set(true);
|
|
1914
2135
|
this._backupSelectedDate.set(null);
|
|
1915
2136
|
this._backupRangeStart.set(null);
|
|
@@ -1918,7 +2139,7 @@ class ZCalendarComponent {
|
|
|
1918
2139
|
const emitValue = this._getEmitValue();
|
|
1919
2140
|
this._onChange(emitValue);
|
|
1920
2141
|
this.zChange.emit(emitValue);
|
|
1921
|
-
this.
|
|
2142
|
+
this.inputDisplayValue.set('');
|
|
1922
2143
|
if (this.isRangeMode()) {
|
|
1923
2144
|
this._inputDisplayStart.set('');
|
|
1924
2145
|
this._inputDisplayEnd.set('');
|
|
@@ -1933,24 +2154,24 @@ class ZCalendarComponent {
|
|
|
1933
2154
|
return;
|
|
1934
2155
|
}
|
|
1935
2156
|
if (this.isTimeMode()) {
|
|
1936
|
-
let hour = this.
|
|
2157
|
+
let hour = this.hour();
|
|
1937
2158
|
if (this.zTimeFormat() === '12h') {
|
|
1938
|
-
if (this.
|
|
2159
|
+
if (this.period() === 'PM' && hour < 12) {
|
|
1939
2160
|
hour += 12;
|
|
1940
2161
|
}
|
|
1941
|
-
if (this.
|
|
2162
|
+
if (this.period() === 'AM' && hour === 12) {
|
|
1942
2163
|
hour = 0;
|
|
1943
2164
|
}
|
|
1944
2165
|
}
|
|
1945
2166
|
const baseDate = this._selectedDate() ?? new Date();
|
|
1946
|
-
this._selectedDate.set(setTime(baseDate, hour, this.
|
|
2167
|
+
this._selectedDate.set(setTime(baseDate, hour, this.minute(), this.second()));
|
|
1947
2168
|
}
|
|
1948
2169
|
this._appliedViaOk.set(true);
|
|
1949
2170
|
this._applyValue();
|
|
1950
2171
|
this.close();
|
|
1951
2172
|
}
|
|
1952
2173
|
navigatePrevious() {
|
|
1953
|
-
const view = this.
|
|
2174
|
+
const view = this.currentView();
|
|
1954
2175
|
const current = this._currentMonth();
|
|
1955
2176
|
const yearStep = this.isYearMode() || this.isQuarterMode() ? 9 : 12;
|
|
1956
2177
|
const navigationMap = {
|
|
@@ -1962,7 +2183,7 @@ class ZCalendarComponent {
|
|
|
1962
2183
|
this._currentMonth.set(navigationMap[view]);
|
|
1963
2184
|
}
|
|
1964
2185
|
navigateNext() {
|
|
1965
|
-
const view = this.
|
|
2186
|
+
const view = this.currentView();
|
|
1966
2187
|
const current = this._currentMonth();
|
|
1967
2188
|
const yearStep = this.isYearMode() || this.isQuarterMode() ? 9 : 12;
|
|
1968
2189
|
const navigationMap = {
|
|
@@ -1982,12 +2203,12 @@ class ZCalendarComponent {
|
|
|
1982
2203
|
this._currentMonth.set(addYears(current, 1));
|
|
1983
2204
|
}
|
|
1984
2205
|
setView(view) {
|
|
1985
|
-
this.
|
|
1986
|
-
this.
|
|
2206
|
+
this.hasViewChanged.set(true);
|
|
2207
|
+
this.currentView.set(view);
|
|
1987
2208
|
}
|
|
1988
2209
|
setEndView(view) {
|
|
1989
|
-
this.
|
|
1990
|
-
this.
|
|
2210
|
+
this.hasEndViewChanged.set(true);
|
|
2211
|
+
this.endView.set(view);
|
|
1991
2212
|
}
|
|
1992
2213
|
onEndMonthClick(monthIndex) {
|
|
1993
2214
|
const currentDate = this._endMonth();
|
|
@@ -1999,8 +2220,8 @@ class ZCalendarComponent {
|
|
|
1999
2220
|
newMonth = addMonths(startMonth, 1);
|
|
2000
2221
|
}
|
|
2001
2222
|
this._endMonth.set(newMonth);
|
|
2002
|
-
this.
|
|
2003
|
-
this.
|
|
2223
|
+
this.hasEndViewChanged.set(true);
|
|
2224
|
+
this.endView.set('day');
|
|
2004
2225
|
}
|
|
2005
2226
|
onEndYearClick(year) {
|
|
2006
2227
|
const currentDate = this._endMonth();
|
|
@@ -2010,8 +2231,8 @@ class ZCalendarComponent {
|
|
|
2010
2231
|
newYear = startYear + 1;
|
|
2011
2232
|
}
|
|
2012
2233
|
this._endMonth.set(setYear(currentDate, newYear));
|
|
2013
|
-
this.
|
|
2014
|
-
this.
|
|
2234
|
+
this.hasEndViewChanged.set(true);
|
|
2235
|
+
this.endView.set('month');
|
|
2015
2236
|
}
|
|
2016
2237
|
onHourInput(event) {
|
|
2017
2238
|
const input = event.target;
|
|
@@ -2020,7 +2241,7 @@ class ZCalendarComponent {
|
|
|
2020
2241
|
return;
|
|
2021
2242
|
}
|
|
2022
2243
|
const value = parseTimeValue(digits, 23);
|
|
2023
|
-
this.
|
|
2244
|
+
this.hour.set(value);
|
|
2024
2245
|
this._updateTimeToDate();
|
|
2025
2246
|
this._updateInputDisplayAfterTimeChange();
|
|
2026
2247
|
}
|
|
@@ -2031,7 +2252,7 @@ class ZCalendarComponent {
|
|
|
2031
2252
|
return;
|
|
2032
2253
|
}
|
|
2033
2254
|
const value = parseTimeValue(digits, 59);
|
|
2034
|
-
this.
|
|
2255
|
+
this.minute.set(value);
|
|
2035
2256
|
this._updateTimeToDate();
|
|
2036
2257
|
this._updateInputDisplayAfterTimeChange();
|
|
2037
2258
|
}
|
|
@@ -2042,7 +2263,7 @@ class ZCalendarComponent {
|
|
|
2042
2263
|
return;
|
|
2043
2264
|
}
|
|
2044
2265
|
const value = parseTimeValue(digits, 59);
|
|
2045
|
-
this.
|
|
2266
|
+
this.second.set(value);
|
|
2046
2267
|
this._updateTimeToDate();
|
|
2047
2268
|
this._updateInputDisplayAfterTimeChange();
|
|
2048
2269
|
}
|
|
@@ -2053,19 +2274,19 @@ class ZCalendarComponent {
|
|
|
2053
2274
|
if (digits.length > 0 && digits.length <= 2) {
|
|
2054
2275
|
if (dataType === 'hour') {
|
|
2055
2276
|
const value = parseTimeValue(digits, this.zTimeFormat() === '12h' ? 12 : 23);
|
|
2056
|
-
this.
|
|
2277
|
+
this.hour.set(value);
|
|
2057
2278
|
this._updateTimeToDate();
|
|
2058
2279
|
this._updateInputDisplayAfterTimeChange();
|
|
2059
2280
|
}
|
|
2060
2281
|
if (dataType === 'minute') {
|
|
2061
2282
|
const value = parseTimeValue(digits, 59);
|
|
2062
|
-
this.
|
|
2283
|
+
this.minute.set(value);
|
|
2063
2284
|
this._updateTimeToDate();
|
|
2064
2285
|
this._updateInputDisplayAfterTimeChange();
|
|
2065
2286
|
}
|
|
2066
2287
|
if (dataType === 'second') {
|
|
2067
2288
|
const value = parseTimeValue(digits, 59);
|
|
2068
|
-
this.
|
|
2289
|
+
this.second.set(value);
|
|
2069
2290
|
this._updateTimeToDate();
|
|
2070
2291
|
this._updateInputDisplayAfterTimeChange();
|
|
2071
2292
|
}
|
|
@@ -2198,11 +2419,11 @@ class ZCalendarComponent {
|
|
|
2198
2419
|
_handleSingleSelection(date) {
|
|
2199
2420
|
let finalDate = date;
|
|
2200
2421
|
if (this.zShowTime()) {
|
|
2201
|
-
finalDate = setTime(date, this.
|
|
2422
|
+
finalDate = setTime(date, this.hour(), this.minute(), this.second());
|
|
2202
2423
|
}
|
|
2203
2424
|
this._selectedDate.set(finalDate);
|
|
2204
2425
|
this._dirty.set(true);
|
|
2205
|
-
this.
|
|
2426
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
2206
2427
|
if (!this.zShowTime() && !this.zShowOk()) {
|
|
2207
2428
|
this._applyValue();
|
|
2208
2429
|
this.close();
|
|
@@ -2214,20 +2435,20 @@ class ZCalendarComponent {
|
|
|
2214
2435
|
if (!start || (start && end)) {
|
|
2215
2436
|
let startDate = date;
|
|
2216
2437
|
if (this.zShowTime()) {
|
|
2217
|
-
let hour = this.
|
|
2438
|
+
let hour = this.hour();
|
|
2218
2439
|
if (this.zTimeFormat() === '12h') {
|
|
2219
|
-
if (this.
|
|
2440
|
+
if (this.period() === 'PM' && hour < 12) {
|
|
2220
2441
|
hour += 12;
|
|
2221
2442
|
}
|
|
2222
|
-
if (this.
|
|
2443
|
+
if (this.period() === 'AM' && hour === 12) {
|
|
2223
2444
|
hour = 0;
|
|
2224
2445
|
}
|
|
2225
2446
|
}
|
|
2226
|
-
startDate = setTime(date, hour, this.
|
|
2447
|
+
startDate = setTime(date, hour, this.minute(), this.second());
|
|
2227
2448
|
}
|
|
2228
2449
|
this._rangeStart.set(startDate);
|
|
2229
2450
|
this._rangeEnd.set(null);
|
|
2230
|
-
this.
|
|
2451
|
+
this.activePresetKey.set('custom');
|
|
2231
2452
|
this._inputDisplayStart.set(this.displayValueStart());
|
|
2232
2453
|
this._inputDisplayEnd.set('');
|
|
2233
2454
|
return;
|
|
@@ -2252,7 +2473,7 @@ class ZCalendarComponent {
|
|
|
2252
2473
|
this._inputDisplayStart.set(this.displayValueStart());
|
|
2253
2474
|
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2254
2475
|
if (normalized.start && normalized.end) {
|
|
2255
|
-
this.
|
|
2476
|
+
this.activePresetKey.set(this._detectMatchingPreset(normalized.start, normalized.end));
|
|
2256
2477
|
}
|
|
2257
2478
|
if (!this.showOkButton() && !this.showCancelButton()) {
|
|
2258
2479
|
this._applyValue();
|
|
@@ -2260,29 +2481,29 @@ class ZCalendarComponent {
|
|
|
2260
2481
|
}
|
|
2261
2482
|
}
|
|
2262
2483
|
_updateTimeToDate() {
|
|
2263
|
-
if (!this.zShowTime()) {
|
|
2484
|
+
if (!this.zShowTime() && !this.isTimeMode()) {
|
|
2264
2485
|
return;
|
|
2265
2486
|
}
|
|
2266
|
-
let hour = this.
|
|
2487
|
+
let hour = this.hour();
|
|
2267
2488
|
if (this.zTimeFormat() === '12h') {
|
|
2268
|
-
if (this.
|
|
2489
|
+
if (this.period() === 'PM' && hour < 12) {
|
|
2269
2490
|
hour += 12;
|
|
2270
2491
|
}
|
|
2271
|
-
if (this.
|
|
2492
|
+
if (this.period() === 'AM' && hour === 12) {
|
|
2272
2493
|
hour = 0;
|
|
2273
2494
|
}
|
|
2274
2495
|
}
|
|
2275
2496
|
if (this.isRangeMode()) {
|
|
2276
2497
|
const start = this._rangeStart();
|
|
2277
2498
|
if (start) {
|
|
2278
|
-
this._rangeStart.set(setTime(start, hour, this.
|
|
2499
|
+
this._rangeStart.set(setTime(start, hour, this.minute(), this.second()));
|
|
2279
2500
|
this._dirty.set(true);
|
|
2280
2501
|
}
|
|
2281
2502
|
return;
|
|
2282
2503
|
}
|
|
2283
2504
|
const selected = this._selectedDate();
|
|
2284
2505
|
if (selected) {
|
|
2285
|
-
this._selectedDate.set(setTime(selected, hour, this.
|
|
2506
|
+
this._selectedDate.set(setTime(selected, hour, this.minute(), this.second()));
|
|
2286
2507
|
}
|
|
2287
2508
|
}
|
|
2288
2509
|
_detectMatchingPreset(start, end) {
|
|
@@ -2304,7 +2525,7 @@ class ZCalendarComponent {
|
|
|
2304
2525
|
this._onChange(emitValue);
|
|
2305
2526
|
this.zChange.emit(emitValue);
|
|
2306
2527
|
this._dirty.set(true);
|
|
2307
|
-
this.
|
|
2528
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
2308
2529
|
if (this.isRangeMode()) {
|
|
2309
2530
|
this._inputDisplayStart.set(this.displayValueStart());
|
|
2310
2531
|
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
@@ -2393,10 +2614,10 @@ class ZCalendarComponent {
|
|
|
2393
2614
|
}
|
|
2394
2615
|
}
|
|
2395
2616
|
_syncTimeSignals(date) {
|
|
2396
|
-
this.
|
|
2397
|
-
this.
|
|
2398
|
-
this.
|
|
2399
|
-
this.
|
|
2617
|
+
this.hour.set(date.getHours());
|
|
2618
|
+
this.minute.set(date.getMinutes());
|
|
2619
|
+
this.second.set(date.getSeconds());
|
|
2620
|
+
this.period.set(date.getHours() >= 12 ? 'PM' : 'AM');
|
|
2400
2621
|
}
|
|
2401
2622
|
_getParseFormat() {
|
|
2402
2623
|
if (!this.zShowTime() && !this.isTimeMode()) {
|
|
@@ -2419,7 +2640,7 @@ class ZCalendarComponent {
|
|
|
2419
2640
|
return `${this.zFormat()} ${timeFormat}`;
|
|
2420
2641
|
}
|
|
2421
2642
|
_updateInputDisplay() {
|
|
2422
|
-
this.
|
|
2643
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
2423
2644
|
}
|
|
2424
2645
|
_clearDateValues() {
|
|
2425
2646
|
if (this.isRangeMode()) {
|
|
@@ -2449,7 +2670,7 @@ class ZCalendarComponent {
|
|
|
2449
2670
|
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2450
2671
|
return;
|
|
2451
2672
|
}
|
|
2452
|
-
this.
|
|
2673
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
2453
2674
|
}
|
|
2454
2675
|
_emitControl() {
|
|
2455
2676
|
this.zControl.emit({
|
|
@@ -2471,65 +2692,170 @@ class ZCalendarComponent {
|
|
|
2471
2692
|
});
|
|
2472
2693
|
}
|
|
2473
2694
|
togglePeriod() {
|
|
2474
|
-
const currentPeriod = this.
|
|
2695
|
+
const currentPeriod = this.period();
|
|
2475
2696
|
const newPeriod = currentPeriod === 'AM' ? 'PM' : 'AM';
|
|
2476
|
-
this.
|
|
2477
|
-
const currentHour = this.
|
|
2697
|
+
this.period.set(newPeriod);
|
|
2698
|
+
const currentHour = this.hour();
|
|
2478
2699
|
if (newPeriod === 'PM' && currentHour < 12) {
|
|
2479
|
-
this.
|
|
2700
|
+
this.hour.set(currentHour + 12);
|
|
2480
2701
|
}
|
|
2481
2702
|
if (newPeriod === 'AM' && currentHour >= 12) {
|
|
2482
|
-
this.
|
|
2703
|
+
this.hour.set(currentHour - 12);
|
|
2483
2704
|
}
|
|
2484
2705
|
this._updateTimeToDate();
|
|
2485
2706
|
this._updateInputDisplayAfterTimeChange();
|
|
2486
2707
|
}
|
|
2708
|
+
incrementHour() {
|
|
2709
|
+
const maxHour = this.zTimeFormat() === '12h' ? 12 : 23;
|
|
2710
|
+
const minHour = this.zTimeFormat() === '12h' ? 1 : 0;
|
|
2711
|
+
let currentHour = this.displayHour();
|
|
2712
|
+
currentHour = currentHour >= maxHour ? minHour : currentHour + 1;
|
|
2713
|
+
this.selectHour(currentHour);
|
|
2714
|
+
}
|
|
2715
|
+
decrementHour() {
|
|
2716
|
+
const maxHour = this.zTimeFormat() === '12h' ? 12 : 23;
|
|
2717
|
+
const minHour = this.zTimeFormat() === '12h' ? 1 : 0;
|
|
2718
|
+
let currentHour = this.displayHour();
|
|
2719
|
+
currentHour = currentHour <= minHour ? maxHour : currentHour - 1;
|
|
2720
|
+
this.selectHour(currentHour);
|
|
2721
|
+
}
|
|
2722
|
+
incrementMinute() {
|
|
2723
|
+
let currentMinute = this.minute();
|
|
2724
|
+
currentMinute = currentMinute >= 59 ? 0 : currentMinute + 1;
|
|
2725
|
+
this.selectMinute(currentMinute);
|
|
2726
|
+
}
|
|
2727
|
+
decrementMinute() {
|
|
2728
|
+
let currentMinute = this.minute();
|
|
2729
|
+
currentMinute = currentMinute <= 0 ? 59 : currentMinute - 1;
|
|
2730
|
+
this.selectMinute(currentMinute);
|
|
2731
|
+
}
|
|
2732
|
+
incrementSecond() {
|
|
2733
|
+
let currentSecond = this.second();
|
|
2734
|
+
currentSecond = currentSecond >= 59 ? 0 : currentSecond + 1;
|
|
2735
|
+
this.selectSecond(currentSecond);
|
|
2736
|
+
}
|
|
2737
|
+
decrementSecond() {
|
|
2738
|
+
let currentSecond = this.second();
|
|
2739
|
+
currentSecond = currentSecond <= 0 ? 59 : currentSecond - 1;
|
|
2740
|
+
this.selectSecond(currentSecond);
|
|
2741
|
+
}
|
|
2742
|
+
incrementHourEnd() {
|
|
2743
|
+
const maxHour = this.zTimeFormat() === '12h' ? 12 : 23;
|
|
2744
|
+
const minHour = this.zTimeFormat() === '12h' ? 1 : 0;
|
|
2745
|
+
let currentHour = this.displayHourEnd();
|
|
2746
|
+
currentHour = currentHour >= maxHour ? minHour : currentHour + 1;
|
|
2747
|
+
this.selectHourEnd(currentHour);
|
|
2748
|
+
}
|
|
2749
|
+
decrementHourEnd() {
|
|
2750
|
+
const maxHour = this.zTimeFormat() === '12h' ? 12 : 23;
|
|
2751
|
+
const minHour = this.zTimeFormat() === '12h' ? 1 : 0;
|
|
2752
|
+
let currentHour = this.displayHourEnd();
|
|
2753
|
+
currentHour = currentHour <= minHour ? maxHour : currentHour - 1;
|
|
2754
|
+
this.selectHourEnd(currentHour);
|
|
2755
|
+
}
|
|
2756
|
+
incrementMinuteEnd() {
|
|
2757
|
+
let currentMinute = this._minuteEnd();
|
|
2758
|
+
currentMinute = currentMinute >= 59 ? 0 : currentMinute + 1;
|
|
2759
|
+
this.selectMinuteEnd(currentMinute);
|
|
2760
|
+
}
|
|
2761
|
+
decrementMinuteEnd() {
|
|
2762
|
+
let currentMinute = this._minuteEnd();
|
|
2763
|
+
currentMinute = currentMinute <= 0 ? 59 : currentMinute - 1;
|
|
2764
|
+
this.selectMinuteEnd(currentMinute);
|
|
2765
|
+
}
|
|
2766
|
+
incrementSecondEnd() {
|
|
2767
|
+
let currentSecond = this._secondEnd();
|
|
2768
|
+
currentSecond = currentSecond >= 59 ? 0 : currentSecond + 1;
|
|
2769
|
+
this.selectSecondEnd(currentSecond);
|
|
2770
|
+
}
|
|
2771
|
+
decrementSecondEnd() {
|
|
2772
|
+
let currentSecond = this._secondEnd();
|
|
2773
|
+
currentSecond = currentSecond <= 0 ? 59 : currentSecond - 1;
|
|
2774
|
+
this.selectSecondEnd(currentSecond);
|
|
2775
|
+
}
|
|
2776
|
+
openTimeDropdown(event) {
|
|
2777
|
+
event.stopPropagation();
|
|
2778
|
+
this.timeDropdownOpen.set(true);
|
|
2779
|
+
}
|
|
2780
|
+
closeTimeDropdown() {
|
|
2781
|
+
this.timeDropdownOpen.set(false);
|
|
2782
|
+
}
|
|
2783
|
+
openTimeDropdownEnd(event) {
|
|
2784
|
+
event.stopPropagation();
|
|
2785
|
+
this.timeDropdownEndOpen.set(true);
|
|
2786
|
+
}
|
|
2787
|
+
closeTimeDropdownEnd() {
|
|
2788
|
+
this.timeDropdownEndOpen.set(false);
|
|
2789
|
+
}
|
|
2790
|
+
onTimeDropdownShow() {
|
|
2791
|
+
this._scrollToTimeDropdown();
|
|
2792
|
+
}
|
|
2793
|
+
onTimeDropdownEndShow() {
|
|
2794
|
+
this._scrollToTimeDropdown(true);
|
|
2795
|
+
}
|
|
2796
|
+
_scrollToTimeDropdown(isEnd = false) {
|
|
2797
|
+
setTimeout(() => {
|
|
2798
|
+
const suffix = isEnd ? '-end' : '';
|
|
2799
|
+
if (this.zShowHour()) {
|
|
2800
|
+
this._scrollToTimeValue(`.z-time-scroll-hour${suffix}`);
|
|
2801
|
+
}
|
|
2802
|
+
if (this.zShowMinute()) {
|
|
2803
|
+
this._scrollToTimeValue(`.z-time-scroll-minute${suffix}`);
|
|
2804
|
+
}
|
|
2805
|
+
if (this.zShowSecond()) {
|
|
2806
|
+
this._scrollToTimeValue(`.z-time-scroll-second${suffix}`);
|
|
2807
|
+
}
|
|
2808
|
+
});
|
|
2809
|
+
}
|
|
2487
2810
|
_updateInputDisplayAfterTimeChange() {
|
|
2488
2811
|
if (this.isRangeMode()) {
|
|
2489
2812
|
this._inputDisplayStart.set(this.displayValueStart());
|
|
2490
2813
|
return;
|
|
2491
2814
|
}
|
|
2492
|
-
this.
|
|
2815
|
+
this.inputDisplayValue.set(this.displayValue());
|
|
2493
2816
|
}
|
|
2494
2817
|
onPeriodChange(event) {
|
|
2495
2818
|
const select = event.target;
|
|
2496
2819
|
const newPeriod = select.value;
|
|
2497
|
-
const currentHour = this.
|
|
2498
|
-
this.
|
|
2820
|
+
const currentHour = this.hour();
|
|
2821
|
+
this.period.set(newPeriod);
|
|
2499
2822
|
if (newPeriod === 'PM' && currentHour < 12) {
|
|
2500
|
-
this.
|
|
2823
|
+
this.hour.set(currentHour + 12);
|
|
2501
2824
|
}
|
|
2502
2825
|
if (newPeriod === 'AM' && currentHour >= 12) {
|
|
2503
|
-
this.
|
|
2826
|
+
this.hour.set(currentHour - 12);
|
|
2504
2827
|
}
|
|
2505
2828
|
this._updateTimeToDate();
|
|
2506
2829
|
}
|
|
2507
2830
|
selectHour(hour) {
|
|
2508
2831
|
let actualHour = hour;
|
|
2509
2832
|
if (this.zTimeFormat() === '12h') {
|
|
2510
|
-
if (this.
|
|
2833
|
+
if (this.period() === 'PM' && hour !== 12) {
|
|
2511
2834
|
actualHour = hour + 12;
|
|
2512
2835
|
}
|
|
2513
|
-
if (this.
|
|
2836
|
+
if (this.period() === 'AM' && hour === 12) {
|
|
2514
2837
|
actualHour = 0;
|
|
2515
2838
|
}
|
|
2516
2839
|
}
|
|
2517
|
-
this.
|
|
2840
|
+
this.hour.set(actualHour);
|
|
2518
2841
|
this._updateTimeToDate();
|
|
2519
2842
|
this._updateInputDisplayAfterTimeChange();
|
|
2843
|
+
this._scrollToTimeValue('.z-time-scroll-hour');
|
|
2520
2844
|
}
|
|
2521
2845
|
selectMinute(minute) {
|
|
2522
|
-
this.
|
|
2846
|
+
this.minute.set(minute);
|
|
2523
2847
|
this._updateTimeToDate();
|
|
2524
2848
|
this._updateInputDisplayAfterTimeChange();
|
|
2849
|
+
this._scrollToTimeValue('.z-time-scroll-minute');
|
|
2525
2850
|
}
|
|
2526
2851
|
selectSecond(second) {
|
|
2527
|
-
this.
|
|
2852
|
+
this.second.set(second);
|
|
2528
2853
|
this._updateTimeToDate();
|
|
2529
2854
|
this._updateInputDisplayAfterTimeChange();
|
|
2855
|
+
this._scrollToTimeValue('.z-time-scroll-second');
|
|
2530
2856
|
}
|
|
2531
2857
|
selectPeriod(period) {
|
|
2532
|
-
if (this.
|
|
2858
|
+
if (this.period() === period) {
|
|
2533
2859
|
return;
|
|
2534
2860
|
}
|
|
2535
2861
|
this.togglePeriod();
|
|
@@ -2547,16 +2873,19 @@ class ZCalendarComponent {
|
|
|
2547
2873
|
this._hourEnd.set(actualHour);
|
|
2548
2874
|
this._updateEndTimeToDate();
|
|
2549
2875
|
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2876
|
+
this._scrollToTimeValue('.z-time-scroll-hour-end');
|
|
2550
2877
|
}
|
|
2551
2878
|
selectMinuteEnd(minute) {
|
|
2552
2879
|
this._minuteEnd.set(minute);
|
|
2553
2880
|
this._updateEndTimeToDate();
|
|
2554
2881
|
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2882
|
+
this._scrollToTimeValue('.z-time-scroll-minute-end');
|
|
2555
2883
|
}
|
|
2556
2884
|
selectSecondEnd(second) {
|
|
2557
2885
|
this._secondEnd.set(second);
|
|
2558
2886
|
this._updateEndTimeToDate();
|
|
2559
2887
|
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2888
|
+
this._scrollToTimeValue('.z-time-scroll-second-end');
|
|
2560
2889
|
}
|
|
2561
2890
|
selectPeriodEnd(period) {
|
|
2562
2891
|
if (this._periodEnd() === period) {
|
|
@@ -2571,268 +2900,15 @@ class ZCalendarComponent {
|
|
|
2571
2900
|
const scrollTop = value * itemHeight;
|
|
2572
2901
|
container.scrollTo({ top: scrollTop, behavior: 'smooth' });
|
|
2573
2902
|
}
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
isMinuteSelected(minute) {
|
|
2578
|
-
return this._minute() === minute;
|
|
2579
|
-
}
|
|
2580
|
-
isSecondSelected(second) {
|
|
2581
|
-
return this._second() === second;
|
|
2582
|
-
}
|
|
2583
|
-
isHourEndSelected(hour) {
|
|
2584
|
-
return this.displayHourEnd() === hour;
|
|
2585
|
-
}
|
|
2586
|
-
isMinuteEndSelected(minute) {
|
|
2587
|
-
return this._minuteEnd() === minute;
|
|
2588
|
-
}
|
|
2589
|
-
isSecondEndSelected(second) {
|
|
2590
|
-
return this._secondEnd() === second;
|
|
2591
|
-
}
|
|
2592
|
-
isEndHourDisabled(hour) {
|
|
2593
|
-
if (!this.isSameDayRange()) {
|
|
2594
|
-
return false;
|
|
2595
|
-
}
|
|
2596
|
-
const startHour = this._hour();
|
|
2597
|
-
let actualHour = hour;
|
|
2598
|
-
let actualStartHour = startHour;
|
|
2599
|
-
if (this.zTimeFormat() === '12h') {
|
|
2600
|
-
if (this._periodEnd() === 'PM' && hour !== 12) {
|
|
2601
|
-
actualHour = hour + 12;
|
|
2602
|
-
}
|
|
2603
|
-
if (this._periodEnd() === 'AM' && hour === 12) {
|
|
2604
|
-
actualHour = 0;
|
|
2605
|
-
}
|
|
2606
|
-
if (this._period() === 'PM' && startHour !== 12) {
|
|
2607
|
-
actualStartHour = startHour + 12;
|
|
2608
|
-
}
|
|
2609
|
-
if (this._period() === 'AM' && startHour === 12) {
|
|
2610
|
-
actualStartHour = 0;
|
|
2611
|
-
}
|
|
2612
|
-
}
|
|
2613
|
-
return actualHour < actualStartHour;
|
|
2614
|
-
}
|
|
2615
|
-
isEndMinuteDisabled(minute) {
|
|
2616
|
-
if (!this.isSameDayRange()) {
|
|
2617
|
-
return false;
|
|
2618
|
-
}
|
|
2619
|
-
const startHour = this._hour();
|
|
2620
|
-
const endHour = this._hourEnd();
|
|
2621
|
-
let actualStartHour = startHour;
|
|
2622
|
-
let actualEndHour = endHour;
|
|
2623
|
-
if (this.zTimeFormat() === '12h') {
|
|
2624
|
-
if (this._period() === 'PM' && startHour !== 12) {
|
|
2625
|
-
actualStartHour = startHour + 12;
|
|
2626
|
-
}
|
|
2627
|
-
if (this._period() === 'AM' && startHour === 12) {
|
|
2628
|
-
actualStartHour = 0;
|
|
2629
|
-
}
|
|
2630
|
-
if (this._periodEnd() === 'PM' && endHour !== 12) {
|
|
2631
|
-
actualEndHour = endHour + 12;
|
|
2632
|
-
}
|
|
2633
|
-
if (this._periodEnd() === 'AM' && endHour === 12) {
|
|
2634
|
-
actualEndHour = 0;
|
|
2635
|
-
}
|
|
2636
|
-
}
|
|
2637
|
-
if (actualEndHour !== actualStartHour) {
|
|
2638
|
-
return false;
|
|
2639
|
-
}
|
|
2640
|
-
return minute < this._minute();
|
|
2641
|
-
}
|
|
2642
|
-
isEndSecondDisabled(second) {
|
|
2643
|
-
if (!this.isSameDayRange()) {
|
|
2644
|
-
return false;
|
|
2645
|
-
}
|
|
2646
|
-
const startHour = this._hour();
|
|
2647
|
-
const endHour = this._hourEnd();
|
|
2648
|
-
let actualStartHour = startHour;
|
|
2649
|
-
let actualEndHour = endHour;
|
|
2650
|
-
if (this.zTimeFormat() === '12h') {
|
|
2651
|
-
if (this._period() === 'PM' && startHour !== 12) {
|
|
2652
|
-
actualStartHour = startHour + 12;
|
|
2653
|
-
}
|
|
2654
|
-
if (this._period() === 'AM' && startHour === 12) {
|
|
2655
|
-
actualStartHour = 0;
|
|
2656
|
-
}
|
|
2657
|
-
if (this._periodEnd() === 'PM' && endHour !== 12) {
|
|
2658
|
-
actualEndHour = endHour + 12;
|
|
2659
|
-
}
|
|
2660
|
-
if (this._periodEnd() === 'AM' && endHour === 12) {
|
|
2661
|
-
actualEndHour = 0;
|
|
2662
|
-
}
|
|
2663
|
-
}
|
|
2664
|
-
if (actualEndHour !== actualStartHour) {
|
|
2665
|
-
return false;
|
|
2666
|
-
}
|
|
2667
|
-
if (this._minuteEnd() !== this._minute()) {
|
|
2668
|
-
return false;
|
|
2669
|
-
}
|
|
2670
|
-
return second <= this._second();
|
|
2671
|
-
}
|
|
2672
|
-
isEndPeriodDisabled(period) {
|
|
2673
|
-
if (!this.isSameDayRange()) {
|
|
2674
|
-
return false;
|
|
2675
|
-
}
|
|
2676
|
-
if (this._period() === 'PM' && period === 'AM') {
|
|
2677
|
-
return true;
|
|
2678
|
-
}
|
|
2679
|
-
return false;
|
|
2680
|
-
}
|
|
2681
|
-
_scrollToCurrentTime() {
|
|
2682
|
-
if (!this.zShowTime() && !this.isTimeMode()) {
|
|
2683
|
-
return;
|
|
2684
|
-
}
|
|
2685
|
-
const itemHeight = 28;
|
|
2686
|
-
setTimeout(() => {
|
|
2687
|
-
const timeColumns = document.querySelectorAll('.z-time-column');
|
|
2688
|
-
if (!timeColumns.length) {
|
|
2689
|
-
return;
|
|
2690
|
-
}
|
|
2691
|
-
const columnsArray = Array.from(timeColumns);
|
|
2692
|
-
const startIndex = 0;
|
|
2693
|
-
let columnIndex = startIndex;
|
|
2694
|
-
if (this.zShowHour()) {
|
|
2695
|
-
const hourColumn = columnsArray[columnIndex];
|
|
2696
|
-
if (hourColumn) {
|
|
2697
|
-
const hourValue = this.zTimeFormat() === '12h' ? this.displayHour() - 1 : this._hour();
|
|
2698
|
-
hourColumn.scrollTo({ top: hourValue * itemHeight, behavior: 'smooth' });
|
|
2699
|
-
}
|
|
2700
|
-
columnIndex++;
|
|
2701
|
-
}
|
|
2702
|
-
if (this.zShowMinute()) {
|
|
2703
|
-
const minuteColumn = columnsArray[columnIndex];
|
|
2704
|
-
if (minuteColumn) {
|
|
2705
|
-
minuteColumn.scrollTo({ top: this._minute() * itemHeight, behavior: 'smooth' });
|
|
2706
|
-
}
|
|
2707
|
-
columnIndex++;
|
|
2708
|
-
}
|
|
2709
|
-
if (this.zShowSecond()) {
|
|
2710
|
-
const secondColumn = columnsArray[columnIndex];
|
|
2711
|
-
if (secondColumn) {
|
|
2712
|
-
secondColumn.scrollTo({ top: this._second() * itemHeight, behavior: 'smooth' });
|
|
2713
|
-
}
|
|
2714
|
-
}
|
|
2715
|
-
}, 50);
|
|
2716
|
-
}
|
|
2717
|
-
_scrollToEndTime() {
|
|
2718
|
-
if (!this.zShowTime() || !this.isRangeMode()) {
|
|
2903
|
+
_scrollToTimeValue(scrollbarSelector) {
|
|
2904
|
+
const scrollbar = document.querySelector(scrollbarSelector);
|
|
2905
|
+
if (!scrollbar) {
|
|
2719
2906
|
return;
|
|
2720
2907
|
}
|
|
2721
|
-
const
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
if (!timeColumns.length) {
|
|
2725
|
-
return;
|
|
2726
|
-
}
|
|
2727
|
-
const columnsArray = Array.from(timeColumns);
|
|
2728
|
-
const columnsPerSection = (this.zShowHour() ? 1 : 0) + (this.zShowMinute() ? 1 : 0) + (this.zShowSecond() ? 1 : 0);
|
|
2729
|
-
const endStartIndex = columnsPerSection;
|
|
2730
|
-
let columnIndex = endStartIndex;
|
|
2731
|
-
if (this.zShowHour()) {
|
|
2732
|
-
const hourColumn = columnsArray[columnIndex];
|
|
2733
|
-
if (hourColumn) {
|
|
2734
|
-
const hourValue = this.zTimeFormat() === '12h' ? this.displayHourEnd() - 1 : this._hourEnd();
|
|
2735
|
-
hourColumn.scrollTo({ top: hourValue * itemHeight, behavior: 'smooth' });
|
|
2736
|
-
}
|
|
2737
|
-
columnIndex++;
|
|
2738
|
-
}
|
|
2739
|
-
if (this.zShowMinute()) {
|
|
2740
|
-
const minuteColumn = columnsArray[columnIndex];
|
|
2741
|
-
if (minuteColumn) {
|
|
2742
|
-
minuteColumn.scrollTo({ top: this._minuteEnd() * itemHeight, behavior: 'smooth' });
|
|
2743
|
-
}
|
|
2744
|
-
columnIndex++;
|
|
2745
|
-
}
|
|
2746
|
-
if (this.zShowSecond()) {
|
|
2747
|
-
const secondColumn = columnsArray[columnIndex];
|
|
2748
|
-
if (secondColumn) {
|
|
2749
|
-
secondColumn.scrollTo({ top: this._secondEnd() * itemHeight, behavior: 'smooth' });
|
|
2750
|
-
}
|
|
2751
|
-
}
|
|
2752
|
-
}, 50);
|
|
2753
|
-
}
|
|
2754
|
-
_scrollToTimeOnOpen() {
|
|
2755
|
-
if (!this.zShowTime() && !this.isTimeMode()) {
|
|
2756
|
-
return;
|
|
2908
|
+
const selectedButton = scrollbar.querySelector('button.bg-primary');
|
|
2909
|
+
if (selectedButton) {
|
|
2910
|
+
selectedButton.scrollIntoView({ block: 'center', behavior: 'smooth' });
|
|
2757
2911
|
}
|
|
2758
|
-
const itemHeight = 28;
|
|
2759
|
-
setTimeout(() => {
|
|
2760
|
-
const timeColumns = document.querySelectorAll('.z-time-column');
|
|
2761
|
-
if (!timeColumns.length) {
|
|
2762
|
-
return;
|
|
2763
|
-
}
|
|
2764
|
-
const columnsArray = Array.from(timeColumns);
|
|
2765
|
-
if (this.isRangeMode()) {
|
|
2766
|
-
const columnsPerSection = (this.zShowHour() ? 1 : 0) + (this.zShowMinute() ? 1 : 0) + (this.zShowSecond() ? 1 : 0);
|
|
2767
|
-
let columnIndex = 0;
|
|
2768
|
-
if (this.zShowHour()) {
|
|
2769
|
-
const hourColumn = columnsArray[columnIndex];
|
|
2770
|
-
if (hourColumn) {
|
|
2771
|
-
const hourValue = this.zTimeFormat() === '12h' ? this.displayHour() - 1 : this._hour();
|
|
2772
|
-
hourColumn.scrollTop = hourValue * itemHeight;
|
|
2773
|
-
}
|
|
2774
|
-
columnIndex++;
|
|
2775
|
-
}
|
|
2776
|
-
if (this.zShowMinute()) {
|
|
2777
|
-
const minuteColumn = columnsArray[columnIndex];
|
|
2778
|
-
if (minuteColumn) {
|
|
2779
|
-
minuteColumn.scrollTop = this._minute() * itemHeight;
|
|
2780
|
-
}
|
|
2781
|
-
columnIndex++;
|
|
2782
|
-
}
|
|
2783
|
-
if (this.zShowSecond()) {
|
|
2784
|
-
const secondColumn = columnsArray[columnIndex];
|
|
2785
|
-
if (secondColumn) {
|
|
2786
|
-
secondColumn.scrollTop = this._second() * itemHeight;
|
|
2787
|
-
}
|
|
2788
|
-
}
|
|
2789
|
-
columnIndex = columnsPerSection;
|
|
2790
|
-
if (this.zShowHour()) {
|
|
2791
|
-
const hourColumn = columnsArray[columnIndex];
|
|
2792
|
-
if (hourColumn) {
|
|
2793
|
-
const hourValue = this.zTimeFormat() === '12h' ? this.displayHourEnd() - 1 : this._hourEnd();
|
|
2794
|
-
hourColumn.scrollTop = hourValue * itemHeight;
|
|
2795
|
-
}
|
|
2796
|
-
columnIndex++;
|
|
2797
|
-
}
|
|
2798
|
-
if (this.zShowMinute()) {
|
|
2799
|
-
const minuteColumn = columnsArray[columnIndex];
|
|
2800
|
-
if (minuteColumn) {
|
|
2801
|
-
minuteColumn.scrollTop = this._minuteEnd() * itemHeight;
|
|
2802
|
-
}
|
|
2803
|
-
columnIndex++;
|
|
2804
|
-
}
|
|
2805
|
-
if (this.zShowSecond()) {
|
|
2806
|
-
const secondColumn = columnsArray[columnIndex];
|
|
2807
|
-
if (secondColumn) {
|
|
2808
|
-
secondColumn.scrollTop = this._secondEnd() * itemHeight;
|
|
2809
|
-
}
|
|
2810
|
-
}
|
|
2811
|
-
return;
|
|
2812
|
-
}
|
|
2813
|
-
let columnIndex = 0;
|
|
2814
|
-
if (this.zShowHour()) {
|
|
2815
|
-
const hourColumn = columnsArray[columnIndex];
|
|
2816
|
-
if (hourColumn) {
|
|
2817
|
-
const hourValue = this.zTimeFormat() === '12h' ? this.displayHour() - 1 : this._hour();
|
|
2818
|
-
hourColumn.scrollTop = hourValue * itemHeight;
|
|
2819
|
-
}
|
|
2820
|
-
columnIndex++;
|
|
2821
|
-
}
|
|
2822
|
-
if (this.zShowMinute()) {
|
|
2823
|
-
const minuteColumn = columnsArray[columnIndex];
|
|
2824
|
-
if (minuteColumn) {
|
|
2825
|
-
minuteColumn.scrollTop = this._minute() * itemHeight;
|
|
2826
|
-
}
|
|
2827
|
-
columnIndex++;
|
|
2828
|
-
}
|
|
2829
|
-
if (this.zShowSecond()) {
|
|
2830
|
-
const secondColumn = columnsArray[columnIndex];
|
|
2831
|
-
if (secondColumn) {
|
|
2832
|
-
secondColumn.scrollTop = this._second() * itemHeight;
|
|
2833
|
-
}
|
|
2834
|
-
}
|
|
2835
|
-
}, 0);
|
|
2836
2912
|
}
|
|
2837
2913
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2838
2914
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ZCalendarComponent, isStandalone: true, selector: "z-calendar", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zMode: { classPropertyName: "zMode", publicName: "zMode", isSignal: true, isRequired: false, transformFunction: null }, zSize: { classPropertyName: "zSize", publicName: "zSize", isSignal: true, isRequired: false, transformFunction: null }, zLabel: { classPropertyName: "zLabel", publicName: "zLabel", isSignal: true, isRequired: false, transformFunction: null }, zLabelClass: { classPropertyName: "zLabelClass", publicName: "zLabelClass", isSignal: true, isRequired: false, transformFunction: null }, zPlaceholder: { classPropertyName: "zPlaceholder", publicName: "zPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, zRequired: { classPropertyName: "zRequired", publicName: "zRequired", isSignal: true, isRequired: false, transformFunction: null }, zDisabled: { classPropertyName: "zDisabled", publicName: "zDisabled", isSignal: true, isRequired: false, transformFunction: null }, zReadonly: { classPropertyName: "zReadonly", publicName: "zReadonly", isSignal: true, isRequired: false, transformFunction: null }, zShowTime: { classPropertyName: "zShowTime", publicName: "zShowTime", isSignal: true, isRequired: false, transformFunction: null }, zTimeFormat: { classPropertyName: "zTimeFormat", publicName: "zTimeFormat", isSignal: true, isRequired: false, transformFunction: null }, zShowHour: { classPropertyName: "zShowHour", publicName: "zShowHour", isSignal: true, isRequired: false, transformFunction: null }, zShowMinute: { classPropertyName: "zShowMinute", publicName: "zShowMinute", isSignal: true, isRequired: false, transformFunction: null }, zShowSecond: { classPropertyName: "zShowSecond", publicName: "zShowSecond", isSignal: true, isRequired: false, transformFunction: null }, zQuickSelect: { classPropertyName: "zQuickSelect", publicName: "zQuickSelect", isSignal: true, isRequired: false, transformFunction: null }, zAllowClear: { classPropertyName: "zAllowClear", publicName: "zAllowClear", isSignal: true, isRequired: false, transformFunction: null }, zFormat: { classPropertyName: "zFormat", publicName: "zFormat", isSignal: true, isRequired: false, transformFunction: null }, zMinDate: { classPropertyName: "zMinDate", publicName: "zMinDate", isSignal: true, isRequired: false, transformFunction: null }, zMaxDate: { classPropertyName: "zMaxDate", publicName: "zMaxDate", isSignal: true, isRequired: false, transformFunction: null }, zValueType: { classPropertyName: "zValueType", publicName: "zValueType", isSignal: true, isRequired: false, transformFunction: null }, zValidators: { classPropertyName: "zValidators", publicName: "zValidators", isSignal: true, isRequired: false, transformFunction: null }, zLocale: { classPropertyName: "zLocale", publicName: "zLocale", isSignal: true, isRequired: false, transformFunction: null }, zShowOk: { classPropertyName: "zShowOk", publicName: "zShowOk", isSignal: true, isRequired: false, transformFunction: null }, zOkText: { classPropertyName: "zOkText", publicName: "zOkText", isSignal: true, isRequired: false, transformFunction: null }, zShowCancel: { classPropertyName: "zShowCancel", publicName: "zShowCancel", isSignal: true, isRequired: false, transformFunction: null }, zCancelText: { classPropertyName: "zCancelText", publicName: "zCancelText", isSignal: true, isRequired: false, transformFunction: null }, zDisabledDate: { classPropertyName: "zDisabledDate", publicName: "zDisabledDate", isSignal: true, isRequired: false, transformFunction: null }, zScrollClose: { classPropertyName: "zScrollClose", publicName: "zScrollClose", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zControl: "zControl", zChange: "zChange" }, providers: [
|
|
@@ -2842,7 +2918,7 @@ class ZCalendarComponent {
|
|
|
2842
2918
|
multi: true,
|
|
2843
2919
|
},
|
|
2844
2920
|
TranslatePipe,
|
|
2845
|
-
], viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }, { propertyName: "inputRef", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }], exportAs: ["zCalendar"], ngImport: i0, template: "<div class=\"z-calendar-wrapper flex w-full flex-col gap-2\">\n @if (zLabel()) {\n <label [for]=\"pickerId\" class=\"text-xs leading-none font-medium\" [class]=\"zLabelClass()\">\n {{ zLabel() }}\n @if (zRequired()) {\n <span class=\"text-destructive! ml-0.5\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <div\n #triggerEl\n z-popover\n [zPopoverContent]=\"calendarTpl\"\n zPosition=\"bottom-left\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"6\"\n [zDisabled]=\"isDisabled() || zReadonly()\"\n [zManualClose]=\"showCancelButton()\"\n [zScrollClose]=\"zScrollClose()\"\n zTrigger=\"click\"\n zClass=\"border-0 shadow-none bg-transparent p-0\"\n (zHideStart)=\"onPopoverHide()\"\n (zShow)=\"onPopoverShow()\"\n (zControl)=\"onPopoverControl($event)\"\n [id]=\"pickerId\"\n [class]=\"triggerClasses()\"\n (keydown)=\"onTriggerKeydown($event)\">\n <z-icon\n [zType]=\"isRangeMode() ? 'lucideCalendarRange' : 'lucideCalendar'\"\n zSize=\"16\"\n class=\"text-muted-foreground shrink-0 cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggle()\" />\n\n @if (isRangeMode()) {\n <input\n type=\"text\"\n data-range-type=\"start\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_start_date' | translate\"\n [value]=\"inputDisplayStart()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onStartInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onStartInputEnter($event)\"\n (keydown.escape)=\"onStartInputEscape()\" />\n <span class=\"text-muted-foreground text-sm\">-</span>\n <input\n type=\"text\"\n data-range-type=\"end\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_end_date' | translate\"\n [value]=\"inputDisplayEnd()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onEndInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onEndInputEnter($event)\"\n (keydown.escape)=\"onEndInputEscape()\" />\n } @else {\n <input\n #inputEl\n type=\"text\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-sm outline-none\"\n [placeholder]=\"zPlaceholder()\"\n [value]=\"inputDisplayValue()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onInputEnter($event)\"\n (keydown.escape)=\"onInputEscape()\" />\n }\n\n @if (zAllowClear() && !isDisabled() && !zReadonly()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"text-muted-foreground hover:text-foreground flex size-5 shrink-0 cursor-pointer items-center justify-center rounded transition-all\"\n [class.opacity-0]=\"!hasValue()\"\n [class.pointer-events-none]=\"!hasValue()\"\n (click)=\"onClear($event)\">\n <z-icon zType=\"lucideX\" zSize=\"14\" />\n </button>\n }\n </div>\n </div>\n\n @if (showError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n</div>\n\n<ng-template #calendarTpl>\n <div\n class=\"z-calendar-calendar bg-popover border-border flex max-h-[90vh] max-w-[95vw] flex-col overflow-auto rounded-[6px] border shadow-lg sm:max-h-none sm:max-w-none sm:flex-row sm:overflow-visible\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div\n class=\"border-border flex shrink-0 flex-row gap-1 overflow-x-auto border-b p-2 sm:flex-col sm:gap-0 sm:space-y-1 sm:overflow-x-visible sm:border-r sm:border-b-0\">\n @for (preset of quickSelectPresets; track preset.key) {\n @let presetDisabled = preset | zIsPresetDisabled: zDisabledDate();\n <button\n type=\"button\"\n class=\"cursor-pointer rounded-[4px] px-3 py-1.5 text-left text-sm whitespace-nowrap transition-colors\"\n [class.hover:bg-muted]=\"activePresetKey() !== preset.key && !presetDisabled\"\n [class.bg-primary]=\"activePresetKey() === preset.key\"\n [class.text-primary-foreground]=\"activePresetKey() === preset.key\"\n [class.font-medium]=\"activePresetKey() === preset.key\"\n [class.opacity-40]=\"presetDisabled\"\n [class.cursor-not-allowed]=\"presetDisabled\"\n [disabled]=\"presetDisabled\"\n (click)=\"onQuickSelect(preset)\">\n {{ preset.label }}\n </button>\n }\n </div>\n }\n <div class=\"flex flex-1 flex-col gap-2 overflow-auto p-3 sm:overflow-visible\">\n @if (!isTimeMode()) {\n <div class=\"z-calendars-wrapper flex flex-col items-start gap-3 sm:flex-row sm:gap-0\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex flex-col gap-1\">\n @if (!isTimeMode()) {\n <div class=\"flex w-full items-center justify-between space-x-1\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePrevious()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePreviousFast()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0.5\">\n @if (!isYearMode() && !isQuarterMode()) {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"w-20 px-2!\"\n [zWave]=\"false\"\n [zDisabled]=\"false\"\n (click)=\"setView('month')\">\n {{ currentMonthName() }}\n </button>\n }\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"px-2!\"\n [zWave]=\"false\"\n [zDisabled]=\"isYearMode()\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNextFast()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNext()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"16\" />\n </button>\n </div>\n\n <div class=\"z-calendar-views w-full\" [class.z-calendar-views-quarter]=\"isQuarterMode()\">\n @if (currentView() === 'day') {\n <div class=\"flex h-full w-full flex-col gap-1\" [class.z-calendar-animate]=\"hasViewChanged()\">\n <div class=\"grid w-full grid-cols-7\">\n @for (weekday of weekdayNames; track weekday) {\n <div class=\"text-muted-foreground flex h-7 items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n @for (week of calendarDays(); track $index) {\n <div class=\"grid w-full grid-cols-7\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'month') {\n <div class=\"grid h-full w-full grid-cols-3 grid-rows-4\" [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let monthDisabled = isStartMonthDisabled(i);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: currentMonthIndex()\"\n [disabled]=\"monthDisabled\"\n [class.opacity-30]=\"monthDisabled\"\n [class.cursor-not-allowed]=\"monthDisabled\"\n (click)=\"onMonthSelect(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 gap-0.5\"\n [class.grid-rows-4]=\"!isYearMode() && !isQuarterMode()\"\n [class.grid-rows-3]=\"isYearMode() || isQuarterMode()\"\n [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (year of isYearMode() || isQuarterMode() ? yearRangeSmall() : yearRange(); track year) {\n @let yearDisabled = isStartYearDisabled(year);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: currentYear()\"\n [disabled]=\"yearDisabled\"\n [class.opacity-30]=\"yearDisabled\"\n [class.cursor-not-allowed]=\"yearDisabled\"\n (click)=\"onYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'quarter') {\n <div class=\"grid w-full grid-cols-2 gap-2\" [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (quarter of quarterNames; track quarter; let i = $index) {\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zQuarterClasses: currentQuarterIndex()\"\n (click)=\"onQuarterClick(i)\">\n {{ quarter }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time Picker Side Panel (for single date with showTime) -->\n @if (!isRangeMode() && zShowTime() && currentView() === 'day') {\n <div\n class=\"border-border mt-3 flex w-full flex-col items-center border-t pt-3 sm:mt-0 sm:w-auto sm:border-t-0 sm:border-l sm:pt-0 sm:pl-3\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_time' | translate }}\n </div>\n <div class=\"flex flex-col items-center gap-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[140px] w-12 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[140px] w-12 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[140px] w-12 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex w-full gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div class=\"border-border bg-border hidden self-stretch sm:mx-3 sm:block sm:w-px\"></div>\n <div class=\"border-border bg-border block h-px w-full sm:hidden\"></div>\n\n <div class=\"z-calendar-section flex flex-col gap-1\">\n <div class=\"flex w-full items-center justify-between space-x-1\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0.5\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"w-20 px-2!\"\n [zWave]=\"false\"\n (click)=\"setEndView('month')\">\n {{ endMonthName() }}\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"px-2!\"\n [zWave]=\"false\"\n (click)=\"setEndView('year')\">\n {{ endMonthYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"16\" />\n </button>\n </div>\n\n <div class=\"z-calendar-views w-full\">\n @if (endView() === 'day') {\n <div class=\"flex h-full w-full flex-col gap-1\" [class.z-calendar-animate]=\"hasEndViewChanged()\">\n <div class=\"grid grid-cols-7 gap-px\">\n @for (weekday of weekdayNames; track weekday) {\n <div class=\"text-muted-foreground flex h-8 w-8 items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n @for (week of calendarDaysEnd(); track $index) {\n <div class=\"grid grid-cols-7 gap-px\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (endView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4\"\n [class.z-calendar-animate]=\"hasEndViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let endMonthDisabled = isEndMonthDisabled(i);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: endMonth().getMonth()\"\n [disabled]=\"endMonthDisabled\"\n [class.opacity-30]=\"endMonthDisabled\"\n [class.cursor-not-allowed]=\"endMonthDisabled\"\n (click)=\"onEndMonthClick(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (endView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-0.5\"\n [class.z-calendar-animate]=\"hasEndViewChanged()\">\n @for (year of endYearRange(); track year) {\n @let endYearDisabled = isEndYearDisabled(year);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: endMonth().getFullYear()\"\n [disabled]=\"endYearDisabled\"\n [class.opacity-30]=\"endYearDisabled\"\n [class.cursor-not-allowed]=\"endYearDisabled\"\n (click)=\"onEndYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Range Mode Time Picker Side Panel -->\n @if (isRangeMode() && zShowTime() && currentView() === 'day' && endView() === 'day') {\n <div\n class=\"border-border mt-3 flex w-full flex-row justify-center gap-3 border-t pt-3 sm:mt-0 sm:w-auto sm:border-t-0 sm:border-l sm:pt-0 sm:pl-3\">\n <!-- Start Time -->\n <div class=\"flex flex-col\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_start' | translate }}\n </div>\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 flex-1 cursor-pointer items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 flex-1 cursor-pointer items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n\n <!-- End Time -->\n <div class=\"flex flex-col\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_end' | translate }}\n </div>\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n @let hourDisabled = isEndHourDisabled(hour);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!hourDisabled\"\n [class.cursor-pointer]=\"!hourDisabled\"\n [class.bg-primary]=\"isHourEndSelected(hour)\"\n [class.text-primary-foreground]=\"isHourEndSelected(hour)\"\n [class.font-medium]=\"isHourEndSelected(hour)\"\n [class.opacity-30]=\"hourDisabled\"\n [class.cursor-not-allowed]=\"hourDisabled\"\n [disabled]=\"hourDisabled\"\n (click)=\"selectHourEnd(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n @let minuteDisabled = isEndMinuteDisabled(minute);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!minuteDisabled\"\n [class.cursor-pointer]=\"!minuteDisabled\"\n [class.bg-primary]=\"isMinuteEndSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteEndSelected(minute)\"\n [class.font-medium]=\"isMinuteEndSelected(minute)\"\n [class.opacity-30]=\"minuteDisabled\"\n [class.cursor-not-allowed]=\"minuteDisabled\"\n [disabled]=\"minuteDisabled\"\n (click)=\"selectMinuteEnd(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n @let secondDisabled = isEndSecondDisabled(second);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!secondDisabled\"\n [class.cursor-pointer]=\"!secondDisabled\"\n [class.bg-primary]=\"isSecondEndSelected(second)\"\n [class.text-primary-foreground]=\"isSecondEndSelected(second)\"\n [class.font-medium]=\"isSecondEndSelected(second)\"\n [class.opacity-30]=\"secondDisabled\"\n [class.cursor-not-allowed]=\"secondDisabled\"\n [disabled]=\"secondDisabled\"\n (click)=\"selectSecondEnd(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex gap-1\">\n @let amDisabled = isEndPeriodDisabled('AM');\n <button\n type=\"button\"\n class=\"flex h-6 flex-1 items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.hover:bg-muted]=\"!amDisabled\"\n [class.cursor-pointer]=\"!amDisabled\"\n [class.bg-primary]=\"periodEnd() === 'AM'\"\n [class.text-primary-foreground]=\"periodEnd() === 'AM'\"\n [class.opacity-30]=\"amDisabled\"\n [class.cursor-not-allowed]=\"amDisabled\"\n [disabled]=\"amDisabled\"\n (click)=\"selectPeriodEnd('AM')\">\n AM\n </button>\n @let pmDisabled = isEndPeriodDisabled('PM');\n <button\n type=\"button\"\n class=\"flex h-6 flex-1 items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.hover:bg-muted]=\"!pmDisabled\"\n [class.cursor-pointer]=\"!pmDisabled\"\n [class.bg-primary]=\"periodEnd() === 'PM'\"\n [class.text-primary-foreground]=\"periodEnd() === 'PM'\"\n [class.opacity-30]=\"pmDisabled\"\n [class.cursor-not-allowed]=\"pmDisabled\"\n [disabled]=\"pmDisabled\"\n (click)=\"selectPeriodEnd('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"flex flex-col items-center gap-2 py-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex w-full gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n }\n\n @if (!(zQuickSelect() && zMode() === 'range' && !showOkButton() && !showCancelButton())) {\n <div class=\"border-border flex items-center justify-between gap-2 border-t pt-2\">\n @if (!zQuickSelect() || zMode() !== 'range') {\n <button type=\"button\" z-button zType=\"secondary\" zSize=\"sm\" [zWave]=\"false\" (click)=\"onTodayClick()\">\n {{ todayButtonText() }}\n </button>\n } @else {\n <div></div>\n }\n\n @if (showOkButton() || showCancelButton()) {\n <div class=\"flex items-center gap-2\">\n @if (showCancelButton()) {\n <button type=\"button\" z-button zType=\"outline\" zSize=\"sm\" (click)=\"onCancelClick()\">\n {{ zCancelText() ?? ('i18n_z_ui_calendar_cancel' | translate) }}\n </button>\n }\n @if (showOkButton()) {\n <button type=\"button\" z-button zSize=\"sm\" [zDisabled]=\"!canApply()\" (click)=\"onOkClick()\">\n {{ zOkText() ?? ('i18n_z_ui_calendar_ok' | translate) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n", styles: [".z-calendar-calendar .z-calendar-section{width:280px;flex-shrink:0}.z-calendar-calendar .z-calendar-views{height:225px;width:100%;display:flex;align-items:center;justify-content:center;flex-direction:column}.z-calendar-calendar .z-calendar-views.z-calendar-views-quarter{height:auto}.z-calendar-calendar .z-calendar-animate{animation:z-calendar-view-enter .2s ease-out}.z-time-picker{display:flex;flex-direction:column;gap:.5rem;flex-shrink:0}.z-time-picker .z-time-columns{display:flex;gap:.25rem}.z-time-picker .z-time-column{width:42px;height:180px;overflow-y:auto;scroll-snap-type:y mandatory;scroll-behavior:smooth;scrollbar-width:thin}.z-time-picker .z-time-column::-webkit-scrollbar{width:4px}.z-time-picker .z-time-column::-webkit-scrollbar-track{background:transparent}.z-time-picker .z-time-column::-webkit-scrollbar-thumb{background-color:hsl(var(--border));border-radius:2px}.z-time-picker .z-time-item{height:32px;width:100%;display:flex;align-items:center;justify-content:center;font-size:.875rem;scroll-snap-align:center;border-radius:4px;cursor:pointer;transition:background-color .15s ease,color .15s ease}.z-time-picker .z-time-item:hover:not(.z-time-item-selected){background-color:hsl(var(--muted))}.z-time-picker .z-time-item.z-time-item-selected{background-color:hsl(var(--primary));color:hsl(var(--primary-foreground));font-weight:500}.z-time-picker .z-time-item:focus-visible{outline:2px solid hsl(var(--ring));outline-offset:-2px}.z-time-picker .z-time-period-buttons{display:flex;flex-direction:column;gap:.25rem;padding-top:8px}.z-time-picker .z-time-period-buttons button{height:28px;font-size:.75rem;border-radius:4px;transition:background-color .15s ease,color .15s ease}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"], dependencies: [{ kind: "component", type: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zManualClose", "zScrollClose", "zShowArrow"], outputs: ["zShow", "zHide", "zHideStart", "zControl"], exportAs: ["zPopover"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: ZDayClassesPipe, name: "zDayClasses" }, { kind: "pipe", type: ZMonthClassesPipe, name: "zMonthClasses" }, { kind: "pipe", type: ZQuarterClassesPipe, name: "zQuarterClasses" }, { kind: "pipe", type: ZYearClassesPipe, name: "zYearClasses" }, { kind: "pipe", type: ZIsPresetDisabledPipe, name: "zIsPresetDisabled" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2921
|
+
], viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }, { propertyName: "inputRef", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }], exportAs: ["zCalendar"], ngImport: i0, template: "<div class=\"z-calendar-wrapper flex w-full flex-col gap-2\">\n @if (zLabel()) {\n <label [for]=\"pickerId\" class=\"text-xs leading-none font-medium\" [class]=\"zLabelClass()\">\n {{ zLabel() }}\n @if (zRequired()) {\n <span class=\"text-destructive! ml-0.5\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <div\n #triggerEl\n z-popover\n [zPopoverContent]=\"calendarTpl\"\n zPosition=\"bottom-left\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"6\"\n [zDisabled]=\"isDisabled() || zReadonly()\"\n [zManualClose]=\"showCancelButton()\"\n [zScrollClose]=\"zScrollClose()\"\n zTrigger=\"click\"\n zClass=\"border-0 shadow-none bg-transparent p-0\"\n (zHideStart)=\"onPopoverHide()\"\n (zShow)=\"onPopoverShow()\"\n (zControl)=\"onPopoverControl($event)\"\n [id]=\"pickerId\"\n [class]=\"triggerClasses()\"\n (keydown)=\"onTriggerKeydown($event)\">\n <z-icon\n [zType]=\"isRangeMode() ? 'lucideCalendarRange' : 'lucideCalendar'\"\n zSize=\"16\"\n class=\"text-muted-foreground shrink-0 cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggle()\" />\n\n @if (isRangeMode()) {\n <input\n type=\"text\"\n data-range-type=\"start\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_start_date' | translate\"\n [value]=\"inputDisplayStart()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onStartInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onStartInputEnter($event)\"\n (keydown.escape)=\"onStartInputEscape()\" />\n <span class=\"text-muted-foreground text-sm\">-</span>\n <input\n type=\"text\"\n data-range-type=\"end\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_end_date' | translate\"\n [value]=\"inputDisplayEnd()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onEndInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onEndInputEnter($event)\"\n (keydown.escape)=\"onEndInputEscape()\" />\n } @else {\n <input\n #inputEl\n type=\"text\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-sm outline-none\"\n [placeholder]=\"zPlaceholder()\"\n [value]=\"inputDisplayValue()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onInputEnter($event)\"\n (keydown.escape)=\"onInputEscape()\" />\n }\n\n @if (zAllowClear() && !isDisabled() && !zReadonly()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"text-muted-foreground hover:text-foreground flex size-5 shrink-0 cursor-pointer items-center justify-center rounded transition-all\"\n [class.opacity-0]=\"!hasValue()\"\n [class.pointer-events-none]=\"!hasValue()\"\n (click)=\"onClear($event)\">\n <z-icon zType=\"lucideX\" zSize=\"14\" />\n </button>\n }\n </div>\n </div>\n\n @if (showError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n</div>\n\n<ng-template #calendarTpl>\n <div\n class=\"z-calendar-calendar bg-popover border-border flex max-h-[90vh] max-w-[95vw] flex-col overflow-auto rounded-[6px] border shadow-lg sm:max-h-none sm:max-w-none sm:flex-row sm:overflow-visible\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div\n class=\"border-border flex shrink-0 flex-row gap-1 overflow-x-auto border-b p-2 sm:flex-col sm:gap-0 sm:space-y-1 sm:overflow-x-visible sm:border-r sm:border-b-0\">\n @for (preset of quickSelectPresets; track preset.key) {\n @let presetDisabled = preset | zIsPresetDisabled: zDisabledDate();\n <button\n type=\"button\"\n class=\"cursor-pointer rounded-[4px] px-3 py-1.5 text-left text-sm whitespace-nowrap transition-colors\"\n [class.hover:bg-muted]=\"activePresetKey() !== preset.key && !presetDisabled\"\n [class.bg-primary]=\"activePresetKey() === preset.key\"\n [class.text-primary-foreground]=\"activePresetKey() === preset.key\"\n [class.font-medium]=\"activePresetKey() === preset.key\"\n [class.opacity-40]=\"presetDisabled\"\n [class.cursor-not-allowed]=\"presetDisabled\"\n [disabled]=\"presetDisabled\"\n (click)=\"onQuickSelect(preset)\">\n {{ preset.label }}\n </button>\n }\n </div>\n }\n <div\n class=\"flex flex-1 flex-col items-center overflow-auto p-2 sm:overflow-visible\"\n [class]=\"!isRangeMode() ? 'w-[280px]' : ''\">\n @if (!isTimeMode()) {\n <div\n class=\"z-calendars-wrapper flex w-full flex-col items-center gap-3 sm:flex-row sm:items-stretch sm:justify-center sm:gap-0\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex shrink-0 flex-col\">\n @if (!isTimeMode()) {\n <!-- Header -->\n <div class=\"border-border flex w-full items-center justify-between gap-0.5 px-2\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePrevious()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"14\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePreviousFast()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"14\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0\">\n @if (!isYearMode() && !isQuarterMode()) {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n [zDisabled]=\"false\"\n (click)=\"setView('month')\">\n {{ currentMonthName() }}\n </button>\n }\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n [zDisabled]=\"isYearMode()\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNextFast()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"14\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNext()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"14\" />\n </button>\n </div>\n\n <!-- Body -->\n <div\n class=\"flex h-full w-full flex-col items-center justify-center p-2\"\n [class.min-h-[224px]]=\"!isQuarterMode()\"\n [class.h-[224px]]=\"\n !isYearMode() &&\n !isMonthMode() &&\n !isQuarterMode() &&\n (currentView() === 'month' || currentView() === 'year')\n \"\n [class.min-h-[100px]]=\"isQuarterMode()\"\n [class.!min-h-auto]=\"isYearMode() || isMonthMode() || isQuarterMode()\"\n [class.!h-auto]=\"isYearMode() || isMonthMode() || isQuarterMode()\">\n @if (currentView() === 'day') {\n <div\n class=\"flex h-full w-full flex-1 flex-col gap-1\"\n [class.animate-calendar-enter]=\"hasViewChanged()\">\n <!-- Weekday headers -->\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (weekday of weekdayNames; track weekday) {\n <div\n class=\"text-muted-foreground flex w-[33px] items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n <!-- Date rows -->\n @for (week of calendarDays(); track $index) {\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n class=\"!w-[33px] !text-sm\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (currentView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"hasViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let monthDisabled = i | zIsStartMonthDisabled: startMonthDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: selectedMonthIndex() : todayMonthIndex()\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"monthDisabled\"\n [class.opacity-30]=\"monthDisabled\"\n [class.cursor-not-allowed]=\"monthDisabled\"\n (click)=\"onMonthSelect(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"hasViewChanged()\">\n @for (year of yearRange(); track year) {\n @let yearDisabled = year | zIsStartYearDisabled: startYearDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: selectedYear() : todayYear()\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"yearDisabled\"\n [class.opacity-30]=\"yearDisabled\"\n [class.cursor-not-allowed]=\"yearDisabled\"\n (click)=\"onYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'quarter') {\n <div\n class=\"grid h-full w-full grid-cols-2 grid-rows-2 gap-2 p-1\"\n [class.animate-calendar-enter]=\"hasViewChanged()\">\n @for (quarter of quarterNames; track quarter; let i = $index) {\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zQuarterClasses: selectedQuarterIndex() : todayQuarterIndex()\"\n class=\"!h-8 !w-full !text-sm\"\n (click)=\"onQuarterClick(i)\">\n {{ quarter }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div class=\"border-border bg-border hidden self-stretch sm:mx-2 sm:block sm:w-px\"></div>\n <div class=\"border-border bg-border block h-px w-full sm:hidden\"></div>\n\n <div class=\"z-calendar-section flex shrink-0 flex-col\">\n <!-- Header -->\n <div class=\"border-border flex w-full items-center justify-between gap-0.5 px-2\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"14\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"14\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setEndView('month')\">\n {{ endMonthName() }}\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setEndView('year')\">\n {{ endMonthYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"14\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"14\" />\n </button>\n </div>\n\n <!-- Body -->\n <div\n class=\"flex h-full min-h-[224px] w-full flex-col items-center justify-center p-2\"\n [class.h-[224px]]=\"endView() === 'month' || endView() === 'year'\">\n @if (endView() === 'day') {\n <div\n class=\"flex h-full w-full flex-1 flex-col gap-1\"\n [class.animate-calendar-enter]=\"hasEndViewChanged()\">\n <!-- Weekday headers -->\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (weekday of weekdayNames; track weekday) {\n <div\n class=\"text-muted-foreground flex w-[33px] items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n <!-- Date rows -->\n @for (week of calendarDaysEnd(); track $index) {\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n class=\"!w-[33px] !text-sm\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (endView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"hasEndViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let endMonthDisabled = i | zIsEndMonthDisabled: endMonthDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: endMonth().getMonth() : -1\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"endMonthDisabled\"\n [class.opacity-30]=\"endMonthDisabled\"\n [class.cursor-not-allowed]=\"endMonthDisabled\"\n (click)=\"onEndMonthClick(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (endView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"hasEndViewChanged()\">\n @for (year of endYearRange(); track year) {\n @let endYearDisabled = year | zIsEndYearDisabled: endYearDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: endMonth().getFullYear() : -1\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"endYearDisabled\"\n [class.opacity-30]=\"endYearDisabled\"\n [class.cursor-not-allowed]=\"endYearDisabled\"\n (click)=\"onEndYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Compact Time Picker Below Calendar (Single Date) -->\n @if (!isRangeMode() && zShowTime()) {\n <div class=\"border-border w-full border-t text-center\">\n <div\n class=\"hover:bg-muted my-1 inline-flex cursor-pointer items-center rounded-sm px-2 py-1 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownTpl\"\n zPosition=\"bottom\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-md\"\n (zShow)=\"onTimeDropdownShow()\">\n <div class=\"flex items-center justify-center gap-1\">\n <!-- Hour -->\n @if (zShowHour()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementHour(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedHour() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementHour(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground text-sm font-medium\">:</span>\n }\n <!-- Minute -->\n @if (zShowMinute()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementMinute(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedMinute() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementMinute(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground text-sm font-medium\">:</span>\n }\n <!-- Second -->\n @if (zShowSecond()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementSecond(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedSecond() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementSecond(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n <!-- AM/PM Toggle -->\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n class=\"bg-primary/10 text-primary hover:bg-primary/20 active:bg-primary/30 ml-1 flex w-8 cursor-pointer items-center justify-center rounded border-none px-2 py-1 text-xs font-semibold transition-colors\"\n (click)=\"togglePeriod(); $event.stopPropagation()\">\n {{ period() }}\n </button>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Compact Time Pickers Below Calendars (Range Mode) -->\n @if (isRangeMode() && zShowTime()) {\n <div class=\"border-border flex w-full flex-col border-t sm:flex-row sm:gap-3\">\n <!-- Start Time -->\n <div class=\"flex w-full flex-col items-center justify-center gap-1\">\n <div\n class=\"hover:bg-muted my-1 inline-flex cursor-pointer items-center rounded-sm px-2 py-1 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownStartTpl\"\n zPosition=\"bottom\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-md\"\n (zShow)=\"onTimeDropdownShow()\">\n <div class=\"flex items-center justify-center gap-1\">\n <!-- Hour -->\n @if (zShowHour()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementHour(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedHour() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementHour(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground text-sm font-medium\">:</span>\n }\n <!-- Minute -->\n @if (zShowMinute()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementMinute(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedMinute() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementMinute(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground text-sm font-medium\">:</span>\n }\n <!-- Second -->\n @if (zShowSecond()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementSecond(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedSecond() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementSecond(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n <!-- AM/PM Toggle -->\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n class=\"bg-primary/10 text-primary hover:bg-primary/20 active:bg-primary/30 ml-1 flex w-8 cursor-pointer items-center justify-center rounded border-none px-2 py-1 text-xs font-semibold transition-colors\"\n (click)=\"togglePeriod(); $event.stopPropagation()\">\n {{ period() }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Divider space -->\n <div class=\"border-border bg-border h-px self-stretch sm:mx-2 sm:block sm:h-full sm:w-px\"></div>\n\n <!-- End Time -->\n <div class=\"flex w-full flex-col items-center justify-center gap-1\">\n <div\n class=\"hover:bg-muted my-1 inline-flex cursor-pointer items-center rounded-sm px-2 py-1 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownEndTpl\"\n zPosition=\"bottom\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-md\"\n (zShow)=\"onTimeDropdownEndShow()\">\n <div class=\"flex items-center justify-center gap-1\">\n <!-- Hour -->\n @if (zShowHour()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementHourEnd(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedHourEnd() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementHourEnd(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground text-sm font-medium\">:</span>\n }\n <!-- Minute -->\n @if (zShowMinute()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementMinuteEnd(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedMinuteEnd() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementMinuteEnd(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground text-sm font-medium\">:</span>\n }\n <!-- Second -->\n @if (zShowSecond()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementSecondEnd(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedSecondEnd() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementSecondEnd(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n <!-- AM/PM Toggle -->\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n class=\"bg-primary/10 text-primary hover:bg-primary/20 active:bg-primary/30 ml-1 flex w-8 cursor-pointer items-center justify-center rounded border-none px-2 py-1 text-xs font-semibold transition-colors\"\n (click)=\"togglePeriodEnd(); $event.stopPropagation()\">\n {{ periodEnd() }}\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n }\n } @else {\n <!-- Time Only Mode - Compact Display -->\n <div class=\"flex flex-col items-center gap-3 pb-2\">\n <div\n class=\"hover:bg-muted inline-flex cursor-pointer items-center rounded-md px-3 py-2 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownTpl\"\n zPosition=\"bottom\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-md\"\n (zShow)=\"onTimeDropdownShow()\">\n <div class=\"flex items-center justify-center gap-1.5\">\n <!-- Hour -->\n @if (zShowHour()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-9 cursor-pointer flex-col items-center gap-0 rounded px-1.5 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-1 flex h-5 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementHour(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"16\" />\n </button>\n <span class=\"text-foreground min-w-6 text-center text-base leading-tight font-medium select-none\">\n {{ formattedHour() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-1 flex h-5 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementHour(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"16\" />\n </button>\n </div>\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground text-base font-medium\">:</span>\n }\n <!-- Minute -->\n @if (zShowMinute()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-9 cursor-pointer flex-col items-center gap-0 rounded px-1.5 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-1 flex h-5 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementMinute(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"16\" />\n </button>\n <span class=\"text-foreground min-w-6 text-center text-base leading-tight font-medium select-none\">\n {{ formattedMinute() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-1 flex h-5 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementMinute(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"16\" />\n </button>\n </div>\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground text-base font-medium\">:</span>\n }\n <!-- Second -->\n @if (zShowSecond()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-9 cursor-pointer flex-col items-center gap-0 rounded px-1.5 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-1 flex h-5 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementSecond(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"16\" />\n </button>\n <span class=\"text-foreground min-w-6 text-center text-base leading-tight font-medium select-none\">\n {{ formattedSecond() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-1 flex h-5 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementSecond(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"16\" />\n </button>\n </div>\n }\n <!-- AM/PM Toggle -->\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n class=\"bg-primary/10 text-primary hover:bg-primary/20 active:bg-primary/30 ml-1 flex w-10 cursor-pointer items-center justify-center rounded border-none px-2.5 py-1.5 text-sm font-semibold transition-colors\"\n (click)=\"togglePeriod(); $event.stopPropagation()\">\n {{ period() }}\n </button>\n }\n </div>\n </div>\n </div>\n }\n\n @if (!(zQuickSelect() && zMode() === 'range' && !showOkButton() && !showCancelButton())) {\n <div class=\"border-border flex w-full items-center justify-between gap-2 border-t pt-2\">\n @if (!zQuickSelect() || zMode() !== 'range') {\n <button type=\"button\" z-button zType=\"secondary\" zSize=\"sm\" [zWave]=\"false\" (click)=\"onTodayClick()\">\n {{ todayButtonText() }}\n </button>\n } @else {\n <div></div>\n }\n\n @if (showOkButton() || showCancelButton()) {\n <div class=\"flex items-center gap-2\">\n @if (showCancelButton()) {\n <button type=\"button\" z-button zType=\"outline\" zSize=\"sm\" (click)=\"onCancelClick()\">\n {{ zCancelText() ?? ('i18n_z_ui_calendar_cancel' | translate) }}\n </button>\n }\n @if (showOkButton()) {\n <button type=\"button\" z-button zSize=\"sm\" [zDisabled]=\"!canApply()\" (click)=\"onOkClick()\">\n {{ zOkText() ?? ('i18n_z_ui_calendar_ok' | translate) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #timeDropdownTpl>\n <div class=\"bg-popover flex overflow-hidden rounded-[6px]\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond()\"\n [class.border-border]=\"zShowMinute() || zShowSecond()\">\n <ng-scrollbar\n class=\"z-time-scroll-hour h-[200px] w-12\"\n [class.rounded]=\"!zShowMinute() && !zShowSecond()\"\n [class.rounded-l]=\"zShowMinute() || zShowSecond()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrSelected = hr | zIsTimeSelected: displayHour();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrSelected\"\n [class.bg-primary]=\"hrSelected\"\n [class.text-primary-foreground]=\"hrSelected\"\n [class.font-medium]=\"hrSelected\"\n (click)=\"selectHour(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div class=\"flex flex-col\" [class.border-r]=\"zShowSecond()\" [class.border-border]=\"zShowSecond()\">\n <ng-scrollbar\n class=\"z-time-scroll-minute h-[200px] w-12\"\n [class.rounded]=\"!zShowHour() && !zShowSecond()\"\n [class.rounded-l]=\"!zShowHour() && zShowSecond()\"\n [class.rounded-r]=\"zShowHour() && !zShowSecond()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minSelected = min | zIsTimeSelected: minute();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minSelected\"\n [class.bg-primary]=\"minSelected\"\n [class.text-primary-foreground]=\"minSelected\"\n [class.font-medium]=\"minSelected\"\n (click)=\"selectMinute(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div class=\"flex flex-col\">\n <ng-scrollbar\n class=\"z-time-scroll-second h-[200px] w-12\"\n [class.rounded]=\"!zShowHour() && !zShowMinute()\"\n [class.rounded-r]=\"zShowHour() || zShowMinute()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secSelected = sec | zIsTimeSelected: second();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secSelected\"\n [class.bg-primary]=\"secSelected\"\n [class.text-primary-foreground]=\"secSelected\"\n [class.font-medium]=\"secSelected\"\n (click)=\"selectSecond(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #timeDropdownStartTpl>\n <div class=\"bg-popover flex overflow-hidden rounded-[6px]\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond()\"\n [class.border-border]=\"zShowMinute() || zShowSecond()\">\n <ng-scrollbar\n class=\"z-time-scroll-hour h-[200px] w-12\"\n [class.rounded]=\"!zShowMinute() && !zShowSecond()\"\n [class.rounded-l]=\"zShowMinute() || zShowSecond()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrSelected = hr | zIsTimeSelected: displayHour();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrSelected\"\n [class.bg-primary]=\"hrSelected\"\n [class.text-primary-foreground]=\"hrSelected\"\n [class.font-medium]=\"hrSelected\"\n (click)=\"selectHour(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div class=\"flex flex-col\" [class.border-r]=\"zShowSecond()\" [class.border-border]=\"zShowSecond()\">\n <ng-scrollbar\n class=\"z-time-scroll-minute h-[200px] w-12\"\n [class.rounded]=\"!zShowHour() && !zShowSecond()\"\n [class.rounded-l]=\"!zShowHour() && zShowSecond()\"\n [class.rounded-r]=\"zShowHour() && !zShowSecond()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minSelected = min | zIsTimeSelected: minute();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minSelected\"\n [class.bg-primary]=\"minSelected\"\n [class.text-primary-foreground]=\"minSelected\"\n [class.font-medium]=\"minSelected\"\n (click)=\"selectMinute(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div class=\"flex flex-col\">\n <ng-scrollbar\n class=\"z-time-scroll-second h-[200px] w-12\"\n [class.rounded]=\"!zShowHour() && !zShowMinute()\"\n [class.rounded-r]=\"zShowHour() || zShowMinute()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secSelected = sec | zIsTimeSelected: second();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secSelected\"\n [class.bg-primary]=\"secSelected\"\n [class.text-primary-foreground]=\"secSelected\"\n [class.font-medium]=\"secSelected\"\n (click)=\"selectSecond(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #timeDropdownEndTpl>\n <div class=\"bg-popover flex overflow-hidden rounded-[6px]\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond()\"\n [class.border-border]=\"zShowMinute() || zShowSecond()\">\n <ng-scrollbar\n class=\"z-time-scroll-hour-end h-[200px] w-12\"\n [class.rounded]=\"!zShowMinute() && !zShowSecond()\"\n [class.rounded-l]=\"zShowMinute() || zShowSecond()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrDisabled = hr | zIsEndHourDisabled: endTimeContext();\n @let hrEndSelected = hr | zIsTimeSelected: displayHourEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrDisabled && !hrEndSelected\"\n [class.cursor-pointer]=\"!hrDisabled\"\n [class.bg-primary]=\"hrEndSelected\"\n [class.text-primary-foreground]=\"hrEndSelected\"\n [class.font-medium]=\"hrEndSelected\"\n [class.opacity-30]=\"hrDisabled\"\n [class.cursor-not-allowed]=\"hrDisabled\"\n [disabled]=\"hrDisabled\"\n (click)=\"selectHourEnd(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div class=\"flex flex-col\" [class.border-r]=\"zShowSecond()\" [class.border-border]=\"zShowSecond()\">\n <ng-scrollbar\n class=\"z-time-scroll-minute-end h-[200px] w-12\"\n [class.rounded]=\"!zShowHour() && !zShowSecond()\"\n [class.rounded-l]=\"!zShowHour() && zShowSecond()\"\n [class.rounded-r]=\"zShowHour() && !zShowSecond()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minDisabled = min | zIsEndMinuteDisabled: endTimeContext();\n @let minEndSelected = min | zIsTimeSelected: minuteEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minDisabled && !minEndSelected\"\n [class.cursor-pointer]=\"!minDisabled\"\n [class.bg-primary]=\"minEndSelected\"\n [class.text-primary-foreground]=\"minEndSelected\"\n [class.font-medium]=\"minEndSelected\"\n [class.opacity-30]=\"minDisabled\"\n [class.cursor-not-allowed]=\"minDisabled\"\n [disabled]=\"minDisabled\"\n (click)=\"selectMinuteEnd(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div class=\"flex flex-col\">\n <ng-scrollbar\n class=\"z-time-scroll-second-end h-[200px] w-12\"\n [class.rounded]=\"!zShowHour() && !zShowMinute()\"\n [class.rounded-r]=\"zShowHour() || zShowMinute()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secDisabled = sec | zIsEndSecondDisabled: endTimeContext();\n @let secEndSelected = sec | zIsTimeSelected: secondEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secDisabled && !secEndSelected\"\n [class.cursor-pointer]=\"!secDisabled\"\n [class.bg-primary]=\"secEndSelected\"\n [class.text-primary-foreground]=\"secEndSelected\"\n [class.font-medium]=\"secEndSelected\"\n [class.opacity-30]=\"secDisabled\"\n [class.cursor-not-allowed]=\"secDisabled\"\n [disabled]=\"secDisabled\"\n (click)=\"selectSecondEnd(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n", styles: [".animate-calendar-enter{animation:z-calendar-view-enter .2s ease-out}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"], dependencies: [{ kind: "component", type: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zManualClose", "zScrollClose", "zShowArrow"], outputs: ["zShow", "zHide", "zHideStart", "zControl"], exportAs: ["zPopover"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: ZDayClassesPipe, name: "zDayClasses" }, { kind: "pipe", type: ZMonthClassesPipe, name: "zMonthClasses" }, { kind: "pipe", type: ZQuarterClassesPipe, name: "zQuarterClasses" }, { kind: "pipe", type: ZYearClassesPipe, name: "zYearClasses" }, { kind: "pipe", type: ZIsPresetDisabledPipe, name: "zIsPresetDisabled" }, { kind: "pipe", type: ZIsTimeSelectedPipe, name: "zIsTimeSelected" }, { kind: "pipe", type: ZIsEndHourDisabledPipe, name: "zIsEndHourDisabled" }, { kind: "pipe", type: ZIsEndMinuteDisabledPipe, name: "zIsEndMinuteDisabled" }, { kind: "pipe", type: ZIsEndSecondDisabledPipe, name: "zIsEndSecondDisabled" }, { kind: "pipe", type: ZIsStartMonthDisabledPipe, name: "zIsStartMonthDisabled" }, { kind: "pipe", type: ZIsEndMonthDisabledPipe, name: "zIsEndMonthDisabled" }, { kind: "pipe", type: ZIsStartYearDisabledPipe, name: "zIsStartYearDisabled" }, { kind: "pipe", type: ZIsEndYearDisabledPipe, name: "zIsEndYearDisabled" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2846
2922
|
}
|
|
2847
2923
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZCalendarComponent, decorators: [{
|
|
2848
2924
|
type: Component,
|
|
@@ -2857,6 +2933,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2857
2933
|
ZQuarterClassesPipe,
|
|
2858
2934
|
ZYearClassesPipe,
|
|
2859
2935
|
ZIsPresetDisabledPipe,
|
|
2936
|
+
ZIsTimeSelectedPipe,
|
|
2937
|
+
ZIsEndHourDisabledPipe,
|
|
2938
|
+
ZIsEndMinuteDisabledPipe,
|
|
2939
|
+
ZIsEndSecondDisabledPipe,
|
|
2940
|
+
ZIsStartMonthDisabledPipe,
|
|
2941
|
+
ZIsEndMonthDisabledPipe,
|
|
2942
|
+
ZIsStartYearDisabledPipe,
|
|
2943
|
+
ZIsEndYearDisabledPipe,
|
|
2860
2944
|
TranslatePipe,
|
|
2861
2945
|
], standalone: true, providers: [
|
|
2862
2946
|
{
|
|
@@ -2865,7 +2949,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2865
2949
|
multi: true,
|
|
2866
2950
|
},
|
|
2867
2951
|
TranslatePipe,
|
|
2868
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, exportAs: 'zCalendar', template: "<div class=\"z-calendar-wrapper flex w-full flex-col gap-2\">\n @if (zLabel()) {\n <label [for]=\"pickerId\" class=\"text-xs leading-none font-medium\" [class]=\"zLabelClass()\">\n {{ zLabel() }}\n @if (zRequired()) {\n <span class=\"text-destructive! ml-0.5\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <div\n #triggerEl\n z-popover\n [zPopoverContent]=\"calendarTpl\"\n zPosition=\"bottom-left\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"6\"\n [zDisabled]=\"isDisabled() || zReadonly()\"\n [zManualClose]=\"showCancelButton()\"\n [zScrollClose]=\"zScrollClose()\"\n zTrigger=\"click\"\n zClass=\"border-0 shadow-none bg-transparent p-0\"\n (zHideStart)=\"onPopoverHide()\"\n (zShow)=\"onPopoverShow()\"\n (zControl)=\"onPopoverControl($event)\"\n [id]=\"pickerId\"\n [class]=\"triggerClasses()\"\n (keydown)=\"onTriggerKeydown($event)\">\n <z-icon\n [zType]=\"isRangeMode() ? 'lucideCalendarRange' : 'lucideCalendar'\"\n zSize=\"16\"\n class=\"text-muted-foreground shrink-0 cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggle()\" />\n\n @if (isRangeMode()) {\n <input\n type=\"text\"\n data-range-type=\"start\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_start_date' | translate\"\n [value]=\"inputDisplayStart()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onStartInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onStartInputEnter($event)\"\n (keydown.escape)=\"onStartInputEscape()\" />\n <span class=\"text-muted-foreground text-sm\">-</span>\n <input\n type=\"text\"\n data-range-type=\"end\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_end_date' | translate\"\n [value]=\"inputDisplayEnd()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onEndInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onEndInputEnter($event)\"\n (keydown.escape)=\"onEndInputEscape()\" />\n } @else {\n <input\n #inputEl\n type=\"text\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-sm outline-none\"\n [placeholder]=\"zPlaceholder()\"\n [value]=\"inputDisplayValue()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onInputEnter($event)\"\n (keydown.escape)=\"onInputEscape()\" />\n }\n\n @if (zAllowClear() && !isDisabled() && !zReadonly()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"text-muted-foreground hover:text-foreground flex size-5 shrink-0 cursor-pointer items-center justify-center rounded transition-all\"\n [class.opacity-0]=\"!hasValue()\"\n [class.pointer-events-none]=\"!hasValue()\"\n (click)=\"onClear($event)\">\n <z-icon zType=\"lucideX\" zSize=\"14\" />\n </button>\n }\n </div>\n </div>\n\n @if (showError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n</div>\n\n<ng-template #calendarTpl>\n <div\n class=\"z-calendar-calendar bg-popover border-border flex max-h-[90vh] max-w-[95vw] flex-col overflow-auto rounded-[6px] border shadow-lg sm:max-h-none sm:max-w-none sm:flex-row sm:overflow-visible\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div\n class=\"border-border flex shrink-0 flex-row gap-1 overflow-x-auto border-b p-2 sm:flex-col sm:gap-0 sm:space-y-1 sm:overflow-x-visible sm:border-r sm:border-b-0\">\n @for (preset of quickSelectPresets; track preset.key) {\n @let presetDisabled = preset | zIsPresetDisabled: zDisabledDate();\n <button\n type=\"button\"\n class=\"cursor-pointer rounded-[4px] px-3 py-1.5 text-left text-sm whitespace-nowrap transition-colors\"\n [class.hover:bg-muted]=\"activePresetKey() !== preset.key && !presetDisabled\"\n [class.bg-primary]=\"activePresetKey() === preset.key\"\n [class.text-primary-foreground]=\"activePresetKey() === preset.key\"\n [class.font-medium]=\"activePresetKey() === preset.key\"\n [class.opacity-40]=\"presetDisabled\"\n [class.cursor-not-allowed]=\"presetDisabled\"\n [disabled]=\"presetDisabled\"\n (click)=\"onQuickSelect(preset)\">\n {{ preset.label }}\n </button>\n }\n </div>\n }\n <div class=\"flex flex-1 flex-col gap-2 overflow-auto p-3 sm:overflow-visible\">\n @if (!isTimeMode()) {\n <div class=\"z-calendars-wrapper flex flex-col items-start gap-3 sm:flex-row sm:gap-0\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex flex-col gap-1\">\n @if (!isTimeMode()) {\n <div class=\"flex w-full items-center justify-between space-x-1\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePrevious()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePreviousFast()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0.5\">\n @if (!isYearMode() && !isQuarterMode()) {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"w-20 px-2!\"\n [zWave]=\"false\"\n [zDisabled]=\"false\"\n (click)=\"setView('month')\">\n {{ currentMonthName() }}\n </button>\n }\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"px-2!\"\n [zWave]=\"false\"\n [zDisabled]=\"isYearMode()\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNextFast()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNext()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"16\" />\n </button>\n </div>\n\n <div class=\"z-calendar-views w-full\" [class.z-calendar-views-quarter]=\"isQuarterMode()\">\n @if (currentView() === 'day') {\n <div class=\"flex h-full w-full flex-col gap-1\" [class.z-calendar-animate]=\"hasViewChanged()\">\n <div class=\"grid w-full grid-cols-7\">\n @for (weekday of weekdayNames; track weekday) {\n <div class=\"text-muted-foreground flex h-7 items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n @for (week of calendarDays(); track $index) {\n <div class=\"grid w-full grid-cols-7\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'month') {\n <div class=\"grid h-full w-full grid-cols-3 grid-rows-4\" [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let monthDisabled = isStartMonthDisabled(i);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: currentMonthIndex()\"\n [disabled]=\"monthDisabled\"\n [class.opacity-30]=\"monthDisabled\"\n [class.cursor-not-allowed]=\"monthDisabled\"\n (click)=\"onMonthSelect(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 gap-0.5\"\n [class.grid-rows-4]=\"!isYearMode() && !isQuarterMode()\"\n [class.grid-rows-3]=\"isYearMode() || isQuarterMode()\"\n [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (year of isYearMode() || isQuarterMode() ? yearRangeSmall() : yearRange(); track year) {\n @let yearDisabled = isStartYearDisabled(year);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: currentYear()\"\n [disabled]=\"yearDisabled\"\n [class.opacity-30]=\"yearDisabled\"\n [class.cursor-not-allowed]=\"yearDisabled\"\n (click)=\"onYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'quarter') {\n <div class=\"grid w-full grid-cols-2 gap-2\" [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (quarter of quarterNames; track quarter; let i = $index) {\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zQuarterClasses: currentQuarterIndex()\"\n (click)=\"onQuarterClick(i)\">\n {{ quarter }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time Picker Side Panel (for single date with showTime) -->\n @if (!isRangeMode() && zShowTime() && currentView() === 'day') {\n <div\n class=\"border-border mt-3 flex w-full flex-col items-center border-t pt-3 sm:mt-0 sm:w-auto sm:border-t-0 sm:border-l sm:pt-0 sm:pl-3\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_time' | translate }}\n </div>\n <div class=\"flex flex-col items-center gap-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[140px] w-12 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[140px] w-12 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[140px] w-12 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex w-full gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div class=\"border-border bg-border hidden self-stretch sm:mx-3 sm:block sm:w-px\"></div>\n <div class=\"border-border bg-border block h-px w-full sm:hidden\"></div>\n\n <div class=\"z-calendar-section flex flex-col gap-1\">\n <div class=\"flex w-full items-center justify-between space-x-1\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0.5\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"w-20 px-2!\"\n [zWave]=\"false\"\n (click)=\"setEndView('month')\">\n {{ endMonthName() }}\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"px-2!\"\n [zWave]=\"false\"\n (click)=\"setEndView('year')\">\n {{ endMonthYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"16\" />\n </button>\n </div>\n\n <div class=\"z-calendar-views w-full\">\n @if (endView() === 'day') {\n <div class=\"flex h-full w-full flex-col gap-1\" [class.z-calendar-animate]=\"hasEndViewChanged()\">\n <div class=\"grid grid-cols-7 gap-px\">\n @for (weekday of weekdayNames; track weekday) {\n <div class=\"text-muted-foreground flex h-8 w-8 items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n @for (week of calendarDaysEnd(); track $index) {\n <div class=\"grid grid-cols-7 gap-px\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (endView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4\"\n [class.z-calendar-animate]=\"hasEndViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let endMonthDisabled = isEndMonthDisabled(i);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: endMonth().getMonth()\"\n [disabled]=\"endMonthDisabled\"\n [class.opacity-30]=\"endMonthDisabled\"\n [class.cursor-not-allowed]=\"endMonthDisabled\"\n (click)=\"onEndMonthClick(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (endView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-0.5\"\n [class.z-calendar-animate]=\"hasEndViewChanged()\">\n @for (year of endYearRange(); track year) {\n @let endYearDisabled = isEndYearDisabled(year);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: endMonth().getFullYear()\"\n [disabled]=\"endYearDisabled\"\n [class.opacity-30]=\"endYearDisabled\"\n [class.cursor-not-allowed]=\"endYearDisabled\"\n (click)=\"onEndYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Range Mode Time Picker Side Panel -->\n @if (isRangeMode() && zShowTime() && currentView() === 'day' && endView() === 'day') {\n <div\n class=\"border-border mt-3 flex w-full flex-row justify-center gap-3 border-t pt-3 sm:mt-0 sm:w-auto sm:border-t-0 sm:border-l sm:pt-0 sm:pl-3\">\n <!-- Start Time -->\n <div class=\"flex flex-col\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_start' | translate }}\n </div>\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 flex-1 cursor-pointer items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 flex-1 cursor-pointer items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n\n <!-- End Time -->\n <div class=\"flex flex-col\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_end' | translate }}\n </div>\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n @let hourDisabled = isEndHourDisabled(hour);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!hourDisabled\"\n [class.cursor-pointer]=\"!hourDisabled\"\n [class.bg-primary]=\"isHourEndSelected(hour)\"\n [class.text-primary-foreground]=\"isHourEndSelected(hour)\"\n [class.font-medium]=\"isHourEndSelected(hour)\"\n [class.opacity-30]=\"hourDisabled\"\n [class.cursor-not-allowed]=\"hourDisabled\"\n [disabled]=\"hourDisabled\"\n (click)=\"selectHourEnd(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n @let minuteDisabled = isEndMinuteDisabled(minute);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!minuteDisabled\"\n [class.cursor-pointer]=\"!minuteDisabled\"\n [class.bg-primary]=\"isMinuteEndSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteEndSelected(minute)\"\n [class.font-medium]=\"isMinuteEndSelected(minute)\"\n [class.opacity-30]=\"minuteDisabled\"\n [class.cursor-not-allowed]=\"minuteDisabled\"\n [disabled]=\"minuteDisabled\"\n (click)=\"selectMinuteEnd(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n @let secondDisabled = isEndSecondDisabled(second);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!secondDisabled\"\n [class.cursor-pointer]=\"!secondDisabled\"\n [class.bg-primary]=\"isSecondEndSelected(second)\"\n [class.text-primary-foreground]=\"isSecondEndSelected(second)\"\n [class.font-medium]=\"isSecondEndSelected(second)\"\n [class.opacity-30]=\"secondDisabled\"\n [class.cursor-not-allowed]=\"secondDisabled\"\n [disabled]=\"secondDisabled\"\n (click)=\"selectSecondEnd(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex gap-1\">\n @let amDisabled = isEndPeriodDisabled('AM');\n <button\n type=\"button\"\n class=\"flex h-6 flex-1 items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.hover:bg-muted]=\"!amDisabled\"\n [class.cursor-pointer]=\"!amDisabled\"\n [class.bg-primary]=\"periodEnd() === 'AM'\"\n [class.text-primary-foreground]=\"periodEnd() === 'AM'\"\n [class.opacity-30]=\"amDisabled\"\n [class.cursor-not-allowed]=\"amDisabled\"\n [disabled]=\"amDisabled\"\n (click)=\"selectPeriodEnd('AM')\">\n AM\n </button>\n @let pmDisabled = isEndPeriodDisabled('PM');\n <button\n type=\"button\"\n class=\"flex h-6 flex-1 items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.hover:bg-muted]=\"!pmDisabled\"\n [class.cursor-pointer]=\"!pmDisabled\"\n [class.bg-primary]=\"periodEnd() === 'PM'\"\n [class.text-primary-foreground]=\"periodEnd() === 'PM'\"\n [class.opacity-30]=\"pmDisabled\"\n [class.cursor-not-allowed]=\"pmDisabled\"\n [disabled]=\"pmDisabled\"\n (click)=\"selectPeriodEnd('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"flex flex-col items-center gap-2 py-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex w-full gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n }\n\n @if (!(zQuickSelect() && zMode() === 'range' && !showOkButton() && !showCancelButton())) {\n <div class=\"border-border flex items-center justify-between gap-2 border-t pt-2\">\n @if (!zQuickSelect() || zMode() !== 'range') {\n <button type=\"button\" z-button zType=\"secondary\" zSize=\"sm\" [zWave]=\"false\" (click)=\"onTodayClick()\">\n {{ todayButtonText() }}\n </button>\n } @else {\n <div></div>\n }\n\n @if (showOkButton() || showCancelButton()) {\n <div class=\"flex items-center gap-2\">\n @if (showCancelButton()) {\n <button type=\"button\" z-button zType=\"outline\" zSize=\"sm\" (click)=\"onCancelClick()\">\n {{ zCancelText() ?? ('i18n_z_ui_calendar_cancel' | translate) }}\n </button>\n }\n @if (showOkButton()) {\n <button type=\"button\" z-button zSize=\"sm\" [zDisabled]=\"!canApply()\" (click)=\"onOkClick()\">\n {{ zOkText() ?? ('i18n_z_ui_calendar_ok' | translate) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n", styles: [".z-calendar-calendar .z-calendar-section{width:280px;flex-shrink:0}.z-calendar-calendar .z-calendar-views{height:225px;width:100%;display:flex;align-items:center;justify-content:center;flex-direction:column}.z-calendar-calendar .z-calendar-views.z-calendar-views-quarter{height:auto}.z-calendar-calendar .z-calendar-animate{animation:z-calendar-view-enter .2s ease-out}.z-time-picker{display:flex;flex-direction:column;gap:.5rem;flex-shrink:0}.z-time-picker .z-time-columns{display:flex;gap:.25rem}.z-time-picker .z-time-column{width:42px;height:180px;overflow-y:auto;scroll-snap-type:y mandatory;scroll-behavior:smooth;scrollbar-width:thin}.z-time-picker .z-time-column::-webkit-scrollbar{width:4px}.z-time-picker .z-time-column::-webkit-scrollbar-track{background:transparent}.z-time-picker .z-time-column::-webkit-scrollbar-thumb{background-color:hsl(var(--border));border-radius:2px}.z-time-picker .z-time-item{height:32px;width:100%;display:flex;align-items:center;justify-content:center;font-size:.875rem;scroll-snap-align:center;border-radius:4px;cursor:pointer;transition:background-color .15s ease,color .15s ease}.z-time-picker .z-time-item:hover:not(.z-time-item-selected){background-color:hsl(var(--muted))}.z-time-picker .z-time-item.z-time-item-selected{background-color:hsl(var(--primary));color:hsl(var(--primary-foreground));font-weight:500}.z-time-picker .z-time-item:focus-visible{outline:2px solid hsl(var(--ring));outline-offset:-2px}.z-time-picker .z-time-period-buttons{display:flex;flex-direction:column;gap:.25rem;padding-top:8px}.z-time-picker .z-time-period-buttons button{height:28px;font-size:.75rem;border-radius:4px;transition:background-color .15s ease,color .15s ease}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"] }]
|
|
2952
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, exportAs: 'zCalendar', template: "<div class=\"z-calendar-wrapper flex w-full flex-col gap-2\">\n @if (zLabel()) {\n <label [for]=\"pickerId\" class=\"text-xs leading-none font-medium\" [class]=\"zLabelClass()\">\n {{ zLabel() }}\n @if (zRequired()) {\n <span class=\"text-destructive! ml-0.5\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <div\n #triggerEl\n z-popover\n [zPopoverContent]=\"calendarTpl\"\n zPosition=\"bottom-left\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"6\"\n [zDisabled]=\"isDisabled() || zReadonly()\"\n [zManualClose]=\"showCancelButton()\"\n [zScrollClose]=\"zScrollClose()\"\n zTrigger=\"click\"\n zClass=\"border-0 shadow-none bg-transparent p-0\"\n (zHideStart)=\"onPopoverHide()\"\n (zShow)=\"onPopoverShow()\"\n (zControl)=\"onPopoverControl($event)\"\n [id]=\"pickerId\"\n [class]=\"triggerClasses()\"\n (keydown)=\"onTriggerKeydown($event)\">\n <z-icon\n [zType]=\"isRangeMode() ? 'lucideCalendarRange' : 'lucideCalendar'\"\n zSize=\"16\"\n class=\"text-muted-foreground shrink-0 cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggle()\" />\n\n @if (isRangeMode()) {\n <input\n type=\"text\"\n data-range-type=\"start\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_start_date' | translate\"\n [value]=\"inputDisplayStart()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onStartInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onStartInputEnter($event)\"\n (keydown.escape)=\"onStartInputEscape()\" />\n <span class=\"text-muted-foreground text-sm\">-</span>\n <input\n type=\"text\"\n data-range-type=\"end\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_end_date' | translate\"\n [value]=\"inputDisplayEnd()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onEndInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onEndInputEnter($event)\"\n (keydown.escape)=\"onEndInputEscape()\" />\n } @else {\n <input\n #inputEl\n type=\"text\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-sm outline-none\"\n [placeholder]=\"zPlaceholder()\"\n [value]=\"inputDisplayValue()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onInputEnter($event)\"\n (keydown.escape)=\"onInputEscape()\" />\n }\n\n @if (zAllowClear() && !isDisabled() && !zReadonly()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"text-muted-foreground hover:text-foreground flex size-5 shrink-0 cursor-pointer items-center justify-center rounded transition-all\"\n [class.opacity-0]=\"!hasValue()\"\n [class.pointer-events-none]=\"!hasValue()\"\n (click)=\"onClear($event)\">\n <z-icon zType=\"lucideX\" zSize=\"14\" />\n </button>\n }\n </div>\n </div>\n\n @if (showError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n</div>\n\n<ng-template #calendarTpl>\n <div\n class=\"z-calendar-calendar bg-popover border-border flex max-h-[90vh] max-w-[95vw] flex-col overflow-auto rounded-[6px] border shadow-lg sm:max-h-none sm:max-w-none sm:flex-row sm:overflow-visible\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div\n class=\"border-border flex shrink-0 flex-row gap-1 overflow-x-auto border-b p-2 sm:flex-col sm:gap-0 sm:space-y-1 sm:overflow-x-visible sm:border-r sm:border-b-0\">\n @for (preset of quickSelectPresets; track preset.key) {\n @let presetDisabled = preset | zIsPresetDisabled: zDisabledDate();\n <button\n type=\"button\"\n class=\"cursor-pointer rounded-[4px] px-3 py-1.5 text-left text-sm whitespace-nowrap transition-colors\"\n [class.hover:bg-muted]=\"activePresetKey() !== preset.key && !presetDisabled\"\n [class.bg-primary]=\"activePresetKey() === preset.key\"\n [class.text-primary-foreground]=\"activePresetKey() === preset.key\"\n [class.font-medium]=\"activePresetKey() === preset.key\"\n [class.opacity-40]=\"presetDisabled\"\n [class.cursor-not-allowed]=\"presetDisabled\"\n [disabled]=\"presetDisabled\"\n (click)=\"onQuickSelect(preset)\">\n {{ preset.label }}\n </button>\n }\n </div>\n }\n <div\n class=\"flex flex-1 flex-col items-center overflow-auto p-2 sm:overflow-visible\"\n [class]=\"!isRangeMode() ? 'w-[280px]' : ''\">\n @if (!isTimeMode()) {\n <div\n class=\"z-calendars-wrapper flex w-full flex-col items-center gap-3 sm:flex-row sm:items-stretch sm:justify-center sm:gap-0\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex shrink-0 flex-col\">\n @if (!isTimeMode()) {\n <!-- Header -->\n <div class=\"border-border flex w-full items-center justify-between gap-0.5 px-2\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePrevious()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"14\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePreviousFast()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"14\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0\">\n @if (!isYearMode() && !isQuarterMode()) {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n [zDisabled]=\"false\"\n (click)=\"setView('month')\">\n {{ currentMonthName() }}\n </button>\n }\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n [zDisabled]=\"isYearMode()\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNextFast()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"14\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNext()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"14\" />\n </button>\n </div>\n\n <!-- Body -->\n <div\n class=\"flex h-full w-full flex-col items-center justify-center p-2\"\n [class.min-h-[224px]]=\"!isQuarterMode()\"\n [class.h-[224px]]=\"\n !isYearMode() &&\n !isMonthMode() &&\n !isQuarterMode() &&\n (currentView() === 'month' || currentView() === 'year')\n \"\n [class.min-h-[100px]]=\"isQuarterMode()\"\n [class.!min-h-auto]=\"isYearMode() || isMonthMode() || isQuarterMode()\"\n [class.!h-auto]=\"isYearMode() || isMonthMode() || isQuarterMode()\">\n @if (currentView() === 'day') {\n <div\n class=\"flex h-full w-full flex-1 flex-col gap-1\"\n [class.animate-calendar-enter]=\"hasViewChanged()\">\n <!-- Weekday headers -->\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (weekday of weekdayNames; track weekday) {\n <div\n class=\"text-muted-foreground flex w-[33px] items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n <!-- Date rows -->\n @for (week of calendarDays(); track $index) {\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n class=\"!w-[33px] !text-sm\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (currentView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"hasViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let monthDisabled = i | zIsStartMonthDisabled: startMonthDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: selectedMonthIndex() : todayMonthIndex()\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"monthDisabled\"\n [class.opacity-30]=\"monthDisabled\"\n [class.cursor-not-allowed]=\"monthDisabled\"\n (click)=\"onMonthSelect(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"hasViewChanged()\">\n @for (year of yearRange(); track year) {\n @let yearDisabled = year | zIsStartYearDisabled: startYearDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: selectedYear() : todayYear()\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"yearDisabled\"\n [class.opacity-30]=\"yearDisabled\"\n [class.cursor-not-allowed]=\"yearDisabled\"\n (click)=\"onYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'quarter') {\n <div\n class=\"grid h-full w-full grid-cols-2 grid-rows-2 gap-2 p-1\"\n [class.animate-calendar-enter]=\"hasViewChanged()\">\n @for (quarter of quarterNames; track quarter; let i = $index) {\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zQuarterClasses: selectedQuarterIndex() : todayQuarterIndex()\"\n class=\"!h-8 !w-full !text-sm\"\n (click)=\"onQuarterClick(i)\">\n {{ quarter }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div class=\"border-border bg-border hidden self-stretch sm:mx-2 sm:block sm:w-px\"></div>\n <div class=\"border-border bg-border block h-px w-full sm:hidden\"></div>\n\n <div class=\"z-calendar-section flex shrink-0 flex-col\">\n <!-- Header -->\n <div class=\"border-border flex w-full items-center justify-between gap-0.5 px-2\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"14\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"14\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setEndView('month')\">\n {{ endMonthName() }}\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setEndView('year')\">\n {{ endMonthYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"14\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"14\" />\n </button>\n </div>\n\n <!-- Body -->\n <div\n class=\"flex h-full min-h-[224px] w-full flex-col items-center justify-center p-2\"\n [class.h-[224px]]=\"endView() === 'month' || endView() === 'year'\">\n @if (endView() === 'day') {\n <div\n class=\"flex h-full w-full flex-1 flex-col gap-1\"\n [class.animate-calendar-enter]=\"hasEndViewChanged()\">\n <!-- Weekday headers -->\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (weekday of weekdayNames; track weekday) {\n <div\n class=\"text-muted-foreground flex w-[33px] items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n <!-- Date rows -->\n @for (week of calendarDaysEnd(); track $index) {\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n class=\"!w-[33px] !text-sm\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (endView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"hasEndViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let endMonthDisabled = i | zIsEndMonthDisabled: endMonthDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: endMonth().getMonth() : -1\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"endMonthDisabled\"\n [class.opacity-30]=\"endMonthDisabled\"\n [class.cursor-not-allowed]=\"endMonthDisabled\"\n (click)=\"onEndMonthClick(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (endView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"hasEndViewChanged()\">\n @for (year of endYearRange(); track year) {\n @let endYearDisabled = year | zIsEndYearDisabled: endYearDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: endMonth().getFullYear() : -1\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"endYearDisabled\"\n [class.opacity-30]=\"endYearDisabled\"\n [class.cursor-not-allowed]=\"endYearDisabled\"\n (click)=\"onEndYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Compact Time Picker Below Calendar (Single Date) -->\n @if (!isRangeMode() && zShowTime()) {\n <div class=\"border-border w-full border-t text-center\">\n <div\n class=\"hover:bg-muted my-1 inline-flex cursor-pointer items-center rounded-sm px-2 py-1 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownTpl\"\n zPosition=\"bottom\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-md\"\n (zShow)=\"onTimeDropdownShow()\">\n <div class=\"flex items-center justify-center gap-1\">\n <!-- Hour -->\n @if (zShowHour()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementHour(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedHour() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementHour(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground text-sm font-medium\">:</span>\n }\n <!-- Minute -->\n @if (zShowMinute()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementMinute(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedMinute() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementMinute(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground text-sm font-medium\">:</span>\n }\n <!-- Second -->\n @if (zShowSecond()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementSecond(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedSecond() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementSecond(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n <!-- AM/PM Toggle -->\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n class=\"bg-primary/10 text-primary hover:bg-primary/20 active:bg-primary/30 ml-1 flex w-8 cursor-pointer items-center justify-center rounded border-none px-2 py-1 text-xs font-semibold transition-colors\"\n (click)=\"togglePeriod(); $event.stopPropagation()\">\n {{ period() }}\n </button>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Compact Time Pickers Below Calendars (Range Mode) -->\n @if (isRangeMode() && zShowTime()) {\n <div class=\"border-border flex w-full flex-col border-t sm:flex-row sm:gap-3\">\n <!-- Start Time -->\n <div class=\"flex w-full flex-col items-center justify-center gap-1\">\n <div\n class=\"hover:bg-muted my-1 inline-flex cursor-pointer items-center rounded-sm px-2 py-1 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownStartTpl\"\n zPosition=\"bottom\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-md\"\n (zShow)=\"onTimeDropdownShow()\">\n <div class=\"flex items-center justify-center gap-1\">\n <!-- Hour -->\n @if (zShowHour()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementHour(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedHour() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementHour(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground text-sm font-medium\">:</span>\n }\n <!-- Minute -->\n @if (zShowMinute()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementMinute(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedMinute() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementMinute(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground text-sm font-medium\">:</span>\n }\n <!-- Second -->\n @if (zShowSecond()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementSecond(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedSecond() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementSecond(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n <!-- AM/PM Toggle -->\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n class=\"bg-primary/10 text-primary hover:bg-primary/20 active:bg-primary/30 ml-1 flex w-8 cursor-pointer items-center justify-center rounded border-none px-2 py-1 text-xs font-semibold transition-colors\"\n (click)=\"togglePeriod(); $event.stopPropagation()\">\n {{ period() }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Divider space -->\n <div class=\"border-border bg-border h-px self-stretch sm:mx-2 sm:block sm:h-full sm:w-px\"></div>\n\n <!-- End Time -->\n <div class=\"flex w-full flex-col items-center justify-center gap-1\">\n <div\n class=\"hover:bg-muted my-1 inline-flex cursor-pointer items-center rounded-sm px-2 py-1 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownEndTpl\"\n zPosition=\"bottom\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-md\"\n (zShow)=\"onTimeDropdownEndShow()\">\n <div class=\"flex items-center justify-center gap-1\">\n <!-- Hour -->\n @if (zShowHour()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementHourEnd(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedHourEnd() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementHourEnd(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground text-sm font-medium\">:</span>\n }\n <!-- Minute -->\n @if (zShowMinute()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementMinuteEnd(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedMinuteEnd() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementMinuteEnd(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground text-sm font-medium\">:</span>\n }\n <!-- Second -->\n @if (zShowSecond()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-7 cursor-pointer flex-col items-center gap-0 rounded px-1 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementSecondEnd(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n </button>\n <span class=\"text-foreground min-w-5 text-center text-sm leading-tight font-medium select-none\">\n {{ formattedSecondEnd() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-0.5 flex h-4 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementSecondEnd(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" />\n </button>\n </div>\n }\n <!-- AM/PM Toggle -->\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n class=\"bg-primary/10 text-primary hover:bg-primary/20 active:bg-primary/30 ml-1 flex w-8 cursor-pointer items-center justify-center rounded border-none px-2 py-1 text-xs font-semibold transition-colors\"\n (click)=\"togglePeriodEnd(); $event.stopPropagation()\">\n {{ periodEnd() }}\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n }\n } @else {\n <!-- Time Only Mode - Compact Display -->\n <div class=\"flex flex-col items-center gap-3 pb-2\">\n <div\n class=\"hover:bg-muted inline-flex cursor-pointer items-center rounded-md px-3 py-2 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownTpl\"\n zPosition=\"bottom\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-md\"\n (zShow)=\"onTimeDropdownShow()\">\n <div class=\"flex items-center justify-center gap-1.5\">\n <!-- Hour -->\n @if (zShowHour()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-9 cursor-pointer flex-col items-center gap-0 rounded px-1.5 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-1 flex h-5 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementHour(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"16\" />\n </button>\n <span class=\"text-foreground min-w-6 text-center text-base leading-tight font-medium select-none\">\n {{ formattedHour() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-1 flex h-5 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementHour(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"16\" />\n </button>\n </div>\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground text-base font-medium\">:</span>\n }\n <!-- Minute -->\n @if (zShowMinute()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-9 cursor-pointer flex-col items-center gap-0 rounded px-1.5 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-1 flex h-5 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementMinute(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"16\" />\n </button>\n <span class=\"text-foreground min-w-6 text-center text-base leading-tight font-medium select-none\">\n {{ formattedMinute() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-1 flex h-5 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementMinute(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"16\" />\n </button>\n </div>\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground text-base font-medium\">:</span>\n }\n <!-- Second -->\n @if (zShowSecond()) {\n <div\n class=\"hover:bg-muted/50 flex min-w-9 cursor-pointer flex-col items-center gap-0 rounded px-1.5 transition-colors\">\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mb-1 flex h-5 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"decrementSecond(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"16\" />\n </button>\n <span class=\"text-foreground min-w-6 text-center text-base leading-tight font-medium select-none\">\n {{ formattedSecond() }}\n </span>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground active:bg-accent mt-1 flex h-5 w-full cursor-pointer items-center justify-center rounded border-none bg-transparent transition-colors\"\n (click)=\"incrementSecond(); $event.stopPropagation()\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"16\" />\n </button>\n </div>\n }\n <!-- AM/PM Toggle -->\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n class=\"bg-primary/10 text-primary hover:bg-primary/20 active:bg-primary/30 ml-1 flex w-10 cursor-pointer items-center justify-center rounded border-none px-2.5 py-1.5 text-sm font-semibold transition-colors\"\n (click)=\"togglePeriod(); $event.stopPropagation()\">\n {{ period() }}\n </button>\n }\n </div>\n </div>\n </div>\n }\n\n @if (!(zQuickSelect() && zMode() === 'range' && !showOkButton() && !showCancelButton())) {\n <div class=\"border-border flex w-full items-center justify-between gap-2 border-t pt-2\">\n @if (!zQuickSelect() || zMode() !== 'range') {\n <button type=\"button\" z-button zType=\"secondary\" zSize=\"sm\" [zWave]=\"false\" (click)=\"onTodayClick()\">\n {{ todayButtonText() }}\n </button>\n } @else {\n <div></div>\n }\n\n @if (showOkButton() || showCancelButton()) {\n <div class=\"flex items-center gap-2\">\n @if (showCancelButton()) {\n <button type=\"button\" z-button zType=\"outline\" zSize=\"sm\" (click)=\"onCancelClick()\">\n {{ zCancelText() ?? ('i18n_z_ui_calendar_cancel' | translate) }}\n </button>\n }\n @if (showOkButton()) {\n <button type=\"button\" z-button zSize=\"sm\" [zDisabled]=\"!canApply()\" (click)=\"onOkClick()\">\n {{ zOkText() ?? ('i18n_z_ui_calendar_ok' | translate) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #timeDropdownTpl>\n <div class=\"bg-popover flex overflow-hidden rounded-[6px]\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond()\"\n [class.border-border]=\"zShowMinute() || zShowSecond()\">\n <ng-scrollbar\n class=\"z-time-scroll-hour h-[200px] w-12\"\n [class.rounded]=\"!zShowMinute() && !zShowSecond()\"\n [class.rounded-l]=\"zShowMinute() || zShowSecond()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrSelected = hr | zIsTimeSelected: displayHour();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrSelected\"\n [class.bg-primary]=\"hrSelected\"\n [class.text-primary-foreground]=\"hrSelected\"\n [class.font-medium]=\"hrSelected\"\n (click)=\"selectHour(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div class=\"flex flex-col\" [class.border-r]=\"zShowSecond()\" [class.border-border]=\"zShowSecond()\">\n <ng-scrollbar\n class=\"z-time-scroll-minute h-[200px] w-12\"\n [class.rounded]=\"!zShowHour() && !zShowSecond()\"\n [class.rounded-l]=\"!zShowHour() && zShowSecond()\"\n [class.rounded-r]=\"zShowHour() && !zShowSecond()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minSelected = min | zIsTimeSelected: minute();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minSelected\"\n [class.bg-primary]=\"minSelected\"\n [class.text-primary-foreground]=\"minSelected\"\n [class.font-medium]=\"minSelected\"\n (click)=\"selectMinute(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div class=\"flex flex-col\">\n <ng-scrollbar\n class=\"z-time-scroll-second h-[200px] w-12\"\n [class.rounded]=\"!zShowHour() && !zShowMinute()\"\n [class.rounded-r]=\"zShowHour() || zShowMinute()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secSelected = sec | zIsTimeSelected: second();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secSelected\"\n [class.bg-primary]=\"secSelected\"\n [class.text-primary-foreground]=\"secSelected\"\n [class.font-medium]=\"secSelected\"\n (click)=\"selectSecond(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #timeDropdownStartTpl>\n <div class=\"bg-popover flex overflow-hidden rounded-[6px]\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond()\"\n [class.border-border]=\"zShowMinute() || zShowSecond()\">\n <ng-scrollbar\n class=\"z-time-scroll-hour h-[200px] w-12\"\n [class.rounded]=\"!zShowMinute() && !zShowSecond()\"\n [class.rounded-l]=\"zShowMinute() || zShowSecond()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrSelected = hr | zIsTimeSelected: displayHour();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrSelected\"\n [class.bg-primary]=\"hrSelected\"\n [class.text-primary-foreground]=\"hrSelected\"\n [class.font-medium]=\"hrSelected\"\n (click)=\"selectHour(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div class=\"flex flex-col\" [class.border-r]=\"zShowSecond()\" [class.border-border]=\"zShowSecond()\">\n <ng-scrollbar\n class=\"z-time-scroll-minute h-[200px] w-12\"\n [class.rounded]=\"!zShowHour() && !zShowSecond()\"\n [class.rounded-l]=\"!zShowHour() && zShowSecond()\"\n [class.rounded-r]=\"zShowHour() && !zShowSecond()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minSelected = min | zIsTimeSelected: minute();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minSelected\"\n [class.bg-primary]=\"minSelected\"\n [class.text-primary-foreground]=\"minSelected\"\n [class.font-medium]=\"minSelected\"\n (click)=\"selectMinute(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div class=\"flex flex-col\">\n <ng-scrollbar\n class=\"z-time-scroll-second h-[200px] w-12\"\n [class.rounded]=\"!zShowHour() && !zShowMinute()\"\n [class.rounded-r]=\"zShowHour() || zShowMinute()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secSelected = sec | zIsTimeSelected: second();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secSelected\"\n [class.bg-primary]=\"secSelected\"\n [class.text-primary-foreground]=\"secSelected\"\n [class.font-medium]=\"secSelected\"\n (click)=\"selectSecond(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #timeDropdownEndTpl>\n <div class=\"bg-popover flex overflow-hidden rounded-[6px]\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond()\"\n [class.border-border]=\"zShowMinute() || zShowSecond()\">\n <ng-scrollbar\n class=\"z-time-scroll-hour-end h-[200px] w-12\"\n [class.rounded]=\"!zShowMinute() && !zShowSecond()\"\n [class.rounded-l]=\"zShowMinute() || zShowSecond()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrDisabled = hr | zIsEndHourDisabled: endTimeContext();\n @let hrEndSelected = hr | zIsTimeSelected: displayHourEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrDisabled && !hrEndSelected\"\n [class.cursor-pointer]=\"!hrDisabled\"\n [class.bg-primary]=\"hrEndSelected\"\n [class.text-primary-foreground]=\"hrEndSelected\"\n [class.font-medium]=\"hrEndSelected\"\n [class.opacity-30]=\"hrDisabled\"\n [class.cursor-not-allowed]=\"hrDisabled\"\n [disabled]=\"hrDisabled\"\n (click)=\"selectHourEnd(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div class=\"flex flex-col\" [class.border-r]=\"zShowSecond()\" [class.border-border]=\"zShowSecond()\">\n <ng-scrollbar\n class=\"z-time-scroll-minute-end h-[200px] w-12\"\n [class.rounded]=\"!zShowHour() && !zShowSecond()\"\n [class.rounded-l]=\"!zShowHour() && zShowSecond()\"\n [class.rounded-r]=\"zShowHour() && !zShowSecond()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minDisabled = min | zIsEndMinuteDisabled: endTimeContext();\n @let minEndSelected = min | zIsTimeSelected: minuteEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minDisabled && !minEndSelected\"\n [class.cursor-pointer]=\"!minDisabled\"\n [class.bg-primary]=\"minEndSelected\"\n [class.text-primary-foreground]=\"minEndSelected\"\n [class.font-medium]=\"minEndSelected\"\n [class.opacity-30]=\"minDisabled\"\n [class.cursor-not-allowed]=\"minDisabled\"\n [disabled]=\"minDisabled\"\n (click)=\"selectMinuteEnd(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div class=\"flex flex-col\">\n <ng-scrollbar\n class=\"z-time-scroll-second-end h-[200px] w-12\"\n [class.rounded]=\"!zShowHour() && !zShowMinute()\"\n [class.rounded-r]=\"zShowHour() || zShowMinute()\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secDisabled = sec | zIsEndSecondDisabled: endTimeContext();\n @let secEndSelected = sec | zIsTimeSelected: secondEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secDisabled && !secEndSelected\"\n [class.cursor-pointer]=\"!secDisabled\"\n [class.bg-primary]=\"secEndSelected\"\n [class.text-primary-foreground]=\"secEndSelected\"\n [class.font-medium]=\"secEndSelected\"\n [class.opacity-30]=\"secDisabled\"\n [class.cursor-not-allowed]=\"secDisabled\"\n [disabled]=\"secDisabled\"\n (click)=\"selectSecondEnd(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n", styles: [".animate-calendar-enter{animation:z-calendar-view-enter .2s ease-out}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"] }]
|
|
2869
2953
|
}], ctorParameters: () => [], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], zMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMode", required: false }] }], zSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSize", required: false }] }], zLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLabel", required: false }] }], zLabelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLabelClass", required: false }] }], zPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "zPlaceholder", required: false }] }], zRequired: [{ type: i0.Input, args: [{ isSignal: true, alias: "zRequired", required: false }] }], zDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDisabled", required: false }] }], zReadonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "zReadonly", required: false }] }], zShowTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowTime", required: false }] }], zTimeFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "zTimeFormat", required: false }] }], zShowHour: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowHour", required: false }] }], zShowMinute: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowMinute", required: false }] }], zShowSecond: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowSecond", required: false }] }], zQuickSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "zQuickSelect", required: false }] }], zAllowClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "zAllowClear", required: false }] }], zFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "zFormat", required: false }] }], zMinDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMinDate", required: false }] }], zMaxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMaxDate", required: false }] }], zValueType: [{ type: i0.Input, args: [{ isSignal: true, alias: "zValueType", required: false }] }], zValidators: [{ type: i0.Input, args: [{ isSignal: true, alias: "zValidators", required: false }] }], zLocale: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLocale", required: false }] }], zShowOk: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowOk", required: false }] }], zOkText: [{ type: i0.Input, args: [{ isSignal: true, alias: "zOkText", required: false }] }], zShowCancel: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowCancel", required: false }] }], zCancelText: [{ type: i0.Input, args: [{ isSignal: true, alias: "zCancelText", required: false }] }], zDisabledDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDisabledDate", required: false }] }], zScrollClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "zScrollClose", required: false }] }], zControl: [{ type: i0.Output, args: ["zControl"] }], zChange: [{ type: i0.Output, args: ["zChange"] }], triggerRef: [{ type: i0.ViewChild, args: ['triggerEl', { isSignal: true }] }], inputRef: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }] } });
|
|
2870
2954
|
|
|
2871
2955
|
/**
|