cloud-ide-element 1.1.105 → 1.1.113
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.
|
@@ -1505,7 +1505,20 @@ class CideInputComponent {
|
|
|
1505
1505
|
if (this.ngModel) {
|
|
1506
1506
|
// Parse existing datetime value
|
|
1507
1507
|
const dateTimeString = this.ngModel.toString();
|
|
1508
|
-
|
|
1508
|
+
// Parse datetime string - handle both local format (YYYY-MM-DDTHH:mm:ss) and ISO format
|
|
1509
|
+
let dateTime;
|
|
1510
|
+
// Check if it's in local format (no timezone indicator)
|
|
1511
|
+
if (dateTimeString.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?$/)) {
|
|
1512
|
+
// Parse as local time (YYYY-MM-DDTHH:mm:ss)
|
|
1513
|
+
const [datePart, timePart] = dateTimeString.split('T');
|
|
1514
|
+
const [year, month, day] = datePart.split('-').map(Number);
|
|
1515
|
+
const [hour, minute, second = 0] = timePart.split(':').map(Number);
|
|
1516
|
+
dateTime = new Date(year, month - 1, day, hour, minute, second);
|
|
1517
|
+
}
|
|
1518
|
+
else {
|
|
1519
|
+
// Try parsing as ISO string or other format
|
|
1520
|
+
dateTime = new Date(dateTimeString);
|
|
1521
|
+
}
|
|
1509
1522
|
if (!isNaN(dateTime.getTime())) {
|
|
1510
1523
|
// Initialize date picker values
|
|
1511
1524
|
this.selectedDate = dateTime;
|
|
@@ -1597,8 +1610,16 @@ class CideInputComponent {
|
|
|
1597
1610
|
// Combine date and time
|
|
1598
1611
|
const dateTime = new Date(this.selectedDate);
|
|
1599
1612
|
dateTime.setHours(hours, this.timeMinutes, this.timeSeconds);
|
|
1600
|
-
// Format as datetime-local string (YYYY-MM-DDTHH:mm
|
|
1601
|
-
|
|
1613
|
+
// Format as datetime-local string (YYYY-MM-DDTHH:mm) in LOCAL time, not UTC
|
|
1614
|
+
// This prevents timezone conversion issues
|
|
1615
|
+
const year = dateTime.getFullYear();
|
|
1616
|
+
const month = String(dateTime.getMonth() + 1).padStart(2, '0');
|
|
1617
|
+
const day = String(dateTime.getDate()).padStart(2, '0');
|
|
1618
|
+
const hour = String(dateTime.getHours()).padStart(2, '0');
|
|
1619
|
+
const minute = String(dateTime.getMinutes()).padStart(2, '0');
|
|
1620
|
+
const second = String(dateTime.getSeconds()).padStart(2, '0');
|
|
1621
|
+
// Format: YYYY-MM-DDTHH:mm:ss (local time, no timezone)
|
|
1622
|
+
const dateTimeString = `${year}-${month}-${day}T${hour}:${minute}:${second}`;
|
|
1602
1623
|
this.ngModel = dateTimeString;
|
|
1603
1624
|
this.ngModelChange.emit(dateTimeString);
|
|
1604
1625
|
this.onChange(dateTimeString);
|
|
@@ -1614,9 +1635,23 @@ class CideInputComponent {
|
|
|
1614
1635
|
getDateTimeDisplayValue() {
|
|
1615
1636
|
if (!this.ngModel)
|
|
1616
1637
|
return '';
|
|
1617
|
-
const
|
|
1638
|
+
const dateTimeString = this.ngModel.toString();
|
|
1639
|
+
// Parse datetime string - handle both local format (YYYY-MM-DDTHH:mm:ss) and ISO format
|
|
1640
|
+
let dateTime;
|
|
1641
|
+
// Check if it's in local format (no timezone indicator)
|
|
1642
|
+
if (dateTimeString.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?$/)) {
|
|
1643
|
+
// Parse as local time (YYYY-MM-DDTHH:mm:ss)
|
|
1644
|
+
const [datePart, timePart] = dateTimeString.split('T');
|
|
1645
|
+
const [year, month, day] = datePart.split('-').map(Number);
|
|
1646
|
+
const [hour, minute, second = 0] = timePart.split(':').map(Number);
|
|
1647
|
+
dateTime = new Date(year, month - 1, day, hour, minute, second);
|
|
1648
|
+
}
|
|
1649
|
+
else {
|
|
1650
|
+
// Try parsing as ISO string or other format
|
|
1651
|
+
dateTime = new Date(dateTimeString);
|
|
1652
|
+
}
|
|
1618
1653
|
if (isNaN(dateTime.getTime()))
|
|
1619
|
-
return
|
|
1654
|
+
return dateTimeString;
|
|
1620
1655
|
// Format: MMM DD, YYYY HH:mm AM/PM
|
|
1621
1656
|
const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
1622
1657
|
const month = monthNames[dateTime.getMonth()];
|
|
@@ -1637,6 +1672,23 @@ class CideInputComponent {
|
|
|
1637
1672
|
this.portalService.destroyPortal(this.dateTimePickerPortalId);
|
|
1638
1673
|
this.createDateTimePickerUsingPortal();
|
|
1639
1674
|
}
|
|
1675
|
+
/**
|
|
1676
|
+
* @description Set current date and time (Now button)
|
|
1677
|
+
*/
|
|
1678
|
+
setCurrentDateTime() {
|
|
1679
|
+
const now = new Date();
|
|
1680
|
+
// Set date
|
|
1681
|
+
this.selectedDate = now;
|
|
1682
|
+
this.currentMonth = now.getMonth();
|
|
1683
|
+
this.currentYear = now.getFullYear();
|
|
1684
|
+
this.generateCalendar();
|
|
1685
|
+
// Set time
|
|
1686
|
+
let hours = now.getHours();
|
|
1687
|
+
this.timeFormat = hours >= 12 ? 'PM' : 'AM';
|
|
1688
|
+
this.timeHours = hours === 0 ? 12 : (hours > 12 ? hours - 12 : hours);
|
|
1689
|
+
this.timeMinutes = now.getMinutes();
|
|
1690
|
+
this.timeSeconds = now.getSeconds();
|
|
1691
|
+
}
|
|
1640
1692
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1641
1693
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideInputComponent, isStandalone: true, selector: "cide-ele-input", inputs: { fill: "fill", label: "label", labelHide: "labelHide", disabled: "disabled", clearInput: "clearInput", labelPlacement: "labelPlacement", labelDir: "labelDir", placeholder: "placeholder", leadingIcon: "leadingIcon", trailingIcon: "trailingIcon", helperText: "helperText", helperTextCollapse: "helperTextCollapse", hideHelperAndErrorText: "hideHelperAndErrorText", errorText: "errorText", maxlength: "maxlength", minlength: "minlength", required: "required", autocapitalize: "autocapitalize", autocomplete: "autocomplete", type: "type", width: "width", id: "id", ngModel: "ngModel", option: "option", min: "min", max: "max", step: "step", size: "size" }, outputs: { ngModelChange: "ngModelChange" }, providers: [
|
|
1642
1694
|
{
|
|
@@ -1651,7 +1703,7 @@ class CideInputComponent {
|
|
|
1651
1703
|
useExisting: forwardRef(() => CideInputComponent),
|
|
1652
1704
|
},
|
|
1653
1705
|
CapitalizePipe
|
|
1654
|
-
], 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 === '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\n 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\"\n [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 }\"\n [value]=\"getDateDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\" (click)=\"trailingIconClick()\"\n [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 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\"\n [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 }\"\n [value]=\"getTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\" (click)=\"trailingIconClick()\"\n [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\"\n [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 }\"\n [value]=\"getDateTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\" (click)=\"trailingIconClick()\"\n [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\"\n [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 }\"\n [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\" (focus)=\"focusControl()\"\n [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\"\n [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 }\"\n [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\" (focus)=\"focusControl()\"\n [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 \n type=\"button\" \n 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 \n 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 \n type=\"button\" \n 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 \n 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 \n 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 \n type=\"button\"\n 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\"\n [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\"\n [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 \n 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 \n 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\"\n [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\"\n [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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow]=\"timeFormat === 'AM'\"\n [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow]=\"timeFormat === 'PM'\"\n [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') }} {{ timeFormat }}\n </span>\n </div>\n\n <!-- Time Picker Footer -->\n <div class=\"tw-flex tw-gap-2\">\n <button \n 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 \n 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 \n type=\"button\" \n 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 \n 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 \n type=\"button\" \n 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 \n 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 \n 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 \n type=\"button\"\n 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\"\n [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\"\n [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 \n 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 \n 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\"\n [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\"\n [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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'AM'\"\n [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'PM'\"\n [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') }} {{ 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 \n 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 \n 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:
|
|
1706
|
+
], 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 === '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\n 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\"\n [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 }\"\n [value]=\"getDateDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\" (click)=\"trailingIconClick()\"\n [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 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\"\n [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 }\"\n [value]=\"getTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\" (click)=\"trailingIconClick()\"\n [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\"\n [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 }\"\n [value]=\"getDateTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\" (click)=\"trailingIconClick()\"\n [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\"\n [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 }\"\n [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\" (focus)=\"focusControl()\"\n [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\"\n [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 }\"\n [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\" (focus)=\"focusControl()\"\n [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 \n type=\"button\" \n 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 \n 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 \n type=\"button\" \n 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 \n 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 \n 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 \n type=\"button\"\n 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\"\n [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\"\n [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 \n 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 \n 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\"\n [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\"\n [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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow]=\"timeFormat === 'AM'\"\n [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow]=\"timeFormat === 'PM'\"\n [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') }} {{ timeFormat }}\n </span>\n </div>\n\n <!-- Time Picker Footer -->\n <div class=\"tw-flex tw-gap-2\">\n <button \n 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 \n 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 \n type=\"button\" \n 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 \n 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 \n type=\"button\" \n 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 \n 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 \n 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 \n type=\"button\"\n 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\"\n [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\"\n [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 \n 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 \n 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\"\n [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\"\n [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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'AM'\"\n [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'PM'\"\n [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') }} {{ 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 \n 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 \n 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 \n 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:
|
|
1655
1707
|
// directives
|
|
1656
1708
|
CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type:
|
|
1657
1709
|
// for ngModel
|
|
@@ -1677,7 +1729,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
|
|
|
1677
1729
|
useExisting: forwardRef(() => CideInputComponent),
|
|
1678
1730
|
},
|
|
1679
1731
|
CapitalizePipe
|
|
1680
|
-
], template: "<div class=\"cide-input\">\n <!------------------------------------------TEXT | PASSWORD | DATE | URL------------------------------------------>\n @if (type === 'text' || type === 'number' || type === 'password' || type === 'email' || type === 'tel' || type === '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\n 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\"\n [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 }\"\n [value]=\"getDateDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\" (click)=\"trailingIconClick()\"\n [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 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\"\n [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 }\"\n [value]=\"getTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\" (click)=\"trailingIconClick()\"\n [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\"\n [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 }\"\n [value]=\"getDateTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\" (click)=\"trailingIconClick()\"\n [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\"\n [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 }\"\n [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\" (focus)=\"focusControl()\"\n [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\"\n [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 }\"\n [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\" (focus)=\"focusControl()\"\n [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 \n type=\"button\" \n 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 \n 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 \n type=\"button\" \n 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 \n 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 \n 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 \n type=\"button\"\n 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\"\n [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\"\n [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 \n 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 \n 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\"\n [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\"\n [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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow]=\"timeFormat === 'AM'\"\n [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow]=\"timeFormat === 'PM'\"\n [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') }} {{ timeFormat }}\n </span>\n </div>\n\n <!-- Time Picker Footer -->\n <div class=\"tw-flex tw-gap-2\">\n <button \n 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 \n 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 \n type=\"button\" \n 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 \n 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 \n type=\"button\" \n 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 \n 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 \n 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 \n type=\"button\"\n 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\"\n [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\"\n [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 \n 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 \n 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\"\n [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\"\n [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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'AM'\"\n [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'PM'\"\n [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') }} {{ 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 \n 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 \n 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"] }]
|
|
1732
|
+
], template: "<div class=\"cide-input\">\n <!------------------------------------------TEXT | PASSWORD | DATE | URL------------------------------------------>\n @if (type === 'text' || type === 'number' || type === 'password' || type === 'email' || type === 'tel' || type === '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\n 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\"\n [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 }\"\n [value]=\"getDateDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\" (click)=\"trailingIconClick()\"\n [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 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\"\n [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 }\"\n [value]=\"getTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\" (click)=\"trailingIconClick()\"\n [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\"\n [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 }\"\n [value]=\"getDateTimeDisplayValue()\" type=\"text\" readonly (focus)=\"focusControl()\" (click)=\"trailingIconClick()\"\n [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\"\n [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 }\"\n [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\" (focus)=\"focusControl()\"\n [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\"\n [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 }\"\n [(ngModel)]=\"ngModel\" [type]=\"typeInternal\" (input)=\"upDateValue($event)\" (focus)=\"focusControl()\"\n [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 \n type=\"button\" \n 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 \n 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 \n type=\"button\" \n 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 \n 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 \n 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 \n type=\"button\"\n 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\"\n [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\"\n [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 \n 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 \n 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\"\n [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\"\n [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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow]=\"timeFormat === 'AM'\"\n [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow]=\"timeFormat === 'PM'\"\n [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') }} {{ timeFormat }}\n </span>\n </div>\n\n <!-- Time Picker Footer -->\n <div class=\"tw-flex tw-gap-2\">\n <button \n 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 \n 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 \n type=\"button\" \n 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 \n 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 \n type=\"button\" \n 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 \n 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 \n 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 \n type=\"button\"\n 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\"\n [class.tw-text-white]=\"$index === currentMonth\"\n [class.tw-text-gray-700]=\"$index !== currentMonth\"\n [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 \n 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 \n 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\"\n [class.tw-text-gray-900]=\"dayInfo.isCurrentMonth\"\n [class.tw-bg-blue-500]=\"dayInfo.isSelected\"\n [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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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 \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'AM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'AM'\"\n [class.tw-text-gray-600]=\"timeFormat !== 'AM'\"\n (click)=\"timeFormat = 'AM'\">\n AM\n </button>\n <button \n 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'\"\n [class.tw-text-gray-800]=\"timeFormat === 'PM'\"\n [class.tw-shadow-sm]=\"timeFormat === 'PM'\"\n [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') }} {{ 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 \n 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 \n 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 \n 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"] }]
|
|
1681
1733
|
}], ctorParameters: () => [], propDecorators: { fill: [{
|
|
1682
1734
|
type: Input
|
|
1683
1735
|
}], label: [{
|
|
@@ -1785,8 +1837,20 @@ class CideSelectComponent {
|
|
|
1785
1837
|
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
|
|
1786
1838
|
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
1787
1839
|
id = input('', ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
1788
|
-
// ngModel
|
|
1789
|
-
|
|
1840
|
+
// ngModel with @Input() for two-way binding support
|
|
1841
|
+
_ngModel = '';
|
|
1842
|
+
get ngModel() {
|
|
1843
|
+
return this._ngModel;
|
|
1844
|
+
}
|
|
1845
|
+
set ngModel(value) {
|
|
1846
|
+
if (this._ngModel !== value) {
|
|
1847
|
+
this._ngModel = value;
|
|
1848
|
+
// Update internal state and validate
|
|
1849
|
+
this.validateValue(value);
|
|
1850
|
+
// Note: We don't emit ngModelChange here to avoid double emissions
|
|
1851
|
+
// The emission happens in selectOption() and clearSelection() when user interacts
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1790
1854
|
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
1791
1855
|
fill = input('outline', ...(ngDevMode ? [{ debugName: "fill" }] : []));
|
|
1792
1856
|
labelPlacement = input('floating', ...(ngDevMode ? [{ debugName: "labelPlacement" }] : []));
|
|
@@ -1902,14 +1966,17 @@ class CideSelectComponent {
|
|
|
1902
1966
|
// Note: options and loading changes are now handled by effect() in ngOnInit
|
|
1903
1967
|
}
|
|
1904
1968
|
writeValue(value) {
|
|
1905
|
-
|
|
1906
|
-
if (this.
|
|
1907
|
-
this.
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1969
|
+
// Only update if value actually changed to avoid infinite loops
|
|
1970
|
+
if (this._ngModel !== value) {
|
|
1971
|
+
this._ngModel = value;
|
|
1972
|
+
if (this.searchable()) {
|
|
1973
|
+
this.searchChange.emit({
|
|
1974
|
+
query: "",
|
|
1975
|
+
value: value // emit raw value for external handlers
|
|
1976
|
+
});
|
|
1977
|
+
}
|
|
1978
|
+
this.validateValue(value);
|
|
1911
1979
|
}
|
|
1912
|
-
this.validateValue(value);
|
|
1913
1980
|
}
|
|
1914
1981
|
registerOnChange(fn) {
|
|
1915
1982
|
this.onChange = fn;
|
|
@@ -2364,25 +2431,25 @@ class CideSelectComponent {
|
|
|
2364
2431
|
current.push(optionValue.toString());
|
|
2365
2432
|
}
|
|
2366
2433
|
// For array-based form controls, emit array; for CSV-based, emit CSV
|
|
2367
|
-
if (Array.isArray(this.
|
|
2368
|
-
this.
|
|
2434
|
+
if (Array.isArray(this._ngModel)) {
|
|
2435
|
+
this._ngModel = current;
|
|
2369
2436
|
this.onChange(current);
|
|
2370
2437
|
this.ngModelChange.emit(current);
|
|
2371
2438
|
}
|
|
2372
2439
|
else {
|
|
2373
2440
|
const newCsv = current.join(',');
|
|
2374
|
-
this.
|
|
2441
|
+
this._ngModel = newCsv;
|
|
2375
2442
|
this.onChange(newCsv);
|
|
2376
2443
|
this.ngModelChange.emit(newCsv);
|
|
2377
2444
|
}
|
|
2378
2445
|
this.selectionChange.emit(option);
|
|
2379
|
-
this.validateValue(this.
|
|
2446
|
+
this.validateValue(this._ngModel);
|
|
2380
2447
|
this.isTouched = true;
|
|
2381
2448
|
this.onTouched();
|
|
2382
2449
|
// Do not close dropdown in multi-select mode
|
|
2383
2450
|
}
|
|
2384
2451
|
else {
|
|
2385
|
-
this.
|
|
2452
|
+
this._ngModel = optionValue;
|
|
2386
2453
|
this.onChange(optionValue);
|
|
2387
2454
|
this.ngModelChange.emit(optionValue);
|
|
2388
2455
|
this.selectionChange.emit(option);
|
|
@@ -2460,14 +2527,14 @@ class CideSelectComponent {
|
|
|
2460
2527
|
}
|
|
2461
2528
|
}
|
|
2462
2529
|
clearSelection() {
|
|
2463
|
-
if (this.multiple() && Array.isArray(this.
|
|
2464
|
-
this.
|
|
2530
|
+
if (this.multiple() && Array.isArray(this._ngModel)) {
|
|
2531
|
+
this._ngModel = [];
|
|
2465
2532
|
this.onChange([]);
|
|
2466
2533
|
this.ngModelChange.emit([]);
|
|
2467
2534
|
this.validateValue([]);
|
|
2468
2535
|
}
|
|
2469
2536
|
else {
|
|
2470
|
-
this.
|
|
2537
|
+
this._ngModel = '';
|
|
2471
2538
|
this.onChange('');
|
|
2472
2539
|
this.ngModelChange.emit('');
|
|
2473
2540
|
this.validateValue('');
|
|
@@ -2791,7 +2858,7 @@ class CideSelectComponent {
|
|
|
2791
2858
|
return timeoutId;
|
|
2792
2859
|
}
|
|
2793
2860
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideSelectComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2794
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideSelectComponent, isStandalone: true, selector: "cide-ele-select", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelHide: { classPropertyName: "labelHide", publicName: "labelHide", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, helperText: { classPropertyName: "helperText", publicName: "helperText", isSignal: true, isRequired: false, transformFunction: null }, errorText: { classPropertyName: "errorText", publicName: "errorText", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fill: { classPropertyName: "fill", publicName: "fill", isSignal: true, isRequired: false, transformFunction: null }, labelPlacement: { classPropertyName: "labelPlacement", publicName: "labelPlacement", isSignal: true, isRequired: false, transformFunction: null }, labelDir: { classPropertyName: "labelDir", publicName: "labelDir", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null }, trailingIcon: { classPropertyName: "trailingIcon", publicName: "trailingIcon", isSignal: true, isRequired: false, transformFunction: null }, clearInput: { classPropertyName: "clearInput", publicName: "clearInput", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, showSearchInput: { classPropertyName: "showSearchInput", publicName: "showSearchInput", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, valueKey: { classPropertyName: "valueKey", publicName: "valueKey", isSignal: true, isRequired: false, transformFunction: null }, labelKey: { classPropertyName: "labelKey", publicName: "labelKey", isSignal: true, isRequired: false, transformFunction: null }, treeView: { classPropertyName: "treeView", publicName: "treeView", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { ngModelChange: "ngModelChange", selectionChange: "change", searchChange: "searchChange" }, providers: [
|
|
2861
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideSelectComponent, isStandalone: true, selector: "cide-ele-select", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelHide: { classPropertyName: "labelHide", publicName: "labelHide", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, helperText: { classPropertyName: "helperText", publicName: "helperText", isSignal: true, isRequired: false, transformFunction: null }, errorText: { classPropertyName: "errorText", publicName: "errorText", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ngModel: { classPropertyName: "ngModel", publicName: "ngModel", isSignal: false, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fill: { classPropertyName: "fill", publicName: "fill", isSignal: true, isRequired: false, transformFunction: null }, labelPlacement: { classPropertyName: "labelPlacement", publicName: "labelPlacement", isSignal: true, isRequired: false, transformFunction: null }, labelDir: { classPropertyName: "labelDir", publicName: "labelDir", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null }, trailingIcon: { classPropertyName: "trailingIcon", publicName: "trailingIcon", isSignal: true, isRequired: false, transformFunction: null }, clearInput: { classPropertyName: "clearInput", publicName: "clearInput", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, showSearchInput: { classPropertyName: "showSearchInput", publicName: "showSearchInput", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, valueKey: { classPropertyName: "valueKey", publicName: "valueKey", isSignal: true, isRequired: false, transformFunction: null }, labelKey: { classPropertyName: "labelKey", publicName: "labelKey", isSignal: true, isRequired: false, transformFunction: null }, treeView: { classPropertyName: "treeView", publicName: "treeView", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { ngModelChange: "ngModelChange", selectionChange: "change", searchChange: "searchChange" }, providers: [
|
|
2795
2862
|
{
|
|
2796
2863
|
provide: NG_VALUE_ACCESSOR,
|
|
2797
2864
|
useExisting: forwardRef(() => CideSelectComponent),
|
|
@@ -2824,6 +2891,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
|
|
|
2824
2891
|
}], searchInputRef: [{
|
|
2825
2892
|
type: ViewChild,
|
|
2826
2893
|
args: ['searchInput', { static: false }]
|
|
2894
|
+
}], ngModel: [{
|
|
2895
|
+
type: Input
|
|
2827
2896
|
}], ngModelChange: [{
|
|
2828
2897
|
type: Output
|
|
2829
2898
|
}], selectionChange: [{
|
|
@@ -12594,7 +12663,7 @@ class CideEleDataGridComponent {
|
|
|
12594
12663
|
return String(value);
|
|
12595
12664
|
}
|
|
12596
12665
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleDataGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
12597
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleDataGridComponent, isStandalone: true, selector: "cide-ele-data-grid", inputs: { config: "config", templateRenderers: "templateRenderers", customFormatters: "customFormatters", actionHandlers: "actionHandlers", serverSidePagination: "serverSidePagination", totalServerItems: "totalServerItems", currentServerPage: "currentServerPage", currentServerPageSize: "currentServerPageSize", dragDropEnabled: "dragDropEnabled" }, outputs: { gridEvent: "gridEvent" }, usesOnChanges: true, ngImport: i0, template: " <!-- Data Grid Component -->\n <div class=\"data-grid-container tw-bg-white tw-shadow tw-overflow-visible tw-flex tw-flex-col\" \n [ngClass]=\"[\n mergedConfig().tableClass || '',\n mergedConfig().fullHeight ? 'tw-h-full' : '',\n isDragDropEnabled() ? 'drag-drop-enabled' : '',\n isTreeEnabled() ? 'tree-enabled' : ''\n ]\">\n \n <!-- Header Section -->\n @if (mergedConfig().title || mergedConfig().subtitle) {\n <div class=\"tw-px-3 tw-py-2 tw-border-b tw-border-gray-200\">\n @if (mergedConfig().title) {\n <h3 class=\"tw-text-base tw-font-semibold tw-text-gray-900\">\n {{ mergedConfig().title }}\n </h3>\n }\n @if (mergedConfig().subtitle) {\n <p class=\"tw-text-sm tw-text-gray-600 tw-mt-0.5\">\n {{ mergedConfig().subtitle }}\n </p>\n }\n </div>\n }\n\n <!-- Search Section -->\n @if (searchConfig.enabled) {\n <div class=\"tw-px-3 tw-py-1.5 tw-border-b tw-border-gray-200\">\n <div class=\"tw-flex tw-items-center tw-justify-between\">\n <!-- Left Side: Search Input and Action Icons -->\n <div class=\"tw-flex tw-items-center tw-space-x-1.5\">\n <!-- Search Input - Apple Style -->\n <div class=\"tw-max-w-md data-grid-search-input\">\n <cide-ele-input [labelHide]=\"true\" [hideHelperAndErrorText]=\"true\" id=\"search-input\" type=\"text\"\n [ngModel]=\"searchQuery()\"\n (ngModelChange)=\"updateSearchQuery($event)\"\n [placeholder]=\"searchConfig.placeholder\"\n [disabled]=\"loading() || isRefreshing()\"\n leadingIcon=\"search\"\n fill=\"outline\"\n size=\"sm\">\n </cide-ele-input>\n </div>\n \n <!-- Action Icons (Filter, Sort, Download) - Apple Style Compact -->\n <div class=\"tw-flex tw-items-center tw-space-x-1 data-grid-action-buttons\">\n <!-- Filter Button with Dropdown -->\n <div class=\"tw-relative\">\n <button type=\"button\"\n class=\"filter-dropdown-trigger tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-blue-600 hover:tw-bg-blue-50 tw-transition-all tw-duration-200 tw-relative\"\n [class.tw-text-blue-600]=\"columnFilters().length > 0\"\n [class.tw-bg-blue-50]=\"columnFilters().length > 0\"\n title=\"Filter\"\n (click)=\"toggleFilterDropdown()\">\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">filter_list</cide-ele-icon>\n @if (columnFilters().length > 0) {\n <span class=\"tw-absolute -tw-top-1 -tw-right-1 tw-inline-flex tw-items-center tw-justify-center tw-w-4 tw-h-4 tw-text-xs tw-font-semibold tw-text-white tw-bg-blue-600 tw-rounded-full tw-border tw-border-white\">\n {{ columnFilters().length }}\n </span>\n }\n </button>\n \n <!-- Filter Dropdown Menu -->\n @if (showFilterDropdown()) {\n <div class=\"filter-dropdown tw-absolute tw-left-0 tw-mt-2 tw-w-80 tw-bg-white tw-rounded-lg tw-shadow-xl tw-border tw-border-gray-200 tw-z-50 tw-overflow-hidden\"\n (click)=\"$event.stopPropagation()\">\n <div class=\"tw-py-1.5\">\n <div class=\"tw-px-3 tw-py-2 tw-bg-gray-50 tw-border-b tw-border-gray-200 tw-flex tw-items-center tw-justify-between\">\n <span class=\"tw-text-xs tw-font-semibold tw-text-gray-500 tw-uppercase tw-tracking-wider\">Active Filters</span>\n @if (columnFilters().length > 0) {\n <button type=\"button\" \n class=\"tw-text-xs tw-text-blue-600 hover:tw-text-blue-800 tw-font-medium\"\n (click)=\"clearAllFilters()\">\n Clear All\n </button>\n }\n </div>\n @if (columnFilters().length === 0) {\n <div class=\"tw-px-4 tw-py-6 tw-text-center\">\n <cide-ele-icon class=\"tw-w-12 tw-h-12 tw-text-gray-300 tw-mx-auto tw-mb-2\">filter_list</cide-ele-icon>\n <p class=\"tw-text-sm tw-text-gray-500\">No filters applied</p>\n <p class=\"tw-text-xs tw-text-gray-400 tw-mt-1\">Use column filters to narrow down your results</p>\n </div>\n } @else {\n <div class=\"tw-max-h-96 tw-overflow-y-auto\">\n @for (filter of columnFilters(); track filter.columnKey) {\n <div class=\"tw-px-4 tw-py-3 hover:tw-bg-gray-50 tw-border-b tw-border-gray-100 last:tw-border-b-0\">\n <div class=\"tw-flex tw-items-start tw-justify-between tw-gap-2\">\n <div class=\"tw-flex-1 tw-min-w-0\">\n <div class=\"tw-text-xs tw-font-semibold tw-text-gray-600 tw-mb-1\">{{ getColumnHeader(filter.columnKey) }}</div>\n <div class=\"tw-text-sm tw-text-gray-700 tw-flex tw-items-center tw-gap-1\">\n @if (filter.operator === 'in' && isArray(filter.value)) {\n <span class=\"tw-inline-flex tw-items-center tw-gap-1\">\n <cide-ele-icon class=\"tw-w-3 tw-h-3\">check_circle</cide-ele-icon>\n {{ getArrayLength(filter.value) }} selected\n </span>\n } @else {\n <span>{{ $any(filter.value) }}</span>\n }\n </div>\n </div>\n <button type=\"button\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-rounded tw-text-gray-400 hover:tw-text-red-600 hover:tw-bg-red-50 tw-transition-colors\"\n (click)=\"removeFilter(filter.columnKey)\"\n title=\"Remove filter\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4\">close</cide-ele-icon>\n </button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n \n <!-- Download/Export Button with Dropdown -->\n <div class=\"tw-relative\">\n <button type=\"button\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-gray-700 hover:tw-bg-gray-100 tw-transition-all tw-duration-200\"\n title=\"Export\"\n (click)=\"toggleExportMenu($event)\">\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">file_download</cide-ele-icon>\n </button>\n \n <!-- Export Dropdown Menu - Improved Design -->\n @if (showExportMenu()) {\n <div class=\"tw-absolute tw-right-0 tw-mt-2 tw-w-56 tw-bg-white tw-rounded-lg tw-shadow-xl tw-border tw-border-gray-200 tw-z-50 tw-overflow-hidden\"\n (click)=\"$event.stopPropagation()\">\n <div class=\"tw-py-1.5\">\n <div class=\"tw-px-3 tw-py-2 tw-bg-gray-50 tw-border-b tw-border-gray-200\">\n <span class=\"tw-text-xs tw-font-semibold tw-text-gray-500 tw-uppercase tw-tracking-wider\">Export Options</span>\n </div>\n <button type=\"button\"\n class=\"tw-w-full tw-text-left tw-px-4 tw-py-3 tw-text-sm tw-text-gray-700 hover:tw-bg-green-50 hover:tw-text-green-700 tw-flex tw-items-center tw-transition-colors tw-duration-150\"\n (click)=\"exportData('csv')\">\n <div class=\"tw-w-8 tw-h-8 tw-rounded tw-bg-green-100 tw-flex tw-items-center tw-justify-center tw-mr-3\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-green-600\">description</cide-ele-icon>\n </div>\n <div class=\"tw-flex-1\">\n <div class=\"tw-font-medium\">CSV</div>\n <div class=\"tw-text-xs tw-text-gray-500\">Comma separated values</div>\n </div>\n </button>\n <button type=\"button\"\n class=\"tw-w-full tw-text-left tw-px-4 tw-py-3 tw-text-sm tw-text-gray-700 hover:tw-bg-blue-50 hover:tw-text-blue-700 tw-flex tw-items-center tw-transition-colors tw-duration-150\"\n (click)=\"exportData('excel')\">\n <div class=\"tw-w-8 tw-h-8 tw-rounded tw-bg-blue-100 tw-flex tw-items-center tw-justify-center tw-mr-3\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-blue-600\">table_chart</cide-ele-icon>\n </div>\n <div class=\"tw-flex-1\">\n <div class=\"tw-font-medium\">Excel</div>\n <div class=\"tw-text-xs tw-text-gray-500\">Microsoft Excel format</div>\n </div>\n </button>\n <button type=\"button\"\n class=\"tw-w-full tw-text-left tw-px-4 tw-py-3 tw-text-sm tw-text-gray-700 hover:tw-bg-red-50 hover:tw-text-red-700 tw-flex tw-items-center tw-transition-colors tw-duration-150\"\n (click)=\"exportData('pdf')\">\n <div class=\"tw-w-8 tw-h-8 tw-rounded tw-bg-red-100 tw-flex tw-items-center tw-justify-center tw-mr-3\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-red-600\">picture_as_pdf</cide-ele-icon>\n </div>\n <div class=\"tw-flex-1\">\n <div class=\"tw-font-medium\">PDF</div>\n <div class=\"tw-text-xs tw-text-gray-500\">Portable document format</div>\n </div>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n \n <!-- Right Side: Drag Order Actions -->\n @if (isDragDropEnabled() && (isDragging() || hasOrderChanged())) {\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <button cideEleButton \n variant=\"outline\" \n size=\"sm\" \n type=\"button\"\n (click)=\"onActionClick(null, { key: 'reset-order', label: 'Reset Order', icon: 'undo', variant: 'outline', onClick: 'resetOrder' })\"\n class=\"tw-text-blue-700 tw-border-blue-300 hover:tw-bg-blue-100\">\n <cide-ele-icon size=\"xs\" class=\"tw-w-4 tw-h-4 tw-mr-1\">undo</cide-ele-icon>\n Reset Order\n </button>\n <button cideEleButton \n variant=\"primary\" \n size=\"sm\" \n type=\"button\"\n (click)=\"onActionClick(null, { key: 'save-order', label: 'Save Order', icon: 'save', variant: 'primary', onClick: 'saveOrder' })\"\n class=\"tw-bg-blue-600 hover:tw-bg-blue-700 tw-text-white\">\n <cide-ele-icon size=\"xs\" class=\"tw-w-4 tw-h-4 tw-mr-1\">save</cide-ele-icon>\n Save Order\n </button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Table Section -->\n <div class=\"tw-overflow-x-auto tw-relative\"\n [ngClass]=\"{\n 'tw-flex-1 tw-min-h-0': mergedConfig().fullHeight,\n 'tw-overflow-y-auto': scrollConfig?.enabled,\n 'tw-max-h-full': scrollConfig?.enabled\n }\"\n [style.maxHeight]=\"scrollConfig?.enabled ? scrollConfig?.maxHeight : null\"\n [style.minHeight]=\"scrollConfig?.enabled ? scrollConfig?.minHeight : null\">\n <table class=\"tw-min-w-full tw-divide-y tw-divide-gray-200 tw-h-full tw-table-fixed\"\n [class.empty-table]=\"displayedData.length === 0\"\n [ngClass]=\"{\n 'tw-table-striped': mergedConfig().striped,\n 'tw-border': mergedConfig().bordered,\n 'tw-table-sm': mergedConfig().compact\n }\"\n style=\"table-layout: fixed;\">\n \n <!-- Table Header -->\n <thead class=\"tw-bg-gray-50\" \n [ngClass]=\"[\n mergedConfig().headerClass || '',\n scrollConfig?.enabled && scrollConfig?.stickyHeader ? 'tw-sticky tw-top-0 tw-z-10' : ''\n ]\">\n <tr>\n @for (column of visibleColumns(); track column.key) {\n <th\n class=\"tw-px-3 tw-py-2 tw-text-left tw-text-xs tw-font-medium tw-text-gray-500 tw-uppercase tw-tracking-wider tw-relative\"\n [ngClass]=\"[\n getColumnWidthClass(column.width),\n getColumnMaxWidthClass(column.width),\n column.align === 'center' ? 'tw-text-center' : '',\n column.align === 'right' ? 'tw-text-right' : ''\n ]\"\n [style.width]=\"getColumnWidthStyle(column.width)\"\n [style.maxWidth]=\"getColumnMaxWidthStyle(column.width)\"\n [title]=\"column.header\">\n <div class=\"tw-flex tw-items-center tw-justify-between tw-gap-1\">\n <div class=\"tw-flex tw-items-center tw-gap-1 tw-truncate tw-flex-1\">\n <span class=\"tw-truncate\">{{ column.header }}</span>\n @if (getColumnSortDirection(column.key) === 'asc') {\n <cide-ele-icon class=\"tw-w-3 tw-h-3 tw-text-blue-600 tw-flex-shrink-0\" title=\"Sorted Ascending\">arrow_upward</cide-ele-icon>\n }\n @if (getColumnSortDirection(column.key) === 'desc') {\n <cide-ele-icon class=\"tw-w-3 tw-h-3 tw-text-blue-600 tw-flex-shrink-0\" title=\"Sorted Descending\">arrow_downward</cide-ele-icon>\n }\n </div>\n \n <!-- Active Filter Indicator -->\n @if (isColumnFiltered(column.key)) {\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded tw-bg-blue-100 tw-text-blue-700 tw-text-xs tw-font-medium tw-mr-1\">\n <cide-ele-icon class=\"tw-w-3 tw-h-3 tw-mr-0.5\">filter_alt</cide-ele-icon>\n {{ getActiveFilterCount(column.key) }}\n </div>\n }\n \n <!-- Column Menu Trigger (Three Dots Icon) -->\n @if (mergedConfig().columnMenu?.enabled) {\n <button\n type=\"button\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-rounded tw-text-gray-600 hover:tw-text-gray-800 hover:tw-bg-gray-100 tw-transition-all column-menu-trigger\"\n [class.tw-text-blue-600]=\"isColumnMenuOpen(column.key) || isColumnFiltered(column.key)\"\n [class.tw-bg-blue-50]=\"isColumnFiltered(column.key)\"\n (click)=\"toggleColumnMenu(column.key, $event)\"\n title=\"Column options\">\n <cide-ele-icon class=\"tw-w-5 tw-h-4\">more_vert</cide-ele-icon>\n </button>\n }\n </div>\n\n <!-- Column Menu Dropdown -->\n @if (isColumnMenuOpen(column.key)) {\n <div class=\"column-menu-dropdown tw-absolute tw-z-[9999] tw-mt-2 tw-w-56 tw-rounded-lg tw-shadow-lg tw-bg-white tw-ring-1 tw-ring-black tw-ring-opacity-5\">\n <div class=\"tw-py-1\">\n <!-- Sort Options -->\n @if (mergedConfig().columnMenu?.showSort && column.sortable !== false) {\n @let sortDirection = getColumnSortDirection(column.key);\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-justify-between tw-px-4 tw-py-2 tw-text-sm tw-transition-colors\"\n [class.tw-text-blue-700]=\"sortDirection === 'asc'\"\n [class.tw-bg-blue-50]=\"sortDirection === 'asc'\"\n [class.tw-text-gray-700]=\"sortDirection !== 'asc'\"\n [class.hover:tw-bg-gray-50]=\"sortDirection !== 'asc'\"\n (click)=\"onColumnSort(column, 'asc')\">\n <div class=\"tw-flex tw-items-center\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3\" \n [class.tw-text-blue-600]=\"sortDirection === 'asc'\"\n [class.tw-text-gray-400]=\"sortDirection !== 'asc'\">arrow_upward</cide-ele-icon>\n Ascending\n </div>\n @if (sortDirection === 'asc') {\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-blue-600\">check</cide-ele-icon>\n }\n </button>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-justify-between tw-px-4 tw-py-2 tw-text-sm tw-transition-colors\"\n [class.tw-text-blue-700]=\"sortDirection === 'desc'\"\n [class.tw-bg-blue-50]=\"sortDirection === 'desc'\"\n [class.tw-text-gray-700]=\"sortDirection !== 'desc'\"\n [class.hover:tw-bg-gray-50]=\"sortDirection !== 'desc'\"\n (click)=\"onColumnSort(column, 'desc')\">\n <div class=\"tw-flex tw-items-center\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3\"\n [class.tw-text-blue-600]=\"sortDirection === 'desc'\"\n [class.tw-text-gray-400]=\"sortDirection !== 'desc'\">arrow_downward</cide-ele-icon>\n Descending\n </div>\n @if (sortDirection === 'desc') {\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-blue-600\">check</cide-ele-icon>\n }\n </button>\n <div class=\"tw-border-t tw-border-gray-100 tw-my-1\"></div>\n }\n\n <!-- Filter Option -->\n @if (mergedConfig().columnMenu?.showFilter && column.filterable !== false) {\n <!-- Check if there's a custom filter renderer template -->\n @if (column.filterRenderer && templateRenderers[column.filterRenderer]) {\n <div class=\"tw-px-4 tw-py-2\">\n <ng-container [ngTemplateOutlet]=\"$any(templateRenderers[column.filterRenderer])\"\n [ngTemplateOutletContext]=\"{ $implicit: column, column: column, onFilter: onColumnFilter.bind(this) }\">\n </ng-container>\n </div>\n } @else {\n <!-- Excel-style Filter Button -->\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-justify-between tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n [class.tw-bg-blue-50]=\"isFilterPanelOpen(column.key)\"\n (click)=\"toggleFilterPanel(column.key, $event)\">\n <div class=\"tw-flex tw-items-center\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">filter_list</cide-ele-icon>\n Filter\n </div>\n <cide-ele-icon class=\"tw-w-3 tw-h-3 tw-text-gray-400\">\n {{ isFilterPanelOpen(column.key) ? 'expand_less' : 'expand_more' }}\n </cide-ele-icon>\n </button>\n \n <!-- Excel-style Filter Panel -->\n @if (isFilterPanelOpen(column.key)) {\n <div class=\"tw-px-2 tw-py-2 tw-bg-gray-50\" (click)=\"$event.stopPropagation()\">\n <!-- Search box -->\n <div class=\"tw-px-2 tw-mb-2\">\n <input\n type=\"text\"\n class=\"tw-w-full tw-px-2 tw-py-1 tw-text-xs tw-border tw-border-gray-300 tw-rounded focus:tw-outline-none focus:tw-ring-1 focus:tw-ring-blue-500\"\n placeholder=\"Search...\"\n [(ngModel)]=\"filterSearchTerm\"\n (click)=\"$event.stopPropagation()\">\n </div>\n \n <!-- Select All / Deselect All -->\n <div class=\"tw-px-2 tw-mb-1 tw-flex tw-gap-2\">\n <button\n type=\"button\"\n class=\"tw-text-xs tw-text-blue-600 hover:tw-text-blue-700\"\n (click)=\"selectAllFilterValues(column); $event.stopPropagation()\">\n Select All\n </button>\n <span class=\"tw-text-xs tw-text-gray-400\">|</span>\n <button\n type=\"button\"\n class=\"tw-text-xs tw-text-blue-600 hover:tw-text-blue-700\"\n (click)=\"deselectAllFilterValues(column); $event.stopPropagation()\">\n Clear\n </button>\n </div>\n \n <!-- Filter values list -->\n <div class=\"tw-max-h-48 tw-overflow-y-auto\">\n @for (item of getUniqueColumnValues(column); track item.value) {\n <label class=\"tw-flex tw-items-center tw-px-2 tw-py-1 tw-text-xs hover:tw-bg-white tw-cursor-pointer tw-rounded\">\n <input\n type=\"checkbox\"\n class=\"tw-mr-2 tw-rounded tw-border-gray-300 tw-text-blue-600 focus:tw-ring-blue-500\"\n [checked]=\"item.checked\"\n (change)=\"toggleFilterValue(column, item.value, $any($event.target).checked)\"\n (click)=\"$event.stopPropagation()\">\n <span class=\"tw-flex-1 tw-truncate\">{{ item.label }}</span>\n <span class=\"tw-text-gray-400 tw-ml-1\">({{ item.count }})</span>\n </label>\n }\n </div>\n </div>\n }\n }\n <div class=\"tw-border-t tw-border-gray-100 tw-my-1\"></div>\n }\n\n <!-- Autosize Option -->\n @if (mergedConfig().columnMenu?.showAutosize) {\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnAutosize(column)\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">fit_screen</cide-ele-icon>\n Autosize\n </button>\n }\n\n <!-- Group By Column Option -->\n @if (mergedConfig().columnMenu?.showGroupBy && column.groupable !== false) {\n @let isGrouped = groupedColumns().includes(column.key);\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-justify-between tw-px-4 tw-py-2 tw-text-sm tw-transition-colors\"\n [class.tw-text-blue-700]=\"isGrouped\"\n [class.tw-bg-blue-50]=\"isGrouped\"\n [class.tw-text-gray-700]=\"!isGrouped\"\n [class.hover:tw-bg-gray-50]=\"!isGrouped\"\n (click)=\"onColumnGroupBy(column)\">\n <div class=\"tw-flex tw-items-center\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3\" \n [class.tw-text-blue-600]=\"isGrouped\"\n [class.tw-text-gray-400]=\"!isGrouped\">group_work</cide-ele-icon>\n Group By Column\n </div>\n @if (isGrouped) {\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-blue-600\">check</cide-ele-icon>\n }\n </button>\n }\n\n <!-- Manage Columns Option -->\n @if (mergedConfig().columnMenu?.showManageColumns) {\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onManageColumns()\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">view_column</cide-ele-icon>\n Manage Columns\n </button>\n }\n\n <!-- Reset Columns Option -->\n @if (mergedConfig().columnMenu?.showResetColumns) {\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnReset()\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">refresh</cide-ele-icon>\n Reset Columns\n </button>\n }\n\n <!-- Hide Column Option -->\n @if (mergedConfig().columnMenu?.showHideColumn && column.hideable !== false) {\n <div class=\"tw-border-t tw-border-gray-100 tw-my-1\"></div>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnHide(column)\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">visibility_off</cide-ele-icon>\n Hide Column\n </button>\n }\n\n <!-- Aggregation Select Option -->\n @if (mergedConfig().columnMenu?.showAggregation && column.aggregatable !== false) {\n <div class=\"tw-border-t tw-border-gray-100 tw-my-1\"></div>\n <div class=\"tw-px-4 tw-py-2 tw-text-xs tw-font-semibold tw-text-gray-500 tw-uppercase\">Aggregation</div>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnAggregation(column, 'sum')\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">functions</cide-ele-icon>\n Sum\n </button>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnAggregation(column, 'avg')\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">analytics</cide-ele-icon>\n Average\n </button>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnAggregation(column, 'count')\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">tag</cide-ele-icon>\n Count\n </button>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnAggregation(column, 'min')\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">arrow_downward</cide-ele-icon>\n Min\n </button>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnAggregation(column, 'max')\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">arrow_upward</cide-ele-icon>\n Max\n </button>\n }\n </div>\n </div>\n }\n </th>\n }\n </tr>\n </thead>\n\n <!-- Table Body -->\n <tbody class=\"tw-divide-y tw-divide-gray-200\">\n @if (loading() || isRefreshing() || pageChangeLoading()) {\n <!-- Skeleton Loading Rows -->\n @for (skeletonItem of getSkeletonArray(); track $index) {\n <tr class=\"tw-animate-pulse tw-border-b tw-border-gray-200\">\n @for (column of visibleColumns(); track column.key) {\n <td class=\"tw-px-3 tw-py-2 tw-whitespace-nowrap\"\n [ngClass]=\"[\n getColumnWidthClass(column.width),\n getColumnMaxWidthClass(column.width)\n ]\"\n [style.width]=\"getColumnWidthStyle(column.width)\"\n [style.maxWidth]=\"getColumnMaxWidthStyle(column.width)\">\n <div class=\"tw-h-2 tw-bg-gray-200 tw-rounded tw-w-3/4\"></div>\n </td>\n }\n </tr>\n }\n } @else {\n @for (item of displayedData; track trackByFn($index, item)) {\n @if (isGroupHeader(item)) {\n <!-- Group Header Row -->\n @let groupKey = getGroupKey(item);\n @let groupLevel = getGroupLevel(item);\n <tr class=\"data-grid-group-row tw-border-b-2 tw-border-gray-300 tw-font-semibold\"\n [class.tw-bg-gray-50]=\"groupLevel === 0\"\n [class.tw-bg-gray-100]=\"groupLevel === 1\"\n [class.tw-bg-gray-200]=\"groupLevel > 1\"\n (click)=\"toggleGroupExpansion(groupKey)\">\n <td class=\"tw-px-3 tw-py-1 tw-cursor-pointer tw-transition-colors\"\n [attr.colspan]=\"visibleColumns().length\">\n <div class=\"tw-flex tw-items-center tw-gap-2\" [style.padding-left.px]=\"groupLevel * 24\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-gray-600 tw-cursor-pointer\">\n {{ isGroupExpanded(groupKey) ? 'expand_more' : 'chevron_right' }}\n </cide-ele-icon>\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-blue-600\">group_work</cide-ele-icon>\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-900\">\n {{ getGroupColumnHeader(item) }}: {{ getGroupValueDisplay(item) }}\n </span>\n <span class=\"tw-text-xs tw-text-gray-500 tw-ml-2 tw-bg-gray-200 tw-px-2 tw-py-0.5 tw-rounded-full\">\n {{ getGroupRowCount(item) }}\n </span>\n </div>\n </td>\n </tr>\n } @else {\n <!-- Regular Data Row -->\n <tr class=\"tw-group data-grid-row tw-border-b-2 tw-border-gray-200\"\n [ngClass]=\"[\n mergedConfig().rowClass || '',\n isRefreshing() ? 'tw-opacity-60 tw-pointer-events-none' : '',\n isDragDropEnabled() ? 'tw-cursor-move tw-border-2 tw-border-transparent' : '',\n !isDragDropEnabled() ? 'tw-transition-colors tw-duration-150' : '',\n isTreeEnabled() ? getTreeLevelClass(item) : ''\n ]\"\n [style.border-color]=\"isDragOverRow === $index ? '#3b82f6' : 'transparent'\"\n [style.background-color]=\"isDragOverRow === $index ? '#eff6ff' : ''\"\n (click)=\"onRowClick(item)\"\n (keydown.enter)=\"onRowClick(item)\"\n (keydown.space)=\"onRowClick(item)\"\n [class.tw-cursor-pointer]=\"mergedConfig().onRowClick && !isDragDropEnabled()\"\n [tabindex]=\"mergedConfig().onRowClick && !isDragDropEnabled() ? 0 : -1\"\n [attr.role]=\"mergedConfig().onRowClick && !isDragDropEnabled() ? 'button' : null\"\n [attr.aria-label]=\"mergedConfig().onRowClick && !isDragDropEnabled() ? 'Select row' : null\"\n [draggable]=\"isDragDropEnabled()\"\n (dragstart)=\"onDragStart($event, item, $index)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event, item, $index)\"\n (dragend)=\"onDragEnd($event)\">\n \n @for (column of visibleColumns(); track column.key) {\n <td class=\"tw-pr-3 tw-py-1 tw-relative\"\n [ngClass]=\"[\n getColumnWidthClass(column.width),\n getColumnMaxWidthClass(column.width),\n mergedConfig().cellClass || '',\n column.align === 'center' ? 'tw-text-center' : '',\n column.align === 'right' ? 'tw-text-right' : '',\n column.truncate !== false ? 'tw-whitespace-nowrap' : 'tw-whitespace-normal'\n ]\"\n [style.width]=\"getColumnWidthStyle(column.width)\"\n [style.paddingLeft]=\"isTreeEnabled() && $index === 0 ? getTreeIndentStyle(item) : '12px'\"\n [style.maxWidth]=\"getColumnMaxWidthStyle(column.width) || (getColumnMaxWidthClass(column.width) === 'tw-max-w-xs' ? '200px' : getColumnMaxWidthClass(column.width) === 'tw-max-w-sm' ? '300px' : getColumnMaxWidthClass(column.width) === 'tw-max-w-md' ? '400px' : null)\"\n [style.minWidth]=\"isTreeEnabled() && $index === 0 ? '150px' : (getColumnWidthStyle(column.width) ? null : '100px')\">\n <!-- Tree Expand/Collapse Button (only for first column when tree is enabled) -->\n @if (isTreeEnabled() && $index === 0) {\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <!-- Tree Indentation -->\n <div class=\"tw-flex tw-items-center\">\n @if (hasChildren(item)) {\n <button \n variant=\"outline\"\n size=\"xs\"\n type=\"button\"\n (click)=\"onActionClick(item, { key: 'toggle-expand', label: 'Toggle', icon: '', variant: 'ghost', onClick: 'toggle-expand' }); $event.stopPropagation()\"\n class=\"tw-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-text-gray-500 hover:tw-text-gray-700 tw-rounded\"\n [class.tw-transition-colors]=\"!isDragDropEnabled()\"\n [title]=\"isItemExpanded(item) ? 'Collapse' : 'Expand'\">\n <cide-ele-icon \n class=\"tw-w-3 tw-h-3\"\n [class.tw-transition-transform]=\"!isDragDropEnabled()\"\n [class.tw-rotate-90]=\"isItemExpanded(item)\"\n size=\"xs\">\n chevron_right\n </cide-ele-icon>\n </button>\n } @else {\n <div class=\"tw-w-8 tw-h-5 tw-flex tw-items-center tw-justify-center\">\n <!-- <div class=\"tw-w-1 tw-h-1 tw-bg-gray-300 tw-rounded-full\"></div> -->\n </div>\n }\n </div>\n \n <!-- Cell Content -->\n <div class=\"tw-flex-1 tw-w-full\">\n @if (column.type === 'text') {\n <p class=\"tw-text-sm tw-text-gray-900\"\n [class.tw-truncate]=\"column.truncate\"\n [title]=\"column.truncate ? (getNestedValue(item, column.valueGetter || column.key) || '').toString() : ''\">\n {{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}\n </p>\n } @else if (column.type === 'number') {\n <span class=\"tw-text-sm tw-text-gray-900 tw-font-mono\">\n {{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}\n </span>\n } @else if (column.type === 'date') {\n <span class=\"tw-text-sm tw-text-gray-600\">\n {{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}\n </span>\n } @else if (column.type === 'boolean') {\n <span class=\"tw-inline-flex tw-items-center tw-px-2 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium\"\n [ngClass]=\"getNestedValue(item, column.valueGetter || column.key) ? 'tw-bg-green-100 tw-text-green-800' : 'tw-bg-red-100 tw-text-red-800'\">\n {{ getNestedValue(item, column.valueGetter || column.key) ? 'Yes' : 'No' }}\n </span>\n } @else if (column.type === 'status' && column.statusConfig) {\n <span class=\"tw-inline-flex tw-items-center tw-px-2 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium\"\n [ngClass]=\"getStatusClass(getNestedValue(item, column.valueGetter || column.key), column.statusConfig)\">\n {{ getStatusText(getNestedValue(item, column.valueGetter || column.key), column.statusConfig) }}\n </span>\n } @else if (column.type === 'actions' && column.actions) {\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n @for (action of column.actions; track action.key) {\n <button\n cideEleButton\n [variant]=\"action.variant || 'ghost'\"\n size=\"xs\"\n type=\"button\"\n (click)=\"onActionClick(item, action); $event.stopPropagation()\"\n [title]=\"action.tooltip || action.label\"\n [disabled]=\"isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-px-2 tw-py-2 tw-text-xs tw-font-medium tw-rounded\"\n [class.tw-transition-colors]=\"!isDragDropEnabled()\"\n [ngClass]=\"{\n 'tw-text-gray-700 tw-bg-gray-100 hover:tw-bg-gray-200': action.variant === 'ghost',\n 'tw-text-white tw-bg-blue-600 hover:tw-bg-blue-700': action.variant === 'primary',\n 'tw-text-blue-700 tw-bg-blue-50 tw-border tw-border-blue-200 hover:tw-bg-blue-100': action.variant === 'outline',\n 'tw-text-white tw-bg-red-600 hover:tw-bg-red-700': action.variant === 'danger'\n }\">\n @if (action.icon) {\n <svg class=\"tw-w-3 tw-h-3 tw-mr-1\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M10 12l-5-5h10l-5 5z\"/>\n </svg>\n }\n {{ action.label }}\n </button>\n }\n </div>\n } @else if (column.type === 'custom') {\n <!-- Template Renderer -->\n @if (column.renderer && isTemplateRenderer(column.renderer)) {\n <ng-container \n [ngTemplateOutlet]=\"getTemplateRenderer(column.renderer)!\"\n [ngTemplateOutletContext]=\"getTemplateContext(getNestedValue(item, column.valueGetter || column.key), item, column)\">\n </ng-container>\n }\n <!-- Default rendering -->\n @else {\n <div>{{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}</div>\n }\n }\n </div>\n </div>\n } @else {\n <!-- Regular cell content (non-tree or non-first column) -->\n @if (column.type === 'text') {\n <p class=\"tw-text-sm tw-text-gray-900\"\n [class.tw-truncate]=\"column.truncate\"\n [title]=\"column.truncate ? (getNestedValue(item, column.valueGetter || column.key) || '').toString() : ''\">\n {{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}\n </p>\n } @else if (column.type === 'number') {\n <span class=\"tw-text-sm tw-text-gray-900 tw-font-mono\">\n {{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}\n </span>\n } @else if (column.type === 'date') {\n <span class=\"tw-text-sm tw-text-gray-600\">\n {{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}\n </span>\n } @else if (column.type === 'boolean') {\n <span class=\"tw-inline-flex tw-items-center tw-px-2 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium\"\n [ngClass]=\"getNestedValue(item, column.valueGetter || column.key) ? 'tw-bg-green-100 tw-text-green-800' : 'tw-bg-red-100 tw-text-red-800'\">\n {{ getNestedValue(item, column.valueGetter || column.key) ? 'Yes' : 'No' }}\n </span>\n } @else if (column.type === 'status' && column.statusConfig) {\n <span class=\"tw-inline-flex tw-items-center tw-px-2 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium\"\n [ngClass]=\"getStatusClass(getNestedValue(item, column.valueGetter || column.key), column.statusConfig)\">\n {{ getStatusText(getNestedValue(item, column.valueGetter || column.key), column.statusConfig) }}\n </span>\n } @else if (column.type === 'actions' && column.actions) {\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n @for (action of column.actions; track action.key) {\n <button\n cideEleButton\n [variant]=\"action.variant || 'ghost'\"\n size=\"xs\"\n type=\"button\"\n (click)=\"onActionClick(item, action); $event.stopPropagation()\"\n [title]=\"action.tooltip || action.label\"\n [disabled]=\"isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-px-2 tw-py-2 tw-text-xs tw-font-medium tw-rounded\"\n [class.tw-transition-colors]=\"!isDragDropEnabled()\"\n [ngClass]=\"{\n 'tw-text-gray-700 tw-bg-gray-100 hover:tw-bg-gray-200': action.variant === 'ghost',\n 'tw-text-white tw-bg-blue-600 hover:tw-bg-blue-700': action.variant === 'primary',\n 'tw-text-blue-700 tw-bg-blue-50 tw-border tw-border-blue-200 hover:tw-bg-blue-100': action.variant === 'outline',\n 'tw-text-white tw-bg-red-600 hover:tw-bg-red-700': action.variant === 'danger'\n }\">\n @if (action.icon) {\n <svg class=\"tw-w-3 tw-h-3 tw-mr-1\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M10 12l-5-5h10l-5 5z\"/>\n </svg>\n }\n {{ action.label }}\n </button>\n }\n </div>\n } @else if (column.type === 'custom') {\n <!-- Template Renderer -->\n @if (column.renderer && isTemplateRenderer(column.renderer)) {\n <ng-container \n [ngTemplateOutlet]=\"getTemplateRenderer(column.renderer)!\"\n [ngTemplateOutletContext]=\"getTemplateContext(getNestedValue(item, column.valueGetter || column.key), item, column)\">\n </ng-container>\n }\n <!-- Default rendering -->\n @else {\n <div>{{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}</div>\n }\n }\n }\n </td>\n }\n </tr>\n }\n }\n \n <!-- Empty State -->\n @if (displayedData.length === 0) {\n <tr class=\"tw-h-full\">\n <td [attr.colspan]=\"visibleColumns().length\" class=\"tw-px-6 tw-py-22 tw-text-center tw-h-full tw-align-middle\">\n <div class=\"tw-text-gray-500 tw-flex tw-flex-col tw-items-center tw-justify-center tw-min-h-[300px]\">\n <svg class=\"tw-mx-auto tw-h-12 tw-w-12 tw-text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"></path>\n </svg>\n <h3 class=\"tw-mt-2 tw-text-sm tw-font-medium tw-text-gray-900\">No data found</h3>\n <p class=\"tw-mt-1 tw-text-sm tw-text-gray-500\">\n @if (searchQuery()) {\n No results match your search criteria.\n } @else {\n There are no items to display.\n }\n </p>\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n </div>\n\n <!-- Pagination Section -->\n @if (paginationConfig.enabled && totalItems() > 0) {\n <div class=\"tw-px-3 tw-py-0 tw-border-t tw-border-gray-200 tw-bg-white tw-relative tw-z-20\"\n [class.tw-opacity-60]=\"isRefreshing()\">\n \n <!-- Results Info and Page Size -->\n <div class=\"tw-flex tw-flex-col sm:tw-flex-row tw-justify-between tw-items-start sm:tw-items-center tw-space-y-1 sm:tw-space-y-0\">\n \n <!-- Results Info -->\n @if (paginationConfig.showPageInfo) {\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <p class=\"tw-text-sm tw-text-gray-700\">\n Showing {{ getItemRangeText() }} results\n </p>\n \n <!-- Page Size Selector -->\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-gray-500\">view_list</cide-ele-icon>\n <span class=\"tw-text-sm tw-text-gray-700\">Per page:</span>\n <div class=\"tw-w-16 tw-relative\">\n <cide-ele-select\n [labelHide]=\"true\"\n [ngModel]=\"pageSize()\"\n (ngModelChange)=\"updatePageSize($event)\"\n [options]=\"getPageSizeOptions()\"\n [disabled]=\"isRefreshing()\"\n fill=\"outline\"\n size=\"xs\"\n class=\"tw-z-30\">\n </cide-ele-select>\n </div>\n </div>\n </div>\n }\n\n <!-- Pagination Controls -->\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n \n <!-- Previous/Next and Page Numbers -->\n <div class=\"tw-flex tw-items-center tw-space-x-1\">\n \n <!-- First Page -->\n <button\n type=\"button\"\n (click)=\"onPageChange(1)\"\n [disabled]=\"currentPage() === 1 || isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-gray-700 hover:tw-bg-gray-100 tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n title=\"First page\">\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">first_page</cide-ele-icon>\n </button>\n \n <!-- Previous Page -->\n <button\n type=\"button\"\n (click)=\"previousPage()\"\n [disabled]=\"!hasPreviousPage() || isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-gray-700 hover:tw-bg-gray-100 tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n title=\"Previous page\">\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">chevron_left</cide-ele-icon>\n </button>\n \n <!-- Page Numbers -->\n @for (page of getEnhancedPageNumbers(); track page) {\n @if (page === '...') {\n <span class=\"tw-px-2 tw-py-2 tw-text-sm tw-text-gray-500\">...</span>\n } @else {\n <button\n type=\"button\"\n (click)=\"onPageChange(page)\"\n [disabled]=\"isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-p-0 tw-rounded tw-text-xs tw-font-medium tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n [ngClass]=\"{\n 'tw-bg-blue-600 tw-text-white hover:tw-bg-blue-700': currentPage() === page,\n 'tw-bg-white tw-text-gray-700 tw-border tw-border-gray-300 hover:tw-bg-gray-50': currentPage() !== page\n }\"\n [title]=\"'Page ' + page\">\n {{ page }}\n </button>\n }\n }\n \n <!-- Next Page -->\n <button\n type=\"button\"\n (click)=\"nextPage()\"\n [disabled]=\"!hasNextPage() || isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-gray-700 hover:tw-bg-gray-100 tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n title=\"Next page\">\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">chevron_right</cide-ele-icon>\n </button>\n \n <!-- Last Page -->\n <button\n type=\"button\"\n (click)=\"onPageChange(totalPages())\"\n [disabled]=\"currentPage() === totalPages() || isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-gray-700 hover:tw-bg-gray-100 tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n title=\"Last page\">\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">last_page</cide-ele-icon>\n </button>\n \n </div>\n\n <!-- Quick Jump and Refresh -->\n @if (paginationConfig.showQuickJump || paginationConfig.showRefresh) {\n <div class=\"tw-flex tw-items-center tw-space-x-1 tw-border-l tw-border-gray-200 tw-pl-2\">\n \n <!-- Quick Jump -->\n @if (paginationConfig.showQuickJump) {\n <div class=\"tw-flex tw-items-center tw-space-x-1\">\n <span class=\"tw-text-sm tw-text-gray-700\">Go to:</span>\n <div class=\"tw-w-16\">\n <cide-ele-input id=\"jump-to-page-input\" type=\"number\" [labelHide]=\"true\" [hideHelperAndErrorText]=\"true\"\n [(ngModel)]=\"jumpToPage\" [min]=\"1\" [max]=\"totalPages()\"\n [disabled]=\"isRefreshing()\"\n size=\"xs\"\n (keydown.enter)=\"onJumpToPage()\">\n </cide-ele-input>\n </div>\n <button\n type=\"button\"\n (click)=\"onJumpToPage()\"\n [disabled]=\"isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-p-0 tw-rounded tw-text-xs tw-font-medium tw-bg-gray-100 tw-text-gray-700 tw-border tw-border-gray-300 hover:tw-bg-gray-200 tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n title=\"Go to page\">\n Go\n </button>\n </div>\n }\n \n <!-- Refresh Button -->\n @if (paginationConfig.showRefresh) {\n <button\n type=\"button\"\n (click)=\"onRefresh()\"\n [disabled]=\"isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-gray-700 hover:tw-bg-gray-100 tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n title=\"Refresh\">\n @if (isRefreshing()) {\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4 tw-animate-spin\">refresh</cide-ele-icon>\n } @else {\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">refresh</cide-ele-icon>\n }\n </button>\n }\n </div>\n }\n \n </div>\n </div>\n </div>\n }\n\n <!-- Manage Columns Modal -->\n @if (showManageColumnsModal()) {\n <div class=\"tw-fixed tw-inset-0 tw-z-50 tw-overflow-y-auto\" \n (click)=\"closeManageColumnsModal()\"\n style=\"background-color: rgba(0, 0, 0, 0.5);\">\n <div class=\"tw-flex tw-items-center tw-justify-center tw-min-h-screen tw-p-4\">\n <div class=\"tw-bg-white tw-rounded-lg tw-shadow-xl tw-max-w-md tw-w-full tw-max-h-[80vh] tw-overflow-hidden tw-flex tw-flex-col\"\n (click)=\"$event.stopPropagation()\">\n <!-- Modal Header -->\n <div class=\"tw-px-6 tw-py-4 tw-border-b tw-border-gray-200 tw-flex tw-items-center tw-justify-between\">\n <h3 class=\"tw-text-lg tw-font-semibold tw-text-gray-900\">Manage Columns</h3>\n <button type=\"button\"\n class=\"tw-text-gray-400 hover:tw-text-gray-600 tw-transition-colors\"\n (click)=\"closeManageColumnsModal()\">\n <cide-ele-icon class=\"tw-w-5 tw-h-5\">close</cide-ele-icon>\n </button>\n </div>\n \n <!-- Modal Body -->\n <div class=\"tw-px-6 tw-py-4 tw-overflow-y-auto tw-flex-1\">\n <p class=\"tw-text-sm tw-text-gray-600 tw-mb-4\">Select columns to show or hide:</p>\n <div class=\"tw-space-y-2\">\n @for (column of mergedConfig().columns; track column.key) {\n <label class=\"tw-flex tw-items-center tw-px-3 tw-py-2 tw-rounded-md hover:tw-bg-gray-50 tw-cursor-pointer tw-transition-colors\">\n <input type=\"checkbox\"\n class=\"tw-mr-3 tw-rounded tw-border-gray-300 tw-text-blue-600 focus:tw-ring-blue-500\"\n [checked]=\"!isColumnHidden(column.key)\"\n (change)=\"toggleColumnVisibility(column.key); $event.stopPropagation()\">\n <span class=\"tw-text-sm tw-text-gray-700 tw-flex-1\">{{ column.header }}</span>\n @if (isColumnHidden(column.key)) {\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-gray-400 tw-ml-2\">visibility_off</cide-ele-icon>\n } @else {\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-gray-400 tw-ml-2\">visibility</cide-ele-icon>\n }\n </label>\n }\n </div>\n </div>\n \n <!-- Modal Footer -->\n <div class=\"tw-px-6 tw-py-4 tw-border-t tw-border-gray-200 tw-flex tw-items-center tw-justify-end tw-gap-3\">\n <button type=\"button\"\n class=\"tw-px-4 tw-py-2 tw-text-sm tw-font-medium tw-text-gray-700 tw-bg-white tw-border tw-border-gray-300 tw-rounded-md hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"closeManageColumnsModal()\">\n Close\n </button>\n <button type=\"button\"\n class=\"tw-px-4 tw-py-2 tw-text-sm tw-font-medium tw-text-white tw-bg-blue-600 tw-border tw-border-transparent tw-rounded-md hover:tw-bg-blue-700 tw-transition-colors\"\n (click)=\"onColumnReset(); closeManageColumnsModal()\">\n Reset All\n </button>\n </div>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".data-grid-container{width:100%;display:flex;flex-direction:column;min-height:400px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;color:var(--cide-ele-text-primary);background-color:var(--cide-ele-grid-bg, var(--cide-ele-bg-primary, #ffffff));border-radius:0;overflow:hidden;box-shadow:var(--cide-ele-shadow-sm);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.data-grid-container.tw-h-full{height:100%;min-height:100%}.data-grid-container .tw-overflow-x-auto{scrollbar-width:thin;scrollbar-color:var(--cide-ele-scrollbar-thumb, #d1d5db) var(--cide-ele-scrollbar-track, #f9fafb)}.data-grid-container .tw-overflow-x-auto.tw-flex-1{flex:1;min-height:0}.data-grid-container .tw-overflow-x-auto::-webkit-scrollbar{height:6px}.data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-track{background:var(--cide-ele-scrollbar-track, #f9fafb)}.data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb{background:var(--cide-ele-scrollbar-thumb, #d1d5db);border-radius:3px}.data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover{background:var(--cide-ele-scrollbar-thumb-hover, #9ca3af)}.data-grid-container table{min-height:300px;border-collapse:separate;border-spacing:0;width:100%;background-color:var(--cide-ele-grid-bg)}.data-grid-container thead{background-color:var(--cide-ele-grid-bg-header);border-bottom:2px solid var(--cide-ele-grid-border-header);position:relative;z-index:100}.data-grid-container thead th{background:transparent;color:var(--cide-ele-grid-text-header);font-weight:500;font-size:12px;text-transform:none;letter-spacing:-.01em;padding:4px 10px;border-bottom:1px solid var(--cide-ele-grid-border);text-align:left;white-space:nowrap;position:relative;transition:all .2s cubic-bezier(.4,0,.2,1)}.data-grid-container thead th:first-child{padding-left:12px}.data-grid-container thead th:last-child{padding-right:12px}.data-grid-container thead th:hover{background-color:var(--cide-ele-grid-bg-header-hover, var(--cide-ele-grid-bg-hover, var(--cide-ele-bg-hover)))}.data-grid-container thead th .column-menu-trigger{opacity:1;transition:all .2s cubic-bezier(.4,0,.2,1);margin-left:4px;cursor:pointer;padding:2px;border-radius:4px}.data-grid-container thead th .column-menu-trigger:hover{background-color:var(--cide-ele-bg-tertiary)}.data-grid-container tbody{background-color:var(--cide-ele-grid-bg, #ffffff)}.data-grid-container tbody td{padding:6px 10px;border-bottom:1px solid var(--cide-ele-grid-border, #e5e7eb);color:var(--cide-ele-grid-text, #1f2937);font-size:13px;vertical-align:middle;line-height:1.5;transition:all .2s cubic-bezier(.4,0,.2,1);background-color:transparent}.data-grid-container tbody td:first-child{padding-left:12px}.data-grid-container tbody td:last-child{padding-right:12px}.data-grid-container tbody tr{background-color:var(--cide-ele-grid-bg, #ffffff);transition:all .2s cubic-bezier(.4,0,.2,1)}.data-grid-container tbody tr td{color:var(--cide-ele-grid-text, #1f2937)}.data-grid-container tbody tr:hover,.data-grid-container tbody tr.data-grid-row:hover,.data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover{background-color:var(--cide-ele-grid-bg-hover)!important;border-left:2px solid transparent}.data-grid-container tbody tr:hover td,.data-grid-container tbody tr.data-grid-row:hover td,.data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover td{background-color:transparent!important;border-bottom-color:var(--cide-ele-grid-border);color:var(--cide-ele-grid-text)!important}.data-grid-container tbody tr:active{background-color:var(--cide-ele-bg-active);transform:scale(.999)}.data-grid-container tbody tr:active td{color:var(--cide-ele-grid-text)}.data-grid-container.tw-h-full table,.data-grid-container.tw-h-full tbody{height:100%}.data-grid-container.tw-table-striped tbody tr:nth-child(2n){background-color:var(--cide-ele-grid-bg-striped);border-left:1px solid transparent}.data-grid-container.tw-table-striped tbody tr:nth-child(2n):hover{background-color:var(--cide-ele-grid-bg-hover);border-left:2px solid var(--cide-ele-grid-border-hover)}.data-grid-container.tw-table-striped tbody tr:nth-child(2n):hover td{color:var(--cide-ele-grid-text)}.data-grid-container.tw-table-striped tbody tr:nth-child(2n) td{color:var(--cide-ele-grid-text)}.data-grid-container tbody tr.data-grid-group-row{background-color:var(--cide-ele-grid-bg-group)!important}.data-grid-container tbody tr.data-grid-group-row td{color:var(--cide-ele-grid-text)}.data-grid-container tbody tr.data-grid-group-row:hover{background-color:var(--cide-ele-grid-bg-hover)!important}.data-grid-container tbody tr.data-grid-group-row:hover td{color:var(--cide-ele-grid-text)}.data-grid-container.tw-table-sm thead th{padding:8px 10px;font-size:11px}.data-grid-container.tw-table-sm thead th:first-child{padding-left:16px}.data-grid-container.tw-table-sm thead th:last-child{padding-right:16px}.data-grid-container.tw-table-sm tbody td{padding:8px 10px;font-size:12px;line-height:1.4}.data-grid-container.tw-table-sm tbody td:first-child{padding-left:16px}.data-grid-container.tw-table-sm tbody td:last-child{padding-right:16px}.data-grid-container tbody tr.tw-cursor-pointer:hover{background-color:var(--cide-ele-grid-bg-hover)!important;border-left:2px solid var(--cide-ele-grid-border-hover)!important}.data-grid-container tbody tr.tw-cursor-pointer:hover td{background-color:transparent!important;color:var(--cide-ele-grid-text)!important}.data-grid-container.loading-overlay{position:relative}.data-grid-container.loading-overlay:after{content:\"\";position:absolute;inset:0;background:#ffffffd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:10;animation:fadeIn .2s cubic-bezier(.4,0,.2,1)}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.data-grid-container .tw-animate-pulse div{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.data-grid-container .data-grid-action-buttons button{position:relative;border:1px solid rgba(0,0,0,.08);background:transparent;outline:none;cursor:pointer;-webkit-tap-highlight-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:6px;transition:all .2s cubic-bezier(.4,0,.2,1)}.data-grid-container .data-grid-action-buttons button cide-ele-icon{color:#6b7280;transition:all .2s cubic-bezier(.4,0,.2,1)}.data-grid-container .data-grid-action-buttons button:hover:not(:disabled){background-color:#0000000a;border-color:#0000001f}.data-grid-container .data-grid-action-buttons button:hover:not(:disabled) cide-ele-icon{color:#374151;transform:scale(1.05)}.data-grid-container .data-grid-action-buttons button:active:not(:disabled){background-color:#00000014;border-color:#00000026;transform:scale(.95)}.data-grid-container .data-grid-action-buttons button:active:not(:disabled) cide-ele-icon{transform:scale(.98)}.data-grid-container .data-grid-action-buttons button:focus-visible{outline:none;border-color:#3b82f64d;box-shadow:0 0 0 3px #3b82f61f}.data-grid-container .data-grid-action-buttons button:disabled{cursor:not-allowed;opacity:.3;background:transparent!important;border-color:#0000000d}.data-grid-container .action-buttons{display:flex;gap:.25rem}.data-grid-container .action-buttons button{transition:all .15s ease-in-out}.data-grid-container .action-buttons button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 2px 4px #0000001a}.data-grid-container .action-buttons button:disabled{cursor:not-allowed;opacity:.5}.data-grid-container .pagination-controls{padding:12px 20px;border-top:2px solid var(--cide-ele-grid-border-header);background-color:var(--cide-ele-grid-bg-header)}.data-grid-container .pagination-controls button{transition:all .2s cubic-bezier(.4,0,.2,1);border-radius:6px}.data-grid-container .pagination-controls button:hover:not(:disabled){background-color:#0000000a;transform:scale(1.02)}.data-grid-container .pagination-controls button:active:not(:disabled){transform:scale(.98);background-color:#00000014}.data-grid-container .pagination-controls button:disabled{cursor:not-allowed;opacity:.3}.data-grid-container .pagination-controls button.active{background-color:#3b82f61a;color:#3b82f6;font-weight:500;box-shadow:0 0 0 1px #3b82f633}.data-grid-container .pagination-controls input[type=number]{transition:all .2s cubic-bezier(.4,0,.2,1);border:1px solid rgba(0,0,0,.06);border-radius:6px}.data-grid-container .pagination-controls input[type=number]:hover{border-color:#0000001a}.data-grid-container .pagination-controls input[type=number]:focus{outline:none;border-color:#3b82f64d;box-shadow:0 0 0 3px #3b82f614;background-color:#fff}.data-grid-container .status-badge{font-weight:500;letter-spacing:-.01em;padding:4px 12px;border-radius:12px;font-size:12px;display:inline-flex;align-items:center;transition:all .2s cubic-bezier(.4,0,.2,1)}.data-grid-container .status-badge.active{background-color:#34d39926;color:#059669;border:1px solid rgba(52,211,153,.3)}.data-grid-container .status-badge.active:hover{background-color:#34d39933}.data-grid-container .status-badge.inactive{background-color:#f8717126;color:#dc2626;border:1px solid rgba(248,113,113,.3)}.data-grid-container .status-badge.inactive:hover{background-color:#f8717133}.data-grid-container .data-grid-search-input ::ng-deep .cide-input-wrapper{transition:all .2s cubic-bezier(.4,0,.2,1)}.data-grid-container .data-grid-search-input ::ng-deep .cide-input-wrapper:hover:not(:has(input:disabled)){background-color:#00000005}.data-grid-container .data-grid-search-input ::ng-deep input{font-size:13px;font-weight:400;color:#1f2937;transition:all .2s cubic-bezier(.4,0,.2,1);border-radius:8px}.data-grid-container .data-grid-search-input ::ng-deep input::placeholder{color:#9ca3af;font-weight:400}.data-grid-container .data-grid-search-input ::ng-deep input:focus{outline:none;border-color:#3b82f64d;box-shadow:0 0 0 3px #3b82f614;background-color:#fff}.data-grid-container .data-grid-search-input ::ng-deep input:disabled{background-color:#00000005;color:#9ca3af;cursor:not-allowed}.data-grid-container .data-grid-search-input ::ng-deep .cide-input-leading-icon cide-ele-icon{color:#9ca3af;transition:color .2s cubic-bezier(.4,0,.2,1)}.data-grid-container .data-grid-search-input ::ng-deep input:focus~.cide-input-leading-icon cide-ele-icon,.data-grid-container .data-grid-search-input ::ng-deep .cide-input-wrapper:has(input:focus) .cide-input-leading-icon cide-ele-icon{color:#6b7280}.data-grid-container .data-grid-search-input ::ng-deep .cide-input-wrapper[data-fill=outline]{border:1px solid #e5e7eb;background-color:#fafafa;border-radius:8px}.data-grid-container .data-grid-search-input ::ng-deep .cide-input-wrapper[data-fill=outline]:hover:not(:has(input:disabled)){border-color:#d1d5db;background-color:#fff}.data-grid-container .data-grid-search-input ::ng-deep .cide-input-wrapper[data-fill=outline]:has(input:focus){border-color:#3b82f64d;background-color:#fff}.data-grid-container .search-input{position:relative}.data-grid-container .search-input input{transition:all .15s ease-in-out}.data-grid-container .search-input input:focus{box-shadow:0 0 0 3px #3b82f61a}.data-grid-container .search-input .search-icon{pointer-events:none}.data-grid-container .column-menu-dropdown{animation:dropdownFadeIn .15s cubic-bezier(.4,0,.2,1);box-shadow:0 10px 25px #0000001a,0 4px 10px #0000000d;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border:1px solid rgba(0,0,0,.05);position:absolute!important;z-index:9999!important}.data-grid-container .column-menu-dropdown button{font-size:13px;font-weight:400;letter-spacing:-.01em;text-align:left;transition:all .15s cubic-bezier(.4,0,.2,1)}.data-grid-container .column-menu-dropdown button:hover{background-color:#3b82f60d;color:#1f2937}.data-grid-container .column-menu-dropdown button:hover cide-ele-icon{color:#3b82f6}.data-grid-container .column-menu-dropdown button:active{background-color:#3b82f61a;transform:scale(.98)}.data-grid-container .column-menu-dropdown .tw-uppercase{letter-spacing:.05em}@keyframes dropdownFadeIn{0%{opacity:0;transform:translateY(-8px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.data-grid-container .empty-state{padding:4rem 2rem;text-align:center}.data-grid-container .empty-state svg{margin:0 auto 1.5rem;opacity:.3;transition:all .3s cubic-bezier(.4,0,.2,1)}.data-grid-container .empty-state svg:hover{opacity:.5;transform:scale(1.05)}.data-grid-container .empty-state h3{margin-bottom:.75rem;font-weight:600;color:#374151;font-size:16px;letter-spacing:-.01em}.data-grid-container .empty-state p{color:#6b7280;font-size:14px;line-height:1.5}.data-grid-container.tw-h-full tbody tr:only-child td{height:100%;vertical-align:middle}.data-grid-container.tw-h-full table.empty-table{height:100%}.data-grid-container.tw-h-full tbody tr:only-child{height:100%}@media (max-width: 640px){.data-grid-container .tw-px-6{padding-left:1rem;padding-right:1rem}.data-grid-container .pagination-controls{flex-direction:column;gap:1rem}.data-grid-container .pagination-controls .flex{justify-content:center}.data-grid-container .pagination-info{display:none}.data-grid-container .search-actions{flex-direction:column;gap:1rem}}.data-grid-container :host .tw-bg-white{background-color:#fff!important}.data-grid-container :host .tw-bg-gray-50{background-color:#fafafa!important}.data-grid-container :host .tw-bg-gray-100{background-color:#f3f4f6!important}.data-grid-container :host thead{background-color:var(--cide-ele-grid-bg-header, #fafafa)!important}.data-grid-container :host thead th{background-color:transparent!important;color:var(--cide-ele-grid-text-header, #6b7280)!important}.data-grid-container :host thead th:hover{background-color:var(--cide-ele-grid-bg-header-hover, var(--cide-ele-grid-bg-hover, #f3f4f6))!important}.data-grid-container :host .data-grid-group-row{background-color:#f3f4f6!important}.data-grid-container :host tbody{background-color:#fff!important}.data-grid-container :host tbody tr{background-color:#fff!important}.data-grid-container :host tbody tr td{background-color:transparent}.data-grid-container :host.tw-table-striped tbody tr:nth-child(2n){background-color:#fafafa!important}.data-grid-container :host .tw-text-gray-900{color:#1f2937!important}.data-grid-container :host .tw-text-gray-600{color:#4b5563!important}.data-grid-container :host .tw-text-gray-500{color:#6b7280!important}.data-grid-container :host .tw-text-gray-400{color:#9ca3af!important}.data-grid-container :host .tw-text-gray-700{color:#374151!important}.data-grid-container :host .tw-border-gray-200,.data-grid-container :host .tw-divide-gray-200{border-color:#e5e7eb!important}.data-grid-container :host .tw-border-gray-300{border-color:#d1d5db!important}.data-grid-container :host tbody tr:hover,.data-grid-container :host tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host tbody tr.data-grid-row:hover{background-color:var(--cide-ele-grid-bg-hover)!important}.data-grid-container :host tbody tr:hover td,.data-grid-container :host tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host tbody tr.data-grid-row:hover td{background-color:transparent!important;color:var(--cide-ele-grid-text)!important}.data-grid-container :host tbody tr:hover .tw-text-gray-900,.data-grid-container :host tbody tr:hover .tw-text-gray-700,.data-grid-container :host tbody tr:hover .tw-text-gray-600,.data-grid-container :host tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host tbody tr.data-grid-row:hover .tw-text-gray-600{color:var(--cide-ele-grid-text)!important}.data-grid-container :host tbody tr.tw-cursor-pointer:hover{background-color:var(--cide-ele-grid-bg-hover)!important;border-left:2px solid var(--cide-ele-grid-border-hover)!important}.data-grid-container :host tbody tr.tw-cursor-pointer:hover td{background-color:transparent!important;color:var(--cide-ele-grid-text)!important}.data-grid-container :host .tw-overflow-x-auto{scrollbar-width:thin;scrollbar-color:#d1d5db #f9fafb}.data-grid-container :host .tw-overflow-x-auto::-webkit-scrollbar-track{background:#f9fafb!important}.data-grid-container :host .tw-overflow-x-auto::-webkit-scrollbar-thumb{background:#d1d5db!important}.data-grid-container :host .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover{background:#9ca3af!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-white,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-white,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-white{background-color:#fff!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-gray-50,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-gray-50,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-gray-50{background-color:#fafafa!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-gray-100,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-gray-100,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-gray-100{background-color:#f3f4f6!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .data-grid-group-row,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .data-grid-group-row,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .data-grid-group-row{background-color:#f3f4f6!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody{background-color:#fff!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr{background-color:#fff!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr td,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr td,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr td{background-color:transparent}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container.tw-table-striped tbody tr:nth-child(2n),::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container.tw-table-striped tbody tr:nth-child(2n),::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container.tw-table-striped tbody tr:nth-child(2n){background-color:#fafafa!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-900,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-900,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-900{color:#1f2937!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-600,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-600,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-600{color:#4b5563!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-500,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-500,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-500{color:#6b7280!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-400,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-400,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-400{color:#9ca3af!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-700,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-700,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-700{color:#374151!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-border-gray-200,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-divide-gray-200,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-border-gray-200,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-divide-gray-200,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-border-gray-200,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-divide-gray-200{border-color:#e5e7eb!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-border-gray-300,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-border-gray-300,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-border-gray-300{border-color:#d1d5db!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover{background-color:var(--cide-ele-grid-bg-hover)!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover td,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover td,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover td,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover td,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover td,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover td,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover td,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover td,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover td{background-color:transparent!important;color:var(--cide-ele-grid-text)!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-900,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-700,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-600,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-900,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-700,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-600,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-900,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-700,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-600,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-900,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-700,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-600,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-900,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-700,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-600,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-900,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-700,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-600{color:var(--cide-ele-grid-text)!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.tw-cursor-pointer:hover,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.tw-cursor-pointer:hover,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.tw-cursor-pointer:hover{background-color:var(--cide-ele-grid-bg-hover)!important;border-left:2px solid var(--cide-ele-grid-border-hover)!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.tw-cursor-pointer:hover td,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.tw-cursor-pointer:hover td,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.tw-cursor-pointer:hover td{background-color:transparent!important;color:var(--cide-ele-grid-text)!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto{scrollbar-width:thin;scrollbar-color:#d1d5db #f9fafb}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-track,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-track,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-track{background:#f9fafb!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb{background:#d1d5db!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover{background:#9ca3af!important}.data-grid-container :host-context(.dark-mode) .tw-bg-white,.data-grid-container :host-context([data-theme=dark]) .tw-bg-white,.data-grid-container :host-context(body.dark-mode) .tw-bg-white,.data-grid-container :host-context(html.dark-mode) .tw-bg-white,.data-grid-container :host-context([data-theme=dark] body) .tw-bg-white,.data-grid-container :host-context([data-theme=dark] html) .tw-bg-white{background-color:var(--cide-ele-grid-bg, #1f2937)!important}.data-grid-container :host-context(.dark-mode) .tw-bg-gray-50,.data-grid-container :host-context([data-theme=dark]) .tw-bg-gray-50,.data-grid-container :host-context(body.dark-mode) .tw-bg-gray-50,.data-grid-container :host-context(html.dark-mode) .tw-bg-gray-50,.data-grid-container :host-context([data-theme=dark] body) .tw-bg-gray-50,.data-grid-container :host-context([data-theme=dark] html) .tw-bg-gray-50{background-color:var(--cide-ele-grid-bg-header, #374151)!important}.data-grid-container :host-context(.dark-mode) .tw-bg-gray-100,.data-grid-container :host-context([data-theme=dark]) .tw-bg-gray-100,.data-grid-container :host-context(body.dark-mode) .tw-bg-gray-100,.data-grid-container :host-context(html.dark-mode) .tw-bg-gray-100,.data-grid-container :host-context([data-theme=dark] body) .tw-bg-gray-100,.data-grid-container :host-context([data-theme=dark] html) .tw-bg-gray-100{background-color:var(--cide-ele-grid-bg-group, #374151)!important}.data-grid-container :host-context(.dark-mode) .data-grid-group-row,.data-grid-container :host-context([data-theme=dark]) .data-grid-group-row,.data-grid-container :host-context(body.dark-mode) .data-grid-group-row,.data-grid-container :host-context(html.dark-mode) .data-grid-group-row,.data-grid-container :host-context([data-theme=dark] body) .data-grid-group-row,.data-grid-container :host-context([data-theme=dark] html) .data-grid-group-row{background-color:var(--cide-ele-grid-bg-group, #374151)!important}.data-grid-container :host-context(.dark-mode) tbody,.data-grid-container :host-context([data-theme=dark]) tbody,.data-grid-container :host-context(body.dark-mode) tbody,.data-grid-container :host-context(html.dark-mode) tbody,.data-grid-container :host-context([data-theme=dark] body) tbody,.data-grid-container :host-context([data-theme=dark] html) tbody{background-color:var(--cide-ele-grid-bg, #1f2937)!important}.data-grid-container :host-context(.dark-mode) tbody tr,.data-grid-container :host-context([data-theme=dark]) tbody tr,.data-grid-container :host-context(body.dark-mode) tbody tr,.data-grid-container :host-context(html.dark-mode) tbody tr,.data-grid-container :host-context([data-theme=dark] body) tbody tr,.data-grid-container :host-context([data-theme=dark] html) tbody tr{background-color:var(--cide-ele-grid-bg, #1f2937)!important}.data-grid-container :host-context(.dark-mode) tbody tr td,.data-grid-container :host-context([data-theme=dark]) tbody tr td,.data-grid-container :host-context(body.dark-mode) tbody tr td,.data-grid-container :host-context(html.dark-mode) tbody tr td,.data-grid-container :host-context([data-theme=dark] body) tbody tr td,.data-grid-container :host-context([data-theme=dark] html) tbody tr td{background-color:transparent}.data-grid-container :host-context(.dark-mode).tw-table-striped tbody tr:nth-child(2n),.data-grid-container :host-context([data-theme=dark]).tw-table-striped tbody tr:nth-child(2n),.data-grid-container :host-context(body.dark-mode).tw-table-striped tbody tr:nth-child(2n),.data-grid-container :host-context(html.dark-mode).tw-table-striped tbody tr:nth-child(2n),.data-grid-container :host-context([data-theme=dark] body).tw-table-striped tbody tr:nth-child(2n),.data-grid-container :host-context([data-theme=dark] html).tw-table-striped tbody tr:nth-child(2n){background-color:var(--cide-ele-grid-bg-striped, #111827)!important}.data-grid-container :host-context(.dark-mode) .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark]) .tw-text-gray-900,.data-grid-container :host-context(body.dark-mode) .tw-text-gray-900,.data-grid-container :host-context(html.dark-mode) .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] body) .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] html) .tw-text-gray-900{color:var(--cide-ele-text-primary, #f9fafb)!important}.data-grid-container :host-context(.dark-mode) .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark]) .tw-text-gray-600,.data-grid-container :host-context(body.dark-mode) .tw-text-gray-600,.data-grid-container :host-context(html.dark-mode) .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] body) .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] html) .tw-text-gray-600{color:var(--cide-ele-text-secondary, #d1d5db)!important}.data-grid-container :host-context(.dark-mode) .tw-text-gray-500,.data-grid-container :host-context([data-theme=dark]) .tw-text-gray-500,.data-grid-container :host-context(body.dark-mode) .tw-text-gray-500,.data-grid-container :host-context(html.dark-mode) .tw-text-gray-500,.data-grid-container :host-context([data-theme=dark] body) .tw-text-gray-500,.data-grid-container :host-context([data-theme=dark] html) .tw-text-gray-500{color:var(--cide-ele-text-tertiary, #9ca3af)!important}.data-grid-container :host-context(.dark-mode) .tw-text-gray-400,.data-grid-container :host-context([data-theme=dark]) .tw-text-gray-400,.data-grid-container :host-context(body.dark-mode) .tw-text-gray-400,.data-grid-container :host-context(html.dark-mode) .tw-text-gray-400,.data-grid-container :host-context([data-theme=dark] body) .tw-text-gray-400,.data-grid-container :host-context([data-theme=dark] html) .tw-text-gray-400{color:var(--cide-ele-text-tertiary, #9ca3af)!important}.data-grid-container :host-context(.dark-mode) .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark]) .tw-text-gray-700,.data-grid-container :host-context(body.dark-mode) .tw-text-gray-700,.data-grid-container :host-context(html.dark-mode) .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] body) .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] html) .tw-text-gray-700{color:var(--cide-ele-text-secondary, #d1d5db)!important}.data-grid-container :host-context(.dark-mode) .tw-border-gray-200,.data-grid-container :host-context(.dark-mode) .tw-divide-gray-200,.data-grid-container :host-context([data-theme=dark]) .tw-border-gray-200,.data-grid-container :host-context([data-theme=dark]) .tw-divide-gray-200,.data-grid-container :host-context(body.dark-mode) .tw-border-gray-200,.data-grid-container :host-context(body.dark-mode) .tw-divide-gray-200,.data-grid-container :host-context(html.dark-mode) .tw-border-gray-200,.data-grid-container :host-context(html.dark-mode) .tw-divide-gray-200,.data-grid-container :host-context([data-theme=dark] body) .tw-border-gray-200,.data-grid-container :host-context([data-theme=dark] body) .tw-divide-gray-200,.data-grid-container :host-context([data-theme=dark] html) .tw-border-gray-200,.data-grid-container :host-context([data-theme=dark] html) .tw-divide-gray-200{border-color:var(--cide-ele-grid-border, #374151)!important}.data-grid-container :host-context(.dark-mode) .tw-border-gray-300,.data-grid-container :host-context([data-theme=dark]) .tw-border-gray-300,.data-grid-container :host-context(body.dark-mode) .tw-border-gray-300,.data-grid-container :host-context(html.dark-mode) .tw-border-gray-300,.data-grid-container :host-context([data-theme=dark] body) .tw-border-gray-300,.data-grid-container :host-context([data-theme=dark] html) .tw-border-gray-300{border-color:var(--cide-ele-grid-border, #374151)!important}.data-grid-container :host-context(.dark-mode) tbody tr:hover,.data-grid-container :host-context(.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host-context(.dark-mode) tbody tr.data-grid-row:hover,.data-grid-container :host-context([data-theme=dark]) tbody tr:hover,.data-grid-container :host-context([data-theme=dark]) tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host-context([data-theme=dark]) tbody tr.data-grid-row:hover,.data-grid-container :host-context(body.dark-mode) tbody tr:hover,.data-grid-container :host-context(body.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host-context(body.dark-mode) tbody tr.data-grid-row:hover,.data-grid-container :host-context(html.dark-mode) tbody tr:hover,.data-grid-container :host-context(html.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host-context(html.dark-mode) tbody tr.data-grid-row:hover,.data-grid-container :host-context([data-theme=dark] body) tbody tr:hover,.data-grid-container :host-context([data-theme=dark] body) tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host-context([data-theme=dark] body) tbody tr.data-grid-row:hover,.data-grid-container :host-context([data-theme=dark] html) tbody tr:hover,.data-grid-container :host-context([data-theme=dark] html) tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host-context([data-theme=dark] html) tbody tr.data-grid-row:hover{background-color:var(--cide-ele-grid-bg-hover, #374151)!important}.data-grid-container :host-context(.dark-mode) tbody tr:hover td,.data-grid-container :host-context(.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host-context(.dark-mode) tbody tr.data-grid-row:hover td,.data-grid-container :host-context([data-theme=dark]) tbody tr:hover td,.data-grid-container :host-context([data-theme=dark]) tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host-context([data-theme=dark]) tbody tr.data-grid-row:hover td,.data-grid-container :host-context(body.dark-mode) tbody tr:hover td,.data-grid-container :host-context(body.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host-context(body.dark-mode) tbody tr.data-grid-row:hover td,.data-grid-container :host-context(html.dark-mode) tbody tr:hover td,.data-grid-container :host-context(html.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host-context(html.dark-mode) tbody tr.data-grid-row:hover td,.data-grid-container :host-context([data-theme=dark] body) tbody tr:hover td,.data-grid-container :host-context([data-theme=dark] body) tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host-context([data-theme=dark] body) tbody tr.data-grid-row:hover td,.data-grid-container :host-context([data-theme=dark] html) tbody tr:hover td,.data-grid-container :host-context([data-theme=dark] html) tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host-context([data-theme=dark] html) tbody tr.data-grid-row:hover td{background-color:transparent!important;color:var(--cide-ele-text-primary, #f9fafb)!important}.data-grid-container :host-context(.dark-mode) tbody tr:hover .tw-text-gray-900,.data-grid-container :host-context(.dark-mode) tbody tr:hover .tw-text-gray-700,.data-grid-container :host-context(.dark-mode) tbody tr:hover .tw-text-gray-600,.data-grid-container :host-context(.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host-context(.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host-context(.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host-context(.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host-context(.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host-context(.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark]) tbody tr:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark]) tbody tr:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark]) tbody tr:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark]) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark]) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark]) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark]) tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark]) tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark]) tbody tr.data-grid-row:hover .tw-text-gray-600,.data-grid-container :host-context(body.dark-mode) tbody tr:hover .tw-text-gray-900,.data-grid-container :host-context(body.dark-mode) tbody tr:hover .tw-text-gray-700,.data-grid-container :host-context(body.dark-mode) tbody tr:hover .tw-text-gray-600,.data-grid-container :host-context(body.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host-context(body.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host-context(body.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host-context(body.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host-context(body.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host-context(body.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-600,.data-grid-container :host-context(html.dark-mode) tbody tr:hover .tw-text-gray-900,.data-grid-container :host-context(html.dark-mode) tbody tr:hover .tw-text-gray-700,.data-grid-container :host-context(html.dark-mode) tbody tr:hover .tw-text-gray-600,.data-grid-container :host-context(html.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host-context(html.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host-context(html.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host-context(html.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host-context(html.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host-context(html.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] body) tbody tr:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] body) tbody tr:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] body) tbody tr:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] body) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] body) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] body) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] body) tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] body) tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] body) tbody tr.data-grid-row:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] html) tbody tr:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] html) tbody tr:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] html) tbody tr:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] html) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] html) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] html) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] html) tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] html) tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] html) tbody tr.data-grid-row:hover .tw-text-gray-600{color:var(--cide-ele-text-primary, #f9fafb)!important}.data-grid-container :host-context(.dark-mode) tbody tr.tw-cursor-pointer:hover,.data-grid-container :host-context([data-theme=dark]) tbody tr.tw-cursor-pointer:hover,.data-grid-container :host-context(body.dark-mode) tbody tr.tw-cursor-pointer:hover,.data-grid-container :host-context(html.dark-mode) tbody tr.tw-cursor-pointer:hover,.data-grid-container :host-context([data-theme=dark] body) tbody tr.tw-cursor-pointer:hover,.data-grid-container :host-context([data-theme=dark] html) tbody tr.tw-cursor-pointer:hover{background-color:var(--cide-ele-grid-bg-hover, #374151)!important;border-left:2px solid var(--cide-ele-grid-border-hover, #60a5fa)!important}.data-grid-container :host-context(.dark-mode) tbody tr.tw-cursor-pointer:hover td,.data-grid-container :host-context([data-theme=dark]) tbody tr.tw-cursor-pointer:hover td,.data-grid-container :host-context(body.dark-mode) tbody tr.tw-cursor-pointer:hover td,.data-grid-container :host-context(html.dark-mode) tbody tr.tw-cursor-pointer:hover td,.data-grid-container :host-context([data-theme=dark] body) tbody tr.tw-cursor-pointer:hover td,.data-grid-container :host-context([data-theme=dark] html) tbody tr.tw-cursor-pointer:hover td{background-color:transparent!important;color:var(--cide-ele-text-primary, #f9fafb)!important}.data-grid-container :host-context(.dark-mode).drag-drop-enabled tbody tr:hover,.data-grid-container :host-context([data-theme=dark]).drag-drop-enabled tbody tr:hover,.data-grid-container :host-context(body.dark-mode).drag-drop-enabled tbody tr:hover,.data-grid-container :host-context(html.dark-mode).drag-drop-enabled tbody tr:hover,.data-grid-container :host-context([data-theme=dark] body).drag-drop-enabled tbody tr:hover,.data-grid-container :host-context([data-theme=dark] html).drag-drop-enabled tbody tr:hover{background-color:var(--cide-ele-grid-bg-hover, #374151)!important}.data-grid-container :host-context(.dark-mode).drag-drop-enabled tbody tr:hover td,.data-grid-container :host-context([data-theme=dark]).drag-drop-enabled tbody tr:hover td,.data-grid-container :host-context(body.dark-mode).drag-drop-enabled tbody tr:hover td,.data-grid-container :host-context(html.dark-mode).drag-drop-enabled tbody tr:hover td,.data-grid-container :host-context([data-theme=dark] body).drag-drop-enabled tbody tr:hover td,.data-grid-container :host-context([data-theme=dark] html).drag-drop-enabled tbody tr:hover td{color:var(--cide-ele-text-primary, #f9fafb)!important}.data-grid-container :host-context(.dark-mode).drag-drop-enabled tbody tr[draggable=true]:hover,.data-grid-container :host-context([data-theme=dark]).drag-drop-enabled tbody tr[draggable=true]:hover,.data-grid-container :host-context(body.dark-mode).drag-drop-enabled tbody tr[draggable=true]:hover,.data-grid-container :host-context(html.dark-mode).drag-drop-enabled tbody tr[draggable=true]:hover,.data-grid-container :host-context([data-theme=dark] body).drag-drop-enabled tbody tr[draggable=true]:hover,.data-grid-container :host-context([data-theme=dark] html).drag-drop-enabled tbody tr[draggable=true]:hover{background-color:var(--cide-ele-grid-bg-hover, #374151)!important}.data-grid-container :host-context(.dark-mode).drag-drop-enabled tbody tr[draggable=true]:hover td,.data-grid-container :host-context([data-theme=dark]).drag-drop-enabled tbody tr[draggable=true]:hover td,.data-grid-container :host-context(body.dark-mode).drag-drop-enabled tbody tr[draggable=true]:hover td,.data-grid-container :host-context(html.dark-mode).drag-drop-enabled tbody tr[draggable=true]:hover td,.data-grid-container :host-context([data-theme=dark] body).drag-drop-enabled tbody tr[draggable=true]:hover td,.data-grid-container :host-context([data-theme=dark] html).drag-drop-enabled tbody tr[draggable=true]:hover td{color:var(--cide-ele-text-primary, #f9fafb)!important}.data-grid-container.drag-drop-enabled tbody tr{transition:all .2s ease}.data-grid-container.drag-drop-enabled tbody tr:hover{background-color:var(--cide-ele-grid-bg-hover, #f9fafb)}.data-grid-container.drag-drop-enabled tbody tr:hover td{color:var(--cide-ele-grid-text, #1f2937)}.data-grid-container.drag-drop-enabled tbody tr.tw-opacity-50{background-color:#dbeafecc;border:2px dashed var(--cide-ele-brand-primary, #3b82f6);border-radius:4px}.data-grid-container.drag-drop-enabled tbody tr.tw-bg-blue-50{background-color:#eff6ffe6}.data-grid-container.drag-drop-enabled tbody tr[draggable=true]{cursor:move;position:relative}.data-grid-container.drag-drop-enabled tbody tr[draggable=true]:hover{background-color:var(--cide-ele-grid-bg-hover, #f9fafb);box-shadow:0 1px 3px #0000001a}.data-grid-container.drag-drop-enabled tbody tr[draggable=true]:hover td{color:var(--cide-ele-grid-text, #1f2937)}.data-grid-container.drag-drop-enabled tbody tr[draggable=true]:active{cursor:grabbing}.data-grid-container.drag-drop-enabled tbody tr[style*=border-top]{position:relative}.data-grid-container.drag-drop-enabled tbody tr[style*=border-top]:before{content:\"\";position:absolute;top:-2px;left:0;right:0;height:2px;background:linear-gradient(90deg,#3b82f6,#60a5fa);z-index:10}.data-grid-container.tree-enabled tbody tr td:first-child{position:relative}.data-grid-container.tree-enabled tbody tr td:first-child button{transition:all .15s ease}.data-grid-container.tree-enabled tbody tr td:first-child button:hover{background-color:var(--cide-ele-bg-tertiary);border-radius:2px}.data-grid-container.tree-enabled tbody tr td:first-child button svg{transition:transform .2s ease}.data-grid-container.tree-enabled tbody tr[style*=padding-left]{border-left:2px solid transparent}.data-grid-container.tree-enabled tbody tr[style*=padding-left]:hover{border-left-color:var(--cide-ele-border-primary)}.tree-level-0{border-bottom:2px solid var(--cide-ele-border-primary)!important;background-color:var(--cide-ele-grid-bg)}.tree-level-0:hover{background-color:var(--cide-ele-bg-hover)!important}.tree-level-0 td:first-child{font-weight:600}.tree-level-1{border-bottom:1px solid var(--cide-ele-border-secondary)!important;background-color:var(--cide-ele-grid-bg-striped)}.tree-level-1:hover{background-color:var(--cide-ele-grid-bg-hover)!important}.tree-level-1 td:first-child{font-weight:500}.tree-level-2{border-bottom:1px solid var(--cide-ele-border-secondary)!important;background-color:var(--cide-ele-bg-secondary)}.tree-level-2:hover{background-color:var(--cide-ele-bg-hover)!important}.tree-level-2 td:first-child{font-weight:400}.tree-level-deep{border-bottom:1px solid var(--cide-ele-border-primary)!important;background-color:var(--cide-ele-bg-primary)}.tree-level-deep:hover{background-color:var(--cide-ele-bg-hover)!important}.tree-level-deep td:first-child{font-weight:300}table td{box-sizing:border-box;word-wrap:break-word;overflow-wrap:break-word}table td.tw-overflow-hidden{overflow:hidden;text-overflow:ellipsis}table td:first-child{min-width:150px}table td:first-child>div{display:flex;align-items:center;min-width:0}table td:first-child>div .tw-flex{min-width:0}table td .tw-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CideInputComponent, selector: "cide-ele-input", inputs: ["fill", "label", "labelHide", "disabled", "clearInput", "labelPlacement", "labelDir", "placeholder", "leadingIcon", "trailingIcon", "helperText", "helperTextCollapse", "hideHelperAndErrorText", "errorText", "maxlength", "minlength", "required", "autocapitalize", "autocomplete", "type", "width", "id", "ngModel", "option", "min", "max", "step", "size"], outputs: ["ngModelChange"] }, { kind: "component", type: CideSelectComponent, selector: "cide-ele-select", inputs: ["label", "labelHide", "placeholder", "helperText", "errorText", "required", "disabled", "id", "size", "fill", "labelPlacement", "labelDir", "leadingIcon", "trailingIcon", "clearInput", "options", "multiple", "searchable", "showSearchInput", "loading", "valueKey", "labelKey", "treeView"], outputs: ["ngModelChange", "change", "searchChange"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton], cide-ele-button", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }] });
|
|
12666
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideEleDataGridComponent, isStandalone: true, selector: "cide-ele-data-grid", inputs: { config: "config", templateRenderers: "templateRenderers", customFormatters: "customFormatters", actionHandlers: "actionHandlers", serverSidePagination: "serverSidePagination", totalServerItems: "totalServerItems", currentServerPage: "currentServerPage", currentServerPageSize: "currentServerPageSize", dragDropEnabled: "dragDropEnabled" }, outputs: { gridEvent: "gridEvent" }, usesOnChanges: true, ngImport: i0, template: " <!-- Data Grid Component -->\n <div class=\"data-grid-container tw-bg-white tw-shadow tw-overflow-visible tw-flex tw-flex-col\" \n [ngClass]=\"[\n mergedConfig().tableClass || '',\n mergedConfig().fullHeight ? 'tw-h-full' : '',\n isDragDropEnabled() ? 'drag-drop-enabled' : '',\n isTreeEnabled() ? 'tree-enabled' : ''\n ]\">\n \n <!-- Header Section -->\n @if (mergedConfig().title || mergedConfig().subtitle) {\n <div class=\"tw-px-3 tw-py-2 tw-border-b tw-border-gray-200\">\n @if (mergedConfig().title) {\n <h3 class=\"tw-text-base tw-font-semibold tw-text-gray-900\">\n {{ mergedConfig().title }}\n </h3>\n }\n @if (mergedConfig().subtitle) {\n <p class=\"tw-text-sm tw-text-gray-600 tw-mt-0.5\">\n {{ mergedConfig().subtitle }}\n </p>\n }\n </div>\n }\n\n <!-- Search Section -->\n @if (searchConfig.enabled) {\n <div class=\"tw-px-3 tw-py-1.5 tw-border-b tw-border-gray-200\">\n <div class=\"tw-flex tw-items-center tw-justify-between\">\n <!-- Left Side: Search Input and Action Icons -->\n <div class=\"tw-flex tw-items-center tw-space-x-1.5\">\n <!-- Search Input - Apple Style -->\n <div class=\"tw-max-w-md data-grid-search-input\">\n <cide-ele-input [labelHide]=\"true\" [hideHelperAndErrorText]=\"true\" id=\"search-input\" type=\"text\"\n [ngModel]=\"searchQuery()\"\n (ngModelChange)=\"updateSearchQuery($event)\"\n [placeholder]=\"searchConfig.placeholder\"\n [disabled]=\"loading() || isRefreshing()\"\n leadingIcon=\"search\"\n fill=\"outline\"\n size=\"sm\">\n </cide-ele-input>\n </div>\n \n <!-- Action Icons (Filter, Sort, Download) - Apple Style Compact -->\n <div class=\"tw-flex tw-items-center tw-space-x-1 data-grid-action-buttons\">\n <!-- Filter Button with Dropdown -->\n <div class=\"tw-relative\">\n <button type=\"button\"\n class=\"filter-dropdown-trigger tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-blue-600 hover:tw-bg-blue-50 tw-transition-all tw-duration-200 tw-relative\"\n [class.tw-text-blue-600]=\"columnFilters().length > 0\"\n [class.tw-bg-blue-50]=\"columnFilters().length > 0\"\n title=\"Filter\"\n (click)=\"toggleFilterDropdown()\">\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">filter_list</cide-ele-icon>\n @if (columnFilters().length > 0) {\n <span class=\"tw-absolute -tw-top-1 -tw-right-1 tw-inline-flex tw-items-center tw-justify-center tw-w-4 tw-h-4 tw-text-xs tw-font-semibold tw-text-white tw-bg-blue-600 tw-rounded-full tw-border tw-border-white\">\n {{ columnFilters().length }}\n </span>\n }\n </button>\n \n <!-- Filter Dropdown Menu -->\n @if (showFilterDropdown()) {\n <div class=\"filter-dropdown tw-absolute tw-left-0 tw-mt-2 tw-w-80 tw-bg-white tw-rounded-lg tw-shadow-xl tw-border tw-border-gray-200 tw-z-50 tw-overflow-hidden\"\n (click)=\"$event.stopPropagation()\">\n <div class=\"tw-py-1.5\">\n <div class=\"tw-px-3 tw-py-2 tw-bg-gray-50 tw-border-b tw-border-gray-200 tw-flex tw-items-center tw-justify-between\">\n <span class=\"tw-text-xs tw-font-semibold tw-text-gray-500 tw-uppercase tw-tracking-wider\">Active Filters</span>\n @if (columnFilters().length > 0) {\n <button type=\"button\" \n class=\"tw-text-xs tw-text-blue-600 hover:tw-text-blue-800 tw-font-medium\"\n (click)=\"clearAllFilters()\">\n Clear All\n </button>\n }\n </div>\n @if (columnFilters().length === 0) {\n <div class=\"tw-px-4 tw-py-6 tw-text-center\">\n <cide-ele-icon class=\"tw-w-12 tw-h-12 tw-text-gray-300 tw-mx-auto tw-mb-2\">filter_list</cide-ele-icon>\n <p class=\"tw-text-sm tw-text-gray-500\">No filters applied</p>\n <p class=\"tw-text-xs tw-text-gray-400 tw-mt-1\">Use column filters to narrow down your results</p>\n </div>\n } @else {\n <div class=\"tw-max-h-96 tw-overflow-y-auto\">\n @for (filter of columnFilters(); track filter.columnKey) {\n <div class=\"tw-px-4 tw-py-3 hover:tw-bg-gray-50 tw-border-b tw-border-gray-100 last:tw-border-b-0\">\n <div class=\"tw-flex tw-items-start tw-justify-between tw-gap-2\">\n <div class=\"tw-flex-1 tw-min-w-0\">\n <div class=\"tw-text-xs tw-font-semibold tw-text-gray-600 tw-mb-1\">{{ getColumnHeader(filter.columnKey) }}</div>\n <div class=\"tw-text-sm tw-text-gray-700 tw-flex tw-items-center tw-gap-1\">\n @if (filter.operator === 'in' && isArray(filter.value)) {\n <span class=\"tw-inline-flex tw-items-center tw-gap-1\">\n <cide-ele-icon class=\"tw-w-3 tw-h-3\">check_circle</cide-ele-icon>\n {{ getArrayLength(filter.value) }} selected\n </span>\n } @else {\n <span>{{ $any(filter.value) }}</span>\n }\n </div>\n </div>\n <button type=\"button\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-rounded tw-text-gray-400 hover:tw-text-red-600 hover:tw-bg-red-50 tw-transition-colors\"\n (click)=\"removeFilter(filter.columnKey)\"\n title=\"Remove filter\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4\">close</cide-ele-icon>\n </button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n \n <!-- Download/Export Button with Dropdown -->\n <div class=\"tw-relative\">\n <button type=\"button\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-gray-700 hover:tw-bg-gray-100 tw-transition-all tw-duration-200\"\n title=\"Export\"\n (click)=\"toggleExportMenu($event)\">\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">file_download</cide-ele-icon>\n </button>\n \n <!-- Export Dropdown Menu - Improved Design -->\n @if (showExportMenu()) {\n <div class=\"tw-absolute tw-right-0 tw-mt-2 tw-w-56 tw-bg-white tw-rounded-lg tw-shadow-xl tw-border tw-border-gray-200 tw-z-50 tw-overflow-hidden\"\n (click)=\"$event.stopPropagation()\">\n <div class=\"tw-py-1.5\">\n <div class=\"tw-px-3 tw-py-2 tw-bg-gray-50 tw-border-b tw-border-gray-200\">\n <span class=\"tw-text-xs tw-font-semibold tw-text-gray-500 tw-uppercase tw-tracking-wider\">Export Options</span>\n </div>\n <button type=\"button\"\n class=\"tw-w-full tw-text-left tw-px-4 tw-py-3 tw-text-sm tw-text-gray-700 hover:tw-bg-green-50 hover:tw-text-green-700 tw-flex tw-items-center tw-transition-colors tw-duration-150\"\n (click)=\"exportData('csv')\">\n <div class=\"tw-w-8 tw-h-8 tw-rounded tw-bg-green-100 tw-flex tw-items-center tw-justify-center tw-mr-3\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-green-600\">description</cide-ele-icon>\n </div>\n <div class=\"tw-flex-1\">\n <div class=\"tw-font-medium\">CSV</div>\n <div class=\"tw-text-xs tw-text-gray-500\">Comma separated values</div>\n </div>\n </button>\n <button type=\"button\"\n class=\"tw-w-full tw-text-left tw-px-4 tw-py-3 tw-text-sm tw-text-gray-700 hover:tw-bg-blue-50 hover:tw-text-blue-700 tw-flex tw-items-center tw-transition-colors tw-duration-150\"\n (click)=\"exportData('excel')\">\n <div class=\"tw-w-8 tw-h-8 tw-rounded tw-bg-blue-100 tw-flex tw-items-center tw-justify-center tw-mr-3\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-blue-600\">table_chart</cide-ele-icon>\n </div>\n <div class=\"tw-flex-1\">\n <div class=\"tw-font-medium\">Excel</div>\n <div class=\"tw-text-xs tw-text-gray-500\">Microsoft Excel format</div>\n </div>\n </button>\n <button type=\"button\"\n class=\"tw-w-full tw-text-left tw-px-4 tw-py-3 tw-text-sm tw-text-gray-700 hover:tw-bg-red-50 hover:tw-text-red-700 tw-flex tw-items-center tw-transition-colors tw-duration-150\"\n (click)=\"exportData('pdf')\">\n <div class=\"tw-w-8 tw-h-8 tw-rounded tw-bg-red-100 tw-flex tw-items-center tw-justify-center tw-mr-3\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-red-600\">picture_as_pdf</cide-ele-icon>\n </div>\n <div class=\"tw-flex-1\">\n <div class=\"tw-font-medium\">PDF</div>\n <div class=\"tw-text-xs tw-text-gray-500\">Portable document format</div>\n </div>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n \n <!-- Right Side: Drag Order Actions -->\n @if (isDragDropEnabled() && (isDragging() || hasOrderChanged())) {\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <button cideEleButton \n variant=\"outline\" \n size=\"sm\" \n type=\"button\"\n (click)=\"onActionClick(null, { key: 'reset-order', label: 'Reset Order', icon: 'undo', variant: 'outline', onClick: 'resetOrder' })\"\n class=\"tw-text-blue-700 tw-border-blue-300 hover:tw-bg-blue-100\">\n <cide-ele-icon size=\"xs\" class=\"tw-w-4 tw-h-4 tw-mr-1\">undo</cide-ele-icon>\n Reset Order\n </button>\n <button cideEleButton \n variant=\"primary\" \n size=\"sm\" \n type=\"button\"\n (click)=\"onActionClick(null, { key: 'save-order', label: 'Save Order', icon: 'save', variant: 'primary', onClick: 'saveOrder' })\"\n class=\"tw-bg-blue-600 hover:tw-bg-blue-700 tw-text-white\">\n <cide-ele-icon size=\"xs\" class=\"tw-w-4 tw-h-4 tw-mr-1\">save</cide-ele-icon>\n Save Order\n </button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Table Section -->\n <div class=\"tw-overflow-x-auto tw-relative\"\n [ngClass]=\"{\n 'tw-flex-1 tw-min-h-0': mergedConfig().fullHeight,\n 'tw-overflow-y-auto': scrollConfig?.enabled,\n 'tw-max-h-full': scrollConfig?.enabled\n }\"\n [style.maxHeight]=\"scrollConfig?.enabled ? scrollConfig?.maxHeight : null\"\n [style.minHeight]=\"scrollConfig?.enabled ? scrollConfig?.minHeight : null\">\n <table class=\"tw-min-w-full tw-divide-y tw-divide-gray-200 tw-h-full tw-table-fixed\"\n [class.empty-table]=\"displayedData.length === 0\"\n [ngClass]=\"{\n 'tw-table-striped': mergedConfig().striped,\n 'tw-border': mergedConfig().bordered,\n 'tw-table-sm': mergedConfig().compact\n }\"\n style=\"table-layout: fixed;\">\n \n <!-- Table Header -->\n <thead class=\"tw-bg-gray-50\" \n [ngClass]=\"[\n mergedConfig().headerClass || '',\n scrollConfig?.enabled && scrollConfig?.stickyHeader ? 'tw-sticky tw-top-0 tw-z-10' : ''\n ]\">\n <tr>\n @for (column of visibleColumns(); track column.key) {\n <th\n class=\"tw-px-3 tw-py-2 tw-text-left tw-text-xs tw-font-medium tw-text-gray-500 tw-uppercase tw-tracking-wider tw-relative\"\n [ngClass]=\"[\n getColumnWidthClass(column.width),\n getColumnMaxWidthClass(column.width),\n column.align === 'center' ? 'tw-text-center' : '',\n column.align === 'right' ? 'tw-text-right' : ''\n ]\"\n [style.width]=\"getColumnWidthStyle(column.width)\"\n [style.maxWidth]=\"getColumnMaxWidthStyle(column.width)\"\n [title]=\"column.header\">\n <div class=\"tw-flex tw-items-center tw-justify-between tw-gap-1\">\n <div class=\"tw-flex tw-items-center tw-gap-1 tw-truncate tw-flex-1\">\n <span class=\"tw-truncate\">{{ column.header }}</span>\n @if (getColumnSortDirection(column.key) === 'asc') {\n <cide-ele-icon class=\"tw-w-3 tw-h-3 tw-text-blue-600 tw-flex-shrink-0\" title=\"Sorted Ascending\">arrow_upward</cide-ele-icon>\n }\n @if (getColumnSortDirection(column.key) === 'desc') {\n <cide-ele-icon class=\"tw-w-3 tw-h-3 tw-text-blue-600 tw-flex-shrink-0\" title=\"Sorted Descending\">arrow_downward</cide-ele-icon>\n }\n </div>\n \n <!-- Active Filter Indicator -->\n @if (isColumnFiltered(column.key)) {\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded tw-bg-blue-100 tw-text-blue-700 tw-text-xs tw-font-medium tw-mr-1\">\n <cide-ele-icon class=\"tw-w-3 tw-h-3 tw-mr-0.5\">filter_alt</cide-ele-icon>\n {{ getActiveFilterCount(column.key) }}\n </div>\n }\n \n <!-- Column Menu Trigger (Three Dots Icon) -->\n @if (mergedConfig().columnMenu?.enabled) {\n <button\n type=\"button\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-rounded tw-text-gray-600 hover:tw-text-gray-800 hover:tw-bg-gray-100 tw-transition-all column-menu-trigger\"\n [class.tw-text-blue-600]=\"isColumnMenuOpen(column.key) || isColumnFiltered(column.key)\"\n [class.tw-bg-blue-50]=\"isColumnFiltered(column.key)\"\n (click)=\"toggleColumnMenu(column.key, $event)\"\n title=\"Column options\">\n <cide-ele-icon class=\"tw-w-5 tw-h-4\">more_vert</cide-ele-icon>\n </button>\n }\n </div>\n\n <!-- Column Menu Dropdown -->\n @if (isColumnMenuOpen(column.key)) {\n <div class=\"column-menu-dropdown tw-absolute tw-z-[9999] tw-mt-2 tw-w-56 tw-rounded-lg tw-shadow-lg tw-bg-white tw-ring-1 tw-ring-black tw-ring-opacity-5\">\n <div class=\"tw-py-1\">\n <!-- Sort Options -->\n @if (mergedConfig().columnMenu?.showSort && column.sortable !== false) {\n @let sortDirection = getColumnSortDirection(column.key);\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-justify-between tw-px-4 tw-py-2 tw-text-sm tw-transition-colors\"\n [class.tw-text-blue-700]=\"sortDirection === 'asc'\"\n [class.tw-bg-blue-50]=\"sortDirection === 'asc'\"\n [class.tw-text-gray-700]=\"sortDirection !== 'asc'\"\n [class.hover:tw-bg-gray-50]=\"sortDirection !== 'asc'\"\n (click)=\"onColumnSort(column, 'asc')\">\n <div class=\"tw-flex tw-items-center\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3\" \n [class.tw-text-blue-600]=\"sortDirection === 'asc'\"\n [class.tw-text-gray-400]=\"sortDirection !== 'asc'\">arrow_upward</cide-ele-icon>\n Ascending\n </div>\n @if (sortDirection === 'asc') {\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-blue-600\">check</cide-ele-icon>\n }\n </button>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-justify-between tw-px-4 tw-py-2 tw-text-sm tw-transition-colors\"\n [class.tw-text-blue-700]=\"sortDirection === 'desc'\"\n [class.tw-bg-blue-50]=\"sortDirection === 'desc'\"\n [class.tw-text-gray-700]=\"sortDirection !== 'desc'\"\n [class.hover:tw-bg-gray-50]=\"sortDirection !== 'desc'\"\n (click)=\"onColumnSort(column, 'desc')\">\n <div class=\"tw-flex tw-items-center\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3\"\n [class.tw-text-blue-600]=\"sortDirection === 'desc'\"\n [class.tw-text-gray-400]=\"sortDirection !== 'desc'\">arrow_downward</cide-ele-icon>\n Descending\n </div>\n @if (sortDirection === 'desc') {\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-blue-600\">check</cide-ele-icon>\n }\n </button>\n <div class=\"tw-border-t tw-border-gray-100 tw-my-1\"></div>\n }\n\n <!-- Filter Option -->\n @if (mergedConfig().columnMenu?.showFilter && column.filterable !== false) {\n <!-- Check if there's a custom filter renderer template -->\n @if (column.filterRenderer && templateRenderers[column.filterRenderer]) {\n <div class=\"tw-px-4 tw-py-2\">\n <ng-container [ngTemplateOutlet]=\"$any(templateRenderers[column.filterRenderer])\"\n [ngTemplateOutletContext]=\"{ $implicit: column, column: column, onFilter: onColumnFilter.bind(this) }\">\n </ng-container>\n </div>\n } @else {\n <!-- Excel-style Filter Button -->\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-justify-between tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n [class.tw-bg-blue-50]=\"isFilterPanelOpen(column.key)\"\n (click)=\"toggleFilterPanel(column.key, $event)\">\n <div class=\"tw-flex tw-items-center\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">filter_list</cide-ele-icon>\n Filter\n </div>\n <cide-ele-icon class=\"tw-w-3 tw-h-3 tw-text-gray-400\">\n {{ isFilterPanelOpen(column.key) ? 'expand_less' : 'expand_more' }}\n </cide-ele-icon>\n </button>\n \n <!-- Excel-style Filter Panel -->\n @if (isFilterPanelOpen(column.key)) {\n <div class=\"tw-px-2 tw-py-2 tw-bg-gray-50\" (click)=\"$event.stopPropagation()\">\n <!-- Search box -->\n <div class=\"tw-px-2 tw-mb-2\">\n <input\n type=\"text\"\n class=\"tw-w-full tw-px-2 tw-py-1 tw-text-xs tw-border tw-border-gray-300 tw-rounded focus:tw-outline-none focus:tw-ring-1 focus:tw-ring-blue-500\"\n placeholder=\"Search...\"\n [(ngModel)]=\"filterSearchTerm\"\n (click)=\"$event.stopPropagation()\">\n </div>\n \n <!-- Select All / Deselect All -->\n <div class=\"tw-px-2 tw-mb-1 tw-flex tw-gap-2\">\n <button\n type=\"button\"\n class=\"tw-text-xs tw-text-blue-600 hover:tw-text-blue-700\"\n (click)=\"selectAllFilterValues(column); $event.stopPropagation()\">\n Select All\n </button>\n <span class=\"tw-text-xs tw-text-gray-400\">|</span>\n <button\n type=\"button\"\n class=\"tw-text-xs tw-text-blue-600 hover:tw-text-blue-700\"\n (click)=\"deselectAllFilterValues(column); $event.stopPropagation()\">\n Clear\n </button>\n </div>\n \n <!-- Filter values list -->\n <div class=\"tw-max-h-48 tw-overflow-y-auto\">\n @for (item of getUniqueColumnValues(column); track item.value) {\n <label class=\"tw-flex tw-items-center tw-px-2 tw-py-1 tw-text-xs hover:tw-bg-white tw-cursor-pointer tw-rounded\">\n <input\n type=\"checkbox\"\n class=\"tw-mr-2 tw-rounded tw-border-gray-300 tw-text-blue-600 focus:tw-ring-blue-500\"\n [checked]=\"item.checked\"\n (change)=\"toggleFilterValue(column, item.value, $any($event.target).checked)\"\n (click)=\"$event.stopPropagation()\">\n <span class=\"tw-flex-1 tw-truncate\">{{ item.label }}</span>\n <span class=\"tw-text-gray-400 tw-ml-1\">({{ item.count }})</span>\n </label>\n }\n </div>\n </div>\n }\n }\n <div class=\"tw-border-t tw-border-gray-100 tw-my-1\"></div>\n }\n\n <!-- Autosize Option -->\n @if (mergedConfig().columnMenu?.showAutosize) {\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnAutosize(column)\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">fit_screen</cide-ele-icon>\n Autosize\n </button>\n }\n\n <!-- Group By Column Option -->\n @if (mergedConfig().columnMenu?.showGroupBy && column.groupable !== false) {\n @let isGrouped = groupedColumns().includes(column.key);\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-justify-between tw-px-4 tw-py-2 tw-text-sm tw-transition-colors\"\n [class.tw-text-blue-700]=\"isGrouped\"\n [class.tw-bg-blue-50]=\"isGrouped\"\n [class.tw-text-gray-700]=\"!isGrouped\"\n [class.hover:tw-bg-gray-50]=\"!isGrouped\"\n (click)=\"onColumnGroupBy(column)\">\n <div class=\"tw-flex tw-items-center\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3\" \n [class.tw-text-blue-600]=\"isGrouped\"\n [class.tw-text-gray-400]=\"!isGrouped\">group_work</cide-ele-icon>\n Group By Column\n </div>\n @if (isGrouped) {\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-blue-600\">check</cide-ele-icon>\n }\n </button>\n }\n\n <!-- Manage Columns Option -->\n @if (mergedConfig().columnMenu?.showManageColumns) {\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onManageColumns()\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">view_column</cide-ele-icon>\n Manage Columns\n </button>\n }\n\n <!-- Reset Columns Option -->\n @if (mergedConfig().columnMenu?.showResetColumns) {\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnReset()\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">refresh</cide-ele-icon>\n Reset Columns\n </button>\n }\n\n <!-- Hide Column Option -->\n @if (mergedConfig().columnMenu?.showHideColumn && column.hideable !== false) {\n <div class=\"tw-border-t tw-border-gray-100 tw-my-1\"></div>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnHide(column)\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">visibility_off</cide-ele-icon>\n Hide Column\n </button>\n }\n\n <!-- Aggregation Select Option -->\n @if (mergedConfig().columnMenu?.showAggregation && column.aggregatable !== false) {\n <div class=\"tw-border-t tw-border-gray-100 tw-my-1\"></div>\n <div class=\"tw-px-4 tw-py-2 tw-text-xs tw-font-semibold tw-text-gray-500 tw-uppercase\">Aggregation</div>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnAggregation(column, 'sum')\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">functions</cide-ele-icon>\n Sum\n </button>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnAggregation(column, 'avg')\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">analytics</cide-ele-icon>\n Average\n </button>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnAggregation(column, 'count')\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">tag</cide-ele-icon>\n Count\n </button>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnAggregation(column, 'min')\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">arrow_downward</cide-ele-icon>\n Min\n </button>\n <button\n type=\"button\"\n class=\"tw-w-full tw-flex tw-items-center tw-px-4 tw-py-2 tw-text-sm tw-text-gray-700 hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"onColumnAggregation(column, 'max')\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-3 tw-text-gray-400\">arrow_upward</cide-ele-icon>\n Max\n </button>\n }\n </div>\n </div>\n }\n </th>\n }\n </tr>\n </thead>\n\n <!-- Table Body -->\n <tbody class=\"tw-divide-y tw-divide-gray-200\">\n @if (loading() || isRefreshing() || pageChangeLoading()) {\n <!-- Skeleton Loading Rows -->\n @for (skeletonItem of getSkeletonArray(); track $index) {\n <tr class=\"tw-animate-pulse tw-border-b tw-border-gray-200\">\n @for (column of visibleColumns(); track column.key) {\n <td class=\"tw-px-3 tw-py-2 tw-whitespace-nowrap\"\n [ngClass]=\"[\n getColumnWidthClass(column.width),\n getColumnMaxWidthClass(column.width)\n ]\"\n [style.width]=\"getColumnWidthStyle(column.width)\"\n [style.maxWidth]=\"getColumnMaxWidthStyle(column.width)\">\n <div class=\"tw-h-2 tw-bg-gray-200 tw-rounded tw-w-3/4\"></div>\n </td>\n }\n </tr>\n }\n } @else {\n @for (item of displayedData; track trackByFn($index, item)) {\n @if (isGroupHeader(item)) {\n <!-- Group Header Row -->\n @let groupKey = getGroupKey(item);\n @let groupLevel = getGroupLevel(item);\n <tr class=\"data-grid-group-row tw-border-b-2 tw-border-gray-300 tw-font-semibold\"\n [class.tw-bg-gray-50]=\"groupLevel === 0\"\n [class.tw-bg-gray-100]=\"groupLevel === 1\"\n [class.tw-bg-gray-200]=\"groupLevel > 1\"\n (click)=\"toggleGroupExpansion(groupKey)\">\n <td class=\"tw-px-3 tw-py-1 tw-cursor-pointer tw-transition-colors\"\n [attr.colspan]=\"visibleColumns().length\">\n <div class=\"tw-flex tw-items-center tw-gap-2\" [style.padding-left.px]=\"groupLevel * 24\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-gray-600 tw-cursor-pointer\">\n {{ isGroupExpanded(groupKey) ? 'expand_more' : 'chevron_right' }}\n </cide-ele-icon>\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-blue-600\">group_work</cide-ele-icon>\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-900\">\n {{ getGroupColumnHeader(item) }}: {{ getGroupValueDisplay(item) }}\n </span>\n <span class=\"tw-text-xs tw-text-gray-500 tw-ml-2 tw-bg-gray-200 tw-px-2 tw-py-0.5 tw-rounded-full\">\n {{ getGroupRowCount(item) }}\n </span>\n </div>\n </td>\n </tr>\n } @else {\n <!-- Regular Data Row -->\n <tr class=\"tw-group data-grid-row tw-border-b-2 tw-border-gray-200\"\n [ngClass]=\"[\n mergedConfig().rowClass || '',\n isRefreshing() ? 'tw-opacity-60 tw-pointer-events-none' : '',\n isDragDropEnabled() ? 'tw-cursor-move tw-border-2 tw-border-transparent' : '',\n !isDragDropEnabled() ? 'tw-transition-colors tw-duration-150' : '',\n isTreeEnabled() ? getTreeLevelClass(item) : ''\n ]\"\n [style.border-color]=\"isDragOverRow === $index ? '#3b82f6' : 'transparent'\"\n [style.background-color]=\"isDragOverRow === $index ? '#eff6ff' : ''\"\n (click)=\"onRowClick(item)\"\n (keydown.enter)=\"onRowClick(item)\"\n (keydown.space)=\"onRowClick(item)\"\n [class.tw-cursor-pointer]=\"mergedConfig().onRowClick && !isDragDropEnabled()\"\n [tabindex]=\"mergedConfig().onRowClick && !isDragDropEnabled() ? 0 : -1\"\n [attr.role]=\"mergedConfig().onRowClick && !isDragDropEnabled() ? 'button' : null\"\n [attr.aria-label]=\"mergedConfig().onRowClick && !isDragDropEnabled() ? 'Select row' : null\"\n [draggable]=\"isDragDropEnabled()\"\n (dragstart)=\"onDragStart($event, item, $index)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event, item, $index)\"\n (dragend)=\"onDragEnd($event)\">\n \n @for (column of visibleColumns(); track column.key) {\n <td class=\"tw-pr-3 tw-py-1 tw-relative\"\n [ngClass]=\"[\n getColumnWidthClass(column.width),\n getColumnMaxWidthClass(column.width),\n mergedConfig().cellClass || '',\n column.align === 'center' ? 'tw-text-center' : '',\n column.align === 'right' ? 'tw-text-right' : '',\n column.truncate !== false ? 'tw-whitespace-nowrap' : 'tw-whitespace-normal'\n ]\"\n [style.width]=\"getColumnWidthStyle(column.width)\"\n [style.paddingLeft]=\"isTreeEnabled() && $index === 0 ? getTreeIndentStyle(item) : '12px'\"\n [style.maxWidth]=\"getColumnMaxWidthStyle(column.width) || (getColumnMaxWidthClass(column.width) === 'tw-max-w-xs' ? '200px' : getColumnMaxWidthClass(column.width) === 'tw-max-w-sm' ? '300px' : getColumnMaxWidthClass(column.width) === 'tw-max-w-md' ? '400px' : null)\"\n [style.minWidth]=\"isTreeEnabled() && $index === 0 ? '150px' : (getColumnWidthStyle(column.width) ? null : '100px')\">\n <!-- Tree Expand/Collapse Button (only for first column when tree is enabled) -->\n @if (isTreeEnabled() && $index === 0) {\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <!-- Tree Indentation -->\n <div class=\"tw-flex tw-items-center\">\n @if (hasChildren(item)) {\n <button \n variant=\"outline\"\n size=\"xs\"\n type=\"button\"\n (click)=\"onActionClick(item, { key: 'toggle-expand', label: 'Toggle', icon: '', variant: 'ghost', onClick: 'toggle-expand' }); $event.stopPropagation()\"\n class=\"tw-flex tw-items-center tw-justify-center tw-w-5 tw-h-5 tw-text-gray-500 hover:tw-text-gray-700 tw-rounded\"\n [class.tw-transition-colors]=\"!isDragDropEnabled()\"\n [title]=\"isItemExpanded(item) ? 'Collapse' : 'Expand'\">\n <cide-ele-icon \n class=\"tw-w-3 tw-h-3\"\n [class.tw-transition-transform]=\"!isDragDropEnabled()\"\n [class.tw-rotate-90]=\"isItemExpanded(item)\"\n size=\"xs\">\n chevron_right\n </cide-ele-icon>\n </button>\n } @else {\n <div class=\"tw-w-8 tw-h-5 tw-flex tw-items-center tw-justify-center\">\n <!-- <div class=\"tw-w-1 tw-h-1 tw-bg-gray-300 tw-rounded-full\"></div> -->\n </div>\n }\n </div>\n \n <!-- Cell Content -->\n <div class=\"tw-flex-1 tw-w-full\">\n @if (column.type === 'text') {\n <p class=\"tw-text-sm tw-text-gray-900\"\n [class.tw-truncate]=\"column.truncate\"\n [title]=\"column.truncate ? (getNestedValue(item, column.valueGetter || column.key) || '').toString() : ''\">\n {{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}\n </p>\n } @else if (column.type === 'number') {\n <span class=\"tw-text-sm tw-text-gray-900 tw-font-mono\">\n {{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}\n </span>\n } @else if (column.type === 'date') {\n <span class=\"tw-text-sm tw-text-gray-600\">\n {{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}\n </span>\n } @else if (column.type === 'boolean') {\n <span class=\"tw-inline-flex tw-items-center tw-px-2 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium\"\n [ngClass]=\"getNestedValue(item, column.valueGetter || column.key) ? 'tw-bg-green-100 tw-text-green-800' : 'tw-bg-red-100 tw-text-red-800'\">\n {{ getNestedValue(item, column.valueGetter || column.key) ? 'Yes' : 'No' }}\n </span>\n } @else if (column.type === 'status' && column.statusConfig) {\n <span class=\"tw-inline-flex tw-items-center tw-px-2 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium\"\n [ngClass]=\"getStatusClass(getNestedValue(item, column.valueGetter || column.key), column.statusConfig)\">\n {{ getStatusText(getNestedValue(item, column.valueGetter || column.key), column.statusConfig) }}\n </span>\n } @else if (column.type === 'actions' && column.actions) {\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n @for (action of column.actions; track action.key) {\n <button\n cideEleButton\n [variant]=\"action.variant || 'ghost'\"\n size=\"xs\"\n type=\"button\"\n (click)=\"onActionClick(item, action); $event.stopPropagation()\"\n [title]=\"action.tooltip || action.label\"\n [disabled]=\"isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-px-2 tw-py-2 tw-text-xs tw-font-medium tw-rounded\"\n [class.tw-transition-colors]=\"!isDragDropEnabled()\"\n [ngClass]=\"{\n 'tw-text-gray-700 tw-bg-gray-100 hover:tw-bg-gray-200': action.variant === 'ghost',\n 'tw-text-white tw-bg-blue-600 hover:tw-bg-blue-700': action.variant === 'primary',\n 'tw-text-blue-700 tw-bg-blue-50 tw-border tw-border-blue-200 hover:tw-bg-blue-100': action.variant === 'outline',\n 'tw-text-white tw-bg-red-600 hover:tw-bg-red-700': action.variant === 'danger'\n }\">\n @if (action.icon) {\n <svg class=\"tw-w-3 tw-h-3 tw-mr-1\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M10 12l-5-5h10l-5 5z\"/>\n </svg>\n }\n {{ action.label }}\n </button>\n }\n </div>\n } @else if (column.type === 'custom') {\n <!-- Template Renderer -->\n @if (column.renderer && isTemplateRenderer(column.renderer)) {\n <ng-container \n [ngTemplateOutlet]=\"getTemplateRenderer(column.renderer)!\"\n [ngTemplateOutletContext]=\"getTemplateContext(getNestedValue(item, column.valueGetter || column.key), item, column)\">\n </ng-container>\n }\n <!-- Default rendering -->\n @else {\n <div>{{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}</div>\n }\n }\n </div>\n </div>\n } @else {\n <!-- Regular cell content (non-tree or non-first column) -->\n @if (column.type === 'text') {\n <p class=\"tw-text-sm tw-text-gray-900\"\n [class.tw-truncate]=\"column.truncate\"\n [title]=\"column.truncate ? (getNestedValue(item, column.valueGetter || column.key) || '').toString() : ''\">\n {{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}\n </p>\n } @else if (column.type === 'number') {\n <span class=\"tw-text-sm tw-text-gray-900 tw-font-mono\">\n {{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}\n </span>\n } @else if (column.type === 'date') {\n <span class=\"tw-text-sm tw-text-gray-600\">\n {{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}\n </span>\n } @else if (column.type === 'boolean') {\n <span class=\"tw-inline-flex tw-items-center tw-px-2 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium\"\n [ngClass]=\"getNestedValue(item, column.valueGetter || column.key) ? 'tw-bg-green-100 tw-text-green-800' : 'tw-bg-red-100 tw-text-red-800'\">\n {{ getNestedValue(item, column.valueGetter || column.key) ? 'Yes' : 'No' }}\n </span>\n } @else if (column.type === 'status' && column.statusConfig) {\n <span class=\"tw-inline-flex tw-items-center tw-px-2 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium\"\n [ngClass]=\"getStatusClass(getNestedValue(item, column.valueGetter || column.key), column.statusConfig)\">\n {{ getStatusText(getNestedValue(item, column.valueGetter || column.key), column.statusConfig) }}\n </span>\n } @else if (column.type === 'actions' && column.actions) {\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n @for (action of column.actions; track action.key) {\n <button\n cideEleButton\n [variant]=\"action.variant || 'ghost'\"\n size=\"xs\"\n type=\"button\"\n (click)=\"onActionClick(item, action); $event.stopPropagation()\"\n [title]=\"action.tooltip || action.label\"\n [disabled]=\"isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-px-2 tw-py-2 tw-text-xs tw-font-medium tw-rounded\"\n [class.tw-transition-colors]=\"!isDragDropEnabled()\"\n [ngClass]=\"{\n 'tw-text-gray-700 tw-bg-gray-100 hover:tw-bg-gray-200': action.variant === 'ghost',\n 'tw-text-white tw-bg-blue-600 hover:tw-bg-blue-700': action.variant === 'primary',\n 'tw-text-blue-700 tw-bg-blue-50 tw-border tw-border-blue-200 hover:tw-bg-blue-100': action.variant === 'outline',\n 'tw-text-white tw-bg-red-600 hover:tw-bg-red-700': action.variant === 'danger'\n }\">\n @if (action.icon) {\n <svg class=\"tw-w-3 tw-h-3 tw-mr-1\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path d=\"M10 12l-5-5h10l-5 5z\"/>\n </svg>\n }\n {{ action.label }}\n </button>\n }\n </div>\n } @else if (column.type === 'custom') {\n <!-- Template Renderer -->\n @if (column.renderer && isTemplateRenderer(column.renderer)) {\n <ng-container \n [ngTemplateOutlet]=\"getTemplateRenderer(column.renderer)!\"\n [ngTemplateOutletContext]=\"getTemplateContext(getNestedValue(item, column.valueGetter || column.key), item, column)\">\n </ng-container>\n }\n <!-- Default rendering -->\n @else {\n <div>{{ formatValue(getNestedValue(item, column.valueGetter || column.key), column) }}</div>\n }\n }\n }\n </td>\n }\n </tr>\n }\n }\n \n <!-- Empty State -->\n @if (displayedData.length === 0) {\n <tr class=\"tw-h-full\">\n <td [attr.colspan]=\"visibleColumns().length\" class=\"tw-px-6 tw-py-22 tw-text-center tw-h-full tw-align-middle\">\n <div class=\"tw-text-gray-500 tw-flex tw-flex-col tw-items-center tw-justify-center tw-min-h-[300px]\">\n <svg class=\"tw-mx-auto tw-h-12 tw-w-12 tw-text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"></path>\n </svg>\n <h3 class=\"tw-mt-2 tw-text-sm tw-font-medium tw-text-gray-900\">No data found</h3>\n <p class=\"tw-mt-1 tw-text-sm tw-text-gray-500\">\n @if (searchQuery()) {\n No results match your search criteria.\n } @else {\n There are no items to display.\n }\n </p>\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n </div>\n\n <!-- Pagination Section -->\n @if (paginationConfig.enabled && totalItems() > 0) {\n <div class=\"tw-px-3 tw-py-0 tw-border-t tw-border-gray-200 tw-bg-white tw-relative tw-z-20\"\n [class.tw-opacity-60]=\"isRefreshing()\">\n \n <!-- Results Info and Page Size -->\n <div class=\"tw-flex tw-flex-col sm:tw-flex-row tw-justify-between tw-items-start sm:tw-items-center tw-space-y-1 sm:tw-space-y-0\">\n \n <!-- Results Info -->\n @if (paginationConfig.showPageInfo) {\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <p class=\"tw-text-sm tw-text-gray-700\">\n Showing {{ getItemRangeText() }} results\n </p>\n \n <!-- Page Size Selector -->\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-gray-500\">view_list</cide-ele-icon>\n <span class=\"tw-text-sm tw-text-gray-700\">Per page:</span>\n <div class=\"tw-w-16 tw-relative\">\n <cide-ele-select\n [labelHide]=\"true\"\n [ngModel]=\"pageSize()\"\n (ngModelChange)=\"updatePageSize($event)\"\n [options]=\"getPageSizeOptions()\"\n [disabled]=\"isRefreshing()\"\n fill=\"outline\"\n size=\"xs\"\n class=\"tw-z-30\">\n </cide-ele-select>\n </div>\n </div>\n </div>\n }\n\n <!-- Pagination Controls -->\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n \n <!-- Previous/Next and Page Numbers -->\n <div class=\"tw-flex tw-items-center tw-space-x-1\">\n \n <!-- First Page -->\n <button\n type=\"button\"\n (click)=\"onPageChange(1)\"\n [disabled]=\"currentPage() === 1 || isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-gray-700 hover:tw-bg-gray-100 tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n title=\"First page\">\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">first_page</cide-ele-icon>\n </button>\n \n <!-- Previous Page -->\n <button\n type=\"button\"\n (click)=\"previousPage()\"\n [disabled]=\"!hasPreviousPage() || isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-gray-700 hover:tw-bg-gray-100 tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n title=\"Previous page\">\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">chevron_left</cide-ele-icon>\n </button>\n \n <!-- Page Numbers -->\n @for (page of getEnhancedPageNumbers(); track page) {\n @if (page === '...') {\n <span class=\"tw-px-2 tw-py-2 tw-text-sm tw-text-gray-500\">...</span>\n } @else {\n <button\n type=\"button\"\n (click)=\"onPageChange(page)\"\n [disabled]=\"isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-p-0 tw-rounded tw-text-xs tw-font-medium tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n [ngClass]=\"{\n 'tw-bg-blue-600 tw-text-white hover:tw-bg-blue-700': currentPage() === page,\n 'tw-bg-white tw-text-gray-700 tw-border tw-border-gray-300 hover:tw-bg-gray-50': currentPage() !== page\n }\"\n [title]=\"'Page ' + page\">\n {{ page }}\n </button>\n }\n }\n \n <!-- Next Page -->\n <button\n type=\"button\"\n (click)=\"nextPage()\"\n [disabled]=\"!hasNextPage() || isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-gray-700 hover:tw-bg-gray-100 tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n title=\"Next page\">\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">chevron_right</cide-ele-icon>\n </button>\n \n <!-- Last Page -->\n <button\n type=\"button\"\n (click)=\"onPageChange(totalPages())\"\n [disabled]=\"currentPage() === totalPages() || isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-gray-700 hover:tw-bg-gray-100 tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n title=\"Last page\">\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">last_page</cide-ele-icon>\n </button>\n \n </div>\n\n <!-- Quick Jump and Refresh -->\n @if (paginationConfig.showQuickJump || paginationConfig.showRefresh) {\n <div class=\"tw-flex tw-items-center tw-space-x-1 tw-border-l tw-border-gray-200 tw-pl-2\">\n \n <!-- Quick Jump -->\n @if (paginationConfig.showQuickJump) {\n <div class=\"tw-flex tw-items-center tw-space-x-1\">\n <span class=\"tw-text-sm tw-text-gray-700\">Go to:</span>\n <div class=\"tw-w-16\">\n <cide-ele-input id=\"jump-to-page-input\" type=\"number\" [labelHide]=\"true\" [hideHelperAndErrorText]=\"true\"\n [(ngModel)]=\"jumpToPage\" [min]=\"1\" [max]=\"totalPages()\"\n [disabled]=\"isRefreshing()\"\n size=\"xs\"\n (keydown.enter)=\"onJumpToPage()\">\n </cide-ele-input>\n </div>\n <button\n type=\"button\"\n (click)=\"onJumpToPage()\"\n [disabled]=\"isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-p-0 tw-rounded tw-text-xs tw-font-medium tw-bg-gray-100 tw-text-gray-700 tw-border tw-border-gray-300 hover:tw-bg-gray-200 tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n title=\"Go to page\">\n Go\n </button>\n </div>\n }\n \n <!-- Refresh Button -->\n @if (paginationConfig.showRefresh) {\n <button\n type=\"button\"\n (click)=\"onRefresh()\"\n [disabled]=\"isRefreshing()\"\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-w-7 tw-h-7 tw-p-0 tw-rounded-md tw-text-gray-500 hover:tw-text-gray-700 hover:tw-bg-gray-100 tw-transition-all tw-duration-200 disabled:tw-opacity-50 disabled:tw-cursor-not-allowed\"\n title=\"Refresh\">\n @if (isRefreshing()) {\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4 tw-animate-spin\">refresh</cide-ele-icon>\n } @else {\n <cide-ele-icon class=\"tw-w-[22px] tw-h-4\">refresh</cide-ele-icon>\n }\n </button>\n }\n </div>\n }\n \n </div>\n </div>\n </div>\n }\n\n <!-- Manage Columns Modal -->\n @if (showManageColumnsModal()) {\n <div class=\"tw-fixed tw-inset-0 tw-z-50 tw-overflow-y-auto\" \n (click)=\"closeManageColumnsModal()\"\n style=\"background-color: rgba(0, 0, 0, 0.5);\">\n <div class=\"tw-flex tw-items-center tw-justify-center tw-min-h-screen tw-p-4\">\n <div class=\"tw-bg-white tw-rounded-lg tw-shadow-xl tw-max-w-md tw-w-full tw-max-h-[80vh] tw-overflow-hidden tw-flex tw-flex-col\"\n (click)=\"$event.stopPropagation()\">\n <!-- Modal Header -->\n <div class=\"tw-px-6 tw-py-4 tw-border-b tw-border-gray-200 tw-flex tw-items-center tw-justify-between\">\n <h3 class=\"tw-text-lg tw-font-semibold tw-text-gray-900\">Manage Columns</h3>\n <button type=\"button\"\n class=\"tw-text-gray-400 hover:tw-text-gray-600 tw-transition-colors\"\n (click)=\"closeManageColumnsModal()\">\n <cide-ele-icon class=\"tw-w-5 tw-h-5\">close</cide-ele-icon>\n </button>\n </div>\n \n <!-- Modal Body -->\n <div class=\"tw-px-6 tw-py-4 tw-overflow-y-auto tw-flex-1\">\n <p class=\"tw-text-sm tw-text-gray-600 tw-mb-4\">Select columns to show or hide:</p>\n <div class=\"tw-space-y-2\">\n @for (column of mergedConfig().columns; track column.key) {\n <label class=\"tw-flex tw-items-center tw-px-3 tw-py-2 tw-rounded-md hover:tw-bg-gray-50 tw-cursor-pointer tw-transition-colors\">\n <input type=\"checkbox\"\n class=\"tw-mr-3 tw-rounded tw-border-gray-300 tw-text-blue-600 focus:tw-ring-blue-500\"\n [checked]=\"!isColumnHidden(column.key)\"\n (change)=\"toggleColumnVisibility(column.key); $event.stopPropagation()\">\n <span class=\"tw-text-sm tw-text-gray-700 tw-flex-1\">{{ column.header }}</span>\n @if (isColumnHidden(column.key)) {\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-gray-400 tw-ml-2\">visibility_off</cide-ele-icon>\n } @else {\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-text-gray-400 tw-ml-2\">visibility</cide-ele-icon>\n }\n </label>\n }\n </div>\n </div>\n \n <!-- Modal Footer -->\n <div class=\"tw-px-6 tw-py-4 tw-border-t tw-border-gray-200 tw-flex tw-items-center tw-justify-end tw-gap-3\">\n <button type=\"button\"\n class=\"tw-px-4 tw-py-2 tw-text-sm tw-font-medium tw-text-gray-700 tw-bg-white tw-border tw-border-gray-300 tw-rounded-md hover:tw-bg-gray-50 tw-transition-colors\"\n (click)=\"closeManageColumnsModal()\">\n Close\n </button>\n <button type=\"button\"\n class=\"tw-px-4 tw-py-2 tw-text-sm tw-font-medium tw-text-white tw-bg-blue-600 tw-border tw-border-transparent tw-rounded-md hover:tw-bg-blue-700 tw-transition-colors\"\n (click)=\"onColumnReset(); closeManageColumnsModal()\">\n Reset All\n </button>\n </div>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".data-grid-container{width:100%;display:flex;flex-direction:column;min-height:400px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;color:var(--cide-ele-text-primary);background-color:var(--cide-ele-grid-bg, var(--cide-ele-bg-primary, #ffffff));border-radius:0;overflow:hidden;box-shadow:var(--cide-ele-shadow-sm);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.data-grid-container.tw-h-full{height:100%;min-height:100%}.data-grid-container .tw-overflow-x-auto{scrollbar-width:thin;scrollbar-color:var(--cide-ele-scrollbar-thumb, #d1d5db) var(--cide-ele-scrollbar-track, #f9fafb)}.data-grid-container .tw-overflow-x-auto.tw-flex-1{flex:1;min-height:0}.data-grid-container .tw-overflow-x-auto::-webkit-scrollbar{height:6px}.data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-track{background:var(--cide-ele-scrollbar-track, #f9fafb)}.data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb{background:var(--cide-ele-scrollbar-thumb, #d1d5db);border-radius:3px}.data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover{background:var(--cide-ele-scrollbar-thumb-hover, #9ca3af)}.data-grid-container table{min-height:300px;border-collapse:separate;border-spacing:0;width:100%;background-color:var(--cide-ele-grid-bg)}.data-grid-container thead{background-color:var(--cide-ele-grid-bg-header);border-bottom:2px solid var(--cide-ele-grid-border-header);position:relative;z-index:100}.data-grid-container thead th{background:transparent;color:var(--cide-ele-grid-text-header);font-weight:500;font-size:12px;text-transform:none;letter-spacing:-.01em;padding:4px 10px;border-bottom:1px solid var(--cide-ele-grid-border);text-align:left;white-space:nowrap;position:relative;transition:all .2s cubic-bezier(.4,0,.2,1)}.data-grid-container thead th:first-child{padding-left:12px}.data-grid-container thead th:last-child{padding-right:12px}.data-grid-container thead th:hover{background-color:var(--cide-ele-grid-bg-header-hover, var(--cide-ele-grid-bg-hover, var(--cide-ele-bg-hover)))}.data-grid-container thead th .column-menu-trigger{opacity:1;transition:all .2s cubic-bezier(.4,0,.2,1);margin-left:4px;cursor:pointer;padding:2px;border-radius:4px}.data-grid-container thead th .column-menu-trigger:hover{background-color:var(--cide-ele-bg-tertiary)}.data-grid-container tbody{background-color:var(--cide-ele-grid-bg, #ffffff)}.data-grid-container tbody td{padding:6px 10px;border-bottom:1px solid var(--cide-ele-grid-border, #e5e7eb);color:var(--cide-ele-grid-text, #1f2937);font-size:13px;vertical-align:middle;line-height:1.5;transition:all .2s cubic-bezier(.4,0,.2,1);background-color:transparent}.data-grid-container tbody td:first-child{padding-left:12px}.data-grid-container tbody td:last-child{padding-right:12px}.data-grid-container tbody tr{background-color:var(--cide-ele-grid-bg, #ffffff);transition:all .2s cubic-bezier(.4,0,.2,1)}.data-grid-container tbody tr td{color:var(--cide-ele-grid-text, #1f2937)}.data-grid-container tbody tr:hover,.data-grid-container tbody tr.data-grid-row:hover,.data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover{background-color:var(--cide-ele-grid-bg-hover)!important;border-left:2px solid transparent}.data-grid-container tbody tr:hover td,.data-grid-container tbody tr.data-grid-row:hover td,.data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover td{background-color:transparent!important;border-bottom-color:var(--cide-ele-grid-border);color:var(--cide-ele-grid-text)!important}.data-grid-container tbody tr:active{background-color:var(--cide-ele-bg-active);transform:scale(.999)}.data-grid-container tbody tr:active td{color:var(--cide-ele-grid-text)}.data-grid-container.tw-h-full table,.data-grid-container.tw-h-full tbody{height:100%}.data-grid-container.tw-table-striped tbody tr:nth-child(2n){background-color:var(--cide-ele-grid-bg-striped);border-left:1px solid transparent}.data-grid-container.tw-table-striped tbody tr:nth-child(2n):hover{background-color:var(--cide-ele-grid-bg-hover);border-left:2px solid var(--cide-ele-grid-border-hover)}.data-grid-container.tw-table-striped tbody tr:nth-child(2n):hover td{color:var(--cide-ele-grid-text)}.data-grid-container.tw-table-striped tbody tr:nth-child(2n) td{color:var(--cide-ele-grid-text)}.data-grid-container tbody tr.data-grid-group-row{background-color:var(--cide-ele-grid-bg-group)!important}.data-grid-container tbody tr.data-grid-group-row td{color:var(--cide-ele-grid-text)}.data-grid-container tbody tr.data-grid-group-row:hover{background-color:var(--cide-ele-grid-bg-hover)!important}.data-grid-container tbody tr.data-grid-group-row:hover td{color:var(--cide-ele-grid-text)}.data-grid-container.tw-table-sm thead th{padding:8px 10px;font-size:11px}.data-grid-container.tw-table-sm thead th:first-child{padding-left:16px}.data-grid-container.tw-table-sm thead th:last-child{padding-right:16px}.data-grid-container.tw-table-sm tbody td{padding:8px 10px;font-size:12px;line-height:1.4}.data-grid-container.tw-table-sm tbody td:first-child{padding-left:16px}.data-grid-container.tw-table-sm tbody td:last-child{padding-right:16px}.data-grid-container tbody tr.tw-cursor-pointer:hover{background-color:var(--cide-ele-grid-bg-hover)!important;border-left:2px solid var(--cide-ele-grid-border-hover)!important}.data-grid-container tbody tr.tw-cursor-pointer:hover td{background-color:transparent!important;color:var(--cide-ele-grid-text)!important}.data-grid-container.loading-overlay{position:relative}.data-grid-container.loading-overlay:after{content:\"\";position:absolute;inset:0;background:#ffffffd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:10;animation:fadeIn .2s cubic-bezier(.4,0,.2,1)}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.data-grid-container .tw-animate-pulse div{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.data-grid-container .data-grid-action-buttons button{position:relative;border:1px solid rgba(0,0,0,.08);background:transparent;outline:none;cursor:pointer;-webkit-tap-highlight-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:6px;transition:all .2s cubic-bezier(.4,0,.2,1)}.data-grid-container .data-grid-action-buttons button cide-ele-icon{color:#6b7280;transition:all .2s cubic-bezier(.4,0,.2,1)}.data-grid-container .data-grid-action-buttons button:hover:not(:disabled){background-color:#0000000a;border-color:#0000001f}.data-grid-container .data-grid-action-buttons button:hover:not(:disabled) cide-ele-icon{color:#374151;transform:scale(1.05)}.data-grid-container .data-grid-action-buttons button:active:not(:disabled){background-color:#00000014;border-color:#00000026;transform:scale(.95)}.data-grid-container .data-grid-action-buttons button:active:not(:disabled) cide-ele-icon{transform:scale(.98)}.data-grid-container .data-grid-action-buttons button:focus-visible{outline:none;border-color:#3b82f64d;box-shadow:0 0 0 3px #3b82f61f}.data-grid-container .data-grid-action-buttons button:disabled{cursor:not-allowed;opacity:.3;background:transparent!important;border-color:#0000000d}.data-grid-container .action-buttons{display:flex;gap:.25rem}.data-grid-container .action-buttons button{transition:all .15s ease-in-out}.data-grid-container .action-buttons button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 2px 4px #0000001a}.data-grid-container .action-buttons button:disabled{cursor:not-allowed;opacity:.5}.data-grid-container .pagination-controls{padding:12px 20px;border-top:2px solid var(--cide-ele-grid-border-header);background-color:var(--cide-ele-grid-bg-header)}.data-grid-container .pagination-controls button{transition:all .2s cubic-bezier(.4,0,.2,1);border-radius:6px}.data-grid-container .pagination-controls button:hover:not(:disabled){background-color:#0000000a;transform:scale(1.02)}.data-grid-container .pagination-controls button:active:not(:disabled){transform:scale(.98);background-color:#00000014}.data-grid-container .pagination-controls button:disabled{cursor:not-allowed;opacity:.3}.data-grid-container .pagination-controls button.active{background-color:#3b82f61a;color:#3b82f6;font-weight:500;box-shadow:0 0 0 1px #3b82f633}.data-grid-container .pagination-controls input[type=number]{transition:all .2s cubic-bezier(.4,0,.2,1);border:1px solid rgba(0,0,0,.06);border-radius:6px}.data-grid-container .pagination-controls input[type=number]:hover{border-color:#0000001a}.data-grid-container .pagination-controls input[type=number]:focus{outline:none;border-color:#3b82f64d;box-shadow:0 0 0 3px #3b82f614;background-color:#fff}.data-grid-container .status-badge{font-weight:500;letter-spacing:-.01em;padding:4px 12px;border-radius:12px;font-size:12px;display:inline-flex;align-items:center;transition:all .2s cubic-bezier(.4,0,.2,1)}.data-grid-container .status-badge.active{background-color:#34d39926;color:#059669;border:1px solid rgba(52,211,153,.3)}.data-grid-container .status-badge.active:hover{background-color:#34d39933}.data-grid-container .status-badge.inactive{background-color:#f8717126;color:#dc2626;border:1px solid rgba(248,113,113,.3)}.data-grid-container .status-badge.inactive:hover{background-color:#f8717133}.data-grid-container .data-grid-search-input ::ng-deep .cide-input-wrapper{transition:all .2s cubic-bezier(.4,0,.2,1)}.data-grid-container .data-grid-search-input ::ng-deep .cide-input-wrapper:hover:not(:has(input:disabled)){background-color:#00000005}.data-grid-container .data-grid-search-input ::ng-deep input{font-size:13px;font-weight:400;color:#1f2937;transition:all .2s cubic-bezier(.4,0,.2,1);border-radius:8px}.data-grid-container .data-grid-search-input ::ng-deep input::placeholder{color:#9ca3af;font-weight:400}.data-grid-container .data-grid-search-input ::ng-deep input:focus{outline:none;border-color:#3b82f64d;box-shadow:0 0 0 3px #3b82f614;background-color:#fff}.data-grid-container .data-grid-search-input ::ng-deep input:disabled{background-color:#00000005;color:#9ca3af;cursor:not-allowed}.data-grid-container .data-grid-search-input ::ng-deep .cide-input-leading-icon cide-ele-icon{color:#9ca3af;transition:color .2s cubic-bezier(.4,0,.2,1)}.data-grid-container .data-grid-search-input ::ng-deep input:focus~.cide-input-leading-icon cide-ele-icon,.data-grid-container .data-grid-search-input ::ng-deep .cide-input-wrapper:has(input:focus) .cide-input-leading-icon cide-ele-icon{color:#6b7280}.data-grid-container .data-grid-search-input ::ng-deep .cide-input-wrapper[data-fill=outline]{border:1px solid #e5e7eb;background-color:#fafafa;border-radius:8px}.data-grid-container .data-grid-search-input ::ng-deep .cide-input-wrapper[data-fill=outline]:hover:not(:has(input:disabled)){border-color:#d1d5db;background-color:#fff}.data-grid-container .data-grid-search-input ::ng-deep .cide-input-wrapper[data-fill=outline]:has(input:focus){border-color:#3b82f64d;background-color:#fff}.data-grid-container .search-input{position:relative}.data-grid-container .search-input input{transition:all .15s ease-in-out}.data-grid-container .search-input input:focus{box-shadow:0 0 0 3px #3b82f61a}.data-grid-container .search-input .search-icon{pointer-events:none}.data-grid-container .column-menu-dropdown{animation:dropdownFadeIn .15s cubic-bezier(.4,0,.2,1);box-shadow:0 10px 25px #0000001a,0 4px 10px #0000000d;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border:1px solid rgba(0,0,0,.05);position:absolute!important;z-index:9999!important}.data-grid-container .column-menu-dropdown button{font-size:13px;font-weight:400;letter-spacing:-.01em;text-align:left;transition:all .15s cubic-bezier(.4,0,.2,1)}.data-grid-container .column-menu-dropdown button:hover{background-color:#3b82f60d;color:#1f2937}.data-grid-container .column-menu-dropdown button:hover cide-ele-icon{color:#3b82f6}.data-grid-container .column-menu-dropdown button:active{background-color:#3b82f61a;transform:scale(.98)}.data-grid-container .column-menu-dropdown .tw-uppercase{letter-spacing:.05em}@keyframes dropdownFadeIn{0%{opacity:0;transform:translateY(-8px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.data-grid-container .empty-state{padding:4rem 2rem;text-align:center}.data-grid-container .empty-state svg{margin:0 auto 1.5rem;opacity:.3;transition:all .3s cubic-bezier(.4,0,.2,1)}.data-grid-container .empty-state svg:hover{opacity:.5;transform:scale(1.05)}.data-grid-container .empty-state h3{margin-bottom:.75rem;font-weight:600;color:#374151;font-size:16px;letter-spacing:-.01em}.data-grid-container .empty-state p{color:#6b7280;font-size:14px;line-height:1.5}.data-grid-container.tw-h-full tbody tr:only-child td{height:100%;vertical-align:middle}.data-grid-container.tw-h-full table.empty-table{height:100%}.data-grid-container.tw-h-full tbody tr:only-child{height:100%}@media (max-width: 640px){.data-grid-container .tw-px-6{padding-left:1rem;padding-right:1rem}.data-grid-container .pagination-controls{flex-direction:column;gap:1rem}.data-grid-container .pagination-controls .flex{justify-content:center}.data-grid-container .pagination-info{display:none}.data-grid-container .search-actions{flex-direction:column;gap:1rem}}.data-grid-container :host .tw-bg-white{background-color:#fff!important}.data-grid-container :host .tw-bg-gray-50{background-color:#fafafa!important}.data-grid-container :host .tw-bg-gray-100{background-color:#f3f4f6!important}.data-grid-container :host thead{background-color:var(--cide-ele-grid-bg-header, #fafafa)!important}.data-grid-container :host thead th{background-color:transparent!important;color:var(--cide-ele-grid-text-header, #6b7280)!important}.data-grid-container :host thead th:hover{background-color:var(--cide-ele-grid-bg-header-hover, var(--cide-ele-grid-bg-hover, #f3f4f6))!important}.data-grid-container :host .data-grid-group-row{background-color:#f3f4f6!important}.data-grid-container :host tbody{background-color:#fff!important}.data-grid-container :host tbody tr{background-color:#fff!important}.data-grid-container :host tbody tr td{background-color:transparent}.data-grid-container :host.tw-table-striped tbody tr:nth-child(2n){background-color:#fafafa!important}.data-grid-container :host .tw-text-gray-900{color:#1f2937!important}.data-grid-container :host .tw-text-gray-600{color:#4b5563!important}.data-grid-container :host .tw-text-gray-500{color:#6b7280!important}.data-grid-container :host .tw-text-gray-400{color:#9ca3af!important}.data-grid-container :host .tw-text-gray-700{color:#374151!important}.data-grid-container :host .tw-border-gray-200,.data-grid-container :host .tw-divide-gray-200{border-color:#e5e7eb!important}.data-grid-container :host .tw-border-gray-300{border-color:#d1d5db!important}.data-grid-container :host tbody tr:hover,.data-grid-container :host tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host tbody tr.data-grid-row:hover{background-color:var(--cide-ele-grid-bg-hover)!important}.data-grid-container :host tbody tr:hover td,.data-grid-container :host tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host tbody tr.data-grid-row:hover td{background-color:transparent!important;color:var(--cide-ele-grid-text)!important}.data-grid-container :host tbody tr:hover .tw-text-gray-900,.data-grid-container :host tbody tr:hover .tw-text-gray-700,.data-grid-container :host tbody tr:hover .tw-text-gray-600,.data-grid-container :host tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host tbody tr.data-grid-row:hover .tw-text-gray-600{color:var(--cide-ele-grid-text)!important}.data-grid-container :host tbody tr.tw-cursor-pointer:hover{background-color:var(--cide-ele-grid-bg-hover)!important;border-left:2px solid var(--cide-ele-grid-border-hover)!important}.data-grid-container :host tbody tr.tw-cursor-pointer:hover td{background-color:transparent!important;color:var(--cide-ele-grid-text)!important}.data-grid-container :host .tw-overflow-x-auto{scrollbar-width:thin;scrollbar-color:#d1d5db #f9fafb}.data-grid-container :host .tw-overflow-x-auto::-webkit-scrollbar-track{background:#f9fafb!important}.data-grid-container :host .tw-overflow-x-auto::-webkit-scrollbar-thumb{background:#d1d5db!important}.data-grid-container :host .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover{background:#9ca3af!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-white,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-white,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-white{background-color:#fff!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-gray-50,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-gray-50,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-gray-50{background-color:#fafafa!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-gray-100,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-gray-100,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-bg-gray-100{background-color:#f3f4f6!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .data-grid-group-row,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .data-grid-group-row,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .data-grid-group-row{background-color:#f3f4f6!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody{background-color:#fff!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr{background-color:#fff!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr td,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr td,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr td{background-color:transparent}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container.tw-table-striped tbody tr:nth-child(2n),::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container.tw-table-striped tbody tr:nth-child(2n),::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container.tw-table-striped tbody tr:nth-child(2n){background-color:#fafafa!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-900,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-900,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-900{color:#1f2937!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-600,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-600,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-600{color:#4b5563!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-500,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-500,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-500{color:#6b7280!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-400,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-400,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-400{color:#9ca3af!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-700,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-700,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-text-gray-700{color:#374151!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-border-gray-200,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-divide-gray-200,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-border-gray-200,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-divide-gray-200,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-border-gray-200,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-divide-gray-200{border-color:#e5e7eb!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-border-gray-300,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-border-gray-300,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-border-gray-300{border-color:#d1d5db!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover{background-color:var(--cide-ele-grid-bg-hover)!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover td,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover td,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover td,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover td,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover td,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover td,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover td,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover td,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover td{background-color:transparent!important;color:var(--cide-ele-grid-text)!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-900,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-700,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-600,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-900,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-700,::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-600,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-900,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-700,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-600,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-900,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-700,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-600,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-900,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-700,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr:hover .tw-text-gray-600,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-900,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-700,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.data-grid-row:hover .tw-text-gray-600{color:var(--cide-ele-grid-text)!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.tw-cursor-pointer:hover,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.tw-cursor-pointer:hover,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.tw-cursor-pointer:hover{background-color:var(--cide-ele-grid-bg-hover)!important;border-left:2px solid var(--cide-ele-grid-border-hover)!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.tw-cursor-pointer:hover td,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.tw-cursor-pointer:hover td,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container tbody tr.tw-cursor-pointer:hover td{background-color:transparent!important;color:var(--cide-ele-grid-text)!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto{scrollbar-width:thin;scrollbar-color:#d1d5db #f9fafb}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-track,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-track,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-track{background:#f9fafb!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb{background:#d1d5db!important}::ng-deep :root:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover,::ng-deep html:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover,::ng-deep body:not([data-theme=dark]):not(.dark-mode) .data-grid-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover{background:#9ca3af!important}.data-grid-container :host-context(.dark-mode) .tw-bg-white,.data-grid-container :host-context([data-theme=dark]) .tw-bg-white,.data-grid-container :host-context(body.dark-mode) .tw-bg-white,.data-grid-container :host-context(html.dark-mode) .tw-bg-white,.data-grid-container :host-context([data-theme=dark] body) .tw-bg-white,.data-grid-container :host-context([data-theme=dark] html) .tw-bg-white{background-color:var(--cide-ele-grid-bg, #1f2937)!important}.data-grid-container :host-context(.dark-mode) .tw-bg-gray-50,.data-grid-container :host-context([data-theme=dark]) .tw-bg-gray-50,.data-grid-container :host-context(body.dark-mode) .tw-bg-gray-50,.data-grid-container :host-context(html.dark-mode) .tw-bg-gray-50,.data-grid-container :host-context([data-theme=dark] body) .tw-bg-gray-50,.data-grid-container :host-context([data-theme=dark] html) .tw-bg-gray-50{background-color:var(--cide-ele-grid-bg-header, #374151)!important}.data-grid-container :host-context(.dark-mode) .tw-bg-gray-100,.data-grid-container :host-context([data-theme=dark]) .tw-bg-gray-100,.data-grid-container :host-context(body.dark-mode) .tw-bg-gray-100,.data-grid-container :host-context(html.dark-mode) .tw-bg-gray-100,.data-grid-container :host-context([data-theme=dark] body) .tw-bg-gray-100,.data-grid-container :host-context([data-theme=dark] html) .tw-bg-gray-100{background-color:var(--cide-ele-grid-bg-group, #374151)!important}.data-grid-container :host-context(.dark-mode) .data-grid-group-row,.data-grid-container :host-context([data-theme=dark]) .data-grid-group-row,.data-grid-container :host-context(body.dark-mode) .data-grid-group-row,.data-grid-container :host-context(html.dark-mode) .data-grid-group-row,.data-grid-container :host-context([data-theme=dark] body) .data-grid-group-row,.data-grid-container :host-context([data-theme=dark] html) .data-grid-group-row{background-color:var(--cide-ele-grid-bg-group, #374151)!important}.data-grid-container :host-context(.dark-mode) tbody,.data-grid-container :host-context([data-theme=dark]) tbody,.data-grid-container :host-context(body.dark-mode) tbody,.data-grid-container :host-context(html.dark-mode) tbody,.data-grid-container :host-context([data-theme=dark] body) tbody,.data-grid-container :host-context([data-theme=dark] html) tbody{background-color:var(--cide-ele-grid-bg, #1f2937)!important}.data-grid-container :host-context(.dark-mode) tbody tr,.data-grid-container :host-context([data-theme=dark]) tbody tr,.data-grid-container :host-context(body.dark-mode) tbody tr,.data-grid-container :host-context(html.dark-mode) tbody tr,.data-grid-container :host-context([data-theme=dark] body) tbody tr,.data-grid-container :host-context([data-theme=dark] html) tbody tr{background-color:var(--cide-ele-grid-bg, #1f2937)!important}.data-grid-container :host-context(.dark-mode) tbody tr td,.data-grid-container :host-context([data-theme=dark]) tbody tr td,.data-grid-container :host-context(body.dark-mode) tbody tr td,.data-grid-container :host-context(html.dark-mode) tbody tr td,.data-grid-container :host-context([data-theme=dark] body) tbody tr td,.data-grid-container :host-context([data-theme=dark] html) tbody tr td{background-color:transparent}.data-grid-container :host-context(.dark-mode).tw-table-striped tbody tr:nth-child(2n),.data-grid-container :host-context([data-theme=dark]).tw-table-striped tbody tr:nth-child(2n),.data-grid-container :host-context(body.dark-mode).tw-table-striped tbody tr:nth-child(2n),.data-grid-container :host-context(html.dark-mode).tw-table-striped tbody tr:nth-child(2n),.data-grid-container :host-context([data-theme=dark] body).tw-table-striped tbody tr:nth-child(2n),.data-grid-container :host-context([data-theme=dark] html).tw-table-striped tbody tr:nth-child(2n){background-color:var(--cide-ele-grid-bg-striped, #111827)!important}.data-grid-container :host-context(.dark-mode) .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark]) .tw-text-gray-900,.data-grid-container :host-context(body.dark-mode) .tw-text-gray-900,.data-grid-container :host-context(html.dark-mode) .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] body) .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] html) .tw-text-gray-900{color:var(--cide-ele-text-primary, #f9fafb)!important}.data-grid-container :host-context(.dark-mode) .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark]) .tw-text-gray-600,.data-grid-container :host-context(body.dark-mode) .tw-text-gray-600,.data-grid-container :host-context(html.dark-mode) .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] body) .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] html) .tw-text-gray-600{color:var(--cide-ele-text-secondary, #d1d5db)!important}.data-grid-container :host-context(.dark-mode) .tw-text-gray-500,.data-grid-container :host-context([data-theme=dark]) .tw-text-gray-500,.data-grid-container :host-context(body.dark-mode) .tw-text-gray-500,.data-grid-container :host-context(html.dark-mode) .tw-text-gray-500,.data-grid-container :host-context([data-theme=dark] body) .tw-text-gray-500,.data-grid-container :host-context([data-theme=dark] html) .tw-text-gray-500{color:var(--cide-ele-text-tertiary, #9ca3af)!important}.data-grid-container :host-context(.dark-mode) .tw-text-gray-400,.data-grid-container :host-context([data-theme=dark]) .tw-text-gray-400,.data-grid-container :host-context(body.dark-mode) .tw-text-gray-400,.data-grid-container :host-context(html.dark-mode) .tw-text-gray-400,.data-grid-container :host-context([data-theme=dark] body) .tw-text-gray-400,.data-grid-container :host-context([data-theme=dark] html) .tw-text-gray-400{color:var(--cide-ele-text-tertiary, #9ca3af)!important}.data-grid-container :host-context(.dark-mode) .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark]) .tw-text-gray-700,.data-grid-container :host-context(body.dark-mode) .tw-text-gray-700,.data-grid-container :host-context(html.dark-mode) .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] body) .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] html) .tw-text-gray-700{color:var(--cide-ele-text-secondary, #d1d5db)!important}.data-grid-container :host-context(.dark-mode) .tw-border-gray-200,.data-grid-container :host-context(.dark-mode) .tw-divide-gray-200,.data-grid-container :host-context([data-theme=dark]) .tw-border-gray-200,.data-grid-container :host-context([data-theme=dark]) .tw-divide-gray-200,.data-grid-container :host-context(body.dark-mode) .tw-border-gray-200,.data-grid-container :host-context(body.dark-mode) .tw-divide-gray-200,.data-grid-container :host-context(html.dark-mode) .tw-border-gray-200,.data-grid-container :host-context(html.dark-mode) .tw-divide-gray-200,.data-grid-container :host-context([data-theme=dark] body) .tw-border-gray-200,.data-grid-container :host-context([data-theme=dark] body) .tw-divide-gray-200,.data-grid-container :host-context([data-theme=dark] html) .tw-border-gray-200,.data-grid-container :host-context([data-theme=dark] html) .tw-divide-gray-200{border-color:var(--cide-ele-grid-border, #374151)!important}.data-grid-container :host-context(.dark-mode) .tw-border-gray-300,.data-grid-container :host-context([data-theme=dark]) .tw-border-gray-300,.data-grid-container :host-context(body.dark-mode) .tw-border-gray-300,.data-grid-container :host-context(html.dark-mode) .tw-border-gray-300,.data-grid-container :host-context([data-theme=dark] body) .tw-border-gray-300,.data-grid-container :host-context([data-theme=dark] html) .tw-border-gray-300{border-color:var(--cide-ele-grid-border, #374151)!important}.data-grid-container :host-context(.dark-mode) tbody tr:hover,.data-grid-container :host-context(.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host-context(.dark-mode) tbody tr.data-grid-row:hover,.data-grid-container :host-context([data-theme=dark]) tbody tr:hover,.data-grid-container :host-context([data-theme=dark]) tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host-context([data-theme=dark]) tbody tr.data-grid-row:hover,.data-grid-container :host-context(body.dark-mode) tbody tr:hover,.data-grid-container :host-context(body.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host-context(body.dark-mode) tbody tr.data-grid-row:hover,.data-grid-container :host-context(html.dark-mode) tbody tr:hover,.data-grid-container :host-context(html.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host-context(html.dark-mode) tbody tr.data-grid-row:hover,.data-grid-container :host-context([data-theme=dark] body) tbody tr:hover,.data-grid-container :host-context([data-theme=dark] body) tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host-context([data-theme=dark] body) tbody tr.data-grid-row:hover,.data-grid-container :host-context([data-theme=dark] html) tbody tr:hover,.data-grid-container :host-context([data-theme=dark] html) tbody tr.hover\\:tw-bg-gray-50:hover,.data-grid-container :host-context([data-theme=dark] html) tbody tr.data-grid-row:hover{background-color:var(--cide-ele-grid-bg-hover, #374151)!important}.data-grid-container :host-context(.dark-mode) tbody tr:hover td,.data-grid-container :host-context(.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host-context(.dark-mode) tbody tr.data-grid-row:hover td,.data-grid-container :host-context([data-theme=dark]) tbody tr:hover td,.data-grid-container :host-context([data-theme=dark]) tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host-context([data-theme=dark]) tbody tr.data-grid-row:hover td,.data-grid-container :host-context(body.dark-mode) tbody tr:hover td,.data-grid-container :host-context(body.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host-context(body.dark-mode) tbody tr.data-grid-row:hover td,.data-grid-container :host-context(html.dark-mode) tbody tr:hover td,.data-grid-container :host-context(html.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host-context(html.dark-mode) tbody tr.data-grid-row:hover td,.data-grid-container :host-context([data-theme=dark] body) tbody tr:hover td,.data-grid-container :host-context([data-theme=dark] body) tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host-context([data-theme=dark] body) tbody tr.data-grid-row:hover td,.data-grid-container :host-context([data-theme=dark] html) tbody tr:hover td,.data-grid-container :host-context([data-theme=dark] html) tbody tr.hover\\:tw-bg-gray-50:hover td,.data-grid-container :host-context([data-theme=dark] html) tbody tr.data-grid-row:hover td{background-color:transparent!important;color:var(--cide-ele-text-primary, #f9fafb)!important}.data-grid-container :host-context(.dark-mode) tbody tr:hover .tw-text-gray-900,.data-grid-container :host-context(.dark-mode) tbody tr:hover .tw-text-gray-700,.data-grid-container :host-context(.dark-mode) tbody tr:hover .tw-text-gray-600,.data-grid-container :host-context(.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host-context(.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host-context(.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host-context(.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host-context(.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host-context(.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark]) tbody tr:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark]) tbody tr:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark]) tbody tr:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark]) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark]) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark]) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark]) tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark]) tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark]) tbody tr.data-grid-row:hover .tw-text-gray-600,.data-grid-container :host-context(body.dark-mode) tbody tr:hover .tw-text-gray-900,.data-grid-container :host-context(body.dark-mode) tbody tr:hover .tw-text-gray-700,.data-grid-container :host-context(body.dark-mode) tbody tr:hover .tw-text-gray-600,.data-grid-container :host-context(body.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host-context(body.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host-context(body.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host-context(body.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host-context(body.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host-context(body.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-600,.data-grid-container :host-context(html.dark-mode) tbody tr:hover .tw-text-gray-900,.data-grid-container :host-context(html.dark-mode) tbody tr:hover .tw-text-gray-700,.data-grid-container :host-context(html.dark-mode) tbody tr:hover .tw-text-gray-600,.data-grid-container :host-context(html.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host-context(html.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host-context(html.dark-mode) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host-context(html.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host-context(html.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host-context(html.dark-mode) tbody tr.data-grid-row:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] body) tbody tr:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] body) tbody tr:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] body) tbody tr:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] body) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] body) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] body) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] body) tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] body) tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] body) tbody tr.data-grid-row:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] html) tbody tr:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] html) tbody tr:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] html) tbody tr:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] html) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] html) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] html) tbody tr.hover\\:tw-bg-gray-50:hover .tw-text-gray-600,.data-grid-container :host-context([data-theme=dark] html) tbody tr.data-grid-row:hover .tw-text-gray-900,.data-grid-container :host-context([data-theme=dark] html) tbody tr.data-grid-row:hover .tw-text-gray-700,.data-grid-container :host-context([data-theme=dark] html) tbody tr.data-grid-row:hover .tw-text-gray-600{color:var(--cide-ele-text-primary, #f9fafb)!important}.data-grid-container :host-context(.dark-mode) tbody tr.tw-cursor-pointer:hover,.data-grid-container :host-context([data-theme=dark]) tbody tr.tw-cursor-pointer:hover,.data-grid-container :host-context(body.dark-mode) tbody tr.tw-cursor-pointer:hover,.data-grid-container :host-context(html.dark-mode) tbody tr.tw-cursor-pointer:hover,.data-grid-container :host-context([data-theme=dark] body) tbody tr.tw-cursor-pointer:hover,.data-grid-container :host-context([data-theme=dark] html) tbody tr.tw-cursor-pointer:hover{background-color:var(--cide-ele-grid-bg-hover, #374151)!important;border-left:2px solid var(--cide-ele-grid-border-hover, #60a5fa)!important}.data-grid-container :host-context(.dark-mode) tbody tr.tw-cursor-pointer:hover td,.data-grid-container :host-context([data-theme=dark]) tbody tr.tw-cursor-pointer:hover td,.data-grid-container :host-context(body.dark-mode) tbody tr.tw-cursor-pointer:hover td,.data-grid-container :host-context(html.dark-mode) tbody tr.tw-cursor-pointer:hover td,.data-grid-container :host-context([data-theme=dark] body) tbody tr.tw-cursor-pointer:hover td,.data-grid-container :host-context([data-theme=dark] html) tbody tr.tw-cursor-pointer:hover td{background-color:transparent!important;color:var(--cide-ele-text-primary, #f9fafb)!important}.data-grid-container :host-context(.dark-mode).drag-drop-enabled tbody tr:hover,.data-grid-container :host-context([data-theme=dark]).drag-drop-enabled tbody tr:hover,.data-grid-container :host-context(body.dark-mode).drag-drop-enabled tbody tr:hover,.data-grid-container :host-context(html.dark-mode).drag-drop-enabled tbody tr:hover,.data-grid-container :host-context([data-theme=dark] body).drag-drop-enabled tbody tr:hover,.data-grid-container :host-context([data-theme=dark] html).drag-drop-enabled tbody tr:hover{background-color:var(--cide-ele-grid-bg-hover, #374151)!important}.data-grid-container :host-context(.dark-mode).drag-drop-enabled tbody tr:hover td,.data-grid-container :host-context([data-theme=dark]).drag-drop-enabled tbody tr:hover td,.data-grid-container :host-context(body.dark-mode).drag-drop-enabled tbody tr:hover td,.data-grid-container :host-context(html.dark-mode).drag-drop-enabled tbody tr:hover td,.data-grid-container :host-context([data-theme=dark] body).drag-drop-enabled tbody tr:hover td,.data-grid-container :host-context([data-theme=dark] html).drag-drop-enabled tbody tr:hover td{color:var(--cide-ele-text-primary, #f9fafb)!important}.data-grid-container :host-context(.dark-mode).drag-drop-enabled tbody tr[draggable=true]:hover,.data-grid-container :host-context([data-theme=dark]).drag-drop-enabled tbody tr[draggable=true]:hover,.data-grid-container :host-context(body.dark-mode).drag-drop-enabled tbody tr[draggable=true]:hover,.data-grid-container :host-context(html.dark-mode).drag-drop-enabled tbody tr[draggable=true]:hover,.data-grid-container :host-context([data-theme=dark] body).drag-drop-enabled tbody tr[draggable=true]:hover,.data-grid-container :host-context([data-theme=dark] html).drag-drop-enabled tbody tr[draggable=true]:hover{background-color:var(--cide-ele-grid-bg-hover, #374151)!important}.data-grid-container :host-context(.dark-mode).drag-drop-enabled tbody tr[draggable=true]:hover td,.data-grid-container :host-context([data-theme=dark]).drag-drop-enabled tbody tr[draggable=true]:hover td,.data-grid-container :host-context(body.dark-mode).drag-drop-enabled tbody tr[draggable=true]:hover td,.data-grid-container :host-context(html.dark-mode).drag-drop-enabled tbody tr[draggable=true]:hover td,.data-grid-container :host-context([data-theme=dark] body).drag-drop-enabled tbody tr[draggable=true]:hover td,.data-grid-container :host-context([data-theme=dark] html).drag-drop-enabled tbody tr[draggable=true]:hover td{color:var(--cide-ele-text-primary, #f9fafb)!important}.data-grid-container.drag-drop-enabled tbody tr{transition:all .2s ease}.data-grid-container.drag-drop-enabled tbody tr:hover{background-color:var(--cide-ele-grid-bg-hover, #f9fafb)}.data-grid-container.drag-drop-enabled tbody tr:hover td{color:var(--cide-ele-grid-text, #1f2937)}.data-grid-container.drag-drop-enabled tbody tr.tw-opacity-50{background-color:#dbeafecc;border:2px dashed var(--cide-ele-brand-primary, #3b82f6);border-radius:4px}.data-grid-container.drag-drop-enabled tbody tr.tw-bg-blue-50{background-color:#eff6ffe6}.data-grid-container.drag-drop-enabled tbody tr[draggable=true]{cursor:move;position:relative}.data-grid-container.drag-drop-enabled tbody tr[draggable=true]:hover{background-color:var(--cide-ele-grid-bg-hover, #f9fafb);box-shadow:0 1px 3px #0000001a}.data-grid-container.drag-drop-enabled tbody tr[draggable=true]:hover td{color:var(--cide-ele-grid-text, #1f2937)}.data-grid-container.drag-drop-enabled tbody tr[draggable=true]:active{cursor:grabbing}.data-grid-container.drag-drop-enabled tbody tr[style*=border-top]{position:relative}.data-grid-container.drag-drop-enabled tbody tr[style*=border-top]:before{content:\"\";position:absolute;top:-2px;left:0;right:0;height:2px;background:linear-gradient(90deg,#3b82f6,#60a5fa);z-index:10}.data-grid-container.tree-enabled tbody tr td:first-child{position:relative}.data-grid-container.tree-enabled tbody tr td:first-child button{transition:all .15s ease}.data-grid-container.tree-enabled tbody tr td:first-child button:hover{background-color:var(--cide-ele-bg-tertiary);border-radius:2px}.data-grid-container.tree-enabled tbody tr td:first-child button svg{transition:transform .2s ease}.data-grid-container.tree-enabled tbody tr[style*=padding-left]{border-left:2px solid transparent}.data-grid-container.tree-enabled tbody tr[style*=padding-left]:hover{border-left-color:var(--cide-ele-border-primary)}.tree-level-0{border-bottom:2px solid var(--cide-ele-border-primary)!important;background-color:var(--cide-ele-grid-bg)}.tree-level-0:hover{background-color:var(--cide-ele-bg-hover)!important}.tree-level-0 td:first-child{font-weight:600}.tree-level-1{border-bottom:1px solid var(--cide-ele-border-secondary)!important;background-color:var(--cide-ele-grid-bg-striped)}.tree-level-1:hover{background-color:var(--cide-ele-grid-bg-hover)!important}.tree-level-1 td:first-child{font-weight:500}.tree-level-2{border-bottom:1px solid var(--cide-ele-border-secondary)!important;background-color:var(--cide-ele-bg-secondary)}.tree-level-2:hover{background-color:var(--cide-ele-bg-hover)!important}.tree-level-2 td:first-child{font-weight:400}.tree-level-deep{border-bottom:1px solid var(--cide-ele-border-primary)!important;background-color:var(--cide-ele-bg-primary)}.tree-level-deep:hover{background-color:var(--cide-ele-bg-hover)!important}.tree-level-deep td:first-child{font-weight:300}table td{box-sizing:border-box;word-wrap:break-word;overflow-wrap:break-word}table td.tw-overflow-hidden{overflow:hidden;text-overflow:ellipsis}table td:first-child{min-width:150px}table td:first-child>div{display:flex;align-items:center;min-width:0}table td:first-child>div .tw-flex{min-width:0}table td .tw-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CideInputComponent, selector: "cide-ele-input", inputs: ["fill", "label", "labelHide", "disabled", "clearInput", "labelPlacement", "labelDir", "placeholder", "leadingIcon", "trailingIcon", "helperText", "helperTextCollapse", "hideHelperAndErrorText", "errorText", "maxlength", "minlength", "required", "autocapitalize", "autocomplete", "type", "width", "id", "ngModel", "option", "min", "max", "step", "size"], outputs: ["ngModelChange"] }, { kind: "component", type: CideSelectComponent, selector: "cide-ele-select", inputs: ["label", "labelHide", "placeholder", "helperText", "errorText", "required", "disabled", "id", "ngModel", "size", "fill", "labelPlacement", "labelDir", "leadingIcon", "trailingIcon", "clearInput", "options", "multiple", "searchable", "showSearchInput", "loading", "valueKey", "labelKey", "treeView"], outputs: ["ngModelChange", "change", "searchChange"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton], cide-ele-button", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }] });
|
|
12598
12667
|
}
|
|
12599
12668
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideEleDataGridComponent, decorators: [{
|
|
12600
12669
|
type: Component,
|