@shival99/z-ui 1.3.6 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/shival99-z-ui-components-z-calendar.mjs +46 -55
- package/fesm2022/shival99-z-ui-components-z-calendar.mjs.map +1 -1
- package/fesm2022/shival99-z-ui-components-z-table.mjs +37 -2
- package/fesm2022/shival99-z-ui-components-z-table.mjs.map +1 -1
- package/package.json +1 -1
- package/types/shival99-z-ui-components-z-calendar.d.ts +4 -4
- package/types/shival99-z-ui-components-z-table.d.ts +2 -0
|
@@ -2764,65 +2764,33 @@ class ZCalendarComponent {
|
|
|
2764
2764
|
const columnsArray = Array.from(timeColumns);
|
|
2765
2765
|
if (this.isRangeMode()) {
|
|
2766
2766
|
const columnsPerSection = (this.zShowHour() ? 1 : 0) + (this.zShowMinute() ? 1 : 0) + (this.zShowSecond() ? 1 : 0);
|
|
2767
|
-
|
|
2768
|
-
if (
|
|
2769
|
-
|
|
2770
|
-
if (
|
|
2771
|
-
const
|
|
2772
|
-
|
|
2773
|
-
const hourValue = this.zTimeFormat() === '12h' ? this.displayHour() - 1 : this._hour();
|
|
2774
|
-
hourColumn.scrollTop = hourValue * itemHeight;
|
|
2775
|
-
}
|
|
2776
|
-
columnIndex++;
|
|
2777
|
-
}
|
|
2778
|
-
if (this.zShowMinute()) {
|
|
2779
|
-
const minuteColumn = columnsArray[columnIndex];
|
|
2780
|
-
if (minuteColumn) {
|
|
2781
|
-
minuteColumn.scrollTop = this._minute() * itemHeight;
|
|
2782
|
-
}
|
|
2783
|
-
columnIndex++;
|
|
2784
|
-
}
|
|
2785
|
-
if (this.zShowSecond()) {
|
|
2786
|
-
const secondColumn = columnsArray[columnIndex];
|
|
2787
|
-
if (secondColumn) {
|
|
2788
|
-
secondColumn.scrollTop = this._second() * itemHeight;
|
|
2789
|
-
}
|
|
2767
|
+
let columnIndex = 0;
|
|
2768
|
+
if (this.zShowHour()) {
|
|
2769
|
+
const hourColumn = columnsArray[columnIndex];
|
|
2770
|
+
if (hourColumn) {
|
|
2771
|
+
const hourValue = this.zTimeFormat() === '12h' ? this.displayHour() - 1 : this._hour();
|
|
2772
|
+
hourColumn.scrollTop = hourValue * itemHeight;
|
|
2790
2773
|
}
|
|
2774
|
+
columnIndex++;
|
|
2791
2775
|
}
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
const hourColumn = columnsArray[columnIndex];
|
|
2797
|
-
if (hourColumn) {
|
|
2798
|
-
const hourValue = this.zTimeFormat() === '12h' ? this.displayHourEnd() - 1 : this._hourEnd();
|
|
2799
|
-
hourColumn.scrollTop = hourValue * itemHeight;
|
|
2800
|
-
}
|
|
2801
|
-
columnIndex++;
|
|
2802
|
-
}
|
|
2803
|
-
if (this.zShowMinute()) {
|
|
2804
|
-
const minuteColumn = columnsArray[columnIndex];
|
|
2805
|
-
if (minuteColumn) {
|
|
2806
|
-
minuteColumn.scrollTop = this._minuteEnd() * itemHeight;
|
|
2807
|
-
}
|
|
2808
|
-
columnIndex++;
|
|
2776
|
+
if (this.zShowMinute()) {
|
|
2777
|
+
const minuteColumn = columnsArray[columnIndex];
|
|
2778
|
+
if (minuteColumn) {
|
|
2779
|
+
minuteColumn.scrollTop = this._minute() * itemHeight;
|
|
2809
2780
|
}
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2781
|
+
columnIndex++;
|
|
2782
|
+
}
|
|
2783
|
+
if (this.zShowSecond()) {
|
|
2784
|
+
const secondColumn = columnsArray[columnIndex];
|
|
2785
|
+
if (secondColumn) {
|
|
2786
|
+
secondColumn.scrollTop = this._second() * itemHeight;
|
|
2815
2787
|
}
|
|
2816
2788
|
}
|
|
2817
|
-
|
|
2818
|
-
}
|
|
2819
|
-
const selected = this._selectedDate();
|
|
2820
|
-
if (selected) {
|
|
2821
|
-
let columnIndex = 0;
|
|
2789
|
+
columnIndex = columnsPerSection;
|
|
2822
2790
|
if (this.zShowHour()) {
|
|
2823
2791
|
const hourColumn = columnsArray[columnIndex];
|
|
2824
2792
|
if (hourColumn) {
|
|
2825
|
-
const hourValue = this.zTimeFormat() === '12h' ? this.
|
|
2793
|
+
const hourValue = this.zTimeFormat() === '12h' ? this.displayHourEnd() - 1 : this._hourEnd();
|
|
2826
2794
|
hourColumn.scrollTop = hourValue * itemHeight;
|
|
2827
2795
|
}
|
|
2828
2796
|
columnIndex++;
|
|
@@ -2830,16 +2798,39 @@ class ZCalendarComponent {
|
|
|
2830
2798
|
if (this.zShowMinute()) {
|
|
2831
2799
|
const minuteColumn = columnsArray[columnIndex];
|
|
2832
2800
|
if (minuteColumn) {
|
|
2833
|
-
minuteColumn.scrollTop = this.
|
|
2801
|
+
minuteColumn.scrollTop = this._minuteEnd() * itemHeight;
|
|
2834
2802
|
}
|
|
2835
2803
|
columnIndex++;
|
|
2836
2804
|
}
|
|
2837
2805
|
if (this.zShowSecond()) {
|
|
2838
2806
|
const secondColumn = columnsArray[columnIndex];
|
|
2839
2807
|
if (secondColumn) {
|
|
2840
|
-
secondColumn.scrollTop = this.
|
|
2808
|
+
secondColumn.scrollTop = this._secondEnd() * itemHeight;
|
|
2841
2809
|
}
|
|
2842
2810
|
}
|
|
2811
|
+
return;
|
|
2812
|
+
}
|
|
2813
|
+
let columnIndex = 0;
|
|
2814
|
+
if (this.zShowHour()) {
|
|
2815
|
+
const hourColumn = columnsArray[columnIndex];
|
|
2816
|
+
if (hourColumn) {
|
|
2817
|
+
const hourValue = this.zTimeFormat() === '12h' ? this.displayHour() - 1 : this._hour();
|
|
2818
|
+
hourColumn.scrollTop = hourValue * itemHeight;
|
|
2819
|
+
}
|
|
2820
|
+
columnIndex++;
|
|
2821
|
+
}
|
|
2822
|
+
if (this.zShowMinute()) {
|
|
2823
|
+
const minuteColumn = columnsArray[columnIndex];
|
|
2824
|
+
if (minuteColumn) {
|
|
2825
|
+
minuteColumn.scrollTop = this._minute() * itemHeight;
|
|
2826
|
+
}
|
|
2827
|
+
columnIndex++;
|
|
2828
|
+
}
|
|
2829
|
+
if (this.zShowSecond()) {
|
|
2830
|
+
const secondColumn = columnsArray[columnIndex];
|
|
2831
|
+
if (secondColumn) {
|
|
2832
|
+
secondColumn.scrollTop = this._second() * itemHeight;
|
|
2833
|
+
}
|
|
2843
2834
|
}
|
|
2844
2835
|
}, 0);
|
|
2845
2836
|
}
|
|
@@ -2851,7 +2842,7 @@ class ZCalendarComponent {
|
|
|
2851
2842
|
multi: true,
|
|
2852
2843
|
},
|
|
2853
2844
|
TranslatePipe,
|
|
2854
|
-
], viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }, { propertyName: "inputRef", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }], exportAs: ["zCalendar"], ngImport: i0, template: "<div class=\"z-calendar-wrapper flex w-full flex-col gap-2\">\n @if (zLabel()) {\n <label [for]=\"pickerId\" class=\"text-xs leading-none font-medium\" [class]=\"zLabelClass()\">\n {{ zLabel() }}\n @if (zRequired()) {\n <span class=\"text-destructive! ml-0.5\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <div\n #triggerEl\n z-popover\n [zPopoverContent]=\"calendarTpl\"\n zPosition=\"bottom-left\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"6\"\n [zDisabled]=\"isDisabled() || zReadonly()\"\n [zManualClose]=\"showCancelButton()\"\n [zScrollClose]=\"zScrollClose()\"\n zTrigger=\"click\"\n zClass=\"border-0 shadow-none bg-transparent p-0\"\n (zHideStart)=\"onPopoverHide()\"\n (zShow)=\"onPopoverShow()\"\n (zControl)=\"onPopoverControl($event)\"\n [id]=\"pickerId\"\n [class]=\"triggerClasses()\"\n (keydown)=\"onTriggerKeydown($event)\">\n <z-icon\n [zType]=\"isRangeMode() ? 'lucideCalendarRange' : 'lucideCalendar'\"\n zSize=\"16\"\n class=\"text-muted-foreground shrink-0 cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggle()\" />\n\n @if (isRangeMode()) {\n <input\n type=\"text\"\n data-range-type=\"start\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_start_date' | translate\"\n [value]=\"inputDisplayStart()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onStartInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onStartInputEnter($event)\"\n (keydown.escape)=\"onStartInputEscape()\" />\n <span class=\"text-muted-foreground text-sm\">-</span>\n <input\n type=\"text\"\n data-range-type=\"end\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_end_date' | translate\"\n [value]=\"inputDisplayEnd()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onEndInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onEndInputEnter($event)\"\n (keydown.escape)=\"onEndInputEscape()\" />\n } @else {\n <input\n #inputEl\n type=\"text\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-sm outline-none\"\n [placeholder]=\"zPlaceholder()\"\n [value]=\"inputDisplayValue()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onInputEnter($event)\"\n (keydown.escape)=\"onInputEscape()\" />\n }\n\n @if (zAllowClear() && !isDisabled() && !zReadonly()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"text-muted-foreground hover:text-foreground flex size-5 shrink-0 cursor-pointer items-center justify-center rounded transition-all\"\n [class.opacity-0]=\"!hasValue()\"\n [class.pointer-events-none]=\"!hasValue()\"\n (click)=\"onClear($event)\">\n <z-icon zType=\"lucideX\" zSize=\"14\" />\n </button>\n }\n </div>\n </div>\n\n @if (showError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n</div>\n\n<ng-template #calendarTpl>\n <div\n class=\"z-calendar-calendar bg-popover border-border flex rounded-[6px] border shadow-lg\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border flex flex-col space-y-1 border-r p-2\">\n @for (preset of quickSelectPresets; track preset.key) {\n @let presetDisabled = preset | zIsPresetDisabled: zDisabledDate();\n <button\n type=\"button\"\n class=\"cursor-pointer rounded-[4px] px-3 py-1.5 text-left text-sm whitespace-nowrap transition-colors\"\n [class.hover:bg-muted]=\"activePresetKey() !== preset.key && !presetDisabled\"\n [class.bg-primary]=\"activePresetKey() === preset.key\"\n [class.text-primary-foreground]=\"activePresetKey() === preset.key\"\n [class.font-medium]=\"activePresetKey() === preset.key\"\n [class.opacity-40]=\"presetDisabled\"\n [class.cursor-not-allowed]=\"presetDisabled\"\n [disabled]=\"presetDisabled\"\n (click)=\"onQuickSelect(preset)\">\n {{ preset.label }}\n </button>\n }\n </div>\n }\n <div class=\"flex flex-col gap-2 p-3\">\n @if (!isTimeMode()) {\n <div class=\"z-calendars-wrapper flex items-start\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex flex-col gap-1\">\n @if (!isTimeMode()) {\n <div class=\"flex w-full items-center justify-between space-x-1\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePrevious()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePreviousFast()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0.5\">\n @if (!isYearMode() && !isQuarterMode()) {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"w-20 px-2!\"\n [zWave]=\"false\"\n [zDisabled]=\"false\"\n (click)=\"setView('month')\">\n {{ currentMonthName() }}\n </button>\n }\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"px-2!\"\n [zWave]=\"false\"\n [zDisabled]=\"isYearMode()\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNextFast()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNext()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"16\" />\n </button>\n </div>\n\n <div class=\"z-calendar-views w-full\" [class.z-calendar-views-quarter]=\"isQuarterMode()\">\n @if (currentView() === 'day') {\n <div class=\"flex h-full w-full flex-col gap-1\" [class.z-calendar-animate]=\"hasViewChanged()\">\n <div class=\"grid w-full grid-cols-7\">\n @for (weekday of weekdayNames; track weekday) {\n <div class=\"text-muted-foreground flex h-7 items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n @for (week of calendarDays(); track $index) {\n <div class=\"grid w-full grid-cols-7\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'month') {\n <div class=\"grid h-full w-full grid-cols-3 grid-rows-4\" [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let monthDisabled = isStartMonthDisabled(i);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: currentMonthIndex()\"\n [disabled]=\"monthDisabled\"\n [class.opacity-30]=\"monthDisabled\"\n [class.cursor-not-allowed]=\"monthDisabled\"\n (click)=\"onMonthSelect(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 gap-0.5\"\n [class.grid-rows-4]=\"!isYearMode() && !isQuarterMode()\"\n [class.grid-rows-3]=\"isYearMode() || isQuarterMode()\"\n [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (year of isYearMode() || isQuarterMode() ? yearRangeSmall() : yearRange(); track year) {\n @let yearDisabled = isStartYearDisabled(year);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: currentYear()\"\n [disabled]=\"yearDisabled\"\n [class.opacity-30]=\"yearDisabled\"\n [class.cursor-not-allowed]=\"yearDisabled\"\n (click)=\"onYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'quarter') {\n <div class=\"grid w-full grid-cols-2 gap-2\" [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (quarter of quarterNames; track quarter; let i = $index) {\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zQuarterClasses: currentQuarterIndex()\"\n (click)=\"onQuarterClick(i)\">\n {{ quarter }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time Picker Side Panel (for single date with showTime) -->\n @if (!isRangeMode() && zShowTime() && currentView() === 'day') {\n <div class=\"border-border flex flex-col border-l pl-3\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_time' | translate }}\n </div>\n <div class=\"flex gap-1\">\n <!-- Hour Column -->\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[235px] w-12 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n\n <!-- Minute Column -->\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[235px] w-12 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n\n <!-- Second Column -->\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[235px] w-12 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n\n <!-- AM/PM Column -->\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 w-12 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 w-12 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div class=\"border-border bg-border mx-3 w-px self-stretch\"></div>\n\n <div class=\"z-calendar-section flex flex-col gap-1\">\n <div class=\"flex w-full items-center justify-between space-x-1\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0.5\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"w-20 px-2!\"\n [zWave]=\"false\"\n (click)=\"setEndView('month')\">\n {{ endMonthName() }}\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"px-2!\"\n [zWave]=\"false\"\n (click)=\"setEndView('year')\">\n {{ endMonthYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"16\" />\n </button>\n </div>\n\n <div class=\"z-calendar-views w-full\">\n @if (endView() === 'day') {\n <div class=\"flex h-full w-full flex-col gap-1\" [class.z-calendar-animate]=\"hasEndViewChanged()\">\n <div class=\"grid grid-cols-7 gap-px\">\n @for (weekday of weekdayNames; track weekday) {\n <div class=\"text-muted-foreground flex h-8 w-8 items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n @for (week of calendarDaysEnd(); track $index) {\n <div class=\"grid grid-cols-7 gap-px\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (endView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4\"\n [class.z-calendar-animate]=\"hasEndViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let endMonthDisabled = isEndMonthDisabled(i);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: endMonth().getMonth()\"\n [disabled]=\"endMonthDisabled\"\n [class.opacity-30]=\"endMonthDisabled\"\n [class.cursor-not-allowed]=\"endMonthDisabled\"\n (click)=\"onEndMonthClick(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (endView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-0.5\"\n [class.z-calendar-animate]=\"hasEndViewChanged()\">\n @for (year of endYearRange(); track year) {\n @let endYearDisabled = isEndYearDisabled(year);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: endMonth().getFullYear()\"\n [disabled]=\"endYearDisabled\"\n [class.opacity-30]=\"endYearDisabled\"\n [class.cursor-not-allowed]=\"endYearDisabled\"\n (click)=\"onEndYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Range Mode Time Picker Side Panel -->\n @if (isRangeMode() && zShowTime() && currentView() === 'day' && endView() === 'day') {\n <div class=\"border-border flex flex-col gap-4 border-l pl-3\">\n <!-- Start Time -->\n <div class=\"flex flex-col\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_start' | translate }}\n </div>\n <div class=\"flex gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 w-9 cursor-pointer items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 w-9 cursor-pointer items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n\n <!-- End Time -->\n <div class=\"flex flex-col\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_end' | translate }}\n </div>\n <div class=\"flex gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n @let hourDisabled = isEndHourDisabled(hour);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!hourDisabled\"\n [class.cursor-pointer]=\"!hourDisabled\"\n [class.bg-primary]=\"isHourEndSelected(hour)\"\n [class.text-primary-foreground]=\"isHourEndSelected(hour)\"\n [class.font-medium]=\"isHourEndSelected(hour)\"\n [class.opacity-30]=\"hourDisabled\"\n [class.cursor-not-allowed]=\"hourDisabled\"\n [disabled]=\"hourDisabled\"\n (click)=\"selectHourEnd(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n @let minuteDisabled = isEndMinuteDisabled(minute);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!minuteDisabled\"\n [class.cursor-pointer]=\"!minuteDisabled\"\n [class.bg-primary]=\"isMinuteEndSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteEndSelected(minute)\"\n [class.font-medium]=\"isMinuteEndSelected(minute)\"\n [class.opacity-30]=\"minuteDisabled\"\n [class.cursor-not-allowed]=\"minuteDisabled\"\n [disabled]=\"minuteDisabled\"\n (click)=\"selectMinuteEnd(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n @let secondDisabled = isEndSecondDisabled(second);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!secondDisabled\"\n [class.cursor-pointer]=\"!secondDisabled\"\n [class.bg-primary]=\"isSecondEndSelected(second)\"\n [class.text-primary-foreground]=\"isSecondEndSelected(second)\"\n [class.font-medium]=\"isSecondEndSelected(second)\"\n [class.opacity-30]=\"secondDisabled\"\n [class.cursor-not-allowed]=\"secondDisabled\"\n [disabled]=\"secondDisabled\"\n (click)=\"selectSecondEnd(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n @let amDisabled = isEndPeriodDisabled('AM');\n <button\n type=\"button\"\n class=\"flex h-6 w-9 items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.hover:bg-muted]=\"!amDisabled\"\n [class.cursor-pointer]=\"!amDisabled\"\n [class.bg-primary]=\"periodEnd() === 'AM'\"\n [class.text-primary-foreground]=\"periodEnd() === 'AM'\"\n [class.opacity-30]=\"amDisabled\"\n [class.cursor-not-allowed]=\"amDisabled\"\n [disabled]=\"amDisabled\"\n (click)=\"selectPeriodEnd('AM')\">\n AM\n </button>\n @let pmDisabled = isEndPeriodDisabled('PM');\n <button\n type=\"button\"\n class=\"flex h-6 w-9 items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.hover:bg-muted]=\"!pmDisabled\"\n [class.cursor-pointer]=\"!pmDisabled\"\n [class.bg-primary]=\"periodEnd() === 'PM'\"\n [class.text-primary-foreground]=\"periodEnd() === 'PM'\"\n [class.opacity-30]=\"pmDisabled\"\n [class.cursor-not-allowed]=\"pmDisabled\"\n [disabled]=\"pmDisabled\"\n (click)=\"selectPeriodEnd('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"flex justify-center gap-1 py-2\">\n <!-- Hour Column -->\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n\n <!-- Minute Column -->\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n\n <!-- Second Column -->\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n\n <!-- AM/PM Column -->\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 w-14 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 w-14 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n }\n\n @if (!(zQuickSelect() && zMode() === 'range' && !showOkButton() && !showCancelButton())) {\n <div class=\"border-border flex items-center justify-between gap-2 border-t pt-2\">\n @if (!zQuickSelect() || zMode() !== 'range') {\n <button type=\"button\" z-button zType=\"secondary\" zSize=\"sm\" [zWave]=\"false\" (click)=\"onTodayClick()\">\n {{ todayButtonText() }}\n </button>\n } @else {\n <div></div>\n }\n\n @if (showOkButton() || showCancelButton()) {\n <div class=\"flex items-center gap-2\">\n @if (showCancelButton()) {\n <button type=\"button\" z-button zType=\"outline\" zSize=\"sm\" (click)=\"onCancelClick()\">\n {{ zCancelText() ?? ('i18n_z_ui_calendar_cancel' | translate) }}\n </button>\n }\n @if (showOkButton()) {\n <button type=\"button\" z-button zSize=\"sm\" [zDisabled]=\"!canApply()\" (click)=\"onOkClick()\">\n {{ zOkText() ?? ('i18n_z_ui_calendar_ok' | translate) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n", styles: [".z-calendar-calendar .z-calendar-section{width:280px;flex-shrink:0}.z-calendar-calendar .z-calendar-views{height:225px;width:100%;display:flex;align-items:center;justify-content:center;flex-direction:column}.z-calendar-calendar .z-calendar-views.z-calendar-views-quarter{height:auto}.z-calendar-calendar .z-calendar-animate{animation:z-calendar-view-enter .2s ease-out}.z-time-picker{display:flex;flex-direction:column;gap:.5rem;flex-shrink:0}.z-time-picker .z-time-columns{display:flex;gap:.25rem}.z-time-picker .z-time-column{width:42px;height:180px;overflow-y:auto;scroll-snap-type:y mandatory;scroll-behavior:smooth;scrollbar-width:thin}.z-time-picker .z-time-column::-webkit-scrollbar{width:4px}.z-time-picker .z-time-column::-webkit-scrollbar-track{background:transparent}.z-time-picker .z-time-column::-webkit-scrollbar-thumb{background-color:hsl(var(--border));border-radius:2px}.z-time-picker .z-time-item{height:32px;width:100%;display:flex;align-items:center;justify-content:center;font-size:.875rem;scroll-snap-align:center;border-radius:4px;cursor:pointer;transition:background-color .15s ease,color .15s ease}.z-time-picker .z-time-item:hover:not(.z-time-item-selected){background-color:hsl(var(--muted))}.z-time-picker .z-time-item.z-time-item-selected{background-color:hsl(var(--primary));color:hsl(var(--primary-foreground));font-weight:500}.z-time-picker .z-time-item:focus-visible{outline:2px solid hsl(var(--ring));outline-offset:-2px}.z-time-picker .z-time-period-buttons{display:flex;flex-direction:column;gap:.25rem;padding-top:8px}.z-time-picker .z-time-period-buttons button{height:28px;font-size:.75rem;border-radius:4px;transition:background-color .15s ease,color .15s ease}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"], dependencies: [{ kind: "component", type: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zManualClose", "zScrollClose", "zShowArrow"], outputs: ["zShow", "zHide", "zHideStart", "zControl"], exportAs: ["zPopover"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: ZDayClassesPipe, name: "zDayClasses" }, { kind: "pipe", type: ZMonthClassesPipe, name: "zMonthClasses" }, { kind: "pipe", type: ZQuarterClassesPipe, name: "zQuarterClasses" }, { kind: "pipe", type: ZYearClassesPipe, name: "zYearClasses" }, { kind: "pipe", type: ZIsPresetDisabledPipe, name: "zIsPresetDisabled" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2845
|
+
], viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }, { propertyName: "inputRef", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }], exportAs: ["zCalendar"], ngImport: i0, template: "<div class=\"z-calendar-wrapper flex w-full flex-col gap-2\">\n @if (zLabel()) {\n <label [for]=\"pickerId\" class=\"text-xs leading-none font-medium\" [class]=\"zLabelClass()\">\n {{ zLabel() }}\n @if (zRequired()) {\n <span class=\"text-destructive! ml-0.5\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <div\n #triggerEl\n z-popover\n [zPopoverContent]=\"calendarTpl\"\n zPosition=\"bottom-left\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"6\"\n [zDisabled]=\"isDisabled() || zReadonly()\"\n [zManualClose]=\"showCancelButton()\"\n [zScrollClose]=\"zScrollClose()\"\n zTrigger=\"click\"\n zClass=\"border-0 shadow-none bg-transparent p-0\"\n (zHideStart)=\"onPopoverHide()\"\n (zShow)=\"onPopoverShow()\"\n (zControl)=\"onPopoverControl($event)\"\n [id]=\"pickerId\"\n [class]=\"triggerClasses()\"\n (keydown)=\"onTriggerKeydown($event)\">\n <z-icon\n [zType]=\"isRangeMode() ? 'lucideCalendarRange' : 'lucideCalendar'\"\n zSize=\"16\"\n class=\"text-muted-foreground shrink-0 cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggle()\" />\n\n @if (isRangeMode()) {\n <input\n type=\"text\"\n data-range-type=\"start\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_start_date' | translate\"\n [value]=\"inputDisplayStart()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onStartInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onStartInputEnter($event)\"\n (keydown.escape)=\"onStartInputEscape()\" />\n <span class=\"text-muted-foreground text-sm\">-</span>\n <input\n type=\"text\"\n data-range-type=\"end\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_end_date' | translate\"\n [value]=\"inputDisplayEnd()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onEndInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onEndInputEnter($event)\"\n (keydown.escape)=\"onEndInputEscape()\" />\n } @else {\n <input\n #inputEl\n type=\"text\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-sm outline-none\"\n [placeholder]=\"zPlaceholder()\"\n [value]=\"inputDisplayValue()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onInputEnter($event)\"\n (keydown.escape)=\"onInputEscape()\" />\n }\n\n @if (zAllowClear() && !isDisabled() && !zReadonly()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"text-muted-foreground hover:text-foreground flex size-5 shrink-0 cursor-pointer items-center justify-center rounded transition-all\"\n [class.opacity-0]=\"!hasValue()\"\n [class.pointer-events-none]=\"!hasValue()\"\n (click)=\"onClear($event)\">\n <z-icon zType=\"lucideX\" zSize=\"14\" />\n </button>\n }\n </div>\n </div>\n\n @if (showError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n</div>\n\n<ng-template #calendarTpl>\n <div\n class=\"z-calendar-calendar bg-popover border-border flex max-h-[90vh] max-w-[95vw] flex-col overflow-auto rounded-[6px] border shadow-lg sm:max-h-none sm:max-w-none sm:flex-row sm:overflow-visible\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div\n class=\"border-border flex shrink-0 flex-row gap-1 overflow-x-auto border-b p-2 sm:flex-col sm:gap-0 sm:space-y-1 sm:overflow-x-visible sm:border-r sm:border-b-0\">\n @for (preset of quickSelectPresets; track preset.key) {\n @let presetDisabled = preset | zIsPresetDisabled: zDisabledDate();\n <button\n type=\"button\"\n class=\"cursor-pointer rounded-[4px] px-3 py-1.5 text-left text-sm whitespace-nowrap transition-colors\"\n [class.hover:bg-muted]=\"activePresetKey() !== preset.key && !presetDisabled\"\n [class.bg-primary]=\"activePresetKey() === preset.key\"\n [class.text-primary-foreground]=\"activePresetKey() === preset.key\"\n [class.font-medium]=\"activePresetKey() === preset.key\"\n [class.opacity-40]=\"presetDisabled\"\n [class.cursor-not-allowed]=\"presetDisabled\"\n [disabled]=\"presetDisabled\"\n (click)=\"onQuickSelect(preset)\">\n {{ preset.label }}\n </button>\n }\n </div>\n }\n <div class=\"flex flex-1 flex-col gap-2 overflow-auto p-3 sm:overflow-visible\">\n @if (!isTimeMode()) {\n <div class=\"z-calendars-wrapper flex flex-col items-start gap-3 sm:flex-row sm:gap-0\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex flex-col gap-1\">\n @if (!isTimeMode()) {\n <div class=\"flex w-full items-center justify-between space-x-1\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePrevious()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePreviousFast()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0.5\">\n @if (!isYearMode() && !isQuarterMode()) {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"w-20 px-2!\"\n [zWave]=\"false\"\n [zDisabled]=\"false\"\n (click)=\"setView('month')\">\n {{ currentMonthName() }}\n </button>\n }\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"px-2!\"\n [zWave]=\"false\"\n [zDisabled]=\"isYearMode()\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNextFast()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNext()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"16\" />\n </button>\n </div>\n\n <div class=\"z-calendar-views w-full\" [class.z-calendar-views-quarter]=\"isQuarterMode()\">\n @if (currentView() === 'day') {\n <div class=\"flex h-full w-full flex-col gap-1\" [class.z-calendar-animate]=\"hasViewChanged()\">\n <div class=\"grid w-full grid-cols-7\">\n @for (weekday of weekdayNames; track weekday) {\n <div class=\"text-muted-foreground flex h-7 items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n @for (week of calendarDays(); track $index) {\n <div class=\"grid w-full grid-cols-7\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'month') {\n <div class=\"grid h-full w-full grid-cols-3 grid-rows-4\" [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let monthDisabled = isStartMonthDisabled(i);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: currentMonthIndex()\"\n [disabled]=\"monthDisabled\"\n [class.opacity-30]=\"monthDisabled\"\n [class.cursor-not-allowed]=\"monthDisabled\"\n (click)=\"onMonthSelect(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 gap-0.5\"\n [class.grid-rows-4]=\"!isYearMode() && !isQuarterMode()\"\n [class.grid-rows-3]=\"isYearMode() || isQuarterMode()\"\n [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (year of isYearMode() || isQuarterMode() ? yearRangeSmall() : yearRange(); track year) {\n @let yearDisabled = isStartYearDisabled(year);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: currentYear()\"\n [disabled]=\"yearDisabled\"\n [class.opacity-30]=\"yearDisabled\"\n [class.cursor-not-allowed]=\"yearDisabled\"\n (click)=\"onYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'quarter') {\n <div class=\"grid w-full grid-cols-2 gap-2\" [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (quarter of quarterNames; track quarter; let i = $index) {\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zQuarterClasses: currentQuarterIndex()\"\n (click)=\"onQuarterClick(i)\">\n {{ quarter }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time Picker Side Panel (for single date with showTime) -->\n @if (!isRangeMode() && zShowTime() && currentView() === 'day') {\n <div\n class=\"border-border mt-3 flex w-full flex-col items-center border-t pt-3 sm:mt-0 sm:w-auto sm:border-t-0 sm:border-l sm:pt-0 sm:pl-3\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_time' | translate }}\n </div>\n <div class=\"flex flex-col items-center gap-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[140px] w-12 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[140px] w-12 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[140px] w-12 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex w-full gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div class=\"border-border bg-border hidden self-stretch sm:mx-3 sm:block sm:w-px\"></div>\n <div class=\"border-border bg-border block h-px w-full sm:hidden\"></div>\n\n <div class=\"z-calendar-section flex flex-col gap-1\">\n <div class=\"flex w-full items-center justify-between space-x-1\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0.5\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"w-20 px-2!\"\n [zWave]=\"false\"\n (click)=\"setEndView('month')\">\n {{ endMonthName() }}\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"px-2!\"\n [zWave]=\"false\"\n (click)=\"setEndView('year')\">\n {{ endMonthYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"16\" />\n </button>\n </div>\n\n <div class=\"z-calendar-views w-full\">\n @if (endView() === 'day') {\n <div class=\"flex h-full w-full flex-col gap-1\" [class.z-calendar-animate]=\"hasEndViewChanged()\">\n <div class=\"grid grid-cols-7 gap-px\">\n @for (weekday of weekdayNames; track weekday) {\n <div class=\"text-muted-foreground flex h-8 w-8 items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n @for (week of calendarDaysEnd(); track $index) {\n <div class=\"grid grid-cols-7 gap-px\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (endView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4\"\n [class.z-calendar-animate]=\"hasEndViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let endMonthDisabled = isEndMonthDisabled(i);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: endMonth().getMonth()\"\n [disabled]=\"endMonthDisabled\"\n [class.opacity-30]=\"endMonthDisabled\"\n [class.cursor-not-allowed]=\"endMonthDisabled\"\n (click)=\"onEndMonthClick(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (endView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-0.5\"\n [class.z-calendar-animate]=\"hasEndViewChanged()\">\n @for (year of endYearRange(); track year) {\n @let endYearDisabled = isEndYearDisabled(year);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: endMonth().getFullYear()\"\n [disabled]=\"endYearDisabled\"\n [class.opacity-30]=\"endYearDisabled\"\n [class.cursor-not-allowed]=\"endYearDisabled\"\n (click)=\"onEndYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Range Mode Time Picker Side Panel -->\n @if (isRangeMode() && zShowTime() && currentView() === 'day' && endView() === 'day') {\n <div\n class=\"border-border mt-3 flex w-full flex-row justify-center gap-3 border-t pt-3 sm:mt-0 sm:w-auto sm:border-t-0 sm:border-l sm:pt-0 sm:pl-3\">\n <!-- Start Time -->\n <div class=\"flex flex-col\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_start' | translate }}\n </div>\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 flex-1 cursor-pointer items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 flex-1 cursor-pointer items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n\n <!-- End Time -->\n <div class=\"flex flex-col\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_end' | translate }}\n </div>\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n @let hourDisabled = isEndHourDisabled(hour);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!hourDisabled\"\n [class.cursor-pointer]=\"!hourDisabled\"\n [class.bg-primary]=\"isHourEndSelected(hour)\"\n [class.text-primary-foreground]=\"isHourEndSelected(hour)\"\n [class.font-medium]=\"isHourEndSelected(hour)\"\n [class.opacity-30]=\"hourDisabled\"\n [class.cursor-not-allowed]=\"hourDisabled\"\n [disabled]=\"hourDisabled\"\n (click)=\"selectHourEnd(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n @let minuteDisabled = isEndMinuteDisabled(minute);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!minuteDisabled\"\n [class.cursor-pointer]=\"!minuteDisabled\"\n [class.bg-primary]=\"isMinuteEndSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteEndSelected(minute)\"\n [class.font-medium]=\"isMinuteEndSelected(minute)\"\n [class.opacity-30]=\"minuteDisabled\"\n [class.cursor-not-allowed]=\"minuteDisabled\"\n [disabled]=\"minuteDisabled\"\n (click)=\"selectMinuteEnd(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n @let secondDisabled = isEndSecondDisabled(second);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!secondDisabled\"\n [class.cursor-pointer]=\"!secondDisabled\"\n [class.bg-primary]=\"isSecondEndSelected(second)\"\n [class.text-primary-foreground]=\"isSecondEndSelected(second)\"\n [class.font-medium]=\"isSecondEndSelected(second)\"\n [class.opacity-30]=\"secondDisabled\"\n [class.cursor-not-allowed]=\"secondDisabled\"\n [disabled]=\"secondDisabled\"\n (click)=\"selectSecondEnd(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex gap-1\">\n @let amDisabled = isEndPeriodDisabled('AM');\n <button\n type=\"button\"\n class=\"flex h-6 flex-1 items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.hover:bg-muted]=\"!amDisabled\"\n [class.cursor-pointer]=\"!amDisabled\"\n [class.bg-primary]=\"periodEnd() === 'AM'\"\n [class.text-primary-foreground]=\"periodEnd() === 'AM'\"\n [class.opacity-30]=\"amDisabled\"\n [class.cursor-not-allowed]=\"amDisabled\"\n [disabled]=\"amDisabled\"\n (click)=\"selectPeriodEnd('AM')\">\n AM\n </button>\n @let pmDisabled = isEndPeriodDisabled('PM');\n <button\n type=\"button\"\n class=\"flex h-6 flex-1 items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.hover:bg-muted]=\"!pmDisabled\"\n [class.cursor-pointer]=\"!pmDisabled\"\n [class.bg-primary]=\"periodEnd() === 'PM'\"\n [class.text-primary-foreground]=\"periodEnd() === 'PM'\"\n [class.opacity-30]=\"pmDisabled\"\n [class.cursor-not-allowed]=\"pmDisabled\"\n [disabled]=\"pmDisabled\"\n (click)=\"selectPeriodEnd('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"flex flex-col items-center gap-2 py-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex w-full gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n }\n\n @if (!(zQuickSelect() && zMode() === 'range' && !showOkButton() && !showCancelButton())) {\n <div class=\"border-border flex items-center justify-between gap-2 border-t pt-2\">\n @if (!zQuickSelect() || zMode() !== 'range') {\n <button type=\"button\" z-button zType=\"secondary\" zSize=\"sm\" [zWave]=\"false\" (click)=\"onTodayClick()\">\n {{ todayButtonText() }}\n </button>\n } @else {\n <div></div>\n }\n\n @if (showOkButton() || showCancelButton()) {\n <div class=\"flex items-center gap-2\">\n @if (showCancelButton()) {\n <button type=\"button\" z-button zType=\"outline\" zSize=\"sm\" (click)=\"onCancelClick()\">\n {{ zCancelText() ?? ('i18n_z_ui_calendar_cancel' | translate) }}\n </button>\n }\n @if (showOkButton()) {\n <button type=\"button\" z-button zSize=\"sm\" [zDisabled]=\"!canApply()\" (click)=\"onOkClick()\">\n {{ zOkText() ?? ('i18n_z_ui_calendar_ok' | translate) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n", styles: [".z-calendar-calendar .z-calendar-section{width:280px;flex-shrink:0}.z-calendar-calendar .z-calendar-views{height:225px;width:100%;display:flex;align-items:center;justify-content:center;flex-direction:column}.z-calendar-calendar .z-calendar-views.z-calendar-views-quarter{height:auto}.z-calendar-calendar .z-calendar-animate{animation:z-calendar-view-enter .2s ease-out}.z-time-picker{display:flex;flex-direction:column;gap:.5rem;flex-shrink:0}.z-time-picker .z-time-columns{display:flex;gap:.25rem}.z-time-picker .z-time-column{width:42px;height:180px;overflow-y:auto;scroll-snap-type:y mandatory;scroll-behavior:smooth;scrollbar-width:thin}.z-time-picker .z-time-column::-webkit-scrollbar{width:4px}.z-time-picker .z-time-column::-webkit-scrollbar-track{background:transparent}.z-time-picker .z-time-column::-webkit-scrollbar-thumb{background-color:hsl(var(--border));border-radius:2px}.z-time-picker .z-time-item{height:32px;width:100%;display:flex;align-items:center;justify-content:center;font-size:.875rem;scroll-snap-align:center;border-radius:4px;cursor:pointer;transition:background-color .15s ease,color .15s ease}.z-time-picker .z-time-item:hover:not(.z-time-item-selected){background-color:hsl(var(--muted))}.z-time-picker .z-time-item.z-time-item-selected{background-color:hsl(var(--primary));color:hsl(var(--primary-foreground));font-weight:500}.z-time-picker .z-time-item:focus-visible{outline:2px solid hsl(var(--ring));outline-offset:-2px}.z-time-picker .z-time-period-buttons{display:flex;flex-direction:column;gap:.25rem;padding-top:8px}.z-time-picker .z-time-period-buttons button{height:28px;font-size:.75rem;border-radius:4px;transition:background-color .15s ease,color .15s ease}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"], dependencies: [{ kind: "component", type: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zManualClose", "zScrollClose", "zShowArrow"], outputs: ["zShow", "zHide", "zHideStart", "zControl"], exportAs: ["zPopover"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: ZDayClassesPipe, name: "zDayClasses" }, { kind: "pipe", type: ZMonthClassesPipe, name: "zMonthClasses" }, { kind: "pipe", type: ZQuarterClassesPipe, name: "zQuarterClasses" }, { kind: "pipe", type: ZYearClassesPipe, name: "zYearClasses" }, { kind: "pipe", type: ZIsPresetDisabledPipe, name: "zIsPresetDisabled" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2855
2846
|
}
|
|
2856
2847
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZCalendarComponent, decorators: [{
|
|
2857
2848
|
type: Component,
|
|
@@ -2874,7 +2865,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2874
2865
|
multi: true,
|
|
2875
2866
|
},
|
|
2876
2867
|
TranslatePipe,
|
|
2877
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, exportAs: 'zCalendar', template: "<div class=\"z-calendar-wrapper flex w-full flex-col gap-2\">\n @if (zLabel()) {\n <label [for]=\"pickerId\" class=\"text-xs leading-none font-medium\" [class]=\"zLabelClass()\">\n {{ zLabel() }}\n @if (zRequired()) {\n <span class=\"text-destructive! ml-0.5\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <div\n #triggerEl\n z-popover\n [zPopoverContent]=\"calendarTpl\"\n zPosition=\"bottom-left\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"6\"\n [zDisabled]=\"isDisabled() || zReadonly()\"\n [zManualClose]=\"showCancelButton()\"\n [zScrollClose]=\"zScrollClose()\"\n zTrigger=\"click\"\n zClass=\"border-0 shadow-none bg-transparent p-0\"\n (zHideStart)=\"onPopoverHide()\"\n (zShow)=\"onPopoverShow()\"\n (zControl)=\"onPopoverControl($event)\"\n [id]=\"pickerId\"\n [class]=\"triggerClasses()\"\n (keydown)=\"onTriggerKeydown($event)\">\n <z-icon\n [zType]=\"isRangeMode() ? 'lucideCalendarRange' : 'lucideCalendar'\"\n zSize=\"16\"\n class=\"text-muted-foreground shrink-0 cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggle()\" />\n\n @if (isRangeMode()) {\n <input\n type=\"text\"\n data-range-type=\"start\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_start_date' | translate\"\n [value]=\"inputDisplayStart()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onStartInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onStartInputEnter($event)\"\n (keydown.escape)=\"onStartInputEscape()\" />\n <span class=\"text-muted-foreground text-sm\">-</span>\n <input\n type=\"text\"\n data-range-type=\"end\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_end_date' | translate\"\n [value]=\"inputDisplayEnd()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onEndInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onEndInputEnter($event)\"\n (keydown.escape)=\"onEndInputEscape()\" />\n } @else {\n <input\n #inputEl\n type=\"text\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-sm outline-none\"\n [placeholder]=\"zPlaceholder()\"\n [value]=\"inputDisplayValue()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onInputEnter($event)\"\n (keydown.escape)=\"onInputEscape()\" />\n }\n\n @if (zAllowClear() && !isDisabled() && !zReadonly()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"text-muted-foreground hover:text-foreground flex size-5 shrink-0 cursor-pointer items-center justify-center rounded transition-all\"\n [class.opacity-0]=\"!hasValue()\"\n [class.pointer-events-none]=\"!hasValue()\"\n (click)=\"onClear($event)\">\n <z-icon zType=\"lucideX\" zSize=\"14\" />\n </button>\n }\n </div>\n </div>\n\n @if (showError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n</div>\n\n<ng-template #calendarTpl>\n <div\n class=\"z-calendar-calendar bg-popover border-border flex rounded-[6px] border shadow-lg\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div class=\"border-border flex flex-col space-y-1 border-r p-2\">\n @for (preset of quickSelectPresets; track preset.key) {\n @let presetDisabled = preset | zIsPresetDisabled: zDisabledDate();\n <button\n type=\"button\"\n class=\"cursor-pointer rounded-[4px] px-3 py-1.5 text-left text-sm whitespace-nowrap transition-colors\"\n [class.hover:bg-muted]=\"activePresetKey() !== preset.key && !presetDisabled\"\n [class.bg-primary]=\"activePresetKey() === preset.key\"\n [class.text-primary-foreground]=\"activePresetKey() === preset.key\"\n [class.font-medium]=\"activePresetKey() === preset.key\"\n [class.opacity-40]=\"presetDisabled\"\n [class.cursor-not-allowed]=\"presetDisabled\"\n [disabled]=\"presetDisabled\"\n (click)=\"onQuickSelect(preset)\">\n {{ preset.label }}\n </button>\n }\n </div>\n }\n <div class=\"flex flex-col gap-2 p-3\">\n @if (!isTimeMode()) {\n <div class=\"z-calendars-wrapper flex items-start\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex flex-col gap-1\">\n @if (!isTimeMode()) {\n <div class=\"flex w-full items-center justify-between space-x-1\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePrevious()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePreviousFast()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0.5\">\n @if (!isYearMode() && !isQuarterMode()) {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"w-20 px-2!\"\n [zWave]=\"false\"\n [zDisabled]=\"false\"\n (click)=\"setView('month')\">\n {{ currentMonthName() }}\n </button>\n }\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"px-2!\"\n [zWave]=\"false\"\n [zDisabled]=\"isYearMode()\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNextFast()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNext()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"16\" />\n </button>\n </div>\n\n <div class=\"z-calendar-views w-full\" [class.z-calendar-views-quarter]=\"isQuarterMode()\">\n @if (currentView() === 'day') {\n <div class=\"flex h-full w-full flex-col gap-1\" [class.z-calendar-animate]=\"hasViewChanged()\">\n <div class=\"grid w-full grid-cols-7\">\n @for (weekday of weekdayNames; track weekday) {\n <div class=\"text-muted-foreground flex h-7 items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n @for (week of calendarDays(); track $index) {\n <div class=\"grid w-full grid-cols-7\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'month') {\n <div class=\"grid h-full w-full grid-cols-3 grid-rows-4\" [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let monthDisabled = isStartMonthDisabled(i);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: currentMonthIndex()\"\n [disabled]=\"monthDisabled\"\n [class.opacity-30]=\"monthDisabled\"\n [class.cursor-not-allowed]=\"monthDisabled\"\n (click)=\"onMonthSelect(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 gap-0.5\"\n [class.grid-rows-4]=\"!isYearMode() && !isQuarterMode()\"\n [class.grid-rows-3]=\"isYearMode() || isQuarterMode()\"\n [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (year of isYearMode() || isQuarterMode() ? yearRangeSmall() : yearRange(); track year) {\n @let yearDisabled = isStartYearDisabled(year);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: currentYear()\"\n [disabled]=\"yearDisabled\"\n [class.opacity-30]=\"yearDisabled\"\n [class.cursor-not-allowed]=\"yearDisabled\"\n (click)=\"onYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'quarter') {\n <div class=\"grid w-full grid-cols-2 gap-2\" [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (quarter of quarterNames; track quarter; let i = $index) {\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zQuarterClasses: currentQuarterIndex()\"\n (click)=\"onQuarterClick(i)\">\n {{ quarter }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time Picker Side Panel (for single date with showTime) -->\n @if (!isRangeMode() && zShowTime() && currentView() === 'day') {\n <div class=\"border-border flex flex-col border-l pl-3\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_time' | translate }}\n </div>\n <div class=\"flex gap-1\">\n <!-- Hour Column -->\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[235px] w-12 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n\n <!-- Minute Column -->\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[235px] w-12 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n\n <!-- Second Column -->\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[235px] w-12 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n\n <!-- AM/PM Column -->\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 w-12 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 w-12 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div class=\"border-border bg-border mx-3 w-px self-stretch\"></div>\n\n <div class=\"z-calendar-section flex flex-col gap-1\">\n <div class=\"flex w-full items-center justify-between space-x-1\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0.5\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"w-20 px-2!\"\n [zWave]=\"false\"\n (click)=\"setEndView('month')\">\n {{ endMonthName() }}\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"px-2!\"\n [zWave]=\"false\"\n (click)=\"setEndView('year')\">\n {{ endMonthYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"16\" />\n </button>\n </div>\n\n <div class=\"z-calendar-views w-full\">\n @if (endView() === 'day') {\n <div class=\"flex h-full w-full flex-col gap-1\" [class.z-calendar-animate]=\"hasEndViewChanged()\">\n <div class=\"grid grid-cols-7 gap-px\">\n @for (weekday of weekdayNames; track weekday) {\n <div class=\"text-muted-foreground flex h-8 w-8 items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n @for (week of calendarDaysEnd(); track $index) {\n <div class=\"grid grid-cols-7 gap-px\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (endView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4\"\n [class.z-calendar-animate]=\"hasEndViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let endMonthDisabled = isEndMonthDisabled(i);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: endMonth().getMonth()\"\n [disabled]=\"endMonthDisabled\"\n [class.opacity-30]=\"endMonthDisabled\"\n [class.cursor-not-allowed]=\"endMonthDisabled\"\n (click)=\"onEndMonthClick(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (endView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-0.5\"\n [class.z-calendar-animate]=\"hasEndViewChanged()\">\n @for (year of endYearRange(); track year) {\n @let endYearDisabled = isEndYearDisabled(year);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: endMonth().getFullYear()\"\n [disabled]=\"endYearDisabled\"\n [class.opacity-30]=\"endYearDisabled\"\n [class.cursor-not-allowed]=\"endYearDisabled\"\n (click)=\"onEndYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Range Mode Time Picker Side Panel -->\n @if (isRangeMode() && zShowTime() && currentView() === 'day' && endView() === 'day') {\n <div class=\"border-border flex flex-col gap-4 border-l pl-3\">\n <!-- Start Time -->\n <div class=\"flex flex-col\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_start' | translate }}\n </div>\n <div class=\"flex gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 w-9 cursor-pointer items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 w-9 cursor-pointer items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n\n <!-- End Time -->\n <div class=\"flex flex-col\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_end' | translate }}\n </div>\n <div class=\"flex gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n @let hourDisabled = isEndHourDisabled(hour);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!hourDisabled\"\n [class.cursor-pointer]=\"!hourDisabled\"\n [class.bg-primary]=\"isHourEndSelected(hour)\"\n [class.text-primary-foreground]=\"isHourEndSelected(hour)\"\n [class.font-medium]=\"isHourEndSelected(hour)\"\n [class.opacity-30]=\"hourDisabled\"\n [class.cursor-not-allowed]=\"hourDisabled\"\n [disabled]=\"hourDisabled\"\n (click)=\"selectHourEnd(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n @let minuteDisabled = isEndMinuteDisabled(minute);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!minuteDisabled\"\n [class.cursor-pointer]=\"!minuteDisabled\"\n [class.bg-primary]=\"isMinuteEndSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteEndSelected(minute)\"\n [class.font-medium]=\"isMinuteEndSelected(minute)\"\n [class.opacity-30]=\"minuteDisabled\"\n [class.cursor-not-allowed]=\"minuteDisabled\"\n [disabled]=\"minuteDisabled\"\n (click)=\"selectMinuteEnd(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[140px] w-10 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n @let secondDisabled = isEndSecondDisabled(second);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!secondDisabled\"\n [class.cursor-pointer]=\"!secondDisabled\"\n [class.bg-primary]=\"isSecondEndSelected(second)\"\n [class.text-primary-foreground]=\"isSecondEndSelected(second)\"\n [class.font-medium]=\"isSecondEndSelected(second)\"\n [class.opacity-30]=\"secondDisabled\"\n [class.cursor-not-allowed]=\"secondDisabled\"\n [disabled]=\"secondDisabled\"\n (click)=\"selectSecondEnd(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n @let amDisabled = isEndPeriodDisabled('AM');\n <button\n type=\"button\"\n class=\"flex h-6 w-9 items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.hover:bg-muted]=\"!amDisabled\"\n [class.cursor-pointer]=\"!amDisabled\"\n [class.bg-primary]=\"periodEnd() === 'AM'\"\n [class.text-primary-foreground]=\"periodEnd() === 'AM'\"\n [class.opacity-30]=\"amDisabled\"\n [class.cursor-not-allowed]=\"amDisabled\"\n [disabled]=\"amDisabled\"\n (click)=\"selectPeriodEnd('AM')\">\n AM\n </button>\n @let pmDisabled = isEndPeriodDisabled('PM');\n <button\n type=\"button\"\n class=\"flex h-6 w-9 items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.hover:bg-muted]=\"!pmDisabled\"\n [class.cursor-pointer]=\"!pmDisabled\"\n [class.bg-primary]=\"periodEnd() === 'PM'\"\n [class.text-primary-foreground]=\"periodEnd() === 'PM'\"\n [class.opacity-30]=\"pmDisabled\"\n [class.cursor-not-allowed]=\"pmDisabled\"\n [disabled]=\"pmDisabled\"\n (click)=\"selectPeriodEnd('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"flex justify-center gap-1 py-2\">\n <!-- Hour Column -->\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n\n <!-- Minute Column -->\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n\n <!-- Second Column -->\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n\n <!-- AM/PM Column -->\n @if (zTimeFormat() === '12h') {\n <div class=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 w-14 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 w-14 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n }\n\n @if (!(zQuickSelect() && zMode() === 'range' && !showOkButton() && !showCancelButton())) {\n <div class=\"border-border flex items-center justify-between gap-2 border-t pt-2\">\n @if (!zQuickSelect() || zMode() !== 'range') {\n <button type=\"button\" z-button zType=\"secondary\" zSize=\"sm\" [zWave]=\"false\" (click)=\"onTodayClick()\">\n {{ todayButtonText() }}\n </button>\n } @else {\n <div></div>\n }\n\n @if (showOkButton() || showCancelButton()) {\n <div class=\"flex items-center gap-2\">\n @if (showCancelButton()) {\n <button type=\"button\" z-button zType=\"outline\" zSize=\"sm\" (click)=\"onCancelClick()\">\n {{ zCancelText() ?? ('i18n_z_ui_calendar_cancel' | translate) }}\n </button>\n }\n @if (showOkButton()) {\n <button type=\"button\" z-button zSize=\"sm\" [zDisabled]=\"!canApply()\" (click)=\"onOkClick()\">\n {{ zOkText() ?? ('i18n_z_ui_calendar_ok' | translate) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n", styles: [".z-calendar-calendar .z-calendar-section{width:280px;flex-shrink:0}.z-calendar-calendar .z-calendar-views{height:225px;width:100%;display:flex;align-items:center;justify-content:center;flex-direction:column}.z-calendar-calendar .z-calendar-views.z-calendar-views-quarter{height:auto}.z-calendar-calendar .z-calendar-animate{animation:z-calendar-view-enter .2s ease-out}.z-time-picker{display:flex;flex-direction:column;gap:.5rem;flex-shrink:0}.z-time-picker .z-time-columns{display:flex;gap:.25rem}.z-time-picker .z-time-column{width:42px;height:180px;overflow-y:auto;scroll-snap-type:y mandatory;scroll-behavior:smooth;scrollbar-width:thin}.z-time-picker .z-time-column::-webkit-scrollbar{width:4px}.z-time-picker .z-time-column::-webkit-scrollbar-track{background:transparent}.z-time-picker .z-time-column::-webkit-scrollbar-thumb{background-color:hsl(var(--border));border-radius:2px}.z-time-picker .z-time-item{height:32px;width:100%;display:flex;align-items:center;justify-content:center;font-size:.875rem;scroll-snap-align:center;border-radius:4px;cursor:pointer;transition:background-color .15s ease,color .15s ease}.z-time-picker .z-time-item:hover:not(.z-time-item-selected){background-color:hsl(var(--muted))}.z-time-picker .z-time-item.z-time-item-selected{background-color:hsl(var(--primary));color:hsl(var(--primary-foreground));font-weight:500}.z-time-picker .z-time-item:focus-visible{outline:2px solid hsl(var(--ring));outline-offset:-2px}.z-time-picker .z-time-period-buttons{display:flex;flex-direction:column;gap:.25rem;padding-top:8px}.z-time-picker .z-time-period-buttons button{height:28px;font-size:.75rem;border-radius:4px;transition:background-color .15s ease,color .15s ease}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"] }]
|
|
2868
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, exportAs: 'zCalendar', template: "<div class=\"z-calendar-wrapper flex w-full flex-col gap-2\">\n @if (zLabel()) {\n <label [for]=\"pickerId\" class=\"text-xs leading-none font-medium\" [class]=\"zLabelClass()\">\n {{ zLabel() }}\n @if (zRequired()) {\n <span class=\"text-destructive! ml-0.5\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <div\n #triggerEl\n z-popover\n [zPopoverContent]=\"calendarTpl\"\n zPosition=\"bottom-left\"\n zPopoverWidth=\"auto\"\n [zOffset]=\"6\"\n [zDisabled]=\"isDisabled() || zReadonly()\"\n [zManualClose]=\"showCancelButton()\"\n [zScrollClose]=\"zScrollClose()\"\n zTrigger=\"click\"\n zClass=\"border-0 shadow-none bg-transparent p-0\"\n (zHideStart)=\"onPopoverHide()\"\n (zShow)=\"onPopoverShow()\"\n (zControl)=\"onPopoverControl($event)\"\n [id]=\"pickerId\"\n [class]=\"triggerClasses()\"\n (keydown)=\"onTriggerKeydown($event)\">\n <z-icon\n [zType]=\"isRangeMode() ? 'lucideCalendarRange' : 'lucideCalendar'\"\n zSize=\"16\"\n class=\"text-muted-foreground shrink-0 cursor-pointer\"\n (click)=\"$event.stopPropagation(); toggle()\" />\n\n @if (isRangeMode()) {\n <input\n type=\"text\"\n data-range-type=\"start\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_start_date' | translate\"\n [value]=\"inputDisplayStart()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onStartInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onStartInputEnter($event)\"\n (keydown.escape)=\"onStartInputEscape()\" />\n <span class=\"text-muted-foreground text-sm\">-</span>\n <input\n type=\"text\"\n data-range-type=\"end\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-center text-sm outline-none\"\n [placeholder]=\"'i18n_z_ui_calendar_end_date' | translate\"\n [value]=\"inputDisplayEnd()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onEndInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onEndInputEnter($event)\"\n (keydown.escape)=\"onEndInputEscape()\" />\n } @else {\n <input\n #inputEl\n type=\"text\"\n class=\"placeholder:text-muted-foreground min-w-0 flex-1 truncate bg-transparent text-sm outline-none\"\n [placeholder]=\"zPlaceholder()\"\n [value]=\"inputDisplayValue()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"zReadonly()\"\n (click)=\"isOpen() && $event.stopPropagation()\"\n (focus)=\"onInputFocus($event)\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur($event)\"\n (keydown.enter)=\"onInputEnter($event)\"\n (keydown.escape)=\"onInputEscape()\" />\n }\n\n @if (zAllowClear() && !isDisabled() && !zReadonly()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"text-muted-foreground hover:text-foreground flex size-5 shrink-0 cursor-pointer items-center justify-center rounded transition-all\"\n [class.opacity-0]=\"!hasValue()\"\n [class.pointer-events-none]=\"!hasValue()\"\n (click)=\"onClear($event)\">\n <z-icon zType=\"lucideX\" zSize=\"14\" />\n </button>\n }\n </div>\n </div>\n\n @if (showError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n</div>\n\n<ng-template #calendarTpl>\n <div\n class=\"z-calendar-calendar bg-popover border-border flex max-h-[90vh] max-w-[95vw] flex-col overflow-auto rounded-[6px] border shadow-lg sm:max-h-none sm:max-w-none sm:flex-row sm:overflow-visible\"\n (keydown)=\"onCalendarKeydown($event)\">\n @if (zQuickSelect() && zMode() === 'range') {\n <div\n class=\"border-border flex shrink-0 flex-row gap-1 overflow-x-auto border-b p-2 sm:flex-col sm:gap-0 sm:space-y-1 sm:overflow-x-visible sm:border-r sm:border-b-0\">\n @for (preset of quickSelectPresets; track preset.key) {\n @let presetDisabled = preset | zIsPresetDisabled: zDisabledDate();\n <button\n type=\"button\"\n class=\"cursor-pointer rounded-[4px] px-3 py-1.5 text-left text-sm whitespace-nowrap transition-colors\"\n [class.hover:bg-muted]=\"activePresetKey() !== preset.key && !presetDisabled\"\n [class.bg-primary]=\"activePresetKey() === preset.key\"\n [class.text-primary-foreground]=\"activePresetKey() === preset.key\"\n [class.font-medium]=\"activePresetKey() === preset.key\"\n [class.opacity-40]=\"presetDisabled\"\n [class.cursor-not-allowed]=\"presetDisabled\"\n [disabled]=\"presetDisabled\"\n (click)=\"onQuickSelect(preset)\">\n {{ preset.label }}\n </button>\n }\n </div>\n }\n <div class=\"flex flex-1 flex-col gap-2 overflow-auto p-3 sm:overflow-visible\">\n @if (!isTimeMode()) {\n <div class=\"z-calendars-wrapper flex flex-col items-start gap-3 sm:flex-row sm:gap-0\">\n <!-- First Calendar -->\n <div class=\"z-calendar-section flex flex-col gap-1\">\n @if (!isTimeMode()) {\n <div class=\"flex w-full items-center justify-between space-x-1\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePrevious()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigatePreviousFast()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0.5\">\n @if (!isYearMode() && !isQuarterMode()) {\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"w-20 px-2!\"\n [zWave]=\"false\"\n [zDisabled]=\"false\"\n (click)=\"setView('month')\">\n {{ currentMonthName() }}\n </button>\n }\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"px-2!\"\n [zWave]=\"false\"\n [zDisabled]=\"isYearMode()\"\n (click)=\"setView('year')\">\n {{ currentYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNextFast()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateStartNext()\"\n [zWave]=\"false\"\n (click)=\"navigateNext()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"16\" />\n </button>\n </div>\n\n <div class=\"z-calendar-views w-full\" [class.z-calendar-views-quarter]=\"isQuarterMode()\">\n @if (currentView() === 'day') {\n <div class=\"flex h-full w-full flex-col gap-1\" [class.z-calendar-animate]=\"hasViewChanged()\">\n <div class=\"grid w-full grid-cols-7\">\n @for (weekday of weekdayNames; track weekday) {\n <div class=\"text-muted-foreground flex h-7 items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n @for (week of calendarDays(); track $index) {\n <div class=\"grid w-full grid-cols-7\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'month') {\n <div class=\"grid h-full w-full grid-cols-3 grid-rows-4\" [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let monthDisabled = isStartMonthDisabled(i);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: currentMonthIndex()\"\n [disabled]=\"monthDisabled\"\n [class.opacity-30]=\"monthDisabled\"\n [class.cursor-not-allowed]=\"monthDisabled\"\n (click)=\"onMonthSelect(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 gap-0.5\"\n [class.grid-rows-4]=\"!isYearMode() && !isQuarterMode()\"\n [class.grid-rows-3]=\"isYearMode() || isQuarterMode()\"\n [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (year of isYearMode() || isQuarterMode() ? yearRangeSmall() : yearRange(); track year) {\n @let yearDisabled = isStartYearDisabled(year);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: currentYear()\"\n [disabled]=\"yearDisabled\"\n [class.opacity-30]=\"yearDisabled\"\n [class.cursor-not-allowed]=\"yearDisabled\"\n (click)=\"onYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (currentView() === 'quarter') {\n <div class=\"grid w-full grid-cols-2 gap-2\" [class.z-calendar-animate]=\"hasViewChanged()\">\n @for (quarter of quarterNames; track quarter; let i = $index) {\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zQuarterClasses: currentQuarterIndex()\"\n (click)=\"onQuarterClick(i)\">\n {{ quarter }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time Picker Side Panel (for single date with showTime) -->\n @if (!isRangeMode() && zShowTime() && currentView() === 'day') {\n <div\n class=\"border-border mt-3 flex w-full flex-col items-center border-t pt-3 sm:mt-0 sm:w-auto sm:border-t-0 sm:border-l sm:pt-0 sm:pl-3\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_time' | translate }}\n </div>\n <div class=\"flex flex-col items-center gap-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[140px] w-12 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[140px] w-12 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[140px] w-12 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex w-full gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Second Calendar (Range Mode Only) -->\n @if (isRangeMode()) {\n <!-- Divider -->\n <div class=\"border-border bg-border hidden self-stretch sm:mx-3 sm:block sm:w-px\"></div>\n <div class=\"border-border bg-border block h-px w-full sm:hidden\"></div>\n\n <div class=\"z-calendar-section flex flex-col gap-1\">\n <div class=\"flex w-full items-center justify-between space-x-1\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPreviousFast()\">\n <z-icon zType=\"lucideChevronsLeft\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zDisabled]=\"!canNavigateEndPrev()\"\n [zWave]=\"false\"\n (click)=\"navigateEndPrevious()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </button>\n\n <div class=\"flex flex-1 items-center justify-center gap-0.5\">\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"w-20 px-2!\"\n [zWave]=\"false\"\n (click)=\"setEndView('month')\">\n {{ endMonthName() }}\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"px-2!\"\n [zWave]=\"false\"\n (click)=\"setEndView('year')\">\n {{ endMonthYear() }}\n </button>\n </div>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNext()\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </button>\n\n <button\n type=\"button\"\n z-button\n zType=\"ghost\"\n zSize=\"sm\"\n class=\"size-8 p-0!\"\n [zWave]=\"false\"\n [zWave]=\"false\"\n (click)=\"navigateEndNextFast()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"16\" />\n </button>\n </div>\n\n <div class=\"z-calendar-views w-full\">\n @if (endView() === 'day') {\n <div class=\"flex h-full w-full flex-col gap-1\" [class.z-calendar-animate]=\"hasEndViewChanged()\">\n <div class=\"grid grid-cols-7 gap-px\">\n @for (weekday of weekdayNames; track weekday) {\n <div class=\"text-muted-foreground flex h-8 w-8 items-center justify-center text-xs font-medium\">\n {{ weekday }}\n </div>\n }\n </div>\n\n @for (week of calendarDaysEnd(); track $index) {\n <div class=\"grid grid-cols-7 gap-px\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"day | zDayClasses\"\n [disabled]=\"day.isDisabled\"\n (click)=\"onDayClick(day)\"\n (mouseenter)=\"onDayHover(day)\"\n (mouseleave)=\"onDayLeave()\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (endView() === 'month') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4\"\n [class.z-calendar-animate]=\"hasEndViewChanged()\">\n @for (month of monthNames; track month; let i = $index) {\n @let endMonthDisabled = isEndMonthDisabled(i);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"i | zMonthClasses: endMonth().getMonth()\"\n [disabled]=\"endMonthDisabled\"\n [class.opacity-30]=\"endMonthDisabled\"\n [class.cursor-not-allowed]=\"endMonthDisabled\"\n (click)=\"onEndMonthClick(i)\">\n {{ month }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (endView() === 'year') {\n <div\n class=\"grid h-full w-full grid-cols-3 grid-rows-4 gap-0.5\"\n [class.z-calendar-animate]=\"hasEndViewChanged()\">\n @for (year of endYearRange(); track year) {\n @let endYearDisabled = isEndYearDisabled(year);\n <div class=\"flex items-center justify-center\">\n <button\n type=\"button\"\n [class]=\"year | zYearClasses: endMonth().getFullYear()\"\n [disabled]=\"endYearDisabled\"\n [class.opacity-30]=\"endYearDisabled\"\n [class.cursor-not-allowed]=\"endYearDisabled\"\n (click)=\"onEndYearClick(year)\">\n {{ year }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Range Mode Time Picker Side Panel -->\n @if (isRangeMode() && zShowTime() && currentView() === 'day' && endView() === 'day') {\n <div\n class=\"border-border mt-3 flex w-full flex-row justify-center gap-3 border-t pt-3 sm:mt-0 sm:w-auto sm:border-t-0 sm:border-l sm:pt-0 sm:pl-3\">\n <!-- Start Time -->\n <div class=\"flex flex-col\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_start' | translate }}\n </div>\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-xs transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 flex-1 cursor-pointer items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-6 flex-1 cursor-pointer items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n\n <!-- End Time -->\n <div class=\"flex flex-col\">\n <div class=\"text-muted-foreground mb-2 text-center text-xs font-medium\">\n {{ 'i18n_z_ui_calendar_end' | translate }}\n </div>\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n @let hourDisabled = isEndHourDisabled(hour);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!hourDisabled\"\n [class.cursor-pointer]=\"!hourDisabled\"\n [class.bg-primary]=\"isHourEndSelected(hour)\"\n [class.text-primary-foreground]=\"isHourEndSelected(hour)\"\n [class.font-medium]=\"isHourEndSelected(hour)\"\n [class.opacity-30]=\"hourDisabled\"\n [class.cursor-not-allowed]=\"hourDisabled\"\n [disabled]=\"hourDisabled\"\n (click)=\"selectHourEnd(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n @let minuteDisabled = isEndMinuteDisabled(minute);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!minuteDisabled\"\n [class.cursor-pointer]=\"!minuteDisabled\"\n [class.bg-primary]=\"isMinuteEndSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteEndSelected(minute)\"\n [class.font-medium]=\"isMinuteEndSelected(minute)\"\n [class.opacity-30]=\"minuteDisabled\"\n [class.cursor-not-allowed]=\"minuteDisabled\"\n [disabled]=\"minuteDisabled\"\n (click)=\"selectMinuteEnd(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar\n class=\"z-time-column border-border h-[120px] w-10 rounded border sm:h-[235px]\"\n track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n @let secondDisabled = isEndSecondDisabled(second);\n <button\n type=\"button\"\n class=\"flex h-7 shrink-0 items-center justify-center text-xs transition-colors\"\n [class.hover:bg-muted]=\"!secondDisabled\"\n [class.cursor-pointer]=\"!secondDisabled\"\n [class.bg-primary]=\"isSecondEndSelected(second)\"\n [class.text-primary-foreground]=\"isSecondEndSelected(second)\"\n [class.font-medium]=\"isSecondEndSelected(second)\"\n [class.opacity-30]=\"secondDisabled\"\n [class.cursor-not-allowed]=\"secondDisabled\"\n [disabled]=\"secondDisabled\"\n (click)=\"selectSecondEnd(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex gap-1\">\n @let amDisabled = isEndPeriodDisabled('AM');\n <button\n type=\"button\"\n class=\"flex h-6 flex-1 items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.hover:bg-muted]=\"!amDisabled\"\n [class.cursor-pointer]=\"!amDisabled\"\n [class.bg-primary]=\"periodEnd() === 'AM'\"\n [class.text-primary-foreground]=\"periodEnd() === 'AM'\"\n [class.opacity-30]=\"amDisabled\"\n [class.cursor-not-allowed]=\"amDisabled\"\n [disabled]=\"amDisabled\"\n (click)=\"selectPeriodEnd('AM')\">\n AM\n </button>\n @let pmDisabled = isEndPeriodDisabled('PM');\n <button\n type=\"button\"\n class=\"flex h-6 flex-1 items-center justify-center rounded text-xs font-medium transition-colors\"\n [class.hover:bg-muted]=\"!pmDisabled\"\n [class.cursor-pointer]=\"!pmDisabled\"\n [class.bg-primary]=\"periodEnd() === 'PM'\"\n [class.text-primary-foreground]=\"periodEnd() === 'PM'\"\n [class.opacity-30]=\"pmDisabled\"\n [class.cursor-not-allowed]=\"pmDisabled\"\n [disabled]=\"pmDisabled\"\n (click)=\"selectPeriodEnd('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"flex flex-col items-center gap-2 py-2\">\n <div class=\"flex justify-center gap-1\">\n @if (zShowHour()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (hour of hourOptions(); track hour) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isHourSelected(hour)\"\n [class.text-primary-foreground]=\"isHourSelected(hour)\"\n [class.font-medium]=\"isHourSelected(hour)\"\n (click)=\"selectHour(hour)\">\n {{ hour | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowMinute()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (minute of minuteOptions; track minute) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isMinuteSelected(minute)\"\n [class.text-primary-foreground]=\"isMinuteSelected(minute)\"\n [class.font-medium]=\"isMinuteSelected(minute)\"\n (click)=\"selectMinute(minute)\">\n {{ minute | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n @if (zShowSecond()) {\n <ng-scrollbar class=\"z-time-column border-border h-[196px] w-14 rounded border\" track=\"vertical\">\n <div class=\"flex flex-col\">\n @for (second of secondOptions; track second) {\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 shrink-0 cursor-pointer items-center justify-center text-sm transition-colors\"\n [class.bg-primary]=\"isSecondSelected(second)\"\n [class.text-primary-foreground]=\"isSecondSelected(second)\"\n [class.font-medium]=\"isSecondSelected(second)\"\n (click)=\"selectSecond(second)\">\n {{ second | number: '2.0-0' }}\n </button>\n }\n </div>\n </ng-scrollbar>\n }\n </div>\n @if (zTimeFormat() === '12h') {\n <div class=\"flex w-full gap-1\">\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'AM'\"\n [class.text-primary-foreground]=\"period() === 'AM'\"\n (click)=\"selectPeriod('AM')\">\n AM\n </button>\n <button\n type=\"button\"\n class=\"hover:bg-muted flex h-7 flex-1 cursor-pointer items-center justify-center rounded text-sm font-medium transition-colors\"\n [class.bg-primary]=\"period() === 'PM'\"\n [class.text-primary-foreground]=\"period() === 'PM'\"\n (click)=\"selectPeriod('PM')\">\n PM\n </button>\n </div>\n }\n </div>\n }\n\n @if (!(zQuickSelect() && zMode() === 'range' && !showOkButton() && !showCancelButton())) {\n <div class=\"border-border flex items-center justify-between gap-2 border-t pt-2\">\n @if (!zQuickSelect() || zMode() !== 'range') {\n <button type=\"button\" z-button zType=\"secondary\" zSize=\"sm\" [zWave]=\"false\" (click)=\"onTodayClick()\">\n {{ todayButtonText() }}\n </button>\n } @else {\n <div></div>\n }\n\n @if (showOkButton() || showCancelButton()) {\n <div class=\"flex items-center gap-2\">\n @if (showCancelButton()) {\n <button type=\"button\" z-button zType=\"outline\" zSize=\"sm\" (click)=\"onCancelClick()\">\n {{ zCancelText() ?? ('i18n_z_ui_calendar_cancel' | translate) }}\n </button>\n }\n @if (showOkButton()) {\n <button type=\"button\" z-button zSize=\"sm\" [zDisabled]=\"!canApply()\" (click)=\"onOkClick()\">\n {{ zOkText() ?? ('i18n_z_ui_calendar_ok' | translate) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n", styles: [".z-calendar-calendar .z-calendar-section{width:280px;flex-shrink:0}.z-calendar-calendar .z-calendar-views{height:225px;width:100%;display:flex;align-items:center;justify-content:center;flex-direction:column}.z-calendar-calendar .z-calendar-views.z-calendar-views-quarter{height:auto}.z-calendar-calendar .z-calendar-animate{animation:z-calendar-view-enter .2s ease-out}.z-time-picker{display:flex;flex-direction:column;gap:.5rem;flex-shrink:0}.z-time-picker .z-time-columns{display:flex;gap:.25rem}.z-time-picker .z-time-column{width:42px;height:180px;overflow-y:auto;scroll-snap-type:y mandatory;scroll-behavior:smooth;scrollbar-width:thin}.z-time-picker .z-time-column::-webkit-scrollbar{width:4px}.z-time-picker .z-time-column::-webkit-scrollbar-track{background:transparent}.z-time-picker .z-time-column::-webkit-scrollbar-thumb{background-color:hsl(var(--border));border-radius:2px}.z-time-picker .z-time-item{height:32px;width:100%;display:flex;align-items:center;justify-content:center;font-size:.875rem;scroll-snap-align:center;border-radius:4px;cursor:pointer;transition:background-color .15s ease,color .15s ease}.z-time-picker .z-time-item:hover:not(.z-time-item-selected){background-color:hsl(var(--muted))}.z-time-picker .z-time-item.z-time-item-selected{background-color:hsl(var(--primary));color:hsl(var(--primary-foreground));font-weight:500}.z-time-picker .z-time-item:focus-visible{outline:2px solid hsl(var(--ring));outline-offset:-2px}.z-time-picker .z-time-period-buttons{display:flex;flex-direction:column;gap:.25rem;padding-top:8px}.z-time-picker .z-time-period-buttons button{height:28px;font-size:.75rem;border-radius:4px;transition:background-color .15s ease,color .15s ease}@keyframes z-calendar-view-enter{0%{opacity:0;transform:scale(.95) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"] }]
|
|
2878
2869
|
}], ctorParameters: () => [], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], zMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMode", required: false }] }], zSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSize", required: false }] }], zLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLabel", required: false }] }], zLabelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLabelClass", required: false }] }], zPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "zPlaceholder", required: false }] }], zRequired: [{ type: i0.Input, args: [{ isSignal: true, alias: "zRequired", required: false }] }], zDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDisabled", required: false }] }], zReadonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "zReadonly", required: false }] }], zShowTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowTime", required: false }] }], zTimeFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "zTimeFormat", required: false }] }], zShowHour: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowHour", required: false }] }], zShowMinute: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowMinute", required: false }] }], zShowSecond: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowSecond", required: false }] }], zQuickSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "zQuickSelect", required: false }] }], zAllowClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "zAllowClear", required: false }] }], zFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "zFormat", required: false }] }], zMinDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMinDate", required: false }] }], zMaxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMaxDate", required: false }] }], zValueType: [{ type: i0.Input, args: [{ isSignal: true, alias: "zValueType", required: false }] }], zValidators: [{ type: i0.Input, args: [{ isSignal: true, alias: "zValidators", required: false }] }], zLocale: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLocale", required: false }] }], zShowOk: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowOk", required: false }] }], zOkText: [{ type: i0.Input, args: [{ isSignal: true, alias: "zOkText", required: false }] }], zShowCancel: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowCancel", required: false }] }], zCancelText: [{ type: i0.Input, args: [{ isSignal: true, alias: "zCancelText", required: false }] }], zDisabledDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDisabledDate", required: false }] }], zScrollClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "zScrollClose", required: false }] }], zControl: [{ type: i0.Output, args: ["zControl"] }], zChange: [{ type: i0.Output, args: ["zChange"] }], triggerRef: [{ type: i0.ViewChild, args: ['triggerEl', { isSignal: true }] }], inputRef: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }] } });
|
|
2879
2870
|
|
|
2880
2871
|
/**
|