@shival99/z-ui 1.3.4 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/shival99-z-ui-components-z-calendar.mjs +532 -16
- package/fesm2022/shival99-z-ui-components-z-calendar.mjs.map +1 -1
- package/fesm2022/shival99-z-ui-i18n.mjs +2 -0
- package/fesm2022/shival99-z-ui-i18n.mjs.map +1 -1
- package/package.json +1 -1
- package/types/shival99-z-ui-components-z-calendar.d.ts +40 -5
- package/types/shival99-z-ui-components-z-modal.d.ts +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DecimalPipe } from '@angular/common';
|
|
1
2
|
import * as i0 from '@angular/core';
|
|
2
3
|
import { Pipe, input, output, viewChild, computed, signal, inject, Injector, DestroyRef, ChangeDetectorRef, effect, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
4
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
@@ -8,6 +9,7 @@ import { ZIconComponent } from '@shival99/z-ui/components/z-icon';
|
|
|
8
9
|
import { ZPopoverDirective } from '@shival99/z-ui/components/z-popover';
|
|
9
10
|
import { ZTranslateService } from '@shival99/z-ui/services';
|
|
10
11
|
import { zTransform, zUuid, zMergeClasses } from '@shival99/z-ui/utils';
|
|
12
|
+
import { NgScrollbar } from 'ngx-scrollbar';
|
|
11
13
|
import { merge } from 'rxjs';
|
|
12
14
|
import { cva } from 'class-variance-authority';
|
|
13
15
|
|
|
@@ -633,6 +635,14 @@ class ZCalendarComponent {
|
|
|
633
635
|
weekdayNames = getWeekdayNames('vi-VN');
|
|
634
636
|
monthNames = getMonthNames('vi-VN');
|
|
635
637
|
quickSelectPresets = getQuickSelectPresets();
|
|
638
|
+
hourOptions = computed(() => {
|
|
639
|
+
if (this.zTimeFormat() === '12h') {
|
|
640
|
+
return Array.from({ length: 12 }, (_, i) => i + 1);
|
|
641
|
+
}
|
|
642
|
+
return Array.from({ length: 24 }, (_, i) => i);
|
|
643
|
+
}, ...(ngDevMode ? [{ debugName: "hourOptions" }] : []));
|
|
644
|
+
minuteOptions = Array.from({ length: 60 }, (_, i) => i);
|
|
645
|
+
secondOptions = Array.from({ length: 60 }, (_, i) => i);
|
|
636
646
|
formattedHour = computed(() => {
|
|
637
647
|
const h = this._hour();
|
|
638
648
|
if (this.zTimeFormat() === '12h') {
|
|
@@ -643,6 +653,20 @@ class ZCalendarComponent {
|
|
|
643
653
|
}, ...(ngDevMode ? [{ debugName: "formattedHour" }] : []));
|
|
644
654
|
formattedMinute = computed(() => formatTimeValue(this._minute()), ...(ngDevMode ? [{ debugName: "formattedMinute" }] : []));
|
|
645
655
|
formattedSecond = computed(() => formatTimeValue(this._second()), ...(ngDevMode ? [{ debugName: "formattedSecond" }] : []));
|
|
656
|
+
displayHour = computed(() => {
|
|
657
|
+
const h = this._hour();
|
|
658
|
+
if (this.zTimeFormat() === '12h') {
|
|
659
|
+
return h % 12 || 12;
|
|
660
|
+
}
|
|
661
|
+
return h;
|
|
662
|
+
}, ...(ngDevMode ? [{ debugName: "displayHour" }] : []));
|
|
663
|
+
displayHourEnd = computed(() => {
|
|
664
|
+
const h = this._hourEnd();
|
|
665
|
+
if (this.zTimeFormat() === '12h') {
|
|
666
|
+
return h % 12 || 12;
|
|
667
|
+
}
|
|
668
|
+
return h;
|
|
669
|
+
}, ...(ngDevMode ? [{ debugName: "displayHourEnd" }] : []));
|
|
646
670
|
_popoverControl = signal(null, ...(ngDevMode ? [{ debugName: "_popoverControl" }] : []));
|
|
647
671
|
_selectedDate = signal(null, ...(ngDevMode ? [{ debugName: "_selectedDate" }] : []));
|
|
648
672
|
_rangeStart = signal(null, ...(ngDevMode ? [{ debugName: "_rangeStart" }] : []));
|
|
@@ -697,6 +721,17 @@ class ZCalendarComponent {
|
|
|
697
721
|
const date = this._selectedDate();
|
|
698
722
|
return date ? Math.floor(date.getMonth() / 3) : -1;
|
|
699
723
|
}, ...(ngDevMode ? [{ debugName: "currentQuarterIndex" }] : []));
|
|
724
|
+
isSameDayRange = computed(() => {
|
|
725
|
+
if (!this.isRangeMode()) {
|
|
726
|
+
return false;
|
|
727
|
+
}
|
|
728
|
+
const start = this._rangeStart();
|
|
729
|
+
const end = this._rangeEnd();
|
|
730
|
+
if (!start || !end) {
|
|
731
|
+
return false;
|
|
732
|
+
}
|
|
733
|
+
return isSameDay(start, end);
|
|
734
|
+
}, ...(ngDevMode ? [{ debugName: "isSameDayRange" }] : []));
|
|
700
735
|
isDisabled = computed(() => this._disabled() || this.zDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
701
736
|
isRangeMode = computed(() => this.zMode() === 'range', ...(ngDevMode ? [{ debugName: "isRangeMode" }] : []));
|
|
702
737
|
canApply = computed(() => {
|
|
@@ -956,7 +991,7 @@ class ZCalendarComponent {
|
|
|
956
991
|
return '';
|
|
957
992
|
}
|
|
958
993
|
if (this.isMonthMode()) {
|
|
959
|
-
return date
|
|
994
|
+
return formatDate(date, this.zFormat());
|
|
960
995
|
}
|
|
961
996
|
if (this.isYearMode()) {
|
|
962
997
|
return date.getFullYear().toString();
|
|
@@ -972,16 +1007,16 @@ class ZCalendarComponent {
|
|
|
972
1007
|
inputDisplayStart = computed(() => this._inputDisplayStart(), ...(ngDevMode ? [{ debugName: "inputDisplayStart" }] : []));
|
|
973
1008
|
inputDisplayEnd = computed(() => this._inputDisplayEnd(), ...(ngDevMode ? [{ debugName: "inputDisplayEnd" }] : []));
|
|
974
1009
|
displayValueStart = computed(() => {
|
|
975
|
-
const format = this.
|
|
1010
|
+
const format = this._getDisplayFormatStart();
|
|
976
1011
|
const start = this._rangeStart();
|
|
977
1012
|
return start ? formatDate(start, format) : '';
|
|
978
1013
|
}, ...(ngDevMode ? [{ debugName: "displayValueStart" }] : []));
|
|
979
1014
|
displayValueEnd = computed(() => {
|
|
980
|
-
const format = this.
|
|
1015
|
+
const format = this._getDisplayFormatEnd();
|
|
981
1016
|
const end = this._rangeEnd();
|
|
982
1017
|
return end ? formatDate(end, format) : '';
|
|
983
1018
|
}, ...(ngDevMode ? [{ debugName: "displayValueEnd" }] : []));
|
|
984
|
-
|
|
1019
|
+
_getDisplayFormatStart() {
|
|
985
1020
|
let format = this.zFormat();
|
|
986
1021
|
if (this.zShowTime() || this.isTimeMode()) {
|
|
987
1022
|
const timeParts = [];
|
|
@@ -1000,6 +1035,25 @@ class ZCalendarComponent {
|
|
|
1000
1035
|
}
|
|
1001
1036
|
return format;
|
|
1002
1037
|
}
|
|
1038
|
+
_getDisplayFormatEnd() {
|
|
1039
|
+
let format = this.zFormat();
|
|
1040
|
+
if (this.zShowTime() || this.isTimeMode()) {
|
|
1041
|
+
const timeParts = [];
|
|
1042
|
+
if (this.zShowHour()) {
|
|
1043
|
+
timeParts.push(this.zTimeFormat() === '12h' ? 'hh' : 'HH');
|
|
1044
|
+
}
|
|
1045
|
+
if (this.zShowMinute()) {
|
|
1046
|
+
timeParts.push('mm');
|
|
1047
|
+
}
|
|
1048
|
+
if (this.zShowSecond()) {
|
|
1049
|
+
timeParts.push('ss');
|
|
1050
|
+
}
|
|
1051
|
+
const timeFormat = timeParts.join(':');
|
|
1052
|
+
const periodSuffix = this.zTimeFormat() === '12h' ? ` ${this._periodEnd()}` : '';
|
|
1053
|
+
format = this.isTimeMode() ? timeFormat + periodSuffix : `${this.zFormat()} ${timeFormat}${periodSuffix}`;
|
|
1054
|
+
}
|
|
1055
|
+
return format;
|
|
1056
|
+
}
|
|
1003
1057
|
showClearButton = computed(() => {
|
|
1004
1058
|
if (!this.zAllowClear() || this.isDisabled() || this.zReadonly() || this.isOpen()) {
|
|
1005
1059
|
return false;
|
|
@@ -1255,6 +1309,7 @@ class ZCalendarComponent {
|
|
|
1255
1309
|
this._inputDisplayStart.set(this.displayValueStart());
|
|
1256
1310
|
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
1257
1311
|
}
|
|
1312
|
+
this._scrollToTimeOnOpen();
|
|
1258
1313
|
if (!this.isRangeMode()) {
|
|
1259
1314
|
this._activePresetKey.set(null);
|
|
1260
1315
|
const selected = this._selectedDate();
|
|
@@ -1286,13 +1341,15 @@ class ZCalendarComponent {
|
|
|
1286
1341
|
return;
|
|
1287
1342
|
}
|
|
1288
1343
|
const now = new Date();
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1344
|
+
if (this.isRangeMode()) {
|
|
1345
|
+
const start = this._rangeStart();
|
|
1346
|
+
const end = this._rangeEnd();
|
|
1347
|
+
this._syncTimeSignals(start ?? now);
|
|
1348
|
+
this._syncEndTimeSignals(end ?? now);
|
|
1292
1349
|
return;
|
|
1293
1350
|
}
|
|
1294
|
-
const
|
|
1295
|
-
this.
|
|
1351
|
+
const selected = this._selectedDate();
|
|
1352
|
+
this._syncTimeSignals(selected ?? now);
|
|
1296
1353
|
}
|
|
1297
1354
|
_syncEndTimeSignals(date) {
|
|
1298
1355
|
const hours = date.getHours();
|
|
@@ -1342,10 +1399,24 @@ class ZCalendarComponent {
|
|
|
1342
1399
|
this._rangeStart.set(this._backupRangeStart());
|
|
1343
1400
|
this._rangeEnd.set(this._backupRangeEnd());
|
|
1344
1401
|
this._dirty.set(false);
|
|
1402
|
+
if (this.isRangeMode()) {
|
|
1403
|
+
const backupStart = this._backupRangeStart();
|
|
1404
|
+
const backupEnd = this._backupRangeEnd();
|
|
1405
|
+
if (backupStart) {
|
|
1406
|
+
this._syncTimeSignals(backupStart);
|
|
1407
|
+
}
|
|
1408
|
+
if (backupEnd) {
|
|
1409
|
+
this._syncEndTimeSignals(backupEnd);
|
|
1410
|
+
}
|
|
1411
|
+
this._inputDisplayStart.set(this.displayValueStart());
|
|
1412
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
1413
|
+
return;
|
|
1414
|
+
}
|
|
1345
1415
|
const backup = this._backupSelectedDate();
|
|
1346
1416
|
if (backup) {
|
|
1347
1417
|
this._syncTimeSignals(backup);
|
|
1348
1418
|
}
|
|
1419
|
+
this._inputDisplayValue.set(this.displayValue());
|
|
1349
1420
|
}
|
|
1350
1421
|
onPopoverControl(control) {
|
|
1351
1422
|
this._popoverControl.set(control);
|
|
@@ -1360,7 +1431,8 @@ class ZCalendarComponent {
|
|
|
1360
1431
|
return;
|
|
1361
1432
|
}
|
|
1362
1433
|
if (event.key === 'Escape' && this.isOpen()) {
|
|
1363
|
-
|
|
1434
|
+
event.preventDefault();
|
|
1435
|
+
this._cancelAndRestore();
|
|
1364
1436
|
}
|
|
1365
1437
|
}
|
|
1366
1438
|
onInputChange(event) {
|
|
@@ -1397,6 +1469,7 @@ class ZCalendarComponent {
|
|
|
1397
1469
|
this._selectedDate.set(date);
|
|
1398
1470
|
this._currentMonth.set(date);
|
|
1399
1471
|
this._syncTimeSignals(date);
|
|
1472
|
+
this._scrollToCurrentTime();
|
|
1400
1473
|
}
|
|
1401
1474
|
}
|
|
1402
1475
|
_getExpectedFormatLength(format) {
|
|
@@ -1427,6 +1500,7 @@ class ZCalendarComponent {
|
|
|
1427
1500
|
this._rangeStart.set(date);
|
|
1428
1501
|
this._currentMonth.set(date);
|
|
1429
1502
|
this._syncTimeSignals(date);
|
|
1503
|
+
this._scrollToCurrentTime();
|
|
1430
1504
|
}
|
|
1431
1505
|
onEndInputChange(event) {
|
|
1432
1506
|
const input = event.target;
|
|
@@ -1453,6 +1527,7 @@ class ZCalendarComponent {
|
|
|
1453
1527
|
this._rangeEnd.set(date);
|
|
1454
1528
|
this._endMonth.set(date);
|
|
1455
1529
|
this._syncEndTimeSignals(date);
|
|
1530
|
+
this._scrollToEndTime();
|
|
1456
1531
|
}
|
|
1457
1532
|
onStartInputEnter(event) {
|
|
1458
1533
|
event.preventDefault();
|
|
@@ -1476,7 +1551,11 @@ class ZCalendarComponent {
|
|
|
1476
1551
|
this._currentMonth.set(date);
|
|
1477
1552
|
this._syncTimeSignals(date);
|
|
1478
1553
|
this._dirty.set(true);
|
|
1554
|
+
this._inputDisplayStart.set(this.displayValueStart());
|
|
1479
1555
|
input.blur();
|
|
1556
|
+
if (this.showOkButton() && this.canApply()) {
|
|
1557
|
+
this.onOkClick();
|
|
1558
|
+
}
|
|
1480
1559
|
}
|
|
1481
1560
|
onEndInputEnter(event) {
|
|
1482
1561
|
event.preventDefault();
|
|
@@ -1500,7 +1579,11 @@ class ZCalendarComponent {
|
|
|
1500
1579
|
this._endMonth.set(date);
|
|
1501
1580
|
this._syncEndTimeSignals(date);
|
|
1502
1581
|
this._dirty.set(true);
|
|
1582
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
1503
1583
|
input.blur();
|
|
1584
|
+
if (this.showOkButton() && this.canApply()) {
|
|
1585
|
+
this.onOkClick();
|
|
1586
|
+
}
|
|
1504
1587
|
}
|
|
1505
1588
|
onInputFocus(_event) {
|
|
1506
1589
|
this._backupSelectedDate.set(this._selectedDate());
|
|
@@ -1603,15 +1686,19 @@ class ZCalendarComponent {
|
|
|
1603
1686
|
input.blur();
|
|
1604
1687
|
}
|
|
1605
1688
|
onCalendarKeydown(event) {
|
|
1606
|
-
|
|
1689
|
+
const { key, target } = event;
|
|
1690
|
+
if (key === 'Escape') {
|
|
1691
|
+
event.preventDefault();
|
|
1692
|
+
this._cancelAndRestore();
|
|
1607
1693
|
return;
|
|
1608
1694
|
}
|
|
1609
|
-
|
|
1610
|
-
if (key === 'Escape') {
|
|
1611
|
-
this.close();
|
|
1695
|
+
if (this._currentView() !== 'day') {
|
|
1612
1696
|
return;
|
|
1613
1697
|
}
|
|
1614
1698
|
if (key === 'Enter') {
|
|
1699
|
+
if (target instanceof HTMLInputElement) {
|
|
1700
|
+
return;
|
|
1701
|
+
}
|
|
1615
1702
|
if (!this.isRangeMode() || this.zShowTime()) {
|
|
1616
1703
|
this.onOkClick();
|
|
1617
1704
|
}
|
|
@@ -1663,6 +1750,7 @@ class ZCalendarComponent {
|
|
|
1663
1750
|
if (this.isYearMode()) {
|
|
1664
1751
|
this._selectedDate.set(setYear(new Date(year, 0, 1), year));
|
|
1665
1752
|
this._dirty.set(true);
|
|
1753
|
+
this._inputDisplayValue.set(this.displayValue());
|
|
1666
1754
|
this._applyValue();
|
|
1667
1755
|
this.close();
|
|
1668
1756
|
return;
|
|
@@ -1684,6 +1772,7 @@ class ZCalendarComponent {
|
|
|
1684
1772
|
const date = new Date(currentYear, firstMonthOfQuarter, 1);
|
|
1685
1773
|
this._selectedDate.set(date);
|
|
1686
1774
|
this._dirty.set(true);
|
|
1775
|
+
this._inputDisplayValue.set(this.displayValue());
|
|
1687
1776
|
this._applyValue();
|
|
1688
1777
|
this.close();
|
|
1689
1778
|
}
|
|
@@ -1692,6 +1781,7 @@ class ZCalendarComponent {
|
|
|
1692
1781
|
const currentYear = this._currentMonth().getFullYear();
|
|
1693
1782
|
this._selectedDate.set(new Date(currentYear, monthIndex, 1));
|
|
1694
1783
|
this._dirty.set(true);
|
|
1784
|
+
this._inputDisplayValue.set(this.displayValue());
|
|
1695
1785
|
this._applyValue();
|
|
1696
1786
|
this.close();
|
|
1697
1787
|
return;
|
|
@@ -1748,10 +1838,12 @@ class ZCalendarComponent {
|
|
|
1748
1838
|
this._minute.set(now.getMinutes());
|
|
1749
1839
|
this._second.set(now.getSeconds());
|
|
1750
1840
|
this._period.set(now.getHours() >= 12 ? 'PM' : 'AM');
|
|
1841
|
+
this._scrollToCurrentTime();
|
|
1751
1842
|
}
|
|
1752
1843
|
if (this.isMonthMode()) {
|
|
1753
1844
|
this._selectedDate.set(new Date(now.getFullYear(), now.getMonth(), 1));
|
|
1754
1845
|
this._dirty.set(true);
|
|
1846
|
+
this._inputDisplayValue.set(this.displayValue());
|
|
1755
1847
|
this._applyValue();
|
|
1756
1848
|
this.close();
|
|
1757
1849
|
return;
|
|
@@ -1759,6 +1851,7 @@ class ZCalendarComponent {
|
|
|
1759
1851
|
if (this.isYearMode()) {
|
|
1760
1852
|
this._selectedDate.set(new Date(now.getFullYear(), 0, 1));
|
|
1761
1853
|
this._dirty.set(true);
|
|
1854
|
+
this._inputDisplayValue.set(this.displayValue());
|
|
1762
1855
|
this._applyValue();
|
|
1763
1856
|
this.close();
|
|
1764
1857
|
return;
|
|
@@ -1767,6 +1860,7 @@ class ZCalendarComponent {
|
|
|
1767
1860
|
const currentQuarter = Math.floor(now.getMonth() / 3);
|
|
1768
1861
|
this._selectedDate.set(new Date(now.getFullYear(), currentQuarter * 3, 1));
|
|
1769
1862
|
this._dirty.set(true);
|
|
1863
|
+
this._inputDisplayValue.set(this.displayValue());
|
|
1770
1864
|
this._applyValue();
|
|
1771
1865
|
this.close();
|
|
1772
1866
|
return;
|
|
@@ -1774,6 +1868,7 @@ class ZCalendarComponent {
|
|
|
1774
1868
|
if (this.isTimeMode()) {
|
|
1775
1869
|
this._selectedDate.set(now);
|
|
1776
1870
|
this._dirty.set(true);
|
|
1871
|
+
this._inputDisplayValue.set(this.displayValue());
|
|
1777
1872
|
if (!this.showOkButton()) {
|
|
1778
1873
|
this._applyValue();
|
|
1779
1874
|
this.close();
|
|
@@ -1800,6 +1895,7 @@ class ZCalendarComponent {
|
|
|
1800
1895
|
const selectedDate = this.zShowTime() ? now : today;
|
|
1801
1896
|
this._selectedDate.set(selectedDate);
|
|
1802
1897
|
this._dirty.set(true);
|
|
1898
|
+
this._inputDisplayValue.set(this.displayValue());
|
|
1803
1899
|
if (!this.showOkButton()) {
|
|
1804
1900
|
this._applyValue();
|
|
1805
1901
|
this.close();
|
|
@@ -1926,6 +2022,7 @@ class ZCalendarComponent {
|
|
|
1926
2022
|
const value = parseTimeValue(digits, 23);
|
|
1927
2023
|
this._hour.set(value);
|
|
1928
2024
|
this._updateTimeToDate();
|
|
2025
|
+
this._updateInputDisplayAfterTimeChange();
|
|
1929
2026
|
}
|
|
1930
2027
|
onMinuteInput(event) {
|
|
1931
2028
|
const input = event.target;
|
|
@@ -1936,6 +2033,7 @@ class ZCalendarComponent {
|
|
|
1936
2033
|
const value = parseTimeValue(digits, 59);
|
|
1937
2034
|
this._minute.set(value);
|
|
1938
2035
|
this._updateTimeToDate();
|
|
2036
|
+
this._updateInputDisplayAfterTimeChange();
|
|
1939
2037
|
}
|
|
1940
2038
|
onSecondInput(event) {
|
|
1941
2039
|
const input = event.target;
|
|
@@ -1946,10 +2044,32 @@ class ZCalendarComponent {
|
|
|
1946
2044
|
const value = parseTimeValue(digits, 59);
|
|
1947
2045
|
this._second.set(value);
|
|
1948
2046
|
this._updateTimeToDate();
|
|
2047
|
+
this._updateInputDisplayAfterTimeChange();
|
|
1949
2048
|
}
|
|
1950
2049
|
onTimeBlur(event) {
|
|
1951
2050
|
const input = event.target;
|
|
1952
2051
|
const dataType = input.getAttribute('data-time-type');
|
|
2052
|
+
const digits = input.value.replace(/\D/g, '');
|
|
2053
|
+
if (digits.length > 0 && digits.length <= 2) {
|
|
2054
|
+
if (dataType === 'hour') {
|
|
2055
|
+
const value = parseTimeValue(digits, this.zTimeFormat() === '12h' ? 12 : 23);
|
|
2056
|
+
this._hour.set(value);
|
|
2057
|
+
this._updateTimeToDate();
|
|
2058
|
+
this._updateInputDisplayAfterTimeChange();
|
|
2059
|
+
}
|
|
2060
|
+
if (dataType === 'minute') {
|
|
2061
|
+
const value = parseTimeValue(digits, 59);
|
|
2062
|
+
this._minute.set(value);
|
|
2063
|
+
this._updateTimeToDate();
|
|
2064
|
+
this._updateInputDisplayAfterTimeChange();
|
|
2065
|
+
}
|
|
2066
|
+
if (dataType === 'second') {
|
|
2067
|
+
const value = parseTimeValue(digits, 59);
|
|
2068
|
+
this._second.set(value);
|
|
2069
|
+
this._updateTimeToDate();
|
|
2070
|
+
this._updateInputDisplayAfterTimeChange();
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
1953
2073
|
if (dataType === 'hour') {
|
|
1954
2074
|
input.value = this.formattedHour();
|
|
1955
2075
|
}
|
|
@@ -1985,6 +2105,7 @@ class ZCalendarComponent {
|
|
|
1985
2105
|
const value = parseTimeValue(digits, 23);
|
|
1986
2106
|
this._hourEnd.set(value);
|
|
1987
2107
|
this._updateEndTimeToDate();
|
|
2108
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
1988
2109
|
}
|
|
1989
2110
|
onMinuteEndInput(event) {
|
|
1990
2111
|
const input = event.target;
|
|
@@ -1995,6 +2116,7 @@ class ZCalendarComponent {
|
|
|
1995
2116
|
const value = parseTimeValue(digits, 59);
|
|
1996
2117
|
this._minuteEnd.set(value);
|
|
1997
2118
|
this._updateEndTimeToDate();
|
|
2119
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
1998
2120
|
}
|
|
1999
2121
|
onSecondEndInput(event) {
|
|
2000
2122
|
const input = event.target;
|
|
@@ -2005,10 +2127,32 @@ class ZCalendarComponent {
|
|
|
2005
2127
|
const value = parseTimeValue(digits, 59);
|
|
2006
2128
|
this._secondEnd.set(value);
|
|
2007
2129
|
this._updateEndTimeToDate();
|
|
2130
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2008
2131
|
}
|
|
2009
2132
|
onTimeBlurEnd(event) {
|
|
2010
2133
|
const input = event.target;
|
|
2011
2134
|
const dataType = input.getAttribute('data-time-type');
|
|
2135
|
+
const digits = input.value.replace(/\D/g, '');
|
|
2136
|
+
if (digits.length > 0 && digits.length <= 2) {
|
|
2137
|
+
if (dataType === 'hour-end') {
|
|
2138
|
+
const value = parseTimeValue(digits, this.zTimeFormat() === '12h' ? 12 : 23);
|
|
2139
|
+
this._hourEnd.set(value);
|
|
2140
|
+
this._updateEndTimeToDate();
|
|
2141
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2142
|
+
}
|
|
2143
|
+
if (dataType === 'minute-end') {
|
|
2144
|
+
const value = parseTimeValue(digits, 59);
|
|
2145
|
+
this._minuteEnd.set(value);
|
|
2146
|
+
this._updateEndTimeToDate();
|
|
2147
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2148
|
+
}
|
|
2149
|
+
if (dataType === 'second-end') {
|
|
2150
|
+
const value = parseTimeValue(digits, 59);
|
|
2151
|
+
this._secondEnd.set(value);
|
|
2152
|
+
this._updateEndTimeToDate();
|
|
2153
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2012
2156
|
if (dataType === 'hour-end') {
|
|
2013
2157
|
input.value = this.formattedHourEnd();
|
|
2014
2158
|
}
|
|
@@ -2031,6 +2175,7 @@ class ZCalendarComponent {
|
|
|
2031
2175
|
this._hourEnd.set(currentHour - 12);
|
|
2032
2176
|
}
|
|
2033
2177
|
this._updateEndTimeToDate();
|
|
2178
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2034
2179
|
}
|
|
2035
2180
|
_updateEndTimeToDate() {
|
|
2036
2181
|
const end = this._rangeEnd();
|
|
@@ -2284,6 +2429,28 @@ class ZCalendarComponent {
|
|
|
2284
2429
|
}
|
|
2285
2430
|
this._selectedDate.set(null);
|
|
2286
2431
|
}
|
|
2432
|
+
onInputEscape() {
|
|
2433
|
+
this._cancelAndRestore();
|
|
2434
|
+
}
|
|
2435
|
+
onStartInputEscape() {
|
|
2436
|
+
this._cancelAndRestore();
|
|
2437
|
+
}
|
|
2438
|
+
onEndInputEscape() {
|
|
2439
|
+
this._cancelAndRestore();
|
|
2440
|
+
}
|
|
2441
|
+
_cancelAndRestore() {
|
|
2442
|
+
this._restoreFromBackup();
|
|
2443
|
+
this._updateAllInputDisplays();
|
|
2444
|
+
this.close();
|
|
2445
|
+
}
|
|
2446
|
+
_updateAllInputDisplays() {
|
|
2447
|
+
if (this.isRangeMode()) {
|
|
2448
|
+
this._inputDisplayStart.set(this.displayValueStart());
|
|
2449
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2450
|
+
return;
|
|
2451
|
+
}
|
|
2452
|
+
this._inputDisplayValue.set(this.displayValue());
|
|
2453
|
+
}
|
|
2287
2454
|
_emitControl() {
|
|
2288
2455
|
this.zControl.emit({
|
|
2289
2456
|
validate: () => this.validate(),
|
|
@@ -2315,6 +2482,14 @@ class ZCalendarComponent {
|
|
|
2315
2482
|
this._hour.set(currentHour - 12);
|
|
2316
2483
|
}
|
|
2317
2484
|
this._updateTimeToDate();
|
|
2485
|
+
this._updateInputDisplayAfterTimeChange();
|
|
2486
|
+
}
|
|
2487
|
+
_updateInputDisplayAfterTimeChange() {
|
|
2488
|
+
if (this.isRangeMode()) {
|
|
2489
|
+
this._inputDisplayStart.set(this.displayValueStart());
|
|
2490
|
+
return;
|
|
2491
|
+
}
|
|
2492
|
+
this._inputDisplayValue.set(this.displayValue());
|
|
2318
2493
|
}
|
|
2319
2494
|
onPeriodChange(event) {
|
|
2320
2495
|
const select = event.target;
|
|
@@ -2329,6 +2504,345 @@ class ZCalendarComponent {
|
|
|
2329
2504
|
}
|
|
2330
2505
|
this._updateTimeToDate();
|
|
2331
2506
|
}
|
|
2507
|
+
selectHour(hour) {
|
|
2508
|
+
let actualHour = hour;
|
|
2509
|
+
if (this.zTimeFormat() === '12h') {
|
|
2510
|
+
if (this._period() === 'PM' && hour !== 12) {
|
|
2511
|
+
actualHour = hour + 12;
|
|
2512
|
+
}
|
|
2513
|
+
if (this._period() === 'AM' && hour === 12) {
|
|
2514
|
+
actualHour = 0;
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
this._hour.set(actualHour);
|
|
2518
|
+
this._updateTimeToDate();
|
|
2519
|
+
this._updateInputDisplayAfterTimeChange();
|
|
2520
|
+
}
|
|
2521
|
+
selectMinute(minute) {
|
|
2522
|
+
this._minute.set(minute);
|
|
2523
|
+
this._updateTimeToDate();
|
|
2524
|
+
this._updateInputDisplayAfterTimeChange();
|
|
2525
|
+
}
|
|
2526
|
+
selectSecond(second) {
|
|
2527
|
+
this._second.set(second);
|
|
2528
|
+
this._updateTimeToDate();
|
|
2529
|
+
this._updateInputDisplayAfterTimeChange();
|
|
2530
|
+
}
|
|
2531
|
+
selectPeriod(period) {
|
|
2532
|
+
if (this._period() === period) {
|
|
2533
|
+
return;
|
|
2534
|
+
}
|
|
2535
|
+
this.togglePeriod();
|
|
2536
|
+
}
|
|
2537
|
+
selectHourEnd(hour) {
|
|
2538
|
+
let actualHour = hour;
|
|
2539
|
+
if (this.zTimeFormat() === '12h') {
|
|
2540
|
+
if (this._periodEnd() === 'PM' && hour !== 12) {
|
|
2541
|
+
actualHour = hour + 12;
|
|
2542
|
+
}
|
|
2543
|
+
if (this._periodEnd() === 'AM' && hour === 12) {
|
|
2544
|
+
actualHour = 0;
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
this._hourEnd.set(actualHour);
|
|
2548
|
+
this._updateEndTimeToDate();
|
|
2549
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2550
|
+
}
|
|
2551
|
+
selectMinuteEnd(minute) {
|
|
2552
|
+
this._minuteEnd.set(minute);
|
|
2553
|
+
this._updateEndTimeToDate();
|
|
2554
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2555
|
+
}
|
|
2556
|
+
selectSecondEnd(second) {
|
|
2557
|
+
this._secondEnd.set(second);
|
|
2558
|
+
this._updateEndTimeToDate();
|
|
2559
|
+
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2560
|
+
}
|
|
2561
|
+
selectPeriodEnd(period) {
|
|
2562
|
+
if (this._periodEnd() === period) {
|
|
2563
|
+
return;
|
|
2564
|
+
}
|
|
2565
|
+
this.togglePeriodEnd();
|
|
2566
|
+
}
|
|
2567
|
+
scrollToSelectedTime(container, value, itemHeight = 28) {
|
|
2568
|
+
if (!container) {
|
|
2569
|
+
return;
|
|
2570
|
+
}
|
|
2571
|
+
const scrollTop = value * itemHeight;
|
|
2572
|
+
container.scrollTo({ top: scrollTop, behavior: 'smooth' });
|
|
2573
|
+
}
|
|
2574
|
+
isHourSelected(hour) {
|
|
2575
|
+
return this.displayHour() === hour;
|
|
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()) {
|
|
2719
|
+
return;
|
|
2720
|
+
}
|
|
2721
|
+
const itemHeight = 28;
|
|
2722
|
+
setTimeout(() => {
|
|
2723
|
+
const timeColumns = document.querySelectorAll('.z-time-column');
|
|
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;
|
|
2757
|
+
}
|
|
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
|
+
const start = this._rangeStart();
|
|
2768
|
+
if (start) {
|
|
2769
|
+
let columnIndex = 0;
|
|
2770
|
+
if (this.zShowHour()) {
|
|
2771
|
+
const hourColumn = columnsArray[columnIndex];
|
|
2772
|
+
if (hourColumn) {
|
|
2773
|
+
const hourValue = this.zTimeFormat() === '12h' ? this.displayHour() - 1 : this._hour();
|
|
2774
|
+
hourColumn.scrollTop = hourValue * itemHeight;
|
|
2775
|
+
}
|
|
2776
|
+
columnIndex++;
|
|
2777
|
+
}
|
|
2778
|
+
if (this.zShowMinute()) {
|
|
2779
|
+
const minuteColumn = columnsArray[columnIndex];
|
|
2780
|
+
if (minuteColumn) {
|
|
2781
|
+
minuteColumn.scrollTop = this._minute() * itemHeight;
|
|
2782
|
+
}
|
|
2783
|
+
columnIndex++;
|
|
2784
|
+
}
|
|
2785
|
+
if (this.zShowSecond()) {
|
|
2786
|
+
const secondColumn = columnsArray[columnIndex];
|
|
2787
|
+
if (secondColumn) {
|
|
2788
|
+
secondColumn.scrollTop = this._second() * itemHeight;
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
const end = this._rangeEnd();
|
|
2793
|
+
if (end) {
|
|
2794
|
+
let columnIndex = columnsPerSection;
|
|
2795
|
+
if (this.zShowHour()) {
|
|
2796
|
+
const hourColumn = columnsArray[columnIndex];
|
|
2797
|
+
if (hourColumn) {
|
|
2798
|
+
const hourValue = this.zTimeFormat() === '12h' ? this.displayHourEnd() - 1 : this._hourEnd();
|
|
2799
|
+
hourColumn.scrollTop = hourValue * itemHeight;
|
|
2800
|
+
}
|
|
2801
|
+
columnIndex++;
|
|
2802
|
+
}
|
|
2803
|
+
if (this.zShowMinute()) {
|
|
2804
|
+
const minuteColumn = columnsArray[columnIndex];
|
|
2805
|
+
if (minuteColumn) {
|
|
2806
|
+
minuteColumn.scrollTop = this._minuteEnd() * itemHeight;
|
|
2807
|
+
}
|
|
2808
|
+
columnIndex++;
|
|
2809
|
+
}
|
|
2810
|
+
if (this.zShowSecond()) {
|
|
2811
|
+
const secondColumn = columnsArray[columnIndex];
|
|
2812
|
+
if (secondColumn) {
|
|
2813
|
+
secondColumn.scrollTop = this._secondEnd() * itemHeight;
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
return;
|
|
2818
|
+
}
|
|
2819
|
+
const selected = this._selectedDate();
|
|
2820
|
+
if (selected) {
|
|
2821
|
+
let columnIndex = 0;
|
|
2822
|
+
if (this.zShowHour()) {
|
|
2823
|
+
const hourColumn = columnsArray[columnIndex];
|
|
2824
|
+
if (hourColumn) {
|
|
2825
|
+
const hourValue = this.zTimeFormat() === '12h' ? this.displayHour() - 1 : this._hour();
|
|
2826
|
+
hourColumn.scrollTop = hourValue * itemHeight;
|
|
2827
|
+
}
|
|
2828
|
+
columnIndex++;
|
|
2829
|
+
}
|
|
2830
|
+
if (this.zShowMinute()) {
|
|
2831
|
+
const minuteColumn = columnsArray[columnIndex];
|
|
2832
|
+
if (minuteColumn) {
|
|
2833
|
+
minuteColumn.scrollTop = this._minute() * itemHeight;
|
|
2834
|
+
}
|
|
2835
|
+
columnIndex++;
|
|
2836
|
+
}
|
|
2837
|
+
if (this.zShowSecond()) {
|
|
2838
|
+
const secondColumn = columnsArray[columnIndex];
|
|
2839
|
+
if (secondColumn) {
|
|
2840
|
+
secondColumn.scrollTop = this._second() * itemHeight;
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2844
|
+
}, 0);
|
|
2845
|
+
}
|
|
2332
2846
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2333
2847
|
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: [
|
|
2334
2848
|
{
|
|
@@ -2337,11 +2851,13 @@ class ZCalendarComponent {
|
|
|
2337
2851
|
multi: true,
|
|
2338
2852
|
},
|
|
2339
2853
|
TranslatePipe,
|
|
2340
|
-
], 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 <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 } @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 }\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 rounded-[6px] border shadow-lg\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border flex flex-col space-y-1 border-r p-2\">\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-col gap-2 p-3\">\n @if (!isTimeMode()) {\n <div class=\"z-calendars-wrapper flex gap-4\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex flex-col justify-center 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\n <!-- Start Time Picker for Range Mode -->\n @if (isRangeMode() && zShowTime() && currentView() === 'day') {\n <div class=\"flex items-center justify-center gap-2 pt-2\">\n <span class=\"text-muted-foreground text-xs\">{{ 'i18n_z_ui_calendar_start' | translate }}:</span>\n <div class=\"flex items-center gap-0.5\">\n @if (zShowHour()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"hour\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedHour()\"\n (input)=\"onHourInput($event)\"\n (blur)=\"onTimeBlur($event)\"\n maxlength=\"2\" />\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"minute\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedMinute()\"\n (input)=\"onMinuteInput($event)\"\n (blur)=\"onTimeBlur($event)\"\n maxlength=\"2\" />\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"second\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedSecond()\"\n (input)=\"onSecondInput($event)\"\n (blur)=\"onTimeBlur($event)\"\n maxlength=\"2\" />\n }\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n tabindex=\"0\"\n class=\"border-input bg-background hover:bg-muted focus:border-ring focus:ring-ring/30 ml-1 cursor-pointer rounded border px-2 py-1 text-sm font-medium transition-colors outline-none focus:ring-2\"\n (click)=\"togglePeriod()\">\n {{ period() }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div class=\"border-border bg-border w-px self-stretch\"></div>\n\n <div class=\"z-calendar-section flex flex-col justify-center 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\n <!-- End Time Picker for Range Mode -->\n @if (zShowTime()) {\n <div class=\"flex items-center justify-center gap-2 pt-2\">\n <span class=\"text-muted-foreground text-xs\">{{ 'i18n_z_ui_calendar_end' | translate }}:</span>\n <div class=\"flex items-center gap-0.5\">\n @if (zShowHour()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"hour-end\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedHourEnd()\"\n (input)=\"onHourEndInput($event)\"\n (blur)=\"onTimeBlurEnd($event)\"\n maxlength=\"2\" />\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"minute-end\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedMinuteEnd()\"\n (input)=\"onMinuteEndInput($event)\"\n (blur)=\"onTimeBlurEnd($event)\"\n maxlength=\"2\" />\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"second-end\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedSecondEnd()\"\n (input)=\"onSecondEndInput($event)\"\n (blur)=\"onTimeBlurEnd($event)\"\n maxlength=\"2\" />\n }\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n tabindex=\"0\"\n class=\"border-input bg-background hover:bg-muted focus:border-ring focus:ring-ring/30 ml-1 cursor-pointer rounded border px-2 py-1 text-sm font-medium transition-colors outline-none focus:ring-2\"\n (click)=\"togglePeriodEnd()\">\n {{ periodEnd() }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (((zShowTime() && currentView() === 'day') || isTimeMode()) && !isRangeMode()) {\n <div class=\"flex items-center justify-center gap-2\">\n <div class=\"flex items-center gap-0.5\">\n @if (zShowHour()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"hour\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedHour()\"\n (input)=\"onHourInput($event)\"\n (blur)=\"onTimeBlur($event)\"\n maxlength=\"2\" />\n }\n\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n\n @if (zShowMinute()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"minute\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedMinute()\"\n (input)=\"onMinuteInput($event)\"\n (blur)=\"onTimeBlur($event)\"\n maxlength=\"2\" />\n }\n\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n\n @if (zShowSecond()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"second\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedSecond()\"\n (input)=\"onSecondInput($event)\"\n (blur)=\"onTimeBlur($event)\"\n maxlength=\"2\" />\n }\n\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n tabindex=\"0\"\n class=\"border-input bg-background hover:bg-muted focus:border-ring focus:ring-ring/30 ml-1 cursor-pointer rounded border px-2 py-1 text-sm font-medium transition-colors outline-none focus:ring-2\"\n (click)=\"togglePeriod()\">\n {{ period() }}\n </button>\n }\n </div>\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}@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: 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: 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 });
|
|
2854
|
+
], 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 rounded-[6px] border shadow-lg\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border flex flex-col space-y-1 border-r p-2\">\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-col gap-2 p-3\">\n @if (!isTimeMode()) {\n <div class=\"z-calendars-wrapper flex\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex flex-col justify-center 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 class=\"border-border flex flex-col border-l 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 gap-1\">\n <!-- Hour Column -->\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[235px] w-12 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\n <!-- Minute Column -->\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[235px] w-12 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\n <!-- Second Column -->\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[235px] w-12 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\n <!-- AM/PM Column -->\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 w-12 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 w-12 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 w-px self-stretch\"></div>\n\n <div class=\"z-calendar-section flex flex-col justify-center 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 class=\"border-border flex flex-col gap-4 border-l 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 gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 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-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 class=\"z-time-column border-border h-[140px] w-10 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-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 class=\"z-time-column border-border h-[140px] w-10 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-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 @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 w-9 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 w-9 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 gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" 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 class=\"z-time-column border-border h-[140px] w-10 rounded border\" 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 class=\"z-time-column border-border h-[140px] w-10 rounded border\" 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 @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n @let amDisabled = isEndPeriodDisabled('AM');\n <button\n type=\"button\"\n class=\"flex h-6 w-9 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 w-9 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 }\n\n @if (isTimeMode()) {\n <div class=\"flex justify-center gap-1 py-2\">\n <!-- Hour Column -->\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\n <!-- Minute Column -->\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\n <!-- Second Column -->\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\n <!-- AM/PM Column -->\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 w-14 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 w-14 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 });
|
|
2341
2855
|
}
|
|
2342
2856
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZCalendarComponent, decorators: [{
|
|
2343
2857
|
type: Component,
|
|
2344
2858
|
args: [{ selector: 'z-calendar', imports: [
|
|
2859
|
+
DecimalPipe,
|
|
2860
|
+
NgScrollbar,
|
|
2345
2861
|
ZIconComponent,
|
|
2346
2862
|
ZPopoverDirective,
|
|
2347
2863
|
ZButtonComponent,
|
|
@@ -2358,7 +2874,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2358
2874
|
multi: true,
|
|
2359
2875
|
},
|
|
2360
2876
|
TranslatePipe,
|
|
2361
|
-
], 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 <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 } @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 }\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 rounded-[6px] border shadow-lg\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border flex flex-col space-y-1 border-r p-2\">\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-col gap-2 p-3\">\n @if (!isTimeMode()) {\n <div class=\"z-calendars-wrapper flex gap-4\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex flex-col justify-center 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\n <!-- Start Time Picker for Range Mode -->\n @if (isRangeMode() && zShowTime() && currentView() === 'day') {\n <div class=\"flex items-center justify-center gap-2 pt-2\">\n <span class=\"text-muted-foreground text-xs\">{{ 'i18n_z_ui_calendar_start' | translate }}:</span>\n <div class=\"flex items-center gap-0.5\">\n @if (zShowHour()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"hour\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedHour()\"\n (input)=\"onHourInput($event)\"\n (blur)=\"onTimeBlur($event)\"\n maxlength=\"2\" />\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"minute\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedMinute()\"\n (input)=\"onMinuteInput($event)\"\n (blur)=\"onTimeBlur($event)\"\n maxlength=\"2\" />\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"second\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedSecond()\"\n (input)=\"onSecondInput($event)\"\n (blur)=\"onTimeBlur($event)\"\n maxlength=\"2\" />\n }\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n tabindex=\"0\"\n class=\"border-input bg-background hover:bg-muted focus:border-ring focus:ring-ring/30 ml-1 cursor-pointer rounded border px-2 py-1 text-sm font-medium transition-colors outline-none focus:ring-2\"\n (click)=\"togglePeriod()\">\n {{ period() }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div class=\"border-border bg-border w-px self-stretch\"></div>\n\n <div class=\"z-calendar-section flex flex-col justify-center 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\n <!-- End Time Picker for Range Mode -->\n @if (zShowTime()) {\n <div class=\"flex items-center justify-center gap-2 pt-2\">\n <span class=\"text-muted-foreground text-xs\">{{ 'i18n_z_ui_calendar_end' | translate }}:</span>\n <div class=\"flex items-center gap-0.5\">\n @if (zShowHour()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"hour-end\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedHourEnd()\"\n (input)=\"onHourEndInput($event)\"\n (blur)=\"onTimeBlurEnd($event)\"\n maxlength=\"2\" />\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"minute-end\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedMinuteEnd()\"\n (input)=\"onMinuteEndInput($event)\"\n (blur)=\"onTimeBlurEnd($event)\"\n maxlength=\"2\" />\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"second-end\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedSecondEnd()\"\n (input)=\"onSecondEndInput($event)\"\n (blur)=\"onTimeBlurEnd($event)\"\n maxlength=\"2\" />\n }\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n tabindex=\"0\"\n class=\"border-input bg-background hover:bg-muted focus:border-ring focus:ring-ring/30 ml-1 cursor-pointer rounded border px-2 py-1 text-sm font-medium transition-colors outline-none focus:ring-2\"\n (click)=\"togglePeriodEnd()\">\n {{ periodEnd() }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (((zShowTime() && currentView() === 'day') || isTimeMode()) && !isRangeMode()) {\n <div class=\"flex items-center justify-center gap-2\">\n <div class=\"flex items-center gap-0.5\">\n @if (zShowHour()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"hour\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedHour()\"\n (input)=\"onHourInput($event)\"\n (blur)=\"onTimeBlur($event)\"\n maxlength=\"2\" />\n }\n\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n\n @if (zShowMinute()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"minute\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedMinute()\"\n (input)=\"onMinuteInput($event)\"\n (blur)=\"onTimeBlur($event)\"\n maxlength=\"2\" />\n }\n\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n\n @if (zShowSecond()) {\n <input\n type=\"text\"\n tabindex=\"0\"\n inputmode=\"numeric\"\n data-time-type=\"second\"\n class=\"border-input bg-background focus:border-ring focus:ring-ring/30 w-10 rounded border px-1.5 py-1 text-center text-sm outline-none focus:ring-2\"\n [value]=\"formattedSecond()\"\n (input)=\"onSecondInput($event)\"\n (blur)=\"onTimeBlur($event)\"\n maxlength=\"2\" />\n }\n\n @if (zTimeFormat() === '12h') {\n <button\n type=\"button\"\n tabindex=\"0\"\n class=\"border-input bg-background hover:bg-muted focus:border-ring focus:ring-ring/30 ml-1 cursor-pointer rounded border px-2 py-1 text-sm font-medium transition-colors outline-none focus:ring-2\"\n (click)=\"togglePeriod()\">\n {{ period() }}\n </button>\n }\n </div>\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}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"] }]
|
|
2877
|
+
], 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 rounded-[6px] border shadow-lg\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border flex flex-col space-y-1 border-r p-2\">\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-col gap-2 p-3\">\n @if (!isTimeMode()) {\n <div class=\"z-calendars-wrapper flex\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex flex-col justify-center 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 class=\"border-border flex flex-col border-l 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 gap-1\">\n <!-- Hour Column -->\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[235px] w-12 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\n <!-- Minute Column -->\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[235px] w-12 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\n <!-- Second Column -->\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[235px] w-12 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\n <!-- AM/PM Column -->\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 w-12 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 w-12 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 w-px self-stretch\"></div>\n\n <div class=\"z-calendar-section flex flex-col justify-center 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 class=\"border-border flex flex-col gap-4 border-l 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 gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 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-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 class=\"z-time-column border-border h-[140px] w-10 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-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 class=\"z-time-column border-border h-[140px] w-10 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-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 @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 w-9 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 w-9 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 gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" 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 class=\"z-time-column border-border h-[140px] w-10 rounded border\" 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 class=\"z-time-column border-border h-[140px] w-10 rounded border\" 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 @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n @let amDisabled = isEndPeriodDisabled('AM');\n <button\n type=\"button\"\n class=\"flex h-6 w-9 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 w-9 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 }\n\n @if (isTimeMode()) {\n <div class=\"flex justify-center gap-1 py-2\">\n <!-- Hour Column -->\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\n <!-- Minute Column -->\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\n <!-- Second Column -->\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\n <!-- AM/PM Column -->\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 w-14 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 w-14 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"] }]
|
|
2362
2878
|
}], 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 }] }] } });
|
|
2363
2879
|
|
|
2364
2880
|
/**
|