cloud-ide-element 1.1.158 → 1.1.159
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/cloud-ide-element.mjs +87 -188
- package/fesm2022/cloud-ide-element.mjs.map +1 -1
- package/index.d.ts +5 -2
- package/package.json +1 -1
|
@@ -722,10 +722,53 @@ class CideInputComponent {
|
|
|
722
722
|
this.onTouched();
|
|
723
723
|
this.onValidate();
|
|
724
724
|
}
|
|
725
|
+
/**
|
|
726
|
+
* @description Handle date input for masking DD/MM/YYYY
|
|
727
|
+
*/
|
|
728
|
+
onDateInput(event) {
|
|
729
|
+
if (this.type !== 'date') {
|
|
730
|
+
this.upDateValue(event);
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
const input = event.target;
|
|
734
|
+
let value = input.value;
|
|
735
|
+
// Remove non-numeric characters except slash
|
|
736
|
+
value = value.replace(/[^\d/]/g, '');
|
|
737
|
+
// Auto-insert slashes
|
|
738
|
+
if (value.length === 2 && !value.includes('/')) {
|
|
739
|
+
value += '/';
|
|
740
|
+
}
|
|
741
|
+
else if (value.length === 5 && (value.match(/\//g) || []).length === 1) {
|
|
742
|
+
value += '/';
|
|
743
|
+
}
|
|
744
|
+
// Enforce max length for DD/MM/YYYY
|
|
745
|
+
if (value.length > 10) {
|
|
746
|
+
value = value.substring(0, 10);
|
|
747
|
+
}
|
|
748
|
+
// Update input value if changed
|
|
749
|
+
if (input.value !== value) {
|
|
750
|
+
input.value = value;
|
|
751
|
+
}
|
|
752
|
+
// Process value for ngModel (convert to standard format if complete)
|
|
753
|
+
this.upDateValue({ target: { value } });
|
|
754
|
+
}
|
|
725
755
|
/** @description If control value need to be processed, like UPPERCASE */
|
|
726
756
|
processValue(value, type) {
|
|
727
757
|
value = this.autoCapitalizeByOption(value, type);
|
|
728
758
|
if (type === 'date' && typeof value === 'string' && value) {
|
|
759
|
+
// Handle DD/MM/YYYY format parsing
|
|
760
|
+
const ddmmyyyyRegex = /^(\d{2})\/(\d{2})\/(\d{4})$/;
|
|
761
|
+
const match = value.match(ddmmyyyyRegex);
|
|
762
|
+
if (match) {
|
|
763
|
+
const day = parseInt(match[1], 10);
|
|
764
|
+
const month = parseInt(match[2], 10);
|
|
765
|
+
const year = parseInt(match[3], 10);
|
|
766
|
+
// Basic validation
|
|
767
|
+
if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
|
|
768
|
+
// Create standard YYYY-MM-DD for storage/model
|
|
769
|
+
return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
729
772
|
// Ensure date is in YYYY-MM-DD format
|
|
730
773
|
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
|
|
731
774
|
if (dateRegex.test(value) && !isNaN(Date.parse(value))) {
|
|
@@ -1046,6 +1089,7 @@ class CideInputComponent {
|
|
|
1046
1089
|
else if (this.type === 'date') {
|
|
1047
1090
|
// Toggle custom date picker using portal service
|
|
1048
1091
|
this.showDatePicker = !this.showDatePicker;
|
|
1092
|
+
console.log('🔍 Toggling date picker. New state:', this.showDatePicker);
|
|
1049
1093
|
if (this.showDatePicker) {
|
|
1050
1094
|
this.initializeDatePicker();
|
|
1051
1095
|
this.createDatePickerUsingPortal();
|
|
@@ -1264,9 +1308,14 @@ class CideInputComponent {
|
|
|
1264
1308
|
this.showMonthYearSelector = false;
|
|
1265
1309
|
// Get input element - use idRandom as fallback if id is not provided
|
|
1266
1310
|
const elementId = this.id || this.idRandom;
|
|
1267
|
-
|
|
1268
|
-
if
|
|
1311
|
+
console.log('🔍 Creating date picker portal. Element ID:', elementId);
|
|
1312
|
+
// Check if element exists directly
|
|
1313
|
+
let inputElement = document.getElementById(elementId);
|
|
1314
|
+
if (!inputElement) {
|
|
1315
|
+
console.warn('⚠️ Element not found by ID. Attempting to find via ViewChild or fallback.');
|
|
1269
1316
|
return;
|
|
1317
|
+
}
|
|
1318
|
+
console.log('🔍 Input element found:', inputElement);
|
|
1270
1319
|
// Create template portal configuration
|
|
1271
1320
|
const portalConfig = {
|
|
1272
1321
|
triggerElement: inputElement,
|
|
@@ -1721,7 +1770,7 @@ class CideInputComponent {
|
|
|
1721
1770
|
useExisting: forwardRef(() => CideInputComponent),
|
|
1722
1771
|
},
|
|
1723
1772
|
CapitalizePipe
|
|
1724
|
-
], viewQueries: [{ propertyName: "datePickerTemplate", first: true, predicate: ["datePickerTemplate"], descendants: true, static: true }, { propertyName: "timePickerTemplate", first: true, predicate: ["timePickerTemplate"], descendants: true, static: true }, { propertyName: "dateTimePickerTemplate", first: true, predicate: ["dateTimePickerTemplate"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cide-input\">\n <!------------------------------------------TEXT | PASSWORD | DATE | URL------------------------------------------>\n @if (type === 'text' || type === 'number' || type === 'password' || type === 'email' || type === 'tel' || type ===\n 'date' || type === 'datetime-local' || type === 'url') {\n <div class=\"tw-w-full tw-relative\" [ngStyle]=\"{ width: width }\" [ngClass]=\"{\n 'cide-element-size-xxs': (size === '2xs'),\n 'cide-element-size-xs': (size === 'xs'),\n 'cide-element-size-sm': (size === 'sm'),\n 'cide-element-size-md': (size === 'md'),\n 'cide-element-size-lg': (size === 'lg'),\n 'cide-element-leading-icon': leadingIcon,\n 'cide-element-trailing-icon': trailingIconInternal,\n 'cide-element-clear-input': clearInput,\n 'cide-element-input-label-floating': (labelPlacement === 'floating'),\n 'cide-element-input-label-start': (labelDir === 'start'),\n 'cide-element-input-label-end': (labelDir === 'end'),\n 'cide-element-input-label-fixed': (labelPlacement === 'fixed'),\n 'cide-element-input-label-less': (!label || labelHide),\n 'cide-element-style-outline': (fill === 'outline'),\n 'cide-element-style-solid': (fill === 'solid'),\n 'cide-element-style-standard': (fill === 'standard'),\n 'cide-element-input-number': (type === 'number')\n }\">\n <!-- label -->\n @if (label && !labelHide) {\n <label [for]=\"id\" class=\"cide-input-label\">\n {{label}}\n @if (required) {\n <span class=\"tw-text-red-500 tw-ml-1\">*</span>\n }\n </label>\n }\n\n <!-- all one line elemets which dose not affect with label and error text -->\n <div class=\"cide-element-input-wrapper\">\n <!-- Leading Icon -->\n @if (leadingIcon) {\n <span class=\"cide-input-leading-icon-wrapper\">\n <span class=\"cide-input-leading-icon material-symbols-outlined tw-text-center\">{{leadingIcon}}</span>\n </span>\n }\n\n <!-- Trailing icon -->\n @if (trailingIconInternal) {\n <span class=\"tw-absolute cide-input-trailing-icon tw-select-none tw-right-0\">\n <span class=\"material-symbols-outlined tw-w-8 tw-text-center !tw-text-2xl\"\n [ngClass]=\"{'tw-cursor-pointer': isTrailingIconAllwedClick}\" [attr.tabindex]=\"false\"\n (click)=\"trailingIconClick()\" (keyup)=\"trailingIconClick()\">{{trailingIconInternal}}</span>\n </span>\n }\n\n <!-- Clear -->\n @if (clearInput && ngModel) {\n <button class=\"cide-input-clear\" (click)=\"ClearInputValue()\">\n <span class=\"cide-input-clear-icon material-symbols-outlined\">close</span>\n </button>\n }\n\n <!-- Date Input Wrapper -->\n @if (type === 'date') {\n <div class=\"cide-input-date-wrapper\" [ngClass]=\"{'cide-input-date-has-value': ngModel}\">\n <!-- Date Input (read-only to prevent manual input) -->\n <input [placeholder]=\"placeholder\" [id]=\"id || idRandom\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [value]=\"getDateDisplayValue()\" type=\"text\" (focus)=\"focusControl()\"\n (input)=\"upDateValue($event)\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none\" />\n\n <!-- Placeholder overlay for empty date -->\n @if (!ngModel && placeholder) {\n <div class=\"cide-input-date-overlay\">\n {{placeholder}}\n </div>\n }\n\n <!-- Date picker is now rendered as a portal appended to body -->\n </div>\n }\n\n <!-- Time Input Wrapper -->\n @if (isTimeType()) {\n <div class=\"cide-input-date-wrapper\" [ngClass]=\"{'cide-input-date-has-value': ngModel}\">\n <!-- Time Input (read-only to prevent manual input) -->\n <input [placeholder]=\"placeholder\" [id]=\"id || idRandom\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [value]=\"getTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\"\n (click)=\"trailingIconClick()\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none tw-cursor-pointer\" />\n\n <!-- Placeholder overlay for empty time -->\n @if (!ngModel && placeholder) {\n <div class=\"cide-input-date-overlay\">\n {{placeholder}}\n </div>\n }\n\n <!-- Time picker is now rendered as a portal appended to body -->\n </div>\n }\n\n <!-- DateTime Local Input -->\n @if (type === 'datetime-local') {\n <div class=\"cide-input-date-wrapper\" [ngClass]=\"{'cide-input-date-has-value': ngModel}\">\n <!-- DateTime Input (read-only to prevent manual input) -->\n <input [placeholder]=\"placeholder\" [id]=\"id || idRandom\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [value]=\"getDateTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\"\n (click)=\"trailingIconClick()\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none tw-cursor-pointer\" />\n\n <!-- Placeholder overlay for empty datetime -->\n @if (!ngModel && placeholder) {\n <div class=\"cide-input-date-overlay\">\n {{placeholder}}\n </div>\n }\n\n <!-- DateTime picker is now rendered as a portal appended to body -->\n </div>\n }\n\n <!-- Regular Input (non-date, non-time, non-datetime-local, non-url) -->\n @if (type !== 'date' && !isTimeType() && type !== 'datetime-local' && type !== 'url') {\n <input [placeholder]=\"placeholder\" [id]=\"id\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\"\n (focus)=\"focusControl()\" [autocomplete]=\"autocomplete\" [min]=\"min\" [max]=\"max\" [step]=\"step\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none\" />\n }\n\n <!-- URL Input -->\n @if (type === 'url') {\n <input [placeholder]=\"placeholder\" [id]=\"id\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\"\n (focus)=\"focusControl()\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none\" />\n }\n </div>\n <!-- error text / helper text -->\n @if ((errorText || helperText || !helperTextCollapse) && !hideHelperAndErrorText) {\n <span class=\"cide-input-help-error-text\">{{\n isValid\n ? helperText : (errorText ?\n (isTouched ? errorText : helperText)\n : helperText)}}\n </span>\n }\n </div>\n }\n\n <!-- Input with tralling icon -->\n <!-- <div class=\"tw-inline-block tw-h-12 tw-w-64\">\n <div class=\"tw-w-fullh-full tw-relative\">\n <label\n class=\"tw-absolute -tw-top-1/3 tw-mx-2 tw-bg-white tw-px-0.5 tw-py-0 tw-text-sm tw-leading-4 tw-text-gray-700\">Name</label>\n <span class=\"tw-absolute -tw-bottom-px tw-right-0 -tw-z-10 tw-text-gray-400\">\n <span class=\"material-symbols-outlined tw-w-8 tw-text-center !tw-text-2xl\"> person </span>\n </span>\n <input\n class=\"tw-m-0 tw-h-8 tw-w-full tw-overflow-hidden tw-rounded-md tw-border-2 tw-border-solid tw-border-gray-300 tw-bg-transparent tw-p-0 tw-pb-0.5 tw-pl-1 tw-pr-8 tw-text-sm tw-text-gray-600 tw-outline-none hover:tw-border-blue-400 focus:tw-border-blue-400 focus:tw-text-gray-950\"\n value=\"Ankush Bhure\" />\n </div>\n </div> -->\n\n <!-- Input with leading icon -->\n <!-- <div class=\"tw-inline-block tw-h-12 tw-w-64\">\n <div class=\"tw-w-fullh-full tw-relative\">\n <label\n class=\"tw-absolute -tw-top-1/3 tw-mx-2 tw-bg-white tw-px-0.5 tw-py-0 tw-text-sm tw-leading-4 tw-text-gray-700\">Name</label>\n <span class=\"tw-absolute -tw-bottom-px tw-left-0 -tw-z-10 tw-text-gray-400\">\n <span class=\"material-symbols-outlined tw-w-8 tw-text-center !tw-text-2xl\"> person </span>\n </span>\n <input\n class=\"tw-m-0 tw-h-8 tw-w-full tw-overflow-hidden tw-rounded-md tw-border-2 tw-border-solid tw-border-gray-300 tw-bg-transparent tw-p-0 tw-pb-0.5 tw-pl-8 tw-pr-1 tw-text-sm tw-text-gray-600 tw-outline-none hover:tw-border-blue-400 focus:tw-border-blue-400 focus:tw-text-gray-950\"\n value=\"Ankush Bhure\" />\n </div>\n </div> -->\n\n <!------------------------------------------CHECKBOX------------------------------------------>\n @if (type === 'checkbox') {\n <div class=\"tw-flex\">\n <div class=\"cide-checkbox tw-relative\">\n <input [checked]=\"ngModel\" [value]=\"ngModel\" [id]=\"idRandom\" [type]=\"type\" [disabled]=\"disabled\"\n class=\"tw-absolute tw-left-0 tw-invisible\" (click)=\"updateValueCheckBox(!ngModel); focusControl()\"\n [autocomplete]=\"autocomplete\" />\n <label class=\"cide-checkbox-label tw-cursor-pointer\" [for]=\"idRandom\">\n <span class=\"tw-border-2 tw-border-solid tw-relative tw-rounded-md\">\n <svg width=\"12px\" height=\"10px\" class=\"tw-absolute\">\n <use xlink:href=\"#sdfwiorfklasfjjalfjwerwr\"></use>\n </svg>\n </span>\n @if (!labelHide) {\n <span class=\"tw-text-sm tw-pl-2 tw-leading-[18px] tw-select-none tw-cursor-pointer\">{{label}}</span>\n }\n </label>\n <svg class=\"tw-absolute tw-h-0 tw-w-0 tw-select-none tw-pointer-events-none\">\n <!-- Element hidden and its xpath is used to display inside SVG -->\n <symbol id=\"sdfwiorfklasfjjalfjwerwr\" viewbox=\"0 0 12 10\">\n <polyline points=\"1.5 6 4.5 9 10.5 1\"></polyline>\n </symbol>\n </svg>\n </div>\n </div>\n }\n\n <!-------------------------------------------SELECT------------------------------------------->\n @if (type === 'select') {\n <div>sas\n <div class=\"tw-relative\">\n <div class=\"tw-absolute\">\n @for (item of option; track $index) {\n <div class=\"tw-w-full\">\n {{item}}\n </div>\n }\n </div>\n </div>\n </div>\n }\n</div>\n\n<!-- Date Picker Template -->\n<ng-template #datePickerTemplate>\n <div class=\"tw-bg-white tw-border tw-border-gray-300 tw-rounded-lg tw-shadow-lg tw-p-4\">\n <!-- Date Picker Header -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-4\">\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_left</span>\n </button>\n\n <button type=\"button\"\n class=\"tw-text-sm tw-font-medium tw-text-gray-800 hover:tw-bg-gray-100 tw-px-3 tw-py-1 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n {{ monthNames[currentMonth] }} {{ currentYear }}\n </button>\n\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_right</span>\n </button>\n </div>\n\n <!-- Month/Year Selector -->\n @if (showMonthYearSelector) {\n <div class=\"tw-mb-4\">\n <!-- Year Navigation -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-3\">\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_left</span>\n </button>\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-800\">{{ currentYear }}</span>\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_right</span>\n </button>\n </div>\n\n <!-- Month Grid -->\n <div class=\"tw-grid tw-grid-cols-3 tw-gap-2 tw-mb-3\">\n @for (monthName of shortMonthNames; track $index) {\n <button type=\"button\" class=\"tw-px-3 tw-py-2 tw-text-sm tw-rounded-md tw-transition-colors tw-text-center\"\n [class.tw-bg-blue-500]=\"$index === currentMonth\" [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\" [class.hover:tw-bg-blue-50]=\"$index !== currentMonth\"\n (click)=\"selectMonth($index)\">\n {{ monthName }}\n </button>\n }\n </div>\n\n <!-- Back to Calendar Button -->\n <div class=\"tw-text-center\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-sm tw-text-blue-600 hover:tw-bg-blue-50 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n Back to Calendar\n </button>\n </div>\n </div>\n } @else {\n <!-- Calendar View -->\n <div>\n <!-- Days of Week Header -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1 tw-mb-2\">\n @for (dayName of ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']; track dayName) {\n <div class=\"tw-text-center tw-text-xs tw-font-medium tw-text-gray-500 tw-py-2\">\n {{ dayName }}\n </div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1\">\n @for (dayInfo of calendarDays; track dayInfo.date.getTime()) {\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-text-sm tw-rounded-md tw-transition-colors tw-flex tw-items-center tw-justify-center\"\n [class.tw-text-gray-400]=\"!dayInfo.isCurrentMonth\" [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\" [class.tw-text-white]=\"dayInfo.isSelected\"\n [class.tw-bg-blue-100]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.tw-text-blue-800]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.hover:tw-bg-blue-50]=\"dayInfo.isCurrentMonth && !dayInfo.isSelected\"\n (click)=\"showDateTimePicker ? selectDateTimeDate(dayInfo) : selectDate(dayInfo)\">\n {{ dayInfo.day }}\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Date Picker Footer -->\n <div class=\"tw-flex tw-justify-between tw-mt-3 tw-pt-2 tw-border-t tw-border-gray-200\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-text-gray-600 hover:tw-bg-gray-100 tw-rounded tw-transition-colors\"\n (click)=\"closeDatePicker()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-bg-blue-600 tw-text-white hover:tw-bg-blue-700 tw-rounded tw-transition-colors\"\n (click)=\"closeDatePicker()\">\n Done\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Time Picker Template -->\n<ng-template #timePickerTemplate>\n <div class=\"tw-bg-white tw-border tw-border-gray-300 tw-rounded-lg tw-shadow-lg tw-p-4 tw-w-72\">\n <!-- Time Picker Header -->\n <div class=\"tw-text-center tw-mb-3\">\n <h3 class=\"tw-text-base tw-font-semibold tw-text-gray-800 tw-m-0\">Time</h3>\n </div>\n\n <!-- Time Spinners Container -->\n <div class=\"tw-flex tw-items-center tw-justify-center tw-gap-3 tw-mb-4\">\n <!-- Hours -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'up')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_less</span>\n </button>\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-12 tw-text-center\">\n {{ timeHours }}\n </div>\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'down')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-2\">hour</span>\n </div>\n\n <!-- Colon Separator -->\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-mb-4\">:</div>\n\n <!-- Minutes -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'up')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_less</span>\n </button>\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-12 tw-text-center\">\n {{ timeMinutes.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'down')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-2\">min</span>\n </div>\n\n <!-- Colon Separator -->\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-mb-4\">:</div>\n\n <!-- Seconds -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'up')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_less</span>\n </button>\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-12 tw-text-center\">\n {{ timeSeconds.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'down')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-2\">sec</span>\n </div>\n </div>\n\n <!-- AM/PM Toggle -->\n <div class=\"tw-flex tw-justify-center tw-mb-3\">\n <div class=\"tw-inline-flex tw-rounded-md tw-bg-gray-100 tw-p-0.5\">\n <button type=\"button\"\n class=\"tw-px-4 tw-py-1.5 tw-text-sm tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'AM'\" [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow]=\"timeFormat === 'AM'\" [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button type=\"button\"\n class=\"tw-px-4 tw-py-1.5 tw-text-sm tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'PM'\" [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow]=\"timeFormat === 'PM'\" [class.tw-text-gray-600]=\"timeFormat !== 'PM'\"\n (click)=\"timeFormat = 'PM'\">\n PM\n </button>\n </div>\n </div>\n\n <!-- Current Time Display -->\n <div class=\"tw-text-center tw-mb-3\">\n <span class=\"tw-text-sm tw-text-gray-600\">\n {{ timeHours }}:{{ timeMinutes.toString().padStart(2, '0') }}:{{ timeSeconds.toString().padStart(2, '0') }} {{\n timeFormat }}\n </span>\n </div>\n\n <!-- Time Picker Footer -->\n <div class=\"tw-flex tw-gap-2\">\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-3 tw-py-1.5 tw-text-xs tw-font-medium tw-text-gray-700 tw-bg-white tw-border tw-border-gray-300 hover:tw-bg-gray-50 tw-rounded tw-transition-colors\"\n (click)=\"showDateTimePicker ? closeDateTimePicker() : closeTimePicker()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-3 tw-py-1.5 tw-text-xs tw-font-medium tw-text-white tw-bg-blue-600 hover:tw-bg-blue-700 tw-rounded tw-transition-colors tw-border-0\"\n (click)=\"showDateTimePicker ? applyDateTime() : applyTime()\">\n OK\n </button>\n </div>\n\n </div>\n</ng-template>\n\n<!-- DateTime Picker Template (Combined Date + Time) -->\n<ng-template #dateTimePickerTemplate>\n <div class=\"tw-bg-white tw-border tw-border-gray-300 tw-rounded-lg tw-shadow-lg tw-p-4\">\n <!-- DateTime Picker Header -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-4\">\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_left</span>\n </button>\n\n <button type=\"button\"\n class=\"tw-text-sm tw-font-medium tw-text-gray-800 hover:tw-bg-gray-100 tw-px-3 tw-py-1 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n {{ monthNames[currentMonth] }} {{ currentYear }}\n </button>\n\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_right</span>\n </button>\n </div>\n\n <div class=\"tw-grid tw-grid-cols-2 tw-gap-4\">\n <!-- Left Side: Calendar -->\n <div>\n <!-- Month/Year Selector -->\n @if (showMonthYearSelector) {\n <div class=\"tw-mb-4\">\n <!-- Year Navigation -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-3\">\n <button type=\"button\"\n class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_left</span>\n </button>\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-800\">{{ currentYear }}</span>\n <button type=\"button\"\n class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_right</span>\n </button>\n </div>\n\n <!-- Month Grid -->\n <div class=\"tw-grid tw-grid-cols-3 tw-gap-2 tw-mb-3\">\n @for (monthName of shortMonthNames; track $index) {\n <button type=\"button\" class=\"tw-px-2 tw-py-1.5 tw-text-xs tw-rounded-md tw-transition-colors tw-text-center\"\n [class.tw-bg-blue-500]=\"$index === currentMonth\" [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\" [class.hover:tw-bg-blue-50]=\"$index !== currentMonth\"\n (click)=\"selectMonth($index)\">\n {{ monthName }}\n </button>\n }\n </div>\n\n <!-- Back to Calendar Button -->\n <div class=\"tw-text-center\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-text-blue-600 hover:tw-bg-blue-50 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n Back to Calendar\n </button>\n </div>\n </div>\n } @else {\n <!-- Calendar View -->\n <div>\n <!-- Days of Week Header -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1 tw-mb-2\">\n @for (dayName of ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']; track dayName) {\n <div class=\"tw-text-center tw-text-xs tw-font-medium tw-text-gray-500 tw-py-1\">\n {{ dayName }}\n </div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1\">\n @for (dayInfo of calendarDays; track dayInfo.date.getTime()) {\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-text-xs tw-rounded-md tw-transition-colors tw-flex tw-items-center tw-justify-center\"\n [class.tw-text-gray-400]=\"!dayInfo.isCurrentMonth\" [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\" [class.tw-text-white]=\"dayInfo.isSelected\"\n [class.tw-bg-blue-100]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.tw-text-blue-800]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.hover:tw-bg-blue-50]=\"dayInfo.isCurrentMonth && !dayInfo.isSelected\"\n (click)=\"selectDateTimeDate(dayInfo)\">\n {{ dayInfo.day }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Right Side: Time Picker -->\n <div class=\"tw-border-l tw-border-gray-200 tw-pl-4\">\n <div class=\"tw-text-center tw-mb-2\">\n <h4 class=\"tw-text-sm tw-font-semibold tw-text-gray-800 tw-m-0\">Time</h4>\n </div>\n\n <!-- Time Spinners -->\n <div class=\"tw-flex tw-items-center tw-justify-center tw-gap-2 tw-mb-3\">\n <!-- Hours -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'up')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_less</span>\n </button>\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-10 tw-text-center\">\n {{ timeHours }}\n </div>\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'down')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">hour</span>\n </div>\n\n <!-- Colon -->\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-mb-3\">:</div>\n\n <!-- Minutes -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'up')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_less</span>\n </button>\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-10 tw-text-center\">\n {{ timeMinutes.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'down')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">min</span>\n </div>\n\n <!-- Colon -->\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-mb-3\">:</div>\n\n <!-- Seconds -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'up')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_less</span>\n </button>\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-10 tw-text-center\">\n {{ timeSeconds.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'down')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">sec</span>\n </div>\n </div>\n\n <!-- AM/PM Toggle -->\n <div class=\"tw-flex tw-justify-center tw-mb-2\">\n <div class=\"tw-inline-flex tw-rounded-md tw-bg-gray-100 tw-p-0.5\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'AM'\" [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'AM'\" [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'PM'\" [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'PM'\" [class.tw-text-gray-600]=\"timeFormat !== 'PM'\"\n (click)=\"timeFormat = 'PM'\">\n PM\n </button>\n </div>\n </div>\n\n <!-- Current Time Display -->\n <div class=\"tw-text-center tw-text-xs tw-text-gray-600\">\n {{ timeHours }}:{{ timeMinutes.toString().padStart(2, '0') }}:{{ timeSeconds.toString().padStart(2, '0') }} {{\n timeFormat }}\n </div>\n </div>\n </div>\n\n <!-- DateTime Picker Footer -->\n <div class=\"tw-flex tw-gap-2 tw-mt-3 tw-pt-2 tw-border-t tw-border-gray-200\">\n <button type=\"button\"\n class=\"tw-px-2 tw-py-1 tw-text-xs tw-font-medium tw-text-blue-600 tw-bg-white tw-border tw-border-blue-300 hover:tw-bg-blue-50 tw-rounded tw-transition-colors\"\n (click)=\"setCurrentDateTime()\">\n Now\n </button>\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-2 tw-py-1 tw-text-xs tw-font-medium tw-text-gray-700 tw-bg-white tw-border tw-border-gray-300 hover:tw-bg-gray-50 tw-rounded tw-transition-colors\"\n (click)=\"closeDateTimePicker()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-2 tw-py-1 tw-text-xs tw-font-medium tw-text-white tw-bg-blue-600 hover:tw-bg-blue-700 tw-rounded tw-transition-colors tw-border-0\"\n (click)=\"applyDateTime()\">\n OK\n </button>\n </div>\n </div>\n</ng-template>", styles: ["input[type=date]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}input[type=date]::-webkit-inner-spin-button,input[type=date]::-webkit-outer-spin-button{display:none;-webkit-appearance:none}input[type=date]{-moz-appearance:textfield}input[type=date]::-webkit-datetime-edit,input[type=date]::-webkit-datetime-edit-fields-wrapper{padding:0;background:transparent}input[type=date]::-webkit-datetime-edit-text{color:transparent;background:transparent}input[type=date]{background:transparent!important;border:none!important;outline:none!important}.cide-input-date-wrapper{position:relative;width:100%}.cide-input-date-overlay{position:absolute;inset:0;pointer-events:none;display:flex;align-items:center;padding-left:.25rem;color:var(--tw-gray-500)}.cide-input-date-has-value .cide-input-date-overlay{display:none}.cide-date-picker-panel{min-width:320px;max-width:400px;z-index:1000}.cide-date-picker-panel{animation:datePickerFadeIn .2s ease-out}@keyframes datePickerFadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.cide-date-picker-panel button:disabled{opacity:.5;cursor:not-allowed}.cide-date-picker-panel button:focus{outline:2px solid rgb(59,130,246);outline-offset:2px}.cide-date-picker-panel button:hover:not(:disabled){transform:scale(1.05);transition:transform .1s ease-in-out}.cide-date-picker-panel button.today:not(.selected){box-shadow:0 0 0 1px #3b82f6}.cide-date-picker-panel button.selected{box-shadow:0 2px 4px #3b82f64d;font-weight:600}.cide-date-picker-panel .nav-button{transition:all .2s ease-in-out}.cide-date-picker-panel .nav-button:hover{background-color:var(--tw-gray-200);transform:scale(1.1)}.cide-date-picker-panel h3{-webkit-user-select:none;user-select:none;transition:color .2s ease-in-out}.cide-date-picker-panel .days-header{border-bottom:1px solid var(--tw-gray-200);margin-bottom:.5rem;padding-bottom:.5rem}.cide-date-picker-portal{box-shadow:0 10px 25px -5px #0000001a,0 10px 10px -5px #0000000a;border-radius:.5rem;background:var(--cide-ele-bg-primary, #ffffff);border:1px solid var(--cide-ele-border-primary, #e5e7eb);z-index:9999;transition:opacity .2s ease-in-out,transform .2s ease-in-out;color:var(--cide-ele-text-primary, #1f2937)}.cide-date-picker-portal{animation:portalFadeIn .2s ease-out}@keyframes portalFadeIn{0%{opacity:0;transform:translateY(-8px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.cide-date-picker-portal.cide-portal{position:fixed!important;z-index:9999!important}input[type=time]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}input[type=time]::-webkit-inner-spin-button,input[type=time]::-webkit-outer-spin-button{display:none;-webkit-appearance:none}input[type=time]{-moz-appearance:textfield}input[type=time]::-webkit-datetime-edit,input[type=time]::-webkit-datetime-edit-fields-wrapper{padding:0;background:transparent}input[type=time]::-webkit-datetime-edit-text{color:transparent;background:transparent}input[type=time]{background:transparent!important;border:none!important;outline:none!important}.cide-time-picker-portal{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;border-radius:1rem;background:var(--cide-theme-light-color);border:1px solid var(--tw-gray-200);z-index:9999;transition:opacity .2s ease-in-out,transform .2s ease-in-out;animation:portalFadeIn .2s ease-out;color:var(--cide-theme-text-color)}.cide-time-picker-portal.cide-portal{position:fixed!important;z-index:9999!important}input[type=datetime-local]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}input[type=datetime-local]::-webkit-inner-spin-button,input[type=datetime-local]::-webkit-outer-spin-button{display:none;-webkit-appearance:none}input[type=datetime-local]{-moz-appearance:textfield}input[type=datetime-local]::-webkit-datetime-edit,input[type=datetime-local]::-webkit-datetime-edit-fields-wrapper{padding:0;background:transparent}input[type=datetime-local]::-webkit-datetime-edit-text{color:transparent;background:transparent}input[type=datetime-local]{background:transparent!important;border:none!important;outline:none!important}.cide-datetime-picker-portal{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;border-radius:1rem;background:var(--cide-theme-light-color);border:1px solid var(--tw-gray-200);z-index:9999;transition:opacity .2s ease-in-out,transform .2s ease-in-out;animation:portalFadeIn .2s ease-out;color:var(--cide-theme-text-color)}.cide-datetime-picker-portal.cide-portal{position:fixed!important;z-index:9999!important}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
1773
|
+
], viewQueries: [{ propertyName: "datePickerTemplate", first: true, predicate: ["datePickerTemplate"], descendants: true, static: true }, { propertyName: "timePickerTemplate", first: true, predicate: ["timePickerTemplate"], descendants: true, static: true }, { propertyName: "dateTimePickerTemplate", first: true, predicate: ["dateTimePickerTemplate"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cide-input\">\n <!------------------------------------------TEXT | PASSWORD | DATE | URL------------------------------------------>\n @if (type === 'text' || type === 'number' || type === 'password' || type === 'email' || type === 'tel' || type ===\n 'date' || type === 'datetime-local' || type === 'url') {\n <div class=\"tw-w-full tw-relative\" [ngStyle]=\"{ width: width }\" [ngClass]=\"{\n 'cide-element-size-xxs': (size === '2xs'),\n 'cide-element-size-xs': (size === 'xs'),\n 'cide-element-size-sm': (size === 'sm'),\n 'cide-element-size-md': (size === 'md'),\n 'cide-element-size-lg': (size === 'lg'),\n 'cide-element-leading-icon': leadingIcon,\n 'cide-element-trailing-icon': trailingIconInternal,\n 'cide-element-clear-input': clearInput,\n 'cide-element-input-label-floating': (labelPlacement === 'floating'),\n 'cide-element-input-label-start': (labelDir === 'start'),\n 'cide-element-input-label-end': (labelDir === 'end'),\n 'cide-element-input-label-fixed': (labelPlacement === 'fixed'),\n 'cide-element-input-label-less': (!label || labelHide),\n 'cide-element-style-outline': (fill === 'outline'),\n 'cide-element-style-solid': (fill === 'solid'),\n 'cide-element-style-standard': (fill === 'standard'),\n 'cide-element-input-number': (type === 'number')\n }\">\n <!-- label -->\n @if (label && !labelHide) {\n <label [for]=\"id\" class=\"cide-input-label\">\n {{label}}\n @if (required) {\n <span class=\"tw-text-red-500 tw-ml-1\">*</span>\n }\n </label>\n }\n\n <!-- all one line elemets which dose not affect with label and error text -->\n <div class=\"cide-element-input-wrapper\">\n <!-- Leading Icon -->\n @if (leadingIcon) {\n <span class=\"cide-input-leading-icon-wrapper\">\n <span class=\"cide-input-leading-icon material-symbols-outlined tw-text-center\">{{leadingIcon}}</span>\n </span>\n }\n\n <!-- Trailing icon -->\n @if (trailingIconInternal) {\n <span class=\"tw-absolute cide-input-trailing-icon tw-select-none tw-right-0\">\n <span class=\"material-symbols-outlined tw-w-8 tw-text-center !tw-text-2xl\"\n [ngClass]=\"{'tw-cursor-pointer': isTrailingIconAllwedClick}\" [attr.tabindex]=\"false\"\n (click)=\"trailingIconClick()\" (keyup)=\"trailingIconClick()\">{{trailingIconInternal}}</span>\n </span>\n }\n\n <!-- Clear -->\n @if (clearInput && ngModel) {\n <button class=\"cide-input-clear\" (click)=\"ClearInputValue()\">\n <span class=\"cide-input-clear-icon material-symbols-outlined\">close</span>\n </button>\n }\n\n <!-- Date Input Wrapper -->\n @if (type === 'date') {\n <div class=\"cide-input-date-wrapper\" [ngClass]=\"{'cide-input-date-has-value': ngModel}\">\n <!-- Date Input (read-only to prevent manual input) -->\n <input [placeholder]=\"placeholder || 'DD/MM/YYYY'\" [id]=\"id || idRandom\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [value]=\"getDateDisplayValue()\" type=\"text\" (focus)=\"focusControl()\"\n (input)=\"onDateInput($event)\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none\" />\n\n <!-- Placeholder overlay for empty date -->\n @if (!ngModel && placeholder) {\n <div class=\"cide-input-date-overlay\">\n {{placeholder}}\n </div>\n }\n\n <!-- Date picker is now rendered as a portal appended to body -->\n </div>\n }\n\n <!-- Time Input Wrapper -->\n @if (isTimeType()) {\n <div class=\"cide-input-date-wrapper\" [ngClass]=\"{'cide-input-date-has-value': ngModel}\">\n <!-- Time Input (read-only to prevent manual input) -->\n <input [placeholder]=\"placeholder\" [id]=\"id || idRandom\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [value]=\"getTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\"\n (click)=\"trailingIconClick()\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none tw-cursor-pointer\" />\n\n <!-- Placeholder overlay for empty time -->\n @if (!ngModel && placeholder) {\n <div class=\"cide-input-date-overlay\">\n {{placeholder}}\n </div>\n }\n\n <!-- Time picker is now rendered as a portal appended to body -->\n </div>\n }\n\n <!-- DateTime Local Input -->\n @if (type === 'datetime-local') {\n <div class=\"cide-input-date-wrapper\" [ngClass]=\"{'cide-input-date-has-value': ngModel}\">\n <!-- DateTime Input (read-only to prevent manual input) -->\n <input [placeholder]=\"placeholder\" [id]=\"id || idRandom\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [value]=\"getDateTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\"\n (click)=\"trailingIconClick()\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none tw-cursor-pointer\" />\n\n <!-- Placeholder overlay for empty datetime -->\n @if (!ngModel && placeholder) {\n <div class=\"cide-input-date-overlay\">\n {{placeholder}}\n </div>\n }\n\n <!-- DateTime picker is now rendered as a portal appended to body -->\n </div>\n }\n\n <!-- Regular Input (non-date, non-time, non-datetime-local, non-url) -->\n @if (type !== 'date' && !isTimeType() && type !== 'datetime-local' && type !== 'url') {\n <input [placeholder]=\"placeholder\" [id]=\"id\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\"\n (focus)=\"focusControl()\" [autocomplete]=\"autocomplete\" [min]=\"min\" [max]=\"max\" [step]=\"step\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none\" />\n }\n\n <!-- URL Input -->\n @if (type === 'url') {\n <input [placeholder]=\"placeholder\" [id]=\"id\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\"\n (focus)=\"focusControl()\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none\" />\n }\n </div>\n <!-- error text / helper text -->\n @if ((errorText || helperText || !helperTextCollapse) && !hideHelperAndErrorText) {\n <span class=\"cide-input-help-error-text\">{{\n isValid\n ? helperText : (errorText ?\n (isTouched ? errorText : helperText)\n : helperText)}}\n </span>\n }\n </div>\n }\n\n <!-- Input with tralling icon -->\n <!-- <div class=\"tw-inline-block tw-h-12 tw-w-64\">\n <div class=\"tw-w-fullh-full tw-relative\">\n <label\n class=\"tw-absolute -tw-top-1/3 tw-mx-2 tw-bg-white tw-px-0.5 tw-py-0 tw-text-sm tw-leading-4 tw-text-gray-700\">Name</label>\n <span class=\"tw-absolute -tw-bottom-px tw-right-0 -tw-z-10 tw-text-gray-400\">\n <span class=\"material-symbols-outlined tw-w-8 tw-text-center !tw-text-2xl\"> person </span>\n </span>\n <input\n class=\"tw-m-0 tw-h-8 tw-w-full tw-overflow-hidden tw-rounded-md tw-border-2 tw-border-solid tw-border-gray-300 tw-bg-transparent tw-p-0 tw-pb-0.5 tw-pl-1 tw-pr-8 tw-text-sm tw-text-gray-600 tw-outline-none hover:tw-border-blue-400 focus:tw-border-blue-400 focus:tw-text-gray-950\"\n value=\"Ankush Bhure\" />\n </div>\n </div> -->\n\n <!-- Input with leading icon -->\n <!-- <div class=\"tw-inline-block tw-h-12 tw-w-64\">\n <div class=\"tw-w-fullh-full tw-relative\">\n <label\n class=\"tw-absolute -tw-top-1/3 tw-mx-2 tw-bg-white tw-px-0.5 tw-py-0 tw-text-sm tw-leading-4 tw-text-gray-700\">Name</label>\n <span class=\"tw-absolute -tw-bottom-px tw-left-0 -tw-z-10 tw-text-gray-400\">\n <span class=\"material-symbols-outlined tw-w-8 tw-text-center !tw-text-2xl\"> person </span>\n </span>\n <input\n class=\"tw-m-0 tw-h-8 tw-w-full tw-overflow-hidden tw-rounded-md tw-border-2 tw-border-solid tw-border-gray-300 tw-bg-transparent tw-p-0 tw-pb-0.5 tw-pl-8 tw-pr-1 tw-text-sm tw-text-gray-600 tw-outline-none hover:tw-border-blue-400 focus:tw-border-blue-400 focus:tw-text-gray-950\"\n value=\"Ankush Bhure\" />\n </div>\n </div> -->\n\n <!------------------------------------------CHECKBOX------------------------------------------>\n @if (type === 'checkbox') {\n <div class=\"tw-flex\">\n <div class=\"cide-checkbox tw-relative\">\n <input [checked]=\"ngModel\" [value]=\"ngModel\" [id]=\"idRandom\" [type]=\"type\" [disabled]=\"disabled\"\n class=\"tw-absolute tw-left-0 tw-invisible\" (click)=\"updateValueCheckBox(!ngModel); focusControl()\"\n [autocomplete]=\"autocomplete\" />\n <label class=\"cide-checkbox-label tw-cursor-pointer\" [for]=\"idRandom\">\n <span class=\"tw-border-2 tw-border-solid tw-relative tw-rounded-md\">\n <svg width=\"12px\" height=\"10px\" class=\"tw-absolute\">\n <use xlink:href=\"#sdfwiorfklasfjjalfjwerwr\"></use>\n </svg>\n </span>\n @if (!labelHide) {\n <span class=\"tw-text-sm tw-pl-2 tw-leading-[18px] tw-select-none tw-cursor-pointer\">{{label}}</span>\n }\n </label>\n <svg class=\"tw-absolute tw-h-0 tw-w-0 tw-select-none tw-pointer-events-none\">\n <!-- Element hidden and its xpath is used to display inside SVG -->\n <symbol id=\"sdfwiorfklasfjjalfjwerwr\" viewbox=\"0 0 12 10\">\n <polyline points=\"1.5 6 4.5 9 10.5 1\"></polyline>\n </symbol>\n </svg>\n </div>\n </div>\n }\n\n <!-------------------------------------------SELECT------------------------------------------->\n @if (type === 'select') {\n <div>sas\n <div class=\"tw-relative\">\n <div class=\"tw-absolute\">\n @for (item of option; track $index) {\n <div class=\"tw-w-full\">\n {{item}}\n </div>\n }\n </div>\n </div>\n </div>\n }\n</div>\n\n<!-- Date Picker Template -->\n<ng-template #datePickerTemplate>\n <div class=\"tw-bg-white tw-border tw-border-gray-300 tw-rounded-lg tw-shadow-lg tw-p-4\">\n <!-- Date Picker Header -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-4\">\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_left</span>\n </button>\n\n <button type=\"button\"\n class=\"tw-text-sm tw-font-medium tw-text-gray-800 hover:tw-bg-gray-100 tw-px-3 tw-py-1 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n {{ monthNames[currentMonth] }} {{ currentYear }}\n </button>\n\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_right</span>\n </button>\n </div>\n\n <!-- Month/Year Selector -->\n @if (showMonthYearSelector) {\n <div class=\"tw-mb-4\">\n <!-- Year Navigation -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-3\">\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_left</span>\n </button>\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-800\">{{ currentYear }}</span>\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_right</span>\n </button>\n </div>\n\n <!-- Month Grid -->\n <div class=\"tw-grid tw-grid-cols-3 tw-gap-2 tw-mb-3\">\n @for (monthName of shortMonthNames; track $index) {\n <button type=\"button\" class=\"tw-px-3 tw-py-2 tw-text-sm tw-rounded-md tw-transition-colors tw-text-center\"\n [class.tw-bg-blue-500]=\"$index === currentMonth\" [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\" [class.hover:tw-bg-blue-50]=\"$index !== currentMonth\"\n (click)=\"selectMonth($index)\">\n {{ monthName }}\n </button>\n }\n </div>\n\n <!-- Back to Calendar Button -->\n <div class=\"tw-text-center\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-sm tw-text-blue-600 hover:tw-bg-blue-50 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n Back to Calendar\n </button>\n </div>\n </div>\n } @else {\n <!-- Calendar View -->\n <div>\n <!-- Days of Week Header -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1 tw-mb-2\">\n @for (dayName of ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']; track dayName) {\n <div class=\"tw-text-center tw-text-xs tw-font-medium tw-text-gray-500 tw-py-2\">\n {{ dayName }}\n </div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1\">\n @for (dayInfo of calendarDays; track dayInfo.date.getTime()) {\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-text-sm tw-rounded-md tw-transition-colors tw-flex tw-items-center tw-justify-center\"\n [class.tw-text-gray-400]=\"!dayInfo.isCurrentMonth\" [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\" [class.tw-text-white]=\"dayInfo.isSelected\"\n [class.tw-bg-blue-100]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.tw-text-blue-800]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.hover:tw-bg-blue-50]=\"dayInfo.isCurrentMonth && !dayInfo.isSelected\"\n (click)=\"showDateTimePicker ? selectDateTimeDate(dayInfo) : selectDate(dayInfo)\">\n {{ dayInfo.day }}\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Date Picker Footer -->\n <div class=\"tw-flex tw-justify-between tw-mt-3 tw-pt-2 tw-border-t tw-border-gray-200\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-text-gray-600 hover:tw-bg-gray-100 tw-rounded tw-transition-colors\"\n (click)=\"closeDatePicker()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-bg-blue-600 tw-text-white hover:tw-bg-blue-700 tw-rounded tw-transition-colors\"\n (click)=\"closeDatePicker()\">\n Done\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Time Picker Template -->\n<ng-template #timePickerTemplate>\n <div class=\"tw-bg-white tw-border tw-border-gray-300 tw-rounded-lg tw-shadow-lg tw-p-4 tw-w-72\">\n <!-- Time Picker Header -->\n <div class=\"tw-text-center tw-mb-3\">\n <h3 class=\"tw-text-base tw-font-semibold tw-text-gray-800 tw-m-0\">Time</h3>\n </div>\n\n <!-- Time Spinners Container -->\n <div class=\"tw-flex tw-items-center tw-justify-center tw-gap-3 tw-mb-4\">\n <!-- Hours -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'up')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_less</span>\n </button>\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-12 tw-text-center\">\n {{ timeHours }}\n </div>\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'down')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-2\">hour</span>\n </div>\n\n <!-- Colon Separator -->\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-mb-4\">:</div>\n\n <!-- Minutes -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'up')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_less</span>\n </button>\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-12 tw-text-center\">\n {{ timeMinutes.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'down')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-2\">min</span>\n </div>\n\n <!-- Colon Separator -->\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-mb-4\">:</div>\n\n <!-- Seconds -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'up')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_less</span>\n </button>\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-12 tw-text-center\">\n {{ timeSeconds.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'down')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-2\">sec</span>\n </div>\n </div>\n\n <!-- AM/PM Toggle -->\n <div class=\"tw-flex tw-justify-center tw-mb-3\">\n <div class=\"tw-inline-flex tw-rounded-md tw-bg-gray-100 tw-p-0.5\">\n <button type=\"button\"\n class=\"tw-px-4 tw-py-1.5 tw-text-sm tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'AM'\" [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow]=\"timeFormat === 'AM'\" [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button type=\"button\"\n class=\"tw-px-4 tw-py-1.5 tw-text-sm tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'PM'\" [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow]=\"timeFormat === 'PM'\" [class.tw-text-gray-600]=\"timeFormat !== 'PM'\"\n (click)=\"timeFormat = 'PM'\">\n PM\n </button>\n </div>\n </div>\n\n <!-- Current Time Display -->\n <div class=\"tw-text-center tw-mb-3\">\n <span class=\"tw-text-sm tw-text-gray-600\">\n {{ timeHours }}:{{ timeMinutes.toString().padStart(2, '0') }}:{{ timeSeconds.toString().padStart(2, '0') }} {{\n timeFormat }}\n </span>\n </div>\n\n <!-- Time Picker Footer -->\n <div class=\"tw-flex tw-gap-2\">\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-3 tw-py-1.5 tw-text-xs tw-font-medium tw-text-gray-700 tw-bg-white tw-border tw-border-gray-300 hover:tw-bg-gray-50 tw-rounded tw-transition-colors\"\n (click)=\"showDateTimePicker ? closeDateTimePicker() : closeTimePicker()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-3 tw-py-1.5 tw-text-xs tw-font-medium tw-text-white tw-bg-blue-600 hover:tw-bg-blue-700 tw-rounded tw-transition-colors tw-border-0\"\n (click)=\"showDateTimePicker ? applyDateTime() : applyTime()\">\n OK\n </button>\n </div>\n\n </div>\n</ng-template>\n\n<!-- DateTime Picker Template (Combined Date + Time) -->\n<ng-template #dateTimePickerTemplate>\n <div class=\"tw-bg-white tw-border tw-border-gray-300 tw-rounded-lg tw-shadow-lg tw-p-4\">\n <!-- DateTime Picker Header -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-4\">\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_left</span>\n </button>\n\n <button type=\"button\"\n class=\"tw-text-sm tw-font-medium tw-text-gray-800 hover:tw-bg-gray-100 tw-px-3 tw-py-1 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n {{ monthNames[currentMonth] }} {{ currentYear }}\n </button>\n\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_right</span>\n </button>\n </div>\n\n <div class=\"tw-grid tw-grid-cols-2 tw-gap-4\">\n <!-- Left Side: Calendar -->\n <div>\n <!-- Month/Year Selector -->\n @if (showMonthYearSelector) {\n <div class=\"tw-mb-4\">\n <!-- Year Navigation -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-3\">\n <button type=\"button\"\n class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_left</span>\n </button>\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-800\">{{ currentYear }}</span>\n <button type=\"button\"\n class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_right</span>\n </button>\n </div>\n\n <!-- Month Grid -->\n <div class=\"tw-grid tw-grid-cols-3 tw-gap-2 tw-mb-3\">\n @for (monthName of shortMonthNames; track $index) {\n <button type=\"button\" class=\"tw-px-2 tw-py-1.5 tw-text-xs tw-rounded-md tw-transition-colors tw-text-center\"\n [class.tw-bg-blue-500]=\"$index === currentMonth\" [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\" [class.hover:tw-bg-blue-50]=\"$index !== currentMonth\"\n (click)=\"selectMonth($index)\">\n {{ monthName }}\n </button>\n }\n </div>\n\n <!-- Back to Calendar Button -->\n <div class=\"tw-text-center\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-text-blue-600 hover:tw-bg-blue-50 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n Back to Calendar\n </button>\n </div>\n </div>\n } @else {\n <!-- Calendar View -->\n <div>\n <!-- Days of Week Header -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1 tw-mb-2\">\n @for (dayName of ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']; track dayName) {\n <div class=\"tw-text-center tw-text-xs tw-font-medium tw-text-gray-500 tw-py-1\">\n {{ dayName }}\n </div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1\">\n @for (dayInfo of calendarDays; track dayInfo.date.getTime()) {\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-text-xs tw-rounded-md tw-transition-colors tw-flex tw-items-center tw-justify-center\"\n [class.tw-text-gray-400]=\"!dayInfo.isCurrentMonth\" [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\" [class.tw-text-white]=\"dayInfo.isSelected\"\n [class.tw-bg-blue-100]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.tw-text-blue-800]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.hover:tw-bg-blue-50]=\"dayInfo.isCurrentMonth && !dayInfo.isSelected\"\n (click)=\"selectDateTimeDate(dayInfo)\">\n {{ dayInfo.day }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Right Side: Time Picker -->\n <div class=\"tw-border-l tw-border-gray-200 tw-pl-4\">\n <div class=\"tw-text-center tw-mb-2\">\n <h4 class=\"tw-text-sm tw-font-semibold tw-text-gray-800 tw-m-0\">Time</h4>\n </div>\n\n <!-- Time Spinners -->\n <div class=\"tw-flex tw-items-center tw-justify-center tw-gap-2 tw-mb-3\">\n <!-- Hours -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'up')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_less</span>\n </button>\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-10 tw-text-center\">\n {{ timeHours }}\n </div>\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'down')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">hour</span>\n </div>\n\n <!-- Colon -->\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-mb-3\">:</div>\n\n <!-- Minutes -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'up')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_less</span>\n </button>\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-10 tw-text-center\">\n {{ timeMinutes.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'down')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">min</span>\n </div>\n\n <!-- Colon -->\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-mb-3\">:</div>\n\n <!-- Seconds -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'up')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_less</span>\n </button>\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-10 tw-text-center\">\n {{ timeSeconds.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'down')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">sec</span>\n </div>\n </div>\n\n <!-- AM/PM Toggle -->\n <div class=\"tw-flex tw-justify-center tw-mb-2\">\n <div class=\"tw-inline-flex tw-rounded-md tw-bg-gray-100 tw-p-0.5\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'AM'\" [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'AM'\" [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'PM'\" [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'PM'\" [class.tw-text-gray-600]=\"timeFormat !== 'PM'\"\n (click)=\"timeFormat = 'PM'\">\n PM\n </button>\n </div>\n </div>\n\n <!-- Current Time Display -->\n <div class=\"tw-text-center tw-text-xs tw-text-gray-600\">\n {{ timeHours }}:{{ timeMinutes.toString().padStart(2, '0') }}:{{ timeSeconds.toString().padStart(2, '0') }} {{\n timeFormat }}\n </div>\n </div>\n </div>\n\n <!-- DateTime Picker Footer -->\n <div class=\"tw-flex tw-gap-2 tw-mt-3 tw-pt-2 tw-border-t tw-border-gray-200\">\n <button type=\"button\"\n class=\"tw-px-2 tw-py-1 tw-text-xs tw-font-medium tw-text-blue-600 tw-bg-white tw-border tw-border-blue-300 hover:tw-bg-blue-50 tw-rounded tw-transition-colors\"\n (click)=\"setCurrentDateTime()\">\n Now\n </button>\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-2 tw-py-1 tw-text-xs tw-font-medium tw-text-gray-700 tw-bg-white tw-border tw-border-gray-300 hover:tw-bg-gray-50 tw-rounded tw-transition-colors\"\n (click)=\"closeDateTimePicker()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-2 tw-py-1 tw-text-xs tw-font-medium tw-text-white tw-bg-blue-600 hover:tw-bg-blue-700 tw-rounded tw-transition-colors tw-border-0\"\n (click)=\"applyDateTime()\">\n OK\n </button>\n </div>\n </div>\n</ng-template>", styles: ["input[type=date]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}input[type=date]::-webkit-inner-spin-button,input[type=date]::-webkit-outer-spin-button{display:none;-webkit-appearance:none}input[type=date]{-moz-appearance:textfield}input[type=date]::-webkit-datetime-edit,input[type=date]::-webkit-datetime-edit-fields-wrapper{padding:0;background:transparent}input[type=date]::-webkit-datetime-edit-text{color:transparent;background:transparent}input[type=date]{background:transparent!important;border:none!important;outline:none!important}.cide-input-date-wrapper{position:relative;width:100%}.cide-input-date-overlay{position:absolute;inset:0;pointer-events:none;display:flex;align-items:center;padding-left:.25rem;color:var(--tw-gray-500)}.cide-input-date-has-value .cide-input-date-overlay{display:none}.cide-date-picker-panel{min-width:320px;max-width:400px;z-index:1000}.cide-date-picker-panel{animation:datePickerFadeIn .2s ease-out}@keyframes datePickerFadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.cide-date-picker-panel button:disabled{opacity:.5;cursor:not-allowed}.cide-date-picker-panel button:focus{outline:2px solid rgb(59,130,246);outline-offset:2px}.cide-date-picker-panel button:hover:not(:disabled){transform:scale(1.05);transition:transform .1s ease-in-out}.cide-date-picker-panel button.today:not(.selected){box-shadow:0 0 0 1px #3b82f6}.cide-date-picker-panel button.selected{box-shadow:0 2px 4px #3b82f64d;font-weight:600}.cide-date-picker-panel .nav-button{transition:all .2s ease-in-out}.cide-date-picker-panel .nav-button:hover{background-color:var(--tw-gray-200);transform:scale(1.1)}.cide-date-picker-panel h3{-webkit-user-select:none;user-select:none;transition:color .2s ease-in-out}.cide-date-picker-panel .days-header{border-bottom:1px solid var(--tw-gray-200);margin-bottom:.5rem;padding-bottom:.5rem}.cide-date-picker-portal{box-shadow:0 10px 25px -5px #0000001a,0 10px 10px -5px #0000000a;border-radius:.5rem;background:var(--cide-ele-bg-primary, #ffffff);border:1px solid var(--cide-ele-border-primary, #e5e7eb);z-index:9999;transition:opacity .2s ease-in-out,transform .2s ease-in-out;color:var(--cide-ele-text-primary, #1f2937)}.cide-date-picker-portal{animation:portalFadeIn .2s ease-out}@keyframes portalFadeIn{0%{opacity:0;transform:translateY(-8px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.cide-date-picker-portal.cide-portal{position:fixed!important;z-index:9999!important}input[type=time]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}input[type=time]::-webkit-inner-spin-button,input[type=time]::-webkit-outer-spin-button{display:none;-webkit-appearance:none}input[type=time]{-moz-appearance:textfield}input[type=time]::-webkit-datetime-edit,input[type=time]::-webkit-datetime-edit-fields-wrapper{padding:0;background:transparent}input[type=time]::-webkit-datetime-edit-text{color:transparent;background:transparent}input[type=time]{background:transparent!important;border:none!important;outline:none!important}.cide-time-picker-portal{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;border-radius:1rem;background:var(--cide-theme-light-color);border:1px solid var(--tw-gray-200);z-index:9999;transition:opacity .2s ease-in-out,transform .2s ease-in-out;animation:portalFadeIn .2s ease-out;color:var(--cide-theme-text-color)}.cide-time-picker-portal.cide-portal{position:fixed!important;z-index:9999!important}input[type=datetime-local]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}input[type=datetime-local]::-webkit-inner-spin-button,input[type=datetime-local]::-webkit-outer-spin-button{display:none;-webkit-appearance:none}input[type=datetime-local]{-moz-appearance:textfield}input[type=datetime-local]::-webkit-datetime-edit,input[type=datetime-local]::-webkit-datetime-edit-fields-wrapper{padding:0;background:transparent}input[type=datetime-local]::-webkit-datetime-edit-text{color:transparent;background:transparent}input[type=datetime-local]{background:transparent!important;border:none!important;outline:none!important}.cide-datetime-picker-portal{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;border-radius:1rem;background:var(--cide-theme-light-color);border:1px solid var(--tw-gray-200);z-index:9999;transition:opacity .2s ease-in-out,transform .2s ease-in-out;animation:portalFadeIn .2s ease-out;color:var(--cide-theme-text-color)}.cide-datetime-picker-portal.cide-portal{position:fixed!important;z-index:9999!important}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
1725
1774
|
// directives
|
|
1726
1775
|
CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type:
|
|
1727
1776
|
// for ngModel
|
|
@@ -1747,7 +1796,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
1747
1796
|
useExisting: forwardRef(() => CideInputComponent),
|
|
1748
1797
|
},
|
|
1749
1798
|
CapitalizePipe
|
|
1750
|
-
], template: "<div class=\"cide-input\">\n <!------------------------------------------TEXT | PASSWORD | DATE | URL------------------------------------------>\n @if (type === 'text' || type === 'number' || type === 'password' || type === 'email' || type === 'tel' || type ===\n 'date' || type === 'datetime-local' || type === 'url') {\n <div class=\"tw-w-full tw-relative\" [ngStyle]=\"{ width: width }\" [ngClass]=\"{\n 'cide-element-size-xxs': (size === '2xs'),\n 'cide-element-size-xs': (size === 'xs'),\n 'cide-element-size-sm': (size === 'sm'),\n 'cide-element-size-md': (size === 'md'),\n 'cide-element-size-lg': (size === 'lg'),\n 'cide-element-leading-icon': leadingIcon,\n 'cide-element-trailing-icon': trailingIconInternal,\n 'cide-element-clear-input': clearInput,\n 'cide-element-input-label-floating': (labelPlacement === 'floating'),\n 'cide-element-input-label-start': (labelDir === 'start'),\n 'cide-element-input-label-end': (labelDir === 'end'),\n 'cide-element-input-label-fixed': (labelPlacement === 'fixed'),\n 'cide-element-input-label-less': (!label || labelHide),\n 'cide-element-style-outline': (fill === 'outline'),\n 'cide-element-style-solid': (fill === 'solid'),\n 'cide-element-style-standard': (fill === 'standard'),\n 'cide-element-input-number': (type === 'number')\n }\">\n <!-- label -->\n @if (label && !labelHide) {\n <label [for]=\"id\" class=\"cide-input-label\">\n {{label}}\n @if (required) {\n <span class=\"tw-text-red-500 tw-ml-1\">*</span>\n }\n </label>\n }\n\n <!-- all one line elemets which dose not affect with label and error text -->\n <div class=\"cide-element-input-wrapper\">\n <!-- Leading Icon -->\n @if (leadingIcon) {\n <span class=\"cide-input-leading-icon-wrapper\">\n <span class=\"cide-input-leading-icon material-symbols-outlined tw-text-center\">{{leadingIcon}}</span>\n </span>\n }\n\n <!-- Trailing icon -->\n @if (trailingIconInternal) {\n <span class=\"tw-absolute cide-input-trailing-icon tw-select-none tw-right-0\">\n <span class=\"material-symbols-outlined tw-w-8 tw-text-center !tw-text-2xl\"\n [ngClass]=\"{'tw-cursor-pointer': isTrailingIconAllwedClick}\" [attr.tabindex]=\"false\"\n (click)=\"trailingIconClick()\" (keyup)=\"trailingIconClick()\">{{trailingIconInternal}}</span>\n </span>\n }\n\n <!-- Clear -->\n @if (clearInput && ngModel) {\n <button class=\"cide-input-clear\" (click)=\"ClearInputValue()\">\n <span class=\"cide-input-clear-icon material-symbols-outlined\">close</span>\n </button>\n }\n\n <!-- Date Input Wrapper -->\n @if (type === 'date') {\n <div class=\"cide-input-date-wrapper\" [ngClass]=\"{'cide-input-date-has-value': ngModel}\">\n <!-- Date Input (read-only to prevent manual input) -->\n <input [placeholder]=\"placeholder\" [id]=\"id || idRandom\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [value]=\"getDateDisplayValue()\" type=\"text\" (focus)=\"focusControl()\"\n (input)=\"upDateValue($event)\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none\" />\n\n <!-- Placeholder overlay for empty date -->\n @if (!ngModel && placeholder) {\n <div class=\"cide-input-date-overlay\">\n {{placeholder}}\n </div>\n }\n\n <!-- Date picker is now rendered as a portal appended to body -->\n </div>\n }\n\n <!-- Time Input Wrapper -->\n @if (isTimeType()) {\n <div class=\"cide-input-date-wrapper\" [ngClass]=\"{'cide-input-date-has-value': ngModel}\">\n <!-- Time Input (read-only to prevent manual input) -->\n <input [placeholder]=\"placeholder\" [id]=\"id || idRandom\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [value]=\"getTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\"\n (click)=\"trailingIconClick()\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none tw-cursor-pointer\" />\n\n <!-- Placeholder overlay for empty time -->\n @if (!ngModel && placeholder) {\n <div class=\"cide-input-date-overlay\">\n {{placeholder}}\n </div>\n }\n\n <!-- Time picker is now rendered as a portal appended to body -->\n </div>\n }\n\n <!-- DateTime Local Input -->\n @if (type === 'datetime-local') {\n <div class=\"cide-input-date-wrapper\" [ngClass]=\"{'cide-input-date-has-value': ngModel}\">\n <!-- DateTime Input (read-only to prevent manual input) -->\n <input [placeholder]=\"placeholder\" [id]=\"id || idRandom\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [value]=\"getDateTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\"\n (click)=\"trailingIconClick()\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none tw-cursor-pointer\" />\n\n <!-- Placeholder overlay for empty datetime -->\n @if (!ngModel && placeholder) {\n <div class=\"cide-input-date-overlay\">\n {{placeholder}}\n </div>\n }\n\n <!-- DateTime picker is now rendered as a portal appended to body -->\n </div>\n }\n\n <!-- Regular Input (non-date, non-time, non-datetime-local, non-url) -->\n @if (type !== 'date' && !isTimeType() && type !== 'datetime-local' && type !== 'url') {\n <input [placeholder]=\"placeholder\" [id]=\"id\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\"\n (focus)=\"focusControl()\" [autocomplete]=\"autocomplete\" [min]=\"min\" [max]=\"max\" [step]=\"step\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none\" />\n }\n\n <!-- URL Input -->\n @if (type === 'url') {\n <input [placeholder]=\"placeholder\" [id]=\"id\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\"\n (focus)=\"focusControl()\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none\" />\n }\n </div>\n <!-- error text / helper text -->\n @if ((errorText || helperText || !helperTextCollapse) && !hideHelperAndErrorText) {\n <span class=\"cide-input-help-error-text\">{{\n isValid\n ? helperText : (errorText ?\n (isTouched ? errorText : helperText)\n : helperText)}}\n </span>\n }\n </div>\n }\n\n <!-- Input with tralling icon -->\n <!-- <div class=\"tw-inline-block tw-h-12 tw-w-64\">\n <div class=\"tw-w-fullh-full tw-relative\">\n <label\n class=\"tw-absolute -tw-top-1/3 tw-mx-2 tw-bg-white tw-px-0.5 tw-py-0 tw-text-sm tw-leading-4 tw-text-gray-700\">Name</label>\n <span class=\"tw-absolute -tw-bottom-px tw-right-0 -tw-z-10 tw-text-gray-400\">\n <span class=\"material-symbols-outlined tw-w-8 tw-text-center !tw-text-2xl\"> person </span>\n </span>\n <input\n class=\"tw-m-0 tw-h-8 tw-w-full tw-overflow-hidden tw-rounded-md tw-border-2 tw-border-solid tw-border-gray-300 tw-bg-transparent tw-p-0 tw-pb-0.5 tw-pl-1 tw-pr-8 tw-text-sm tw-text-gray-600 tw-outline-none hover:tw-border-blue-400 focus:tw-border-blue-400 focus:tw-text-gray-950\"\n value=\"Ankush Bhure\" />\n </div>\n </div> -->\n\n <!-- Input with leading icon -->\n <!-- <div class=\"tw-inline-block tw-h-12 tw-w-64\">\n <div class=\"tw-w-fullh-full tw-relative\">\n <label\n class=\"tw-absolute -tw-top-1/3 tw-mx-2 tw-bg-white tw-px-0.5 tw-py-0 tw-text-sm tw-leading-4 tw-text-gray-700\">Name</label>\n <span class=\"tw-absolute -tw-bottom-px tw-left-0 -tw-z-10 tw-text-gray-400\">\n <span class=\"material-symbols-outlined tw-w-8 tw-text-center !tw-text-2xl\"> person </span>\n </span>\n <input\n class=\"tw-m-0 tw-h-8 tw-w-full tw-overflow-hidden tw-rounded-md tw-border-2 tw-border-solid tw-border-gray-300 tw-bg-transparent tw-p-0 tw-pb-0.5 tw-pl-8 tw-pr-1 tw-text-sm tw-text-gray-600 tw-outline-none hover:tw-border-blue-400 focus:tw-border-blue-400 focus:tw-text-gray-950\"\n value=\"Ankush Bhure\" />\n </div>\n </div> -->\n\n <!------------------------------------------CHECKBOX------------------------------------------>\n @if (type === 'checkbox') {\n <div class=\"tw-flex\">\n <div class=\"cide-checkbox tw-relative\">\n <input [checked]=\"ngModel\" [value]=\"ngModel\" [id]=\"idRandom\" [type]=\"type\" [disabled]=\"disabled\"\n class=\"tw-absolute tw-left-0 tw-invisible\" (click)=\"updateValueCheckBox(!ngModel); focusControl()\"\n [autocomplete]=\"autocomplete\" />\n <label class=\"cide-checkbox-label tw-cursor-pointer\" [for]=\"idRandom\">\n <span class=\"tw-border-2 tw-border-solid tw-relative tw-rounded-md\">\n <svg width=\"12px\" height=\"10px\" class=\"tw-absolute\">\n <use xlink:href=\"#sdfwiorfklasfjjalfjwerwr\"></use>\n </svg>\n </span>\n @if (!labelHide) {\n <span class=\"tw-text-sm tw-pl-2 tw-leading-[18px] tw-select-none tw-cursor-pointer\">{{label}}</span>\n }\n </label>\n <svg class=\"tw-absolute tw-h-0 tw-w-0 tw-select-none tw-pointer-events-none\">\n <!-- Element hidden and its xpath is used to display inside SVG -->\n <symbol id=\"sdfwiorfklasfjjalfjwerwr\" viewbox=\"0 0 12 10\">\n <polyline points=\"1.5 6 4.5 9 10.5 1\"></polyline>\n </symbol>\n </svg>\n </div>\n </div>\n }\n\n <!-------------------------------------------SELECT------------------------------------------->\n @if (type === 'select') {\n <div>sas\n <div class=\"tw-relative\">\n <div class=\"tw-absolute\">\n @for (item of option; track $index) {\n <div class=\"tw-w-full\">\n {{item}}\n </div>\n }\n </div>\n </div>\n </div>\n }\n</div>\n\n<!-- Date Picker Template -->\n<ng-template #datePickerTemplate>\n <div class=\"tw-bg-white tw-border tw-border-gray-300 tw-rounded-lg tw-shadow-lg tw-p-4\">\n <!-- Date Picker Header -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-4\">\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_left</span>\n </button>\n\n <button type=\"button\"\n class=\"tw-text-sm tw-font-medium tw-text-gray-800 hover:tw-bg-gray-100 tw-px-3 tw-py-1 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n {{ monthNames[currentMonth] }} {{ currentYear }}\n </button>\n\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_right</span>\n </button>\n </div>\n\n <!-- Month/Year Selector -->\n @if (showMonthYearSelector) {\n <div class=\"tw-mb-4\">\n <!-- Year Navigation -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-3\">\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_left</span>\n </button>\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-800\">{{ currentYear }}</span>\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_right</span>\n </button>\n </div>\n\n <!-- Month Grid -->\n <div class=\"tw-grid tw-grid-cols-3 tw-gap-2 tw-mb-3\">\n @for (monthName of shortMonthNames; track $index) {\n <button type=\"button\" class=\"tw-px-3 tw-py-2 tw-text-sm tw-rounded-md tw-transition-colors tw-text-center\"\n [class.tw-bg-blue-500]=\"$index === currentMonth\" [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\" [class.hover:tw-bg-blue-50]=\"$index !== currentMonth\"\n (click)=\"selectMonth($index)\">\n {{ monthName }}\n </button>\n }\n </div>\n\n <!-- Back to Calendar Button -->\n <div class=\"tw-text-center\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-sm tw-text-blue-600 hover:tw-bg-blue-50 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n Back to Calendar\n </button>\n </div>\n </div>\n } @else {\n <!-- Calendar View -->\n <div>\n <!-- Days of Week Header -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1 tw-mb-2\">\n @for (dayName of ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']; track dayName) {\n <div class=\"tw-text-center tw-text-xs tw-font-medium tw-text-gray-500 tw-py-2\">\n {{ dayName }}\n </div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1\">\n @for (dayInfo of calendarDays; track dayInfo.date.getTime()) {\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-text-sm tw-rounded-md tw-transition-colors tw-flex tw-items-center tw-justify-center\"\n [class.tw-text-gray-400]=\"!dayInfo.isCurrentMonth\" [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\" [class.tw-text-white]=\"dayInfo.isSelected\"\n [class.tw-bg-blue-100]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.tw-text-blue-800]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.hover:tw-bg-blue-50]=\"dayInfo.isCurrentMonth && !dayInfo.isSelected\"\n (click)=\"showDateTimePicker ? selectDateTimeDate(dayInfo) : selectDate(dayInfo)\">\n {{ dayInfo.day }}\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Date Picker Footer -->\n <div class=\"tw-flex tw-justify-between tw-mt-3 tw-pt-2 tw-border-t tw-border-gray-200\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-text-gray-600 hover:tw-bg-gray-100 tw-rounded tw-transition-colors\"\n (click)=\"closeDatePicker()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-bg-blue-600 tw-text-white hover:tw-bg-blue-700 tw-rounded tw-transition-colors\"\n (click)=\"closeDatePicker()\">\n Done\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Time Picker Template -->\n<ng-template #timePickerTemplate>\n <div class=\"tw-bg-white tw-border tw-border-gray-300 tw-rounded-lg tw-shadow-lg tw-p-4 tw-w-72\">\n <!-- Time Picker Header -->\n <div class=\"tw-text-center tw-mb-3\">\n <h3 class=\"tw-text-base tw-font-semibold tw-text-gray-800 tw-m-0\">Time</h3>\n </div>\n\n <!-- Time Spinners Container -->\n <div class=\"tw-flex tw-items-center tw-justify-center tw-gap-3 tw-mb-4\">\n <!-- Hours -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'up')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_less</span>\n </button>\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-12 tw-text-center\">\n {{ timeHours }}\n </div>\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'down')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-2\">hour</span>\n </div>\n\n <!-- Colon Separator -->\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-mb-4\">:</div>\n\n <!-- Minutes -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'up')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_less</span>\n </button>\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-12 tw-text-center\">\n {{ timeMinutes.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'down')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-2\">min</span>\n </div>\n\n <!-- Colon Separator -->\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-mb-4\">:</div>\n\n <!-- Seconds -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'up')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_less</span>\n </button>\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-12 tw-text-center\">\n {{ timeSeconds.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'down')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-2\">sec</span>\n </div>\n </div>\n\n <!-- AM/PM Toggle -->\n <div class=\"tw-flex tw-justify-center tw-mb-3\">\n <div class=\"tw-inline-flex tw-rounded-md tw-bg-gray-100 tw-p-0.5\">\n <button type=\"button\"\n class=\"tw-px-4 tw-py-1.5 tw-text-sm tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'AM'\" [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow]=\"timeFormat === 'AM'\" [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button type=\"button\"\n class=\"tw-px-4 tw-py-1.5 tw-text-sm tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'PM'\" [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow]=\"timeFormat === 'PM'\" [class.tw-text-gray-600]=\"timeFormat !== 'PM'\"\n (click)=\"timeFormat = 'PM'\">\n PM\n </button>\n </div>\n </div>\n\n <!-- Current Time Display -->\n <div class=\"tw-text-center tw-mb-3\">\n <span class=\"tw-text-sm tw-text-gray-600\">\n {{ timeHours }}:{{ timeMinutes.toString().padStart(2, '0') }}:{{ timeSeconds.toString().padStart(2, '0') }} {{\n timeFormat }}\n </span>\n </div>\n\n <!-- Time Picker Footer -->\n <div class=\"tw-flex tw-gap-2\">\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-3 tw-py-1.5 tw-text-xs tw-font-medium tw-text-gray-700 tw-bg-white tw-border tw-border-gray-300 hover:tw-bg-gray-50 tw-rounded tw-transition-colors\"\n (click)=\"showDateTimePicker ? closeDateTimePicker() : closeTimePicker()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-3 tw-py-1.5 tw-text-xs tw-font-medium tw-text-white tw-bg-blue-600 hover:tw-bg-blue-700 tw-rounded tw-transition-colors tw-border-0\"\n (click)=\"showDateTimePicker ? applyDateTime() : applyTime()\">\n OK\n </button>\n </div>\n\n </div>\n</ng-template>\n\n<!-- DateTime Picker Template (Combined Date + Time) -->\n<ng-template #dateTimePickerTemplate>\n <div class=\"tw-bg-white tw-border tw-border-gray-300 tw-rounded-lg tw-shadow-lg tw-p-4\">\n <!-- DateTime Picker Header -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-4\">\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_left</span>\n </button>\n\n <button type=\"button\"\n class=\"tw-text-sm tw-font-medium tw-text-gray-800 hover:tw-bg-gray-100 tw-px-3 tw-py-1 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n {{ monthNames[currentMonth] }} {{ currentYear }}\n </button>\n\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_right</span>\n </button>\n </div>\n\n <div class=\"tw-grid tw-grid-cols-2 tw-gap-4\">\n <!-- Left Side: Calendar -->\n <div>\n <!-- Month/Year Selector -->\n @if (showMonthYearSelector) {\n <div class=\"tw-mb-4\">\n <!-- Year Navigation -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-3\">\n <button type=\"button\"\n class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_left</span>\n </button>\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-800\">{{ currentYear }}</span>\n <button type=\"button\"\n class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_right</span>\n </button>\n </div>\n\n <!-- Month Grid -->\n <div class=\"tw-grid tw-grid-cols-3 tw-gap-2 tw-mb-3\">\n @for (monthName of shortMonthNames; track $index) {\n <button type=\"button\" class=\"tw-px-2 tw-py-1.5 tw-text-xs tw-rounded-md tw-transition-colors tw-text-center\"\n [class.tw-bg-blue-500]=\"$index === currentMonth\" [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\" [class.hover:tw-bg-blue-50]=\"$index !== currentMonth\"\n (click)=\"selectMonth($index)\">\n {{ monthName }}\n </button>\n }\n </div>\n\n <!-- Back to Calendar Button -->\n <div class=\"tw-text-center\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-text-blue-600 hover:tw-bg-blue-50 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n Back to Calendar\n </button>\n </div>\n </div>\n } @else {\n <!-- Calendar View -->\n <div>\n <!-- Days of Week Header -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1 tw-mb-2\">\n @for (dayName of ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']; track dayName) {\n <div class=\"tw-text-center tw-text-xs tw-font-medium tw-text-gray-500 tw-py-1\">\n {{ dayName }}\n </div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1\">\n @for (dayInfo of calendarDays; track dayInfo.date.getTime()) {\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-text-xs tw-rounded-md tw-transition-colors tw-flex tw-items-center tw-justify-center\"\n [class.tw-text-gray-400]=\"!dayInfo.isCurrentMonth\" [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\" [class.tw-text-white]=\"dayInfo.isSelected\"\n [class.tw-bg-blue-100]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.tw-text-blue-800]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.hover:tw-bg-blue-50]=\"dayInfo.isCurrentMonth && !dayInfo.isSelected\"\n (click)=\"selectDateTimeDate(dayInfo)\">\n {{ dayInfo.day }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Right Side: Time Picker -->\n <div class=\"tw-border-l tw-border-gray-200 tw-pl-4\">\n <div class=\"tw-text-center tw-mb-2\">\n <h4 class=\"tw-text-sm tw-font-semibold tw-text-gray-800 tw-m-0\">Time</h4>\n </div>\n\n <!-- Time Spinners -->\n <div class=\"tw-flex tw-items-center tw-justify-center tw-gap-2 tw-mb-3\">\n <!-- Hours -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'up')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_less</span>\n </button>\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-10 tw-text-center\">\n {{ timeHours }}\n </div>\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'down')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">hour</span>\n </div>\n\n <!-- Colon -->\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-mb-3\">:</div>\n\n <!-- Minutes -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'up')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_less</span>\n </button>\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-10 tw-text-center\">\n {{ timeMinutes.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'down')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">min</span>\n </div>\n\n <!-- Colon -->\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-mb-3\">:</div>\n\n <!-- Seconds -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'up')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_less</span>\n </button>\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-10 tw-text-center\">\n {{ timeSeconds.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'down')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">sec</span>\n </div>\n </div>\n\n <!-- AM/PM Toggle -->\n <div class=\"tw-flex tw-justify-center tw-mb-2\">\n <div class=\"tw-inline-flex tw-rounded-md tw-bg-gray-100 tw-p-0.5\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'AM'\" [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'AM'\" [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'PM'\" [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'PM'\" [class.tw-text-gray-600]=\"timeFormat !== 'PM'\"\n (click)=\"timeFormat = 'PM'\">\n PM\n </button>\n </div>\n </div>\n\n <!-- Current Time Display -->\n <div class=\"tw-text-center tw-text-xs tw-text-gray-600\">\n {{ timeHours }}:{{ timeMinutes.toString().padStart(2, '0') }}:{{ timeSeconds.toString().padStart(2, '0') }} {{\n timeFormat }}\n </div>\n </div>\n </div>\n\n <!-- DateTime Picker Footer -->\n <div class=\"tw-flex tw-gap-2 tw-mt-3 tw-pt-2 tw-border-t tw-border-gray-200\">\n <button type=\"button\"\n class=\"tw-px-2 tw-py-1 tw-text-xs tw-font-medium tw-text-blue-600 tw-bg-white tw-border tw-border-blue-300 hover:tw-bg-blue-50 tw-rounded tw-transition-colors\"\n (click)=\"setCurrentDateTime()\">\n Now\n </button>\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-2 tw-py-1 tw-text-xs tw-font-medium tw-text-gray-700 tw-bg-white tw-border tw-border-gray-300 hover:tw-bg-gray-50 tw-rounded tw-transition-colors\"\n (click)=\"closeDateTimePicker()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-2 tw-py-1 tw-text-xs tw-font-medium tw-text-white tw-bg-blue-600 hover:tw-bg-blue-700 tw-rounded tw-transition-colors tw-border-0\"\n (click)=\"applyDateTime()\">\n OK\n </button>\n </div>\n </div>\n</ng-template>", styles: ["input[type=date]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}input[type=date]::-webkit-inner-spin-button,input[type=date]::-webkit-outer-spin-button{display:none;-webkit-appearance:none}input[type=date]{-moz-appearance:textfield}input[type=date]::-webkit-datetime-edit,input[type=date]::-webkit-datetime-edit-fields-wrapper{padding:0;background:transparent}input[type=date]::-webkit-datetime-edit-text{color:transparent;background:transparent}input[type=date]{background:transparent!important;border:none!important;outline:none!important}.cide-input-date-wrapper{position:relative;width:100%}.cide-input-date-overlay{position:absolute;inset:0;pointer-events:none;display:flex;align-items:center;padding-left:.25rem;color:var(--tw-gray-500)}.cide-input-date-has-value .cide-input-date-overlay{display:none}.cide-date-picker-panel{min-width:320px;max-width:400px;z-index:1000}.cide-date-picker-panel{animation:datePickerFadeIn .2s ease-out}@keyframes datePickerFadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.cide-date-picker-panel button:disabled{opacity:.5;cursor:not-allowed}.cide-date-picker-panel button:focus{outline:2px solid rgb(59,130,246);outline-offset:2px}.cide-date-picker-panel button:hover:not(:disabled){transform:scale(1.05);transition:transform .1s ease-in-out}.cide-date-picker-panel button.today:not(.selected){box-shadow:0 0 0 1px #3b82f6}.cide-date-picker-panel button.selected{box-shadow:0 2px 4px #3b82f64d;font-weight:600}.cide-date-picker-panel .nav-button{transition:all .2s ease-in-out}.cide-date-picker-panel .nav-button:hover{background-color:var(--tw-gray-200);transform:scale(1.1)}.cide-date-picker-panel h3{-webkit-user-select:none;user-select:none;transition:color .2s ease-in-out}.cide-date-picker-panel .days-header{border-bottom:1px solid var(--tw-gray-200);margin-bottom:.5rem;padding-bottom:.5rem}.cide-date-picker-portal{box-shadow:0 10px 25px -5px #0000001a,0 10px 10px -5px #0000000a;border-radius:.5rem;background:var(--cide-ele-bg-primary, #ffffff);border:1px solid var(--cide-ele-border-primary, #e5e7eb);z-index:9999;transition:opacity .2s ease-in-out,transform .2s ease-in-out;color:var(--cide-ele-text-primary, #1f2937)}.cide-date-picker-portal{animation:portalFadeIn .2s ease-out}@keyframes portalFadeIn{0%{opacity:0;transform:translateY(-8px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.cide-date-picker-portal.cide-portal{position:fixed!important;z-index:9999!important}input[type=time]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}input[type=time]::-webkit-inner-spin-button,input[type=time]::-webkit-outer-spin-button{display:none;-webkit-appearance:none}input[type=time]{-moz-appearance:textfield}input[type=time]::-webkit-datetime-edit,input[type=time]::-webkit-datetime-edit-fields-wrapper{padding:0;background:transparent}input[type=time]::-webkit-datetime-edit-text{color:transparent;background:transparent}input[type=time]{background:transparent!important;border:none!important;outline:none!important}.cide-time-picker-portal{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;border-radius:1rem;background:var(--cide-theme-light-color);border:1px solid var(--tw-gray-200);z-index:9999;transition:opacity .2s ease-in-out,transform .2s ease-in-out;animation:portalFadeIn .2s ease-out;color:var(--cide-theme-text-color)}.cide-time-picker-portal.cide-portal{position:fixed!important;z-index:9999!important}input[type=datetime-local]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}input[type=datetime-local]::-webkit-inner-spin-button,input[type=datetime-local]::-webkit-outer-spin-button{display:none;-webkit-appearance:none}input[type=datetime-local]{-moz-appearance:textfield}input[type=datetime-local]::-webkit-datetime-edit,input[type=datetime-local]::-webkit-datetime-edit-fields-wrapper{padding:0;background:transparent}input[type=datetime-local]::-webkit-datetime-edit-text{color:transparent;background:transparent}input[type=datetime-local]{background:transparent!important;border:none!important;outline:none!important}.cide-datetime-picker-portal{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;border-radius:1rem;background:var(--cide-theme-light-color);border:1px solid var(--tw-gray-200);z-index:9999;transition:opacity .2s ease-in-out,transform .2s ease-in-out;animation:portalFadeIn .2s ease-out;color:var(--cide-theme-text-color)}.cide-datetime-picker-portal.cide-portal{position:fixed!important;z-index:9999!important}\n"] }]
|
|
1799
|
+
], template: "<div class=\"cide-input\">\n <!------------------------------------------TEXT | PASSWORD | DATE | URL------------------------------------------>\n @if (type === 'text' || type === 'number' || type === 'password' || type === 'email' || type === 'tel' || type ===\n 'date' || type === 'datetime-local' || type === 'url') {\n <div class=\"tw-w-full tw-relative\" [ngStyle]=\"{ width: width }\" [ngClass]=\"{\n 'cide-element-size-xxs': (size === '2xs'),\n 'cide-element-size-xs': (size === 'xs'),\n 'cide-element-size-sm': (size === 'sm'),\n 'cide-element-size-md': (size === 'md'),\n 'cide-element-size-lg': (size === 'lg'),\n 'cide-element-leading-icon': leadingIcon,\n 'cide-element-trailing-icon': trailingIconInternal,\n 'cide-element-clear-input': clearInput,\n 'cide-element-input-label-floating': (labelPlacement === 'floating'),\n 'cide-element-input-label-start': (labelDir === 'start'),\n 'cide-element-input-label-end': (labelDir === 'end'),\n 'cide-element-input-label-fixed': (labelPlacement === 'fixed'),\n 'cide-element-input-label-less': (!label || labelHide),\n 'cide-element-style-outline': (fill === 'outline'),\n 'cide-element-style-solid': (fill === 'solid'),\n 'cide-element-style-standard': (fill === 'standard'),\n 'cide-element-input-number': (type === 'number')\n }\">\n <!-- label -->\n @if (label && !labelHide) {\n <label [for]=\"id\" class=\"cide-input-label\">\n {{label}}\n @if (required) {\n <span class=\"tw-text-red-500 tw-ml-1\">*</span>\n }\n </label>\n }\n\n <!-- all one line elemets which dose not affect with label and error text -->\n <div class=\"cide-element-input-wrapper\">\n <!-- Leading Icon -->\n @if (leadingIcon) {\n <span class=\"cide-input-leading-icon-wrapper\">\n <span class=\"cide-input-leading-icon material-symbols-outlined tw-text-center\">{{leadingIcon}}</span>\n </span>\n }\n\n <!-- Trailing icon -->\n @if (trailingIconInternal) {\n <span class=\"tw-absolute cide-input-trailing-icon tw-select-none tw-right-0\">\n <span class=\"material-symbols-outlined tw-w-8 tw-text-center !tw-text-2xl\"\n [ngClass]=\"{'tw-cursor-pointer': isTrailingIconAllwedClick}\" [attr.tabindex]=\"false\"\n (click)=\"trailingIconClick()\" (keyup)=\"trailingIconClick()\">{{trailingIconInternal}}</span>\n </span>\n }\n\n <!-- Clear -->\n @if (clearInput && ngModel) {\n <button class=\"cide-input-clear\" (click)=\"ClearInputValue()\">\n <span class=\"cide-input-clear-icon material-symbols-outlined\">close</span>\n </button>\n }\n\n <!-- Date Input Wrapper -->\n @if (type === 'date') {\n <div class=\"cide-input-date-wrapper\" [ngClass]=\"{'cide-input-date-has-value': ngModel}\">\n <!-- Date Input (read-only to prevent manual input) -->\n <input [placeholder]=\"placeholder || 'DD/MM/YYYY'\" [id]=\"id || idRandom\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [value]=\"getDateDisplayValue()\" type=\"text\" (focus)=\"focusControl()\"\n (input)=\"onDateInput($event)\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none\" />\n\n <!-- Placeholder overlay for empty date -->\n @if (!ngModel && placeholder) {\n <div class=\"cide-input-date-overlay\">\n {{placeholder}}\n </div>\n }\n\n <!-- Date picker is now rendered as a portal appended to body -->\n </div>\n }\n\n <!-- Time Input Wrapper -->\n @if (isTimeType()) {\n <div class=\"cide-input-date-wrapper\" [ngClass]=\"{'cide-input-date-has-value': ngModel}\">\n <!-- Time Input (read-only to prevent manual input) -->\n <input [placeholder]=\"placeholder\" [id]=\"id || idRandom\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [value]=\"getTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\"\n (click)=\"trailingIconClick()\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none tw-cursor-pointer\" />\n\n <!-- Placeholder overlay for empty time -->\n @if (!ngModel && placeholder) {\n <div class=\"cide-input-date-overlay\">\n {{placeholder}}\n </div>\n }\n\n <!-- Time picker is now rendered as a portal appended to body -->\n </div>\n }\n\n <!-- DateTime Local Input -->\n @if (type === 'datetime-local') {\n <div class=\"cide-input-date-wrapper\" [ngClass]=\"{'cide-input-date-has-value': ngModel}\">\n <!-- DateTime Input (read-only to prevent manual input) -->\n <input [placeholder]=\"placeholder\" [id]=\"id || idRandom\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [value]=\"getDateTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\"\n (click)=\"trailingIconClick()\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none tw-cursor-pointer\" />\n\n <!-- Placeholder overlay for empty datetime -->\n @if (!ngModel && placeholder) {\n <div class=\"cide-input-date-overlay\">\n {{placeholder}}\n </div>\n }\n\n <!-- DateTime picker is now rendered as a portal appended to body -->\n </div>\n }\n\n <!-- Regular Input (non-date, non-time, non-datetime-local, non-url) -->\n @if (type !== 'date' && !isTimeType() && type !== 'datetime-local' && type !== 'url') {\n <input [placeholder]=\"placeholder\" [id]=\"id\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\"\n (focus)=\"focusControl()\" [autocomplete]=\"autocomplete\" [min]=\"min\" [max]=\"max\" [step]=\"step\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none\" />\n }\n\n <!-- URL Input -->\n @if (type === 'url') {\n <input [placeholder]=\"placeholder\" [id]=\"id\" [disabled]=\"disabled\" [ngClass]=\"{\n 'tw-rounded-e-md tw-rounded-es-md': label && labelPlacement === 'fixed',\n 'tw-rounded-md': !(label && labelPlacement === 'fixed'),\n 'tw-pl-1': !leadingIcon,\n 'tw-pr-8': trailingIconInternal,\n 'tw-pr-1': !trailingIconInternal,\n 'tw-h-8 tw-pt-0.5 tw-pb-0': size === 'md',\n 'tw-h-7': size === 'sm',\n '!tw-mt-0': labelHide,\n 'tw-opacity-50 tw-cursor-not-allowed': disabled\n }\" [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\"\n (focus)=\"focusControl()\" [autocomplete]=\"autocomplete\"\n class=\"tw-m-0 tw-w-full tw-bg-transparent tw-overflow-hidden tw-border-solid tw-p-0 cide-input-input tw-outline-none\" />\n }\n </div>\n <!-- error text / helper text -->\n @if ((errorText || helperText || !helperTextCollapse) && !hideHelperAndErrorText) {\n <span class=\"cide-input-help-error-text\">{{\n isValid\n ? helperText : (errorText ?\n (isTouched ? errorText : helperText)\n : helperText)}}\n </span>\n }\n </div>\n }\n\n <!-- Input with tralling icon -->\n <!-- <div class=\"tw-inline-block tw-h-12 tw-w-64\">\n <div class=\"tw-w-fullh-full tw-relative\">\n <label\n class=\"tw-absolute -tw-top-1/3 tw-mx-2 tw-bg-white tw-px-0.5 tw-py-0 tw-text-sm tw-leading-4 tw-text-gray-700\">Name</label>\n <span class=\"tw-absolute -tw-bottom-px tw-right-0 -tw-z-10 tw-text-gray-400\">\n <span class=\"material-symbols-outlined tw-w-8 tw-text-center !tw-text-2xl\"> person </span>\n </span>\n <input\n class=\"tw-m-0 tw-h-8 tw-w-full tw-overflow-hidden tw-rounded-md tw-border-2 tw-border-solid tw-border-gray-300 tw-bg-transparent tw-p-0 tw-pb-0.5 tw-pl-1 tw-pr-8 tw-text-sm tw-text-gray-600 tw-outline-none hover:tw-border-blue-400 focus:tw-border-blue-400 focus:tw-text-gray-950\"\n value=\"Ankush Bhure\" />\n </div>\n </div> -->\n\n <!-- Input with leading icon -->\n <!-- <div class=\"tw-inline-block tw-h-12 tw-w-64\">\n <div class=\"tw-w-fullh-full tw-relative\">\n <label\n class=\"tw-absolute -tw-top-1/3 tw-mx-2 tw-bg-white tw-px-0.5 tw-py-0 tw-text-sm tw-leading-4 tw-text-gray-700\">Name</label>\n <span class=\"tw-absolute -tw-bottom-px tw-left-0 -tw-z-10 tw-text-gray-400\">\n <span class=\"material-symbols-outlined tw-w-8 tw-text-center !tw-text-2xl\"> person </span>\n </span>\n <input\n class=\"tw-m-0 tw-h-8 tw-w-full tw-overflow-hidden tw-rounded-md tw-border-2 tw-border-solid tw-border-gray-300 tw-bg-transparent tw-p-0 tw-pb-0.5 tw-pl-8 tw-pr-1 tw-text-sm tw-text-gray-600 tw-outline-none hover:tw-border-blue-400 focus:tw-border-blue-400 focus:tw-text-gray-950\"\n value=\"Ankush Bhure\" />\n </div>\n </div> -->\n\n <!------------------------------------------CHECKBOX------------------------------------------>\n @if (type === 'checkbox') {\n <div class=\"tw-flex\">\n <div class=\"cide-checkbox tw-relative\">\n <input [checked]=\"ngModel\" [value]=\"ngModel\" [id]=\"idRandom\" [type]=\"type\" [disabled]=\"disabled\"\n class=\"tw-absolute tw-left-0 tw-invisible\" (click)=\"updateValueCheckBox(!ngModel); focusControl()\"\n [autocomplete]=\"autocomplete\" />\n <label class=\"cide-checkbox-label tw-cursor-pointer\" [for]=\"idRandom\">\n <span class=\"tw-border-2 tw-border-solid tw-relative tw-rounded-md\">\n <svg width=\"12px\" height=\"10px\" class=\"tw-absolute\">\n <use xlink:href=\"#sdfwiorfklasfjjalfjwerwr\"></use>\n </svg>\n </span>\n @if (!labelHide) {\n <span class=\"tw-text-sm tw-pl-2 tw-leading-[18px] tw-select-none tw-cursor-pointer\">{{label}}</span>\n }\n </label>\n <svg class=\"tw-absolute tw-h-0 tw-w-0 tw-select-none tw-pointer-events-none\">\n <!-- Element hidden and its xpath is used to display inside SVG -->\n <symbol id=\"sdfwiorfklasfjjalfjwerwr\" viewbox=\"0 0 12 10\">\n <polyline points=\"1.5 6 4.5 9 10.5 1\"></polyline>\n </symbol>\n </svg>\n </div>\n </div>\n }\n\n <!-------------------------------------------SELECT------------------------------------------->\n @if (type === 'select') {\n <div>sas\n <div class=\"tw-relative\">\n <div class=\"tw-absolute\">\n @for (item of option; track $index) {\n <div class=\"tw-w-full\">\n {{item}}\n </div>\n }\n </div>\n </div>\n </div>\n }\n</div>\n\n<!-- Date Picker Template -->\n<ng-template #datePickerTemplate>\n <div class=\"tw-bg-white tw-border tw-border-gray-300 tw-rounded-lg tw-shadow-lg tw-p-4\">\n <!-- Date Picker Header -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-4\">\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_left</span>\n </button>\n\n <button type=\"button\"\n class=\"tw-text-sm tw-font-medium tw-text-gray-800 hover:tw-bg-gray-100 tw-px-3 tw-py-1 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n {{ monthNames[currentMonth] }} {{ currentYear }}\n </button>\n\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_right</span>\n </button>\n </div>\n\n <!-- Month/Year Selector -->\n @if (showMonthYearSelector) {\n <div class=\"tw-mb-4\">\n <!-- Year Navigation -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-3\">\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_left</span>\n </button>\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-800\">{{ currentYear }}</span>\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_right</span>\n </button>\n </div>\n\n <!-- Month Grid -->\n <div class=\"tw-grid tw-grid-cols-3 tw-gap-2 tw-mb-3\">\n @for (monthName of shortMonthNames; track $index) {\n <button type=\"button\" class=\"tw-px-3 tw-py-2 tw-text-sm tw-rounded-md tw-transition-colors tw-text-center\"\n [class.tw-bg-blue-500]=\"$index === currentMonth\" [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\" [class.hover:tw-bg-blue-50]=\"$index !== currentMonth\"\n (click)=\"selectMonth($index)\">\n {{ monthName }}\n </button>\n }\n </div>\n\n <!-- Back to Calendar Button -->\n <div class=\"tw-text-center\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-sm tw-text-blue-600 hover:tw-bg-blue-50 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n Back to Calendar\n </button>\n </div>\n </div>\n } @else {\n <!-- Calendar View -->\n <div>\n <!-- Days of Week Header -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1 tw-mb-2\">\n @for (dayName of ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']; track dayName) {\n <div class=\"tw-text-center tw-text-xs tw-font-medium tw-text-gray-500 tw-py-2\">\n {{ dayName }}\n </div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1\">\n @for (dayInfo of calendarDays; track dayInfo.date.getTime()) {\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-text-sm tw-rounded-md tw-transition-colors tw-flex tw-items-center tw-justify-center\"\n [class.tw-text-gray-400]=\"!dayInfo.isCurrentMonth\" [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\" [class.tw-text-white]=\"dayInfo.isSelected\"\n [class.tw-bg-blue-100]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.tw-text-blue-800]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.hover:tw-bg-blue-50]=\"dayInfo.isCurrentMonth && !dayInfo.isSelected\"\n (click)=\"showDateTimePicker ? selectDateTimeDate(dayInfo) : selectDate(dayInfo)\">\n {{ dayInfo.day }}\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Date Picker Footer -->\n <div class=\"tw-flex tw-justify-between tw-mt-3 tw-pt-2 tw-border-t tw-border-gray-200\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-text-gray-600 hover:tw-bg-gray-100 tw-rounded tw-transition-colors\"\n (click)=\"closeDatePicker()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-bg-blue-600 tw-text-white hover:tw-bg-blue-700 tw-rounded tw-transition-colors\"\n (click)=\"closeDatePicker()\">\n Done\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Time Picker Template -->\n<ng-template #timePickerTemplate>\n <div class=\"tw-bg-white tw-border tw-border-gray-300 tw-rounded-lg tw-shadow-lg tw-p-4 tw-w-72\">\n <!-- Time Picker Header -->\n <div class=\"tw-text-center tw-mb-3\">\n <h3 class=\"tw-text-base tw-font-semibold tw-text-gray-800 tw-m-0\">Time</h3>\n </div>\n\n <!-- Time Spinners Container -->\n <div class=\"tw-flex tw-items-center tw-justify-center tw-gap-3 tw-mb-4\">\n <!-- Hours -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'up')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_less</span>\n </button>\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-12 tw-text-center\">\n {{ timeHours }}\n </div>\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'down')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-2\">hour</span>\n </div>\n\n <!-- Colon Separator -->\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-mb-4\">:</div>\n\n <!-- Minutes -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'up')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_less</span>\n </button>\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-12 tw-text-center\">\n {{ timeMinutes.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'down')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-2\">min</span>\n </div>\n\n <!-- Colon Separator -->\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-mb-4\">:</div>\n\n <!-- Seconds -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'up')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_less</span>\n </button>\n <div class=\"tw-text-2xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-12 tw-text-center\">\n {{ timeSeconds.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'down')\">\n <span class=\"material-symbols-outlined tw-text-lg\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-2\">sec</span>\n </div>\n </div>\n\n <!-- AM/PM Toggle -->\n <div class=\"tw-flex tw-justify-center tw-mb-3\">\n <div class=\"tw-inline-flex tw-rounded-md tw-bg-gray-100 tw-p-0.5\">\n <button type=\"button\"\n class=\"tw-px-4 tw-py-1.5 tw-text-sm tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'AM'\" [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow]=\"timeFormat === 'AM'\" [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button type=\"button\"\n class=\"tw-px-4 tw-py-1.5 tw-text-sm tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'PM'\" [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow]=\"timeFormat === 'PM'\" [class.tw-text-gray-600]=\"timeFormat !== 'PM'\"\n (click)=\"timeFormat = 'PM'\">\n PM\n </button>\n </div>\n </div>\n\n <!-- Current Time Display -->\n <div class=\"tw-text-center tw-mb-3\">\n <span class=\"tw-text-sm tw-text-gray-600\">\n {{ timeHours }}:{{ timeMinutes.toString().padStart(2, '0') }}:{{ timeSeconds.toString().padStart(2, '0') }} {{\n timeFormat }}\n </span>\n </div>\n\n <!-- Time Picker Footer -->\n <div class=\"tw-flex tw-gap-2\">\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-3 tw-py-1.5 tw-text-xs tw-font-medium tw-text-gray-700 tw-bg-white tw-border tw-border-gray-300 hover:tw-bg-gray-50 tw-rounded tw-transition-colors\"\n (click)=\"showDateTimePicker ? closeDateTimePicker() : closeTimePicker()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-3 tw-py-1.5 tw-text-xs tw-font-medium tw-text-white tw-bg-blue-600 hover:tw-bg-blue-700 tw-rounded tw-transition-colors tw-border-0\"\n (click)=\"showDateTimePicker ? applyDateTime() : applyTime()\">\n OK\n </button>\n </div>\n\n </div>\n</ng-template>\n\n<!-- DateTime Picker Template (Combined Date + Time) -->\n<ng-template #dateTimePickerTemplate>\n <div class=\"tw-bg-white tw-border tw-border-gray-300 tw-rounded-lg tw-shadow-lg tw-p-4\">\n <!-- DateTime Picker Header -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-4\">\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_left</span>\n </button>\n\n <button type=\"button\"\n class=\"tw-text-sm tw-font-medium tw-text-gray-800 hover:tw-bg-gray-100 tw-px-3 tw-py-1 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n {{ monthNames[currentMonth] }} {{ currentYear }}\n </button>\n\n <button type=\"button\" class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextMonth()\">\n <span class=\"material-symbols-outlined tw-text-base\">chevron_right</span>\n </button>\n </div>\n\n <div class=\"tw-grid tw-grid-cols-2 tw-gap-4\">\n <!-- Left Side: Calendar -->\n <div>\n <!-- Month/Year Selector -->\n @if (showMonthYearSelector) {\n <div class=\"tw-mb-4\">\n <!-- Year Navigation -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-3\">\n <button type=\"button\"\n class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"previousYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_left</span>\n </button>\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-800\">{{ currentYear }}</span>\n <button type=\"button\"\n class=\"tw-p-1 tw-rounded-md tw-text-gray-600 hover:tw-bg-gray-100 tw-transition-colors\"\n (click)=\"nextYear()\">\n <span class=\"material-symbols-outlined tw-text-base\">keyboard_double_arrow_right</span>\n </button>\n </div>\n\n <!-- Month Grid -->\n <div class=\"tw-grid tw-grid-cols-3 tw-gap-2 tw-mb-3\">\n @for (monthName of shortMonthNames; track $index) {\n <button type=\"button\" class=\"tw-px-2 tw-py-1.5 tw-text-xs tw-rounded-md tw-transition-colors tw-text-center\"\n [class.tw-bg-blue-500]=\"$index === currentMonth\" [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\" [class.hover:tw-bg-blue-50]=\"$index !== currentMonth\"\n (click)=\"selectMonth($index)\">\n {{ monthName }}\n </button>\n }\n </div>\n\n <!-- Back to Calendar Button -->\n <div class=\"tw-text-center\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-text-blue-600 hover:tw-bg-blue-50 tw-rounded-md tw-transition-colors\"\n (click)=\"toggleMonthYearSelector()\">\n Back to Calendar\n </button>\n </div>\n </div>\n } @else {\n <!-- Calendar View -->\n <div>\n <!-- Days of Week Header -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1 tw-mb-2\">\n @for (dayName of ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']; track dayName) {\n <div class=\"tw-text-center tw-text-xs tw-font-medium tw-text-gray-500 tw-py-1\">\n {{ dayName }}\n </div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"tw-grid tw-grid-cols-7 tw-gap-1\">\n @for (dayInfo of calendarDays; track dayInfo.date.getTime()) {\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-text-xs tw-rounded-md tw-transition-colors tw-flex tw-items-center tw-justify-center\"\n [class.tw-text-gray-400]=\"!dayInfo.isCurrentMonth\" [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\" [class.tw-text-white]=\"dayInfo.isSelected\"\n [class.tw-bg-blue-100]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.tw-text-blue-800]=\"dayInfo.isToday && !dayInfo.isSelected\"\n [class.hover:tw-bg-blue-50]=\"dayInfo.isCurrentMonth && !dayInfo.isSelected\"\n (click)=\"selectDateTimeDate(dayInfo)\">\n {{ dayInfo.day }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Right Side: Time Picker -->\n <div class=\"tw-border-l tw-border-gray-200 tw-pl-4\">\n <div class=\"tw-text-center tw-mb-2\">\n <h4 class=\"tw-text-sm tw-font-semibold tw-text-gray-800 tw-m-0\">Time</h4>\n </div>\n\n <!-- Time Spinners -->\n <div class=\"tw-flex tw-items-center tw-justify-center tw-gap-2 tw-mb-3\">\n <!-- Hours -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'up')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_less</span>\n </button>\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-10 tw-text-center\">\n {{ timeHours }}\n </div>\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('hours', 'down')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">hour</span>\n </div>\n\n <!-- Colon -->\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-mb-3\">:</div>\n\n <!-- Minutes -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'up')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_less</span>\n </button>\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-10 tw-text-center\">\n {{ timeMinutes.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('minutes', 'down')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">min</span>\n </div>\n\n <!-- Colon -->\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-mb-3\">:</div>\n\n <!-- Seconds -->\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'up')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_less</span>\n </button>\n <div class=\"tw-text-xl tw-font-medium tw-text-gray-800 tw-my-1 tw-w-10 tw-text-center\">\n {{ timeSeconds.toString().padStart(2, '0') }}\n </div>\n <button type=\"button\"\n class=\"tw-w-7 tw-h-7 tw-flex tw-items-center tw-justify-center tw-rounded-full tw-text-gray-500 hover:tw-bg-gray-100 tw-transition-colors tw-border-0 tw-bg-white\"\n (click)=\"adjustTime('seconds', 'down')\">\n <span class=\"material-symbols-outlined tw-text-base\">expand_more</span>\n </button>\n <span class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">sec</span>\n </div>\n </div>\n\n <!-- AM/PM Toggle -->\n <div class=\"tw-flex tw-justify-center tw-mb-2\">\n <div class=\"tw-inline-flex tw-rounded-md tw-bg-gray-100 tw-p-0.5\">\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'AM'\" [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'AM'\" [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button type=\"button\"\n class=\"tw-px-3 tw-py-1 tw-text-xs tw-font-medium tw-rounded-md tw-transition-colors tw-border-0\"\n [class.tw-bg-white]=\"timeFormat === 'PM'\" [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'PM'\" [class.tw-text-gray-600]=\"timeFormat !== 'PM'\"\n (click)=\"timeFormat = 'PM'\">\n PM\n </button>\n </div>\n </div>\n\n <!-- Current Time Display -->\n <div class=\"tw-text-center tw-text-xs tw-text-gray-600\">\n {{ timeHours }}:{{ timeMinutes.toString().padStart(2, '0') }}:{{ timeSeconds.toString().padStart(2, '0') }} {{\n timeFormat }}\n </div>\n </div>\n </div>\n\n <!-- DateTime Picker Footer -->\n <div class=\"tw-flex tw-gap-2 tw-mt-3 tw-pt-2 tw-border-t tw-border-gray-200\">\n <button type=\"button\"\n class=\"tw-px-2 tw-py-1 tw-text-xs tw-font-medium tw-text-blue-600 tw-bg-white tw-border tw-border-blue-300 hover:tw-bg-blue-50 tw-rounded tw-transition-colors\"\n (click)=\"setCurrentDateTime()\">\n Now\n </button>\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-2 tw-py-1 tw-text-xs tw-font-medium tw-text-gray-700 tw-bg-white tw-border tw-border-gray-300 hover:tw-bg-gray-50 tw-rounded tw-transition-colors\"\n (click)=\"closeDateTimePicker()\">\n Cancel\n </button>\n <button type=\"button\"\n class=\"tw-flex-1 tw-px-2 tw-py-1 tw-text-xs tw-font-medium tw-text-white tw-bg-blue-600 hover:tw-bg-blue-700 tw-rounded tw-transition-colors tw-border-0\"\n (click)=\"applyDateTime()\">\n OK\n </button>\n </div>\n </div>\n</ng-template>", styles: ["input[type=date]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}input[type=date]::-webkit-inner-spin-button,input[type=date]::-webkit-outer-spin-button{display:none;-webkit-appearance:none}input[type=date]{-moz-appearance:textfield}input[type=date]::-webkit-datetime-edit,input[type=date]::-webkit-datetime-edit-fields-wrapper{padding:0;background:transparent}input[type=date]::-webkit-datetime-edit-text{color:transparent;background:transparent}input[type=date]{background:transparent!important;border:none!important;outline:none!important}.cide-input-date-wrapper{position:relative;width:100%}.cide-input-date-overlay{position:absolute;inset:0;pointer-events:none;display:flex;align-items:center;padding-left:.25rem;color:var(--tw-gray-500)}.cide-input-date-has-value .cide-input-date-overlay{display:none}.cide-date-picker-panel{min-width:320px;max-width:400px;z-index:1000}.cide-date-picker-panel{animation:datePickerFadeIn .2s ease-out}@keyframes datePickerFadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.cide-date-picker-panel button:disabled{opacity:.5;cursor:not-allowed}.cide-date-picker-panel button:focus{outline:2px solid rgb(59,130,246);outline-offset:2px}.cide-date-picker-panel button:hover:not(:disabled){transform:scale(1.05);transition:transform .1s ease-in-out}.cide-date-picker-panel button.today:not(.selected){box-shadow:0 0 0 1px #3b82f6}.cide-date-picker-panel button.selected{box-shadow:0 2px 4px #3b82f64d;font-weight:600}.cide-date-picker-panel .nav-button{transition:all .2s ease-in-out}.cide-date-picker-panel .nav-button:hover{background-color:var(--tw-gray-200);transform:scale(1.1)}.cide-date-picker-panel h3{-webkit-user-select:none;user-select:none;transition:color .2s ease-in-out}.cide-date-picker-panel .days-header{border-bottom:1px solid var(--tw-gray-200);margin-bottom:.5rem;padding-bottom:.5rem}.cide-date-picker-portal{box-shadow:0 10px 25px -5px #0000001a,0 10px 10px -5px #0000000a;border-radius:.5rem;background:var(--cide-ele-bg-primary, #ffffff);border:1px solid var(--cide-ele-border-primary, #e5e7eb);z-index:9999;transition:opacity .2s ease-in-out,transform .2s ease-in-out;color:var(--cide-ele-text-primary, #1f2937)}.cide-date-picker-portal{animation:portalFadeIn .2s ease-out}@keyframes portalFadeIn{0%{opacity:0;transform:translateY(-8px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.cide-date-picker-portal.cide-portal{position:fixed!important;z-index:9999!important}input[type=time]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}input[type=time]::-webkit-inner-spin-button,input[type=time]::-webkit-outer-spin-button{display:none;-webkit-appearance:none}input[type=time]{-moz-appearance:textfield}input[type=time]::-webkit-datetime-edit,input[type=time]::-webkit-datetime-edit-fields-wrapper{padding:0;background:transparent}input[type=time]::-webkit-datetime-edit-text{color:transparent;background:transparent}input[type=time]{background:transparent!important;border:none!important;outline:none!important}.cide-time-picker-portal{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;border-radius:1rem;background:var(--cide-theme-light-color);border:1px solid var(--tw-gray-200);z-index:9999;transition:opacity .2s ease-in-out,transform .2s ease-in-out;animation:portalFadeIn .2s ease-out;color:var(--cide-theme-text-color)}.cide-time-picker-portal.cide-portal{position:fixed!important;z-index:9999!important}input[type=datetime-local]::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none}input[type=datetime-local]::-webkit-inner-spin-button,input[type=datetime-local]::-webkit-outer-spin-button{display:none;-webkit-appearance:none}input[type=datetime-local]{-moz-appearance:textfield}input[type=datetime-local]::-webkit-datetime-edit,input[type=datetime-local]::-webkit-datetime-edit-fields-wrapper{padding:0;background:transparent}input[type=datetime-local]::-webkit-datetime-edit-text{color:transparent;background:transparent}input[type=datetime-local]{background:transparent!important;border:none!important;outline:none!important}.cide-datetime-picker-portal{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;border-radius:1rem;background:var(--cide-theme-light-color);border:1px solid var(--tw-gray-200);z-index:9999;transition:opacity .2s ease-in-out,transform .2s ease-in-out;animation:portalFadeIn .2s ease-out;color:var(--cide-theme-text-color)}.cide-datetime-picker-portal.cide-portal{position:fixed!important;z-index:9999!important}\n"] }]
|
|
1751
1800
|
}], ctorParameters: () => [], propDecorators: { fill: [{
|
|
1752
1801
|
type: Input
|
|
1753
1802
|
}], label: [{
|
|
@@ -1939,20 +1988,16 @@ class CideSelectComponent {
|
|
|
1939
1988
|
if (opts && opts.length >= 0) {
|
|
1940
1989
|
this.filterOptions();
|
|
1941
1990
|
// Update portal context if dropdown is open
|
|
1942
|
-
if (this.isOpen && this.
|
|
1943
|
-
|
|
1944
|
-
this.updatePortalContext();
|
|
1945
|
-
}, 0);
|
|
1991
|
+
if (this.isOpen && this.portalContext) {
|
|
1992
|
+
this.portalContext.options = this.filteredOptions;
|
|
1946
1993
|
}
|
|
1947
1994
|
}
|
|
1948
1995
|
});
|
|
1949
1996
|
// Watch for loading changes
|
|
1950
1997
|
effect(() => {
|
|
1951
1998
|
const loading = this.loading();
|
|
1952
|
-
if (this.isOpen && this.
|
|
1953
|
-
|
|
1954
|
-
this.updatePortalContext();
|
|
1955
|
-
}, 0);
|
|
1999
|
+
if (this.isOpen && this.portalContext) {
|
|
2000
|
+
this.portalContext.loading = loading;
|
|
1956
2001
|
}
|
|
1957
2002
|
});
|
|
1958
2003
|
}
|
|
@@ -2113,6 +2158,8 @@ class CideSelectComponent {
|
|
|
2113
2158
|
window.removeEventListener('resize', this.onWindowResize.bind(this));
|
|
2114
2159
|
this.logDebug('Component destroyed, timeouts cleared');
|
|
2115
2160
|
}
|
|
2161
|
+
// Portal context property
|
|
2162
|
+
portalContext = {};
|
|
2116
2163
|
createDropdownPortal() {
|
|
2117
2164
|
try {
|
|
2118
2165
|
const triggerElement = this.elementRef?.nativeElement;
|
|
@@ -2127,25 +2174,27 @@ class CideSelectComponent {
|
|
|
2127
2174
|
// Generate unique portal ID
|
|
2128
2175
|
this.dropdownPortalId = `select-dropdown-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
2129
2176
|
console.log('🔍 Creating new portal with ID:', this.dropdownPortalId);
|
|
2177
|
+
// Initialize shared context object
|
|
2178
|
+
this.portalContext = {
|
|
2179
|
+
options: this.filteredOptions,
|
|
2180
|
+
isOpen: this.isOpen,
|
|
2181
|
+
searchTerm: this.searchTerm,
|
|
2182
|
+
searchable: this.searchable(),
|
|
2183
|
+
multiple: this.multiple(),
|
|
2184
|
+
loading: this.loading(),
|
|
2185
|
+
dropdownPosition: this.dropdownPosition,
|
|
2186
|
+
treeView: this.treeView(),
|
|
2187
|
+
onSearchInput: this.onSearchInput.bind(this),
|
|
2188
|
+
selectOption: this.selectOption.bind(this),
|
|
2189
|
+
isOptionSelected: this.isOptionSelected.bind(this),
|
|
2190
|
+
trackByValue: this.trackByValue.bind(this),
|
|
2191
|
+
getOptionLabel: this.getOptionLabel.bind(this)
|
|
2192
|
+
};
|
|
2130
2193
|
const portalConfig = {
|
|
2131
2194
|
triggerElement,
|
|
2132
2195
|
template: this.dropdownTemplate,
|
|
2133
2196
|
viewContainerRef: this.dropdownContainer,
|
|
2134
|
-
context:
|
|
2135
|
-
options: this.filteredOptions,
|
|
2136
|
-
isOpen: this.isOpen,
|
|
2137
|
-
searchTerm: this.searchTerm,
|
|
2138
|
-
searchable: this.searchable(),
|
|
2139
|
-
multiple: this.multiple(),
|
|
2140
|
-
loading: this.loading(),
|
|
2141
|
-
dropdownPosition: this.dropdownPosition,
|
|
2142
|
-
treeView: this.treeView(),
|
|
2143
|
-
onSearchInput: this.onSearchInput.bind(this),
|
|
2144
|
-
selectOption: this.selectOption.bind(this),
|
|
2145
|
-
isOptionSelected: this.isOptionSelected.bind(this),
|
|
2146
|
-
trackByValue: this.trackByValue.bind(this),
|
|
2147
|
-
getOptionLabel: this.getOptionLabel.bind(this)
|
|
2148
|
-
},
|
|
2197
|
+
context: this.portalContext, // Pass the reference
|
|
2149
2198
|
className: 'cide-select-dropdown-portal',
|
|
2150
2199
|
position: this.dropdownPosition,
|
|
2151
2200
|
align: 'left',
|
|
@@ -2189,165 +2238,6 @@ class CideSelectComponent {
|
|
|
2189
2238
|
console.error(`💥 SELECT [${this.debugId}] destroyDropdownPortal error:`, error);
|
|
2190
2239
|
}
|
|
2191
2240
|
}
|
|
2192
|
-
updatePortalContext() {
|
|
2193
|
-
try {
|
|
2194
|
-
if (!this.dropdownPortalId) {
|
|
2195
|
-
return; // Portal not created yet
|
|
2196
|
-
}
|
|
2197
|
-
// Set flag to prevent blur during update
|
|
2198
|
-
this.isUpdatingOptions = true;
|
|
2199
|
-
// Store reference to search input before destroying portal
|
|
2200
|
-
console.log('🔍 Looking for search input with portal ID:', this.dropdownPortalId);
|
|
2201
|
-
const searchInput = document.querySelector(`#${this.dropdownPortalId} input[type="text"]`);
|
|
2202
|
-
console.log('🔍 searchInput found:', searchInput);
|
|
2203
|
-
// Try alternative selectors if the first one fails
|
|
2204
|
-
let searchInputAlt = null;
|
|
2205
|
-
if (!searchInput) {
|
|
2206
|
-
searchInputAlt = document.querySelector(`[id*="${this.dropdownPortalId}"] input[type="text"]`);
|
|
2207
|
-
console.log('🔍 searchInputAlt found:', searchInputAlt);
|
|
2208
|
-
}
|
|
2209
|
-
const finalSearchInput = searchInput || searchInputAlt;
|
|
2210
|
-
const wasSearchInputFocused = finalSearchInput && document.activeElement === finalSearchInput;
|
|
2211
|
-
const searchInputValue = finalSearchInput ? finalSearchInput.value : '';
|
|
2212
|
-
const cursorPosition = finalSearchInput ? finalSearchInput.selectionStart || 0 : 0;
|
|
2213
|
-
// Since the portal service doesn't have an update context method,
|
|
2214
|
-
// we need to recreate the portal with updated context
|
|
2215
|
-
this.destroyDropdownPortal();
|
|
2216
|
-
this.createDropdownPortal();
|
|
2217
|
-
// Restore focus and value to search input after recreation
|
|
2218
|
-
if (wasSearchInputFocused && searchInputValue) {
|
|
2219
|
-
// Use multiple timing strategies to ensure focus restoration works
|
|
2220
|
-
const restoreFocus = () => {
|
|
2221
|
-
let newSearchInput = document.querySelector(`#${this.dropdownPortalId} input[type="text"]`);
|
|
2222
|
-
console.log('🔍 newSearchInput', newSearchInput);
|
|
2223
|
-
// Try alternative selectors if the first one fails
|
|
2224
|
-
if (!newSearchInput) {
|
|
2225
|
-
newSearchInput = document.querySelector(`[id*="${this.dropdownPortalId}"] input[type="text"]`);
|
|
2226
|
-
console.log('🔍 newSearchInputAlt', newSearchInput);
|
|
2227
|
-
}
|
|
2228
|
-
if (newSearchInput) {
|
|
2229
|
-
newSearchInput.value = searchInputValue;
|
|
2230
|
-
newSearchInput.focus();
|
|
2231
|
-
// Set cursor position to the original position
|
|
2232
|
-
newSearchInput.setSelectionRange(cursorPosition, cursorPosition);
|
|
2233
|
-
return true;
|
|
2234
|
-
}
|
|
2235
|
-
return false;
|
|
2236
|
-
};
|
|
2237
|
-
// Try immediate restoration
|
|
2238
|
-
if (!restoreFocus()) {
|
|
2239
|
-
// Try with requestAnimationFrame
|
|
2240
|
-
requestAnimationFrame(() => {
|
|
2241
|
-
if (!restoreFocus()) {
|
|
2242
|
-
// Try with setTimeout as fallback
|
|
2243
|
-
setTimeout(() => {
|
|
2244
|
-
restoreFocus();
|
|
2245
|
-
// Clear the flag after restoration
|
|
2246
|
-
this.isUpdatingOptions = false;
|
|
2247
|
-
}, 10);
|
|
2248
|
-
}
|
|
2249
|
-
else {
|
|
2250
|
-
// Clear the flag after successful restoration
|
|
2251
|
-
this.isUpdatingOptions = false;
|
|
2252
|
-
}
|
|
2253
|
-
});
|
|
2254
|
-
}
|
|
2255
|
-
else {
|
|
2256
|
-
// Clear the flag after successful restoration
|
|
2257
|
-
this.isUpdatingOptions = false;
|
|
2258
|
-
}
|
|
2259
|
-
}
|
|
2260
|
-
else {
|
|
2261
|
-
// Clear the flag if no focus restoration needed
|
|
2262
|
-
this.isUpdatingOptions = false;
|
|
2263
|
-
}
|
|
2264
|
-
this.logDebug('Portal context updated', {
|
|
2265
|
-
filteredOptionsCount: this.filteredOptions.length,
|
|
2266
|
-
searchTerm: this.searchTerm
|
|
2267
|
-
});
|
|
2268
|
-
}
|
|
2269
|
-
catch (error) {
|
|
2270
|
-
console.error(`💥 SELECT [${this.debugId}] updatePortalContext error:`, error);
|
|
2271
|
-
this.isUpdatingOptions = false;
|
|
2272
|
-
}
|
|
2273
|
-
}
|
|
2274
|
-
updateOptionsInDOM() {
|
|
2275
|
-
try {
|
|
2276
|
-
if (!this.dropdownPortalId) {
|
|
2277
|
-
return false; // Portal not created yet
|
|
2278
|
-
}
|
|
2279
|
-
// Find the options container in the DOM
|
|
2280
|
-
console.log('🔍 Looking for options container with portal ID:', this.dropdownPortalId);
|
|
2281
|
-
let optionsContainer = document.querySelector(`#${this.dropdownPortalId} .tw-py-1`);
|
|
2282
|
-
console.log('🔍 optionsContainer (.tw-py-1):', optionsContainer);
|
|
2283
|
-
// Try alternative selectors if the first one fails
|
|
2284
|
-
if (!optionsContainer) {
|
|
2285
|
-
optionsContainer = document.querySelector(`#${this.dropdownPortalId}`);
|
|
2286
|
-
console.log('🔍 optionsContainer (main):', optionsContainer);
|
|
2287
|
-
}
|
|
2288
|
-
if (!optionsContainer) {
|
|
2289
|
-
optionsContainer = document.querySelector(`[id*="${this.dropdownPortalId}"] .tw-py-1`);
|
|
2290
|
-
console.log('🔍 optionsContainer (alt .tw-py-1):', optionsContainer);
|
|
2291
|
-
}
|
|
2292
|
-
if (!optionsContainer) {
|
|
2293
|
-
optionsContainer = document.querySelector(`[id*="${this.dropdownPortalId}"]`);
|
|
2294
|
-
console.log('🔍 optionsContainer (alt main):', optionsContainer);
|
|
2295
|
-
}
|
|
2296
|
-
if (!optionsContainer) {
|
|
2297
|
-
console.log('🔍 No options container found, returning false');
|
|
2298
|
-
return false;
|
|
2299
|
-
}
|
|
2300
|
-
console.log('🔍 optionsContainer found, clearing and updating with', this.filteredOptions.length, 'options');
|
|
2301
|
-
console.log('🔍 Current optionsContainer HTML before clear:', optionsContainer.innerHTML);
|
|
2302
|
-
// Find and clear only the option buttons and loading states, not the entire container
|
|
2303
|
-
const existingOptions = optionsContainer.querySelectorAll('.cide-select-option, .tw-px-3.tw-py-2, .tw-px-3.tw-py-4');
|
|
2304
|
-
console.log('🔍 Found existing options to remove:', existingOptions.length);
|
|
2305
|
-
existingOptions.forEach(option => option.remove());
|
|
2306
|
-
// Add filtered options directly to DOM
|
|
2307
|
-
this.filteredOptions.forEach((option) => {
|
|
2308
|
-
const button = document.createElement('button');
|
|
2309
|
-
button.type = 'button';
|
|
2310
|
-
button.className = `cide-select-option tw-w-full tw-text-left tw-px-3 tw-py-2 tw-text-sm tw-cursor-pointer tw-transition-colors hover:tw-bg-gray-100 tw-border-none tw-bg-transparent tw-outline-none ${this.isOptionSelected(option) ? 'tw-bg-blue-50 tw-text-blue-700' : ''} ${option.disabled ? 'tw-text-gray-400 tw-cursor-not-allowed' : ''}`;
|
|
2311
|
-
button.textContent = this.getOptionLabel(option);
|
|
2312
|
-
button.disabled = option.disabled || false;
|
|
2313
|
-
// Add event listeners
|
|
2314
|
-
button.addEventListener('mousedown', (e) => {
|
|
2315
|
-
e.preventDefault(); // Prevent blur from closing dropdown before click
|
|
2316
|
-
this.onDropdownMouseDown();
|
|
2317
|
-
});
|
|
2318
|
-
button.addEventListener('click', (e) => {
|
|
2319
|
-
e.preventDefault();
|
|
2320
|
-
e.stopPropagation();
|
|
2321
|
-
this.selectOption(option);
|
|
2322
|
-
});
|
|
2323
|
-
button.addEventListener('keyup', (e) => {
|
|
2324
|
-
if (e.key === 'Enter' || e.key === ' ') {
|
|
2325
|
-
e.preventDefault();
|
|
2326
|
-
this.selectOption(option);
|
|
2327
|
-
}
|
|
2328
|
-
});
|
|
2329
|
-
optionsContainer.appendChild(button);
|
|
2330
|
-
});
|
|
2331
|
-
// Add "No options" message if no options
|
|
2332
|
-
if (this.filteredOptions.length === 0) {
|
|
2333
|
-
const noOptionsDiv = document.createElement('div');
|
|
2334
|
-
noOptionsDiv.className = 'tw-px-3 tw-py-2 tw-text-sm tw-text-gray-500 tw-italic';
|
|
2335
|
-
noOptionsDiv.textContent = this.searchable() && this.searchTerm ? 'No options found' : 'No options available';
|
|
2336
|
-
optionsContainer.appendChild(noOptionsDiv);
|
|
2337
|
-
}
|
|
2338
|
-
console.log('🔍 Options added, final optionsContainer HTML:', optionsContainer.innerHTML);
|
|
2339
|
-
console.log('🔍 Number of child elements in optionsContainer:', optionsContainer.children.length);
|
|
2340
|
-
this.logDebug('Options updated directly in DOM', {
|
|
2341
|
-
filteredOptionsCount: this.filteredOptions.length,
|
|
2342
|
-
searchTerm: this.searchTerm
|
|
2343
|
-
});
|
|
2344
|
-
return true; // Success
|
|
2345
|
-
}
|
|
2346
|
-
catch (error) {
|
|
2347
|
-
console.error(`💥 SELECT [${this.debugId}] updateOptionsInDOM error:`, error);
|
|
2348
|
-
return false; // Failed
|
|
2349
|
-
}
|
|
2350
|
-
}
|
|
2351
2241
|
setupDebouncedSearch() {
|
|
2352
2242
|
this.searchSubject
|
|
2353
2243
|
.pipe(debounceTime(300), // 300ms debounce
|
|
@@ -2789,17 +2679,26 @@ class CideSelectComponent {
|
|
|
2789
2679
|
this.searchTerm = event.target.value;
|
|
2790
2680
|
console.log(`🔍 SELECT [${this.debugId}] Search input changed:`, `"${this.searchTerm}"`);
|
|
2791
2681
|
// If search term is empty, emit immediately without debounce
|
|
2682
|
+
// If search term is empty, emit immediately without debounce
|
|
2792
2683
|
if (this.searchTerm === '' || this.searchTerm === null || this.searchTerm === undefined) {
|
|
2793
2684
|
console.log(`🔍 SELECT [${this.debugId}] Empty search - emitting immediately`);
|
|
2794
2685
|
// Update local filtering immediately
|
|
2795
2686
|
this.filterOptions();
|
|
2796
|
-
|
|
2687
|
+
// Update context properties directly
|
|
2688
|
+
if (this.portalContext) {
|
|
2689
|
+
this.portalContext.searchTerm = this.searchTerm;
|
|
2690
|
+
this.portalContext.options = this.filteredOptions;
|
|
2691
|
+
}
|
|
2797
2692
|
this.performSearch('');
|
|
2798
2693
|
}
|
|
2799
2694
|
else {
|
|
2800
2695
|
// Update local filtering immediately for better UX
|
|
2801
2696
|
this.filterOptions();
|
|
2802
|
-
|
|
2697
|
+
// Update context properties directly
|
|
2698
|
+
if (this.portalContext) {
|
|
2699
|
+
this.portalContext.searchTerm = this.searchTerm;
|
|
2700
|
+
this.portalContext.options = this.filteredOptions;
|
|
2701
|
+
}
|
|
2803
2702
|
// For non-empty values, use debounced search for API calls
|
|
2804
2703
|
this.searchSubject.next(this.searchTerm);
|
|
2805
2704
|
}
|