@shival99/z-ui 2.0.28 → 2.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NgTemplateOutlet, DecimalPipe } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { Pipe, input, output, viewChild, computed, signal, inject, Injector, DestroyRef, effect, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { Pipe, input, output, viewChild, computed, signal, inject, Injector, DestroyRef, linkedSignal, effect, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
4
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
5
|
import * as i1 from '@angular/forms';
|
|
6
6
|
import { NgControl, NgModel, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
@@ -1040,6 +1040,8 @@ class ZCalendarComponent {
|
|
|
1040
1040
|
zEvent = output();
|
|
1041
1041
|
triggerRef = viewChild('triggerEl', ...(ngDevMode ? [{ debugName: "triggerRef" }] : []));
|
|
1042
1042
|
inputRef = viewChild('inputEl', ...(ngDevMode ? [{ debugName: "inputRef" }] : []));
|
|
1043
|
+
startInputRef = viewChild('startInputEl', ...(ngDevMode ? [{ debugName: "startInputRef" }] : []));
|
|
1044
|
+
endInputRef = viewChild('endInputEl', ...(ngDevMode ? [{ debugName: "endInputRef" }] : []));
|
|
1043
1045
|
pickerId = zUuid('z-calendar');
|
|
1044
1046
|
weekdayNames = computed(() => getWeekdayNames(this.zLocale()), ...(ngDevMode ? [{ debugName: "weekdayNames" }] : []));
|
|
1045
1047
|
monthNames = computed(() => getMonthNames(this.zLocale()), ...(ngDevMode ? [{ debugName: "monthNames" }] : []));
|
|
@@ -1116,8 +1118,25 @@ class ZCalendarComponent {
|
|
|
1116
1118
|
period = signal('AM', ...(ngDevMode ? [{ debugName: "period" }] : []));
|
|
1117
1119
|
inputDisplayValue = signal('', ...(ngDevMode ? [{ debugName: "inputDisplayValue" }] : []));
|
|
1118
1120
|
isInputFocused = signal(false, ...(ngDevMode ? [{ debugName: "isInputFocused" }] : []));
|
|
1119
|
-
activePresetKey =
|
|
1120
|
-
|
|
1121
|
+
activePresetKey = linkedSignal(() => {
|
|
1122
|
+
const start = this._rangeStart();
|
|
1123
|
+
const end = this._rangeEnd();
|
|
1124
|
+
if (start && end) {
|
|
1125
|
+
return this._detectMatchingPreset(start, end);
|
|
1126
|
+
}
|
|
1127
|
+
return null;
|
|
1128
|
+
}, ...(ngDevMode ? [{ debugName: "activePresetKey" }] : []));
|
|
1129
|
+
shortDisplayPresetKey = linkedSignal(() => {
|
|
1130
|
+
const start = this._rangeStart();
|
|
1131
|
+
const end = this._rangeEnd();
|
|
1132
|
+
if (start && end) {
|
|
1133
|
+
const matching = this._detectMatchingPreset(start, end);
|
|
1134
|
+
if (matching && matching !== 'custom' && this.zShortTime()) {
|
|
1135
|
+
return matching;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
return null;
|
|
1139
|
+
}, ...(ngDevMode ? [{ debugName: "shortDisplayPresetKey" }] : []));
|
|
1121
1140
|
quickSelectOptions = computed(() => this.quickSelectPresets.map(preset => ({
|
|
1122
1141
|
label: preset.label,
|
|
1123
1142
|
value: preset.key,
|
|
@@ -1685,17 +1704,22 @@ class ZCalendarComponent {
|
|
|
1685
1704
|
this._rangeStart.set(null);
|
|
1686
1705
|
this._rangeEnd.set(null);
|
|
1687
1706
|
this.activePresetKey.set(null);
|
|
1707
|
+
this.shortDisplayPresetKey.set(null);
|
|
1688
1708
|
this.hour.set(0);
|
|
1689
1709
|
this.minute.set(0);
|
|
1690
1710
|
this.second.set(0);
|
|
1691
1711
|
this.uiState.update(s => ({ ...s, touched: false, dirty: false }));
|
|
1692
1712
|
this.inputDisplayValue.set('');
|
|
1713
|
+
if (this.isRangeMode()) {
|
|
1714
|
+
this._updateRangeInputDisplay();
|
|
1715
|
+
}
|
|
1693
1716
|
const emitValue = this._getEmitValue();
|
|
1694
1717
|
this._onChange(emitValue);
|
|
1695
1718
|
if (this._ngControl?.control) {
|
|
1696
1719
|
this._ngControl.control.markAsPristine();
|
|
1697
1720
|
this._ngControl.control.markAsUntouched();
|
|
1698
1721
|
}
|
|
1722
|
+
this._syncDOMInputs();
|
|
1699
1723
|
}
|
|
1700
1724
|
/** @deprecated Use `valid()` for boolean form-submit checks. */
|
|
1701
1725
|
validate() {
|
|
@@ -1841,11 +1865,7 @@ class ZCalendarComponent {
|
|
|
1841
1865
|
if (this.isRangeMode()) {
|
|
1842
1866
|
this._updateRangeInputDisplay();
|
|
1843
1867
|
}
|
|
1844
|
-
|
|
1845
|
-
const inputEl = this.inputRef()?.nativeElement;
|
|
1846
|
-
if (inputEl) {
|
|
1847
|
-
inputEl.value = this.inputDisplayValue();
|
|
1848
|
-
}
|
|
1868
|
+
this._syncDOMInputs();
|
|
1849
1869
|
this.triggerRef()?.nativeElement.blur();
|
|
1850
1870
|
}
|
|
1851
1871
|
_restoreFromBackup() {
|
|
@@ -2017,23 +2037,30 @@ class ZCalendarComponent {
|
|
|
2017
2037
|
const format = this._getParseFormat();
|
|
2018
2038
|
const date = parseDate(value, format, this.zLocale());
|
|
2019
2039
|
if (!date) {
|
|
2020
|
-
|
|
2040
|
+
this._cancelAndRestore();
|
|
2021
2041
|
input.blur();
|
|
2022
2042
|
return;
|
|
2023
2043
|
}
|
|
2024
2044
|
const endDate = this._rangeEnd();
|
|
2025
2045
|
if (endDate && date >= endDate) {
|
|
2026
|
-
|
|
2046
|
+
this._cancelAndRestore();
|
|
2027
2047
|
input.blur();
|
|
2028
2048
|
return;
|
|
2029
2049
|
}
|
|
2030
|
-
this._skipBlurHandler.set(true);
|
|
2031
2050
|
this._rangeStart.set(date);
|
|
2032
2051
|
this._currentMonth.set(date);
|
|
2033
2052
|
this._syncTimeSignals(date);
|
|
2034
2053
|
this.uiState.update(s => ({ ...s, dirty: true }));
|
|
2035
2054
|
this._inputDisplayStart.set(this.displayValueStart());
|
|
2036
|
-
|
|
2055
|
+
if (endDate) {
|
|
2056
|
+
this._skipBlurHandler.set(true);
|
|
2057
|
+
this._confirmTypedValue(input);
|
|
2058
|
+
return;
|
|
2059
|
+
}
|
|
2060
|
+
const endEl = this.endInputRef()?.nativeElement;
|
|
2061
|
+
if (endEl) {
|
|
2062
|
+
endEl.focus();
|
|
2063
|
+
}
|
|
2037
2064
|
}
|
|
2038
2065
|
onEndInputEnter(event) {
|
|
2039
2066
|
event.preventDefault();
|
|
@@ -2049,23 +2076,30 @@ class ZCalendarComponent {
|
|
|
2049
2076
|
const format = this._getParseFormat();
|
|
2050
2077
|
const date = parseDate(value, format, this.zLocale());
|
|
2051
2078
|
if (!date) {
|
|
2052
|
-
|
|
2079
|
+
this._cancelAndRestore();
|
|
2053
2080
|
input.blur();
|
|
2054
2081
|
return;
|
|
2055
2082
|
}
|
|
2056
2083
|
const startDate = this._rangeStart();
|
|
2057
2084
|
if (startDate && date <= startDate) {
|
|
2058
|
-
|
|
2085
|
+
this._cancelAndRestore();
|
|
2059
2086
|
input.blur();
|
|
2060
2087
|
return;
|
|
2061
2088
|
}
|
|
2062
|
-
this._skipBlurHandler.set(true);
|
|
2063
2089
|
this._rangeEnd.set(date);
|
|
2064
2090
|
this._endMonth.set(date);
|
|
2065
2091
|
this._syncEndTimeSignals(date);
|
|
2066
2092
|
this.uiState.update(s => ({ ...s, dirty: true }));
|
|
2067
2093
|
this._inputDisplayEnd.set(this.displayValueEnd());
|
|
2068
|
-
|
|
2094
|
+
if (startDate) {
|
|
2095
|
+
this._skipBlurHandler.set(true);
|
|
2096
|
+
this._confirmTypedValue(input);
|
|
2097
|
+
return;
|
|
2098
|
+
}
|
|
2099
|
+
const startEl = this.startInputRef()?.nativeElement;
|
|
2100
|
+
if (startEl) {
|
|
2101
|
+
startEl.focus();
|
|
2102
|
+
}
|
|
2069
2103
|
}
|
|
2070
2104
|
onInputFocus(_event) {
|
|
2071
2105
|
this.isInputFocused.set(true);
|
|
@@ -2080,6 +2114,16 @@ class ZCalendarComponent {
|
|
|
2080
2114
|
return;
|
|
2081
2115
|
}
|
|
2082
2116
|
if (this.isRangeMode()) {
|
|
2117
|
+
const target = event.relatedTarget;
|
|
2118
|
+
const isFocusInside = target && (this.triggerRef()?.nativeElement.contains(target) || target.closest('.z-calendar-calendar'));
|
|
2119
|
+
if (isFocusInside) {
|
|
2120
|
+
return;
|
|
2121
|
+
}
|
|
2122
|
+
if (this._hasTypedDraft()) {
|
|
2123
|
+
this._restoreFromBackup();
|
|
2124
|
+
this._hasTypedDraft.set(false);
|
|
2125
|
+
}
|
|
2126
|
+
this._syncDOMInputs();
|
|
2083
2127
|
return;
|
|
2084
2128
|
}
|
|
2085
2129
|
const needsConfirmation = this.showOkButton() || this.showCancelButton();
|
|
@@ -2159,10 +2203,7 @@ class ZCalendarComponent {
|
|
|
2159
2203
|
return;
|
|
2160
2204
|
}
|
|
2161
2205
|
}
|
|
2162
|
-
this.
|
|
2163
|
-
this._updateInputDisplay();
|
|
2164
|
-
this.close();
|
|
2165
|
-
input.value = this.displayValue();
|
|
2206
|
+
this._cancelAndRestore();
|
|
2166
2207
|
input.blur();
|
|
2167
2208
|
return;
|
|
2168
2209
|
}
|
|
@@ -2177,10 +2218,7 @@ class ZCalendarComponent {
|
|
|
2177
2218
|
this._confirmTypedValue(input);
|
|
2178
2219
|
return;
|
|
2179
2220
|
}
|
|
2180
|
-
this.
|
|
2181
|
-
this._updateInputDisplay();
|
|
2182
|
-
this.close();
|
|
2183
|
-
input.value = this.displayValue();
|
|
2221
|
+
this._cancelAndRestore();
|
|
2184
2222
|
input.blur();
|
|
2185
2223
|
}
|
|
2186
2224
|
onCalendarKeydown(event) {
|
|
@@ -2434,6 +2472,7 @@ class ZCalendarComponent {
|
|
|
2434
2472
|
this._inputDisplayStart.set('');
|
|
2435
2473
|
this._inputDisplayEnd.set('');
|
|
2436
2474
|
}
|
|
2475
|
+
this._syncDOMInputs();
|
|
2437
2476
|
this.close();
|
|
2438
2477
|
}
|
|
2439
2478
|
onCancelClick() {
|
|
@@ -3042,6 +3081,23 @@ class ZCalendarComponent {
|
|
|
3042
3081
|
}
|
|
3043
3082
|
this._selectedDate.set(null);
|
|
3044
3083
|
}
|
|
3084
|
+
_syncDOMInputs() {
|
|
3085
|
+
if (this.isRangeMode()) {
|
|
3086
|
+
const startEl = this.startInputRef()?.nativeElement;
|
|
3087
|
+
if (startEl) {
|
|
3088
|
+
startEl.value = this.inputDisplayStart();
|
|
3089
|
+
}
|
|
3090
|
+
const endEl = this.endInputRef()?.nativeElement;
|
|
3091
|
+
if (endEl) {
|
|
3092
|
+
endEl.value = this.inputDisplayEnd();
|
|
3093
|
+
}
|
|
3094
|
+
return;
|
|
3095
|
+
}
|
|
3096
|
+
const inputEl = this.inputRef()?.nativeElement;
|
|
3097
|
+
if (inputEl) {
|
|
3098
|
+
inputEl.value = this.inputDisplayValue();
|
|
3099
|
+
}
|
|
3100
|
+
}
|
|
3045
3101
|
onInputEscape(event) {
|
|
3046
3102
|
event.preventDefault();
|
|
3047
3103
|
event.stopPropagation();
|
|
@@ -3070,6 +3126,7 @@ class ZCalendarComponent {
|
|
|
3070
3126
|
this._restoreFromBackup();
|
|
3071
3127
|
this._updateAllInputDisplays();
|
|
3072
3128
|
this.close();
|
|
3129
|
+
this._syncDOMInputs();
|
|
3073
3130
|
}
|
|
3074
3131
|
_updateAllInputDisplays() {
|
|
3075
3132
|
if (this.isRangeMode()) {
|
|
@@ -3298,7 +3355,7 @@ class ZCalendarComponent {
|
|
|
3298
3355
|
multi: true,
|
|
3299
3356
|
},
|
|
3300
3357
|
TranslatePipe,
|
|
3301
|
-
], 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 [zOutsideClickClose]=\"true\"\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 z-tooltip\n [zContent]=\"displayValue()\"\n zTooltipTrigger=\"hover\"\n zTooltipPosition=\"top\"\n [zTooltipDisabled]=\"isInputFocused() || isOpen() || !hasValue()\"\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($event)\" />\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($event)\" />\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($event)\" />\n }\n\n @if (zAllowClear() && !isDisabled() && !zReadonly()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"text-muted-foreground hover:text-foreground flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-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: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTooltipPosition", "zTrigger", "zTooltipTrigger", "zTooltipType", "zTooltipSize", "zClass", "zTooltipClass", "zShowDelay", "zTooltipShowDelay", "zHideDelay", "zTooltipHideDelay", "zArrow", "zTooltipArrow", "zDisabled", "zTooltipDisabled", "zOffset", "zTooltipOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zPopoverTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zTriggerRef", "zManualClose", "zOutsideClickClose", "zScrollClose", "zShowArrow"], outputs: ["zShow", "zHide", "zHideStart", "zControl", "zPositionChange", "zOutsideClick"], 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 });
|
|
3358
|
+
], viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }, { propertyName: "inputRef", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }, { propertyName: "startInputRef", first: true, predicate: ["startInputEl"], descendants: true, isSignal: true }, { propertyName: "endInputRef", first: true, predicate: ["endInputEl"], 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 [zOutsideClickClose]=\"true\"\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 z-tooltip\n [zContent]=\"displayValue()\"\n zTooltipTrigger=\"hover\"\n zTooltipPosition=\"top\"\n [zTooltipDisabled]=\"isInputFocused() || isOpen() || !hasValue()\"\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 #startInputEl\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($event)\" />\n @if (!rangeShortDisplayValue()) {\n <span class=\"text-muted-foreground text-sm\">-</span>\n <input\n #endInputEl\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($event)\" />\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($event)\" />\n }\n\n @if (zAllowClear() && !isDisabled() && !zReadonly()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"text-muted-foreground hover:text-foreground flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-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: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTooltipPosition", "zTrigger", "zTooltipTrigger", "zTooltipType", "zTooltipSize", "zClass", "zTooltipClass", "zShowDelay", "zTooltipShowDelay", "zHideDelay", "zTooltipHideDelay", "zArrow", "zTooltipArrow", "zDisabled", "zTooltipDisabled", "zOffset", "zTooltipOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zPopoverTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zTriggerRef", "zManualClose", "zOutsideClickClose", "zScrollClose", "zShowArrow"], outputs: ["zShow", "zHide", "zHideStart", "zControl", "zPositionChange", "zOutsideClick"], 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 });
|
|
3302
3359
|
}
|
|
3303
3360
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZCalendarComponent, decorators: [{
|
|
3304
3361
|
type: Component,
|
|
@@ -3334,8 +3391,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImpor
|
|
|
3334
3391
|
TranslatePipe,
|
|
3335
3392
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
3336
3393
|
class: 'block min-w-0',
|
|
3337
|
-
}, 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 [zOutsideClickClose]=\"true\"\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 z-tooltip\n [zContent]=\"displayValue()\"\n zTooltipTrigger=\"hover\"\n zTooltipPosition=\"top\"\n [zTooltipDisabled]=\"isInputFocused() || isOpen() || !hasValue()\"\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($event)\" />\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($event)\" />\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($event)\" />\n }\n\n @if (zAllowClear() && !isDisabled() && !zReadonly()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"text-muted-foreground hover:text-foreground flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-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"] }]
|
|
3338
|
-
}], 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 }] }] } });
|
|
3394
|
+
}, 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 [zOutsideClickClose]=\"true\"\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 z-tooltip\n [zContent]=\"displayValue()\"\n zTooltipTrigger=\"hover\"\n zTooltipPosition=\"top\"\n [zTooltipDisabled]=\"isInputFocused() || isOpen() || !hasValue()\"\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 #startInputEl\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($event)\" />\n @if (!rangeShortDisplayValue()) {\n <span class=\"text-muted-foreground text-sm\">-</span>\n <input\n #endInputEl\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($event)\" />\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($event)\" />\n }\n\n @if (zAllowClear() && !isDisabled() && !zReadonly()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"text-muted-foreground hover:text-foreground flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-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"] }]
|
|
3395
|
+
}], 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 }] }], startInputRef: [{ type: i0.ViewChild, args: ['startInputEl', { isSignal: true }] }], endInputRef: [{ type: i0.ViewChild, args: ['endInputEl', { isSignal: true }] }] } });
|
|
3339
3396
|
|
|
3340
3397
|
/**
|
|
3341
3398
|
* Generated bundle index. Do not edit.
|