@shival99/z-ui 2.0.6 → 2.0.8

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.
Files changed (81) hide show
  1. package/assets/css/themes/hospital.css +9 -9
  2. package/fesm2022/shival99-z-ui-components-z-accordion.mjs +1 -1
  3. package/fesm2022/shival99-z-ui-components-z-accordion.mjs.map +1 -1
  4. package/fesm2022/shival99-z-ui-components-z-autocomplete.mjs +2 -2
  5. package/fesm2022/shival99-z-ui-components-z-autocomplete.mjs.map +1 -1
  6. package/fesm2022/shival99-z-ui-components-z-avatar.mjs +1 -1
  7. package/fesm2022/shival99-z-ui-components-z-avatar.mjs.map +1 -1
  8. package/fesm2022/shival99-z-ui-components-z-breadcrumb.mjs +1 -1
  9. package/fesm2022/shival99-z-ui-components-z-breadcrumb.mjs.map +1 -1
  10. package/fesm2022/shival99-z-ui-components-z-button.mjs +32 -9
  11. package/fesm2022/shival99-z-ui-components-z-button.mjs.map +1 -1
  12. package/fesm2022/shival99-z-ui-components-z-calendar.mjs +102 -27
  13. package/fesm2022/shival99-z-ui-components-z-calendar.mjs.map +1 -1
  14. package/fesm2022/shival99-z-ui-components-z-card.mjs +1 -1
  15. package/fesm2022/shival99-z-ui-components-z-card.mjs.map +1 -1
  16. package/fesm2022/shival99-z-ui-components-z-chat.mjs +1 -1
  17. package/fesm2022/shival99-z-ui-components-z-chat.mjs.map +1 -1
  18. package/fesm2022/shival99-z-ui-components-z-checkbox.mjs +1 -1
  19. package/fesm2022/shival99-z-ui-components-z-checkbox.mjs.map +1 -1
  20. package/fesm2022/shival99-z-ui-components-z-code.mjs +1 -1
  21. package/fesm2022/shival99-z-ui-components-z-code.mjs.map +1 -1
  22. package/fesm2022/shival99-z-ui-components-z-drawer.mjs +10 -3
  23. package/fesm2022/shival99-z-ui-components-z-drawer.mjs.map +1 -1
  24. package/fesm2022/shival99-z-ui-components-z-dropdown-menu.mjs +1 -1
  25. package/fesm2022/shival99-z-ui-components-z-dropdown-menu.mjs.map +1 -1
  26. package/fesm2022/shival99-z-ui-components-z-editor.mjs +1 -1
  27. package/fesm2022/shival99-z-ui-components-z-editor.mjs.map +1 -1
  28. package/fesm2022/shival99-z-ui-components-z-empty.mjs +1 -1
  29. package/fesm2022/shival99-z-ui-components-z-empty.mjs.map +1 -1
  30. package/fesm2022/shival99-z-ui-components-z-filter.mjs +1 -1
  31. package/fesm2022/shival99-z-ui-components-z-filter.mjs.map +1 -1
  32. package/fesm2022/shival99-z-ui-components-z-gallery.mjs +3 -3
  33. package/fesm2022/shival99-z-ui-components-z-gallery.mjs.map +1 -1
  34. package/fesm2022/shival99-z-ui-components-z-icon.mjs +72 -5
  35. package/fesm2022/shival99-z-ui-components-z-icon.mjs.map +1 -1
  36. package/fesm2022/shival99-z-ui-components-z-input.mjs +2 -2
  37. package/fesm2022/shival99-z-ui-components-z-input.mjs.map +1 -1
  38. package/fesm2022/shival99-z-ui-components-z-kanban.mjs +1 -1
  39. package/fesm2022/shival99-z-ui-components-z-kanban.mjs.map +1 -1
  40. package/fesm2022/shival99-z-ui-components-z-menu.mjs +16 -6
  41. package/fesm2022/shival99-z-ui-components-z-menu.mjs.map +1 -1
  42. package/fesm2022/shival99-z-ui-components-z-metric-card.mjs +1 -1
  43. package/fesm2022/shival99-z-ui-components-z-metric-card.mjs.map +1 -1
  44. package/fesm2022/shival99-z-ui-components-z-modal.mjs +11 -3
  45. package/fesm2022/shival99-z-ui-components-z-modal.mjs.map +1 -1
  46. package/fesm2022/shival99-z-ui-components-z-pagination.mjs +1 -1
  47. package/fesm2022/shival99-z-ui-components-z-pagination.mjs.map +1 -1
  48. package/fesm2022/shival99-z-ui-components-z-popover.mjs +77 -9
  49. package/fesm2022/shival99-z-ui-components-z-popover.mjs.map +1 -1
  50. package/fesm2022/shival99-z-ui-components-z-select.mjs +2 -2
  51. package/fesm2022/shival99-z-ui-components-z-select.mjs.map +1 -1
  52. package/fesm2022/shival99-z-ui-components-z-steps.mjs +1 -1
  53. package/fesm2022/shival99-z-ui-components-z-steps.mjs.map +1 -1
  54. package/fesm2022/shival99-z-ui-components-z-switch.mjs +1 -1
  55. package/fesm2022/shival99-z-ui-components-z-switch.mjs.map +1 -1
  56. package/fesm2022/shival99-z-ui-components-z-table.mjs +1264 -421
  57. package/fesm2022/shival99-z-ui-components-z-table.mjs.map +1 -1
  58. package/fesm2022/shival99-z-ui-components-z-tabs.mjs +95 -5
  59. package/fesm2022/shival99-z-ui-components-z-tabs.mjs.map +1 -1
  60. package/fesm2022/shival99-z-ui-components-z-tags.mjs +1 -1
  61. package/fesm2022/shival99-z-ui-components-z-tags.mjs.map +1 -1
  62. package/fesm2022/shival99-z-ui-components-z-timeline.mjs +1 -1
  63. package/fesm2022/shival99-z-ui-components-z-timeline.mjs.map +1 -1
  64. package/fesm2022/shival99-z-ui-components-z-upload.mjs +3 -2
  65. package/fesm2022/shival99-z-ui-components-z-upload.mjs.map +1 -1
  66. package/fesm2022/shival99-z-ui-i18n.mjs +66 -8
  67. package/fesm2022/shival99-z-ui-i18n.mjs.map +1 -1
  68. package/package.json +7 -3
  69. package/types/shival99-z-ui-components-z-autocomplete.d.ts +1 -1
  70. package/types/shival99-z-ui-components-z-button.d.ts +7 -4
  71. package/types/shival99-z-ui-components-z-calendar.d.ts +8 -1
  72. package/types/shival99-z-ui-components-z-drawer.d.ts +8 -1
  73. package/types/shival99-z-ui-components-z-editor.d.ts +1 -1
  74. package/types/shival99-z-ui-components-z-icon.d.ts +27 -4
  75. package/types/shival99-z-ui-components-z-menu.d.ts +3 -1
  76. package/types/shival99-z-ui-components-z-modal.d.ts +10 -2
  77. package/types/shival99-z-ui-components-z-popover.d.ts +9 -2
  78. package/types/shival99-z-ui-components-z-select.d.ts +1 -1
  79. package/types/shival99-z-ui-components-z-table.d.ts +129 -53
  80. package/types/shival99-z-ui-components-z-tabs.d.ts +15 -7
  81. package/types/shival99-z-ui-components-z-upload.d.ts +4 -3
@@ -346,6 +346,14 @@ const getQuickSelectPresets = () => [
346
346
  label: 'i18n_z_ui_calendar_today',
347
347
  getValue: () => ({ start: getToday(), end: getToday() }),
348
348
  },
349
+ {
350
+ key: 'yesterday',
351
+ label: 'i18n_z_ui_calendar_yesterday',
352
+ getValue: () => {
353
+ const yesterday = addDays(getToday(), -1);
354
+ return { start: yesterday, end: yesterday };
355
+ },
356
+ },
349
357
  {
350
358
  key: '7days',
351
359
  label: 'i18n_z_ui_calendar_last_7_days',
@@ -923,6 +931,8 @@ class ZCalendarComponent {
923
931
  zShowMinute = input(true, { ...(ngDevMode ? { debugName: "zShowMinute" } : {}), transform: zTransform });
924
932
  zShowSecond = input(true, { ...(ngDevMode ? { debugName: "zShowSecond" } : {}), transform: zTransform });
925
933
  zQuickSelect = input(false, { ...(ngDevMode ? { debugName: "zQuickSelect" } : {}), transform: zTransform });
934
+ zAllowEdit = input(true, { ...(ngDevMode ? { debugName: "zAllowEdit" } : {}), transform: zTransform });
935
+ zShortTime = input(false, { ...(ngDevMode ? { debugName: "zShortTime" } : {}), transform: zTransform });
926
936
  zAllowClear = input(true, { ...(ngDevMode ? { debugName: "zAllowClear" } : {}), transform: zTransform });
927
937
  zFormat = input('DD/MM/YYYY', ...(ngDevMode ? [{ debugName: "zFormat" }] : []));
928
938
  zMinDate = input(null, ...(ngDevMode ? [{ debugName: "zMinDate" }] : []));
@@ -997,6 +1007,8 @@ class ZCalendarComponent {
997
1007
  _backupSelectedDate = signal(null, ...(ngDevMode ? [{ debugName: "_backupSelectedDate" }] : []));
998
1008
  _backupRangeStart = signal(null, ...(ngDevMode ? [{ debugName: "_backupRangeStart" }] : []));
999
1009
  _backupRangeEnd = signal(null, ...(ngDevMode ? [{ debugName: "_backupRangeEnd" }] : []));
1010
+ _backupActivePresetKey = signal(null, ...(ngDevMode ? [{ debugName: "_backupActivePresetKey" }] : []));
1011
+ _backupShortDisplayPresetKey = signal(null, ...(ngDevMode ? [{ debugName: "_backupShortDisplayPresetKey" }] : []));
1000
1012
  _appliedViaOk = signal(false, ...(ngDevMode ? [{ debugName: "_appliedViaOk" }] : []));
1001
1013
  _skipBlurHandler = signal(false, ...(ngDevMode ? [{ debugName: "_skipBlurHandler" }] : []));
1002
1014
  _injector = inject(Injector);
@@ -1017,11 +1029,23 @@ class ZCalendarComponent {
1017
1029
  period = signal('AM', ...(ngDevMode ? [{ debugName: "period" }] : []));
1018
1030
  inputDisplayValue = signal('', ...(ngDevMode ? [{ debugName: "inputDisplayValue" }] : []));
1019
1031
  activePresetKey = signal(null, ...(ngDevMode ? [{ debugName: "activePresetKey" }] : []));
1032
+ shortDisplayPresetKey = signal(null, ...(ngDevMode ? [{ debugName: "shortDisplayPresetKey" }] : []));
1020
1033
  quickSelectOptions = computed(() => this.quickSelectPresets.map(preset => ({
1021
1034
  label: preset.label,
1022
1035
  value: preset.key,
1023
1036
  disabled: this._isQuickSelectPresetDisabled(preset),
1024
1037
  })), ...(ngDevMode ? [{ debugName: "quickSelectOptions" }] : []));
1038
+ rangeShortDisplayValue = computed(() => {
1039
+ this._zTranslate.currentLang();
1040
+ if (!this.isRangeMode() || !this.zQuickSelect() || this.zAllowEdit() || !this.zShortTime()) {
1041
+ return '';
1042
+ }
1043
+ const activePreset = this.quickSelectPresets.find(preset => preset.key === this.shortDisplayPresetKey());
1044
+ if (activePreset && activePreset.key !== 'custom') {
1045
+ return this._zTranslate.instant(activePreset.label);
1046
+ }
1047
+ return '';
1048
+ }, ...(ngDevMode ? [{ debugName: "rangeShortDisplayValue" }] : []));
1025
1049
  uiState = signal({
1026
1050
  hasViewChanged: false,
1027
1051
  hasEndViewChanged: false,
@@ -1345,7 +1369,9 @@ class ZCalendarComponent {
1345
1369
  triggerClasses = computed(() => zMergeClasses(zCalendarVariants({
1346
1370
  zSize: this.zSize(),
1347
1371
  zStatus: this.currentStatus(),
1348
- }), this.class()), ...(ngDevMode ? [{ debugName: "triggerClasses" }] : []));
1372
+ }), !this.zAllowEdit() && !this.isDisabled() && !this.zReadonly()
1373
+ ? 'cursor-pointer hover:bg-muted/30 [&_input]:cursor-pointer'
1374
+ : '', this.class()), ...(ngDevMode ? [{ debugName: "triggerClasses" }] : []));
1349
1375
  _shouldShowValidation = computed(() => {
1350
1376
  const control = this._formControl();
1351
1377
  this._formStateVersion();
@@ -1454,13 +1480,20 @@ class ZCalendarComponent {
1454
1480
  if (range.start && range.end) {
1455
1481
  this._currentMonth.set(range.start);
1456
1482
  this._endMonth.set(isSameMonth(range.start, range.end) ? addMonths(range.end, 1) : range.end);
1483
+ if (!this.shortDisplayPresetKey()) {
1484
+ const presetKey = this._detectMatchingPreset(range.start, range.end);
1485
+ this.activePresetKey.set(presetKey);
1486
+ this.shortDisplayPresetKey.set(this.zShortTime() && presetKey !== 'custom' ? presetKey : null);
1487
+ }
1457
1488
  if (this.zShowTime()) {
1458
1489
  this._syncTimeSignals(range.start);
1459
1490
  this._syncEndTimeSignals(range.end);
1460
1491
  }
1461
1492
  }
1462
- this._inputDisplayStart.set(this.displayValueStart());
1463
- this._inputDisplayEnd.set(this.displayValueEnd());
1493
+ else {
1494
+ this.activePresetKey.set(null);
1495
+ }
1496
+ this._updateRangeInputDisplay();
1464
1497
  }
1465
1498
  return;
1466
1499
  }
@@ -1526,6 +1559,7 @@ class ZCalendarComponent {
1526
1559
  this._selectedDate.set(null);
1527
1560
  this._rangeStart.set(null);
1528
1561
  this._rangeEnd.set(null);
1562
+ this.activePresetKey.set(null);
1529
1563
  this.hour.set(0);
1530
1564
  this.minute.set(0);
1531
1565
  this.second.set(0);
@@ -1589,8 +1623,7 @@ class ZCalendarComponent {
1589
1623
  }
1590
1624
  if (this.isRangeMode()) {
1591
1625
  this.endView.set('day');
1592
- this._inputDisplayStart.set(this.displayValueStart());
1593
- this._inputDisplayEnd.set(this.displayValueEnd());
1626
+ this._updateRangeInputDisplay();
1594
1627
  }
1595
1628
  if (!this.isRangeMode()) {
1596
1629
  this.activePresetKey.set(null);
@@ -1651,6 +1684,8 @@ class ZCalendarComponent {
1651
1684
  this._backupSelectedDate.set(this._selectedDate());
1652
1685
  this._backupRangeStart.set(this._rangeStart());
1653
1686
  this._backupRangeEnd.set(this._rangeEnd());
1687
+ this._backupActivePresetKey.set(this.activePresetKey());
1688
+ this._backupShortDisplayPresetKey.set(this.shortDisplayPresetKey());
1654
1689
  }
1655
1690
  onPopoverHide() {
1656
1691
  this.uiState.update(s => ({ ...s, isFocused: false }));
@@ -1678,8 +1713,7 @@ class ZCalendarComponent {
1678
1713
  this._onTouched();
1679
1714
  this.inputDisplayValue.set(this.displayValue());
1680
1715
  if (this.isRangeMode()) {
1681
- this._inputDisplayStart.set(this.displayValueStart());
1682
- this._inputDisplayEnd.set(this.displayValueEnd());
1716
+ this._updateRangeInputDisplay();
1683
1717
  }
1684
1718
  this.triggerRef()?.nativeElement.blur();
1685
1719
  }
@@ -1687,6 +1721,8 @@ class ZCalendarComponent {
1687
1721
  this._selectedDate.set(this._backupSelectedDate());
1688
1722
  this._rangeStart.set(this._backupRangeStart());
1689
1723
  this._rangeEnd.set(this._backupRangeEnd());
1724
+ this.activePresetKey.set(this._backupActivePresetKey());
1725
+ this.shortDisplayPresetKey.set(this._backupShortDisplayPresetKey());
1690
1726
  this.uiState.update(s => ({ ...s, dirty: false }));
1691
1727
  if (this.isRangeMode()) {
1692
1728
  const backupStart = this._backupRangeStart();
@@ -1697,8 +1733,7 @@ class ZCalendarComponent {
1697
1733
  if (backupEnd) {
1698
1734
  this._syncEndTimeSignals(backupEnd);
1699
1735
  }
1700
- this._inputDisplayStart.set(this.displayValueStart());
1701
- this._inputDisplayEnd.set(this.displayValueEnd());
1736
+ this._updateRangeInputDisplay();
1702
1737
  return;
1703
1738
  }
1704
1739
  const backup = this._backupSelectedDate();
@@ -1725,6 +1760,9 @@ class ZCalendarComponent {
1725
1760
  }
1726
1761
  }
1727
1762
  onInputChange(event) {
1763
+ if (!this.zAllowEdit()) {
1764
+ return;
1765
+ }
1728
1766
  const input = event.target;
1729
1767
  const { value } = input;
1730
1768
  this.inputDisplayValue.set(value);
@@ -1764,6 +1802,9 @@ class ZCalendarComponent {
1764
1802
  return format.replace(/\[.*?\]/g, ' ').length;
1765
1803
  }
1766
1804
  onStartInputChange(event) {
1805
+ if (!this.zAllowEdit()) {
1806
+ return;
1807
+ }
1767
1808
  const input = event.target;
1768
1809
  const { value } = input;
1769
1810
  this._inputDisplayStart.set(value);
@@ -1790,6 +1831,9 @@ class ZCalendarComponent {
1790
1831
  this._syncTimeSignals(date);
1791
1832
  }
1792
1833
  onEndInputChange(event) {
1834
+ if (!this.zAllowEdit()) {
1835
+ return;
1836
+ }
1793
1837
  const input = event.target;
1794
1838
  const { value } = input;
1795
1839
  this._inputDisplayEnd.set(value);
@@ -1817,6 +1861,12 @@ class ZCalendarComponent {
1817
1861
  }
1818
1862
  onStartInputEnter(event) {
1819
1863
  event.preventDefault();
1864
+ if (!this.zAllowEdit()) {
1865
+ this._updateRangeInputDisplay();
1866
+ const input = event.target;
1867
+ input.value = this.inputDisplayStart();
1868
+ return;
1869
+ }
1820
1870
  const input = event.target;
1821
1871
  const value = input.value.trim();
1822
1872
  const format = this._getParseFormat();
@@ -1845,6 +1895,12 @@ class ZCalendarComponent {
1845
1895
  }
1846
1896
  onEndInputEnter(event) {
1847
1897
  event.preventDefault();
1898
+ if (!this.zAllowEdit()) {
1899
+ this._updateRangeInputDisplay();
1900
+ const input = event.target;
1901
+ input.value = this.inputDisplayEnd();
1902
+ return;
1903
+ }
1848
1904
  const input = event.target;
1849
1905
  const value = input.value.trim();
1850
1906
  const format = this._getParseFormat();
@@ -1917,6 +1973,11 @@ class ZCalendarComponent {
1917
1973
  onInputEnter(event) {
1918
1974
  event.preventDefault();
1919
1975
  const input = event.target;
1976
+ if (!this.zAllowEdit()) {
1977
+ this.inputDisplayValue.set(this.displayValue());
1978
+ input.value = this.displayValue();
1979
+ return;
1980
+ }
1920
1981
  const value = input.value.trim();
1921
1982
  if (!value) {
1922
1983
  this._skipBlurHandler.set(true);
@@ -2080,6 +2141,7 @@ class ZCalendarComponent {
2080
2141
  }
2081
2142
  onQuickSelect(preset) {
2082
2143
  this.activePresetKey.set(preset.key);
2144
+ this.shortDisplayPresetKey.set(preset.key === 'custom' ? null : preset.key);
2083
2145
  if (preset.key === 'custom') {
2084
2146
  this._rangeStart.set(null);
2085
2147
  this._rangeEnd.set(null);
@@ -2097,8 +2159,7 @@ class ZCalendarComponent {
2097
2159
  this._currentMonth.set(value);
2098
2160
  this._endMonth.set(addMonths(value, 1));
2099
2161
  this.uiState.update(s => ({ ...s, dirty: true }));
2100
- this._inputDisplayStart.set(this.displayValueStart());
2101
- this._inputDisplayEnd.set(this.displayValueEnd());
2162
+ this._updateRangeInputDisplay();
2102
2163
  if (!this.showOkButton()) {
2103
2164
  this._applyValue();
2104
2165
  this.close();
@@ -2112,8 +2173,7 @@ class ZCalendarComponent {
2112
2173
  this._currentMonth.set(start);
2113
2174
  this._endMonth.set(isSameMonth(start, end) ? addMonths(end, 1) : end);
2114
2175
  this.uiState.update(s => ({ ...s, dirty: true }));
2115
- this._inputDisplayStart.set(this.displayValueStart());
2116
- this._inputDisplayEnd.set(this.displayValueEnd());
2176
+ this._updateRangeInputDisplay();
2117
2177
  if (!this.showOkButton()) {
2118
2178
  this._applyValue();
2119
2179
  this.close();
@@ -2178,13 +2238,14 @@ class ZCalendarComponent {
2178
2238
  const rangeDate = this.zShowTime() ? now : today;
2179
2239
  this._rangeStart.set(rangeDate);
2180
2240
  this._rangeEnd.set(rangeDate);
2241
+ this.activePresetKey.set('today');
2242
+ this.shortDisplayPresetKey.set('today');
2181
2243
  this._endMonth.set(addMonths(today, 1));
2182
2244
  if (this.zShowTime()) {
2183
2245
  this._syncEndTimeSignals(now);
2184
2246
  }
2185
2247
  this.uiState.update(s => ({ ...s, dirty: true }));
2186
- this._inputDisplayStart.set(this.displayValueStart());
2187
- this._inputDisplayEnd.set(this.displayValueEnd());
2248
+ this._updateRangeInputDisplay();
2188
2249
  if (!this.showOkButton() && !this.showCancelButton()) {
2189
2250
  this._applyValue();
2190
2251
  this.close();
@@ -2206,6 +2267,8 @@ class ZCalendarComponent {
2206
2267
  this._selectedDate.set(null);
2207
2268
  this._rangeStart.set(null);
2208
2269
  this._rangeEnd.set(null);
2270
+ this.activePresetKey.set(null);
2271
+ this.shortDisplayPresetKey.set(null);
2209
2272
  this.hour.set(0);
2210
2273
  this.minute.set(0);
2211
2274
  this.second.set(0);
@@ -2213,6 +2276,8 @@ class ZCalendarComponent {
2213
2276
  this._backupSelectedDate.set(null);
2214
2277
  this._backupRangeStart.set(null);
2215
2278
  this._backupRangeEnd.set(null);
2279
+ this._backupActivePresetKey.set(null);
2280
+ this._backupShortDisplayPresetKey.set(null);
2216
2281
  this._appliedViaOk.set(true);
2217
2282
  const emitValue = this._getEmitValue();
2218
2283
  this._onChange(emitValue);
@@ -2578,6 +2643,7 @@ class ZCalendarComponent {
2578
2643
  this._rangeStart.set(startDate);
2579
2644
  this._rangeEnd.set(null);
2580
2645
  this.activePresetKey.set('custom');
2646
+ this.shortDisplayPresetKey.set(null);
2581
2647
  this._inputDisplayStart.set(this.displayValueStart());
2582
2648
  this._inputDisplayEnd.set('');
2583
2649
  return;
@@ -2597,11 +2663,11 @@ class ZCalendarComponent {
2597
2663
  this._rangeStart.set(normalized.start);
2598
2664
  this._rangeEnd.set(normalized.end);
2599
2665
  this.uiState.update(s => ({ ...s, dirty: true }));
2600
- this._inputDisplayStart.set(this.displayValueStart());
2601
- this._inputDisplayEnd.set(this.displayValueEnd());
2602
2666
  if (normalized.start && normalized.end) {
2603
2667
  this.activePresetKey.set(this._detectMatchingPreset(normalized.start, normalized.end));
2604
2668
  }
2669
+ this.shortDisplayPresetKey.set(null);
2670
+ this._updateRangeInputDisplay();
2605
2671
  if (!this.showOkButton() && !this.showCancelButton()) {
2606
2672
  this._applyValue();
2607
2673
  this.close();
@@ -2639,6 +2705,16 @@ class ZCalendarComponent {
2639
2705
  }
2640
2706
  return 'custom';
2641
2707
  }
2708
+ _updateRangeInputDisplay() {
2709
+ const shortDisplay = this.rangeShortDisplayValue();
2710
+ if (shortDisplay) {
2711
+ this._inputDisplayStart.set(shortDisplay);
2712
+ this._inputDisplayEnd.set('');
2713
+ return;
2714
+ }
2715
+ this._inputDisplayStart.set(this.displayValueStart());
2716
+ this._inputDisplayEnd.set(this.displayValueEnd());
2717
+ }
2642
2718
  _isQuickSelectPresetDisabled(preset) {
2643
2719
  const disabledDateFn = this.zDisabledDate();
2644
2720
  if (preset.key === 'custom' || !disabledDateFn) {
@@ -2666,8 +2742,7 @@ class ZCalendarComponent {
2666
2742
  this.uiState.update(s => ({ ...s, dirty: true }));
2667
2743
  this.inputDisplayValue.set(this.displayValue());
2668
2744
  if (this.isRangeMode()) {
2669
- this._inputDisplayStart.set(this.displayValueStart());
2670
- this._inputDisplayEnd.set(this.displayValueEnd());
2745
+ this._updateRangeInputDisplay();
2671
2746
  }
2672
2747
  }
2673
2748
  _getEmitValue() {
@@ -2777,14 +2852,15 @@ class ZCalendarComponent {
2777
2852
  _updateInputDisplay() {
2778
2853
  this.inputDisplayValue.set(this.displayValue());
2779
2854
  if (this.isRangeMode()) {
2780
- this._inputDisplayStart.set(this.displayValueStart());
2781
- this._inputDisplayEnd.set(this.displayValueEnd());
2855
+ this._updateRangeInputDisplay();
2782
2856
  }
2783
2857
  }
2784
2858
  _clearDateValues() {
2785
2859
  if (this.isRangeMode()) {
2786
2860
  this._rangeStart.set(null);
2787
2861
  this._rangeEnd.set(null);
2862
+ this.activePresetKey.set(null);
2863
+ this.shortDisplayPresetKey.set(null);
2788
2864
  return;
2789
2865
  }
2790
2866
  this._selectedDate.set(null);
@@ -2805,8 +2881,7 @@ class ZCalendarComponent {
2805
2881
  }
2806
2882
  _updateAllInputDisplays() {
2807
2883
  if (this.isRangeMode()) {
2808
- this._inputDisplayStart.set(this.displayValueStart());
2809
- this._inputDisplayEnd.set(this.displayValueEnd());
2884
+ this._updateRangeInputDisplay();
2810
2885
  return;
2811
2886
  }
2812
2887
  this.inputDisplayValue.set(this.displayValue());
@@ -3024,14 +3099,14 @@ class ZCalendarComponent {
3024
3099
  });
3025
3100
  }
3026
3101
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3027
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", 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 }, 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 }, zDefaultTime: { classPropertyName: "zDefaultTime", publicName: "zDefaultTime", isSignal: true, isRequired: false, transformFunction: null }, zRangeDefaultTime: { classPropertyName: "zRangeDefaultTime", publicName: "zRangeDefaultTime", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zControl: "zControl", zChange: "zChange", zOnBlur: "zOnBlur", zOnFocus: "zOnFocus", zEvent: "zEvent" }, host: { classAttribute: "block min-w-0" }, providers: [
3102
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", 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 }, zAllowEdit: { classPropertyName: "zAllowEdit", publicName: "zAllowEdit", isSignal: true, isRequired: false, transformFunction: null }, zShortTime: { classPropertyName: "zShortTime", publicName: "zShortTime", 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 }, 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 }, zDefaultTime: { classPropertyName: "zDefaultTime", publicName: "zDefaultTime", isSignal: true, isRequired: false, transformFunction: null }, zRangeDefaultTime: { classPropertyName: "zRangeDefaultTime", publicName: "zRangeDefaultTime", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zControl: "zControl", zChange: "zChange", zOnBlur: "zOnBlur", zOnFocus: "zOnFocus", zEvent: "zEvent" }, host: { classAttribute: "block min-w-0" }, providers: [
3028
3103
  {
3029
3104
  provide: NG_VALUE_ACCESSOR,
3030
3105
  useExisting: forwardRef(() => ZCalendarComponent),
3031
3106
  multi: true,
3032
3107
  },
3033
3108
  TranslatePipe,
3034
- ], 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 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 w-0 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 w-0 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 w-0 min-w-0 flex-1 truncate bg-transparent text-sm outline-none\"\n [placeholder]=\"effectivePlaceholder()\"\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-sm transition-all\"\n [class.opacity-0]=\"!hasValue()\"\n [class.pointer-events-none]=\"!hasValue()\"\n (click)=\"onClear($event)\">\n <z-icon zType=\"lucideX\" zSize=\"18\" />\n </button>\n }\n </div>\n </div>\n\n @if (hasError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n</div>\n\n<ng-template #calendarTpl>\n <div\n class=\"z-calendar-calendar bg-popover border-border flex max-h-[50dvh] max-w-[calc(100vw-1.5rem)] flex-col overflow-hidden rounded-sm border shadow-lg min-[480px]:max-h-[55dvh] sm:max-h-none sm:max-w-none sm:flex-row sm:overflow-visible\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border hidden shrink-0 flex-col gap-0 space-y-1 overflow-y-auto border-r p-2 sm:flex\">\n @for (preset of quickSelectPresets; track preset.key) {\n @let presetDisabled = preset | zIsPresetDisabled: zDisabledDate();\n <button\n type=\"button\"\n class=\"cursor-pointer rounded-sm 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 | translate }}\n </button>\n }\n </div>\n }\n <div\n class=\"flex min-h-0 flex-1 flex-col items-center overflow-hidden pb-0 sm:overflow-visible sm:py-2\"\n [class.sm:pt-0!]=\"isTimeMode()\"\n [class]=\"\n !isRangeMode()\n ? 'w-[17.75rem] max-w-[calc(100vw-1.5rem)]'\n : 'w-[17.75rem] max-w-[calc(100vw-1.5rem)] sm:w-auto sm:max-w-none'\n \">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border w-full border-b px-2 pt-2 pb-2 sm:hidden\">\n <z-select\n class=\"w-full\"\n zSize=\"sm\"\n zPosition=\"bottom-left\"\n [zShowSearch]=\"false\"\n [zAllowClear]=\"false\"\n [zOptions]=\"quickSelectOptions()\"\n [ngModel]=\"activePresetKey()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"onQuickSelectKeyChange($event)\" />\n </div>\n }\n <div class=\"min-h-0 w-full flex-1 overflow-x-hidden overflow-y-auto pt-2 sm:overflow-visible sm:pt-0\">\n @if (!isTimeMode()) {\n <div\n class=\"z-calendars-wrapper flex w-full flex-col items-center gap-0 sm:flex-row sm:items-stretch sm:justify-center\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex w-[17.5rem] shrink-0 flex-col\">\n @if (!isTimeMode()) {\n <!-- Header -->\n <div class=\"border-border flex w-full items-center justify-between gap-0.5 px-2\">\n <!-- Double left arrow (always visible) -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n (click)=\"navigatePreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"18\" />\n </button>\n\n <!-- Single left arrow (hidden in month/year view) -->\n @if (currentView() === 'day') {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n (click)=\"navigatePrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"18\" />\n </button>\n }\n\n <!-- Header content -->\n <div class=\"flex flex-1 shrink-0 items-center justify-center gap-0\">\n @if (currentView() === 'day') {\n <!-- Day view: Month + Year -->\n @if (!isYearMode() && !isQuarterMode()) {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setView('month')\">\n {{ currentMonthName() }}\n </button>\n }\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n [zDisabled]=\"isYearMode()\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n } @else if (currentView() === 'month') {\n <!-- Month view: Only Year -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n } @else if (currentView() === 'year') {\n <!-- Year view: Year Range -->\n <span class=\"text-sm font-medium\">\n {{ yearRange()[0] }} - {{ yearRange()[yearRange().length - 1] }}\n </span>\n } @else if (currentView() === 'quarter') {\n <!-- Quarter view: Only Year -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n }\n </div>\n\n <!-- Single right arrow (hidden in month/year view) -->\n @if (currentView() === 'day') {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"18\" />\n </button>\n }\n\n <!-- Double right arrow (always visible) -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"18\" />\n </button>\n </div>\n\n <!-- Body -->\n <div\n class=\"flex h-full w-full flex-col items-center justify-center p-2\"\n [class.min-h-[14rem]]=\"!isQuarterMode()\"\n [class.h-[14rem]]=\"\n !isYearMode() &&\n !isMonthMode() &&\n !isQuarterMode() &&\n (currentView() === 'month' || currentView() === 'year')\n \"\n [class.min-h-[6.25rem]]=\"isQuarterMode()\"\n [class.!min-h-auto]=\"isYearMode() || isMonthMode() || isQuarterMode()\"\n [class.!h-auto]=\"isYearMode() || isMonthMode() || isQuarterMode()\">\n @if (currentView() === 'day') {\n <div\n class=\"flex h-full w-full flex-1 flex-col gap-1\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n <!-- Weekday headers -->\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (weekday of weekdayNames(); track weekday) {\n <div\n class=\"text-muted-foreground flex h-[1.875rem] w-[2.0313rem] items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n <!-- Date rows -->\n @for (week of calendarDays(); track $index) {\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n class=\"h-[1.875rem] !w-[2.0313rem] !text-sm\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (currentView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n @for (month of monthNames(); track month; let i = $index) {\n @let monthDisabled = i | zIsStartMonthDisabled: startMonthDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: selectedMonthIndex() : todayMonthIndex()\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"monthDisabled\"\n [class.opacity-30]=\"monthDisabled\"\n [class.cursor-not-allowed]=\"monthDisabled\"\n (click)=\"onMonthSelect(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n @for (year of yearRange(); track year) {\n @let yearDisabled = year | zIsStartYearDisabled: startYearDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: selectedYear() : todayYear()\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"yearDisabled\"\n [class.opacity-30]=\"yearDisabled\"\n [class.cursor-not-allowed]=\"yearDisabled\"\n (click)=\"onYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'quarter') {\n <div\n class=\"grid h-full w-full grid-cols-2 grid-rows-2 gap-2 p-1\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n @for (quarter of quarterNames; track quarter; let i = $index) {\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zQuarterClasses: selectedQuarterIndex() : todayQuarterIndex()\"\n class=\"!h-8 !w-full !text-sm\"\n (click)=\"onQuarterClick(i)\">\n {{ quarter }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div\n class=\"border-border bg-border mb-2 hidden self-stretch sm:block sm:w-px\"\n [class.mb-2]=\"!zQuickSelect() || (zQuickSelect() && zShowOk())\"></div>\n <div class=\"border-border bg-border block h-px w-full sm:hidden\"></div>\n\n <div class=\"z-calendar-section flex w-[17.5rem] shrink-0 flex-col pt-2 sm:pt-0\">\n <!-- Header -->\n <div class=\"border-border flex w-full items-center justify-between gap-0.5 px-2\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"18\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"18\" />\n </button>\n\n <div class=\"flex w-[7.5rem] shrink-0 items-center justify-center gap-0\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setEndView('month')\">\n {{ endMonthName() }}\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setEndView('year')\">\n {{ endMonthYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"18\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"18\" />\n </button>\n </div>\n\n <!-- Body -->\n <div\n class=\"flex h-full min-h-[14rem] w-full flex-col items-center justify-center p-2\"\n [class.h-[14rem]]=\"endView() === 'month' || endView() === 'year'\">\n @if (endView() === 'day') {\n <div\n class=\"flex h-full w-full flex-1 flex-col gap-1\"\n [class.animate-calendar-enter]=\"uiState().hasEndViewChanged\">\n <!-- Weekday headers -->\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (weekday of weekdayNames(); track weekday) {\n <div\n class=\"text-muted-foreground flex h-[1.875rem] w-[2.0313rem] items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n <!-- Date rows -->\n @for (week of calendarDaysEnd(); track $index) {\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n class=\"h-[1.875rem] !w-[2.0313rem] !text-sm\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (endView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasEndViewChanged\">\n @for (month of monthNames(); track month; let i = $index) {\n @let endMonthDisabled = i | zIsEndMonthDisabled: endMonthDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: endMonth().getMonth() : -1\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"endMonthDisabled\"\n [class.opacity-30]=\"endMonthDisabled\"\n [class.cursor-not-allowed]=\"endMonthDisabled\"\n (click)=\"onEndMonthClick(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (endView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasEndViewChanged\">\n @for (year of endYearRange(); track year) {\n @let endYearDisabled = year | zIsEndYearDisabled: endYearDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: endMonth().getFullYear() : -1\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"endYearDisabled\"\n [class.opacity-30]=\"endYearDisabled\"\n [class.cursor-not-allowed]=\"endYearDisabled\"\n (click)=\"onEndYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Compact Time Picker Below Calendar (Single Date) -->\n @if (!isRangeMode() && zShowTime()) {\n <div\n class=\"hover:bg-muted border-border flex w-full cursor-pointer items-center justify-center gap-1.5 border-t px-3 py-1.5 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownTpl\"\n zPosition=\"bottom\"\n [zPopoverWidth]=\"240\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-lg\"\n (zShow)=\"onTimeDropdownShow()\">\n <z-icon zType=\"lucideCalendarClock\" zSize=\"18\" class=\"text-muted-foreground mr-1 shrink-0\" />\n <span class=\"text-sm font-medium tabular-nums select-none\">\n @if (zShowHour()) {\n {{ formattedHour() }}\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n {{ formattedMinute() }}\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n {{ formattedSecond() }}\n }\n @if (zTimeFormat() === '12h') {\n <span class=\"text-primary ml-0.5 font-semibold\">\n {{ period() }}\n </span>\n }\n </span>\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"text-muted-foreground shrink-0\" />\n </div>\n }\n\n <!-- Compact Time Pickers Below Calendars (Range Mode) -->\n @if (isRangeMode() && zShowTime()) {\n <div class=\"border-border flex w-full flex-col border-t sm:flex-row\">\n <!-- Start Time -->\n <div\n class=\"hover:bg-muted flex flex-1 cursor-pointer items-center justify-center gap-1.5 px-3 py-1.5 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownTpl\"\n zPosition=\"bottom\"\n [zPopoverWidth]=\"240\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-lg\"\n (zShow)=\"onTimeDropdownShow()\">\n <z-icon zType=\"lucideCalendarClock\" zSize=\"18\" class=\"text-muted-foreground mr-1 shrink-0\" />\n <span class=\"text-sm font-medium tabular-nums select-none\">\n @if (zShowHour()) {\n {{ formattedHour() }}\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n {{ formattedMinute() }}\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n {{ formattedSecond() }}\n }\n @if (zTimeFormat() === '12h') {\n <span class=\"text-primary ml-0.5 font-semibold\">\n {{ period() }}\n </span>\n }\n </span>\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"text-muted-foreground shrink-0\" />\n </div>\n\n <!-- Divider -->\n <div class=\"border-border bg-border h-px self-stretch sm:block sm:h-full sm:w-px\"></div>\n\n <!-- End Time -->\n <div\n class=\"hover:bg-muted flex flex-1 cursor-pointer items-center justify-center gap-1.5 px-3 py-1.5 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownEndTpl\"\n zPosition=\"bottom\"\n [zPopoverWidth]=\"240\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-lg\"\n (zShow)=\"onTimeDropdownEndShow()\">\n <z-icon zType=\"lucideCalendarClock\" zSize=\"18\" class=\"text-muted-foreground mr-1 shrink-0\" />\n <span class=\"text-sm font-medium tabular-nums select-none\">\n @if (zShowHour()) {\n {{ formattedHourEnd() }}\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n {{ formattedMinuteEnd() }}\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n {{ formattedSecondEnd() }}\n }\n @if (zTimeFormat() === '12h') {\n <span class=\"text-primary ml-0.5 font-semibold\">\n {{ periodEnd() }}\n </span>\n }\n </span>\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"text-muted-foreground shrink-0\" />\n </div>\n </div>\n }\n } @else {\n <!-- Time Only Mode -->\n <div class=\"flex w-full justify-center px-2 pt-2 pb-1\">\n <ng-container [ngTemplateOutlet]=\"timeDropdownTpl\" />\n </div>\n }\n </div>\n\n @if (!(zQuickSelect() && zMode() === 'range' && !showOkButton() && !showCancelButton())) {\n <div\n class=\"bg-popover border-border z-10 flex w-full shrink-0 items-center justify-between gap-2 border-t px-2 py-2 shadow-[0_-2px_8px_-2px_rgb(0_0_0_/_10%)] sm:pt-2 sm:pb-0 sm:shadow-none\">\n @if (!zQuickSelect() || zMode() !== 'range') {\n <button type=\"button\" z-button zType=\"secondary\" zSize=\"sm\" [zWave]=\"false\" (click)=\"onTodayClick()\">\n {{ todayButtonText() }}\n </button>\n } @else {\n <div></div>\n }\n\n @if (showOkButton() || showCancelButton()) {\n <div class=\"flex items-center gap-2\">\n @if (showCancelButton()) {\n <button type=\"button\" z-button zType=\"outline\" zSize=\"sm\" (click)=\"onCancelClick()\">\n {{ zCancelText() ?? ('i18n_z_ui_calendar_cancel' | translate) }}\n </button>\n }\n @if (showOkButton()) {\n <button type=\"button\" z-button zSize=\"sm\" [zDisabled]=\"!canApply()\" (click)=\"onOkClick()\">\n {{ zOkText() ?? ('i18n_z_ui_calendar_ok' | translate) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #timeDropdownTpl>\n <div class=\"bg-popover flex min-w-56 justify-center overflow-hidden rounded-sm\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_hour' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-hour h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowMinute() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrSelected = hr === displayHour();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrSelected\"\n [class.bg-primary]=\"hrSelected\"\n [class.text-primary-foreground]=\"hrSelected\"\n [class.font-medium]=\"hrSelected\"\n (click)=\"selectHour(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_minute' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-minute h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"!zShowHour() && (zShowSecond() || zTimeFormat() === '12h')\"\n [class.rounded-br-sm]=\"(zShowHour() || !zShowHour()) && !zShowSecond() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minSelected = min === minute();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minSelected\"\n [class.bg-primary]=\"minSelected\"\n [class.text-primary-foreground]=\"minSelected\"\n [class.font-medium]=\"minSelected\"\n (click)=\"selectMinute(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zTimeFormat() === '12h'\"\n [class.border-border]=\"zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_second' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-second h-[11rem] w-14\"\n [class.rounded-br-sm]=\"zTimeFormat() !== '12h'\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowMinute() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secSelected = sec === second();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secSelected\"\n [class.bg-primary]=\"secSelected\"\n [class.text-primary-foreground]=\"secSelected\"\n [class.font-medium]=\"secSelected\"\n (click)=\"selectSecond(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_period' | translate }}\n </div>\n <ng-scrollbar class=\"z-time-scroll-period h-[11rem] w-14\" [class.rounded-br-sm]=\"true\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (p of ['AM', 'PM']; track p) {\n @let pSelected = p === period();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!pSelected\"\n [class.bg-primary]=\"pSelected\"\n [class.text-primary-foreground]=\"pSelected\"\n [class.font-medium]=\"pSelected\"\n (click)=\"selectPeriod($any(p))\">\n {{ p }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #timeDropdownEndTpl>\n <div class=\"bg-popover flex min-w-56 justify-center overflow-hidden rounded-sm\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_hour' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-hour-end h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowMinute() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrDisabled = hr | zIsEndHourDisabled: endTimeContext();\n @let hrEndSelected = hr === displayHourEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrDisabled && !hrEndSelected\"\n [class.cursor-pointer]=\"!hrDisabled\"\n [class.bg-primary]=\"hrEndSelected\"\n [class.text-primary-foreground]=\"hrEndSelected\"\n [class.font-medium]=\"hrEndSelected\"\n [class.opacity-30]=\"hrDisabled\"\n [class.cursor-not-allowed]=\"hrDisabled\"\n [disabled]=\"hrDisabled\"\n (click)=\"selectHourEnd(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_minute' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-minute-end h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"!zShowHour() && (zShowSecond() || zTimeFormat() === '12h')\"\n [class.rounded-br-sm]=\"(zShowHour() || !zShowHour()) && !zShowSecond() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minDisabled = min | zIsEndMinuteDisabled: endTimeContext();\n @let minEndSelected = min === minuteEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minDisabled && !minEndSelected\"\n [class.cursor-pointer]=\"!minDisabled\"\n [class.bg-primary]=\"minEndSelected\"\n [class.text-primary-foreground]=\"minEndSelected\"\n [class.font-medium]=\"minEndSelected\"\n [class.opacity-30]=\"minDisabled\"\n [class.cursor-not-allowed]=\"minDisabled\"\n [disabled]=\"minDisabled\"\n (click)=\"selectMinuteEnd(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zTimeFormat() === '12h'\"\n [class.border-border]=\"zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_second' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-second-end h-[11rem] w-14\"\n [class.rounded-br-sm]=\"zTimeFormat() !== '12h'\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowMinute() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secDisabled = sec | zIsEndSecondDisabled: endTimeContext();\n @let secEndSelected = sec === secondEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secDisabled && !secEndSelected\"\n [class.cursor-pointer]=\"!secDisabled\"\n [class.bg-primary]=\"secEndSelected\"\n [class.text-primary-foreground]=\"secEndSelected\"\n [class.font-medium]=\"secEndSelected\"\n [class.opacity-30]=\"secDisabled\"\n [class.cursor-not-allowed]=\"secDisabled\"\n [disabled]=\"secDisabled\"\n (click)=\"selectSecondEnd(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_period' | translate }}\n </div>\n <ng-scrollbar class=\"z-time-scroll-period-end h-[11rem] w-14\" [class.rounded-br-sm]=\"true\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (p of ['AM', 'PM']; track p) {\n @let pSelected = p === periodEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!pSelected\"\n [class.bg-primary]=\"pSelected\"\n [class.text-primary-foreground]=\"pSelected\"\n [class.font-medium]=\"pSelected\"\n (click)=\"selectPeriodEnd($any(p))\">\n {{ p }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n", styles: [".animate-calendar-enter{animation:z-calendar-view-enter .2s ease-out}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(.25rem)}to{opacity:1;transform:scale(1) translateY(0)}}.z-calendar input{text-overflow:ellipsis;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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: "component", type: ZSelectComponent, selector: "z-select", inputs: ["class", "zMode", "zSize", "zLabel", "zLabelClass", "zPlaceholder", "zRequired", "zDisabled", "zReadonly", "zLoading", "zPrefix", "zAllowClear", "zWrap", "zShowSearch", "zPlaceholderSearch", "zDebounce", "zNotFoundText", "zEmptyText", "zEmptyIcon", "zMaxTagCount", "zDropdownMaxHeight", "zOptionHeight", "zVirtualScroll", "zShowAction", "zOptions", "zConfig", "zTranslateLabels", "zKey", "zSearchServer", "zLoadingMore", "zEnableLoadMore", "zScrollDistance", "zMaxVisible", "zScrollClose", "zPosition", "zSelectedTemplate", "zOptionTemplate", "zActionTemplate", "zAsyncValidators", "zAsyncDebounce", "zAsyncValidateOn", "zValidators"], outputs: ["zOnSearch", "zOnLoadMore", "zOnBlur", "zOnFocus", "zControl", "zEvent"], exportAs: ["zSelect"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zTriggerRef", "zManualClose", "zScrollClose", "zShowArrow"], outputs: ["zShow", "zHide", "zHideStart", "zControl", "zPositionChange"], 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: ZIsEndHourDisabledPipe, name: "zIsEndHourDisabled" }, { kind: "pipe", type: ZIsEndMinuteDisabledPipe, name: "zIsEndMinuteDisabled" }, { kind: "pipe", type: ZIsEndSecondDisabledPipe, name: "zIsEndSecondDisabled" }, { kind: "pipe", type: ZIsStartMonthDisabledPipe, name: "zIsStartMonthDisabled" }, { kind: "pipe", type: ZIsEndMonthDisabledPipe, name: "zIsEndMonthDisabled" }, { kind: "pipe", type: ZIsStartYearDisabledPipe, name: "zIsStartYearDisabled" }, { kind: "pipe", type: ZIsEndYearDisabledPipe, name: "zIsEndYearDisabled" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
3109
+ ], 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 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 w-0 min-w-0 flex-1 truncate bg-transparent text-sm outline-none disabled:opacity-100\"\n [class.cursor-pointer]=\"!zAllowEdit()\"\n [class.pointer-events-none]=\"!zAllowEdit()\"\n [class.text-center]=\"!rangeShortDisplayValue()\"\n [class.text-left]=\"rangeShortDisplayValue()\"\n [placeholder]=\"'i18n_z_ui_calendar_start_date' | translate\"\n [value]=\"inputDisplayStart()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly() || !zAllowEdit()\"\n (click)=\"zAllowEdit() && 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 @if (!rangeShortDisplayValue()) {\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 w-0 min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none disabled:opacity-100\"\n [class.cursor-pointer]=\"!zAllowEdit()\"\n [class.pointer-events-none]=\"!zAllowEdit()\"\n [placeholder]=\"'i18n_z_ui_calendar_end_date' | translate\"\n [value]=\"inputDisplayEnd()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly() || !zAllowEdit()\"\n (click)=\"zAllowEdit() && 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 }\n } @else {\n <input\n #inputEl\n type=\"text\"\n class=\"placeholder:text-muted-foreground w-0 min-w-0 flex-1 truncate bg-transparent text-sm outline-none disabled:opacity-100\"\n [class.cursor-pointer]=\"!zAllowEdit()\"\n [class.pointer-events-none]=\"!zAllowEdit()\"\n [placeholder]=\"effectivePlaceholder()\"\n [value]=\"inputDisplayValue()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly() || !zAllowEdit()\"\n (click)=\"zAllowEdit() && 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-sm transition-all\"\n [class.opacity-0]=\"!hasValue()\"\n [class.pointer-events-none]=\"!hasValue()\"\n (click)=\"onClear($event)\">\n <z-icon zType=\"lucideX\" zSize=\"18\" />\n </button>\n }\n </div>\n </div>\n\n @if (hasError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n</div>\n\n<ng-template #calendarTpl>\n <div\n class=\"z-calendar-calendar bg-popover border-border flex max-h-[50dvh] max-w-[calc(100vw-1.5rem)] flex-col overflow-hidden rounded-sm border shadow-lg min-[480px]:max-h-[55dvh] sm:max-h-none sm:max-w-none sm:flex-row sm:overflow-visible\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border hidden shrink-0 flex-col gap-0 space-y-1 overflow-y-auto border-r p-2 sm:flex\">\n @for (preset of quickSelectPresets; track preset.key) {\n @let presetDisabled = preset | zIsPresetDisabled: zDisabledDate();\n <button\n type=\"button\"\n class=\"cursor-pointer rounded-sm 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 | translate }}\n </button>\n }\n </div>\n }\n <div\n class=\"flex min-h-0 flex-1 flex-col items-center overflow-hidden pb-0 sm:overflow-visible sm:py-2\"\n [class.sm:pt-0!]=\"isTimeMode()\"\n [class]=\"\n !isRangeMode()\n ? 'w-[17.75rem] max-w-[calc(100vw-1.5rem)]'\n : 'w-[17.75rem] max-w-[calc(100vw-1.5rem)] sm:w-auto sm:max-w-none'\n \">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border w-full border-b px-2 pt-2 pb-2 sm:hidden\">\n <z-select\n class=\"w-full\"\n zSize=\"sm\"\n zPosition=\"bottom-left\"\n [zShowSearch]=\"false\"\n [zAllowClear]=\"false\"\n [zOptions]=\"quickSelectOptions()\"\n [ngModel]=\"activePresetKey()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"onQuickSelectKeyChange($event)\" />\n </div>\n }\n <div class=\"min-h-0 w-full flex-1 overflow-x-hidden overflow-y-auto pt-2 sm:overflow-visible sm:pt-0\">\n @if (!isTimeMode()) {\n <div\n class=\"z-calendars-wrapper flex w-full flex-col items-center gap-0 sm:flex-row sm:items-stretch sm:justify-center\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex w-[17.5rem] shrink-0 flex-col\">\n @if (!isTimeMode()) {\n <!-- Header -->\n <div class=\"border-border flex w-full items-center justify-between gap-0.5 px-2\">\n <!-- Double left arrow (always visible) -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n (click)=\"navigatePreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"18\" />\n </button>\n\n <!-- Single left arrow (hidden in month/year view) -->\n @if (currentView() === 'day') {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n (click)=\"navigatePrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"18\" />\n </button>\n }\n\n <!-- Header content -->\n <div class=\"flex flex-1 shrink-0 items-center justify-center gap-0\">\n @if (currentView() === 'day') {\n <!-- Day view: Month + Year -->\n @if (!isYearMode() && !isQuarterMode()) {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setView('month')\">\n {{ currentMonthName() }}\n </button>\n }\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n [zDisabled]=\"isYearMode()\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n } @else if (currentView() === 'month') {\n <!-- Month view: Only Year -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n } @else if (currentView() === 'year') {\n <!-- Year view: Year Range -->\n <span class=\"text-sm font-medium\">\n {{ yearRange()[0] }} - {{ yearRange()[yearRange().length - 1] }}\n </span>\n } @else if (currentView() === 'quarter') {\n <!-- Quarter view: Only Year -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n }\n </div>\n\n <!-- Single right arrow (hidden in month/year view) -->\n @if (currentView() === 'day') {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"18\" />\n </button>\n }\n\n <!-- Double right arrow (always visible) -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"18\" />\n </button>\n </div>\n\n <!-- Body -->\n <div\n class=\"flex h-full w-full flex-col items-center justify-center p-2\"\n [class.min-h-[14rem]]=\"!isQuarterMode()\"\n [class.h-[14rem]]=\"\n !isYearMode() &&\n !isMonthMode() &&\n !isQuarterMode() &&\n (currentView() === 'month' || currentView() === 'year')\n \"\n [class.min-h-[6.25rem]]=\"isQuarterMode()\"\n [class.!min-h-auto]=\"isYearMode() || isMonthMode() || isQuarterMode()\"\n [class.!h-auto]=\"isYearMode() || isMonthMode() || isQuarterMode()\">\n @if (currentView() === 'day') {\n <div\n class=\"flex h-full w-full flex-1 flex-col gap-1\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n <!-- Weekday headers -->\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (weekday of weekdayNames(); track weekday) {\n <div\n class=\"text-muted-foreground flex h-[1.875rem] w-[2.0313rem] items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n <!-- Date rows -->\n @for (week of calendarDays(); track $index) {\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n class=\"h-[1.875rem] !w-[2.0313rem] !text-sm\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (currentView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n @for (month of monthNames(); track month; let i = $index) {\n @let monthDisabled = i | zIsStartMonthDisabled: startMonthDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: selectedMonthIndex() : todayMonthIndex()\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"monthDisabled\"\n [class.opacity-30]=\"monthDisabled\"\n [class.cursor-not-allowed]=\"monthDisabled\"\n (click)=\"onMonthSelect(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n @for (year of yearRange(); track year) {\n @let yearDisabled = year | zIsStartYearDisabled: startYearDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: selectedYear() : todayYear()\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"yearDisabled\"\n [class.opacity-30]=\"yearDisabled\"\n [class.cursor-not-allowed]=\"yearDisabled\"\n (click)=\"onYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'quarter') {\n <div\n class=\"grid h-full w-full grid-cols-2 grid-rows-2 gap-2 p-1\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n @for (quarter of quarterNames; track quarter; let i = $index) {\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zQuarterClasses: selectedQuarterIndex() : todayQuarterIndex()\"\n class=\"!h-8 !w-full !text-sm\"\n (click)=\"onQuarterClick(i)\">\n {{ quarter }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div\n class=\"border-border bg-border mb-2 hidden self-stretch sm:block sm:w-px\"\n [class.mb-2]=\"!zQuickSelect() || (zQuickSelect() && zShowOk())\"></div>\n <div class=\"border-border bg-border block h-px w-full sm:hidden\"></div>\n\n <div class=\"z-calendar-section flex w-[17.5rem] shrink-0 flex-col pt-2 sm:pt-0\">\n <!-- Header -->\n <div class=\"border-border flex w-full items-center justify-between gap-0.5 px-2\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"18\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"18\" />\n </button>\n\n <div class=\"flex w-[7.5rem] shrink-0 items-center justify-center gap-0\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setEndView('month')\">\n {{ endMonthName() }}\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setEndView('year')\">\n {{ endMonthYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"18\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"18\" />\n </button>\n </div>\n\n <!-- Body -->\n <div\n class=\"flex h-full min-h-[14rem] w-full flex-col items-center justify-center p-2\"\n [class.h-[14rem]]=\"endView() === 'month' || endView() === 'year'\">\n @if (endView() === 'day') {\n <div\n class=\"flex h-full w-full flex-1 flex-col gap-1\"\n [class.animate-calendar-enter]=\"uiState().hasEndViewChanged\">\n <!-- Weekday headers -->\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (weekday of weekdayNames(); track weekday) {\n <div\n class=\"text-muted-foreground flex h-[1.875rem] w-[2.0313rem] items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n <!-- Date rows -->\n @for (week of calendarDaysEnd(); track $index) {\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n class=\"h-[1.875rem] !w-[2.0313rem] !text-sm\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (endView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasEndViewChanged\">\n @for (month of monthNames(); track month; let i = $index) {\n @let endMonthDisabled = i | zIsEndMonthDisabled: endMonthDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: endMonth().getMonth() : -1\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"endMonthDisabled\"\n [class.opacity-30]=\"endMonthDisabled\"\n [class.cursor-not-allowed]=\"endMonthDisabled\"\n (click)=\"onEndMonthClick(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (endView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasEndViewChanged\">\n @for (year of endYearRange(); track year) {\n @let endYearDisabled = year | zIsEndYearDisabled: endYearDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: endMonth().getFullYear() : -1\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"endYearDisabled\"\n [class.opacity-30]=\"endYearDisabled\"\n [class.cursor-not-allowed]=\"endYearDisabled\"\n (click)=\"onEndYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Compact Time Picker Below Calendar (Single Date) -->\n @if (!isRangeMode() && zShowTime()) {\n <div\n class=\"hover:bg-muted border-border flex w-full cursor-pointer items-center justify-center gap-1.5 border-t px-3 py-1.5 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownTpl\"\n zPosition=\"bottom\"\n [zPopoverWidth]=\"240\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-lg\"\n (zShow)=\"onTimeDropdownShow()\">\n <z-icon zType=\"lucideCalendarClock\" zSize=\"18\" class=\"text-muted-foreground mr-1 shrink-0\" />\n <span class=\"text-sm font-medium tabular-nums select-none\">\n @if (zShowHour()) {\n {{ formattedHour() }}\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n {{ formattedMinute() }}\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n {{ formattedSecond() }}\n }\n @if (zTimeFormat() === '12h') {\n <span class=\"text-primary ml-0.5 font-semibold\">\n {{ period() }}\n </span>\n }\n </span>\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"text-muted-foreground shrink-0\" />\n </div>\n }\n\n <!-- Compact Time Pickers Below Calendars (Range Mode) -->\n @if (isRangeMode() && zShowTime()) {\n <div class=\"border-border flex w-full flex-col border-t sm:flex-row\">\n <!-- Start Time -->\n <div\n class=\"hover:bg-muted flex flex-1 cursor-pointer items-center justify-center gap-1.5 px-3 py-1.5 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownTpl\"\n zPosition=\"bottom\"\n [zPopoverWidth]=\"240\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-lg\"\n (zShow)=\"onTimeDropdownShow()\">\n <z-icon zType=\"lucideCalendarClock\" zSize=\"18\" class=\"text-muted-foreground mr-1 shrink-0\" />\n <span class=\"text-sm font-medium tabular-nums select-none\">\n @if (zShowHour()) {\n {{ formattedHour() }}\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n {{ formattedMinute() }}\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n {{ formattedSecond() }}\n }\n @if (zTimeFormat() === '12h') {\n <span class=\"text-primary ml-0.5 font-semibold\">\n {{ period() }}\n </span>\n }\n </span>\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"text-muted-foreground shrink-0\" />\n </div>\n\n <!-- Divider -->\n <div class=\"border-border bg-border h-px self-stretch sm:block sm:h-full sm:w-px\"></div>\n\n <!-- End Time -->\n <div\n class=\"hover:bg-muted flex flex-1 cursor-pointer items-center justify-center gap-1.5 px-3 py-1.5 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownEndTpl\"\n zPosition=\"bottom\"\n [zPopoverWidth]=\"240\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-lg\"\n (zShow)=\"onTimeDropdownEndShow()\">\n <z-icon zType=\"lucideCalendarClock\" zSize=\"18\" class=\"text-muted-foreground mr-1 shrink-0\" />\n <span class=\"text-sm font-medium tabular-nums select-none\">\n @if (zShowHour()) {\n {{ formattedHourEnd() }}\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n {{ formattedMinuteEnd() }}\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n {{ formattedSecondEnd() }}\n }\n @if (zTimeFormat() === '12h') {\n <span class=\"text-primary ml-0.5 font-semibold\">\n {{ periodEnd() }}\n </span>\n }\n </span>\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"text-muted-foreground shrink-0\" />\n </div>\n </div>\n }\n } @else {\n <!-- Time Only Mode -->\n <div class=\"flex w-full justify-center px-2 pt-2 pb-1\">\n <ng-container [ngTemplateOutlet]=\"timeDropdownTpl\" />\n </div>\n }\n </div>\n\n @if (!(zQuickSelect() && zMode() === 'range' && !showOkButton() && !showCancelButton())) {\n <div\n class=\"bg-popover border-border z-10 flex w-full shrink-0 items-center justify-between gap-2 border-t px-2 py-2 shadow-[0_-2px_8px_-2px_rgb(0_0_0_/_10%)] sm:pt-2 sm:pb-0 sm:shadow-none\">\n @if (!zQuickSelect() || zMode() !== 'range') {\n <button type=\"button\" z-button zType=\"secondary\" zSize=\"sm\" [zWave]=\"false\" (click)=\"onTodayClick()\">\n {{ todayButtonText() }}\n </button>\n } @else {\n <div></div>\n }\n\n @if (showOkButton() || showCancelButton()) {\n <div class=\"flex items-center gap-2\">\n @if (showCancelButton()) {\n <button type=\"button\" z-button zType=\"outline\" zSize=\"sm\" (click)=\"onCancelClick()\">\n {{ zCancelText() ?? ('i18n_z_ui_calendar_cancel' | translate) }}\n </button>\n }\n @if (showOkButton()) {\n <button type=\"button\" z-button zSize=\"sm\" [zDisabled]=\"!canApply()\" (click)=\"onOkClick()\">\n {{ zOkText() ?? ('i18n_z_ui_calendar_ok' | translate) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #timeDropdownTpl>\n <div class=\"bg-popover flex min-w-56 justify-center overflow-hidden rounded-sm\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_hour' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-hour h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowMinute() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrSelected = hr === displayHour();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrSelected\"\n [class.bg-primary]=\"hrSelected\"\n [class.text-primary-foreground]=\"hrSelected\"\n [class.font-medium]=\"hrSelected\"\n (click)=\"selectHour(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_minute' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-minute h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"!zShowHour() && (zShowSecond() || zTimeFormat() === '12h')\"\n [class.rounded-br-sm]=\"(zShowHour() || !zShowHour()) && !zShowSecond() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minSelected = min === minute();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minSelected\"\n [class.bg-primary]=\"minSelected\"\n [class.text-primary-foreground]=\"minSelected\"\n [class.font-medium]=\"minSelected\"\n (click)=\"selectMinute(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zTimeFormat() === '12h'\"\n [class.border-border]=\"zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_second' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-second h-[11rem] w-14\"\n [class.rounded-br-sm]=\"zTimeFormat() !== '12h'\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowMinute() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secSelected = sec === second();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secSelected\"\n [class.bg-primary]=\"secSelected\"\n [class.text-primary-foreground]=\"secSelected\"\n [class.font-medium]=\"secSelected\"\n (click)=\"selectSecond(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_period' | translate }}\n </div>\n <ng-scrollbar class=\"z-time-scroll-period h-[11rem] w-14\" [class.rounded-br-sm]=\"true\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (p of ['AM', 'PM']; track p) {\n @let pSelected = p === period();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!pSelected\"\n [class.bg-primary]=\"pSelected\"\n [class.text-primary-foreground]=\"pSelected\"\n [class.font-medium]=\"pSelected\"\n (click)=\"selectPeriod($any(p))\">\n {{ p }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #timeDropdownEndTpl>\n <div class=\"bg-popover flex min-w-56 justify-center overflow-hidden rounded-sm\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_hour' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-hour-end h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowMinute() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrDisabled = hr | zIsEndHourDisabled: endTimeContext();\n @let hrEndSelected = hr === displayHourEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrDisabled && !hrEndSelected\"\n [class.cursor-pointer]=\"!hrDisabled\"\n [class.bg-primary]=\"hrEndSelected\"\n [class.text-primary-foreground]=\"hrEndSelected\"\n [class.font-medium]=\"hrEndSelected\"\n [class.opacity-30]=\"hrDisabled\"\n [class.cursor-not-allowed]=\"hrDisabled\"\n [disabled]=\"hrDisabled\"\n (click)=\"selectHourEnd(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_minute' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-minute-end h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"!zShowHour() && (zShowSecond() || zTimeFormat() === '12h')\"\n [class.rounded-br-sm]=\"(zShowHour() || !zShowHour()) && !zShowSecond() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minDisabled = min | zIsEndMinuteDisabled: endTimeContext();\n @let minEndSelected = min === minuteEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minDisabled && !minEndSelected\"\n [class.cursor-pointer]=\"!minDisabled\"\n [class.bg-primary]=\"minEndSelected\"\n [class.text-primary-foreground]=\"minEndSelected\"\n [class.font-medium]=\"minEndSelected\"\n [class.opacity-30]=\"minDisabled\"\n [class.cursor-not-allowed]=\"minDisabled\"\n [disabled]=\"minDisabled\"\n (click)=\"selectMinuteEnd(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zTimeFormat() === '12h'\"\n [class.border-border]=\"zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_second' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-second-end h-[11rem] w-14\"\n [class.rounded-br-sm]=\"zTimeFormat() !== '12h'\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowMinute() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secDisabled = sec | zIsEndSecondDisabled: endTimeContext();\n @let secEndSelected = sec === secondEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secDisabled && !secEndSelected\"\n [class.cursor-pointer]=\"!secDisabled\"\n [class.bg-primary]=\"secEndSelected\"\n [class.text-primary-foreground]=\"secEndSelected\"\n [class.font-medium]=\"secEndSelected\"\n [class.opacity-30]=\"secDisabled\"\n [class.cursor-not-allowed]=\"secDisabled\"\n [disabled]=\"secDisabled\"\n (click)=\"selectSecondEnd(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_period' | translate }}\n </div>\n <ng-scrollbar class=\"z-time-scroll-period-end h-[11rem] w-14\" [class.rounded-br-sm]=\"true\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (p of ['AM', 'PM']; track p) {\n @let pSelected = p === periodEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!pSelected\"\n [class.bg-primary]=\"pSelected\"\n [class.text-primary-foreground]=\"pSelected\"\n [class.font-medium]=\"pSelected\"\n (click)=\"selectPeriodEnd($any(p))\">\n {{ p }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n", styles: [".animate-calendar-enter{animation:z-calendar-view-enter .2s ease-out}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(.25rem)}to{opacity:1;transform:scale(1) translateY(0)}}.z-calendar input{text-overflow:ellipsis;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zAnimatedType", "zAnimate", "zAnimationTrigger", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "component", type: ZSelectComponent, selector: "z-select", inputs: ["class", "zMode", "zSize", "zLabel", "zLabelClass", "zPlaceholder", "zRequired", "zDisabled", "zReadonly", "zLoading", "zPrefix", "zAllowClear", "zWrap", "zShowSearch", "zPlaceholderSearch", "zDebounce", "zNotFoundText", "zEmptyText", "zEmptyIcon", "zMaxTagCount", "zDropdownMaxHeight", "zOptionHeight", "zVirtualScroll", "zShowAction", "zOptions", "zConfig", "zTranslateLabels", "zKey", "zSearchServer", "zLoadingMore", "zEnableLoadMore", "zScrollDistance", "zMaxVisible", "zScrollClose", "zPosition", "zSelectedTemplate", "zOptionTemplate", "zActionTemplate", "zAsyncValidators", "zAsyncDebounce", "zAsyncValidateOn", "zValidators"], outputs: ["zOnSearch", "zOnLoadMore", "zOnBlur", "zOnFocus", "zControl", "zEvent"], exportAs: ["zSelect"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zTriggerRef", "zManualClose", "zOutsideClickClose", "zScrollClose", "zShowArrow"], outputs: ["zShow", "zHide", "zHideStart", "zControl", "zPositionChange"], exportAs: ["zPopover"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zAnimatedTypeIcon", "zAnimateIcon", "zAnimationTriggerIcon", "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: ZIsEndHourDisabledPipe, name: "zIsEndHourDisabled" }, { kind: "pipe", type: ZIsEndMinuteDisabledPipe, name: "zIsEndMinuteDisabled" }, { kind: "pipe", type: ZIsEndSecondDisabledPipe, name: "zIsEndSecondDisabled" }, { kind: "pipe", type: ZIsStartMonthDisabledPipe, name: "zIsStartMonthDisabled" }, { kind: "pipe", type: ZIsEndMonthDisabledPipe, name: "zIsEndMonthDisabled" }, { kind: "pipe", type: ZIsStartYearDisabledPipe, name: "zIsStartYearDisabled" }, { kind: "pipe", type: ZIsEndYearDisabledPipe, name: "zIsEndYearDisabled" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
3035
3110
  }
3036
3111
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZCalendarComponent, decorators: [{
3037
3112
  type: Component,
@@ -3066,8 +3141,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImpor
3066
3141
  TranslatePipe,
3067
3142
  ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
3068
3143
  class: 'block min-w-0',
3069
- }, 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 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 w-0 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 w-0 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 w-0 min-w-0 flex-1 truncate bg-transparent text-sm outline-none\"\n [placeholder]=\"effectivePlaceholder()\"\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-sm transition-all\"\n [class.opacity-0]=\"!hasValue()\"\n [class.pointer-events-none]=\"!hasValue()\"\n (click)=\"onClear($event)\">\n <z-icon zType=\"lucideX\" zSize=\"18\" />\n </button>\n }\n </div>\n </div>\n\n @if (hasError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n</div>\n\n<ng-template #calendarTpl>\n <div\n class=\"z-calendar-calendar bg-popover border-border flex max-h-[50dvh] max-w-[calc(100vw-1.5rem)] flex-col overflow-hidden rounded-sm border shadow-lg min-[480px]:max-h-[55dvh] sm:max-h-none sm:max-w-none sm:flex-row sm:overflow-visible\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border hidden shrink-0 flex-col gap-0 space-y-1 overflow-y-auto border-r p-2 sm:flex\">\n @for (preset of quickSelectPresets; track preset.key) {\n @let presetDisabled = preset | zIsPresetDisabled: zDisabledDate();\n <button\n type=\"button\"\n class=\"cursor-pointer rounded-sm 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 | translate }}\n </button>\n }\n </div>\n }\n <div\n class=\"flex min-h-0 flex-1 flex-col items-center overflow-hidden pb-0 sm:overflow-visible sm:py-2\"\n [class.sm:pt-0!]=\"isTimeMode()\"\n [class]=\"\n !isRangeMode()\n ? 'w-[17.75rem] max-w-[calc(100vw-1.5rem)]'\n : 'w-[17.75rem] max-w-[calc(100vw-1.5rem)] sm:w-auto sm:max-w-none'\n \">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border w-full border-b px-2 pt-2 pb-2 sm:hidden\">\n <z-select\n class=\"w-full\"\n zSize=\"sm\"\n zPosition=\"bottom-left\"\n [zShowSearch]=\"false\"\n [zAllowClear]=\"false\"\n [zOptions]=\"quickSelectOptions()\"\n [ngModel]=\"activePresetKey()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"onQuickSelectKeyChange($event)\" />\n </div>\n }\n <div class=\"min-h-0 w-full flex-1 overflow-x-hidden overflow-y-auto pt-2 sm:overflow-visible sm:pt-0\">\n @if (!isTimeMode()) {\n <div\n class=\"z-calendars-wrapper flex w-full flex-col items-center gap-0 sm:flex-row sm:items-stretch sm:justify-center\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex w-[17.5rem] shrink-0 flex-col\">\n @if (!isTimeMode()) {\n <!-- Header -->\n <div class=\"border-border flex w-full items-center justify-between gap-0.5 px-2\">\n <!-- Double left arrow (always visible) -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n (click)=\"navigatePreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"18\" />\n </button>\n\n <!-- Single left arrow (hidden in month/year view) -->\n @if (currentView() === 'day') {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n (click)=\"navigatePrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"18\" />\n </button>\n }\n\n <!-- Header content -->\n <div class=\"flex flex-1 shrink-0 items-center justify-center gap-0\">\n @if (currentView() === 'day') {\n <!-- Day view: Month + Year -->\n @if (!isYearMode() && !isQuarterMode()) {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setView('month')\">\n {{ currentMonthName() }}\n </button>\n }\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n [zDisabled]=\"isYearMode()\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n } @else if (currentView() === 'month') {\n <!-- Month view: Only Year -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n } @else if (currentView() === 'year') {\n <!-- Year view: Year Range -->\n <span class=\"text-sm font-medium\">\n {{ yearRange()[0] }} - {{ yearRange()[yearRange().length - 1] }}\n </span>\n } @else if (currentView() === 'quarter') {\n <!-- Quarter view: Only Year -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n }\n </div>\n\n <!-- Single right arrow (hidden in month/year view) -->\n @if (currentView() === 'day') {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"18\" />\n </button>\n }\n\n <!-- Double right arrow (always visible) -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"18\" />\n </button>\n </div>\n\n <!-- Body -->\n <div\n class=\"flex h-full w-full flex-col items-center justify-center p-2\"\n [class.min-h-[14rem]]=\"!isQuarterMode()\"\n [class.h-[14rem]]=\"\n !isYearMode() &&\n !isMonthMode() &&\n !isQuarterMode() &&\n (currentView() === 'month' || currentView() === 'year')\n \"\n [class.min-h-[6.25rem]]=\"isQuarterMode()\"\n [class.!min-h-auto]=\"isYearMode() || isMonthMode() || isQuarterMode()\"\n [class.!h-auto]=\"isYearMode() || isMonthMode() || isQuarterMode()\">\n @if (currentView() === 'day') {\n <div\n class=\"flex h-full w-full flex-1 flex-col gap-1\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n <!-- Weekday headers -->\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (weekday of weekdayNames(); track weekday) {\n <div\n class=\"text-muted-foreground flex h-[1.875rem] w-[2.0313rem] items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n <!-- Date rows -->\n @for (week of calendarDays(); track $index) {\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n class=\"h-[1.875rem] !w-[2.0313rem] !text-sm\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (currentView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n @for (month of monthNames(); track month; let i = $index) {\n @let monthDisabled = i | zIsStartMonthDisabled: startMonthDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: selectedMonthIndex() : todayMonthIndex()\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"monthDisabled\"\n [class.opacity-30]=\"monthDisabled\"\n [class.cursor-not-allowed]=\"monthDisabled\"\n (click)=\"onMonthSelect(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n @for (year of yearRange(); track year) {\n @let yearDisabled = year | zIsStartYearDisabled: startYearDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: selectedYear() : todayYear()\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"yearDisabled\"\n [class.opacity-30]=\"yearDisabled\"\n [class.cursor-not-allowed]=\"yearDisabled\"\n (click)=\"onYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'quarter') {\n <div\n class=\"grid h-full w-full grid-cols-2 grid-rows-2 gap-2 p-1\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n @for (quarter of quarterNames; track quarter; let i = $index) {\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zQuarterClasses: selectedQuarterIndex() : todayQuarterIndex()\"\n class=\"!h-8 !w-full !text-sm\"\n (click)=\"onQuarterClick(i)\">\n {{ quarter }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div\n class=\"border-border bg-border mb-2 hidden self-stretch sm:block sm:w-px\"\n [class.mb-2]=\"!zQuickSelect() || (zQuickSelect() && zShowOk())\"></div>\n <div class=\"border-border bg-border block h-px w-full sm:hidden\"></div>\n\n <div class=\"z-calendar-section flex w-[17.5rem] shrink-0 flex-col pt-2 sm:pt-0\">\n <!-- Header -->\n <div class=\"border-border flex w-full items-center justify-between gap-0.5 px-2\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"18\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"18\" />\n </button>\n\n <div class=\"flex w-[7.5rem] shrink-0 items-center justify-center gap-0\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setEndView('month')\">\n {{ endMonthName() }}\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setEndView('year')\">\n {{ endMonthYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"18\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"18\" />\n </button>\n </div>\n\n <!-- Body -->\n <div\n class=\"flex h-full min-h-[14rem] w-full flex-col items-center justify-center p-2\"\n [class.h-[14rem]]=\"endView() === 'month' || endView() === 'year'\">\n @if (endView() === 'day') {\n <div\n class=\"flex h-full w-full flex-1 flex-col gap-1\"\n [class.animate-calendar-enter]=\"uiState().hasEndViewChanged\">\n <!-- Weekday headers -->\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (weekday of weekdayNames(); track weekday) {\n <div\n class=\"text-muted-foreground flex h-[1.875rem] w-[2.0313rem] items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n <!-- Date rows -->\n @for (week of calendarDaysEnd(); track $index) {\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n class=\"h-[1.875rem] !w-[2.0313rem] !text-sm\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (endView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasEndViewChanged\">\n @for (month of monthNames(); track month; let i = $index) {\n @let endMonthDisabled = i | zIsEndMonthDisabled: endMonthDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: endMonth().getMonth() : -1\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"endMonthDisabled\"\n [class.opacity-30]=\"endMonthDisabled\"\n [class.cursor-not-allowed]=\"endMonthDisabled\"\n (click)=\"onEndMonthClick(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (endView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasEndViewChanged\">\n @for (year of endYearRange(); track year) {\n @let endYearDisabled = year | zIsEndYearDisabled: endYearDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: endMonth().getFullYear() : -1\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"endYearDisabled\"\n [class.opacity-30]=\"endYearDisabled\"\n [class.cursor-not-allowed]=\"endYearDisabled\"\n (click)=\"onEndYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Compact Time Picker Below Calendar (Single Date) -->\n @if (!isRangeMode() && zShowTime()) {\n <div\n class=\"hover:bg-muted border-border flex w-full cursor-pointer items-center justify-center gap-1.5 border-t px-3 py-1.5 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownTpl\"\n zPosition=\"bottom\"\n [zPopoverWidth]=\"240\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-lg\"\n (zShow)=\"onTimeDropdownShow()\">\n <z-icon zType=\"lucideCalendarClock\" zSize=\"18\" class=\"text-muted-foreground mr-1 shrink-0\" />\n <span class=\"text-sm font-medium tabular-nums select-none\">\n @if (zShowHour()) {\n {{ formattedHour() }}\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n {{ formattedMinute() }}\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n {{ formattedSecond() }}\n }\n @if (zTimeFormat() === '12h') {\n <span class=\"text-primary ml-0.5 font-semibold\">\n {{ period() }}\n </span>\n }\n </span>\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"text-muted-foreground shrink-0\" />\n </div>\n }\n\n <!-- Compact Time Pickers Below Calendars (Range Mode) -->\n @if (isRangeMode() && zShowTime()) {\n <div class=\"border-border flex w-full flex-col border-t sm:flex-row\">\n <!-- Start Time -->\n <div\n class=\"hover:bg-muted flex flex-1 cursor-pointer items-center justify-center gap-1.5 px-3 py-1.5 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownTpl\"\n zPosition=\"bottom\"\n [zPopoverWidth]=\"240\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-lg\"\n (zShow)=\"onTimeDropdownShow()\">\n <z-icon zType=\"lucideCalendarClock\" zSize=\"18\" class=\"text-muted-foreground mr-1 shrink-0\" />\n <span class=\"text-sm font-medium tabular-nums select-none\">\n @if (zShowHour()) {\n {{ formattedHour() }}\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n {{ formattedMinute() }}\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n {{ formattedSecond() }}\n }\n @if (zTimeFormat() === '12h') {\n <span class=\"text-primary ml-0.5 font-semibold\">\n {{ period() }}\n </span>\n }\n </span>\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"text-muted-foreground shrink-0\" />\n </div>\n\n <!-- Divider -->\n <div class=\"border-border bg-border h-px self-stretch sm:block sm:h-full sm:w-px\"></div>\n\n <!-- End Time -->\n <div\n class=\"hover:bg-muted flex flex-1 cursor-pointer items-center justify-center gap-1.5 px-3 py-1.5 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownEndTpl\"\n zPosition=\"bottom\"\n [zPopoverWidth]=\"240\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-lg\"\n (zShow)=\"onTimeDropdownEndShow()\">\n <z-icon zType=\"lucideCalendarClock\" zSize=\"18\" class=\"text-muted-foreground mr-1 shrink-0\" />\n <span class=\"text-sm font-medium tabular-nums select-none\">\n @if (zShowHour()) {\n {{ formattedHourEnd() }}\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n {{ formattedMinuteEnd() }}\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n {{ formattedSecondEnd() }}\n }\n @if (zTimeFormat() === '12h') {\n <span class=\"text-primary ml-0.5 font-semibold\">\n {{ periodEnd() }}\n </span>\n }\n </span>\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"text-muted-foreground shrink-0\" />\n </div>\n </div>\n }\n } @else {\n <!-- Time Only Mode -->\n <div class=\"flex w-full justify-center px-2 pt-2 pb-1\">\n <ng-container [ngTemplateOutlet]=\"timeDropdownTpl\" />\n </div>\n }\n </div>\n\n @if (!(zQuickSelect() && zMode() === 'range' && !showOkButton() && !showCancelButton())) {\n <div\n class=\"bg-popover border-border z-10 flex w-full shrink-0 items-center justify-between gap-2 border-t px-2 py-2 shadow-[0_-2px_8px_-2px_rgb(0_0_0_/_10%)] sm:pt-2 sm:pb-0 sm:shadow-none\">\n @if (!zQuickSelect() || zMode() !== 'range') {\n <button type=\"button\" z-button zType=\"secondary\" zSize=\"sm\" [zWave]=\"false\" (click)=\"onTodayClick()\">\n {{ todayButtonText() }}\n </button>\n } @else {\n <div></div>\n }\n\n @if (showOkButton() || showCancelButton()) {\n <div class=\"flex items-center gap-2\">\n @if (showCancelButton()) {\n <button type=\"button\" z-button zType=\"outline\" zSize=\"sm\" (click)=\"onCancelClick()\">\n {{ zCancelText() ?? ('i18n_z_ui_calendar_cancel' | translate) }}\n </button>\n }\n @if (showOkButton()) {\n <button type=\"button\" z-button zSize=\"sm\" [zDisabled]=\"!canApply()\" (click)=\"onOkClick()\">\n {{ zOkText() ?? ('i18n_z_ui_calendar_ok' | translate) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #timeDropdownTpl>\n <div class=\"bg-popover flex min-w-56 justify-center overflow-hidden rounded-sm\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_hour' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-hour h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowMinute() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrSelected = hr === displayHour();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrSelected\"\n [class.bg-primary]=\"hrSelected\"\n [class.text-primary-foreground]=\"hrSelected\"\n [class.font-medium]=\"hrSelected\"\n (click)=\"selectHour(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_minute' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-minute h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"!zShowHour() && (zShowSecond() || zTimeFormat() === '12h')\"\n [class.rounded-br-sm]=\"(zShowHour() || !zShowHour()) && !zShowSecond() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minSelected = min === minute();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minSelected\"\n [class.bg-primary]=\"minSelected\"\n [class.text-primary-foreground]=\"minSelected\"\n [class.font-medium]=\"minSelected\"\n (click)=\"selectMinute(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zTimeFormat() === '12h'\"\n [class.border-border]=\"zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_second' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-second h-[11rem] w-14\"\n [class.rounded-br-sm]=\"zTimeFormat() !== '12h'\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowMinute() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secSelected = sec === second();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secSelected\"\n [class.bg-primary]=\"secSelected\"\n [class.text-primary-foreground]=\"secSelected\"\n [class.font-medium]=\"secSelected\"\n (click)=\"selectSecond(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_period' | translate }}\n </div>\n <ng-scrollbar class=\"z-time-scroll-period h-[11rem] w-14\" [class.rounded-br-sm]=\"true\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (p of ['AM', 'PM']; track p) {\n @let pSelected = p === period();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!pSelected\"\n [class.bg-primary]=\"pSelected\"\n [class.text-primary-foreground]=\"pSelected\"\n [class.font-medium]=\"pSelected\"\n (click)=\"selectPeriod($any(p))\">\n {{ p }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #timeDropdownEndTpl>\n <div class=\"bg-popover flex min-w-56 justify-center overflow-hidden rounded-sm\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_hour' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-hour-end h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowMinute() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrDisabled = hr | zIsEndHourDisabled: endTimeContext();\n @let hrEndSelected = hr === displayHourEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrDisabled && !hrEndSelected\"\n [class.cursor-pointer]=\"!hrDisabled\"\n [class.bg-primary]=\"hrEndSelected\"\n [class.text-primary-foreground]=\"hrEndSelected\"\n [class.font-medium]=\"hrEndSelected\"\n [class.opacity-30]=\"hrDisabled\"\n [class.cursor-not-allowed]=\"hrDisabled\"\n [disabled]=\"hrDisabled\"\n (click)=\"selectHourEnd(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_minute' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-minute-end h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"!zShowHour() && (zShowSecond() || zTimeFormat() === '12h')\"\n [class.rounded-br-sm]=\"(zShowHour() || !zShowHour()) && !zShowSecond() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minDisabled = min | zIsEndMinuteDisabled: endTimeContext();\n @let minEndSelected = min === minuteEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minDisabled && !minEndSelected\"\n [class.cursor-pointer]=\"!minDisabled\"\n [class.bg-primary]=\"minEndSelected\"\n [class.text-primary-foreground]=\"minEndSelected\"\n [class.font-medium]=\"minEndSelected\"\n [class.opacity-30]=\"minDisabled\"\n [class.cursor-not-allowed]=\"minDisabled\"\n [disabled]=\"minDisabled\"\n (click)=\"selectMinuteEnd(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zTimeFormat() === '12h'\"\n [class.border-border]=\"zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_second' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-second-end h-[11rem] w-14\"\n [class.rounded-br-sm]=\"zTimeFormat() !== '12h'\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowMinute() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secDisabled = sec | zIsEndSecondDisabled: endTimeContext();\n @let secEndSelected = sec === secondEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secDisabled && !secEndSelected\"\n [class.cursor-pointer]=\"!secDisabled\"\n [class.bg-primary]=\"secEndSelected\"\n [class.text-primary-foreground]=\"secEndSelected\"\n [class.font-medium]=\"secEndSelected\"\n [class.opacity-30]=\"secDisabled\"\n [class.cursor-not-allowed]=\"secDisabled\"\n [disabled]=\"secDisabled\"\n (click)=\"selectSecondEnd(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_period' | translate }}\n </div>\n <ng-scrollbar class=\"z-time-scroll-period-end h-[11rem] w-14\" [class.rounded-br-sm]=\"true\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (p of ['AM', 'PM']; track p) {\n @let pSelected = p === periodEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!pSelected\"\n [class.bg-primary]=\"pSelected\"\n [class.text-primary-foreground]=\"pSelected\"\n [class.font-medium]=\"pSelected\"\n (click)=\"selectPeriodEnd($any(p))\">\n {{ p }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n", styles: [".animate-calendar-enter{animation:z-calendar-view-enter .2s ease-out}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(.25rem)}to{opacity:1;transform:scale(1) translateY(0)}}.z-calendar input{text-overflow:ellipsis;overflow:hidden}\n"] }]
3070
- }], 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 }] }], 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 }] }], zDefaultTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDefaultTime", required: false }] }], zRangeDefaultTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "zRangeDefaultTime", required: false }] }], zControl: [{ type: i0.Output, args: ["zControl"] }], zChange: [{ type: i0.Output, args: ["zChange"] }], zOnBlur: [{ type: i0.Output, args: ["zOnBlur"] }], zOnFocus: [{ type: i0.Output, args: ["zOnFocus"] }], zEvent: [{ type: i0.Output, args: ["zEvent"] }], triggerRef: [{ type: i0.ViewChild, args: ['triggerEl', { isSignal: true }] }], inputRef: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }] } });
3144
+ }, 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 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 w-0 min-w-0 flex-1 truncate bg-transparent text-sm outline-none disabled:opacity-100\"\n [class.cursor-pointer]=\"!zAllowEdit()\"\n [class.pointer-events-none]=\"!zAllowEdit()\"\n [class.text-center]=\"!rangeShortDisplayValue()\"\n [class.text-left]=\"rangeShortDisplayValue()\"\n [placeholder]=\"'i18n_z_ui_calendar_start_date' | translate\"\n [value]=\"inputDisplayStart()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly() || !zAllowEdit()\"\n (click)=\"zAllowEdit() && 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 @if (!rangeShortDisplayValue()) {\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 w-0 min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none disabled:opacity-100\"\n [class.cursor-pointer]=\"!zAllowEdit()\"\n [class.pointer-events-none]=\"!zAllowEdit()\"\n [placeholder]=\"'i18n_z_ui_calendar_end_date' | translate\"\n [value]=\"inputDisplayEnd()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly() || !zAllowEdit()\"\n (click)=\"zAllowEdit() && 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 }\n } @else {\n <input\n #inputEl\n type=\"text\"\n class=\"placeholder:text-muted-foreground w-0 min-w-0 flex-1 truncate bg-transparent text-sm outline-none disabled:opacity-100\"\n [class.cursor-pointer]=\"!zAllowEdit()\"\n [class.pointer-events-none]=\"!zAllowEdit()\"\n [placeholder]=\"effectivePlaceholder()\"\n [value]=\"inputDisplayValue()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly() || !zAllowEdit()\"\n (click)=\"zAllowEdit() && 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-sm transition-all\"\n [class.opacity-0]=\"!hasValue()\"\n [class.pointer-events-none]=\"!hasValue()\"\n (click)=\"onClear($event)\">\n <z-icon zType=\"lucideX\" zSize=\"18\" />\n </button>\n }\n </div>\n </div>\n\n @if (hasError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n</div>\n\n<ng-template #calendarTpl>\n <div\n class=\"z-calendar-calendar bg-popover border-border flex max-h-[50dvh] max-w-[calc(100vw-1.5rem)] flex-col overflow-hidden rounded-sm border shadow-lg min-[480px]:max-h-[55dvh] sm:max-h-none sm:max-w-none sm:flex-row sm:overflow-visible\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border hidden shrink-0 flex-col gap-0 space-y-1 overflow-y-auto border-r p-2 sm:flex\">\n @for (preset of quickSelectPresets; track preset.key) {\n @let presetDisabled = preset | zIsPresetDisabled: zDisabledDate();\n <button\n type=\"button\"\n class=\"cursor-pointer rounded-sm 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 | translate }}\n </button>\n }\n </div>\n }\n <div\n class=\"flex min-h-0 flex-1 flex-col items-center overflow-hidden pb-0 sm:overflow-visible sm:py-2\"\n [class.sm:pt-0!]=\"isTimeMode()\"\n [class]=\"\n !isRangeMode()\n ? 'w-[17.75rem] max-w-[calc(100vw-1.5rem)]'\n : 'w-[17.75rem] max-w-[calc(100vw-1.5rem)] sm:w-auto sm:max-w-none'\n \">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border w-full border-b px-2 pt-2 pb-2 sm:hidden\">\n <z-select\n class=\"w-full\"\n zSize=\"sm\"\n zPosition=\"bottom-left\"\n [zShowSearch]=\"false\"\n [zAllowClear]=\"false\"\n [zOptions]=\"quickSelectOptions()\"\n [ngModel]=\"activePresetKey()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"onQuickSelectKeyChange($event)\" />\n </div>\n }\n <div class=\"min-h-0 w-full flex-1 overflow-x-hidden overflow-y-auto pt-2 sm:overflow-visible sm:pt-0\">\n @if (!isTimeMode()) {\n <div\n class=\"z-calendars-wrapper flex w-full flex-col items-center gap-0 sm:flex-row sm:items-stretch sm:justify-center\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex w-[17.5rem] shrink-0 flex-col\">\n @if (!isTimeMode()) {\n <!-- Header -->\n <div class=\"border-border flex w-full items-center justify-between gap-0.5 px-2\">\n <!-- Double left arrow (always visible) -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n (click)=\"navigatePreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"18\" />\n </button>\n\n <!-- Single left arrow (hidden in month/year view) -->\n @if (currentView() === 'day') {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n (click)=\"navigatePrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"18\" />\n </button>\n }\n\n <!-- Header content -->\n <div class=\"flex flex-1 shrink-0 items-center justify-center gap-0\">\n @if (currentView() === 'day') {\n <!-- Day view: Month + Year -->\n @if (!isYearMode() && !isQuarterMode()) {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setView('month')\">\n {{ currentMonthName() }}\n </button>\n }\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n [zDisabled]=\"isYearMode()\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n } @else if (currentView() === 'month') {\n <!-- Month view: Only Year -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n } @else if (currentView() === 'year') {\n <!-- Year view: Year Range -->\n <span class=\"text-sm font-medium\">\n {{ yearRange()[0] }} - {{ yearRange()[yearRange().length - 1] }}\n </span>\n } @else if (currentView() === 'quarter') {\n <!-- Quarter view: Only Year -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n }\n </div>\n\n <!-- Single right arrow (hidden in month/year view) -->\n @if (currentView() === 'day') {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"18\" />\n </button>\n }\n\n <!-- Double right arrow (always visible) -->\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"18\" />\n </button>\n </div>\n\n <!-- Body -->\n <div\n class=\"flex h-full w-full flex-col items-center justify-center p-2\"\n [class.min-h-[14rem]]=\"!isQuarterMode()\"\n [class.h-[14rem]]=\"\n !isYearMode() &&\n !isMonthMode() &&\n !isQuarterMode() &&\n (currentView() === 'month' || currentView() === 'year')\n \"\n [class.min-h-[6.25rem]]=\"isQuarterMode()\"\n [class.!min-h-auto]=\"isYearMode() || isMonthMode() || isQuarterMode()\"\n [class.!h-auto]=\"isYearMode() || isMonthMode() || isQuarterMode()\">\n @if (currentView() === 'day') {\n <div\n class=\"flex h-full w-full flex-1 flex-col gap-1\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n <!-- Weekday headers -->\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (weekday of weekdayNames(); track weekday) {\n <div\n class=\"text-muted-foreground flex h-[1.875rem] w-[2.0313rem] items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n <!-- Date rows -->\n @for (week of calendarDays(); track $index) {\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n class=\"h-[1.875rem] !w-[2.0313rem] !text-sm\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (currentView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n @for (month of monthNames(); track month; let i = $index) {\n @let monthDisabled = i | zIsStartMonthDisabled: startMonthDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: selectedMonthIndex() : todayMonthIndex()\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"monthDisabled\"\n [class.opacity-30]=\"monthDisabled\"\n [class.cursor-not-allowed]=\"monthDisabled\"\n (click)=\"onMonthSelect(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n @for (year of yearRange(); track year) {\n @let yearDisabled = year | zIsStartYearDisabled: startYearDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: selectedYear() : todayYear()\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"yearDisabled\"\n [class.opacity-30]=\"yearDisabled\"\n [class.cursor-not-allowed]=\"yearDisabled\"\n (click)=\"onYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'quarter') {\n <div\n class=\"grid h-full w-full grid-cols-2 grid-rows-2 gap-2 p-1\"\n [class.animate-calendar-enter]=\"uiState().hasViewChanged\">\n @for (quarter of quarterNames; track quarter; let i = $index) {\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zQuarterClasses: selectedQuarterIndex() : todayQuarterIndex()\"\n class=\"!h-8 !w-full !text-sm\"\n (click)=\"onQuarterClick(i)\">\n {{ quarter }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div\n class=\"border-border bg-border mb-2 hidden self-stretch sm:block sm:w-px\"\n [class.mb-2]=\"!zQuickSelect() || (zQuickSelect() && zShowOk())\"></div>\n <div class=\"border-border bg-border block h-px w-full sm:hidden\"></div>\n\n <div class=\"z-calendar-section flex w-[17.5rem] shrink-0 flex-col pt-2 sm:pt-0\">\n <!-- Header -->\n <div class=\"border-border flex w-full items-center justify-between gap-0.5 px-2\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"18\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"18\" />\n </button>\n\n <div class=\"flex w-[7.5rem] shrink-0 items-center justify-center gap-0\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setEndView('month')\">\n {{ endMonthName() }}\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"h-7 px-1.5 text-sm!\"\n [zWave]=\"false\"\n (click)=\"setEndView('year')\">\n {{ endMonthYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"18\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-7 shrink-0 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"18\" />\n </button>\n </div>\n\n <!-- Body -->\n <div\n class=\"flex h-full min-h-[14rem] w-full flex-col items-center justify-center p-2\"\n [class.h-[14rem]]=\"endView() === 'month' || endView() === 'year'\">\n @if (endView() === 'day') {\n <div\n class=\"flex h-full w-full flex-1 flex-col gap-1\"\n [class.animate-calendar-enter]=\"uiState().hasEndViewChanged\">\n <!-- Weekday headers -->\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (weekday of weekdayNames(); track weekday) {\n <div\n class=\"text-muted-foreground flex h-[1.875rem] w-[2.0313rem] items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n <!-- Date rows -->\n @for (week of calendarDaysEnd(); track $index) {\n <div class=\"flex w-full flex-1 justify-center gap-1\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n class=\"h-[1.875rem] !w-[2.0313rem] !text-sm\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (endView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasEndViewChanged\">\n @for (month of monthNames(); track month; let i = $index) {\n @let endMonthDisabled = i | zIsEndMonthDisabled: endMonthDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: endMonth().getMonth() : -1\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"endMonthDisabled\"\n [class.opacity-30]=\"endMonthDisabled\"\n [class.cursor-not-allowed]=\"endMonthDisabled\"\n (click)=\"onEndMonthClick(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (endView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-2.5 gap-y-5!\"\n [class.animate-calendar-enter]=\"uiState().hasEndViewChanged\">\n @for (year of endYearRange(); track year) {\n @let endYearDisabled = year | zIsEndYearDisabled: endYearDisabledContext();\n <div class=\"flex flex-1 items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: endMonth().getFullYear() : -1\"\n class=\"!h-7 !w-full !text-sm\"\n [disabled]=\"endYearDisabled\"\n [class.opacity-30]=\"endYearDisabled\"\n [class.cursor-not-allowed]=\"endYearDisabled\"\n (click)=\"onEndYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Compact Time Picker Below Calendar (Single Date) -->\n @if (!isRangeMode() && zShowTime()) {\n <div\n class=\"hover:bg-muted border-border flex w-full cursor-pointer items-center justify-center gap-1.5 border-t px-3 py-1.5 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownTpl\"\n zPosition=\"bottom\"\n [zPopoverWidth]=\"240\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-lg\"\n (zShow)=\"onTimeDropdownShow()\">\n <z-icon zType=\"lucideCalendarClock\" zSize=\"18\" class=\"text-muted-foreground mr-1 shrink-0\" />\n <span class=\"text-sm font-medium tabular-nums select-none\">\n @if (zShowHour()) {\n {{ formattedHour() }}\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n {{ formattedMinute() }}\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n {{ formattedSecond() }}\n }\n @if (zTimeFormat() === '12h') {\n <span class=\"text-primary ml-0.5 font-semibold\">\n {{ period() }}\n </span>\n }\n </span>\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"text-muted-foreground shrink-0\" />\n </div>\n }\n\n <!-- Compact Time Pickers Below Calendars (Range Mode) -->\n @if (isRangeMode() && zShowTime()) {\n <div class=\"border-border flex w-full flex-col border-t sm:flex-row\">\n <!-- Start Time -->\n <div\n class=\"hover:bg-muted flex flex-1 cursor-pointer items-center justify-center gap-1.5 px-3 py-1.5 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownTpl\"\n zPosition=\"bottom\"\n [zPopoverWidth]=\"240\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-lg\"\n (zShow)=\"onTimeDropdownShow()\">\n <z-icon zType=\"lucideCalendarClock\" zSize=\"18\" class=\"text-muted-foreground mr-1 shrink-0\" />\n <span class=\"text-sm font-medium tabular-nums select-none\">\n @if (zShowHour()) {\n {{ formattedHour() }}\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n {{ formattedMinute() }}\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n {{ formattedSecond() }}\n }\n @if (zTimeFormat() === '12h') {\n <span class=\"text-primary ml-0.5 font-semibold\">\n {{ period() }}\n </span>\n }\n </span>\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"text-muted-foreground shrink-0\" />\n </div>\n\n <!-- Divider -->\n <div class=\"border-border bg-border h-px self-stretch sm:block sm:h-full sm:w-px\"></div>\n\n <!-- End Time -->\n <div\n class=\"hover:bg-muted flex flex-1 cursor-pointer items-center justify-center gap-1.5 px-3 py-1.5 transition-colors\"\n z-popover\n [zPopoverContent]=\"timeDropdownEndTpl\"\n zPosition=\"bottom\"\n [zPopoverWidth]=\"240\"\n [zOffset]=\"4\"\n zTrigger=\"click\"\n zClass=\"border-border shadow-lg\"\n (zShow)=\"onTimeDropdownEndShow()\">\n <z-icon zType=\"lucideCalendarClock\" zSize=\"18\" class=\"text-muted-foreground mr-1 shrink-0\" />\n <span class=\"text-sm font-medium tabular-nums select-none\">\n @if (zShowHour()) {\n {{ formattedHourEnd() }}\n }\n @if (zShowHour() && zShowMinute()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowMinute()) {\n {{ formattedMinuteEnd() }}\n }\n @if (zShowMinute() && zShowSecond()) {\n <span class=\"text-muted-foreground\">:</span>\n }\n @if (zShowSecond()) {\n {{ formattedSecondEnd() }}\n }\n @if (zTimeFormat() === '12h') {\n <span class=\"text-primary ml-0.5 font-semibold\">\n {{ periodEnd() }}\n </span>\n }\n </span>\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"text-muted-foreground shrink-0\" />\n </div>\n </div>\n }\n } @else {\n <!-- Time Only Mode -->\n <div class=\"flex w-full justify-center px-2 pt-2 pb-1\">\n <ng-container [ngTemplateOutlet]=\"timeDropdownTpl\" />\n </div>\n }\n </div>\n\n @if (!(zQuickSelect() && zMode() === 'range' && !showOkButton() && !showCancelButton())) {\n <div\n class=\"bg-popover border-border z-10 flex w-full shrink-0 items-center justify-between gap-2 border-t px-2 py-2 shadow-[0_-2px_8px_-2px_rgb(0_0_0_/_10%)] sm:pt-2 sm:pb-0 sm:shadow-none\">\n @if (!zQuickSelect() || zMode() !== 'range') {\n <button type=\"button\" z-button zType=\"secondary\" zSize=\"sm\" [zWave]=\"false\" (click)=\"onTodayClick()\">\n {{ todayButtonText() }}\n </button>\n } @else {\n <div></div>\n }\n\n @if (showOkButton() || showCancelButton()) {\n <div class=\"flex items-center gap-2\">\n @if (showCancelButton()) {\n <button type=\"button\" z-button zType=\"outline\" zSize=\"sm\" (click)=\"onCancelClick()\">\n {{ zCancelText() ?? ('i18n_z_ui_calendar_cancel' | translate) }}\n </button>\n }\n @if (showOkButton()) {\n <button type=\"button\" z-button zSize=\"sm\" [zDisabled]=\"!canApply()\" (click)=\"onOkClick()\">\n {{ zOkText() ?? ('i18n_z_ui_calendar_ok' | translate) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #timeDropdownTpl>\n <div class=\"bg-popover flex min-w-56 justify-center overflow-hidden rounded-sm\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_hour' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-hour h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowMinute() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrSelected = hr === displayHour();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrSelected\"\n [class.bg-primary]=\"hrSelected\"\n [class.text-primary-foreground]=\"hrSelected\"\n [class.font-medium]=\"hrSelected\"\n (click)=\"selectHour(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_minute' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-minute h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"!zShowHour() && (zShowSecond() || zTimeFormat() === '12h')\"\n [class.rounded-br-sm]=\"(zShowHour() || !zShowHour()) && !zShowSecond() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minSelected = min === minute();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minSelected\"\n [class.bg-primary]=\"minSelected\"\n [class.text-primary-foreground]=\"minSelected\"\n [class.font-medium]=\"minSelected\"\n (click)=\"selectMinute(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zTimeFormat() === '12h'\"\n [class.border-border]=\"zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_second' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-second h-[11rem] w-14\"\n [class.rounded-br-sm]=\"zTimeFormat() !== '12h'\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowMinute() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secSelected = sec === second();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secSelected\"\n [class.bg-primary]=\"secSelected\"\n [class.text-primary-foreground]=\"secSelected\"\n [class.font-medium]=\"secSelected\"\n (click)=\"selectSecond(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_period' | translate }}\n </div>\n <ng-scrollbar class=\"z-time-scroll-period h-[11rem] w-14\" [class.rounded-br-sm]=\"true\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (p of ['AM', 'PM']; track p) {\n @let pSelected = p === period();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!pSelected\"\n [class.bg-primary]=\"pSelected\"\n [class.text-primary-foreground]=\"pSelected\"\n [class.font-medium]=\"pSelected\"\n (click)=\"selectPeriod($any(p))\">\n {{ p }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #timeDropdownEndTpl>\n <div class=\"bg-popover flex min-w-56 justify-center overflow-hidden rounded-sm\">\n @if (zShowHour()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_hour' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-hour-end h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowMinute() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"zShowMinute() || zShowSecond() || zTimeFormat() === '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hr of hourOptions(); track hr) {\n @let hrDisabled = hr | zIsEndHourDisabled: endTimeContext();\n @let hrEndSelected = hr === displayHourEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!hrDisabled && !hrEndSelected\"\n [class.cursor-pointer]=\"!hrDisabled\"\n [class.bg-primary]=\"hrEndSelected\"\n [class.text-primary-foreground]=\"hrEndSelected\"\n [class.font-medium]=\"hrEndSelected\"\n [class.opacity-30]=\"hrDisabled\"\n [class.cursor-not-allowed]=\"hrDisabled\"\n [disabled]=\"hrDisabled\"\n (click)=\"selectHourEnd(hr)\">\n {{ hr | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowMinute()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zShowSecond() || zTimeFormat() === '12h'\"\n [class.border-border]=\"zShowSecond() || zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_minute' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-minute-end h-[11rem] w-14\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowSecond() && zTimeFormat() !== '12h'\"\n [class.rounded-tl-sm]=\"!zShowHour() && (zShowSecond() || zTimeFormat() === '12h')\"\n [class.rounded-br-sm]=\"(zShowHour() || !zShowHour()) && !zShowSecond() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (min of minuteOptions; track min) {\n @let minDisabled = min | zIsEndMinuteDisabled: endTimeContext();\n @let minEndSelected = min === minuteEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!minDisabled && !minEndSelected\"\n [class.cursor-pointer]=\"!minDisabled\"\n [class.bg-primary]=\"minEndSelected\"\n [class.text-primary-foreground]=\"minEndSelected\"\n [class.font-medium]=\"minEndSelected\"\n [class.opacity-30]=\"minDisabled\"\n [class.cursor-not-allowed]=\"minDisabled\"\n [disabled]=\"minDisabled\"\n (click)=\"selectMinuteEnd(min)\">\n {{ min | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zShowSecond()) {\n <div\n class=\"flex flex-col\"\n [class.border-r]=\"zTimeFormat() === '12h'\"\n [class.border-border]=\"zTimeFormat() === '12h'\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_second' | translate }}\n </div>\n <ng-scrollbar\n class=\"z-time-scroll-second-end h-[11rem] w-14\"\n [class.rounded-br-sm]=\"zTimeFormat() !== '12h'\"\n [class.rounded-bl-sm]=\"!zShowHour() && !zShowMinute() && zTimeFormat() !== '12h'\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (sec of secondOptions; track sec) {\n @let secDisabled = sec | zIsEndSecondDisabled: endTimeContext();\n @let secEndSelected = sec === secondEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!secDisabled && !secEndSelected\"\n [class.cursor-pointer]=\"!secDisabled\"\n [class.bg-primary]=\"secEndSelected\"\n [class.text-primary-foreground]=\"secEndSelected\"\n [class.font-medium]=\"secEndSelected\"\n [class.opacity-30]=\"secDisabled\"\n [class.cursor-not-allowed]=\"secDisabled\"\n [disabled]=\"secDisabled\"\n (click)=\"selectSecondEnd(sec)\">\n {{ sec | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col\">\n <div\n class=\"text-muted-foreground border-b-border flex h-7 shrink-0 items-center justify-center border-b text-xs font-medium select-none\">\n {{ 'i18n_z_ui_calendar_period' | translate }}\n </div>\n <ng-scrollbar class=\"z-time-scroll-period-end h-[11rem] w-14\" [class.rounded-br-sm]=\"true\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (p of ['AM', 'PM']; track p) {\n @let pSelected = p === periodEnd();\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.hover:bg-muted]=\"!pSelected\"\n [class.bg-primary]=\"pSelected\"\n [class.text-primary-foreground]=\"pSelected\"\n [class.font-medium]=\"pSelected\"\n (click)=\"selectPeriodEnd($any(p))\">\n {{ p }}\n </button>\n }\n </div>\n </ng-scrollbar>\n </div>\n }\n </div>\n</ng-template>\n", styles: [".animate-calendar-enter{animation:z-calendar-view-enter .2s ease-out}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(.25rem)}to{opacity:1;transform:scale(1) translateY(0)}}.z-calendar input{text-overflow:ellipsis;overflow:hidden}\n"] }]
3145
+ }], 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 }] }], zAllowEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "zAllowEdit", required: false }] }], zShortTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShortTime", 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 }] }], 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 }] }], zDefaultTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDefaultTime", required: false }] }], zRangeDefaultTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "zRangeDefaultTime", required: false }] }], zControl: [{ type: i0.Output, args: ["zControl"] }], zChange: [{ type: i0.Output, args: ["zChange"] }], zOnBlur: [{ type: i0.Output, args: ["zOnBlur"] }], zOnFocus: [{ type: i0.Output, args: ["zOnFocus"] }], zEvent: [{ type: i0.Output, args: ["zEvent"] }], triggerRef: [{ type: i0.ViewChild, args: ['triggerEl', { isSignal: true }] }], inputRef: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }] } });
3071
3146
 
3072
3147
  /**
3073
3148
  * Generated bundle index. Do not edit.